资源预览内容
第1页 / 共62页
第2页 / 共62页
第3页 / 共62页
第4页 / 共62页
第5页 / 共62页
第6页 / 共62页
第7页 / 共62页
第8页 / 共62页
第9页 / 共62页
第10页 / 共62页
亲,该文档总共62页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
C语言程序设计The C Programming Language华中科技大学计算机学院 曹计昌*1华中科技大学计算机学院第5章 函数与程序结构 本章内容:n构化编程和C程序的一般结构。n函数的机制: 包括函数定义、函数声明、函 数调用、变量的存储类型、参数数目可变的 函数等。n递归与回溯: 包括解释递归与回溯的概念、 递归函数设计,以及递归调用。n多文件程序设计。 Date2华中科技大学计算机学院5.1 C程序的一般结构5.1.1 结构化程序设计结构化编程是一种解决问题的策略,它包括如下2 条编程标准: (1) 程序中的控制流应该尽可能简单。 (2) 应该自顶向下地设计程序结构。自顶向下设计也称为逐步细化,即把一个问题按功 能分解为若干子问题,如果子问题还较复杂,可将 其继续分解,直到分解成为容易求解的子问题为止 。分解而来的每个子问题被称为模块,C中提供的 函数机制完成每个模块的编程任务,即用函数编写 由分解而来的子问题的代码。Date3华中科技大学计算机学院例 显示从1到10的整数幂。* A TABLE OF POWERS *Int Square Cube Quartic Quintic1 1 1 1 12 4 8 16 323 9 27 81 2434 16 64 256 10245 25 125 625 31256 36 216 1296 77767 49 343 2401 168078 64 512 4096 327689 81 729 6561 5904910 100 1000 10000 100000Date4华中科技大学计算机学院自顶向下的分解问题:(1) 显示标题 (2) 显示表头 (3) 分列整齐地显示整数1到10的2至5次幂 每个子问题都能作为函数直接被编写成代码, 在main中调用这些函数,解决总的问题。Date5华中科技大学计算机学院#include void prn_banner(void); /* prn_banner的函数原型 */ void prn_headings(void); /* prn_headings的函数原型 */ double power(int x,int n); /* power的函数原型 */ void main(void) int i,j;prn_banner() ; /* 显示标题 */prn_headings(); /* 显示表头 */for(i=1;i0 */double power(int x,int n) /*不能为 double power(int x,n) */ int i;double p;for (i=1,p=1;i void prn_banner(void) void prn_headings(void) double power(int x,int n) void main(void) Date17华中科技大学计算机学院2函数原型n 函数定义出现在函数调用后n 被调用函数在其它文件中定义必须在函数调用之前给出函数原型。Date18华中科技大学计算机学院函数原型的一般形式类型名 函数名(参数类型表);参数类型表通常是用逗号隔开的形参类型列 表,而形参名可以省略。例如,double power(int, int); 等价于 double power(int x, int n);无参函数的函数原型参数表必须指定为void Date19华中科技大学计算机学院函数原型的作用函数原型告诉编译器函数返回值的数据类型 ,传递给函数的参数个数、参数类型和参数 顺序。编译器用函数原型校验函数调用, 强 制转换传递的参数类型,从而避免错误的函数 调用导致的致命运行错误或微妙而难以检测 的非致命逻辑错误。例如,printf (“%.1f n“, sqrt(4) ) ; (1)包含了math.h,输出 2.0 */ (2)没有包含math.h,函数调用sqrt(4)不会 产生正确的值。 Date20华中科技大学计算机学院3遗漏函数原型 编译器首次遇到没有声明的函数调用时,将构造一 个缺省声明并继续编译:int f(); /*函数是int类型,但不给出参数表信息*/(1) 函数类型不是int,给出一个错误提示:Type mismatch in redeclaration of f(2) 函数类型是int,就不给出错误提示。编译器对 参数类型不作检查,把正确类型的参数传递给函数 是程序员的责任。假设函数f只有一个类型为int的 参数,函数调用f (2)会产生正确的值,而函数调用 f(2.5)将产生错误的运行结果。 Date21华中科技大学计算机学院良好的编程风格n 在函数调用之前必须给出它的函数定义、函 数原型或两者都给出。n 引入标准头文件的主要原因是它含有函数原 型。 Date22华中科技大学计算机学院5.3 函数调用与参数传递 5.3.1 函数调用 1函数调用的形式 函数名(实参列表) 实参是一个表达式 ,对于无函数,调用形式 :函数名() Date23华中科技大学计算机学院函数调用在程序中出现的形式(1) 作为表达式语句出现。prn_headings();putchar(c); (2)作为表达式中的一个操作数出现。例如:c=getchar()sum += power(i,j); (3)作为函数调用的一个实参出现,即嵌套调用。printf(“%10.0f“, power(i , j) );putchar ( getchar() ); Date24华中科技大学计算机学院2. 函数调用的执行过程 #include int max(int,int); void main(void) int m, a=3, b=4;m=max( a, b );printf(“%d“,m); int max( int x, int y ) if(xy) return x;else return y; Date25华中科技大学计算机学院3实参的求值顺序n实参的求值顺序由具体实现确定,有的按从 左至右的顺序计算,有的按从右至左的顺序 计算a=1;max (a,a+) -从左至右:max(1,1)-从右至左:max(2,1) (多数 )为了保证程序清晰、可移植,应避免使用会 引起副作用的实参表达式 .n实参的求值顺序C语言采用从右至左规则 Date26华中科技大学计算机学院实参的求值顺序C语言采用从右至左规则#include “stdio.h“ void main(void) int x=1;printf(“%dt%dt%dn“,x,x+,x); 运行结果: 2 1 1Date27华中科技大学计算机学院5.3.2 参数的值传递 n参数的传递方式是“值传递”,实参的值单向 传递给相应的形参。n如果实参、形参都是x,被调用函数不能改 变实参x的值。Date28华中科技大学计算机学院例 说明值传递概念的程序#includelong fac(int);void main() int n=4;printf(“%dn“,n); /* 输出4 */printf(“%ldn“,fac(n); /* 输出24 */printf(“%dn“,n); /* 输出4 */long fac(int n) /* 计算n的阶乘 */ long f=1;for( ;n0;-n) f *=n ; /* main中的n值未改变 */printf(“%dn“,n); /* 输出0 */return(f);Date29华中科技大学计算机学院5.4 作用域 作用域:程序正文中可以使用该标识符的那 部分程序段。根据作用域,变量有两类: 局部变量:在函数内部定义的变量,作用域 是定义该变量的程序块,程序块是带有说明 的复合语句(包括函数体)。不同函数可同 名,同一函数内不同程序块可同名。形式参 数是局部变量。 外部变量:在函数外部定义的变量,其作用 域从其定义处开始一直到其所在文件的末尾 ,可由程序中的部分或所有函数共享。Date30华中科技大学计算机学院关键字extern的作用int sp=0;/*sp是外部变量 ,main,push和pop均可访问 */ void main() /* val不能用在main中 */ double valMAXVAL; /* val是外部数组 */ void push(double f ) double pop(void) n利用extern对外部变量进行声明可以扩大其作用 域,使得外部变量在定义之前可以使用,以及其它 源文件中的函数也可以使用。例如void main() extern double valMAXVAL; Date31华中科技大学计算机学院外部变量的声明和定义的区别 外部变量的声明用于通报变量的类型(引用性声明) 外部变量的定义除此以外还引起存储分配(定义性声 明)int sp;这是外部变量的定义,一方面说明了sp类型为int ,另一方面系统还要为其分配2B的存储单元。而extern int sp ;这是外部变量的声明,仅仅说明了sp类型为int, 不会为其分配存储单元。外部变量只能定义一次,而外部变量的声明可以出 现多次。外部变量的初始化只能出现在其定义中。Date32华中科技大学计算机学院5.5 存储类型n变量和函数都有两个属性:数据类型和存储类型。n函数的存储类型决定函数的作用域,可使用的关键 字有extern和static(5.9节)。n变量的存储类型决定变量的作用域、存储分配方式 、生命周期和初始化方式,可使用的关键字有: auto、extern、static和register。存储分配方式:在何时、何处给变量分配存储单元;生命周期:变量在内存中的存在期;初始化方式:在定义变量时如果未显示初始化,是否 有缺省初值,如果有显示初始化,赋初值操作如何 执行(执行一次还是执行多次)。Date33华中科技大学计算机学院5.5.1 存储类型auto 局部变量的缺省存储类型是auto,称自动变量 auto int a; /*等价于int a; 也等价于auto a; */作用域:局
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号