




已阅读5页,还剩295页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
2020/5/19,程序设计,C/C+,教师姓名:赵敏,信息学院计算中心,2020/5/19,目录,第一章C语言概述第二章数据类型及基本运算第三章顺序结构程序设计第四章选择结构程序设计第五章循环结构程序设计,第六章数组第七章函数第八章指针第九章结构与其它自定义类型第十章文件,2020/5/19,第七章函数,2020/5/19,7.1函数的概念7.1.1函数实例及分析一个较大的程序一般应分为若干个程序模块,每一个模块用来实现一个特定的功能,用子程序实现模块的功能。在语言中,子程序的作用是由函数完成的。通过函数的调用与连接来实现程序的化繁为简、化整为零的模块化程序设计。,2020/5/19,在程序设计中,常将一些常用的功能模块编写成函数,放在函数库中供公共选用。要善于利用函数,以减少重复编写程序段的工作量。先举一个简单的函数调用的例子。,2020/5/19,不带参数的函数调用,2020/5/19,【例】给出如下两个函数:printstar()printf(“*n);,print-message()printf(Howdoyoudo!n);,main()printstar();*调用printstar函数*print-message();*调用printmessage*/printstar();*调用printstar函数*,返回,2020/5/19,运行情况如下:*Howdoyoudo!*,2020/5/19,总结:1、库函数和自定义函数;2、在C语言中,一个程序可由一个主函数和若干个函数构成。由主函数调用其他函数,其他函数之间可以互相调用。同一个函数可以被一个或多个函数调用任意多次。下图是一个程序中函数调用的示意图。,2020/5/19,2020/5/19,7.2函数的定义7.2.1函数定义形式第一种:函数类型函数名(形式参数说明表)函数体,实现函数功能的语句序列,代表函数所返回的值的类型,用户标识符,代表函数的自变量,多个时用逗号分隔,2020/5/19,例:定义一个函数,求点(x,y)到原点距离。,doubledistance(doublex,doubley),第一行函数头的句末不能加分号;大多数函数都有值返回。void的使用;返回的函数值类型与所定义的函数类型相一致,若不一致,则以函数的类型为准。,doublez;z=sqrt(x*x+y*y);returnz;,2020/5/19,第二种:函数类型函数名(形式参数表)形式参数说明函数体,实现函数功能的语句序列,代表函数所返回的值的类型,用户标识符,代表函数的自变量,多个时用逗号分隔,2020/5/19,【例】定义一个函数,求点(x,y)到原点的距离。doubledistance(x,y)doublex,y;doublez;z=sqrt(x*x+y*y);returnz;,形式参数说明,形式参数表,2020/5/19,【例】请等价变换函数的定义形式。intmax(a,b,c)inta,b,c;a=ab?a:b;printf(“max=%dn”,ac?a:c);,intmax(inta,intb,intc)a=ab?a:b;printf(“max=%dn”,ac?a:c);,2020/5/19,7.2.2说明事项大多数函数都有值返回,函数体中必须使用return语句将函数值返回出去;return语句的三种形式为:return(表达式)return表达式return,2020/5/19,7.3函数的调用7.3.1函数调用形式函数名(实在参数列表),1、多个参数用逗号分开;2、被调用的是无参函数,圆括号不能省;,【例】调用无参函数。print-message()printf(Howdoyoudo!n);,main()print-message();*调用无参函数print_message()*/,返回,2020/5/19,【例】调用有参函数。intsum(floata,floatb)returna+b;,main()floatx=3.5,y=5.2;printf(“%dn”,sum(x,y);,2020/5/19,【例】编写程序,实现下列算式的计算。X12+42+72+402Y23+43+63+403,由所给算式看出它们的通式为:f=(im)(i=a,a+step,a+2*step,40),2020/5/19,floatf(inta,intm,intstep)inti;longsum=0;returnsum;,#include,for(i=a;i=40;i=i+step)sum=sum+pow(i,m);,2020/5/19,main()longx,y;x=f(1,2,3);y=f(2,3,2);printf(“x=%ldty=%ldn”,x,y);,【思考题】下列函数调用语句正确吗?xf(1,2),错误,错误,错误,xf(2,3,1),xf(1,2.0,3),floatf(inta,intm,intstep)inti;longsum=0;for(i=a;idistance(x2,y2)*x=x1;*y=y1;else*x=x2;*y=y2;,/*函数的功能:求离原点远的那个坐标点(x,y)*/voidfarpoint(x1,y1,x2,y2,x,y)floatx1,y1,x2,y2,*x,*y;,指针参数,2020/5/19,2、执行流程#includemain();a();;,a();b();;,b();,2020/5/19,7.4.2递归函数1、关于递归的概念,下面用一个通俗的例子来说明。【例】有5个人坐在一起,问第5个人多少岁?他说比第4个人大2岁。问第4个人岁数,他说比第3个人大2岁。问第3个人,又说比第2个人大2岁。问第2个人,说比第1个人大2岁。最后问第1个人,他说是10岁。请问第5个人多大。显然,这是一个递归问题。要求第5个人的年龄,就必须先知道第4个人的年龄,而第4个人的年龄也不知道,要求第4个人的年龄必须先知道第3个人的年龄,而第3个人的年龄又取决于第2个人的年龄,第2个人的年龄取决于第1个人的年龄。,2020/5/19,而且每一个人的年龄都比其前1个人的年龄大2。即age(5)age(4)2,age(4)age(3)2,age(3)age(2)2,age(2)age(1)2,age(1)10,如果第1个人10岁,那么可以用通式表述如下:age(n)10(n1)age(n)age(n1)2(n1),可以看到,当n1时,求第n个人的年龄的公式是相同的。,2020/5/19,因此可以用一个函数来描述上述递归过程。下图表示求第5个人年龄的过程。,运行结果为:,2020/5/19,2、函数调用过程如下图所示。,2020/5/19,2020/5/19,3、递归函数的使用注意点(1)递归函数调用是带条件的,每次调用后条件要得到变化,避免无法回归的死回归;(2)递归函数主要用于迭代、级数、链表等方面。,2020/5/19,7.5变量的作用域,上述三个问题必须从“变量的作用域”的角度来解答。变量的作用域是指变量能被有效引用的范围。C语言从“局部变量”和“全局变量”两个方面来做探讨。,1、编写函数时如何命名变量;2、不同函数中定义的变量是否允许同名?3、不同的函数能否共享一组数据?,回答如下问题:,2020/5/19,7.5.1局部变量在函数(包括main函数)内部或复合语句内部定义的一切变量(包括形式参数)都是局部变量,它们的作用域仅限于自身所在的函数内部或复合语句内部,出界无效,在不同函数中定义的变量即便同名,仍代表不同的对象。,2020/5/19,change函数中定义的局部变量i,main函数中定义的局部变量i,输出结果为:i0,【例】change(inti)i=1;,main()inti=0;change(i);printf(“i=%dn”,i);,i=1,2020/5/19,【例】编写程序,调用sort函数,将6个整数从小到大排序。思考如下几个问题:下面这个程序能达到预期的效果吗?如何才能达到预期的效果?,排序算法,2020/5/19,2020/5/19,运行结果为:,返回,2020/5/19,2020/5/19,运行结果为:,2020/5/19,7.5.2全局变量全局变量在函数外部定义的变量;全局变量的作用域从定义变量位置开始至源文件结束;全局变量能够供其后面的一切函数引用。,2020/5/19,main()change();printf(“i=%dn”,i);,输出结果为:i1,【例】inti=0;change()i=1;,全局变量,输出结果为:i0,【例】change(inti)i=1;,main()inti=0;change(i);printf(“i=%dn”,i);,局部变量,在函数或复合语句内部有效,2020/5/19,intp=1,q=5;floatf1(inta)intb,c;charc1,c2;charf2(intx,inty)inti,j;main()intm,n;,全局变量p,q的作用范围,c1,c2的作用范围,/*全局变量*/,/*定义函数f1*/,/*全局变量*/,/*定义函数f2*/,/*主函数*/,/*变量a,b,c的作用域为函数f1内*/,【例】判断哪些是局部变量,哪些是全局变量,并说出各个变量的作用域。,/*x,y,i,j的作用域为f2内*/,/*m,n的作用域为main函数内*/,2020/5/19,效的全局变量。打个通俗的比方:国家有统一的法律和法令,各省,总结:在一个函数中既可以使用本函数中的局部变量,又可以使用有,还可以根据需要制定地方的法律、法令。在甲省,国家统一的法律,法令和甲省的法律法令都是有效的,而在乙省,则国家统一的和乙,省的法律法令有效。显然,甲省的法律法令在乙省无效。,为了便于区别全局变量和局部变量,在C程序设计人员中有一,个不成文的约定(但非规定),将全局变量名的笫一个字母用大写,表示。,2020/5/19,【例】修改“编写程序,调用sort函数,将6个整数从小到大排序”这个程序,使之达到6个整数从小到大排序的目的。先看原程序的处理方法:,思考题:,局部变量例子,2020/5/19,算法设计:将a数组连同循环控制变量i和j定义为全局变量,扩大它们的作用域,达到排序的目的。,2020/5/19,运行结果为:,返回,2020/5/19,7.6变量的存储类别变量的三大属性:类型确定了变量的存储长度和运算方式,例如int,float,char等;作用域确定了变量存在的空间,例如全局变量和局部变量;存储类别(生命周期)确定了变量存在的时间,即什么时候变量存在,其值保留,什么时候变量不存在,其值丢失;,2020/5/19,在C中变量存在的时间是通过变量存储类别的声明来指定的。TurboC支持以下四种存储类别:,TurboC支持的四种存储类别,2020/5/19,7.6.1动态存储动态存储的特点:指变量的存储单元随函数的调用而取得,随函数调用的结束而释放。,C语言约定:在函数内部(包括main函数)定义的一切局部变量(包括形式参数)均为动态变量,自动服从动态存储规则,存储在称为“栈”的动态内存区域中。,动态存储类别的声明原型为:auto数据类型变量名列表,一般省略,2020/5/19,【例】main()autointa,b;scanf(“%d%d”,注意:引用一个从未被赋过值的动态变量,其初值是不确定的,因为C编译程序不会对动态变量自动赋初值。,2020/5/19,7.6.2静态存储静态存储的特点:在程序执行的全过程中,变量始终占据着大小固定的存储单元直至程序运行结束才予以释放。,C语言约定:全局变量和经过static特殊声明的局部变量均为静态变量,自动服从静态存储规则,并存储在称为“数据段”的内存区域中。,2020/5/19,静态存储类别的声明原型为:static数据类型变量名列表;,【例】考察静态局部变量的值。,2020/5/19,f(inta)autob0;staticc3;bb1;cc1;return(abc);main()inta2,i;for(i0;i3;i+)printf(d,f(a);,运行结果为:789,2020/5/19,7.6.3寄存器型存储一般情况下,变量的值是存放在内存中。当程序中用到变量的值时,由控制器发出指令将内存中该变量的值送到运算器中进行运算;如果需要存数,再从运算器将数据送到内存存放(如右图)。如果有一些变量使用频繁,存取变量的值要花很多时间。为提高执行效率,语言允许将值放在CPU中的寄存器中,需要用时直接从寄存器取出。,2020/5/19,寄存器型存储的特点:将变量的存储单元分配在CPU的寄存器中,而不是常规的内存中。,寄存器型存储的定义:register数据类型变量名列表;,寄存器存储的说明:(1)只有局部动态变量和函数的形式参数可以作为寄存器变量,其他(如全局变量)不行;(2)不同计算机系统允许使用寄存器变量数目不尽相同。,2020/5/19,7.6.4外部存储外部存储类别的特点:如果要被同一个程序中的位于其前的函数引用或被另一个源程序文件引用,就必须在引用之前对该全局变量作外部存储声明。,2020/5/19,外部存储类别的声明:extern数据类型变量名列表;【例】对全局变量作外部存储声明,供位于其定义之前的函数引用。,全局变量,2020/5/19,2020/5/19,下面从不同角度做些归纳:(1)从作用域角度分,有局部变量和全局变量。(2)从变量存在的时间(生存期)来区分,有动态存储和静态存储两种类型。静态存储是程序整个运行时间都存在,而动态存储则是在调用函数时临时分配单元。,2020/5/19,(3)关于作用域和生存期的概念。从前面叙述可以知道,对一个变量的性质可以从两个方面分析,一是从变量的作用域,一是从变量值存在时间的长短,即生存期。前者是从空间的角度,后者是从时间的角度。二者有联系但不是同一回事。具体看下图:,2020/5/19,2020/5/19,有宏参数定义指用一个带参数的宏名代表一个字符串,预处理时不再是简单的字符串替换,还要进行参数替换,语法为:,7.7带参数宏与函数的区别,7.7.1有参数宏定义,#define宏名(参数表)字符串,2020/5/19,【例】#defineS(a,b)(ab)?a:bmain()intx,y;scanf(“%d,%d”,【思考题】程序的功能是什么?,2020/5/19,使用说明:宏名与其右边的左圆括号之间不能有空格;【例】#defineS(c)c*c如果S后带有空格,那么S则表示为符号常量(即不带参数的宏名),它所代替的字符串为“(c)c*c”;当参数为表达式时,对参数表达式加括号可以防止二义性;,2020/5/19,【例】写出下列程序运行的结果。#defineS(c)c*cmain()intm=5,n=8,k;k=10*S(m+n);printf(“%dn”,k);,宏代换就是不进行运算,而是直接替换,因此结果为:,运行结果为:98,k=10*S(m+n),10*5+8*5+8=98,2020/5/19,修正后的程序:,运行结果为:,2020/5/19,7.7.2有参数宏与函数的区别(1)在程序控制上,调用带参数宏时,宏实参只是简单的对宏形参进行原形替换;调用函数时,则是先求出实参表达式的值,再代入形参变量中;,2020/5/19,【例】#defineF(a,b)a*bintg(inta,intb)returna*b;main()printf(“%dn”,F(3+1,7-2);printf(“%dn”,g(3+1,7-2);,2020/5/19,(2)宏参数没有固定的数据类型,定义时不涉及类型,宏名和宏参数均无类型;(3)函数调用是在程序运行时发生的,并动态分配所用的内存单元;而宏调用是在编译预处理时进行的,不分配内存单元,不进行值传送,也无值返回;,2020/5/19,(4)使用函数调用不增加运行程序的长度,但每使用一次宏调用,都会使运行程序篇幅有所增长,使编译、链接后的执行程序也增长;(5)宏定义主要用于需要少量参数的简单表达式中,而且调用时不作数据类型检查;(6)使用函数不会带来副作用,但宏若使用不当,可能会带来副作用。,2020/5/19,习题集,2020/5/19,【选择题1】下列程序段正确的是()。,A)#includemain()intij0;,B)includemain()inti,j;,D)#includemain(),C)#include;main(),D,2020/5/19,【选择题2】以下叙述中正确的是()。A)C语言程序总是从第一个定义的函数开始执行;B)在C语言程序中,要调用的函数必须在main()函数中定义C)C语言程序中的main()函数必须放在程序的开始部分;D)C语言程序总是从main()函数开始执行;,D,2020/5/19,【选择题3】有以下函数调用语句:func(exp1,exp2),(exp3,exp4,exp5);其中含有的实参个数和是()。A)1;B)2;C)4;D)5;,B,逗号表达式,2020/5/19,【选择题4】如下程序的运行结果为()。,A)678B)789C)567D)无输出结果,B,2020/5/19,【选择题5】如下程序的运行结果为()。includefun(inta,intb,intc)intx;x=a*b*c;returnx;main()intc;printf(“%dn”,fun(2,3,c);A)0B)1C)6D)无定值,D,涉及到两个知识点:1.传值和传址的调用;2.动态存储变量初值的确定,2020/5/19,【选择题6】有如下程序:,运行结果为()。A)max=3B)max=4C)max=5D)max=6,C,外部变量的定义,外部变量声明,2020/5/19,【选择题7】分析以下程序的运行结果()。,A)5B)6C)7D)8,B,2020/5/19,第八章指针,2020/5/19,指针是C语言中的一个重要的概念。正确而灵活地运用指针,可以有效地表示复杂的数据结构;能动态分配内存;能方便地使用字符串;有效而方便地使用数组;在调用函数时能得到多于1个的值;能直接处理内存地址等,这对设计系统软件是很必要的。,2020/5/19,学好指针的方法:多思考;多比较;多上机,在实践中掌握;,2020/5/19,8.1指针的概念8.1.1地址与指针在计算机中,内存是以字节为单位依次编号,变量一旦获得了编译系统为其分配的存储单元,则该存储单元的起始字节的编号就称为该变量的地址或指针。,【例】inti3;floatj6;则它们的内存分配情况如下:,2020/5/19,内存数据区,i,j,内存分配示意图,【例】inti3;floatj6;,2020/5/19,指针变量i_pointer,普通变量和指针变量的区别,2020/5/19,【例】变量a存储了变量b的地址,可采用将变量a定义为指针,指向变量b,变量指向关系如下图所示:,789,a,b,内存地址为aaff,定义指针变量a,定义一般变量b,并赋初值为789,8.1.2指针变量及其定义1.指针变量指针变量变量中存储的是一个变量的地址,而不是通常意义下的数据和字符;,aaff,2020/5/19,2)指针变量的定义形式:基类型*变量名,指针所指对象的数据类型,【例】intx,*p1;,【前导知识介绍】指针运算符:,2020/5/19,从1001H和1002H中取值。,1001H,pi,i,【例】doubley,z,*p2=,p2,z,【例】inti2,*pi=假设编译后,变量i的存储地址为1001H,那么*pi表示:,2020/5/19,【例】假设有如下定义:inta6=3,7,11,13,17,19,b,*p,*q;,8.1.3指针变量的引用,下表给出了几个指针引用的表达式及其含义:,使p指向a数组的首元素a0的地址,将表达式a0+1的值赋予变量b,b4,指针p后移一个存储单元,指向a1,使q也指向a1所在的存储单元,使p不指向任何变量,b=*p+1,p+,q=p,p=NULL,2020/5/19,注意点:(1)*p若出现在变量定义语句中,表示定义指针变量p;若出现在表达式中,则表示取p所指对象的内容。【例】main()doublex=3.6,*p;p=,赋值表达式,输出结果:3.60,2020/5/19,【例】,运行结果:,2020/5/19,(2)指针变量只能接收、存储与基类型相容的变量地址,所以不能对指针变量赋非地址值或与基类型不相容变量的地址。【例】inti=100,j,*ip;floatx,*xp;判断以下的赋值语句的对错:,错误,对指针变量赋非地址值,错误,j类型与xp所指对象类型不符,ip=i;,xp=,2020/5/19,(3)只能对指针变量赋变量的地址,而不能赋表达式的地址。【例】intx,*p;判断下面的说法:,p=,p,【思考题】p=a与p=【例】inta10,*p=a;,2020/5/19,指针处理二维数组,指针变量所指对象为数组中的行。1.二维数组的两种编译结构【例】给出二维数组,inta34=3,5,7,11,13,17,19,23,29,31,37,41结构之一:把a看作是3行4列的两维数组;,2020/5/19,a,数组名a代表整个数组的存储首地址,【思考题】如果有int*p=a;那么经过p=p1后,p指向的是哪个元素?,2020/5/19,输出结果为:,2020/5/19,结构之二:把a看作是一维数组,inta34=3,5,7,11,13,17,19,23,29,31,37,41;,a,对于一维数组而言,ai是个实实在在的占据内存单元的下标变量,它有明确的值;二维数组中引入的ai是个并不占据内存单元的地址常量,与数组名代表数组的存储首地址完全一样。,a0,a2,a1,2020/5/19,2.通过数组名引用数组元素,a,a0、a1、a2是一维数组名,各自代表自身所在行元素的存储首地址。,因为apa=a+1;,指向长度为5的一维数组的指针变量pb,并在定义pb的同时初始化,使其指向b数组的首元素,3行5列的二维数组b,指向长度为3的一维数组的指针变量pa,4行3列的二维数组a,指针变量pa指向a数组的第二行,即a1,2020/5/19,思考题:a是二维数组,如果有pa;那么p+1指向的是什么?,数组a,如果定义int*p;那么p是指针变量,所以p+1指向为元素2,如果定义int(*p)4;那么p是数组指针,所以p+1所指向为第2行,【例】分析下面两个程序的运行结果。,2020/5/19,输出结果为:,2020/5/19,输出结果为:,2020/5/19,指针与二维数组的联系,2020/5/19,8.3指针与函数两者之间的联系:1、将指针变量作为函数的参数,通过形式参数与实在参数的结合将函数值带出函数体反传给主调函数;,2、定义一个指针,让它指向函数,借助于该指针能使函数如同普通变量一样被方便地传递、调用,并且使函数的通用性得以提高。,2020/5/19,8.3.1指针变量作为函数的参数【例】编写函数sort(intx,inty),将整数x,y从小到大排序,再设计main函数,调用sort函数,实现将键盘输入的三个随机整数升排序。,角度1:普通变量作为函数的参数,2020/5/19,2020/5/19,运行结果为:,角度2:指针变量作为函数的参数。,2020/5/19,2020/5/19,运行结果为:,2020/5/19,定义形式:数据类型(*指针名)();,代表被指向函数的类型,【例】double(*f)();,8.3.2函数指针函数名也是个地址常量,存储了函数目标码的入口地址。若将函数的入口地址赋予指针变量,就称指针变量指向了该函数。指向函数的指针变量称为“函数指针”。,2020/5/19,8.3.3通过函数指针调用其他函数形式:(*指针名)(实参表);,实参表所包含的实参个数、类型必须与被指向的那个函数的形式参数表相一致,而且调用之前函数指针必须已经指向了某个实际函数。,参见书上P132的例8.6,2020/5/19,8.3.4函数指针作为函数的参数(自修)C语言中,函数的参数除了是简单变量名、数组名、指针变量名以外,还允许是函数。,【例】编写函数,利用矩形法计算函数f(x)在a,b区间上的定积分的值,再设计main函数,调用上述函数求和的定积分。,2020/5/19,2020/5/19,8.4指针与字符串8.4.1用一维字符数组定义单字符串1.用一维字符数组定义单字符串【例】charname20=“SmithXia”;,2.用字符指针定义单字符串【例】char*name;,定义字符指针,2020/5/19,【例】char*name=“SmithXia”;等价于char*name;name=“SmithXia”;,定义一个指向字符的指针变量,在定义的同时将字符串的首地址赋予给指针变量,【思考题】以下的表示方法正确吗?char*name;*name“SmithXia”;,错误,2020/5/19,【例】,2020/5/19,运行结果为:,2020/5/19,8.4.2多字符串处理1.用二维字符数组定义多字符串charstate59=“China”,“American”,“Japan”,“Canada”,“India”;,state,state数组的存储结构,state0,state1,state2,state3,state4,2020/5/19,2.用字符型指针数组定义多字符串指针数组数组的每一个下标变量都是一个指针变量,字符型指针数组的定义形式为:char*数组名长度,区别于数组指针(指向数组元素的指针变量):char(*指针名)N,优先次序高于*,2020/5/19,排序后的状况:,state0,state1,state2,【例】char*state3=“China”,“American”,“Japan”;,2020/5/19,2020/5/19,最终运行结果为:,【思考题】同二维数组相比,引入指针数组有什么好处?,2020/5/19,8.5多级指针8.5.1二级指针的定义形式:数据类型*指针名【例】int*q,int*p;,【例】charx=%,*p=,2000H,1000H,%,q,p(2000H),x,变量之间的指向关系,1000H,2020/5/19,8.5.2二级指针与指针数组的联系设有如下定义:char*course5=“Mathematics”,“English”,“Datastructure”,“Cprogramming”,“Internet”,*p=course;,p,二级指针与指针数组之间的指向关系,course0,course1,course2,course3,course4,2020/5/19,course0,course1,course2,course3,course4,p,char*course5=“Mathematics”,“English”,“Datastructure”,“Cprogramming”,“Internet”;*p=course;,2020/5/19,C语言中main函数与其他函数一样可以带形式参数,但如果要通过命令行接受参数,必须以下面的形式来定义main函数:main(intargc,char*argv)或main(intargc,char*argv),8.6命令行参数(自修),为int型变量,为指向字符的指针数组,2020/5/19,形式为:程序名参数1参数2参数n,命令行可以带任意个参数,参数与参数之间必须以空格分隔。【例】ex8100代表什么意思?【例】ex8col100代表什么意思?,argc将自动被赋值为2,argc获得整数值以后,接着编译系统自动建立一个长度为argc的字符指针数组*argvargc,并使argv0指向命令行上的第一个实参数,使argv1指向命令行上的第二个实参数。,2020/5/19,【例】编程程序,在整数序列a10中寻找大于m同时小于n的第一个数(设mprice-=200;,(+py)stock+=10;,1850,/*电冰箱降价200元*/,/*洗衣机库存加10*/,103,2020/5/19,结构指针作为函数的参数使得结构变量也能像普通变量一样实现“传地址”调用。调用发生时,实参传递给形参的是自身结构的存储地址,使形式参数直接指向了实在实参,形参不再另占内存单元,从而使函数体中对形式参数所作的改变就是对实在参数所作。,3.结构指针作为函数的参数,2020/5/19,【例】已知10名学生的三门单科考试成绩,求每一门课程的总平均分。,2020/5/19,2020/5/19,运行结果为:,2020/5/19,习题集,2020/5/19,【例1】,运行结果为:,2020/5/19,【例2】见实验教程P66-程序改错。【例3】见实验教程P66-程序填空。【例4】见实验教程P59-程序填空。,2020/5/19,9.4动态数据结构“链表”常用的动态数据结构有链表、树、图等等。特点:需之则有,不需则无,9.4.1链表概述1.什么是链表,顺序存储将逻辑上相邻的数据分配在物理上相邻的存储单元中,数据之间的逻辑关,2020/5/19,通过存储单元的邻接关系来体现;,链接存储将逻辑上相邻的数据分配在物理上离散的存储单元中,然后在每一个存储单元中粘贴一张标有相邻者存储地址的标签,使数据之间的逻辑关系通过地址的链接关系来体现。,2020/5/19,2.链表实例下图表示存放整数11,13,17,19的链表:,head,1079,1153,1286,1390,头结点,末结点,头指针,数据域,指针域,1079,1153,1286,1390,NULL,13,17,19,11,2020/5/19,9.4.2单链表结点的类型定义,数据域:存储数据,指针域:存储后续结点的地址,2020/5/19,单链表结点的类型定义:,struct结构名数据成员表列;struct结构名*指针名;;,head,1079,1153,1286,1390,2020/5/19,【例】定义素数链表的结点类型structprime。,素数链表:,head,要求素数链表结点只包含一个数据成员,因此结点类型可定义为:structprimeintdata;structprime*next;,2020/5/19,【例】定义学生链表的结点类型structstudent。设一个学生记录包括学号、姓名、性别和高考成绩,学生链表的结点类型可定义为:,structstudentlongnum;char*name;charsex;intscore;structstudent*next;,2020/5/19,structstudentlongnum;char*name;charsex;intscore;structstudent*next;,structstudent*p,*q;,p-num=010201;p-name=“倪桂兰”;p-sex=女;p-score=568;,q-num=010202;q-name=“刘宁宁”;q-sex=女;q-score=544;,p-next=q;,2020/5/19,9.4.3动态存储分配函数,1.malloc函数函数原型:void*malloc(unsignedsize)函数功能:在内存的动态存储区中分配一块长度为size字节的连续空间,并返回该存储区域的首地址;若函数调用失败,返回空指针NULL。,2020/5/19,2.calloc函数函数原型:void*calloc(unsignedn,unsignedsize)函数功能:在内存的动态存储区中分配长度为size字节的连续空间n块,并返回该存储区域的首地址。若函数调用失败,就返回空指针NULL。,2020/5/19,3.free函数函数原型:voidfree(void*p)函数功能:释放当前正被指针p所指向的内存区域,将它归还给系统以作它用。,2020/5/19,9.4.4创建链表,创建链表从空表开始,循环地将新结点逐一产生出来,并按预定的链接关系插入到链表中去的过程。,head,2020/5/19,结点插入通常有两种预定关系:“栈”式结构新结点总是从表首插入,使得最先插入到链表中去的结点被挤压到链尾,成为末结点,而最后插入的结点成为链表的头结点;“队列”式结构新结点是从表尾插入;,1)创建“栈”式链表,2020/5/19,设head为链表头指针,p为创建动态结点的工作指针,则:,建空表:headNULL;,创建新结点,并对结点的数据域赋值:p=(结点类型*)malloc(结点长度),head,2020/5/19,新结点进栈:,重复、步骤若干次;,3,NULL,head,p,p-next=head;,head=p;,head,2020/5/19,【例】用上述步骤往链表中插入两个结点:,head,2020/5/19,【例】编写程序,建立一个存储字符及其ASCII码的链表,规定ASCII码的范围为m,n(32mnext;,2020/5/19,重复、步骤若干次,如下所示;,开辟后续新结点:p=(结点类型*)malloc(结点长度);,新结点插入表尾:last-next=p;,2020/5/19,终止链表的延伸:last-nextNULL;,last指针后移至末结点:lastlast-next;,head,last,2020/5/19,9.4.5结点的删除与插入,1.删除结点删除结点解除该结点的链接关系,使之与链表脱钩,再调用free函数收回它的存储空间。,head,2020/5/19,(1)被删结点p为链表首结点,p=head;/*
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 龙口中小学元旦活动方案
- 贫困幼儿六一活动方案
- 杭州中考试题及答案
- 灌肠基础考试题及答案
- 公文特点考试题及答案
- 幼儿园教学教案设计:安全玩沙池
- 设备维护保养周期性计划表工具
- 分级阅读考试题及答案
- 法院培训考试题及答案
- 高中话题作文:科技在我们身边1500字(9篇)
- 花坛景观设计59课件讲解
- 大一开学新生的安全教育
- 2024天津市非全日制用工劳动合同书(官方范本)范文
- 浙江财经大学《统计学》2023-2024学年第一学期期末试卷
- 2023年度新增学位授权审核分析报告
- 医疗机构信息系统安全防护预案
- 汽车维修质量管理及质量保证期制度
- 广州数控GSK 980TDc车床CNC使用手册
- ISO27001信息安全管理体系培训资料
- 2024年桑黄菌项目可行性研究报告
- 公转私借款合同书模板
评论
0/150
提交评论