基于过程的程序设计.ppt

上传人:牧羊曲112 文档编号:6262686 上传时间:2023-10-11 格式:PPT 页数:52 大小:257.99KB
返回 下载 相关 举报
基于过程的程序设计.ppt_第1页
第1页 / 共52页
基于过程的程序设计.ppt_第2页
第2页 / 共52页
基于过程的程序设计.ppt_第3页
第3页 / 共52页
基于过程的程序设计.ppt_第4页
第4页 / 共52页
基于过程的程序设计.ppt_第5页
第5页 / 共52页
点击查看更多>>
资源描述

《基于过程的程序设计.ppt》由会员分享,可在线阅读,更多相关《基于过程的程序设计.ppt(52页珍藏版)》请在三一办公上搜索。

1、基于过程的程序设计,雷小锋,内容纲要,一、基于过程的程序设计概述二、函数三、域和生命期四、函数模板五、使用泛型,高级话题,三、域和生命期,程序的多文件结构可以在多个文件之间共享函数和变量解决办法:函数声明和变量声明extern 返回类型 函数名(形参表);extern 数据类型 变量名;,三、域和生命期,可以在多个文件之间共享函数和变量解决办法:函数声明和变量声明,/文件A.cppfloat price=2.3;/定义void print()coutpriceendl;,/文件B.cppextern void print();extern float price;int main()price

2、=3.1;print();,三、域和生命期,在定义了一个函数或变量之后,则在所有的源代码文件中都可以使用它,只要在使用之前声明一下。,问题:能否得出以下结论,三、域和生命期,客观世界中的任何事物,其存在于一定的时间和空间范围空间范围:作用域,简称域时间范围:生命期超出自身的作用域和生命期就不可访问,结论:定义了一个函数或变量之后,则在所有的源代码文件中都可以使用它,只要在使用之前声明一下,对吗?,三、域和生命期,作用域:简称域,指标识符能够被使用的空间范围,只有在作用域内标识符才可以被访问(称为可见)标识符作用域的起点均为标识符说明处生命期:标识符所代表的对象存在的时间范围,三、域和生命期函数

3、,作用域:函数在定义或声明之后,就在其所在代码文件中可见可用 函数具有文件作用域,又称全局域生命期:函数驻留在代码区,程序开始运行时载入,程序执行结束释放 函数具有与程序运行期等长的寿命,称为具有静态生命期,三、域和生命期变量,(3.1)变量的作用域有的变量偏安一隅局部域有的变量名扬天下全局域(3.2)变量的生命期有的变量寿与天齐静态生命期有的变量转瞬即逝局部生命期有的变量命悬人手动态生命期(3.3)名字空间namespace,(3.1)变量的作用域,变量的作用域分析函数内部的变量只在函数范围内可见函数外部的变量在文件A.cpp中都可见,/文件A.cppfloat price=2.3;/定义v

4、oid print()float price=3.1;coutpriceendl;,两种作用域局部域局部变量全局域全局变量,(3.1)变量的作用域局部域,局部域:包括块域和函数声明域块域定义:一对大括号括起来的程序段规则:块中定义的标识符,作用域在块内举例:复合语句是一个块;函数是一个块,也称作函数域。函数中定义和声明的标识符,包括形参和局部变量,作用域都在函数内。,【块域举例】,3,5,a=3 b=5,a=5 b=3,输入两数,按从大到小的顺序保存,并输出结果。,结果,栈,t,=3,int main()int a,b;/具有函数域 coutab;cout=a)int t;/具有块域 t=a;

5、a=b;b=t;/交换a,b的值 couta=atb=bendl;return 0;,上述程序若在最后一个cout语句处增加:couttendl;则编译时错误,因为t的作用域只在if语句中,其它地方不可见。,【块域举例】,编程完成两个整数的交换。,int main()int a=10,b=20;couta“,”bendl;/要求调用完成后b=10,a=20 swap(a,b);couta“,”bendl;return 0;,void swap(int a,int b)int temp;temp=a;a=b;b=temp;couta“,”bendl;,调用前:a=10,b=20,调用前:a=10

