C++课件c++04-1模块化与函数1.ppt_第1页
C++课件c++04-1模块化与函数1.ppt_第2页
C++课件c++04-1模块化与函数1.ppt_第3页
C++课件c++04-1模块化与函数1.ppt_第4页
C++课件c++04-1模块化与函数1.ppt_第5页
已阅读5页,还剩125页未读 继续免费阅读

下载本文档

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

文档简介

1、第四章 模块化与函数,2,实际问题,求a!b!c!的值。,3,算法,分别求出a!,b!,c! a!=1*2*3*.*a; b!=1*2*3*.*b; c!=1*2*3*.*c;,4,#include using namespace std; int main() int a,b,c,sum=0; unsigned long la,lb,lc; la=lb=lc=1; int i; cinabc; for (i=1;i=a;i+) la*=i; for (i=1;i=b;i+) lb*=i; for (i=1;i=c;i+) lc*=i; sum = la+lb+lc; couta!+b!+c!

2、=sumendl; return 0; ,5,问题抽化成一个模块,重复了求阶乘的代码 可以设计一个求阶乘的函数,这里的函数具备 求 阶乘的 功能。,6,模块化程序设计的优点,分而治之 代码可重用 便于实现 易于维护 抽象技术,7,模块化程序设计图示,模块化程序设计,第4章 函数,9,本章学习目标,通过本章学习,你能够 了解模块化程序设计 能够分解复杂问题 能够创建模块(函数) 能够使用模块(函数),10,本章主要内容,函数的定义 函数的调用 递归函数 C+标准库函数,内联函数 函数重载 函数模板 默认参数(略),11,实例1模块化,定义求阶乘函数,定义函数(创建模块),模块: unsigned

3、 long fac(int x) int i; unsigned long ul=1; for (i=1;i=x;i+) ul*=i; return ul; ,调用函数(使用模块),int main() int a,b,c,sum=0; unsigned long la,lb,lc; cinabc; la = fac(a); lb = fac(b); lc = fac(c); sum = la+lb+lc; couta!+b!+c!=sumendl; return 0; ,总结规律:设计一个有子函数的程序,定义一个子函数 考虑该函数的形式参数,参数类型,个数 考虑该函数是否有返回值,即考虑该函

4、数设计后是否需要得到一个值,如果 需要,则得有return 返回值。 主函数中调用子函数 如:la = fac(a);,unsigned long fac(int x) int i; unsigned long ul=1; for (i=1;i=x;i+) ul*=i; return ul; ,15,函数定义的格式,返回值类型 函数名(形式参数表) 函数体 ,模块接口,实现 模块功能,数据传递,16,关于函数定义的说明,函数名:fac 标识函数,表明函数功能,与变量名命名规则相同 函数形参(int x) 传递数据,必须是变量,不能是表达式 返回值类型(函数类型):unsigned long 返

5、回给上一层模块的数据的类型 通过return实现 如果无返回值,则函数类型为void 函数体:实现函数的功能 ,unsigned long fac(int x) int i; unsigned long ul=1; for (i=1;i=x;i+) ul*=i; return ul; ,17,函数设计要求,执行单一的、明确的任务 函数名表达其任务 如:factorial 内聚性强、耦合性弱!,18,函数调用,unsigned long fac(int x);/ 函数原型 int main() int a,b,c,sum=0; unsigned long fac(int x);/ 函数原型 un

6、signed long la,lb,lc; cinabc; la = fac(a);/函数调用 lb = fac(b); lc = fac(c); sum = la+lb+lc; couta!+b!+c!=sumendl; return 0; ,unsigned long fac(int x) int i; unsigned long ul=1; for (i=1;i=x;i+) ul*=i; return ul; ,19,关于函数调用的说明,调用前要给出函数原型: 类型 函数名(形参表); /注意; 例:unsigned long fac(int x); 函数调用的形式: 函数名(实参表);

7、 例:fac(a);fac(3);fac(a+4); 实参:可以是常量、变量或表达式,20,函数调用中的类型问题,按函数原型的参数类型强制转换 例: double maximum( int, int, int ); double x; x = maximum(1.1, 2.1, 3.1); x ?,21,函数原型的作用,编译程序用以检验函数的调用,以避免因错误调用而导致运行时错误: 返回值的类型 参数的个数 参数的类型 参数的顺序,设计一个函数,求两个整数的最大值的函数 在主函数中,输入两个整数,调用这个函数,得到这个两个整数的最大值。,23,函数调用的执行过程,使用函数是有代价的!,24,函

