C语言chap6(函数与宏定义)

上传人:油条 文档编号:33780124 上传时间:2018-02-17 格式:PPT 页数:40 大小:358.50KB
返回 下载 相关 举报
C语言chap6(函数与宏定义)_第1页
第1页 / 共40页
C语言chap6(函数与宏定义)_第2页
第2页 / 共40页
C语言chap6(函数与宏定义)_第3页
第3页 / 共40页
C语言chap6(函数与宏定义)_第4页
第4页 / 共40页
C语言chap6(函数与宏定义)_第5页
第5页 / 共40页
点击查看更多>>
资源描述

《C语言chap6(函数与宏定义)》由会员分享,可在线阅读,更多相关《C语言chap6(函数与宏定义)(40页珍藏版)》请在金锄头文库上搜索。

1、2018/2/17,1,6.1 函数概念,第 6 章 函数与宏定义,在进行程序设计时,程序员总是将复杂的问题进行分解, 化整为零。编写一段小程序就能解决一个小问题,然后将这些小程序拼装起来就能解决非常大而复杂的问题。在 C 中,这些小程序统称为函数。,在 C 中,由系统提供的函数放在函数库中供用户选用,以减少重复编写程序模块的工作量。, 所有函数都是平行的,相互独立不能嵌套,但可以相 互调用(main函数不能被其它函数调用)。, C 函数分标准函数(库函数)和自定义函数。, C 函数本身分有参函数和无参函数。,2018/2/17,2,6.2 函数定义的一般形式,1无参函数的定义形式,类型标识符