6、,b=20,调用中:a=20,b=10,调用后:a=10,b=20,交换失败!原因?,(3.1)变量的作用域局部域,局部域:包括块域和函数声明域函数声明域注意:函数声明与函数定义的区别;在函数声明时,其中形参作用域只在声明中,即作用域结束于声明的右括号;,由于形参不能被程序的其他地方引用,所以通常只声明形参个数和类型,形参名省略。,(3.1)变量的作用域全局域,全局域全局变量又称文件作用域定义在所有函数之外的标识符,其作用域从定义处开始,直到整个文件结束,即全局域文件中定义的全局变量和函数都具有全局域,【全局域举例】,编程完成两个整数的交换。,int a=10,b=20;int main()c

7、outa“,”bendl;/要求调用完成后b=10,a=20 swap();couta“,”bendl;return 0;,void swap()int temp;temp=a;a=b;b=temp;couta“,”bendl;,调用前:a=10,b=20,调用前:a=10,b=20,调用中:a=20,b=10,调用后:a=20,b=10,分析交换过程!,同名变量的作用域,int n=0;/全局变量void print()float price=3.1;int i=10;coutntitpriceendl;long i=20,n;n=price*i;coutntitpriceendl;cout

8、:ntitpriceendl;n=price*i;coutntitpriceendl;,函数块print中嵌套一个块其中存在同名变量试分析输出结果,同名变量的作用域,嵌套块中的同名变量服从局部优先原则:内层块屏蔽外层块中的同名变量块内局部变量与全局变量同名块内局部变量优先块内可通过域运算符“:”访问同名全局变量,(3.1)变量的作用域小结,局部域局部变量块域:,如复合语句、函数域函数声明域全局域全局变量所有函数的外部同名变量的作用域嵌套块中存在同名局部变量局部变量与全局变量同名,(3.2)变量的生命期,变量的生命期:从变量获得存储空间到释放存储空间之间的时段。变量只有在其生命期和作用域中才能被

9、访问,变量的生命期决定于变量位于哪个存储区,寿与天齐,转瞬即逝,命悬人手,(3.2)变量的生命期,(1)代码区(Code area):存放程序代码,即程序中各个函数的代码块;(2)全局数据区(Data area):存放全局数据和静态数据;分配时内存清零,结果变量自动初始化为零;(3)栈区(Stack area):存放局部变量,如函数中的变量等;分配栈区时不初始化内存,即变量取随机值;(4)堆区(Free store area):存放与指针相关的动态数据;分配堆区时不处理内存。,(3.2)变量的生命期,变量的存储类型决定变量位于哪个存储区,从而决定变量的生命期C+提供了四种存储类型说明符:aut

10、o、register:自动存储类型static:静态存储类型extern:外部存储类型,(3.2)变量的生命期自动变量,auto、register:自动存储类型用auto说明的变量为自动变量,局部变量都是自动变量。自动变量位于栈区,具有局部生命期。自动变量的生命期和作用域是一致的:块开始执行时系统自动分配空间,块执行结束时系统自动释放空间。,为提高程序运行效率,可将某些变量保存在寄存器中,即用register说明为寄存器变量,不提倡使用。,(3.2)变量的生命期静态变量,static:静态存储类型用static说明的变量为静态变量两种静态变量局部静态变量:定义在局部域的静态变量全局静态变量:定