8、数调用中的程序控制,主调函数(caller)怎么使程序流程进入到被调用函数呢? 通过函数名进入被调函数 被调函数(callee)被调用以后怎么回到主调函数呢? 通过以下途径返回主调函数: return 函数结束部分的右大括号,返回值类型 函数名(形式参数表),形式参数表:数据传递的作用,实参和形参的关系:y=f(x); 2=f(1);,26,函数的参数传递,两种途径: 按值传递 被调函数生成形参 实参值被复制到形参 形参的改变不会改变实参 按引用传递 形参使用实参的存储空间 形参的改变会改变实参,27,函数参数的按值传递,只有在函数被调用时,形参才被分配存储单元。 实参可以是常量、变量或表达式

9、。 数据只能从实参传递给形参,即单向传递。 当实参类型与形参不同时,按形参类型转换。 虚实结合:一一对应(类型、个数、顺序) 函数返回时,释放形参和局部变量所占内存,28,例:输入两整数交换后输出,void swap(int a, int b); int main() int x=5, y=10; coutx=xy=yendl; swap(x,y); coutx=xy=yendl; return 0; ,void swap(int a, int b) int t; t=a; a=b; b=t; couta=ab=bendl; 运行结果: x=5 y=10 a=10 b=5 x=5 y=10,原

10、因何在?,30,按值传递,void swap( int, int ); void main(void) int x=5, y=10; swap(x, y); void swap( int a, int b) ,x, y 为实参,a, b 为形参,31,函数参数的按引用传递,在函数被调用时不为形参分配存储单元,形参使用实参空间。 实参不能是常量或表达式,只能是变量,而且类型必需与形参类型一致。 实参和形参共享数据,即双向传递。,32,何谓引用?,引用是标识符的别名 例如: int i=10;int / i? 声明一个引用时,必须同时对它进行初始化。 一个引用一旦被初始化后,就不能改为其它对象的引

