![《解析C程序设计》第3章自定义函数设计课件_第1页](http://file3.renrendoc.com/fileroot_temp3/2022-1/27/a714e8a9-77f2-4b85-9136-c47e958e5339/a714e8a9-77f2-4b85-9136-c47e958e53391.gif)
![《解析C程序设计》第3章自定义函数设计课件_第2页](http://file3.renrendoc.com/fileroot_temp3/2022-1/27/a714e8a9-77f2-4b85-9136-c47e958e5339/a714e8a9-77f2-4b85-9136-c47e958e53392.gif)
![《解析C程序设计》第3章自定义函数设计课件_第3页](http://file3.renrendoc.com/fileroot_temp3/2022-1/27/a714e8a9-77f2-4b85-9136-c47e958e5339/a714e8a9-77f2-4b85-9136-c47e958e53393.gif)
![《解析C程序设计》第3章自定义函数设计课件_第4页](http://file3.renrendoc.com/fileroot_temp3/2022-1/27/a714e8a9-77f2-4b85-9136-c47e958e5339/a714e8a9-77f2-4b85-9136-c47e958e53394.gif)
![《解析C程序设计》第3章自定义函数设计课件_第5页](http://file3.renrendoc.com/fileroot_temp3/2022-1/27/a714e8a9-77f2-4b85-9136-c47e958e5339/a714e8a9-77f2-4b85-9136-c47e958e53395.gif)
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、l最大值和最小值问题最大值和最小值问题 条件运算符条件运算符 函数的定义函数的定义 函数的调用函数的调用 函数的返回函数的返回 参数的传递参数的传递 函数的声明函数的声明 l交换两个变量值的问题交换两个变量值的问题 变量的作用域变量的作用域 变量的存储类型变量的存储类型 前面的所有程序都是由一个主函数前面的所有程序都是由一个主函数main()组成,程序的所有操作都在主函数中完成。组成,程序的所有操作都在主函数中完成。(当然也包含一些库函数)(当然也包含一些库函数) 对于小程序可以这样做,但是,对于一个对于小程序可以这样做,但是,对于一个有一定规模的程序这样做就不合适了。有一定规模的程序这样做就
2、不合适了。 事实上,事实上,C程序可以程序可以 只包含一个主函数只包含一个主函数 也可以包含一个主函数和若干个其它函数(库也可以包含一个主函数和若干个其它函数(库函数和自定义函数)函数和自定义函数) C语言是一个函数式语言。语言是一个函数式语言。(1)用户自定义函数(包括主函数);)用户自定义函数(包括主函数);(2)系统提供的库函数。由)系统提供的库函数。由C系统开发商提系统开发商提供,程序员可以直接调用。供,程序员可以直接调用。 自定义函数以下简称函数。自定义函数以下简称函数。 下面通过一个简单问题来初步了解自定义下面通过一个简单问题来初步了解自定义函数的用法。函数的用法。 例例3-1 由
3、用户输入三个整数,编程求解三由用户输入三个整数,编程求解三个数的最大值和最小值。个数的最大值和最小值。【分析分析】 根据前面所学,本问题将可以所有功能都在主函数中完成。根据前面所学,本问题将可以所有功能都在主函数中完成。也可以用两个函数分别完成求最大值和最小值,在主函数中调也可以用两个函数分别完成求最大值和最小值,在主函数中调用这两个函数即可。这样的好处是,可以实现代码共享,而且用这两个函数即可。这样的好处是,可以实现代码共享,而且使相对独立功能的代码分离,便于维护。使相对独立功能的代码分离,便于维护。 求最大值和最小值可以使用条件运算符完成,当然还有其求最大值和最小值可以使用条件运算符完成,
4、当然还有其他办法(你知道吗?)。他办法(你知道吗?)。 另外还涉及到函数的定义、函数的调用、函数值的返回、另外还涉及到函数的定义、函数的调用、函数值的返回、参数的传递、函数的声明等基本知识。下面逐步介绍。参数的传递、函数的声明等基本知识。下面逐步介绍。v一般形式:一般形式: expr1 ? expr2 : expr3v运算规则:运算规则:例例 求求 a+|b| printf(“a+|b|=%dn”,b0?a+b:a-b);v条件运算符可嵌套条件运算符可嵌套 如如 x0?1:(xb?a:cd?c:d ab?a:(cd?c:d)vexpr1、expr2、expr3类型可不同,表达式值取较高类型可不
5、同,表达式值取较高的类型的类型 expr2 当当expr1非非0expr1 ? expr2 : expr3= expr3 当当expr1非非0 max=xy?x:y; 合法标识符合法标识符函数返回值类型:缺省函数返回值类型:缺省int型,无返回值型,无返回值void函数体函数体函数类型函数类型 函数名(形式参数类型说明表)函数名(形式参数类型说明表)声明部分声明部分执行部分执行部分现代风格现代风格: :例例 有参函数(现代风格)有参函数(现代风格) int max(int x,int y) int z; z=xy?x:y; return(z); 例例 有参函数(现代风格)有参函数(现代风格)
6、int max(int x,int y) int z; z=xy?x:y; return(z); 例例 空函数空函数 dummy( ) 函数体为空函数体为空例例 无参函数无参函数void printstar( ) printf(“*n”); 或或void printstar(void ) printf(“*n”); 参数:传递数参数:传递数据信息的通道据信息的通道函数类型函数类型 函数名(形式参数表)函数名(形式参数表)形参类型说明形参类型说明声明部分声明部分执行部分执行部分例例 有参函数(传统风格)有参函数(传统风格) int max(x,y) int x,y; int z; z=xy?x:
7、y; return(z); 一般情况下,均使一般情况下,均使用现代风格定义函用现代风格定义函数,并且要指定函数,并且要指定函数类型。数类型。 函数类型表示在调用了该函数后,其返回值的数据类型。可为:函数类型表示在调用了该函数后,其返回值的数据类型。可为:intint、charchar、floatfloat、doubledouble等。如果函数无数据返回时,应使用等。如果函数无数据返回时,应使用void void 作类型定义作类型定义符。注意,省略了类型说明符,符。注意,省略了类型说明符,C C编译器认为函数返回值为一个整型值类型编译器认为函数返回值为一个整型值类型(intint)。)。 函数名
8、即函数的名称,是由用户取的合法标识符。函数名即函数的名称,是由用户取的合法标识符。C C语言的关键字不语言的关键字不能作函数名。自定义函数的名称可以使用库函数名,但这时库函数被屏蔽。能作函数名。自定义函数的名称可以使用库函数名,但这时库函数被屏蔽。 形式参数表是一个用逗号分隔的变量表,当函数被调用时这些变量接形式参数表是一个用逗号分隔的变量表,当函数被调用时这些变量接受调用参数的值。相当于函数调用时传递信息的通道。注意:每个参数必须受调用参数的值。相当于函数调用时传递信息的通道。注意:每个参数必须指明类型!指明类型! 在函数的定义中,如果没有函数体,即函数什么功能都不做,我们称在函数的定义中,
9、如果没有函数体,即函数什么功能都不做,我们称为空函数。空函数的功能主要是在程序设计中,留出该函数的功能,以后在为空函数。空函数的功能主要是在程序设计中,留出该函数的功能,以后在需要的时候补充上去。需要的时候补充上去。(1 1)函数不能单独运行,函数可以被主函数或其它函数调用,)函数不能单独运行,函数可以被主函数或其它函数调用,也可以调用其它函数,但是不能调用主函数。也可以调用其它函数,但是不能调用主函数。(2 2)C C规定,函数体的声明部分和执行部分应严格划分,且声规定,函数体的声明部分和执行部分应严格划分,且声明部分放在函数体的开始。明部分放在函数体的开始。例如,以下定义是不允许的:例如,
10、以下定义是不允许的:void main() double x; scanf(%lf,&x); double s; /* 不能在执行语句中穿插定义变量不能在执行语句中穿插定义变量 */ scanf(%lf,&s); 定义两个函数:定义两个函数:l求两个整数的最大值函数求两个整数的最大值函数l求两个整数的最小值函数求两个整数的最小值函数int max(int x,int y) return(xy?x:y);int min(int x,int y) return(xy?x:y);void main() int a,b,c,d,t; . t=max(a+b,c+d); 被调函数被调函数
11、主调函数主调函数(1)作为函数语句调用。)作为函数语句调用。函数一般无返回值。例:函数一般无返回值。例:printf(“Hello,World!n”);(2)作为函数表达式调用。)作为函数表达式调用。例:例:m=max(a,b)*2;(3)作为函数参数调用。)作为函数参数调用。例:例:printf(“%d”,max(a,b); m=max(a,max(b,c);如果调用的是无参函数,则如果调用的是无参函数,则“实际参数表实际参数表”可以可以没有,但括号没有,但括号()不能省略。不能省略。如果实参表包含多个实参,则各参数间用逗号隔如果实参表包含多个实参,则各参数间用逗号隔开。开。实参与形参的个数
12、应相等、类型应一致。实参与形参的个数应相等、类型应一致。实参与形参按顺序对应,一一传递数据。实参与形参按顺序对应,一一传递数据。 特别说明:如果实参表包括多个实参,对实参求特别说明:如果实参表包括多个实参,对实参求值的顺序并不确定,有的系统自左至右,有的则值的顺序并不确定,有的系统自左至右,有的则是自右至左。是自右至左。TurboC是按自右而左的顺序求值的。是按自右而左的顺序求值的。读者对自已的系统可编程试之。读者对自已的系统可编程试之。 函数不能嵌套定义,即在一个定义好的函数不能嵌套定义,即在一个定义好的函数中,又定义另一个函数。但是函数之函数中,又定义另一个函数。但是函数之间允许相互调用,
13、也允许嵌套调用。但间允许相互调用,也允许嵌套调用。但main函数不能被调用。函数不能被调用。 函数还可以自己调用自己,称为递归调函数还可以自己调用自己,称为递归调用。用。【分析分析】首先定义两个函数:求最大值和最小值,然后在主函数中调用。首先定义两个函数:求最大值和最小值,然后在主函数中调用。#include #include / /* * 定义求最大值的函数定义求最大值的函数 * */ /void maxmum(int x,int y) void maxmum(int x,int y) printf(max=%dn,(xy) ? x : y); / printf(max=%dn,(xy) ?
14、 x : y); /* * 求求x x与与y y的最大值的最大值 * */ / / /* * 定义求最小值的函数定义求最小值的函数 * */ /void minmum(int x,int y)void minmum(int x,int y) printf(min=%dn,(xy) ? x : y); / printf(min=%dn,(xy) ? x : y ; z=(xy) ? x : y ; return(z); / return(z); /* * 返回最大值返回最大值 * */ / int printstar() printf(*);void main() int a; a=prints
15、tar(); printf(%d,a);输出:输出:*10void printstar() printf(*);void main() int a; a=printstar(); printf(%d,a);编译错误:编译错误:No an allowed type in function main#include void main() float a,b; int c; scanf(%f,%f,&a,&b); c=max(a,b); printf(Max is %dn,c);int max(float x, float y) float z; z=xy?x:y; return(
16、z);函数值转换成函数值转换成float函数返回值类型函数返回值类型intfloat转换为转换为int这个程序能运行吗这个程序能运行吗?运行能得到正确结果吗运行能得到正确结果吗?float【分析分析】在前面程序的基础上使用在前面程序的基础上使用returnreturn语句返回最大值和最小值,然后在主函数中调用。语句返回最大值和最小值,然后在主函数中调用。/*LI3_2_2.c*/#include int maxmum(int x,int y) int max; max=(xy) ? x : y; return(max);int minmum(int x,int y) int min; min=
17、(xy?x:y; return(z); 例例 比较两个数并输出大者比较两个数并输出大者#include void main() int a,b,c; scanf(%d,%d,&a,&b); c=max(a,b); printf(Max is %d,c);int max(int x, int y) int z; z=xy?x:y; return(z);形参形参实参实参(主调函数主调函数) c=max(a , b);(被调函数被调函数) max(int x, int y)实际参数实际参数形式参数形式参数参数传递参数传递v值传递方式值传递方式l方式:函数调用时方式:函数调用时, ,为
18、形参分配单元为形参分配单元, ,并将实参的值复制到形并将实参的值复制到形参中;调用结束,形参单元被释放,实参单元仍保留并维持原参中;调用结束,形参单元被释放,实参单元仍保留并维持原值值l特点:特点:u形参与实参占用不同的内存单元形参与实参占用不同的内存单元u单向传递单向传递实参实参a10形参形参x10复制复制实参内存空间实参内存空间形参内存空间形参内存空间v地址传递地址传递l方式:函数调用时,将数据的存储地址作为参数传递给形参方式:函数调用时,将数据的存储地址作为参数传递给形参l特点:特点:u形参与实参占用同样的存储单元形参与实参占用同样的存储单元u“双向双向”传递传递u实参和形参必须是地址常
19、量或变量实参和形参必须是地址常量或变量实参实参a形参形参x实参内存空间实参内存空间形参内存空间形参内存空间#include void main() float a,b; int c; scanf(%f,%f,&a,&b); c=max(a,b); printf(Max is %dn,c);int max(float x, float y) float z; z=xy?x:y; return(z);这个程序能运行吗这个程序能运行吗?运行能得到正确结果吗运行能得到正确结果吗?C语语言规言规定:定:被调被调用函用函数必数必须是须是已存已存在的在的函数函数! 为此,为此,C提供了函数原
20、型的机制。即函数声提供了函数原型的机制。即函数声明后即可调用。明后即可调用。v对被调用函数要求:对被调用函数要求:l必须是已存在的函数必须是已存在的函数l库函数库函数: #include : #include .hl用户自定义函数用户自定义函数: : 函数类型声明函数类型声明v函数声明函数声明l一般形式:一般形式: 函数类型函数类型 函数名函数名( (形参类型形参类型 形参名形参名,. );,. ); 或:或: 函数类型函数类型 函数名函数名();();l作用:告诉编译系统作用:告诉编译系统函数类型、参数个数及类型,以便检验函数类型、参数个数及类型,以便检验l函数定义与函数声明不同函数定义与函
21、数声明不同l函数声明位置:程序的数据声明部分(函数内或外)函数声明位置:程序的数据声明部分(函数内或外)l下列情况下,可不作函数声明下列情况下,可不作函数声明u若函数返值是若函数返值是charchar或或intint型,系统自动按型,系统自动按intint型处理型处理u被调用函数定义出现在主调函数之前被调用函数定义出现在主调函数之前l有些系统有些系统( (如如Borland C+)Borland C+)要求函数声明指出函数返值类型和形参类型,要求函数声明指出函数返值类型和形参类型,并且对并且对void void 和和 int int 型函数也要进行函数声明型函数也要进行函数声明void mai
22、n() float a,b; int c; scanf(%f,%f,&a,&b); c=max(a,b); printf(Max is %dn,c);int max(float x, float y) float z; z=xy?x:y; return(z);int型函数可不作函数声明型函数可不作函数声明(Borland C+不行)不行)float add(float x, float y) float z; z=x+y; return(z);void main() float a,b,c; scanf(%f,%f,&a,&b); c=add(a,b); pri
23、ntf(sum is %f,c);被调函数出现在主调函数被调函数出现在主调函数之前,不必函数声明之前,不必函数声明void main() float add(float,float); /*函数声明函数声明*/ float a,b,c; scanf(%f,%f,&a,&b); c=add(a,b); printf(sum is %f,c);float add(float x, float y) float z; z=x+y; return(z);可以:可以:float add(); 不提倡。不提倡。或:或:float add(float x,float y);float add
24、(float,float); /*函数声明函数声明*/void main() float a,b,c; scanf(%f,%f,&a,&b); c=add(a,b); printf(sum is %f,c);float add(float x, float y) float z; z=x+y; return(z);#include /#include /* * 库函数的声明库函数的声明 * */ /int maxmum(int x,int y,int z); /int maxmum(int x,int y,int z); /* * 自定义函数声明自定义函数声明 * */ /in
25、t minmum(int x,int y,int z); /int minmum(int x,int y,int z); /* * 自定义函数声明自定义函数声明 * */ /void main() /void main() /* * 主函数主函数 * */ / int a,b,c,max,min; int a,b,c,max,min; clrscr(); / clrscr(); /* * 清屏清屏 * */ / scanf(%d,%d,%d,&a,&b,&c); scanf(%d,%d,%d,&a,&b,&c); max=maxmum(a,b,c
26、); / max=maxmum(a,b,c); /* * 函数作表达式,并用变量保存最大值函数作表达式,并用变量保存最大值 * */ / printf(max=%dn,max); printf(max=%dn,max); min=minmum(a,b,c); / min=minmum(a,b,c); /* * 函数作表达式,并用变量保存最小值函数作表达式,并用变量保存最小值 * */ / printf(min=%dn,min); printf(min=%dn,min); int maxmum(int x,int y,int z) /int maxmum(int x,int y,int z) /
27、* * 自定义函数自定义函数 * */ / int max; int max; max=(xy) ? x : y; max=(xy) ? x : y; max=(maxz) ? max : z; max=(maxz) ? max : z; return(max); / return(max); /* * 函数的返回值函数的返回值 * */ / int minmum(int x,int y,int z) /int minmum(int x,int y,int z) /* * 自定义函数自定义函数 * */ / int min; int min; min=(xy) ? ( x z ? x : z)
28、 : ( y z ? y : z); min=(xy) ? ( x z ? x : z) : ( y z ? y : z); return min; / return min; /* * 函数的返回值函数的返回值 * */ / b函数函数a函数函数c函数函数d函数函数e函数函数main()主函数主函数f函数函数库库函函数数必须的,起点必须的,起点b函数函数a函数函数c函数函数d函数函数e函数函数main()主函数主函数f函数函数库库函函数数必须的,起点必须的,起点l使用函数可以控制任务的规模使用函数可以控制任务的规模 l使用函数可以控制变量的作用范围使用函数可以控制变量的作用范围 l使用函数可
29、以由多人分工协作完成程序的开发使用函数可以由多人分工协作完成程序的开发 l使用函数,可以重新利用已有的、调式好的、成熟的程序模使用函数,可以重新利用已有的、调式好的、成熟的程序模块(函数)块(函数) 例例3-33-3:比较年龄的大小。:比较年龄的大小。【分析分析】本例实际上是输入两个整型数据后再比较其大小。本例实际上是输入两个整型数据后再比较其大小。#include #include void main()void main() int yourAge, hisAge, max; int yourAge, hisAge, max; clrscr(); / clrscr(); /* *清屏函数,
30、在清屏函数,在stdio.h中声明中声明 * */ / printf(Please enter your age:); printf(Please enter your age:); scanf(%d, &yourAge); / scanf(%d, &yourAge); /* * 输入你的年龄输入你的年龄yourAge yourAge * */ / printf(Please enter your friends age:); printf(Please enter your friends age:); scanf(%d, &hisAge); / scanf(%d,
31、&hisAge); /* * 输入你朋友的年龄输入你朋友的年龄hisAge hisAge * */ / max = (yourAge = hisAge) ? yourAge : hisAge; / max = (yourAge = hisAge) ? yourAge : hisAge; /* * 条件运算符条件运算符 * */ / printf(The older age is = %dn, max); printf(The older age is = %dn, max); 条件运算符的条件运算符的运用运用【分析分析】首先要输入两个实数,然后调用求两个实数和的函数。首先要输入两个实数
32、,然后调用求两个实数和的函数。#include #include / /* * 定义求两个数和的函数定义求两个数和的函数 * */ /float Add(float a, float b) /float Add(float a, float b) /* * 自定义函数自定义函数 * */ / return (a + b);return (a + b); void main() /void main() /* * 主函数主函数 * */ / float x, y; float x, y; double sum = 0.0; double sum = 0.0; printf(Input two f
33、loating decimals:); printf(Input two floating decimals:); scanf(%f%f, &x, &y); / scanf(%f%f, &x, &y); /* * 输入两个浮点数输入两个浮点数x x和和y y * */ / sum = Add(x,y); / sum = Add(x,y); /* * 调用函数调用函数AddAdd计算计算x x和和y y相加之和并保存结果相加之和并保存结果 * */ / printf(sum = %fn, sum); / printf(sum = %fn, sum); /* * 输
34、出输出x x和和y y相加之和相加之和 * */ / 函数操作函数操作#define MAX(x,y) (x)(y)?(x):(y) .main() int a,b,c,d,t; . t=MAX(a+b,c+d); 宏展开:宏展开:t=(a+b)(c+d)?(a+b):(c+d);int max(int x,int y) return(xy?x:y);void main() int a,b,c,d,t; . t=max(a+b,c+d); l在同一程序不同的函数中定义相同在同一程序不同的函数中定义相同的变量名是否对其它函数中的相同变的变量名是否对其它函数中的相同变量有影响?量有影响? int
35、fun1() int x,y; int sum; sum=x+y;int fun2() int x,y; int t; t=x*y;如果如果a的值为的值为3,b的值为的值为5,怎样将,怎样将a的值变为的值变为5,b的值变为的值变为3呢?最简单的办法就呢?最简单的办法就是在是在main函数中在定义一个变量函数中在定义一个变量c作为中间的交换变量,其程序如下:作为中间的交换变量,其程序如下:#include void main( ) int a=3,b=5,c; printf(Before Exchange: a=%d,b=%dn,a,b); c=a; a=b; b=c; printf(After
36、 Exchange: a=%d,b=%dn,a,b);程序的运行情况:程序的运行情况:Before Exchange: a=3,b=5After Exchange: a=5,b=3本例中的本例中的c=a;a=b;b=c;完成完成a与与b两个变量的交换,也称为交换器。但是怎样使用两个变量的交换,也称为交换器。但是怎样使用函数来实现交换两个变量的值呢?函数来实现交换两个变量的值呢?例例3-7:用函数来实现交换两个变量的值。:用函数来实现交换两个变量的值。 可以定义一个函数可以定义一个函数swapswap来交换两个变量的值,在来交换两个变量的值,在mainmain函数函数中给出中给出a a和和b b
37、的值,然后将这两个变量的值传到自定义函数的值,然后将这两个变量的值传到自定义函数swapswap中。可以在中。可以在mainmain函数和函数和swapswap函数中分别显示函数中分别显示a a和和b b的值,查看的值,查看a a和和b b的值交换情况。的值交换情况。 形参和实参是形参和实参是“值传递值传递”,根据变量的三要素,在内存中,根据变量的三要素,在内存中它们分别占用两个不同的存储空间(后面的存储空间概念均指它们分别占用两个不同的存储空间(后面的存储空间概念均指在内存中的存储空间),通过在内存中的存储空间),通过“值传递值传递”的参数不能传回主调的参数不能传回主调函数。因此,在函数函数
38、。因此,在函数swapswap中可以实现形参的交换,但函数调用中可以实现形参的交换,但函数调用完成后,形参不复存在,完成后,形参不复存在,mainmain函数中的变量值仍未改变。函数中的变量值仍未改变。 那么造成上述结果的原因是什么呢?有怎样解决呢?那么造成上述结果的原因是什么呢?有怎样解决呢? 为了解决这类问题,须了解变量的作用域和存储类型。为了解决这类问题,须了解变量的作用域和存储类型。变量是对程序中数据的存储空间的抽象变量是对程序中数据的存储空间的抽象内存内存.void main() int a; a=10; printf(“%d”,a);编译或函数调用时为其分配内存单元编译或函数调用时
39、为其分配内存单元1020002001程序中使用变量名对内存操作程序中使用变量名对内存操作 变量的属性变量的属性 数据类型:变量所持有的数据的性质(操作属性)数据类型:变量所持有的数据的性质(操作属性) 存储属性存储属性 存储器类型:寄存器、静态存储区、动态存储区存储器类型:寄存器、静态存储区、动态存储区 生存期:变量在某一时刻存在生存期:变量在某一时刻存在-静态变量与动态变量静态变量与动态变量 作用域:变量在某区域内有效作用域:变量在某区域内有效-局部变量与全局变量局部变量与全局变量 变量的存储类型变量的存储类型 auto -自动型自动型 register-寄存器型寄存器型 static -静
40、态型静态型 extern -外部型外部型 变量定义格式变量定义格式: 存储类型存储类型 数据类型数据类型 变量表变量表;如如: int sum; auto int a,b,c; register int i; static float x,y;v变量是对程序中数据的存储空间的抽象定义:在函数内定义,只在本函数内有效定义:在函数内定义,只在本函数内有效说明:说明: mainmain中定义的变量只在中定义的变量只在mainmain中有效中有效 不同函数中同名变量,占不同内存单元不同函数中同名变量,占不同内存单元 形参属于局部变量形参属于局部变量 可定义在复合语句中有效的变量可定义在复合语句中有效的
41、变量 局部变量可用存储类型:局部变量可用存储类型:autoauto、registerregister、static static (默认为默认为autoauto)float f1(int a) int b,c; .char f2(int x,int y) int i,j; main() int m,n; .a,b,c有效有效x,y,i,j有效有效m,n有效有效#define N 5#include void main() int i; int aN=1,2,3,4,5; for(i=0;iN/2;i+) int temp; temp=ai; ai=aN-i-1; aN-i-1=temp; fo
42、r(i=0;iN;i+) printf(%d ,ai);运行结果:5 4 3 2 1#include void main() int a,b; a=3; b=4; printf(main:a=%d,b=%dn,a,b); sub(); printf(main:a=%d,b=%dn,a,b);void sub() int a,b; a=6; b=7; printf(sub:a=%d,b=%dn,a,b);运行结果:运行结果:main:a=3,b=4sub:a=6,b=7main:a=3,b=4#include void main() int a,b; a=3; b=4; printf(main:
43、a=%d,b=%dn,a,b); sub(); printf(main:a=%d,b=%dn,a,b);void sub() int a,b; a=6; b=7; printf(sub:a=%d,b=%dn,a,b); 定义:在函数外定义,可为本文件所有函数共用定义:在函数外定义,可为本文件所有函数共用 有效范围:从定义变量的位置开始到本源文件结束,及有有效范围:从定义变量的位置开始到本源文件结束,及有externextern声声明的其它源文件明的其它源文件外部变量声明:外部变量声明: extern 数据类型数据类型 变量表;变量表;外部变量定义与外部变量声明不同若外部变量与局部变量同名,则外
44、部变量被屏蔽若外部变量与局部变量同名,则外部变量被屏蔽外部变量可用存储类型:外部变量可用存储类型:缺省缺省externextern 或或 staticstatic 应尽量少使用全局变量,因为:应尽量少使用全局变量,因为:Y全局变量在程序全部执行过程中占用存储单元全局变量在程序全部执行过程中占用存储单元Y降低了函数的通用性、可靠性,可移植性降低了函数的通用性、可靠性,可移植性Y降低程序清晰性,容易出错降低程序清晰性,容易出错 定义定义 说明说明u次数:次数: 只能只能1次次 可说明多次可说明多次u位置:位置: 所有函数之外所有函数之外 函数内或函数外函数内或函数外u分配内存:分配内存: 分配内存
45、分配内存,可初始化可初始化 不分配内存不分配内存,不可初始化不可初始化float max,min;float average(float array, int n) int i; float sum=array0; max=min=array0; for(i=1;imax) max=arrayi; else if(arrayiy?x:y; return(z);void main() extern int a,b; printf(max=%d,max(a,b);int a=13,b=-8;运行结果:运行结果:max=13extern int a,b;int max() int z; z=ab?a
46、:b; return(z);main() printf(max=%d,max();int a=13,b=-8;int a=3,b=5;max(int a, int b) int c; c=ab?a:b; return(c);void main() int a=8; printf(max=%d,max(a,b);运行结果:运行结果:max=8/*外部变量的副作用外部变量的副作用*/int i;void main() void prt(); for(i=0;i5;i+) prt();void prt() for(i=0;i5;i+) printf(“%c”,*); printf(“n”);运行结果
47、:运行结果:*【分析分析】每个函数通过返回值方式只能返回一个值,而本例要求每个函数通过返回值方式只能返回一个值,而本例要求3 3个值。个值。解决办法之一是:函数返回平均值,而最大值与最小值通过解决办法之一是:函数返回平均值,而最大值与最小值通过全局变量的形式返回。全局变量的形式返回。#include float Max=0,Min=0,a=10,b=20; /* 定义定义Max和和Min为最大值和最小值全局变量为最大值和最小值全局变量 */float average(); /* 函数声明函数声明 */void main( ) float a,ave; printf(Input a , b: )
48、; scanf(%f,%f,&a,&b); /* 输入两个变量的值输入两个变量的值 */ printf(11 a=%.1f, b=%.1fn,a,b); ave=average(); /* 调用函数调用函数 */ printf(12 a=%.1f, b=%.1fn,a,b); printf(Max=%.1f, Min=%.1f, ave=%.1fn,Max,Min,ave);/* 定义求平均值的函数定义求平均值的函数 */float average() float ave; printf(21 a=%.1f, b=%.1fn,a,b); Max=ab?a:b; /* 求最大值求
49、最大值 */ Min=ab?b:a; /* 求最小值求最小值 */ ave=(a+b)/2.0; /* 求平均值求平均值 */ return(ave); /* 返回平均值返回平均值 */*LI3_7_1.c*/#include void s x,int y);void main( ) int a=3,b=5; printf(11 a=%d, b=%dn,a,b);/* 调用交换函数之前 */ s); /* 调用交换函数swap */ printf(12 a=%d, b=%dn,a,b);/* 调用交换函数之后 */* 定义交换两个变量的值的函数 */void s x,int y) /* 函数定
50、义 */ int a; printf(21 x=%d, y=%dn,x,y); /* 交换变量值之前 */ a=x; x=y; y=a; /* 交换器:交换变量x,y的值 */ printf(22 x=%d, y=%dn,x,y); /* 交换变量值之后 */变量变量a、b的作用域的作用域变量变量x、y、a的作用域的作用域/ /* *LI3_7_2.cLI3_7_2.c* */ /#include #include int a=3,b=8; /int a=3,b=8; /* *全局变量全局变量* */ /void swap();void swap();void main( )void main
51、( ) b=5; b=5; printf(11 a=%d, b=%dn,a,b); / printf(11 a=%d, b=%dn,a,b); /* * 调用交换函数之前调用交换函数之前 * */ / swap(); / swap(); /* * 调用交换函数调用交换函数swap swap * */ / printf(12 a=%d, b=%dn,a,b); / printf(12 a=%d, b=%dn,a,b); /* * 调用交换函数之后调用交换函数之后 * */ / void swap()void swap()/ /* * 函数定义函数定义 * */ / int t; int t; p
52、rintf(21 a=%d, b=%dn,a,b); / printf(21 a=%d, b=%dn,a,b); /* * 交换变量值之前交换变量值之前 * */ / t=a; a=b; b=t; / t=a; a=b; b=t; /* * 本行的本行的3 3句:交换变量句:交换变量a,ba,b的值的值 * */ / printf(22 a=%d, b=%dn,a,b); / printf(22 a=%d, b=%dn,a,b); /* * 交换变量值之后交换变量值之后 * */ / l怎样能够通过参数传递真正实现怎样能够通过参数传递真正实现a a与与b b的交换呢?的交换呢?可以使用指针来完
53、成,将在后面章节讲述。可以使用指针来完成,将在后面章节讲述。 #include int max(int x, int y) int z; z=xy?x:y; return(z);void main() printf(max=%d,max(a,b);int a=13,b=-8;extern int a,b;前面讲过以下程序段,在程序的最后定义全局变量前面讲过以下程序段,在程序的最后定义全局变量a a、b b有意义吗?要使它能有意义吗?要使它能使用,必须通过通过使用,必须通过通过extern int a,b;extern int a,b;语句扩展作用域。这就是变量的存储语句扩展作用域。这就是变量的
54、存储类型所要做的事情。类型所要做的事情。动态变量与静态变量,是从变量的生存期角度来分类的。动态变量与静态变量,是从变量的生存期角度来分类的。1、存储方式、存储方式 静态存储:程序运行期间分配固定存储空间。静态存储:程序运行期间分配固定存储空间。 动态存储:程序运行期间根据需要动态分配存储空间。动态存储:程序运行期间根据需要动态分配存储空间。2、内存用户区、内存用户区程序区静态存储区动态存储区全局变量、局部静态变量形参变量局部动态变量(auto register)函数调用现场保护和返回地址等3 3、生存期、生存期 静态变量静态变量: :从程序开始执行到程序结束。从程序开始执行到程序结束。 动态变
55、量动态变量: :从包含该变量定义的函数开始执行至函数执行结束。从包含该变量定义的函数开始执行至函数执行结束。静态动态存储方式程序整个运行期间函数调用开始至结束生存期编译时赋初值,只赋一次每次函数调用时赋初值自动赋初值0或空字符不确定未赋初值静态存储区动态区存储区寄存器局部变量外部变量作用域定义变量的函数或复合语句内本文件其它文件register局部staticauto外部staticextern存储类别u局部变量默认为局部变量默认为autoauto型型uregisterregister型变量个数受限型变量个数受限, ,且不能为且不能为long, double, floatlong, doubl
56、e, float型型u局部局部staticstatic变量具有全局寿命和局部可见性变量具有全局寿命和局部可见性u局部局部staticstatic变量具有可继承性变量具有可继承性( (下次进入函数该值还存在下次进入函数该值还存在) )uexternextern不是变量定义不是变量定义, ,可扩展外部可扩展外部变量作用域变量作用域 在在C C语言中,函数内部定义的变量(局部变量)缺省为自动变量语言中,函数内部定义的变量(局部变量)缺省为自动变量(automatic variableautomatic variable)。自动变量是最常用的。)。自动变量是最常用的。 关键字关键字autoauto能够
57、显式地指定存储类别。能够显式地指定存储类别。 显式定义显式定义 auto int xauto int x,y y; 隐含定义隐含定义 等价等价 int xint x,y y; 实际上关键字实际上关键字“auto”auto”可以省略,可以省略,autoauto不写则隐含确定为不写则隐含确定为“自动存储类自动存储类别别”,即动态存储方式。,即动态存储方式。 程序中大多数变量属于自动变量。程序中大多数变量属于自动变量。main() int x=1; void prt(void); int x=3; prt(); printf(“2nd x=%dn”,x); printf(“1st x=%dn”,x)
58、;void prt(void) int x=5; printf(“3th x=%dn”,x);运行结果:运行结果:3th x=52nd x=31st x=1x=1作用域作用域x=1作用域作用域x=3作用域作用域x=5作用域作用域 对于使用频繁的变量,可以使用对于使用频繁的变量,可以使用registerregister声明为寄存器变量,其值存储在声明为寄存器变量,其值存储在CPUCPU中,加快了运行速度。中,加快了运行速度。 如:如:register int x;register int x; register char c; register char c; 说明:说明: 只有局部自动变量和形
59、式参数可以作为寄存器变量,其余非法。只有局部自动变量和形式参数可以作为寄存器变量,其余非法。 一个计算机系统中的寄存器数目是有限的,不能定义任意多个寄存器变一个计算机系统中的寄存器数目是有限的,不能定义任意多个寄存器变量。量。 一般来讲只允许一般来讲只允许intint和和charchar才能定义为寄存器变量,但目前大多数系统才能定义为寄存器变量,但目前大多数系统都支持指针型变量定义为寄存器变量。都支持指针型变量定义为寄存器变量。 局部静态变量不能定义为寄存器变量,即不能定义:局部静态变量不能定义为寄存器变量,即不能定义:register static register static int x
60、;int x;,对一个变量只能声明一个存储类别。,对一个变量只能声明一个存储类别。 当今优化的编译系统,能够自动识别使用频繁的变量,从而自动的将这当今优化的编译系统,能够自动识别使用频繁的变量,从而自动的将这些变量放在寄存器中。因此程序设计者实际上根本不需要去声明寄存器变量。些变量放在寄存器中。因此程序设计者实际上根本不需要去声明寄存器变量。 有时希望函数中的局部变量的值在函数调用结束后不消失而保留原值,有时希望函数中的局部变量的值在函数调用结束后不消失而保留原值,以便下一次调用该函数时可以使用上一次调用的最后结果。这时就应该指定以便下一次调用该函数时可以使用上一次调用的最后结果。这时就应该指定该局部变量为该局部变量为“静态局部变量静态局部变量”。#include void main() void increment(void); increment(); increment(); increment();void in
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 生物多样性保护与环境科学
- 江苏省部分校2024-2025学年高三上学期12月联合测试物理试卷
- 高血压急症和亚急症
- Module7-英语四年级上册-教科版含答案
- 生态城市建设中的公众参与
- 合肥项目投资分析报告
- 贫困户创业贷款申请书
- 疫情背景下的在线网络营销新策略
- 电子政务平台在农业信息化中的应用
- 四川省成都市2024年七年级《语文》下册期中试卷与答案(B卷)
- 第七章老年人泌尿系统疾病
- 2025年枝江金润源建设集团招聘笔试参考题库含答案解析
- 危险化学品安全监管培训
- 病原生物学-人体寄生虫学知到智慧树章节测试课后答案2024年秋浙江大学
- 校园安全案例解析
- 2024-2030年中国医疗建筑工程行业发展潜力及投资战略规划分析报告
- 人工智能导论知到智慧树章节测试课后答案2024年秋天津大学
- 校史馆装修工程施工方案
- 金融消保培训
- 南师大学校介绍课件
- 《病理科(中心)建设与配置标准》
评论
0/150
提交评论