11、义在全局域的静态变量静态变量位于全局数据区,具有静态生命期。若未显式初始化则系统自动将其初始化为全0,且只初始化一次。,(3.2)变量的生命期静态变量,局部静态变量定义在局部域中的静态变量当局部块域第一次被执行时,编译系统在全局数据区为局部静态变量分配空间并保存数据,直到整个程序结束才释放该空间局部静态变量具有局部作用域,但却具有全局生命期。,寿与天齐,影响力有限,【局部静态变量举例】,int st()static int t=100;/局部静态变量 t+;return t;int at()int t=100;/自动变量 t+;return t;int main()for(int i=0;i5

12、;i+)coutat()t;coutendl;for(i=0;i5;i+)coutst()t;coutendl;return 0;,运行结果,分析如何得到上述输出?,(3.2)变量的生命期静态变量,全局静态变量定义在全局域中的静态变量全局变量在编译时在全局数据区分配空间,在未显式初始化时系统自动清全0全局静态变量具有全局作用域和全局生命期,静态全局变量或函数的作用域限制在本文件中,其他文件即使通过extern外部声明也无法访问静态全局变量或函数,(3.2)变量的生命期外部变量,extern:外部变量用extern说明的全局变量为外部变量全局变量和函数缺省为外部的,即其作用域可以延伸到程序的其他

13、文件中在其他文件中通过使用“extern”外部声明可以共享已定义的全局变量和函数,extern 返回类型 函数名(形参表);extern 数据类型 变量名;,(3.2)变量的生命期外部变量,问题1:外部变量声明与全局变量定义的区别?变量定义时编译器为其分配存储空间变量声明则表示该全局变量已在其他地方定义过,编译系统不再分配存储空间,问题2:若希望限制全局变量或函数只在本文件使用,该如何处理?,/*A.cpp*/void fun2();/外部函数声明,extern void fun2();int n;/全局变量定义int main()n=1;fun2();/fun2()定义在文件B.cpp中 c

14、outn=nendl;return 0;,尝试分析运行结果,/*B.cpp*/extern int n;/外部变量声明,n定义在A.cpp中void fun2()n=3;,【外部存储类型举例】,(3.2)变量的生命期小结,局部生命期:在局部域定义的变量具有局部生命期;存储于栈区,由系统负责空间的自动分配和释放,且随机初始化;必具有局部作用域。,静态生命期:全局变量、静态变量、函数都具有静态生命期;全局变量和静态变量位于全局数据区,一旦存在就持续到程序运行结束时消亡,且初始化为全0。,动态生命期:变量存储空间的分配和释放由程序控制,位于堆区,不初始化。,(3.3)名字空间,全局变量和函数的命名必

15、须唯一同一文件内不唯一,编译错误多个文件间不唯一,链接错误故需要在所有程序文件范围内保证唯一问题一:多人协作编程如何保证唯一性问题二:使用多家厂商提供的程序库,如MS、IBM、开源代码等,如何保证命名唯一性,(3.3)名字空间,在test.cpp文件中使用输出流对象cout输出字符串“Hello”如果定义全局整型变量cout会如何呢?,/test.cpp#include using namespace std;int cout=10;int main()cout“Hello”endl;,error C2872:cout:ambiguous symbol,全局名字冲突问题,解决办法:使用名字空间

16、,(3.3)名字空间,名字空间全局名字空间:由全局域引入用户名字空间:由用户自定义定义用户名字空间语法:namespace 空间名/变量、函数、类、模板;,namespace std/对象static ios_base:Init _Ios_init;extern _CRTIMP istream cin;extern _CRTIMP ostream cout;extern _CRTIMP ostream cerr,clog;/_Winit类class _CRTIMP _Winit public:_Winit();_Winit();private:static int _Init_cnt;/宽字节

17、对象static _Winit _Wios_init;extern _CRTIMP wistream wcin;extern _CRTIMP wostream wcout,wcerr,wclog;,【名字空间举例】iostream标准头文件,(3.3)名字空间,如何使用名字空间中的成员在名字空间内,直接使用空间内部的标识符在名字空间外,要通过域操作符:,/test.cpp#include int cout=10;int main()std:cout“Hello”std:endl;,OK,(3.3)名字空间,好麻烦哦,每次都要std:coutstd:endlstd:*解决办法:通过using曝光

18、,using 名字空间:成员;/曝光该成员using namespace 名字空间;/曝光所有成员,例如:#include using namespace std;,/test.cpp#include using namespace std;int cout=10;int main()cout“Hello”endl;,error C2872:cout:ambiguous symbol,?,/test.cpp#include using std:endl;int cout=10;int main()std:cout“Hello”endl;,(3.3)名字空间,using namespace st