11、用。,33,例:输入两整数交换后输出,void swap(int ,void swap(int 运行结果: x=5 y=10 a=10 b=5 x=10 y=5,原因何在?,35,函数参数按引用传递,void swap( int void swap( int void print_message(void) cout Welcome to C+!endl;,38,2、函数形参和实参,说明: 实参必须有确定的值 形参必须指定类型 形参与实参类型一致,个数相同 若形参与实参类型不一致,自动按形参类型转换函数调用转换 形参在函数被调用前不占内存;函数调用时为形参分配内存;调用结束,内存释放,39,例

12、: 计算x的立方注意内存,#include using namespace std; float cube(float x) return(x*x*x); int main() float a, product; couta; product=cube(a); cout Cube of a is productendl; return 0; ,x,1.2,1.2,1.728,40,3、函数的返回值 返回语句 形式: return(表达式); 或 return 表达式; 或 return; 功能:使程序控制从被调用函数返回到调用函数中,同时把返回值带给调用函数 说明: 函数中可有多个return

13、语句,但函数被调用后只能有一个值。 若无return语句,遇时,自动返回主调用函数 若函数类型与return语句中表达式值的类型不一致,按前者为准,自动转换-函数调用转换 void型函数,例 无返回值函数 void swap(int x,int y ) int temp; temp=x; x=y; y=temp; ,例 int max(int x,int y) return (xy?x:y); ,41,例: 函数返回值类型转换,#include using namespace std; int max(float x, float y) float z; z=xy?x:y; return(z)

14、; int main() float a,b; int c; cinab; c=max(a,b); coutMax is cendl; return 0; ,运行结果:2.6 , 8.9 Max is 8,42,4、函数调用方式 函数语句: 例 printstar( ); 函数表达式: 例 m=max(a,b)*2; 函数参数: 例 m=max(a,max(b,c);,可以被多次调用,相互调用 例 int f1(int x);/函数原型 int f2(int x); int f3(int x); int main() int a; f1(a); f2(a); f3(a); int f1(int

15、 x) int b; return f2(b); int f2(int x) int c; return f3(c); int f3(int x) ,43,5、函数声明,一般形式: 函数类型 函数名(形参类型 形参名,. ); 或 函数类型 函数名(); 作用:告诉编译系统函数类型、参数个数及类型,以便检验 函数定义与函数声明不同 函数声明位置:程序的数据说明部分(函数内或外) 下列情况下,可不作函数声明 若函数返回值是char或int型,系统自动按int型处理 被调用函数定义出现在主调函数之前,44,例 函数说明举例,函数的嵌套调用 嵌套调用 C规定:函数定义不可嵌套,但可以嵌套调用函数,例

16、如: 求三个数中最大数和最小数的差值,#include using namespace std; int dif(int x,int y,int z); int max(int x,int y,int z); int min(int x,int y,int z); int main() int a,b,c,d; cinabc; d=dif(a,b,c); coutMax-Min“dendl; return 0; ,int dif(int x,int y,int z) return max(x,y,z)-min(x,y,z); int max(int x,int y,int z) int r;

17、r=xy?x:y; return(rz?r:z); int min(int x,int y,int z) int r; r=xy?x:y; return(rz?r:z); ,例 求三个数中最大数和最小数的差值,递归调用 定义:函数直接或间接的调用自身叫函数的递归调用,说明 C+编译系统对递归函数的自调用次数没有限制 每调用函数一次,在内存堆栈区分配空间,用于存放函数变量、返回值等信息,所以递归次数过多,可能引起堆栈溢出,int f(int x) int y,z; z=f(y); . return(2*z); ,例4.10 有5个人坐在一起,问第5个人多少岁?他说比第4个人大两岁。问第4个人岁数

18、,他说比第3个人大两岁。问第3个人,又说比第2个人大两岁。问第2个人,说比第1个人大两岁。最后问第1个人,他说是10岁。请问第5个人多大?,可以用式子表述如下: age(n)=10 (n=1) age(n)=age(n-1)+2 (n1),运行结果如下:18 函数调用过程如图所示,#include using namespace std; int age(int n) int c; if(n= =1) c=10; else c=age(n-1)+2; return(c); int main( ) cout1),递归总结,一个问题若要采用递归来解决时,要满足: 可以把要解决的问题转化为一个新的问

19、题,而这个新的问题的解法与原来的解法相同,只是所处理的对象有规律的递增或递减。 可以应用这个转化过程使问题得到解决。 必定要有一个明确的结束递归的条件,一个可以得到解的基本情况。,52,递归算法,计算n!的递归算法如下: 注:其累计求积算法为: n!=1*2*3*.*(n-1)*n,53,递归算法,由两部分组成: 已知部分 解基本情形:n!=1(n=0) 未知部分 与原始问题类似,但更简单或更小: n!=n*(n-1)!,n0,54,递归算法,递归算法的两个过程: 递推: 4!=43! 3!=32! 2!=21! 1!=1 未知 已知 回归: 4!=43!=243!=32!=62!=21!=2

20、1!=1 未知 已知,55,用递归函数实现递归算法,int fac( int n ) if ( n = 1 ) return 1; else return ( n * fac( n - 1 ) ); ,基本情形,更简单的原始问题,56,递归过程演示,5!,5*4!,4*3!,3*2!,2*1!,1,返回5*24=120,返回4*6=24,返回3*2=6,返回2*1=2,返回1,57,递归函数的常见错误,忽略了基本情形,或错误地编写了递归步,以致程序无法运行到基本情形,而导致无限递归,最终内存耗尽。 忘记从递归函数中返回,例 有以下程序 #include using namespace std;

21、 int f(int n) if (n=1)return 1; else return f(n-1)+1; int main() int i,j=0; for(i=1;i3;i+) j+=f(i); coutjendl; return 0; 程序运行后的输出结果是: a)4 b)3 c)2 d)1,i f(i) j 1 1 1 2 f(2-1)+1 1+2,例:#include using namespace std; long fun(int n) long s; if( n=1| n=2 ) s=2; else s=n-fun(n-1); return s; int main() cout

22、fun(3)endl; return 0; ,运行结果: ns 33-fun(3-1) 3-2=1,内置函数(内联函数) 在编译时将所调用函数的代码直接嵌入到主调函数中,而不是将流程转出去。 指定内置函数,只需在函数首行的左端加一个关键字inline。 例4.4 函数指定为内置函数。 #include using namespace std;,inline int max(int,int, int); /函数声明,注意左端有inline int main( ) int i=10,j=20,k=30,m; m=max(i,j,k); couta) a=b; /求a,b,c中的最大者 if(ca)

23、 a=c; return a; ,实参代替形参,被置换成 if (ji) i=j; if(ki) i=k; m=i;,注意:inline可以写在声明函数或定义函数时 优点:内置函数节省运行时间 缺点:增加了目标程序的长度。 对内置函数的要求: 规模很小,一般为5个语句以下 使用频繁的函数 不包括复杂的控制语句,如循环语句和switch语句,函数重载,函数起名字注意什么? 见名之意 max1,max2,max3 函数调用的时候注意什么? 参数类型一致,从左到右 int max(int ,int,int) long max(long, long, long) double max(double ,

24、 double , double ),int max1(int ,int,int) long max2(long, long, long) double max3(double , double , double ),函数的重载:一组概念相同,处理对象(参数)不同的过程,出于方便编程的目的,用同一个函数名字来命名的技术称为函数重载 重载是不同的函数,以参数的类型,个数和顺序来分辨 函数体可以相同也可以不同,函数的重载“一名多用”,例:void print(double); void print(int); void func() print(1); / void print(int); pri

25、nt(1.0); / void print(double); print(a); / void print(int); print(3.1415f); / void pirnt(double); ,66,函数重载,特点: 函数名相同 参数不同:类型、个数、顺序不同,例4.5 求3个数中最大的数(分别考虑整数、双精度数、长整数的情况)。 #include using namespace std; int main( ) int max(int a,int b,int c); /函数声明 double max(double a,double b,double c); /函数声明 long max(

26、long a,long b,long c); /函数声明 int i1,i2,i3,i; cini1i2i3; /输入3个整数 i=max(i1,i2,i3); /求3个整数中的最大者 couti_max=iendl;,double d1,d2,d3,d; cind1d2d3; d=max(d1,d2,d3); coutg1g2g3; g=max(g1,g2,g3); couta) a=b; if(ca) a=c; return a; ,double max(double a,double b,double c) if(ba) a=b; if(ca) a=c; return a; long m

