chap6函数与宏定义.ppt

上传人:本田雅阁 文档编号:2976395 上传时间:2019-06-16 格式:PPT 页数:40 大小:290.51KB
返回 下载 相关 举报
chap6函数与宏定义.ppt_第1页
第1页 / 共40页
chap6函数与宏定义.ppt_第2页
第2页 / 共40页
chap6函数与宏定义.ppt_第3页
第3页 / 共40页
chap6函数与宏定义.ppt_第4页
第4页 / 共40页
chap6函数与宏定义.ppt_第5页
第5页 / 共40页
点击查看更多>>
资源描述

《chap6函数与宏定义.ppt》由会员分享,可在线阅读,更多相关《chap6函数与宏定义.ppt(40页珍藏版)》请在三一文库上搜索。

1、第 6 章 函数与宏定义,6.1 函数概念,C 函数分标准函数(库函数)和自定义函数。, 所有函数都是平行的,相互独立不能嵌套定义,函数间可以相互调用,但不能调用main()函数。,6.1.1 函数的定义,古典形式: 类型标识符 函数名(形式参数表) 形式参数说明; 函数体; 现代简洁形式: 类型标识符 函数名(形参说明表) 函数体; ,例: int max(x,y) int x, y; / 形式参数说明 / int z; / 函数体中的说明部分 / z=xy ? x : y; return(z); ,这两行可以写成一行: int max(int x, int y),例: int max(in

2、t x, int y) int z; / 函数体中的说明部分 / z=xy ? x : y; return(z); ,函数参数和函数的值,1形式参数和实际参数,例 从键盘输入两个数,输出其中较大的一个。 main( ) int a, b, c ; scanf(“%d %d“, , 形参变量在被调用前不占用存储单元;在被调用结束后,形参所占存储单元亦被释放。 实参可以是常量、变量或表达式。 必须指定形参类型,且应与实参的类型一致。 实参对形参的数据传递是“值传递”。即单向传递,不能逆传。,注意:, 函数的返回值是通过return语句获得的。 return语句的后面可以有括号,也可以没有。如: r

3、eturn z ; return(z); return语句的后面可以是变量,也可以是表达式。如: return(x y ? x : y); return语句返回值的类型应与该函数的类型一致。否则以函数类型为准。 函数类型缺省时按整型处理。,2函数的返回值, 若函数中没有return语句,则函数被调用后也会带回不确定的值。, 为了明确表示不需要函数返回值,可以用“void”定义函数为“无类型”。此时,不得使用a=f( )之类的赋值语句。,凡不需要返回值的函数,一般均定义为“void”类型。,1函数调用的一般形式 函数名(实参表) 说明: 对于无参函数,也不得省略一对小括号。 “实参表”中的参数之

4、间用逗号分开。 实参与形参之间的个数及类型必须一一对应。,函数的调用, 将函数调用作为一个语句。如: printf(“MS C pragramming”); gets(s); 将被调用的函数写在表达式中。如: c=2max(a, b); 注意:被调用函数max必须有确定的返回值。 将函数调用作为一个函数的实参。如: m=max(max(a, b), c);,2函数调用的方式,3对被调用函数的说明 在一个函数中调用另一个函数时: 如果被调函数为库函数,则应在文件开头用“#include”命令声明相应的“头文件”。如: #include “stdio.h” #include “math.h”, 如

5、果被调函数为自定义函数且其定义在主调函数定义之后,则应在主调函数中对该函数进行声明。其语句形式一般为: 类型标识符 被调函数名(参数列表); 如:float add(int x, int y );, 如果被调函数为自定义函数且其定义在主调函数定义之前,则在主调函数中可不必声明。 如果已在所有函数定义之前已作了函数声明,则在各主调函数中可不必对所调用的函数再作声明。如: char letter( ); float f( ); int i( ); main( ) / 不必说明它所调用的函数的类型 /,1局部变量 局部变量-在一个函数内部定义的变量,只能在本函数内使用和有效。 主函数main中定义的

6、变量,也只能在主函数内使用和有效。 不同的函数中可以使用相同名字变量,且互不干扰。 形式参数也是局部变量,也只能在所在函数内使用和有效。 可以在一个函数内的复合语句中定义变量,且这些变量只在本复合语句中有效。 这种复合语句也称为“分程序”或“子模块”。,局部变量和全局变量,6.2 变量的作用域和存储类型,2全局变量 全局变量(外部变量)-在函数(包括main函数)外定义的变量。其有效范围为从定义变量的位置开始到本源文件结束。,在文件开头定义的外部变量才可在整个文件范围内使用,若在定义点之前的函数需引用外部变量,则可用关键字“extern”作“外部变量声明”。 注意: 外部变量的定义只能有一次,

7、它的位置在所有函数之外。而同一程序中的外部变量声明可以有多次,它的位置在函数之内(哪个函数要用就在哪个函数中说明)。系统根据外部变量的定义(而不是根据外部变量的说明)分配存储单元。对外部变量的初始化只能在“定义”时进行,“extern”只是申明该变量是一个已在外部定义过的变量而已。 如果在同一源文件中,外部变量与局部变量同名,则在局部变量的作用范围内,外部变量不起作用。,输出结果: 10, 4, 8 10, 2, 5,例 #include “stdio.h“ main( ) int a=1, b=2, c=3; a+; c+=b; int b=4, c; c=2*b; a+=c; printf

8、(“%d,%d,%dn“, a, b, c); printf(“%d,%d,%dn“, a, b, c); getch(); ,内存中供用户使用的存储区由程序区、静态存储区和动态存储区组成。 变量的存储类型有四种: 自动的(auto):内存的动态存储区 静态的(static) :静态存储区 寄存器的(register):寄存器 静态变量在程序的运行期间占用固定的存储空间,直到程序的终止而释放; 动态变量是在程序的运行期间随着函数的调用随时动态地占用和释放存储空间。,变量的存储类型,局部变量的存储方式 函数中的局部变量若未专门说明,这类局部变量称为自动变量,其类型说明前不论是否有关键字“auto

9、”,都属于动态存储类别。,2) 若希望被调函数在结束后,其局部变量占用的存储空间不释放,以便保留其变量的值,用于下次调用该函数,则用“static”说明为 “局部静态变量”。, 局部静态变量 在静态存储区分配存储单元,在程序的整个运行期间都不释放。 在编译时只赋初值一次,以后每次被调用时不再重新赋值而只保留前次被调用结束时的值。 若未赋初值,则在编译时自动赋初值0 (数值型)或空字符(字符 型)。 虽然局部静态变量在函数被调用结束后其值仍然存在,但其它函数是不能引用的。 动态变量 在动态存储区分配存储单元,函数调用结束后即释放。 赋初值不是在编译时而是在函数被调用时进行的,函数每次被调用时重新