19、d;曝光了名字空间的所有成员,也增大了名字冲突的可能性,/test.cpp#include using namespace std;int cout=10;int main()std:cout“Hello”endl;,(3.3)名字空间,一点辨疑,#include using namespace std;int main()cout“Hello”endl;,#include int main()cout“Hello”endl;,包含则使用C+流类库,该头文件定义在std名字空间中,因此需要using。,包含相当于调用C库,使用的是全局命名空间;,(3.4)头文件和预编译,头文件是实现声明局部化

20、的重要工具,可以集中放置如下内容:常量和外部变量声明函数声明inline函数定义用户数据类型在其他文件中使用或定义对象或函数时,必须包含相应的头文件,#include using namespace std;,(3.4)头文件和预编译,#include:将头文件包含进用户文件使头文件中定义的标识符在用户文件中可见,即可使用头文件中标识符和函数系统定义的头文件定义一些常用的公用标识符和函数通常的包含方式:#include 用户定义的头文件通常的包含方式:#include“*.h”,(3.4)头文件和预编译,#include是一种预编译指令指示在预编译处理后,将指令中指明的文件嵌入到当前源程序文件

21、的指令位置处预编译指令包括:宏定义指令文件包含指令条件编译指令,(3.4)头文件和预编译,宏定义指令语法:#define 宏名 常量串例如:#define PI 3.1416定义宏后,即可在程序中使用标识符PI。在预处理后产生一个中间文件,文件中所有PI被替换为3.1416。,宏替换:字符串和标识符之间的简单替换。预处理不做任何数据类型和合法性检查,也不分配内存单元,(3.4)头文件和预编译,宏定义可以带参数语法:#define 宏名(形参表)表达式串 例如:#define M(x,y)(x)*(y)/2此后,在程序中可以使用M(a,b),预处理后M(a,b)被替换为(a)*(b)/2参数宏类

22、似于函数,本质却仅是字符替换参数宏的参数通常要用括号()括起来,#define M(x,y)x*y/2分析M(8-3,4+2)预编译后的结果?,文件包含指令:#include,#include指令的两种使用方式:#include 称为标准方式,预处理器将在系统的include子目录下搜索指定文件。适于C+提供的头文件;#include“文件名”预处理器首先在当前文件所在目录下搜索,若找不到再按标准方式搜索。适于用户自定义的头文件。,文件包含指令:#include,嵌套包含:include指令可以嵌套存在问题:可能导致重复包含,出现标识符重复定义问题,/f1.henum sexM,F;struc

23、t complex;,/f2.h#include“f1.h”extern sex s1;extern complex c1;,/f3.cpp#include“f1.h”#include“f2.h”;int main(),例如,error C2011:sex:enum type redefinitionerror C2011:complex:struct type redefinition,条件编译指令,解决重复包含:用条件编译指令条件编译:在不同条件下编译程序的不同部分。两种条件编译方式用表达式作编译条件用宏名作编译条件,条件编译指令,用表达式作编译条件#if defined#else#end

24、if#if!defined#else#endif用宏名作编译条件#ifdef#else#endif#ifndef#else#endif#ifdef#elif#elif#else#endif,条件编译指令,#ifdef,#ifndef,defined用来测试某个宏是否被定义 例如,#if defined(UNIX)&!defined(DEBUG)#include f1.h#endif,#ifndef _FILE_H_#define _FILE_H_#include f1.h#endif,/f1.h#ifndef _FILE1_H_#define _FILE1_H_enum sexM,F;struct complex double real;double img;#endif,/f2.h#include“f1.h”extern complex add(complex,/f3.cpp#include“f1.h”#include“f2.h”;int main(),/f2.cpp#include“f2.h”,三、域和生命期小结,域和生命期的概念函数的域和生命期变量的域和生命期局部域/局部变量、全局域/全局变量变量存储区域:全局数据区、堆区、栈区变量存储类型:auto/register,static,extern变量生命期:局部、静态、动态名字空间及其using头文件和预编译,

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

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号