C语言经典课件5-9章.doc_第1页
C语言经典课件5-9章.doc_第2页
C语言经典课件5-9章.doc_第3页
C语言经典课件5-9章.doc_第4页
C语言经典课件5-9章.doc_第5页
已阅读5页,还剩115页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第五章 函数第五章 函数解决大的复杂问题的方法之一是化整为零,分而治之,在程序设计中也采用这样的方法,将大任务分解成若干人的智力能及的小模块,降低程序的复杂性,增加程序的可靠性和可重用性。在C程序中,模块以函数的形式来体现,所以说C程序是由函数构成的语言,是函数式的语言。一个C程序由一个main函数和若干其它函数组成,这些函数可以写在一个文件中,也可以写在若干文件中,无论main函数的位置在何处,程序总是从main函数开始执行,也从main函数结束。图5-1是C程序的组织示意图。文件1文件2文件n函数1一1函数2一1函数n一1程序图5-1 C程序的组织5.1问题的提出5.1.1问题如何使用函数编程计算3!+5!+8!5.1.2问题分析题目要求计算三个阶乘的值,相加后,输出结果,核心在于计算阶乘。如果在一个main()函数里完成的程序如下:例5_1main() long int j,t=1,s=0; for(j=1;j=3;j+) t=t*j;/*计算3阶乘*/ s+=t; for(t=1,j=1;j=5;j+) t=t*j;/* 计算5阶乘*/ s+=t; for(t=1,j=1;j=8;j+) t=t*j;/* 计算8阶乘*/ s+=t; printf(“3!+5!+8!=%ldn”,s);仅仅因为循环次数不同,程序中写了三遍计算阶乘的程序段(三个for语句),程序显得重复累赘,如果把计算阶乘的程序段独立写成一个模块(函数),需要时,调用它,程序的可重用性、可靠性、可维护性都可得到提高,怎样写一个函数呢?,怎样调用这个函数呢?这就是我们学习函数这章的任务。5.1.3 程序1把求阶乘的程序段独立写成一个函数,调用这个函数时,输入n,函数就输出n!,如图5-2。n!n 函数 图5-2 求n!函数例5_2long jch(int n) long t=1; int j; for(j=1;j=0) return x; else return -x;C函数只能通过一个return语句返回一个值,所有return语句的返回值类型应与函数名前的类型一致。这个函数虽然有两个return语句,但执行时只可能执行到一个return语句。函数只完成某一功能,而不返回任何值时,可将函数定义成void类型,在这种函数中return语句可有可无,函数执行完后,有无return语句,都执行返回功能。例:5_4void pok()printf(“0k”); return;/* 可以无return*/ 在一个程序中不能出现同名的多个函数定义,且函数体内不能再定义函数,即不能嵌套定义,如:int ff1() /* ff1函数定义 */ float ff2() /* ff2函数定义出现在ff1函数定义中,错*/ 函数的定义就是给出函数的名字,函数的返回值类型,函数的形参名字与类型,函数的实现语句(函数体)。5.3函数原型、函数声明与函数调用5.3.1函数原型调用函数时,系统需要知道下列信息:u 函数类型u 函数名u 函数的参数(个数、类型及顺序)知道这些信息就可以调用该函数,而不必知道函数的具体实现(函数体),这些信息描述了函数的模型,是函数的用户界面,我们称为函数原型。如: int absint(int); void pok();5.3.2函数的声明在函数调用前,C系统需要知道函数的原型,才能保证函数的正确调用,因此当函数调用在前,定义在后时(当函数为int型时,也可不声明),必须用函数原型声明,以便C系统获取相关信息。声明时参数名可以缺省,但类型名不可以缺省,如: int ff1(int age,char sex); 也可以写为:int ff1(int ,char); 声明中的参数名相当于注释,以便系统检查调用时实参的位置,所以可以缺省。5.3.3函数的调用函数的定义相当于写剧本,函数的调用相当于演戏,函数的定义只是说明了函数的存在,函数必须通过调用才能被执行,函数调用的功能是:u 实参数向形参数传递数据。(由演员担当角色)u 为参数和函数体内的变量分配内存空间。u 中断当前函数的执行,把执行流程转向被调用函数的入口,执行被调用函数。函数调用通过调用表达式进行,其形式为:函数名(实参表列)当函数无返回值时,调用表达式后加分号,作为调用语句使用,如:pok();当函数有返回值时,调用表达式作为其他表达式的一部分,如:c=max(a,b); 函数调用结束后,返回到调用时的中断处,但形参的值不传递给实参,参数的传递是单向值传递,见下例。 例:5_5调用mult10时:实参变量n的值新分配的形参单元 n 例5_5:将一实数乘以10后显示出来576main() float n=5.76,result; float mult10(float); /* 函数的声明*/ result=mult10(n); /* 函数的调用*/ printf(“result=%fn ”,result); printf(“num=%fn ”,n);float mult10(float n) /* 函数的定义*/ n*=10;return(n);程序运行结果:程序运行结果:result=57.600002 图5-3 单向值传递num=5.760000变量作函数的形式参数时,实参可以是表达式(包括已有确定值的变量,常量),当执行到调用表达式时,计算表达式的值,将实参的值传递给形参。函数返回时,形参的值不传给实参,这被称作单向值传递。形参和实参是不同的变量,即便它们有相同的名字,也互不相干,如本例 形实参都是n,但形参n的值不影响实参n。说明:程序从main函数开始执行,执行到函数调用mult10(n)时,将实参n变量中的值传递给形参的n变量,执行mult10函数中的语句,形参n变量乘10后,返回到main函数,并将mult10函数的结果57.600002(形参n变量的值)赋给result变量,形参n变量和实参n变量是不同的内存单元,mult10函数调用结束后,形参n变量的值不传给实参n变量,因此实参n变量的值不会改变。调用的时候,实参变量中的值传递给形参变量,调用结束后,形参变量的值不传给实参变量,这就是单向值传递,见图5-3。例5_6: 求s=s1+s2+s3+s4的值。其中:s1=1+1/2+1/3+1/50;s2=1+1/2+1/3+1/100;s3=1+1/2+1/3+1/150;s4=1+1/2+1/3+1/200float fc(int n) /*定义函数求1+1/2+1/3+1/n的值*/ float s; int i; s=0; for(i=1; i=n; i+) s+=1/(float)i; return(s);main() /*主函数*/float sum;sum=fc(50)+fc(100)+fc(150)+fc(200);/* 四次调用fc()函数,使该函数的形参n分别 为n=50;n=100;n=150;n=200;*/ printf(“sum=%f ”,sum);程序的运行结果:sum=21.1557965.4数组名作函数的参数5.4.1问题的提出在程序设计中,我们经常需要对一组数据排序,如对若干同学的成绩按由高到低的顺序排序,对若干选手的成绩排序,对工厂每月的产品产量排序等,所以有必要写一个能对若干数据排序的函数,需要时调用它即可完成排序任务,这个函数应该怎样定义呢?5.4.2问题分析对大量同类型的数据排序,这些数据应怎样存放是第一个要考虑的问题,根据我们已有的知识,这些数据只能存放在一维数组中,因此送给排序函数进行排序的对象是个一维数组,这是排序函数的第一个参数,其次由于每次需要排序的数目不同,因此还必须有第二个参数,告知该函数需要排序的数据个数,这个参数肯定是个整型变量,这样我们就有下面该函数的轮廓:void sort(一维数组,int n) 用某种算法对该数组排序现在的问题是在C语言中,用一维数组作参数时,应怎样表达?根据前面的知识,实参和形参的类型应该一致,因此,我们的第一个参数,只能是float,int,char这些基本类型中的一个数组,C语言允许一维数组作形参时,可不定义大小,因此如果对整型数据排序,这个函数头如下:void sort(int s,int n) 用某种算法对该数组排序在函数体中我们只要用某种算法排序s数组即可。5.4.3程序例5_7 用选择法排序的该函数如下:void sort(int s,int n) int j,t,k;for(j=0;jn-1;j+)for( k=j+1;kn;k+)if(sjsk) t=sj;sj=sk;sk=t;main() int j,a=60,70,55,89,90,100,67,88,76,95; sort(a,10);for(j=0;j1) /* 递归调用 */ 根据公式我们就可以写出求n!的函数。float ff(int n) float f; if(n0) printf(“n1时,发生递归调用,即在ff函数中又调用ff函数(ff(n-1),下面以5!为例,分析该函数的执行过程:调用main()ff(5); f=ff(4)*5; f=ff(3)*4; f=ff(2)*3; f=ff(1)*2; 120 24 6 2 返回 图5-55.6库函数C语言定义了丰富的库函数,方便我们程序设计,我们只需注意以下几点,便可调用库函数。u 函数的功能u 函数的原型u 库函数所需的头文件我们已经知道,调用函数前,需要定义函数并声明函数,C系统为方便我们使用库函数,已经完成了这两项工作。首先函数按功能分为不同的库,如:数学函数、输入输出函数、字符串处理函数等,每个库都有一个头文件,给出了各库中各个函数的原型声明等有关信息。使用库函数之前,只需在程序中使用#include命令将其相应的头文件包含进来,程序就有了该函数的原型说明。然后在程序执行时,C系统会根据函数的原型说明,到相应的库文件中找到相应的库函数定义,并执行它。比如与数学函数对应的头文件是math.h, 与输入输出对应的头文件是stdio.h,与字符串处理函数对应的头文件是string.h等。例5_11#include “math.h”/*嵌入数学库函数头文件*/main() float f; printf(“input a real number:”); scanf(“%f”,&f); printf(“The sqnare root is of %f is :% f”,f,sqrt(f); /* sqrt是数学函数库math.h头文件中的一个求开方的函数*/库函数是一些被验证的、高效率的函数,进行程序设计时,应优先选用库函数。常用的库函数及标准头文件见附录。注意,系统头文件在include子目录中,系统函数定义在lib子目录中,连接时,系统会根据原型到相应库文件中连接相应的库函数。要正确地进行文件包含和连接应设置正确的环境。如:c:tcincludec:tclib这样才能在编译和连接时找到相应的文件。5.7变量的作用域5.7.1问题的提出写一个函数,送入圆的半径r后,得到圆的面积及圆的周长。5.7.2问题分析我们已经知道,通过函数调用,最多可以用return语句返回一个值给调用函数,如果想返回多个值,怎么办呢?这道题涉及到变量的作用域。5.7.3程序例5_12 现在我们编写利用全局变量来完成写一个函数,送入圆的半径r后,得到圆的面积及圆的周长的程序。float cl;/*定义全局变量c1*/float carea(float r)float ar; ar=3.14*r*r; cl=2*3.14*r;/*使用全局变量c1*/return ar; main()float r,area; printf(“n r=?”); scanf(“%f”,&r);area=carea(r); printf(“r=%5.2f,carae=%5.2f,cl=%5.2fn”,r,area,cl); /*使用全局变量c1*/程序运行结果:r=?3 /* 输入半径3 */r= 3.00,carae=28.26,c1=18.84该程序中使用了在函数体外定义的全局变量c1, 在carea函数中把圆的周长存入c1中,在main函数中把c1的值输出,两个函数都在用c1变量,这是前面的程序中没有的情况,什么是全局变量和局部变量?它们有何特点?5.7.4局部变量和全局变量变量是程序设计中的重要元素,我们已经知道了它的一些属性:类型决定了它所获得的存储空间的大小;存入变量的值可以被多次使用,写入(赋值)将覆盖变量中原有的值;它所占居的存储空间的编号是变量的地址,此外,它还有存储属性,存储属性包括作用域与生存期两个方面。变量的作用域就是变量在源程序代码中的可用范围,作用域根据变量的定义位置区分为局部变量和全局变量两种。在函数体内或语句块中定义的变量称局部变量,它们的作用范围只在所定义的函数体内或语句块中,在函数体外定义的变量,称全局变量,它的作用域从定义点起,直到本源文件结束,如果用extern关键词加以引用说明,它的作用范围可以扩大到在一个程序的所有文件中都可使用。如:图5-6。int p=1,q=5;/*定义外部变量 */外部变量p,q作用域 a,b,c变量作用域float f1(int a) /*定义f1函数 */int b,c; char c1,c2; /*定义外部变量 */x,b,j变量作用域外部变量c1,c2作用域char f2(int x) /*定义f2函数 */int b,j; m,n变量作用域main()/*主函数 */int m,n; 图5-6说明:(1) 在函数体内定义的变量,只在本函数有效,因此在不同函数中可以使用相同名字的变量,如本例中f1、f2函数都有变量b,但两个函数中的b变量是不同的内存空间,它们互不相干。(2) main函数中定义的变量(m,n),也只在main函数中有效,其他函数不得使用。(3) 形参也是局部变量。(4) 函数体外定义的变量都是全局变量(p,q,c1,c2),但根据定义点,作用范围不同。(c1,c2的作用范围小)(5) 外部变量可以增加函数间的联系,但破坏了函数的封装性,增加了程序的难读性(程序中的函数都可以改变全局变量的值),建议少用全局变量。5.8变量的存储类型5.8.1问题通过5次函数调用打印1到5的阶乘值。5.8.2问题分析该题有多种算法,其中效率较高的一种是:先求出1!=1,在1!的基础上再乘2,就得2!(2!=1!*2), 在2!的基础上再乘3,就得3!(3!=2!*3),这样我们要写的函数必须能保存上一次的阶乘值,在(n-1)!的基础上再乘n就完成了n!,问题是局部变量可以保存函数的结果,以备下一次调用函数时使用吗?换句话说在函数调用完成后它还存在吗?如果它不存在,显然它不能保存值。所以定义变量时,不仅要考虑它的作用域还要考虑它的生存期。5.8.3 程序例5_13 通过5次函数调用打印1到5的阶乘值int fact(int x) static int t=1; t*=x; return t;main()int i;for(i=1;i=5;i+) printf(“%d!=%dn”,i,fact(i);程序运行结果为:1!=12!=23!=64!=245!=120思考:请将fact函数中的static int t;语句改为int t;,运行程序,结果是什么? main函数中不用循环语句,直接用printf(“%d!=%dn”5,fact(5);语句,能输出5!的结果吗?为什么?要完全看懂例5-13,必须知道变量的存储类型与变量的生存期。C语言把用户执行程序所占用的内存空间分为三部分:程序代码区、静态变量存储区和动态变量存储区。静态存储区中的变量在编译时创建,在程序结束时才被撤消。全局变量和静态变量放在该区,也就是说,在整个程序的执行期间它们始终存在。而存储在动态存储区中的变量,在程序的执行过程中根据需要创建,在运行完所在域后即被撤消,它们是动态存在的。局部变量和形参就分配在动态存储区。如图5-7。程序代码区静态存储区动态存储取存放可执行程序的机器指令存放外部变量、静态局部变量存放自动变量,形参等 全局变量或静态变量局部变量和形参图5-7C语言定义一个变量的完整形式如下:存储类型说明符 数据类型说明符 变量名其中,存储类型说明符有:auto(自动)、extern(外部)、static(静态)、register(寄存器)四种。5.8.4局部变量的存储类型局部变量有三种存储类型:auto、 static、 register。1.自动变量局部变量定义时不指明存储类型或用auto说明时,都是自动变量。自动变量分配在动态存储区。程序执行到该局部变量所在域时,C系统为该局部变量分配存储空间,执行完该域后,释放其所在的空间。再次调用函数时,系统将为自动变量重新分配空间。如果自动变量定义时有初值,每调用一次函数,都要赋初值。没有赋初值的自动变量,将得到分配给它的内存单元原有的值,是一个不确定的值。2.静态局部变量使用static定义的局部变量,称静态局部变量,它的作用域与自动变量一样,但它被分配在静态存储区中,因此,当函数调用完成后,它依然存在,再次调用函数时,C系统不再重新为静态局部变量分配存储空间,赋给静态局部变量的初值是在编译时完成的,程序执行期间不再赋初值,因此局部静态变量可以保存上一次函数结束时的值,以备下一次函数调用时使用。对定义时未赋初值的静态局部变量,C系统在编译时自动赋初值一次,数值型赋0,字符型赋空格。3.寄存器变量使用register定义的局部变量,称寄存器变量,顾名思意,寄存器变量占用CPU的通用寄存器,而不占内存单元,因此使用寄存器变量就省去了访问内存的时间,从而提高了程序的执行速度。也由于这一特点,使用时请注意:u 寄存器非常有限,不可能让变量长时间占有,所以寄存器变量只可能是自动变量,且程序中使用的寄存器变量的数目也是有限的。u 由于长度的限制,寄存器变量不能是long、flot、doubleint类型。u 寄存器变量没有地址,不能对它进行求地址运算。 那些被频繁使用,占用字节数又不多的变量,适合定义为寄存器变量。 例5_14 使用寄存器变量 main() int s; s=power(5,3); printf(“%d n”,s);power(int x,register int n)/* n为寄存器变量 */ int p; for(p=1;n;n-) p*=x; return p;程序运行结果为:125n是寄存器变量,当传给n的值较大时,可以节省很多到内存存取变量值的时间。 5.8.5全局变量的存储类型全局变量有两种存储类型:extern(外部)和static(静态)。一个大的C程序由若干文件组成,为了增加联系,文件之间应该可以相互引用全局变量,如何引用全局变量呢?这就是我们要讨论的问题。1.外部变量没有用static定义的全局变量,就是外部变量,引用这种外部变量时,用extern加以说明,就可以使它的作用范围扩大到它所在的整个源程序文件,甚至其他文件。 例5_15 阅读下面的程序,注意外部变量的使用方法/* 源程序文件f1.c*/#include “f2.c”extern int a=5;/*定义外部变量 ,extern可缺省*/char c1=a,c2=b; /*定义外部变量 */main()extern int b; /*外部变量b的定义在后,使用在前,必须用extern进行引用性声明 */ char c2=B;printf(“%c n”,c1-32);printf(“%c ,%dn”,c2,b*b);/*局部变量c2起作用*/fact();int b=2; /*定义外部变量b2*/* 源程序文件f2.c*/extern int a;/*使用另一个源程序文件中定义的外部变量必须进行引用性声明*/fact()int k,p=1; for(k=1;k=a;k+) p*=k;printf(“%d!=%d”,a,p);使用外部变量时应注意以下问题:u 在同一个源程序文件中使用外部变量时,如果使用在前,定义在后,必须用extern进行引用性声明。u 使用另一个源程序文件中定义的外部变量,必须用extern声明后,才能使用。u 当全局变量和局部变量名相同时,在局部变量的作用范围内,局部变量起作用,全局变量被屏蔽extern有两种声明形式,定义性声明和引用性声明,定义性声明是为了建立实体,即建立变量的存储空间。引用性声明是为了建立标识符与实体之间的联系。定义性声明的形式为:extern类型 变量名=初始化表达式;定义在函数体外的变量都是外部变量,所以extern通常被缺省,初始化表达式被缺省时,C系统为数值型外部变量赋0,字符型赋空格。引用性声明的形式为:extern 类型 变量名;定义性声明和引用性声明的区别如下:u 定义性声明一定是在外部,引用性声明不限于外部,只要在使用该外部变量前声明即可。u 定义性声明可以初始化,引用性声明不能初始化。u 定义性声明在程序中只有一次,而引用性声明可以有多次。2.静态全局变量当用static定义全局变量时,该全局变量不允许其他文件引用,只能在定义它的源文件中使用,这种变量称静态全局变量。如上例中的外部变量a,若定义成:static int a;则f2.c文件不能引用。C语言中的函数与全局变量类似,无论定义时是否用extern修饰,都是外部的,都具有静态生存期,若要使用在一个程序中的其他文件定义的函数,用extern进行引用性声明,如:extern float ff(float);/*声明将引用一个其他文件中的函数*/如果函数不允许其他文件引用,定义时在前面加static修饰,如: static float fn(int n)/*定义一个不能被其他文件引用的函数。5.9编译预处理在程序头部出现的以#开头,末尾没有分号的命令是编译预处理命令,C系统在进行实质性的编译前,即将源程序文件翻译成目标文件前,先要对这些命令进行处理,故而把它们叫做编译预处理命令,以区别于在程序执行时才起作用的执行语句。C提供的编译预处理命令有:u 宏定义命令 #define u 文件包含命令 #includeu 条件编译命令 #if #else #end ifu 行控制命令 #line其他:#pragma、#error等我们主要介绍前两种。5.9.1宏定义命令用一个宏名(标识符)来代表一个字符串,就叫宏定义,其形式如下:# define 宏名 字符串宏名用大写字母表示,以区别于变量,宏名后的字符串可以是表达式或语句,并可以进行嵌套定义(引用已定义的宏名)。例5_16#define X 5 /* 用X代替5 */#define Y X+1 /* 用Y代替X+1(嵌套定义) */#define Z Y*X/2 /* 用Z代替Y*X/2(嵌套定义) */main()int a=Y; /* 替换为int a=5+1 */printf(“Z=%d,”,Z); /* Z处替换为5+1*5/2 */printf (“%dn”,-a);程序的运行结果为:Z=7,5宏定义命令可以带参数,带参数的宏定义的形式:#define 宏名(参数表) 字符串在字符串中应包含参数表中的参数。如:#define CUBE(X) (X)*(X)(X) int b=0,a=3;b=CUBE(a);/* 替换为b=(a)*(a)*(a) */使用有参数的宏时请注意几点:(1)在实参数为表达式时,字符串中的参数是否用括号括起来,将影响替换结果,如上例改为:#define CUBE(X) X*X*X int b=2,a=3;b=CUBE(b+a);/* 替换为b=b+a*b+a*b+a,而不是(b+a)*(b+a)*(b+a) */(2)宏名与带参数的括号之间不应加空格,否则将空格以后的字符串都作为替代字符串的一部分,成为无参宏,如:#define CUBE (X) (X)*(X)*(X)int b=2,a=3;b=CUBE(a);/* 替换为b=(X) (X)*(X)*(X)(a) */带参数的宏与函数的主要区别是宏调用不需调用及返回时的开销,宏调用在编译时进行简单的字符串替换,宏调用多,将使编译时间增加,源程序增长。5.9.2文件包含文件包含的作用是将另一文件包含(嵌入)到本文件中,如图5-8所示:目标文件当前源程序文件file.objfile.c#include “file1.h”被包含的文件file1.h编译A代码B代码图5-8文件包含命令中,被包含文件用双引号括起来时,编译系统按以下方式搜索所要包含的文件:源程序所在的文件目录中有所要的包含的文件?YN按标准方式搜索其他目录嵌入该文件图5-9被包含文件用尖括号括起来时,编译系统只按标准方式搜索其他目录,搜索范围较小,但搜索时间短。注意,一个#include命令只能包含一个文件,文件包含可以嵌套使用,即一个包含文件又包含另一个文件,当被包含文件的内容被修改后,包含这个文件的源程序文件要重新编译。5.10语法练习1. 选择题(1) 下面哪个是正确的函数定义 A double fun(int x, int y)B double fun(int x; int y)C double fun(int x, y)D double fun(int x, y;)(2) 缺省修饰符的情况下 ,函数自身是_。 A. static B. auto C. register D. extern(3) 下面不正确的说法是_。A.C程序通常是由许多小函数组成的,而不是少量的大函数组成的.B. 在源文件中可以以不同的顺序定义函数。C. 通常调用函数前,函数必须被定义和声明。D. dummy() 是无用的函数。(4) 选择程序的结果_ increment() static int x=0; x+=1;printf(%d , x ); main() increment(); increment(); increment(); A. 1 1 1 B. 1 2 3 C. 0 1 2 D. 0 0 0(5) 选择程序的结果_ main() static char a80 = AB , b80 = LAMP ; int i = 0; strcat( a , b ); while( ai+ != 0 ) bi = ai; puts( b); A. LB B. ABLAMP C. AB D. LBLAMP2.读程序,写结果.(1) main()int k=4,m=1,p;p=func(k,m);printf(“%d,”,p);p=func(k,m);printf(“%dn”,p);func(int a,int b) static int m=0, j=2;j+=m+1;m=j+a+b;return(m); (2) #includeint z;void f(int);int main()z=5;f(z);printf(z=%dn,z);void f(int x)x=2;z+=x; (3) #include void num()extern int x,y;int a=15,b=10;x=a-b;y=a+b;int x,y;main()int a=7,b=5;x=a+b;y=a-b;num();printf(%d,%dn,x,y); (4) f(int a)int i=0;while(ai=10)printf(%d ,ai);i+;main()int a=1,5,10,9,11,7;f(a+1); (5)main()int k=2,x=5,j=7;fun(j,6);printf(“k=%d,j=%d,x=%dn”,k,j,x);fun(int k,int j)int x=7;printf(“k=%d,j=%d,x=%dn”,k,j,x); inct();inct();inct(); inc1();inc1();inc1(); inct() int x=0;x+=1; printf(x=%dt,x); inc1() static int y=0; y+=2; printf(ny=%dt,y); (7)#define A 4 #define B(x) A*(x)/2 main() float c,a=4.5; c=B(a); printf(“%5.1fn”,c); (8)#include #include #define FOREVER 1#define STOP 8main()void f(void);while (FOREVER)f();void f(void)static int cnt=0;printf(cnt=%dn,+cnt);if(cnt=STOP)exit(0);(9)main() int a=3,b; b=ff(a); printf(“a=%d,b=%dn”,a,b); ff(int x) x=x+2; return x; 3.填空(1)下面的程序输入10个数,然后,输出排序后的10个数。main()int a10,i;_;printf(Input 10 numbers:);for(i=0;i10;i+)scanf(%d,&ai);sort(a,10);for(i=0;i10;i+) printf(“%d,”,ai);void sort(_) int i,j,t;for(i=0;i_ n-1;i+) for(j=0;j_n;j+) if(ai _aj) t=ai;ai= aj+1; aj+1=t;(2) 下面的程序计算10个同学一科成绩的平均分。 _ average( float array10 ) int i; float aver, sum = array0; for( i=1; i10; i+ ) sum += arrayi; aver = sum /10;return aver; main() float score10, aver; int i; for( i=0; i10; i+ ) scanf(%f,_); aver =_; printf( average score is %5.2f n,aver );5.11编程练习1. 写一个程序打印三角形的面积,要求:用一个函数判输入的三个数是否为三角形的边,是三角形的边返回1,否则返回0;再用一个函数输入三角形的三条边,计算其面积,返回三角形的面积。提示:程序的形式如下,请将其编写完整。#include “math.h”int pb(float a,float b,float c)int t=0; 是三角形的边t为1 return t; float area(float a,float b,float c)float area;根据a,b,c的值计算三角形的面积。return area;main()输入三角形的边, 调用pb函数如果pb函数值为1,调用area函数计算三角形的面积。如果pb函数值为0,输出出错信息2. 写一个判素数的函数,在主函数中输入一个整数,输出是否素数的信息。3. 写一个字符串复制函数,并在main()函数中调用它。5.11小结C程序是由函数构成的,因此编写C程序的主要工作是使用函数,它包括定义函数、调用函数和声明函数,定义函数要考虑函数的返回值类型、函数名、函数的参数类型、参数个数、函数的执行语句。如果函数有返回值,只能通过return(表达式)语句返回一个值,如果return语句的返回值类型与函数类型冲突,系统自动转换为函数类型。如果没有定义函数类型,则为整型。函数通过调用被执行,调用时,给出函数名和实参(如果有参数)即可。实参的类型、个数、顺序应与形参一致,程序执行到调用语句时,实参的值传给形参,形参的改变不影响实参,这叫单向值传递。如果形参是数组,实参应该是数组名,数组名是数组的首地址,发生调用时,实参数组的地址传给形参数组,实参数组与形参数组地址相同,形参数组的改变,就是实参数组的改变。函数不可嵌套定义,但可嵌套调用,如果函数自己调用自己就是递归调用。如果函数定义在后,调用在前,且函数类型为非整型,必须在调用前用函数原型声明。变量不仅有数据类型,还有存储类型,存储类型指变量的作用域和生存期,即变量的可见性和寿命。C语言大量使用的是自动变量,自动变量的作用域限制在定义它的函数体或语句块内,调用这个函数(块)时,系统自动分配内存空间,调

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论