10、赋值。 若未赋初值,则其值是不确定的,例 打印1到5的阶乘值。 int fac(int n) static int f =1; / 定义f 为int型静态变量 / f = f n ; return( f ); main( ) int i; for (i=1; i=5; i+) printf(“%d!=%dn”, i, fac(i); ,3全局变量的存储方式 全局变量存储在静态区。 用extern作声明可以引用另一个文件中定义的全局变量。但用static定义的全局变量不能被其它文件引用。,根据函数是否能被其它文件所调用,分为: 1内部函数-只能被本文件的其它函数所调用的函数 定义方式 如: st

11、atic int fun(a, b); 2外部函数-可以被其它文件所使用的函数。 定义方式如: extern int fun(a, b); 如果省略extern,则隐含该函数为外部函数。,6.3 内部函数和外部函数,直接递归调用:在函数定义的语句中,存在着调用本函数的语句。 间接递归调用:在不同的函数定义中,存在着互相调用函数语句的情况。(P136),6.4 递归函数的设计和调用,一个函数能设计成为递归函数,在数学上必须具备以下两个条件: 1)问题的后一部分与原始问题类似 2)问题的后一部分是原始问题的简化 例6-7 例6-8,例6-7 编写程序,要求从键盘输入一个正整数n,计算n! 。 分析

12、:求n!可以表达为:,即:f(n)=n*f(n-1) n1 f(0)=1,f(1)=1,long fac(int n) long result; if(n=0|n=1) result=1; else result=n*fac(n-1); return result; main( ) int n; long f; printf(“Please enter value of n:n“); scanf(“%d“, ,“编译预处理”是C与其它高级语言的一个重要区别。它们主要是: 宏定义 文件包含 条件编译,6.5 预处理,1) 不带参数的宏定义 用指定的标识符(宏名)代表一串字符。 #define 宏

13、名 字符串,6.5.1 宏定义,例 求正圆锥体的底周长、底面积和它的体积。 #define PI 3.1415926 /* 宏名PI用大写,行末无分号 */ main( ) float l, s, r, v ; scanf(“%f“, , 进行宏定义时,可以引用已定义的宏名,层层置换。 对程序中用双引号括起来的字符串,即使与宏名相同,也不会被置换。, 宏名的有效范围为该宏定义命令之后至本源文件结束。通常,宏定义命令一般写在文件开头或函数之前作为该文件的一部分。, 可以用 #undef 命令终止宏定义的作用域。如: #define G 9.8 main( ) #undef G float f(

