《C语言程序设计2课件》由会员分享,可在线阅读,更多相关《C语言程序设计2课件(240页珍藏版)》请在金锄头文库上搜索。
1、C语言程序设计2C语言程序设计2第第5章章数数组组从前面几章所介绍的内容可以看到,我们在进行程序设计时仅涉及C语言的基本数据类型。在实际应用过程中仅仅有基本数据类型是远远不够的,为了解决这一矛盾,C语言还提供了多种构造数据类型;数组是C语言提供的一种常用的构造数据类型。数组是把具有相同类型的若干变量按有序(指位置上有序)的形式组织起来的同类数据元素的集合,它的每一个元素是由数组名和下标来唯一标识的。C语言程序设计25.1一维数组v根据标识符的定义规则自行确定数组的名称;v确定数组的大小,即数组中元素的个数;v表明数组的基类型,即其元素的类型。在使用一个数组之前,同前面讲到的变量一样必须对它先行
2、定义。一般来说,数组的定义语句出现在函数体的开头,它的任务是:C语言程序设计25.1.1维数组的定义当数组中每个元素只带有一个下标时,这样的数组称为一维数组。在C语言中,定义一维数组的一般形式如下:类型说明符数组名常量表达式,;其中,类型说明符是指数组的基类型,也就是每个数组元素的类型。常量表达式是一个其值为正整数的表达式,用来表示该数组含有的元素个数,即定义了数组的大小。例如:longarray20;它表示数组名为array,该数组有20个long型元素,它们是array0、array1、array2array19。在定义一维数组时要注意以下几点:C语言程序设计2v数组名的命名规则遵守标识符
3、的命名规则。v常量表达式指出数组的长度,长度为n时,数组元素下标只能从0到n-1,即数组中第一个元素的下标是0,数组中的最后一个元素的下标应该是n-1(称为数组下标的上界)。v常量表达式可以包含常量和符号常量,但不能包含变量。也就是说,不允许对数组的大小作动态的改变。例如:C语言程序设计2intn=20;intan;此种定义形式是错误的,因为n是变量而不是常量。v在一个定义数组的语句中,可以有多个数组说明符,它们之间用逗号隔开。例如:floats10,t20,w30;以上语句定义了三个分别名为s、t、w的单精度(即float)类型数组,其中数组s包含10个元素,数组下标的上界为9;数组t包含2
4、0个元素,数组下标的上界为19;数组w包含30个元素,数组下标的上界为29。C语言程序设计25.1.2一维数组元素的引用数组定义好之后,便可使用它了。但是,数组是一种构造类型,它的使用与简单类型的使用是不一样的。语言中数组名实质上是数组的首地址,是一个常量地址,不能对它进行赋值,因而不能利用数组名来整体引用一个数组,只能单个地使用数组元素。数组元素的描述与引用是由数组名加方括号中的下标组成。C语言程序设计2v其中下标可以是整型常量、整型变量或整型表达式,要求变量和表达式要有确定的值,并且其起始值最小为0,最大为元素总个数减1。例如:varray3=array2+array1+array2-2v
5、一个数组元素实质上等同于一个变量,代表内存中的一个存储单元。它具有和相同类型单个变量一样的属性,可以对它进行赋值和参与各种运算。一个数组占有一串连续的存储单元,而变量即使连续定义,其存储位置不一定连续。v在C语言中,数组作为一个整体,不能参与运算,只能对单个的元素进行处理。一维数组元素的引用方式为:数组名下标说明:C语言程序设计2注意:在引用时,下标不要超过数组的范围。例如,array数组的长度为5,则下标值只能在04之间。特别需要强调的是,由于C语言对程序设计的语法限制不太严格,所以C编译不作下标越界检查,即使引用array5,编译时系统也不会提示错误,是把array4后面的一个单元中的内容
6、作为array5来引用,如图5.1所示。而array4后面的单元并不是我们想要引用的数组元素,如果我们对其进行修改,有可能会造成数组以外的其他变量的值无法使用。所以,必须保证使用的下标值在数组定义的范围内。C语言程序设计212345array0array1array2array3array4array5图5.1一维数组元素的引用C语言程序设计25.1.3一维数组的初始化变量在定义的同时可以进行初始化,数组也可在定义的同时对其各元素指定初始值,即初始化。一维数组的初始化有以下几种方式:C语言程序设计2v对数组的全部元素赋初值。例如:staticintnum51,2,3,4,5;用花括号把要赋给各
7、元素的初始值括起来,数据之间用逗号分隔。关键字static是“静态存储”的含义,可以省略,但意义不同,对于静态存储将在第6章介绍。该语句执行之后有:num0=1,num12,num23,num34,num45。v对数组的部分元素赋初值。例如:intnum5=1,2,3;该语句执行之后有:num01,num12,num23,num30,num40。C语言程序设计2v对数组的全部元素赋初值时,可以省略数组长度说明,c编译系统会根据元素实际个数自行确定。例如:intnum1,2,3,4,5;该语句执行之后num数组的长度自动确定为5,并有:num01,num12,num23,num34,num45。
8、若定义数组长度大于元素个数,则不能省略数组长度的定义。C语言程序设计25.1.4一维数组应用举例例5.1建立一个存放10个数据的数组,假设数组元素值为此数组元素下标的10倍,然后将全部元素按正序和逆序分别输出。本例的程序如下:#includevoidmain()C语言程序设计2inti,a10;/*定义一个整型变量i和一个具有十个元素的数组a*/for(i=0;i10;i+)ai=i*10;/*通过for循环确定数组元素的值*/for(i=0;i=0;i-)printf(%5d,ai); /*通过for循环倒序输出数组元素的值*/C语言程序设计2printf(n);/*为了输出时格式清晰,程序
9、控制换一行*/运行结果如下:01020304050607080909080706050403020100例5.2从键盘任意输入10个整数,求它们中的最大值、总和和平均值。本例的程序如下:C语言程序设计2#includevoidmain()inti,a10,sum=0,max;floatave;printf(input10number:n);for(i=0;i10;i+)scanf(%d,&ai);max=a0;/*假设第一个元素最大*/for(i=0;imax)max=ai;/*求最大值*/sum+=ai;/*求总和*/ave=sum/10.0;/*求平均值*/printf(max=%d,su
10、m=%d,ave=%fn,max,sum,ave);运行结果如下:input10number:77879468725690648285max=94,sum=698,ave=69.800003C语言程序设计2例5.3用一维数组计算Fibonacci数列的前20项。Fibonaccti数列有如下特点:第1,第2两个数为1,1。从第3个数开始,该数是其前面两个数之和。数列定义如下:f(1)1(n=1)f(2)1(n=2)f(n)=f(n-1)+f(n-2)(n3)思考一下:在求平均值时,若写成ave=sum/10,结果会有怎样变化?C语言程序设计2由于数组的下标从0开始,为了符合人们的习惯,只用12
11、0,这里定义一个有21个元素的数组f21,而f0没有使用。本例的程序如下:#includevoidmain()intf21,i;f1=1;f2=1;for(i=3;i=20;i+)fi=fi-1+fi-2;for(i=1;i=20;i+)C语言程序设计2if(i-1)%5=0)printf(n);/*5个数据换行*/printf(%10d,fi);本程序的执行结果如下:11235813 21 345589 1442333776109871597258441816765思考一下,如果想求Fibonaccti数列的前40项,程序该如何修改?C语言程序设计2例5.4判定用户输入的正整数是否为“回文数
12、”。所谓回文数是指正读反读都相同的数。把用户输入的数的各位数字分离出来进行比较。本例的程序如下:#includevoidmain()inta10,i,k=0,b;longnumber,n;printf(输入一正整数:);scanf(%ld,&number);n=number;C语言程序设计2do/*利用循环分离正整数的各位数字*/ak+=n%10;/*把分离出来的数字放在定义好的数组中*/n=n/10;while(n!=0);b=1;/*设定标志用以判定该数是否为回文数*/for(i=0;i=(k-1)/2;i+)if(ai!=ak-1-i)b=0;/*标志变量被赋值为0*?if(b)/*若b
13、不等于0*?printf(%ldn是回文数,number);else/*若b等于0*/printf(%ldn不是回文数,number);C语言程序设计2本程序的两次执行结果如下:输入一正整数:12343211234321是回文数输入一正整数:123321123321是回文数输入一正整效:1234562112345621不是回文数例5.5输入任意10个数,对其进行从小到大排序。方法1:用起泡排序法。起泡排序是将相邻的两个数进行比较,若为逆序,则将两个数据交换。小的数据就好像水中气泡逐渐向上漂浮,大的数据好像石块往下沉。如图5.2所示。C语言程序设计249383838383838383838384
14、949494949494949496464646464646464646496969696757575757575757575759613131313131313131313962727272727272727272796525252525252525252529634343434343434343434962222222222222222222296第1趟 第2趟 第3趟 第4趟 第5趟 第6趟 第7趟 第8趟 第9趟 结果图5.2起泡排序C语言程序设计2若有10个数,第1次将49和38交换,第2次将49和64交换共进行9次,得到38、49、64、75、13、27、52、34、22、96的顺
15、序。经过这样的交换,则最大的数96已经像石块一样沉到底,为最下面的一个数,而小数像水中气泡一样向上浮起到一个位置。经过第一趟(共9次)比较后,得到最大的数96。然后进行第二趟(共8次)比较,得到一个次大的数75,依次进行下去,对余下的数按上面的方法进行比较,共需要9趟。如果有n个数,则要进行n-1趟比较。在第一趟中要进行n-1次比较,在第j趟进行n-j次比较。C语言程序设计2程序如下:#includevoidmain()intdata10;/*定义一个一维整型数组data*/inti,j,temp;/*定义循环变量和临时变量*/printf(Pleaseinput10numbers:n);fo
16、r(i=0;i10;i+)scanf(%d,&datai);C语言程序设计2/*冒泡法排序*/for(i=0;i10-1;i+)/*外循环:控制比较趟数*/for(j=0;jdataj+1)/*如果dataj大于dataj+1,交换两者的位置*/temp=dataj;dataj=dataj+1;dataj+1=temp;printf(ntheresultofsort:n);/*输出排序后的数据*/C语言程序设计2for(i=0;i10;i+) printf(%d,datai);本程序的执行结果如下:Pleaseinput10numbers:49386496751127523422theresu
17、ltofsort:11222734384952647596方法2:用选择排序法。选择排序法是从10个数据中找出最小数与第1个元素值交换,在后9个数据中找出最小数与第2个元素值交换在后2个数据中找出最小数与第9个元素值交换,即每比较一次,找出一个未排序数中的最小值。共比较9轮,如图5.3所示。C语言程序设计2values0values0values0values0values0values0values0values0values0values04938649675112752342211386496754927523422112264967549275234381122273438495264
18、96751122273438495264967511222734384952647596图5.3选择排序C语言程序设计2程序如下:#includevoidmain()intvalues10,i;/*定义一个一维整型数组values*/inttemp,current,j;/*定义循环变量和临时变量*/printf(Pleaseinput10numbers:n);for(i=0;i10;i+)scanf(%d,&valuesi);for(current=0;current10;current+)/*选择法排序*/C语言程序设计2for(j=current+1;jvaluesj)temp=value
19、scurrent;valuescurrent=valuesj;valuesj=temp;printf(ntheresultofsort:n);/*输出排序后的数据*/for(i=0;i10;i+)printf(%d,valuesi);C语言程序设计2本程序的执行结果如下:Pleaseinput10numbers49386496751127523422theresultofsort:11222734384952647596 需要特别说明的是:以上两个排序程序并不是最优化的,在掌握上述程序之后,有兴趣的读者可以对上述两个程序分别进行优化。C语言程序设计25.2二维数组和多维数组前面介绍的数组只有一
20、个下标,称为一维数组,其数组元素也称为单下标变量。在实际问题中有很多量是二维的或多维的,因此语言允许构造多维数组。多维数组元素有多个下标,以标识它在数组中的位置,所以也称为多下标变量。本小节只介绍二维数组,多维数组可由二维数组类推而得到。二维数组类型说明二维数组类型说明的一般形式是:5.2.1二维数组和多维数组的定义C语言程序设计2类型说明符数组名常量表达式1常量表达式2;其中常量表达式1表示第一维下标的长度,常量表达式2表示第二维下标的长度。例如:intarray35;说明了一个三行四列的数组,数组名为array,其下标变量的类型为整型。该数组的下标变量共有35个,即下面15个元素(注意括号
21、中的数值的范围):array00,array01,array02,array03,array04array10,array11,array12,array13,array14array20,array21,array22,array23,array24C语言程序设计2二维数组在概念上是二维的,即是说其下标在两个方向上变化,下标变量在数组中的位置也处于一个平面之中,而不是象一维数组只是一个向量。但是,实际的硬件存储器却是连续编址的,也就是说存储器单元是按一维线性排列的。如何在一维存储器中存放二维数组,可有两种方式:一种是按行排列,即放完一行之后顺次放入第二行。另一种是按列排列,即放完一列之后再顺
22、次放入第二列。在语言中,二维数组是按行排列的。按行顺次存放,先存放array0行,再存放array1行,最后存放array2行。每行中有四个元素也是依次存放。由于数组array说明为int类型,该类型占两个字节的内存空间,所以每个元素均占有两个字节。C语言程序设计2值得说明的是:可以把array看作是一个有3个元素的一维数组,而每个一维数组中的元素又是一个大小为5的一维数组。如图5.4所示,即定义了一个35(3行5列)的二维数组array。array012345array1678910array21112131415图5.4二维数组的含义C语言程序设计2定义二维数组时要注意以下几点:v二维数组
23、中元素的顺序是按行存放,即在内存中先顺序存放第一行的元素,再存放第二行的元素,依此类推。如图5.5所示。v从二维数组的排列顺序可以计算数组元素在数组中的顺序号。假设为nm的二维数组,其中第i行第j列元素在数组中的位置公式为im+j+1。v二维数组可看成是一个特殊的一维数组,它的元素又是一维数组。v多维数组的定义与二维数组的定义相似。例如:C语言程序设计2intarray232;定义了一个三维数组array,array是含有2个元素的二维数组,array的每个元素是含有3个元素的一维数组,而array的每个元素中的元素是含有2个整数,则array中共包括23212个整型元素,结构如图5.6所示。
24、其在内存中的排列如图5.7所示。图5.5二维数组元素存放顺序C语言程序设计2array0array00array10array20array01array11array21array1array00array10array20array01array11array21图5.6三维数组的含义C语言程序设计2array000array001array010array011array020array021array100array101array110array111array120array121图5.7三维数组元素存放顺序C语言程序设计2可以看到,第三维的下标变换得最快,其次为第二维的下标,最慢
25、的是第一维的下标。注意:对于初学者而言,掌握到二维数组就可以了。5.2.2二维数组和多维数组的引用数组必须先定义,然后才能使用。二维数组元素的引用方式为:数组名下标下标其中:下标可以是整型常量、变量或整型表达式,但每一维的下标值都不能超过定义时的范围。例如:C语言程序设计2array2-12但要区别定义数组array23和引用array23的含义,前者表示定义数组的维数和各维的大小,后者array23中的2和3是下标值,array23形式上代表某一个元素,但对于给定定义intarray23而言,引用array23时是不合法的。多维数组的引用方式和二维数组元素的引用方式相似。例如:array12
26、0注意每一维的下标都用方括号括起来,每一维的下标值都不能超过定义时的范围。C语言程序设计25.2.3二维数组和多维数组的初始化二维数组的初始化有如下几种方式:(1)对数组的全部元素赋初值,分以下几种情况分行给二维数组赋初值,例如:把第一个花括弧内的数据赋给第一行元素,把第二个花括弧内的数据赋给第二行元素依次按行赋值。该语句执行之后有:varray001,array012,array02=3,varray104,array115,array12=6,C语言程序设计2v按数组在实际存储时的排列顺序赋初值,例如:vintarray231,2,3,4,5,6;v该语句执行之后有:varray001,a
27、rray012,array02=3,varray104,array115,array12=6,v允许省略第一维长度的说明,但第二维的长度不能省。例如:vintarray31,2,3,4,5,6;varray001,array012,array02=3,varray104,array115,array12=6,C语言程序设计2v分行给二维数组部分元素赋初值时,也可以省略第一维长度的说明,但第二维的长度不能省。例如:vintarray31,2,4,5;v该语句执行之后,系统会根据内部花括号的个数确定为2行。并且未被赋值的元素自动赋0值,因此有:varray001,array012,array02=
28、0,varray104,array115,array12=0,v多维数组的初始化和二维数组的初始化相似。C语言程序设计2v三维数组的初始化有如下几种方式:v分行给三维数组赋初值,例如:vintarray232=1,2,3,4,5,6,7,8,9,10,11,12;v把array看作是两个二维数组,每个二维数组是3行2列,按每个二维数组按行赋初值的方法,分别用花括号把各行元素值括起来,再将第三行的初值再用花括号括起来。v按数组在存储时的排列顺序赋初值,例如:vintarray232=1,2,3,4,5,6,7,8,9,10,11,12;C语言程序设计2v允许省略第一维长度,例如:vintarra
29、y32=1,2,3,4,5,6,7,8,9,10,11,12;v系统自动算出第一维的大小为2,但第二维和第三维不能省。C语言程序设计25.2.4二维数组和多维数组的举例v例5.6输入一个33的矩阵,分别计算并输出矩阵主对角线和周边元素的和。v本例的程序如下:#includevoidmain()inta33,sum1=0,sum2=0,i,j;printf(PleaseinputA:n);/*输入矩阵A*/for(i=0;i3;i+)for(j=0;j3;j+)C语言程序设计2scanf(%d,&aij);printf(caculatesumofcatercornerandaround:n);f
30、or(i=0;i3;i+)for(j=0;j3;j+)if(i=j)sum1+=aij;/*计算矩阵A对角线元素之和*/if(i=0|j=0|i=2|j=2)/*计算矩阵A周边元素之和*/sum2+=aij;printf(sum1=%5d,sum2=%5dn,sum1,sum2);C语言程序设计2v运行结果如下:PleaseinputA:123456789caculatesumofcatercornerandaround:sum1=15,sum2=40例5.7向三维数组中输入值并输出此数组中的元素值。本例的程序如下:#includevoidmain()inta232,i,j,k;C语言程序设计
31、2vprintf(PleaseinputAn);/*输入三维数组A*/for(i=0;i2;i+)for(j=0;j3;j+)for(k=0;k2;k+)scanf(%d,&aijk);printf(PleaseoutputAn);/*输出三维数组A*/for(i=0;i2;i+)for(j=0;j3;j+)for(k=0;k2;k+)printf(a%d%d%d=%dn,i,j,k,aijk);C语言程序设计2v运行结果如下:PleaseinputA123456789101112PleaseoutputAa000=1a001=2a010=3a011=4a020=5C语言程序设计2a021=6
32、a100=7a101=8a110=9a111=10a120=11a121=12v例5.8求一个44矩阵的次对角线元素之积。本例的程序如下:C语言程序设计2#includevoidmain()inta44=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,i,j;ints=0;/*设定累加和变量并设初值为0*/for(i=0;i4;i+)for(j=0;j4;j+)if(i+j=3)s*=aij;printf(s=%dn,s);运行结果如下:s=34C语言程序设计2例5.9编写一个程序统计某班3门课程的成绩,它们是语文、数学和英语。先输入学生人数,然后按从小到大的编号
33、顺序依次输入学生成绩,最后统计每门课程全班的总成绩、平均成绩以及每个学生课程的总成绩和平均成绩。依题意,本程序定义一个二维数组score505。scorei0、scorei1、scorei2分别存储3门课程的分数,scorei3和scorei4分别存储计算出来的个人总分和平均分。total3和avg3分别存储全班各科总分和平均分,本例程序如下:C语言程序设计2v#includevvoidmain()vvintscore505,total3,avg3;vinti,j,n;vprintf(学生人数:);vscanf(%d,&n);/*输入小于50的数*/vprintf(输入成绩n);vfor(i=
34、0;in;i+)vvprintf(第%5d个学生:,i+1);C语言程序设计2vscanf(%d%d%d,&scorei0,&scorei1,&scorei2);vvfor(i=0;in;i+)vvscorei3=0;vfor(j=0;j3;j+)vscorei3+=scoreij;vscorei4=scorei3/3;vvfor(j=0;j3;j+)C语言程序设计2vvtotalj=0;vfor(i=0;in;i+)vtotalj+=scoreij;vavgj=totalj/n;vvprintf(n编号语文数学英语总分平均分n);vfor(i=0;in;i+)C语言程序设计2vvprintf
35、(%5d,i+1);vfor(j=0;j5;j+)vprintf(%7d,scoreij);vprintf(n);vvprintf(总分:);vfor(i=0;i3;i+)vprintf(%7d,totali);vprintf(n平均分:);C语言程序设计2vprintf(总分:);vfor(i=0;i3;i+)vprintf(%7d,totali);vprintf(n平均分:);vfor(i=0;icompare,A0)vprintf(buffer2isgreaterthanbuffer1n);velsevprintf(buffer2islessthanbuffer1n);C语言程序设计2v
36、ptr=strcmp(buf2,buf3);vif(ptr0)vprintf(buffer2isgreaterthanbuffer3n);velsevprintf(buffer2islessthanbuffer3n);vv输出:输出:vbuffer2isgreaterthanbuffer1vbuffer2islessthanbuffer3v说明:说明:v两个字符数组不能直接比较大小,两个字符数组不能直接比较大小,应使用应使用strcmp()函数。例如:函数。例如:vif(str1str2)printf(“1”);是不正是不正确的,应改为:确的,应改为:vif(strcmp(str1,str2)
37、0)printf(1);v5.strlen(字符数组)测试字符串长度函数v功能:统计字符串中字符的个数。功能:统计字符串中字符的个数。返回字符数组中包含的字符串的返回字符数组中包含的字符串的实际长度,不包括实际长度,不包括“0”在内。在内。C语言程序设计2v例5.13v#include“string.h”vvoidmain()vvchars=tv0willn;vprintf(%dn,strlen(s);vv输出:3v6.strlwr(字符串)字符串小写函数v功能:将字符串中的大写字母转换成小写字母。v7.strupr(字符串)字符串大写函数v功能:将字符串中的小写字母转换成大写字母。v以上介绍
38、的几种常用的字符串处理函数都是C语言所提供的库函数,不需要用户再来编写这些函数,但这些库函数的说明都包含在头文件string.h中,如果要在程序中使用这些库函数,则需在程序的开头加入:#includev初学者需要注意:应牢固掌握以上这些函数的功能和用法,并学会自己动手编写这些函数。C语言程序设计25.3.4字符数组的举例字符数组的举例v本例的程序如下:v#includev#includevvoidmain()vvchars120,s220,ch1,ch2;vintm;vprintf(String:);vgets(s1);vprintf(Old,Newcharis:);vscanf(%c,%c,
39、&ch1,&ch2);vfor(m=0;(s1m!=0);m+)vif(s1m=ch1)vs2m=ch2;velsevs2m=s1m;vs2m=0;vprintf(EndString:%sn,s2);vC语言程序设计2v本程序的执行结果如下:vString:evenvOld,Newcharis:n,rvEndString:everC语言程序设计2v例5.15判定一个字符串是否是另一个字符串的子串的程序。v本例的程序如下:v#includev#includevvoidmain()vintm,n,k,index=0;vchars120,s220;vprintf(String:);vgets(s1)
40、;vprintf(SubString:);vgets(s2);vfor(m=0;s1m!=0;m+)vvfor(n=m,k=0;s1n=s2k;n+,k+)vif(s2k+1=0)vvindex=m+1;vbreak;vvif(index!=0)vbreak;vvprintf(index=%dn,index);vC语言程序设计2v本程序的执行结果如下:v第一次运行:vString:youareastudent.vSubString:arevindex=5v第二次运行:vString:youareastudent.vSubString:stdvindex=0C语言程序设计2v匹配过程如图5.13
41、所示。v第1次vyouareastudent.0are0第2次vyouareastudent.0are0vv第5次vyouareastudent.0are0图5.13字符串匹配过程C语言程序设计2例例5.16密码检测。密码检测。v本例的程序如下:本例的程序如下:v#includev#includev#includevvoidmain()vcharpass_str80;/*定义字符数组定义字符数组passstr*/vinti=0,flag=1;v/*检验密码检验密码*/vwhile(flag)vvprintf(请输入密码请输入密码n);vgets(pass_str);/*输入密码输入密码*/vi
42、f(strcmp(pass_str,password)!=0) /*输入的字符串输入的字符串不等于不等于password*/vprintf(口令错误,按任意键继续口令错误,按任意键继续n);vgetch();/*输入任意字母输入任意字母*/C语言程序设计2velsevflag=0;/*输入正确的密码,中止循环*/vi+;vif(i=3)printf(您是非法用户,强行退出!);exit(0);v/*连续输入三次错误密码,退出程序*/vvprintf(口令正确,按任意键继续);getch();v/*其他语句*/*输入正确密码所进入的程序段*/vv本程序的执行结果如下:v请输入密码vpassv口令
43、错误,按任意键继续vpasswordv口令正确,按任意键确认vprintf(%-15s%-15s%-15sn,numm,namem,telm);vC语言程序设计2例5.17创建一个通讯录。v本例的程序如下:v#includev#includevvoidmain()vvintm;vcharnum310,name310,tel310;vfor(m=0;m3;m+)vvprintf(n请输入第%d个记录:n,m+1);vprintf(学号:);vgets(numm);vprintf(姓名:);vgets(namem);vprintf(电话:);vgets(telm);vvprintf(学号 姓名 电
44、话n);vfor(m=0;m3;m+)C语言程序设计2v请输入第请输入第1个记录:个记录:v学号:学号:123 v姓名:姓名:zhangsan v电话:电话:123123123 v请输入第请输入第2个记录:个记录:v学号:学号:456 v姓名:姓名:lisi v电话:电话:456456456 v请输入第请输入第3个记录:个记录:v学号:学号:789 v姓名:姓名:wangwu v电话:电话:789789789 C语言程序设计2学号学号 姓名姓名电话电话123zhangsan123123123456lisi456456456789wangwu 789789789C语言程序设计2本本章章小小结结v
45、本章我们分别详细介绍了一维数组、二维数组、字符数组的定义和引用方法。还简要介绍了字符串的意义和字符串处理函数。v数组是相同类型元素的集合,数组中的每一个元素均由数组名和下标来惟一标识的。v把已定义的数组类型作为基类型,再构造出数组的数组,即为多维数组。多维数组中元素的存储顺序是:按行存放。v对数组的赋值可以用数组初始化赋值,输入函数动态赋值和赋值语句赋值三种方法实现。对数值数组不能用赋值语句整体赋值、输入或输出,而必须用循环语句逐个对数组元素进行操作,但字符数组例外。v在定义数组的同时对数组的全部元素赋初值时,也可不指定数组长度,系统默认的长度就是初值个数,用字符串初始化字符数组时默认的长度是
46、字符个数+1。C语言程序设计2vC语言规定以语言规定以“0”作为字符串的结束标志。作为字符串的结束标志。vC语言没有字符串变量,字符串不是存放在一个变量中而是语言没有字符串变量,字符串不是存放在一个变量中而是存放在一个字符数组中。字符串通常是作为整体被输入和输存放在一个字符数组中。字符串通常是作为整体被输入和输出。其他类型的数组则不能作为整体进行输入和出。其他类型的数组则不能作为整体进行输入和输出。输出。v字符串存放在字符数组中,但字符数组与字符串可以不等长。字符串存放在字符数组中,但字符数组与字符串可以不等长。字符串以字符串以“0”作为结束标志,字符数组不要求其末尾必须作为结束标志,字符数组
47、不要求其末尾必须为为“0”。v字符串的长度是指字符串的实际有效字符的个数。字符串的长度是指字符串的实际有效字符的个数。C语言提语言提供了很多处理字符串的库函数,用户可以直接调用。供了很多处理字符串的库函数,用户可以直接调用。C语言程序设计2习题习题5v以下程序的输出结果是。v#include“stdio.h”vvoidmain()vinta5=0,i;vfor(i=0;i5;i+)ai=i*i;vprintf(“a%d=%d”,i,ai);vv以下程序的输出结果是。v#include“stdio.h”vvoidmain()vinti,a33=1,2,3,4,5,6,7,8,9;vfor(i=0
48、;i3;i+)printf(“%d,”,ai2-i);vC语言程序设计2v3、以下程序的输出结果是、以下程序的输出结果是。v#include“stdio.h”vvoidmain()vinti,k=0,arr10;vfor(i=0;i10;i+)arri=i;vfor(i=0;i6;i+)k+=arri+i;vprintf(“%dn”,k);vv4、以下程序的输出结果是、以下程序的输出结果是。v#include“stdio.h”vvoidmain()vinti,j,k=1,a33=1,2,3,4,5,6,7,8,9;vfor(i=0;i3;i+)vfor(j=0;j3;j+)vif(aij%2=
49、0)k*=aij;vprintf(“%dn”,k);vC语言程序设计2v5、以下程序的输出结果是、以下程序的输出结果是。v#include“stdio.h”vvoidmain()vinti,j,k=1,a33=1,2,3,4,5,6,7,8,9;vfor(i=0;i3;i+)vfor(j=0;j3;j+)vif(aij%2)k*=aij;vprintf(“%dn”,k);vv6、编程实现:输入一行数字字、编程实现:输入一行数字字符,用数组元素作为计数器来统符,用数组元素作为计数器来统计输入的数字字符串中每个数字计输入的数字字符串中每个数字的个数,即的个数,即0的个数放在下的个数放在下标为标为0
50、的元素里,的元素里,1的个数放的个数放在下标为在下标为1的元素里,的元素里,v7、设有一个、设有一个55的方阵,利用输的方阵,利用输入函数动态赋初值后分别计算方入函数动态赋初值后分别计算方阵每行、每列及两对角线上的元阵每行、每列及两对角线上的元素之和。素之和。v8、设有一个二维数组、设有一个二维数组array4=89,56,85,78,69,82,43,-65,84,1,55,23,编程找出数,编程找出数组中最大值、最小值元素及其下组中最大值、最小值元素及其下标。标。C语言程序设计2第6章函数v一个C语言的程序是由一个或多个C语言程序文件组成,一个C语言的程序文件是由一个或多个函数组成的,每个
51、函数负责完成一个特定的操作或功能。一个C语言程序,必须有而且只能有一个名为main的函数,这是整个程序的入口,也就是整个程序的执行起点。利用函数,可以将一些功能上相对独立、可能被重复执行的程序段包装起来,使程序的结构更加模块化。C语言程序设计2第6章函数v在C语言程序设计中,无论多么复杂,规模多么大的程序,最终都落实到一个个简单函数的编写工作上,因此,C语言程序设计的基础工作就是函数的设计和编制。本章讨论的是C语言函数的特点、自定义函数的定义和调用、函数之间传递数据的方法以及递归的概念,本章的最后还将介绍C语言常用的标准库函数。vC语言中的函数分为两类,一类是系统提供的标准函数,又称库函数。标
52、准函数由系统定义,在程序中可以直接使用。另一类是用户自己定义的函数。C语言程序设计2第6章函数v6.1函数的概念v6.2函数的定义和说明v6.3函数调用v6.4函数传递机制v6.5递归v6.6变量的作用域及存储类别v6.7库函数C语言程序设计26.1函数的概念v函数是一个被命名的程序段,通过调用该函数可以多次执行这个程序段。v一个完整的程序是为了完成某个特定的任务而设计的一组指令(语句)。随着程序规模的增大,将语句简单地罗列起来,会使程序的复杂程度过高而难于阅读和维护。v如果将一些功能上相对独立、可能被反复执行的程序段单独提炼出来,用一个名称来代表这段子程序,不仅可以减少总的程序量,而且可以使
53、整个程序的结构更具模块化,更易于阅读和维护。在C语言中就是用函数来描述这样的一段子程序。C语言程序设计2v例6.1vvoidmain()vvincrement();/*调用函数increment*/vincrement();/*调用函数increment*/vincrement();/*调用函数increment*/vvvoidincrement()vvintx=0;vx+=1;vprintf(%dn,x);vC语言程序设计2v程序的运行结果是:1v1v1vincrement是用户定义的函数名,在程序中要反复调用三次,每次执行的结果都是1,通过increment函数的编制,减少了程序的代码,使
54、程序清晰简洁。C语言程序设计26.2函数的定义和说明v6.2.1函数的定义v函数定义就是编写完成函数功能的程序块,也就是确定该函数完成什么功能以及实现步骤,相当于其他语言的一个子程序。v函数定义的一般形式如下:v函数类型函数名形参表列vv声明部分v语句vvC语言程序设计2v其中,用方括号“”包围的部分可以缺省。从格式中看出,函数的定义主要由函数名和用花括号“”包围的函数体两部分组成。用户定义的函数由用户命名。函数名命名规则与变量名相同,这里不再重复。函数名后面的圆括号“()”,无论有无参数都不能省略。C语言程序设计2v函数类型名可以是任何一种合法的数据类型名,表示该函数返回给调用者的结果的数据
55、类型。如果一个函数的功能是用来执行某项操作,无需返回结果,可以用void作为函数类型,表示无返回值。如果在函数定义中没有明确指出函数类型,默认的函数类型为int。C语言程序设计2v形参表可以为空,也可以是由一个或多个形参组成,多个形参之间用逗号分隔。v形参表列的说明格式如下:v形参类型形参名1,形参类型形参名2,v其中参数类型是任何一种合法的数据类型名,参数名是自定义的标识符。形参描述的是函数执行时所需要的数据。C语言程序设计2例6.2计算n!(只带有一个形参)。v#includevlongfactorial(intn)vinti;vlongy=1;vfor(i=1;i=n;i+)vy=y*i
56、;vreturn(y);vvmain()vvintn;vprintf();vscanf(%d,&n);vprintf(n!=%dn,factorial(n);vC语言程序设计2v程序的运行结果如下:vn=5(下划线的值为用户输入的值)vn!=120v在Turbo环境下,如果把函数类型定义为int型,在n8时程序的结果就会出错,而在Vc+环境下结果正常;请读者分析一下原因。C语言程序设计2v例6.2中定义了一个名为factorial的有参函数,该函数带有一个整型的形参,并返回一个长整型的结果值。factorial函数的功能是计算形参n的阶乘,n值由主函数传过来。C语言程序设计2v例6.3编写一个
57、打印一排“*”的函数(不带有任何形参)。vvoidmain()vprintstar();vvprintstar()vvprintf(n*);vv程序的运行结果如下:v*C语言程序设计2v例6.3中定义了一个名为printstar的无参函数,在调用无参函数时,主调函数并不将数据传送给被调用函数,而是执行指定的一组操作,此例中printstar的作用是输出15个星号。无参函数一般不需要带回函数值,因此可以不写函数类型名,但是应提倡无返回值时将函数类型定义为void,有返回值时将函数类型定义为相应类型。C语言程序设计2v注意:在C语言中,函数的定义是不允许嵌套的,就是说不允许在一个函数内部再去定义一
58、个函数。例如,下列程序段是错误的:vf1()vinta,b;vf2(a,b);vvf2(intx,inty)vvreturn(x+y);vvC语言程序设计2v因为在函数f1()的函数体内,不允许定义f2()函数,定义f2()函数应该放在f1()函数体外。v在C语言程序中,有许多定义可以嵌套,如宏定义、类型定义、结构体定义等等,惟独函数定义不能嵌套。C语言程序设计26.2.2函数声明v函数声明是对所用到的函数的特征进行必要的声明。编译系统以函数声明中给出的信息函数名、函数类型、函数参数的个数、类型及排列顺序等为依据,对调用表达式进行检测,以保证调用表达式与函数之间的参数正确传递。v函数声明的一般
59、格式为:v函数类型函数名(形参类型形参名,形参类型形参名,);C语言程序设计2v类似于函数定义中的第一行(称函数头)的内容,也称函数原型,主要区别是:v句末再加一个分号;v形参名可以省略。v不能只写形参名而不写函数的类型C语言程序设计2v例如假设有一个函数的定义为:vfloatadd(floatx,floaty)vv/*函数体*/vv与之对应的函数声明应为:vfloatadd(floatx,floaty);或floatadd(float,float);(注意末尾的分号)C语言程序设计2v例6.4分析以下程序的执行结果。v#includevvoidmain()vvfloatf;vf=func()
60、;vprintf(%fn,f);vvfunc()/*被调用函数的首部*/v/*函数体*/vreturn12.4;vC语言程序设计2v该程序的执行结果不是12.400000,而是12.000000。因为func函数没有指定返回类型,按照规则,默认的返回类型为int型,因此尽管return语句中的返回值为12.4,实际的返回值为12。改正的方法是在程序中增加函数的说明语句,另外在被调用函数的首部增加float,见例6.5。C语言程序设计2v例6.5v#includevmain()vvfloatfunc();/*被调用函数的说明*/vfloatf;vf=func();vprintf(%fn,f);v
61、vfloatfunc()vvreturn12.4;vv程序运行结果为:12.400000C语言程序设计2v此外,C语言还规定,在以下几种情况下可以不在调用函数前对被调用函数作类型说明。v如果被调用函数的定义出现在主调函数之前或被调用函数的定义出现在主调函数之后,但返回值类型为整型,可以不必加以说明。因为编译系统已经先知道了定义的函数类型,会自动处理的。C语言程序设计2v例如,把例6.5改写如下(把main函数放在func函数的下面):v#includevfloatfunc()vvreturn12.4;vvmain()vvfloatf;vf=func();vprintf(%fn,f);vv这样在
62、main函数就不必对func进行说明。C语言程序设计2v如果一个函数要被一个文件中的多个函数调用时,可以将该函数的声明写在所有函数之前,则在各个主调函数中不必对所调用的函数再作类型说明。例如:vfloatf(floatx,inty);/*放在所有函数之前,作统一声明*/vmain()vvvvfun1()vvf(a,b);/*调用f函数,在此函数中不必对f作函数声明*/vvvfun2()vvf(a,b);/*调用f函数,在此函数中也不必对f作函数声明*/vvvfloatf(floatx,inty)vvvC语言程序设计26.3函数调用v在一个函数中调用另一个函数时,程序控制就从调用函数中转移到被调
63、用函数,并且从被调用函数的函数体起始位置开始执行该函数的语句。在执行完函数体中的所有语句,或者遇到return语句时,程序控制就返回调用函数中原来的断点位置继续执行C语言程序设计21.函数调用的一般形式vC语言函数调用的一般格式:v函数名(实参表);v实参表中实参的个数多于1个时,各参数之间用逗号分隔。实参的个数、类型必须与对应的形参一致,否则编译程序往往并不报错,最终可能导致一个不期望的、无法理解的错误结果。C语言程序设计2v例6.6阅读下列程序,观察程序的调用过程。v#includevmain()vvinta=1,b=2,c;vc=max(a,b);vprintf(maxis%dn,c);
64、vvmax(intx,inty)vintz;vz=(xy)?x:y;vreturnz;vv程序的运行结果如下:vmaxis2v该程序的调用过程如图6.1所示。C语言程序设计2图6.1 函数调用过程C语言程序设计2v例6.7阅读程序,观察函数的调用过程。vmain()v图6.1函数调用过程vvincx();vincy();vincx();vincy();vincx();vincy();vvC语言程序设计2vinch()vintx=0;vprintf(x=%dt,+x);vvincy()vinty=0;vprintf(ny=%dn,+y);vC语言程序设计2v程序的运行结果如下:vx=1vy=1v
65、x=1vy=1vx=1vy=1v此程序的调用过程由读者自己完成C语言程序设计22.函数的三种调用方式v当所调用的函数用于求出某个值时,函数的调用可作为表达式出现在任何允许表达式出现的地方。例如:可用以下max函数求出a,b的最大值,然后乘以5,计算的结果赋给c。vc=max(a,b)*5;C语言程序设计2vC语言中的函数可以仅进行某些操作而不返回函数值,这时函数的调用可作为一条独立的语句。例如:上例中的incx()函数。C语言程序设计2v函数作为另一个函数调用的实际参数出现。这种情况是把该函数的返回值作为实参进行传送,因此要求该函数必须是有返回值的。例如:printf(%d,max(x,y);
66、即是把max调用的返回值又作为printf函数的实参来使用的。C语言程序设计23.函数的返回值v函数的返回值是由return语句传递的。return语句的一般形式为vreturn(表达式);或return表达式;C语言程序设计2v说明:v一个函数中可以有多个return语句,当执行到某个return语句时,程序的控制流程返回调用函数,并将return语句中表达式的值作为函数值带回。v若函数体内没有return语句,就一直执行到函数体的末尾,然后返回调用函数。这时也有一个不确定的函数值被带回。C语言程序设计2vreturn语句中表达式的类型应与函数类型一致。若不一致时,则以函数类型为准,并由系统
67、按赋值兼容的原则进行处理v若确实不要求带回函数值,则应将函数定义为void类型。C语言程序设计24.函数的嵌套调用vC语言不将函数定义在另一个函数体中,但允许在调用一个函数的过程中同时调用另一个函数。这种调用称为函数的嵌套调用。例如,f1和f2是分别独立定义的函数,互不从属,但在调用f1的过程中又要调用函数f2。其调用过程如图6.2所示。C语言程序设计2图6.2函数的嵌套调用过程C语言程序设计2v图6.2中为调用过程的步骤,即:v将流程转到f1函数,实参i、t分别传值给形参a、b;v执行f1函数体中语句直到遇到调用f2的语句为止;v调用f2函数,将f1函数中的数据b-l,b+l作为f2函数的实
68、参传送给f2函数的形参;C语言程序设计2v执行f2函数;v将f2函数的返回值带回f1函数中的调用处(即带回到调用函数表达式处);v继续执行f1函数中剩下的语句;v将f1函数的返回值带回main函数中,并赋给变量u。C语言程序设计2v下面举一个关于函数嵌套调用的例子。在main()函数中调用fun1函数,而在fun1函数中又调用fun2函数。该程序内容如下:vfun1(inta,intb)vintc;va+=a;b+=b;vc=fun2(a,b);vreturnc*c;vvfun2(inta,intb)vintc;vc=a*b%3;vreturnc;vC语言程序设计2vvmain()vvintx
69、=11,y=19;vprintf(%dn,fun1(x,y);vv程序的运行结果是:v4v在fun1和fun2两个函数中,虽然它们的形参名相同,但初学者应注意这有点像两个人重名一样,这里也是代表不同的变量,这一问题将在下一节进行讨论。C语言程序设计26.4函数传递机制v1.函数的形参与实参v在调用函数时,函数的参数称为实参。实参可以是常量、变量或表达式,在函数调用时若是表达式则先计算表达式的值。实参的含义是该参数的值,是确定的、确实存在的。v在定义函数时,函数的参数称为形参,又称形式参数,在函数未被调用时,系统不给形参分配内存空间,只有在发生函数调用时,形参才被分配内存空间,同时接受实参传递过
70、来的值。形参属于局部变量,它的作用范围在定义它的函数体内。出了定义它的函数体之外,形参将不存在。C语言程序设计2v2.函数的传递机制vC语言规定:实参与形参之间只有“按值”传送一种传送方式。即实参的值可以传给形参,形参的值不能传给实参。也就是说当简单变量作为实参时,用户不能在函数中改变对应实参的值。C语言程序设计2v例6.8以下程序示例了函数之间的单向传递,观察程序的执行结果。vmain()vvintx=2,y=3,z=0;vprintf(1)x=%dy=%dz=%dn,x,y,z);vtry(x,y,z);vprintf(4)x=%dy=%dz=%dn,x,y,z);vvtry(intx,i
71、nty,intz)vvC语言程序设计2vprintf(2)x=%dy=%dz=%dn,x,y,z);vz=x+y;vx=x*x;vy=y*y;vprintf(3)x=%dy=%dz=%dn,x,y,z);vv程序的运行结果如下:v(1)x=2y=3z=0v(2)x=2y=3z=0v(3)x=4y=9z=5v(4)x=2y=3z=0C语言程序设计2v当程序从main函数开始运行时,按定义在内存中开辟了三个int类型的存储单元x、y、z,且分别赋初值2、3和0,调用try函数之前的printf语句输出结果验证了这些值。当调用try函数之后,程序的流程转向try函数,这时系统为try函数的三个形参x
72、、y、z分配了另外三个临时的存储单元,同时如图6.3(a)所示,实参x、y、z把值传送给对应的形参x、y、z,实参和形参虽然同名,但它们却占用不同的存储单元。C语言程序设计2v当进入try函数后,首先执行一条printf语句,输出try函数中的x、y、z的值,因为未对它们进行任何操作,故仍输出2、3和0。当执行了赋值语句z=x+y;x=x*x;和y=y*y;之后,这时z、x、y存储单元中的值分别为5、4、9,如图6.3(b)所示,这可由随后的printf语句输出结果证实;当退出try函数时,try函数中x、y、z变量所占存储单元将消失(释放)。流程返回到main函数,然后执行main函数中最后
73、一条printf语句,输出了x、y、z的值,由输出结果可见main函数中的x、y、z的值在调用try函数后没有任何变化。v以上程序运行的结果证实了在调用函数时,实参的值将传送给对应的形参,但形参值的变化不会影响对应的实参。C语言程序设计2图6.3参数传递过程C语言程序设计2v例6.9以下程序通过调用swap函数,交换主函数中变量x和y中的数据,观察程序的输出结果。vmain()vvintx=10,y=20;vprintf(1)x=%dy=%dn,x,y);vs);vprintf(4)x=%dy=%dn,x,y);vC语言程序设计2vvsa,intb)vintt;vprintf(2)a=%db=
74、%dn,a,b);vt=a;va=b;vb=t;vprintf(3)a=%db=%dn,a,b);C语言程序设计2v程序的运行结果如下:v(1)x=10y=20v(2)a=10b=20v(3)a=20b=10v(4)x=10y=20v这里,swap函数的功能是交换两个参数的值。但从程序运行结果可以看到:x和y的值已传送给函数swap中的对应形参a和b,在函数swap中a和b也确实进行了交换,但由于在C语言中,数据只能从实参单向传递给形参,形参数据的变化并不影响对应实参,因此在本程序中,不能通过调用swap函数使主函数中x和y的值进行交换。C语言程序设计2v这里,swap函数的功能是交换两个参数
75、的值。但从程序运行结果可以看到:vx和y的值已传送给函数swap中的对应形参a和b,在函数swap中a和b也确实进行了交换,但由于在C语言中,数据只能从实参单向传递给形参,形参数据的变化并不影响对应实参,因此在本程序中,不能通过调用swap函数使主函数中x和y的值进行交换。C语言程序设计2v关于实参与形参的几点说明:v形参与实参各占一个独立的存储空间。形参的存储空间是函数被调用时分配的。调用开始,系统为形参开辟一个临时存储区,然后将各实参之值传递给形参,这时形参就得到了实参的值。在调用结束后,形参所占的临时存储区也被释放。v在函数的传值调用中,要求实参的个数与形参的个数必须相等,并且还要求对应
76、的实参和形参的类型必须相同。如果实参和形参的个数和类型不相同,将会带来麻烦。C语言程序设计2v这些麻烦表现在:v若形参和实参个数不等,一般不报错误,但是结果往往不对。v如果形参和实参类型不一致又无原型说明时,一般不显示错误,但结果不对。如果形参和实参类型不一致但有原型说明时,则编译时显示类型不匹配错误。C语言程序设计2v若形参和实参个数不等,一般不报错误,但是结果往往不对。v如果形参和实参类型不一致又无原型说明时,一般不显示错误,但结果不对。如果形参和实参类型不一致但有原型说明时,则编译时显示类型不匹配错误。C语言程序设计2v用数组名作函数参数与用数组元素作实参有几点不同:v用数组元素作实参时
77、,只要数组类型和函数的形参变量的类型一致,那么作为下标变量的数组元素的类型也和函数形参变量的类型是一致的。因此,并不要求函数的形参也是下标变量。换句话说,对数组元素的处理是按普通变量对待的。C语言程序设计2v用数组名作函数参数时,则要求形参和相对应的实参都必须是类型相同的数组,都必须有明确的数组说明。当形参和实参二者不一致时,即会发生错误。在用数组名作函数参数时,不是把实参数组的每一个元素的值都赋予形参数组的各个元素。因为实际上形参数组并不存在,编译系统不为形参数组分配内存。v那么,数据的传送是如何实现的呢?在上一章中我们曾介绍过,数组名就是数组的首地址。因此在数组名作函数参数时所进行的传送只
78、是地址值的传送,也就是说把实参数组的首地址赋予形参数组名。形参数组名取得该首地址之后,也就等于有了实在的数组。实际上是形参数组和实参数组视为同一数组,共同拥有一段内存空间。C语言程序设计2v上图说明了这种情形。图中设a为实参数组,类型为整型。a占有以2000为首地址的一块内存区。b为形参数组名。当发生函数调用时,进行地址传送,把实参数组a的首地址传送给形参数组名b,于是b也取得该地址2000。于是a,b两数组共同占有以2000为首地址的一段连续内存单元。从图中还可以看出a和b下标相同的元素实际上也占相同的两个内存单元(整型数组每个元素占二字节)。例如a0和b0都占用2000和2001单元,当然
79、a0等于b0。类推则有ai等于bi。C语言程序设计2v从这里我们看到形参数组名接收了一个地址常量,实际上形参数组名的本质是一个指针变量名,这一点有待于我们学完指针那一章再去深刻理解,目前把形参数组和实参数组视为同一数组,只是名字不同罢了。v例6.10分析下面的例子。vmain()vvfloata,b;vfloatadd();vC语言程序设计2va=5.2;vb=8.1;vprintf(%.2fn,add(a,b);vvfloatadd(intx,inty)vvreturn(x+y);vv编译该程序时没有出错信息,但执行后的结果不对,为-16384.00。C语言程序设计2v将上述程序中,floa
80、tadd();语句改为:floatadd(int,int);编译该程序也没有错误信息,执行结果为13.00。v再将上述程序中,floatadd(int,int);语句改为floatadd(float,float);编译时出错,指出类型不匹配。v最后,将add()函数的函数头改为:floatadd(floatx,floaty);执行后,输出如下正确结果:v13.30C语言程序设计2v例6.11数组a中存放了一个学生5门课程的成绩,求平均成绩。vfloataver(floata5)vvinti;vfloatav,s=a0;vfor(i=1;i5;i+)vs=s+ai;vav=s/5;vreturn
81、av;vvvoidmain()vC语言程序设计2vvoidmain()vvfloatsco5,av;vinti;vprintf(ninput5scores:n);vfor(i=0;i5;i+)vscanf(%f,&scoi);vav=aver(sco);vprintf(averagescoreis%5.2f,av);C语言程序设计2v本程序首先定义了一个实型函数aver,有一个形参为实型数组a,长度为5。在函数aver中,把各元素值相加求出平均值,返回给主函数。主函数main中首先完成数组sco的输入,然后以sco作为实参调用aver函数,函数返回值送av,最后输出av值。从运行情况可以看出,
82、程序实现了所要求的功能。C语言程序设计2v例6.12判别一个整数数组中各元素的值,若大于0则输出该值,若小于等于0则输出0值。vvoidnzp(inta,intn)vinti;vprintf(nvaluesofarrayaare:n);vfor(i=0;in;i+)vif(ai0)ai=0;vprintf(%d,ai);vvC语言程序设计2vmain()vintb5,i;vprintf(ninput5numbers:n);vfor(i=0;i5;i+)scanf(%d,&bi);vprintf(initialvaluesofarraybare:n);vfor(i=0;i5;i+)printf(
83、%d,bi);vnzp(b,5);vprintf(nlastvaluesofarraybare:n);vfor(i=0;i0)v由公式可知,求n!可以转化为n(n-1)!,而(n-l)!的解决方法仍与求n!的解法相同,只是处理对象比原来的递减了1,变成了n-1。对于(n-l)!又可转化为求(n-1)(n-2)!,而(n-2)!又可转化为当n=0时,n!=1,这是结束递归的条件,从而使问题得以解决。v根据以上分析,程序如下:vfloatfac(intn)vfloatf;vif(n0)printf(n%cn,getone,putone);vvvoidhanoi(intn,charone,chart
84、wo,charthree)v/*将n个盘从one借助two,移到three*/vC语言程序设计2vif(n=1)move(one,three);velsevhanoi(n-1,one,three,two);vmove(one,three):vhanoi(n-1,two,one,three);vvvmain()vintm;vprintf(inputthenumberofdiskes:);vscanf(%d,&m);vprintf(Thesteptomoving3ddiskes:n,m);vhanoi(m,A,B,C);vC语言程序设计2v程序的运行结果如下:vinputthenumberofdi
85、skes:3vThesteptomoving3diskes:vACvABvCBvACvBAvBCvACv由于篇幅关系,不再对上述程序作过多解释,请读者仔细理解。C语言程序设计26.6变量的作用域及存储类别v6.6.1变量的作用域v作用域是指一个标识符,包括变量名、函数名等,在程序中可以被使用的范围。在这个范围内引用该标识符是合法的,而在这个范围以外,该标识符是不能被引用的。C语言的标识符作用域可分为局部作用域、函数作用域和全局作用域。C语言中可以定义变量的位置有函数内部、函数参数中及所有函数外部。这些变量分别称为局部变量、形式参数变量和全局变量。定义的位置不同,变量的作用域也不同。有关形式参数
86、已经介绍过,本节只讨论局部变量和全局变量。C语言程序设计21.局部变量v局部变量又称做内部变量,是在函数内部定义的变量,它只在本函数范围内有效。形式参数也是局部变量。其作用域只限于本函数,即从变量定义的位置起,到函数体结束。也就是说,只能在本函数内才可以使用它,在此函数外不能使用。v对于局部变量,它只在进入本函数时,系统生成该变量,并为它分配空间,而函数执行完毕时,系统收回其存储空间,该局部变量消亡,静态局部变量例外(见下一节)。C语言程序设计2v例6.16局部变量示例。vf1()vintx,y;vx=1;y=2;局部变量x,y的作用域vvvf2(inta)vintx,y;vx=10;y=20
87、;局部变量x,y的作用域vvvmain()vinta,b;va=100;b=200;局部变量a,b的作用域vvC语言程序设计2v说明:vmain函数中定义的变量(a,b)也是局部变量,只在主函数中有效,不会因为它们是在主函数中定义的,就可以在整个文件或程序中访问它们。同样地,主函数中也不能使用其他函数定义的变量。v不同函数中可以使用相同名字的变量,这些局部变量代表不同的对象,分配不同的存储空间,因而,它们互不影响。例如在f1函数中定义了x、y变量,在f2函数中也定义了x、y变量,他们在内存中占不同的单元,互不混淆。v形式参数也是局部变量。例如f2函数中的形参a,也只在f2函数中有效。其他函数不
88、能使用它。C语言程序设计22.全局变量v全局变量又称做外部变量,是在函数外部定义的变量。其作用域是从变量定义的位置开始,到本源文件结束为止,即从定义点开始到文件结束中的函数均可访问该变量C语言程序设计2v例6.17全局变量的用法。vinta=1,b=2;vfloatf1()vintx;vintc,d;vvvcharc1,c2;vcharf2()全局变量a,b的作用域vinti,j;vv全局变量c1,c2的作用域vmain()vintm,n;vvva、b、c1、c2都是全局变量,但它们的作用域不同,在main函数和f2函数中可以使用全局变量a、b、c1、c2,但是在f1函数中,只能使用全局变量a
89、、b,而不能使用c1和c2。C语言程序设计2v说明:v全局变量可以被其作用域内的所有函数访问,因此全局变量可以作为一种在各函数之间进行数据通信的手段。如,函数的调用只能带回一个返回值,因此有时可以利用全局变量增加与函数联系的渠道,从函数得到一个以上的返回值。v例6.18编写一个函数,求一个浮点数组中各元素的平均值、最大值和最小值。v显然希望从函数中得到3个结果值,除了可得到一个函数的返回值以外,还可以利用全局变量。C语言程序设计2vfloatmax=0,min=0;vfloataverage(floata,intn)vinti;vfloataver,sum=a0;vmax=min=a0;vfo
90、r(i=1;imax)max=ai;velseif(aimin)min=ai;vsum+=ai;vvC语言程序设计2vaver=sum/n;vreturn(aver);vvmain()vfloatt,s10;vinti;vfor(i=0;iy)z=x;形参x,y的作用域velsez=y;vreturn(z);x,y的作用域vvmain()vintx=10,z;/*x,z为局部变量*/vz=max(x,y);局部变量x作用域vprintf(%d,z);全局变量y作用域vC语言程序设计2v程序的运行结果如下:v10v程序中定义了全局变量x、y,在max函数中又定义了x、y形参,形参也是局部变量。全
91、局变量x、y在max函数范围内不起作用。main函数中定义了一个局部变量x,因此全局变量x在main函数范围内不起作用,而全局变量y在此范围内有效。因此max(x,y)相当于max(10,2),程序运行后得到的结果为10。C语言程序设计2v使用全局变量会增加程序的内存开销,因为全局变量在程序的整个执行过程中都有效,即一直占用内存单元,而不像局部变量那样,在进入所在函数时才开辟存储单元,退出函数时便将其释放。使用全局变量还会降低函数的通用性,而且会降低程序的清晰度。建议不要无限制地使用全局变量。C语言程序设计2在上一节中,从变量的作用域角度将C语言中的变量分为局部变量和全局变量两类。实际上,在C
92、语言中,变量的定义分为两个方面,一是变量的数据类型,二是变量的存储类别。变量的数据类型决定变量的取值范围及其操作方法。而变量的存储类别指的是数据在内存中存储的方法,它决定变量的生存期及其作用域。6.6.2 6.6.2 变量的存储类别变量的存储类别C语言程序设计2vC语言变量有如下语言变量有如下4种存储类型:种存储类型:v自动型(auto型);v外部型或全局型(extern型);v寄存器型(register型);v静态型(static型)。v下面分别对各种存储类型进行说明。C语言程序设计21.auto型变量vauto型变量是在函数内部定义的一种变量,它局限于该函数或所在的函数。故也称为局部变量。
93、函数中的形参和在函数中定义的变量都属此类,在调用该函数时系统会给它们分配存储空间,在函数调用结束之后就自动释放这些存储空间。C语言程序设计2vauto型变量定义的一般形式如下:vauto数据类型标识符变量名表;v其中,方括号表示可以省略,auto是自动变量的存储类型标识符。如果省略auto,系统隐含认为此变量为auto。过去使用的变量,实际上都是auto型的变量。例如:vintf1(inta)vintb;vautointc=0;vvvc变量是自动变量,c=0,执行完f1函数后自动释放其所占的存储单元C语言程序设计22.extern型变量vextern型变量也称为外部变量,它是一种全局变量,在函
94、数之外定义,其定义的一般形式如下:vextern数据类型标识符变量名表;v其中extern标识符可以省略。v只有定义为extern型的外部变量才能供其他文件使用。外部变量的定义是在所有函数体之外,用extern或默认存储类型说明,定义时可以给它赋初值,而且只能赋值一次。v外部变量的作用域是整个程序,即外部变量对程序中的所有函数都是可见的。需要注意以下几点:C语言程序设计2v如果外部变量是在源文件中各个函数之前定义,则该源文件中的各个函数都可以使用它,不需另加说明。v如果外部变量是在一个源文件中间定义,则在其定义之前的函数中使用它时,应该用extern进行说明。例如:vexternfloatx,
95、y;/*外部变量x,y在定义之前的函数中使用时应加以说明*/vf1()vy=x+1;vvvfloatx,y;/*定义x,y为外部变量*/vmain()vvC语言程序设计2v在一个源文件中定义的外部变量,可以在另一个源文件中引用,但必须用extern进行说明。说明方法同。v例如,一个程序包含如下两个源文件,v文件的内容为:vinta,b;vmain()v.vv文件中的内容为:vexterninta,b;vf1()vb=a+1;vvvmain()vvva、b在源文件中被定义为外部变量,在第二个源文件中使用时,就应在第二个源文件的开头用extern进行说明。有了这个说明之后,中的各个函数都可以使用该
96、外部变量了。C语言程序设计23.静态变量v静态变量是在定义它们的函数或文件中长久存在的变量。静态变量分内部静态变量和外部静态变量两种。v(1)内部静态变量v内部静态变量同auto型变量,也是在函数内定义的,它局限于定义它的函数。其定义的一般形式如下:vstatic数据类型标识符变量名表;v例如:staticinta,b;v但是内部静态变量又不同于auto型变量,它是在整个程序的执行过程中始终保持存在。因此一个内部静态变量的值在函数的一次调用结束时并不消失,它在下次调用时还可继续使用原来保留的值,也就是说当一个局部变量被定义为static类别时,它的存在时间会延长,而作用域不变。C语言程序设计2
97、v例6.20vfi()vintx=0;vx=x+1;vprintf(x=%dn,x);vvmain()vf1();vf1();vf1();vv程序的运行结果如下:vx=1vx=1vx=1v若把intx=0;改为staticintx=0;v运行结果则为:vx=1vx=2vx=3v从程序可以看出,自动变量在函数每次被调用时都进行初始化,因此,输出结果始终是1。而静态变量只在编译阶段初始化一次,f1函数第一次被调用时,x=0,退出时为1。第二次调用时,x的值是1,仍然存在,因此输出时x值为2。同样,第三次调用时,x的值为3。C语言程序设计2v(2)外部静态变量v外部静态变量是在函数外部定义的变量,其
98、作用域是定义它的源文件。对于定义它的源文件是可见的,而对该文件之外的文件则是不可见的。因此,外部静态变量的名字与其他源文件中的同名变量互不影响。v外部静态变量一般在源文件的开始和所有函数之外定义,其定义形式同内部静态变量。C语言程序设计24.register型变量v为了提高程序的执行效率,C语言允许将局部变量的值放在CPU的通用寄存器中,这种变量称为寄存器变量。寄存器变量是局部变量,它只适用于auto型变量和函数的形式参数。所以,它只能在函数内部定义,它的作用域和生命期同auto型变量一样。v寄存器变量定义的一般形式为:vregister数据类型标识符变量名表;v在计算机中,从内存存取数据要比
99、直接从寄存器中存取数据慢,所以对一些使用特别频繁的变量,可以通过register将其定义成寄存器变量,是程序直接从寄存器中存取数据,以提高程序的效率。C语言程序设计2v由于计算机的寄存器数目有限,并且不同的计算机系统允许使用寄存器的个数不同,所以不宜定义太多的寄存器变量,只有将少量变化频繁的变量定义成寄存器变量,如循环控制变量等。当一函数内定义的寄存器变量的个数超过系统所允许使用的寄存器数时,系统将自动将其作为一般局部变量处理,即仍使用内存单元存放其值,并不提高运行速度。v说明:v只有局部自动变量和形式参数可说明为寄存器变量。v一个计算机系统中的寄存器的数目是有限的。v不同的系统对regist
100、er的处理不同。v局部静态变量不能定义为寄存器变量。不能写成:vregisterstaticinta,b,c;.C语言程序设计26.7库函数v6.7.1库函数v库函数不是C语言的一部分。人们可以根据需要自己编写出所需的函数。为了用户使用方便,每一种C编译版本都提供一批由厂家开发编写的函数,放在一个库中,这就是函数库。函数库中的函数称为库函数。应当注意,每一种C版本提供的库函数的数量、函数名、函数功能是不相同的。因此在使用时应查阅本系统是否提供所用到的函数。C语言的库函数极其丰富,它包括数学函数,如求正弦值的sin函数,求平方根值的sqrt函数;包括了对字符和字符串进行处理的函数;包括了进行输入
101、输出处理的各种函数读者应该学会正确调用这些已有的库函数,而不必自己编写。本书附录中列出了常用的库函数,供读者查阅。C语言程序设计2v1.调用C语言标准库函数时要求的include命令v在使用库函数时,往往要用到函数执行时所需的一些信息(例如宏定义),这些信息分别包含在一些头文件(headerfile)中。因此在使用库函数时,一般应该用include命令将有关的头文件包括到程序中。对每一类库函数,附录中都列出了在调用该类库函数时,用户在源程序include命令中应该包含的头文件名。例如,调用数学库函数时,要求程序在调用数学库函数前包含以下的include命令:v#includevinclude命
102、令必须以#号开头,系统提供的头文件以.h作为文件的后缀,文件名用一对双引号或一对尖括号“”括起来。注意:include命令不是C语句,因此不能在最后加分号。有关include命令的功能将在以后详细介绍,在此之前读者只需依样使用就可以了。C语言程序设计2v2.标准库函数的调用v对库函数的一般调用形式为:v函数名(参数表);v在C语言中,库函数的调用可以两种形式出现:v出现在表达式中。例如,求y=x3.5+4.5可以通过以下语句调用pow函数来求得:vy=pow(x,3.5)+4.5;v在这里,函数的调用出现在赋值号右边的表达式中。v作为一个独立的语句完成某种操作。例如以下调用:vprintf(t
103、hisisanewbookn);v在printf函数调用之后加了一个分号,这就构成了一条独立语句,完成了输出一行thisisanewbook信息的操作。C语言程序设计26.7.2常用库函数vANSIC标准既定义了C标准库的内容,也定义了C标准库的形式。即ANSIC标准命名并描述了所有符合ANSIC标准的编译程序都必须支持的一组函数。但是,许多编译程序可以附加一些ANSIC标准中未定义的函数,最常见的有图形和鼠标处理函数等等。不准备移植的程序中可以随意使用这些非标准函数,不会带来任何副作用,但是要向新环境移植的程序必须严格限制非标准函数的使用。下面介绍一些常用的库函数。C语言程序设计21.数学函
104、数vANSIC标准定义的数学函数可以分为以下4类:v三角函数;v双曲线函数;v指数和对数函数;v其他函数。v所有这些数学函数都需要用到math.h头文件。另外,在数学函数中,所有的角度都用弧度表示。常用的几个数学函数描述如下,其他的函数在本书附录中加以描述。v(1)abs()函数v调用方式为:intabs(intx)v该函数的作用是计算整数x的绝对值。C语言程序设计2v例6.21函数abs()的使用。v#includevmain()v#includevintvalue;vprintf(Inputthevalue:);vscanf(%d,&value);vprintf(Theabsoluteva
105、lueof%dis:%dn,value,abs(value);vv运行程序,输入value的值为-212,结果为:vInputthevalue:-212vTheabsolutevalueof-212is:212C语言程序设计2v(2)fabs()函数v调用方式为:doublefabs(doublex)v该函数的作用是计算浮点数x的绝对值。v例6.22函数fabs()的使用。v#includevmain()vvprintf(%1.1f%1.1fn,fabs(1.0),fabs(-1.0);vv运行时,屏幕显示为:1.01.0v相关的函数有cabs()、labs()。它们分别是求复数、长整型数的绝
106、对值。C语言程序设计2v(3)exp()函数v调用方式为:doubleexp(doublex)v该函数的作用是求以自然数为底的指数ex的值。v例6.23函数exp()的使用。v#includevmain()vvprintf(valueofetothefirst:%f,exp(1.0);vv程序运行后显示的结果为:vvalueofetothefirst:2.718282C语言程序设计2v(4)sqrt()函数v调用方式为:doubleexp(doublex)v该函数返回x的平方根。如果x为负数,函数将产生定义域错。v例6.24函数sqrt()的使用。v#includevmain()vvprint
107、f(%f,sqrt(16.0);vv程序的运行结果为:4.000000C语言程序设计2v(5)sin()函数v调用方式为:doublesin(doublex)v该函数返回x的正弦值,x必须以弧度为单位。v例6.25用sin()函数打印-1到1的正弦值,步长为0.5。v#includevmain()vdoubleval=-1.0;vdovprintf(sineof%fis%f.n,val,sin(val);vval+=0.5;vwhile(val=1.0);vv程序的运行结果为:vsineof-1.000000is-0.841471.vsineof-0.500000is-0.479426.vsi
108、neof0.000000is0.000000.vsineof0.500000is0.479426.vsineof1.000000is0.841471.C语言程序设计2v(6)cos()函数v调用方式为:doublecos(doublex)v该函数返回x的余弦值,x必须以弧度为单位。v例6.26用cos()函数打印-1到1的余弦值,步长为0.5。v将例6.22稍做修改即可完成本程序。v#includevmain()vdoubleval=-1.0;vclrscr();/*清除整个当前字符窗口,并把光标定位在左上角*/vdovprintf(cosineof%fis%f.n,val,cos(val);
109、vval+=0.5;vwhile(val=1.0);vv程序的运行结果为:vcosineof-1.000000is0.540302.vcosineof-0.500000is0.877583.vcosineof0.000000is1.000000.vcosineof0.500000is0.877583.vcosineof1.000000is0.540302.C语言程序设计2v2.过程控制函数v下面涉及的过程控制函数,主要是用来控制程序执行、终止或调用其他程序执行的方式。v(1)abort()函数v调用方式:voidabort()v函数abort()使程序立即非正常终止,文件没有被清除。在支持返回
110、值的环境里,该函数向调用者(通常是操作系统)返回事先规定的值,由此表示程序失败。该函数的原型在pocess.h和stdlib.h中。v例6.27用户键入字母w时,以下程序非正常终止。v#includev#includevmain()vvfor(;)vif(getchar()=w)abort();vv程序运行时,除了键入w,其余输入任何字母数字,均会出现死循环。若键入w,屏幕显示“Abnormalprogramtermination”信息。C语言程序设计2v(2)exit()v调用方式:voidexit(intexit_code)v函数exit()使程序立即正常终止。环境支持时exit_code
111、值被传递到调用过程。按照惯例,如果程序正常退出,exit_code值为0,否则,由预先规定的非零值指出错误。该函数的原型在pocess.h和stdlib.h中。v例6.28输入一个字符,若该字符为q或Q,则退出本程序,否则继续循环。v#includev#includevmain()vcharc;vwhile(1)vvprintf(nInputthecharacter(qtoquit):n)vc=getch();vif(c=q|c=Q)exit(0);vprintf(nYouenter:%cn,c);vvv程序运行时,首先显示下面一行提示信息:vInputthecharacter(qtoquit
112、):v待键入字符a后,屏幕显示:vYouenter:avInputthecharacter(qtoquit):v等待用户重新输入。直到键入q或Q,程序返回到编辑状态。C语言程序设计2本章小结v源程序是由函数组成的。虽然在前面各章的程序中都只有一个主函数main(),但实用程序往往由多个函数组成。函数是源程序的基本模块,通过对函数模块的调用实现特定的功能。语言中的函数相当于其它高级语言的子程序。语言不仅提供了极为丰富的库函数(如TurboC,MSC都提供了三百多个库函数),还允许用户建立自己定义的函数。用户可把自己的算法编成一个个相对独立的函数模块,然后用调用的方法来使用函数。v可以说程序的全部
113、工作都是由各式各样的函数完成的,所以也把语言称为函数式语言。由于采用了函数模块式的结构,语言易于实现结构化程序设计。使程序的层次结构清晰,便于程序的编写、阅读、调试。C语言程序设计2v在语言中可从不同的角度对函数分类。v1.从函数定义的角度看,函数可分为库函数和用户定义函数两种。v2.语言的函数兼有其它语言中的函数和过程两种功能,从这个角度看,又可把函数分为有返回值函数和无返回值函数两种。v3.从主调函数和被调函数之间数据传送的角度看又可分为无参函数和有参函数两种。C语言程序设计2v在语言中,所有的函数定义,包括主函数main在内,都是平行的。也就是说,在一个函数的函数体内,不能再定义另一个函
114、数,即不能嵌套定义。但是函数之间允许相互调用,也允许嵌套调用。习惯上把调用者称为主调函数。函数还可以自己调用自己,称为递归调用。main函数是主函数,它可以调用其它函数,而不允许被其它函数调用。因此,程序的执行总是从main函数开始,完成对其它函数的调用后再返回到main函数,最后由main函数结束整个程序。一个源程序必须有,也只能有一个主函数main。v函数直接或间接地调用自身称为递归调用。如果一个问题可以被分解为规模较小的同类型问题,就可以采用递归方法求解。设计递归算法的关键在于设计递归的三要素。vC语言的编译器提供了大量的库函数,完成各种常用功能,可以在程序中直接调用这些库函数。C语言程
115、序设计2v习题6v1.以下程序的输出结果是。v#includevmain()vinti=1,j=3;printf(“%d,”,i+);vinti=0;i+=j*2;printf(“%d,%d,”,i,j);vprintf(“%d,%dn”,i,j);v2.以下程序的输出结果是。v#includevintfunc(int,int);vmain()vintk=4,m=1,p;vp=func(k,m);printf(“%d,”,p);vp=func(k,m);printf(“%dn”,p);vvintfunc(inta,intb)vstaticintm,i=2;i+=m+1;m=i+a+b;retu
116、rnm;C语言程序设计2v3.以下程序的输出结果是。v#includevvoidfunc(ints)vstaticintj=0;vdosj+=sj+1;while(+j2);vvmain()vintk,a10=1,2,3,4,5;vfor(k=1;k3;k+)func(a);vfor(k=1;k5;k+)printf(“%d”,ak)vv4.以下程序的输出结果是。v#includevfunc(inta)vstaticintc=3;intb=0;va=c+,b+;return(a);vvmain()vinta=2,i,k;vfor(i=0;i2;i+)k+=func(a+);vprintf(“%
117、dn”,k);vC语言程序设计2v5.以下程序的输出结果是。v#includevintm=13;vfunc(intx,inty)vintm=3;vreturn(x+y-m);vvmain()vinta=7,b=5;vprintf(“%dn”,func(a,b)/m);vv以下程序的输出结果是。v6.#includevvoidfunc()vstaticinta=3;va+=2;printf(“%d”,a);vvmain()vinta;vfor(a=1;a=4;a+)func();vprintf(“n”);vC语言程序设计2v7.以下程序的输出结果是。v#includevdoublesub(dou
118、blex,doubley,doublez)vy-=1.0;z=z+x;returnz;vmain()vdoublea=2.5,b=9.0;vprintf(“%fn”,sub(b-a,a,a);vv8.以下程序的输出结果是。v#includevintfun2(inta,intb)vintc;vc=a*b%3;returnc;vintfun1(inta,intb)vintc;va+=a;b+=b,c=fun2(a,a);returnc*c;vmain()vintx=11,y=19;vprintf(“%dn”,fun1(x,y);vC语言程序设计2v9.编写fun函数用以判断一个数是否为素数,提示:可在函数中设置一个逻辑量,并把该值返回给调用者。v10.编写函数,根据整型参数n的值,计算如下公式的值:vv11.编写函数,根据整型参数m的值,计算如下公式的值:v C语言程序设计2