2、 函数名( ) 说明部分 ; 语句;,无参函数一般不需要返回函数值,可以省略类型标识符。,2有参函数的定义形式,类型标识符 函数名(形式参数表)形式参数说明; 说明部分 ; 语句;,无分号!,无分号!,2018/2/17,3,3“ 空函数 ”,例:int max(x,y)int x, y;/ 形式参数说明 / int z;/ 函数体中的说明部分 / z=xy ? x : y; return(z);,类型说明符 函数名( ) ,“空函数”什么操作也不做。其作用是在此处留一函数的位置,以便将来扩充功能之用。函数名也在将来换取实际的函数名。,这两行可以写成一行:int max(int x, int

3、y),2018/2/17,4,6.3 函数参数和函数的值,1形式参数和实际参数,例6.1 从键盘输入两个数,输出其中较大的一个。 main( ) int a, b, c ; scanf(“%d,%d”, ,2018/2/17,5, 形参变量在被调用前不占用存储单元;在被调用结束后,形参所占存储单元亦被释放。 实参可以是常量、变量或表达式。 必须指定形参类型,且必须与实参的类型一致。 实参对形参的数据传递是“值传递”。即单向传递,不能逆传。 可以在形参表中直接说明形参类型。如: int max(int x, int y); float fun(int a10, int n);,注意:,2018/

4、2/17,6, 函数的返回值是通过return语句获得的。当不需返回函数值时,可省去return语句。 return语句的后面可以有括号,也可以没有。如: return z ; return(z); return语句的后面可以是变量,也可以是表达式。如: return(x y ? x : y); return语句返回值的类型应与该函数的类型一致。否则以函数类型为准。,2函数的返回值,2018/2/17,7, 若函数中没有return语句,则该函数被调用后也会带回不确定的值。如:main( ), int a, b, c ; a=printstar( ); b=print_message( );

5、c=printstar( ); printf(“%d,%d,%dn”,a,b,c);,输出的a, b, c的值将是随机值。, 为了明确表示不需要函数返回值,可以用“void”定义函数为“无类型”。此时,不得使用a=printstar( )之类的语句。,凡不需要返回值的函数,一般均定义为“void”类型。,2018/2/17,8,1函数调用的一般形式函数名(实参表);说明: 对于无参函数,尽管没有“实参表”,但也不得省略括号。 “实参表”中的参数之间用逗号分开。 实参与形参之间的个数及类型必须一一对应。 对实参求值的顺序是自左至右还是自右至左, 视具体的系统而定。Turbo C 和 MS C 是

6、按自右至左的顺序求值。,6.4 函数的调用,2018/2/17,9,例6.2main( ) int i =2 , p ; p = fun( i , + + i ); printf ( “%d”, p ) ;int fun ( a , b )int a , b ; int c ; if ( a b ) c = 1; else if ( a = = b ) c = 0 ; else c = 1 ; return( c ) ;,输出结果:0,注意:这里是按自右至左求值的,相当于fun(3,3)。若按自左至右求值,则相当于fun(2,3), 则输出为-1。,2018/2/17,10,调用函数,可以有如

7、下三种方式: 将函数调用作为一个语句。如: printf(“MS C pragramming”); gets(s); 将被调用的函数写在表达式中。如: c=2max(a, b);注意:被调用函数max必须有确定的返回值。 将函数调用作为一个函数的实参。如: m=max(max(a, b), c);3对被调用函数的说明在一个函数中调用另一个函数时: 如果被调函数为库函数,则应在文件开头用“#include”命令声明相应的“头文件”。如: #include “stdio.h” #include “math.h”,2函数调用的方式,2018/2/17,11,类型标识符 被调函数名( );如:floa

8、t add( ); 如果被调函数为自定义函数且其定义在主调函数定义之前,则在主调函数中可不必声明其类型。因为编译程序已知道其类型。 如果被调函数的值是整型或字符型,可不必声明类型,系统自动按整型说明。 如果在所有被调函数定义之前、在文件的开头、在函数的外部已对被调函数作了类型说明,则在各主调函数中可不必说明其类型。如: char letter( ); float f( ); int i( ); main( ) / 不必说明它所调用的函数的类型 /, 如果被调函数为自定义函数且其定义在主调函数定义之后,则应在主调函数中声明其类型(称之为”函数声明”)。其语句形式为:,2018/2/17,12,例

9、6.3 编程求11999之间的数m,而m、m2和m3均是回文数(数位左右对称)。如:m=11、m2=121、m3=1331, 。,#include “stdio.h”main( )long int m; for (m=11; m1000; m+) if (fun(m),2018/2/17,13,C 语言函数的定义都是相互平行、独立的,不能嵌套定义。但可以嵌套调用函数。所谓函数的嵌套调用就是在被调用的函数中又调用另外的函数。 6.6 函数的递归调用 在调用一个函数的过程中又出现直接或间接地调用该函数本身,称为函数的递归调用。,6.5 函数的嵌套调用,2018/2/17,14,例6.4 有5人排成

10、一队,从最后一人开始,其年龄均比前面的人大2岁,而最前面的人年龄是10岁,问最后一人的年龄是多少岁?,Main( ),age(5),age(4)+2,age( )n=5,age(3)+2,age( )n=4,age(2)+2,age( )n=3,age(1)+2,age( )n=2,age(1) =10,age( )n=1,age(1)=10,age(1)=12,age(1)=14,age(1)=16,age(1)=18,输出age(5),2018/2/17,15,函数的递归调用利用了堆栈技术。在本例中:,Age(5),Age(51)+2,Age(41)+2,Age(31)+2,Age(21)

11、+2,10+2=12,12+2=14,14+2=16,16+2=18,18,Age(21)+2,Age(31)+2,Age(41)+2,Age(51)+2,Age(5),Age(5),Age(51)+2,Age(41)+2,Age(31)+2,Age(21)+2,入栈,出栈,出栈结果,写出下面程序的运行结果:例6.4 e#include stdio.hfun(int x)int p; if(x=0|x=1) return 3; p=x-fun(x-2); return p; void main() printf(%dn,fun(9); ,结果为:7,2018/2/17,17,汉诺塔问题参考程序

12、(将A座上的N个disks 借助B座移动到C座),#include stdio.hvoid h(int m,char x,char y,char z);void main()int n; char a=a;char b=b;char c=c; printf(input disks:); scanf(%d, ,2018/2/17,18,1局部变量在一个函数内部定义的变量,只能在本函数内使用和有效,称为“局部变量”。主函数main中定义的变量,也只能在主函数内使用和有效。不同函数中可以使用相同名字的变量,且互不干扰。形式参数也是局部变量,也只能在所在函数内使用和有效。可以在一个函数内的复合语句中定

13、义变量,且这些变量只在本复合语句中有效。 这种复合语句也称为“分程序”或“子模块”。2全局变量 在函数(包括main函数)外定义的变量为外部变量,称为“全局变量”。全局变量的有效范围为从定义变量的位置开始到本源文件结束。,6.7 局部变量和全局变量,2018/2/17,19, 如无必要,不要使用全局变量。因为全局变量既降低程序的清晰性和函数的通用性,且又在程序的全部执行过程中都占用存储空间。 在文件开头定义的外部变量才可在整个文件范围内使用,若在定义点之前的函数需引用外部变量,则可用关键字“extern”作“外部变量说明”。注意:外部变量定义和外部变量说明并不是同一回事。外部变量的定义只能有一

14、次,它的位置在所有函数之外。而同一程序中的外部变量说明可以有多次,它的位置在函数之内(哪个函数要用就在哪个函数中说明)。系统根据外部变量的定义(而不是根据外部变量的说明)分配存储单元。对外部变量的初始化只能在“定义”时进行,“extern”只是申明该变量是一个已在外部定义过的变量而已。 如果在同一源文件中,外部变量与局部变量同名,则在局部变量的作用范围内,外部变量不起作用。, 全局变量增加了函数间数据联系的渠道。由于同一文件中的所有函数都能引用全局变量的值,当需要从一个函数中带回多个值时,就能克服函数调用只能返回一个值的局限性。,2018/2/17,20,输出结果:10, 4, 810, 2,

15、 5,例6.5#include “stdio.h”main( ) int a=1, b=2, c=3; a+; c+=b; int b=4, c; c=2b; a+=c; printf(“%d,%d,%dn”, a, b, c); printf(“%d,%d,%dn”, a, b, c);,C编译內存管理示意图:,程序区,静态存储区,用户定义存储区,动态存储区,数据区,2018/2/17,22,1变量的存储类别 静态变量在程序的运行期间占用固定的存储空间,直到程序的终止而释放;而动态变量是在程序的运行期间随着函数的调用随时动态地占用和释放存储空间。即存储方式是根据变量的存储类别决定的。C的存储类别有四种: 自动的(auto)、静态的(static)、寄存器的(register)、外部的(extern)。2局部变量的存储方式函数中的局部变量若未专门说明,都是由编译系统自动动态分配存储空间,这类局部变量称为自动变量,其类型说明前不论是否有关键字“auto”,都属于动态存储类别。,

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 行业资料 > 其它行业文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号