14、) ,G 的作用范围,2带参数的宏定义,语句形式: #define 宏名(形参表) 字符串,注意:字符串应包含形参表中的参数 例 #define PI 3.1415926 #define S(r) PI*r*r main( ) float a, area; a=3.6; area=S(a); /*area=3.1415926*a*a,但不会置换a为3.6 */ printf(“r=%f narea=%f n“,a,area); getch(); ,若将area=S(a) 改写成 area=S(a+2),将置换为: area=PI a+2a+2,而不是: area=PI (a+2)(a+2)。

15、若要达到后者,则应将宏定义命令改写为: #define S(r) PI (r) (r) 宏名与括号之间不得有空格,因为宏名与表达式之间的分隔符为空格。如果用#define S (r) PI r r 的话,则被置换为 area=(r) PI r r (a) 宏展开并不进行值的传递,即不求表达式的值,也没有“返回值”的概念。 宏不存在类型问题,宏名无类型,参数也无类型,表达式可以是任何类型。,注:这里的 t 展开后为 t = (a+b)(c+d)?(a+b):(c+d) 如果第一行写成: #define MAX(x,y) xy ? x : y 则这里的 t 展开后为 t = a+bc+d?a+b:

16、c+d 因为置换展开是用“表达式”对等的置换“形参表”中的参数。, 定义带参数的宏,可以实现一些简单的函数功能。,如: #define MAX(x,y) (x)(y)?(x) : (y) main( ) int a, b, c, t ; t = MAX(a+b, c+d); ,6.5.2 “文件包含”,用 #include 命令实现一个文件包含另一个文件。 语句形式: #include “文件名”,例 #include “stdio.h“ #define N 2 #define M N+1 #define NUM (M+1)*M/2 main( ) int i, n=0; for (i=1;

17、i=NUM; i+) n+; printf(“%2d“, n); getch(); ,输出结果: 1 2 3 4 5 6 7 8, 一个include命令只能指定一个被包含文件,如果要包含n个文件,则要用n个include命令。, NUM被代换展开后为:( 2+1+1) 2+1/2,#include命令中,文件名既可用双引“ ”号(推荐),也可用尖括号括起来。表示被包含在标准目录中(include).“”表示被包含文件在指定目录中,若只有文件名不带路径,则在当前目录中,若找不到,再到标准目录中找。 包含文件名可以是.c源文件或.头文件,如 #include #include “myhead.h

18、” #include “D:myexammyfile.c”,6.12 条件编译 语句形式: 1#ifdef 宏名 程序段1 #else 程序段2 #endif 作用:如果宏名已定义,则编译“程序段1”,否则编译“程序段2” 。,所谓“宏名已定义”是无论“宏名”定义为什么内容。 条件编译的作用:缩短编译时间,减少目标程序的长度。,作用:如果宏名未定义,则编译“程序段1” ,否则编译“程序段2”。 3#if 表达式 程序段1 #else 程序段2 #endif 作用:当“表达式”值为非0 ,则编译“程序段1” ,否则编译“程序段2”。,2#ifndef 宏名 程序段1 #else 程序段2 #en

19、dif,4#if 表达式1 程序段1 #elif 表达式2 程序段2 #else 程序段3 #endif 作用:当“表达式1”值为非0 ,则编译“程序段1” , 否则判断”表达式2”; 当“表达式2”的值为真,则编译“程序段2”,否则编译”程序段3”。,例 #define TED 10 main() #ifdef TED printf(“Hi,Tedn“); #else printf(“HI,Anyonen“); #endif #ifndef PALPH printf(“RAPLH not definedn“); #endif getch(); ,例,main() #if MAX99 prin

20、tf(“compile for array greater than 99“); #else printf(“compile for small array“); #endif getch(); ,例 #define N 2 #define M N+1 #define NUM 2*M+1 main( ) int i; for (i=1; i=NUM; i+) printf(“%dn“, i ); getch(); 程序中的 for 循环执行的次数是多少?,例 #define MAX(x, y) (x)(y)?(x) : (y) main( ) int a=5, b=2, c=3, d=3, t; t=MAX(a+b, c+d)*10; printf(“%dn“, t); /* t的值是多少? */ getch(); ,作业: 6.41,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 其他


经营许可证编号:宁ICP备18001539号-1