计算机程序设计基础(C)第07章_第1页
计算机程序设计基础(C)第07章_第2页
计算机程序设计基础(C)第07章_第3页
计算机程序设计基础(C)第07章_第4页
计算机程序设计基础(C)第07章_第5页
已阅读5页,还剩56页未读 继续免费阅读

下载本文档

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

文档简介

计算机程序设计基础(C)王虎函数与模块设计函数是模块化的基本单位主调函数与被调函数程序、源文件与函数关系程序中各模块关系mainfun1fun2fun3fun4fun5file1.cmain(){}fun1(){}fun2(){}file2.cfun3(){}fun4(){}fun5(){}program函数与模块设计一个C程序由一个或多个程序模块组成,每一个程序模块作为一个源程序文件。对于较大的程序,通常将程序内容分别放在若干个源文件中,再由若干源程序文件组成一个C程序。这样便于分别编写、分别编译,提高调试效率。一个源程序文件可以为多个C程序公用。函数与模块设计一个源程序文件由一个或多个函数以及其他有关内容(如命令行、数据定义等)组成。一个源程序文件是一个编译单位,在程序编译时是以源程序文件为单位进行编译的,而不是以函数为单位进行编译的。C程序的执行是从main函数开始的,如果在main函数中调用其他函数,在调用后流程返回到main函数,在main函数中结束整个程序的运行。函数与模块设计所有函数都是平行的,即在定义函数时是分别进行的,是互相独立的一个函数并不从属于另一函数,即函数不能嵌套定义函数间可以互相调用,但不能调用main函数。main函数是系统调用的函数与模块设计从用户使用的角度看,函数有两种:

标准函数,即库函数。这是由系统提供的,用户不必自己定义这些函数,可以直接使用它们。不同的C系统提供的库函数的数量和功能会有一些不同,但许多基本的函数是共同的用户自己定义的函数,用以解决用户的专门需要库函数#include"stdio.h" 例2.2

#include"math.h"main(){doublex,y;

printf("inputnumber:\n");

scanf("%lf",&x); y=cos(x); printf("coseof%lfis%lf\n",x,y);}自定义函数int

min(intx,inty){

intz; if(x>y) z=y; else z=x;

return(z);}#include<stdio.h>int

min(intx,inty);main(){

int

m,n,r;

scanf("%d%d",&m,&n); r=min(m,n);

printf("\nmin=%d",r);}

例2.3函数定义存储类型符

类型标识符函数名(形式参数表){

声明定义部分;

执行语句序列;}1、extern(默认)2、static即函数返回值类型,可为任何有效类型若有返回值,则函数体内至少有一条return语句函数定义无参函数的定义一般形式

存储类型符类型标识符

函数名(){声明部分语句部分}函数定义有参函数的定义一般形式

存储类型符

类型标识符函数名(形式参数表列){声明部分语句部分}函数调用函数调用的一般形式为:

函数名(实参表列);如果是调用无参函数,则“实参表列”可以没有,但括弧不能省略这种调用形式多用于被调函数无返回值,或有返回值但主调函数不使用

printf(“hello,world!”);函数调用第二种调用方式作为表达式的组成部分

r=min(m,n);此时要求被调函数必须有返回值函数调用的执行过程将当前正在执行的函数状态保存下来(如本函数的内部变量、当前语句的地址等),暂停本函数的执行,转去执行被调函数为被调函数形参分配内存,依次计算实参的值并将计算结果依次赋给相应位置上的形参函数调用的执行过程执行被调函数的函数体对“无返回值”函数,执行到“return;”便返回上一级函数调用处。若无return语句,则执行到函数体的右花括号返回上一级函数调用处对“有返回值”函数,执行到“return(表达式);”语句时计算表达式的值并将该值返回到上一级函数调用处函数调用的执行过程被调函数返回时,将释放本函数中定义的变量、数组和形参返回主调函数继续执行返回时,若调用形式是函数语句,则执行该语句的下一条语句;若调用形式是表达式,则执行该表达式其余未执行部分例2.3函数声明若函数的定义放在主调函数之后,则在调用该函数之前应对被调函数进行声明(说明),这与使用变量之前要先进行变量说明是一样的特例被调函数的定义出现在主调函数之前时,直接调用参见例7.1被调函数的返回值是整型或字符型时,对被调函数可不作说明,直接调用函数声明#include<stdio.h>main(){

int

m,n,r;

scanf("%d%d",&m,&n); r=min(m,n);

printf("\nmin=%d",r);}

例2.3变形

无函数声明int

min(intx,inty){

intz; if(x>y) z=y; else z=x;

return(z);}函数声明函数原型的一般形式为:1.函数类型函数名(参数类型1,参数类型2……);2.函数类型函数名(参数类型1参数名1,参数类型2参数名2……);声明的作用是把函数名、函数参数的个数和参数类型等信息通知编译系统,以便在遇到函数调用时,编译系统能正确识别函数并检查调用是否合法。函数声明main(){

floatadd(float

a,floatb);

floatx,y,z;

printf("\ninputfloatx,y:");

scanf("%f,%f",&x,&y);z=add(x,y);

printf("\nsumis%f\n",z);}例7.2编写函数,计算两个实数之和floatadd(float

a,floatb){floatc;c=a+b;returnc;

}声明时可以省去形参名floatadd(float,float);函数声明传统习惯法类型标识符函数名()这种表示方法,在函数声明中省略对参数的描述参考例7.3函数声明系统函数的声明用预编译的包含命令