27、ax(long a,long b,long c) if(ba) a=b; if(ca) a=c; return a; ,运行情况如下: 185 -76 567 i_max=567 56.87 90.23 -3214.78 d_max=90.23 67854 -912456 673456 g_max=673456,特点:参数类型不同,函数体一样,例4.6参数个数不同的重载。 #include using namespace std; int main( ) int max(int a,int b,int c); /函数声明 int max(int a,int b); /函数声明 int a=8,

28、b=-12,c=27; cout“max(a,b,c)=“max(a,b,c)endl; cout“max(a,b)=“max(a,b)endl; return 0; ,int max(int a,int b,int c) if(ba) a=b; if(ca) a=c; return a; int max(int a,int b) if(ab) return a; else return b; 运行情况如下: max(a,b,c)=27 max(a,b)=8 两次调用max函数的参数个数不同,系统就根据参数的个数找到与之匹配的函数并调用它。,重载注意事项,int f(int); long f(

29、int); void f(int); 调用时,注意参数的不同而调用不同的函数,参数个数,参数类型或者参数顺序3者中必须至少有一种不同,返回值类型可以相同可以不同。,72,函数模板,一种有效的编程工具: 生成若干重载函数 使用关键字 template,定义函数模板的形式: template 通用函数定义 在调用函数时系统会根据实参的类型来取代模板中的虚拟类型,从而实现了不同函数的功能。 类型参数可以不只一个,可以根据需要确定个数。 如:template 注意: 它只适用于函数的参数个数相同而类型不同,且函数体相同的情况,如果参数的个数不同,则不能用函数模板。,函数模板,例4.7 将例4.6程序改

30、为通过函数模板来实现。 #include using namespace std; template /模板定义,其中T为类型参数 T max(T a,T b,T c) if(ba) a=b; if(ca) a=c; return a;,int main( ) int i1=185,i2=-76,i3=567,i; double d1=56.87,d2=90.23,d3=-3214.78,d; long g1=67854,g2=-912456,g3=673456,g; i=max(i1,i2,i3); d=max(d1,d2,d3); g=max(g1,g2,g3); couti_max=ie