#include<头文件名.h>将含有系统函数声明的头文件包含到本程序中外部函数的声明若被调函数和主调函数不在同一个编译单位,在主调函数的函数体外、或在主调函数所在编译单位的开头对将要调用的函数进行声明extern

类型说明符

被调函数名(类型形参,类型形参…);函数的返回值函数的返回值是通过函数调用使主调函数得到的确定值例如:例2.3中:r=min(m,n);设m值为2,n值为3,那么

min(2,3)的值是2,赋值语句将这个函数值赋给变量r

函数的返回值函数的返回值是通过函数中的return语句获得一个函数中可以有一个以上的return语句,执行到哪一个return语句,哪一个语句起作用。参考例7.4return语句后面的括弧也可以不要例如:“returnz;”等价于“return(z);return后面的值可以是一个表达式例如:intmin(int

x,int

y){return(x<y?x:y);}函数的返回值函数的返回值应当属于某一个确定的类型,在定义函数时指定函数返回值的类型例如:下面是3个函数的首行:intmax(floatx,floaty)/*函数值为整型*/charletter(charc1,charc2)/*函数值为字符型*/doublemin(int

x,int

y)/*函数值为双精度型*/

注意:凡不加类型说明的函数,自动按整型处理。但C99已取消该规定函数的返回值在定义函数时指定的函数类型一般应该和return语句中的表达式类型一致如果函数值的类型和return语句中表达式的值不一致,则以函数类型为准。对数值型数据,可以自动进行类型转换。即函数类型决定返回值的类型。对于不带回值的函数,应当用“void”定义函数为“无类型”(或称“空类型”)。此时在函数体中可以不出现return,或通过一个不带表达式的return返回函数的返回值例7.4对函数max的三次调用main(){int

a,b,c;

printf("pleaseinputa,b:\n");

scanf("%d,%d",&a,&b);c=max(a,b);

printf("max=%d\n",c);a=16;b=24;

printf("max=%d\n",max(a,b));

max(a+b,a*b);}max(int

x,inty){

if(x>=y)return(x);elsereturn(y);}函数参数传递形参

int

max(int

x,inty){

。。。

}实参

main(){c=max(a,b);

}函数参数传递如果实参表列包含多个实参,则各参数间:用逗号隔开实参与形参的个数应相等,类型应匹配实参与形参按顺序对应,一一传递数据函数调用如果实参表列包括多个实参,对实参求值的顺序并不是确定的,有的系统按自左至右顺序求实参的值,有的系统则按自右至左顺序inti=1;printf("%d,%d",i,i++);形参与实参形式参数在函数调用发生时获得内存空间,进而接受相应实际参数的值;在调用结束后,形参所占的内存单元也被释放。实参可以是常量、变量或表达式,函数调用发生前计算每个实际参数的值实际参数与形式参数在数目、类型、顺序上保持一致或赋值兼容函数的返回值main(){int

a,b,c;

printf("pleaseinputa,b:\n");

scanf("%d,%d",&a,&b);c=max();

printf("max=%d\n",c);}变形:1、没有函数声明,不带实参调用函数max2、加上函数声明,不带实参调用函数max3、没有函数声明,实参形参不匹配调用c=max(1.1,b);4、加上函数声明,实参形参不匹配调用c=max(1.1,b);max(int

x,inty){

if(x>=y)return(x);elsereturn(y);}形参与实参值传递:实参向形参的数据传递是单向“值传递”,只能由实参传给形参,而不能由形参传回来给实参函数内部对形式参数值的改变不会对实际参数产生任何影响形参与实参#include<stdio.h>

例7.5voidswap(inta,intb){a=a+b;b=a-b;a=a-b;

printf("\na=%d,b=%d",a,b);}main(){

inta=10,b=20;

swap(a,b);

printf("\na=%d,b=%d",a,b);}函数的嵌套调用嵌套定义在定义一个函数时,其函数体内又包含另一个函数的完整定义嵌套调用在一个被调用的函数中,又调用另一个函数函数的嵌套调用main(){

...

fun1();

...}fun1(){

...

fun2();

...

return;}fun2(){

...

fun3();

...

return;}fun3(){

...

return;}函数的嵌套调用例7.6编程计算1!+2!+…+N!doublefac(intn){ 计算当前参数n的阶乘并返回}doubleSfac(intn){

for(i=1;i<=n;i++){调用fac计算出i的阶乘累加求和

}

返回累加和值

}main(){ s=Sfac(n);}函数的递归调用一个函数自己调用自己,称为递归求n!也可以用递归方法,即5!=4!×5,而4!=3!×4

1!=1。可用下面的递归公式表示:n!=1(n=0,1)n!=n·(n-1)!(n>1)函数的递归调用#include<stdio.h>longfac(intm);main(){

intn;

printf("\nn=");

scanf("%d",&n);

printf("%d!=%ld\n",n,fac(n));}

例7.7longfac(intm){longp;

if(m>1)p=m*fac(m-1);elsep=1L;

return(p);}变量的作用域-局部变量在一个函数内部定义的变量称内部变量。它只在本函数范围内有效,即:只有在本函数内才能使用这些变量,故称为“局部变量”参考例2.3变量的作用域-局部变量main(){int

a=10;

printf("\n*a=%d,",a);{int

a=20;

printf("**a=%d,",a);}

func();

printf("****a=%d\n",a);}voidfunc(){

int

a=30;

printf("***a=%d,",a);}例7.8局部变量主函数中定义的变量只在主函数中有效,而不因为在主函数中定义而在整个文件或程序中有效。主函数也不能使用其他函数中定义的变量不同函数中可以使用相同名字的变量,它们代表不同的对象,互不干扰形式参数也是局部变量在一个函数内部,可以在复合语句中定义变量,这些变量只在本复合语句中有效,这种复合语句也称为“分程序”或“程序块”变量的作用域-全局变量函数之外定义的变量称为外部变量。外部变量可以为本文件中其他函数所共用。它的有效范围为从定义变量的位置开始到本源文件结束。所以也称全程变量。变量的作用域-全局变量#include<stdio.h>例7.10inta=1,b=2;//外部变量a,bvoidfac(){inta=3;//内部变量a与外部变量a同名

printf("\nfac:a=%d,b=%d\n",a,b);}main(){intb=4;//内部变量b与外部变量b同名

fac();

printf("main:a=%d,b=%d\n",a,b);}

变量的存储类型从变量的作用域(即从空间)角度来分,可以分为全局变量和局部变量从变量值存在的时间角度来分,又可以分为静态存储方式和动态存储方式变量的存储类型变量和函数有两个属性:数据类型和数据的存储类别。存储类别指的是数据在内存中存储的方式。存储方式分为两大类:静态存储类和动态存储类。包含:自动的(auto)静态的(static)寄存器的(register)外部的(extern)变量的存储类型自动变量auto:不专门声明为static存储类别的局部变量都是动态分配存储空间,在调用该函数时系统会给它们分配存储空间,在函数调用结束时就自动释放这些存储空间。函数中的形参和在函数中定义的变量(包括在复合语句中定义的变量),都属此类自动变量用关键字auto作存储类别的声明变量的存储类型register变量变量的值是存放在内存中的。当程序中用到哪一个变量的值时,由控制器发出指令将内存中该变量的值送到运算器中。经过运算器进行运算,如果需要存数,再从运算器将数据送到内存存放变量的存储类型如果有一些变量使用频繁,为提高执行效率,C语言允许将局部变量的值放在CPU中的寄存器中,需要用时直接从寄存器取出参加运算,不必再到内存中去存取。这种变量叫做寄存器变量,用关键字register作声明只能用于整型和字符型,且个数有限不能使用取地址运算优化应该依靠编译器变量的存储类型当函数中的局部变量的值在函数调用结束后不消失而保留原值时,该变量称为静态局部变量。用关键字static进行声明变量的存储类型int

sum(intx)例7.11{staticintj=0;//定义静态整型变量jj=j+x;returnj;}main(){

inti=1;

printf("sum(i)=");

for(;i<=5;i+=2)printf("%d,",sum(i));

printf("i=%d\n",i);}变量的存储类型静态局部变量属于静态存储类别,在静态存储区内分配存储单元。在程序整个运行期间都不释放。而自动变量(即动态局部变量)属于动态存储类别,占动态存储区空间而不占静态存储区空间,函数调用结束后即释放对静态局部变量是在编译时赋初值的,即只赋初值一次,在程序运行时它已有初值。以后每次调用函数时不再重新赋初值而只是保留上次函数调用结束时的值变量的存储类型如在定义局部变量时不赋初值的话,则对静态局部变量来说,编译时自动赋初值0(对数值型变量)或空字符(对字符变量,NUL

)。而对自动变量来说,如果不赋初值则它的值是一个不确定的值虽然静态局部变量在函数调用结束后仍然存在,但其他函数不能引用它变量的存储类型外部变量是在函数的外部定义的全局变量,它的作用域是从变量的定义处开始,到本程序文件的末尾。在此作用域内,全局变量可以为程序中各个函数所引用。编译时将外部变量分配在静态存储区。用extern来声明外部变量,以扩展外部变量的作用域变量类别小结变量的生存期是从时间的角度来看变量,是指从分配存储空间开始一直到存储空间被释放的这段时期全局变量的生存期,是从其定义开始一直到整个程序运行结束局部变量的生存期,随着定义它的代码的执行而存在,随着该代码的执行结束而消亡变量类别小结变量的作用域是从空间的角度来看变量,是指变量在程序的哪些区域有效变量允许的存储类别作用域外部变量省略从定义到程序结束,也可被其它源文件使用static从定义到程序结束,仅能被定义它的文件使用内部变量省略

温馨提示

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

评论

0/150

提交评论