31、ndl; coutf_max=fendl; coutg_max=gendl; return 0; ,int max(int a,int b,int c) if(ba) a=b; if(ca) a=c; return a; ,函数在声明时可以预先给出默认的形参值,调用时如给出实参,则采用实参值,否则采用预先给出的默认形参值。 例如:,有默认参数的函数,int add(int x=5,int y=6) return x+y; ,void main() add(10,20); /10+20 add(10); /10+6 add(); /5+6 ,默认形参值必须从右向左顺序声明,并且在默认形参值的右面

32、不能有非默认形参值的参数。因为调用时实参取代形参是从左向右的顺序。 例:,int add(int x,int y=5,int z=6); /正确 int add(int x=1,int y=5,int z); /错误 int add(int x=1,int y,int z=6); /错误,例4.8 求2个或3个正整数中的最大数,用带有默认参数的函数实现。 #include using namespace std; int main( ) int max(int a, int b, int c=0); int a,b,c; cinabc; coutmax(a,b,c)=max(a,b,c)end

33、l; coutmax(a,b)=max(a,b)endl; /c取默认值 return 0; ,int max(int a,int b,int c) if(ba) a=b; if(ca) a=c; return a; ,运行情况如下: 14 -56 135 max(a,b,c)=135 max(a,b)=14,在一个函数内部定义的变量是内部变量,它只在本函数范围内有效,也就是说只有在本函数内才能使用它们,在此函数以外是不能使用这些变量的。同样,在复合语句中定义的变量只在本复合语句范围内有效。这称为局部变量(local variable)。如,局部变量和全局变量变量作用域区分,局部变量,floa

34、t f1(int a) /函数f1 int b,c; b、c有效a有效 char f2(int x, int y) /函数f2 int i,j; i、j有效x、y有效 int main( ) /主函数 int m,n; int p,q; p、q在复合语句中有效 m、n有效 ,说明: (1) 主函数main中定义的变量也只在主函数中有效 (2) 不同函数中可以使用同名的变量,它们代表不同的对象,互不干扰。 (3) 可以在复合语句中定义变量,这些变量仅在本复合语句中有效。 (4) 形式参数也是局部变量。其他函数不能调用。 (5) 在函数声明中出现的参数名,其作用范围只在本行的括号内。,例如 int

35、 max(int a,int b); /函数声明中出现a、b int max(int x,int y) /函数定义,形参是x、y coutxyendl; /合法,x、y在函数体中有效 coutabendl; /非法,a、b在函数体中无效 编译时认为max函数体中的a和b未经定义。,在函数内定义的变量是局部变量,而在函数之外定义的变量是外部变量,称为全局变量(全程变量)。全局变量的有效范围为从定义变量的位置开始到本源文件结束。如,4.11.2 全局变量,int p=1,q=5;/全局变量全局变量p、q的作用范围 float f1(int a)/定义函数f1 int b,c; char c1,c2

36、; /全局变量 全局变量c1、c2 的作用范围 char f2 (int x, int y) /定义函数f2 int i,j; main ( )/主函数 int m,n; ,4.12 变量的存储类别 概述 变量是对程序中数据的存储空间的抽象,编译或函数调用时为其分配内存单元,10,程序中使用变量名对内存操作,变量的属性 数据类型:变量所持有的数据的性质(操作属性) 存储属性 生存期:变量在内存中的存在期间。变量在某一时刻存在-静态变量与动态变量(时间角度) 作用域:变量在某区域内有效-局部变量与全局变量(空间角度) 变量的存储类型 auto -自动型 register-寄存器型 static

37、-静态型 extern -外部型 变量定义格式: 存储类型 数据类型 变量表;,4.12 变量的存储类别 概述 变量是对程序中数据的存储空间的抽象,如: int sum; auto int a,b,c; register int i; static float x,y;,动态变量与静态变量 存储方式 静态存储:程序运行期间分配固定存储空间 动态存储:程序运行期间根据需要动态分配存储空间 内存用户区,生存期 静态变量:从程序开始执行到程序结束 动态变量:从包含该变量定义的函数开始执行至函数执行结束,局部变量与全局变量 局部变量-内部变量 定义:在函数内定义,只在本函数内有效 说明: main中定

38、义的变量只在main中有效 不同函数中同名变量,占不同内存单元 形参属于局部变量 可定义在复合语句中有效的变量 局部变量可用存储类型:auto register static (默认为auto),例 不同函数中同名变量,#include using namespace std; int main() int a,b; int sub( ); a=3; b=4; coutmain: a“,”bendl; sub( ); coutmain: a“,”bendl; return 0; int sub( ) int a,b; a=6; b=7; cout sub: a“,”bendl; ,运行结果:

39、main:a=3,b=4 sub:a=6,b=7 main:a=3,b=4,全局变量-外部变量 定义:在函数外定义,可为本文件所有函数共用 有效范围:从定义变量的位置开始到本源文件结束,及有extern说明的其它源文件,应尽量少使用全局变量,因为: 全局变量在程序全部执行过程中占用存储单元 降低了函数的通用性、可靠性,可移植性 降低程序清晰性,容易出错,定义 说明 次数: 只能1次 可说明多次 位置: 所有函数之外 函数内或函数外 分配内存: 分配内存,可初始化 不分配内存,不可初始化,外部变量说明: extern 数据类型 变量表;,外部变量定义与外部变量说明不同,若全局变量与局部变量同名,

40、则全局变量被屏蔽,外部变量可用存储类型:缺省 或 static,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(arrayimin) min=arrayi; sum+=arrayi; return(sum/n); main() int i; float ave,score10; /*Input */ ave=average(score,10); coutmax= maxmin=“ minavera

41、ge=“aveendl; ,extern char c1,c2;,extern char c1,c2;,运行结果:max=13,#include using namespace std; extern int a,b; int max() int z; z=ab?a:b; return(z); int main() coutmax=“max()endl; return 0; int a=13,b=-8;,运行结果:max=8,int i; #include using namespace std; int main() void prt(); for(i=0;i5;i+) prt( ); vo

42、id prt( ) for(i=0;i5;i+) cout“*”; coutendl; ,例 外部变量副作用,运行结果:*,作用域分类,全局 局部”可见” “不可见” int a=5; int main() void f(); int b=5; a=1; f(); void f() int c=1; a=5; 若全局变量和局部变量同名,全局变量被屏蔽。 若多个函数中出现局部变量同名的情况,同名的局部变量之间没有任何关系,相互独立。,存储方式分类按在内存中存在的时间,静态存储占有固定的存储单元 动态存储动态随机的存储单元 4种存储类型 auto -自动型 register-寄存器型 static

43、 -静态型 extern -外部型,如: int sum; auto int a,b,c; register int i; static float x,y;,局部变量默认为auto型,如int a=3; 局部static变量具有全局寿命和局部可见性 局部static变量具有可继承性即占有的存储单元不释放,在下一次调用函数时,该变量保留上一次函数调用结束时的值。 extern不是变量定义,可扩展外部变量作用域,例 auto 变量的作用域同名局部变量,#include using namespace std; int main() int x=1; void prt(void); int x=3

44、; prt( ); cout“2nd x=”xendl; cout“1st x=”xendl; return 0; void prt( ) int x=5; cout“3th x=”xendl; ,运行结果: 3th x=5 2nd x=3 1st x=1,#include using namespace std; int main() void increment(void); increment(); increment(); increment(); return 0; void increment(void) int x=0; x+; coutxendl; ,例 局部静态变量值具有可继

45、承性,运行结果:1 1 1,#include using namespace std; int main() void increment(void); increment(); increment(); increment(); return 0; void increment(void) static int x=0; x+; coutxendl; ,运行结果:1 2 3,例 变量的寿命与可见性,#include int i=1; main() static int a; register int b=-10; int c=0; cout-MAIN-n“endl; couti: i a:

46、a “b:” b“ c:” c; c=c+8; other(); cout-MAIN-n“endl; couti: i a: a “b:” b“ c:” c; i=i+10; other(); ,other() static int a=2; static int b; int c=10; a=a+2; i=i+32; c=c+5; cout-OTHER-“endl; couti: i a: a “b:” b“ c:” c; b=a; ,-Main- i:1 a:0 b:-10 c:0,-Other- i:33 a:4 b:0 c:15,-Main- i:33 a:0 b:-10 c:8,-O

47、ther- i:75 a:6 b:4 c:15,8,4,33,15,4,43,6,75,15,6,#include using namespace std; int main() void gx(),gy(); extern int x,y; cout“1: x=”x“ty=“yendl; y=246; gx(); gy(); void gx() extern int x,y; x=135; cout“2: x=”x“ty=“yendl; int x,y; void gy() cout“3: x=”x“ty=“yendl; ,例 用extern扩展外部变量作用域,运行结果: 1: x=0 y=

48、0 2: x=135 y=246 3: x=135 y=246,例 引用其它文件中的外部变量,例 引用其它文件中的变量,输出ab和a的m次方,Ch7.cpp,Ch8.cpp,运行结果: Enter the number a and its power: 2,3 2*3=6 2*3=8,一个变量除了数据类型以外,还有3种属性: 存储类别 C+允许使用auto,static,register和extern 4种存储类别。 作用域 指程序中可以引用该变量的区域。 存储期 指变量在内存的存储期限。 以上3种属性是有联系的,程序设计者只能声明变量的存储类别,通过存储类别可以确定变量的作用域和存储期。,4

49、.13 变量属性小结,变量存储类型,4.14 关于变量的声明和定义,把建立存储空间的声明称为定义 而把不需要建立存储空间的声明称为声明 例如 函数的声明是函数的原型, 函数的定义是函数功能的确立。,int main( ) extern int a; /声明a是一个已定义的外部变量 int a; /是定义,定义a为整型外部变量,用static来声明一个变量 对局部变量用static声明,使该变量在本函数调用结束后不释放,整个程序执行期间始终存在,使其存储期为程序的全过程。 全局变量用static声明,则该变量的作用域只限于本文件模块(即被声明的文件中)。 用auto,register,stati

50、c声明变量时,是在定义变量的基础上加上这些关键字,而不能单独使用。 例如: static a; 是不合法的,应写成static int a;,static静态局部变量的例子,输出15的阶乘值(即1!,2!,3!,4!,5!) #include using namespace std; int main( ) unsigned long fac(int n); for (int i =1;i=5;i+) coutfac(i); return 0; unsigned long fac(int n) unsigned long f=1; for(int i=1;i=n;i+) f*=i; retur

51、n f; ,例 文件file1.c int a; main( ) . . f2; . f1; . f1( ) auto int b; f2; . f2( ) static int c; ,内部函数 函数只能被本文件中其他函数所调用 内部函数定义:,static 类型标识符 函数名(形参表),外部函数 函数能被其他文件调用 外部函数定义: 在函数首部的最左端冠以关键字extern 如果在定义函数时省略extern,则默认为外部函数,如: extern int fun (int a, int b),extern 类型标识符 函数名(形参表),4.15 内部函数和外部函数,例4.15 输入两个整数,

52、要求输出其中的大者。file1.cpp(文件) #include using namespace std; int main( ) extern int max(int,int); int a,b; cinab; coutmax(a,b)endl; return 0; ,file2.cpp(文件2) int max(int x,int y) int z; z=xy?x:y; return z; ,运行情况如下: 7 -34 7,在计算机上运行一个含多文件的程序时,需要建立一个项目文件(project file),在该项目文件中包含程序的各个文件。,作用:对源程序编译之前对程序中特殊的命令进行处

53、理,生成扩展C+源程序 种类 宏定义 #define 文件包含 #include 条件编译 #if-#else-#endif等 格式: “#”开头 占单独书写行 语句尾不加分号,4.16 预处理命令,#include 包含指令 将一个源文件嵌入到当前源文件中该点处。 #include 按标准方式搜索,文件位于C+系统目录的include子目录下 #include文件名 首先在当前目录中搜索,若没有,再按标准方式搜索。 #define 宏定义指令 定义符号常量,很多情况下已被const定义语句取代。 定义带参数宏,已被内联函数取代。 #undef 删除由#define定义的宏,使之不再起作用。,#include 包含指令作用相当于写几十行、几百行甚至更多行的内容。 在文件头部的被包含的文件成为“头文件” 对类型的声明(类,自定义的类型) 函数声明 内置函数的定义 宏定义 全局变量定义 根据需要包

温馨提示

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

评论

0/150

提交评论