面向对想程序设计4.ppt

上传人:asd****56 文档编号:87081691 上传时间:2023-04-16 格式:PPT 页数:197 大小:1.13MB
返回 下载 相关 举报
面向对想程序设计4.ppt_第1页
第1页 / 共197页
面向对想程序设计4.ppt_第2页
第2页 / 共197页
点击查看更多>>
资源描述

《面向对想程序设计4.ppt》由会员分享,可在线阅读,更多相关《面向对想程序设计4.ppt(197页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、C+语言和面向对象程序设计语言和面向对象程序设计程序设计基础程序设计基础结构化程序设计结构化程序设计面向对象程序设计面向对象程序设计程序健壮性设计程序健壮性设计第二章第二章 程序设计基础程序设计基础基本基本C+语法格式语法格式数据类型数据类型运算符和表达式运算符和表达式基本语句基本语句本章要求目标:回顾C+与C相同部分知识点,掌握不同部分知识点数据类型const常量变量定义与初始化方式内容内容基本基本C+语法格式语法格式数据类型数据类型运算符和表达式运算符和表达式基本语句基本语句2.1基本C+语法格式C+是严格区分大小写的是严格区分大小写的C+是一种自由格式的语言是一种自由格式的语言 用用C+

2、语言编程时,程序的书写非常自由,甚语言编程时,程序的书写非常自由,甚至可以把整个函数体全部书写在一行上。但这样做,至可以把整个函数体全部书写在一行上。但这样做,对人来说,如果程序稍长一点,就难理解了。对人来说,如果程序稍长一点,就难理解了。2.1基本C+语法格式C+是严格区分大小写的是严格区分大小写的C+是一种自由格式的语言是一种自由格式的语言书写基本原则如下:书写基本原则如下:1.一行一般写一条语句。长语句一行写不下时可一行一般写一条语句。长语句一行写不下时可以一条写多行。分行原则是不能将一个单词分开。以一条写多行。分行原则是不能将一个单词分开。用用双引号引用的字符串和宏定义一行写不下需要续

3、行时双引号引用的字符串和宏定义一行写不下需要续行时需用续行符需用续行符。2.在书写在书写C+程序时,采用比较美观的程序时,采用比较美观的“缩进缩进”格式来书写。格式来书写。2.1基本C+语法格式(续)良好编程习惯:较长的语句可分割成几行,如果必须这样分割一条语句,请挑选最合适的断点。比如对一个用逗号分割的列表来说,可选择在某个逗号之后断开;对于较长的表达式,可考虑在一个运算符之后断开,等等。一个语句分割成多行后,除第一行之外,其他所有行都进行缩进处理。2.1基本C+语法格式(续)良好编程习惯:对于缩进的尺度,约定一个你喜欢的大小,然后始终如一的应用它。Tab键可用于产生缩进,但是制表间距可能会

4、不一样。我们建议使用1/4in(1in=2.54cm)的制表间距,或者(更适宜地)用3个空格大小构成一个缩进级别。2.1基本C+语法格式(续)C+程序的注释程序的注释作用:提高程序的可读性;调试程序作用:提高程序的可读性;调试程序/和和/*/软件编码规范中说:软件编码规范中说:“可读性第一,效率可读性第一,效率第二第二”。在程序中必须包含适量的注释,。在程序中必须包含适量的注释,以提高程序的可读性和易维护性,程序注以提高程序的可读性和易维护性,程序注释一般占程序代码总量的释一般占程序代码总量的20%-50%。2.1基本C+语法格式(续)良好编程习惯:每个程序都应该以注释开头,由于描述该程序的用

5、途、作者、日期和时间。/Program:Display greetings/Author(s):Ima Programmer/Date:1/24/2001/Program:Display greetings/Author(s):Ima Programmer/Date:1/24/2001#include using namespace std;int main()cout Hello world!field)字符串常量符号常量是指有名字的变量。在程序中使用常量时,除了采用字面常量形式外,还可以首先通过常量定义给常量取一个名字,并指定一个类型,然后,在程序中通过常量名来使用这些常量。符号常量符号常

6、量符号常量C C语言中声明符号常量的方法语言中声明符号常量的方法用用#define#define声明符号常量声明符号常量#definepi3.1415926#definepi3.1415926C+C+语言中广泛采用的声明符号常量的方法语言中广泛采用的声明符号常量的方法constconst数据类型数据类型常量名常量名=常量值;常量值;或:或:数据类型数据类型 constconst常量名常量名=常量值;常量值;用用constconst声明符号常量声明符号常量用用#define#define声明符号常声明符号常量量解释解释C+C+语言中广泛采用的声语言中广泛采用的声明符号常量的方法明符号常量的方法C

7、 C语言中声明符号常语言中声明符号常量的方法。其中量的方法。其中#define#define是预处理指令。是预处理指令。缺点是不能显式声明缺点是不能显式声明常量的类型。常量的类型。形式形式constconst数据类型数据类型常量名常量名=常量值;常量值;或:或:数据类型数据类型 constconst常量名常量名=常量值;常量值;正确声正确声明明constconst doubledouble pi=3.1415926;pi=3.1415926;#definepi3.1415926#definepi3.1415926错误声错误声明明constdoublepi;/constdoublepi;/错误错

8、误pi=3.1415926;/pi=3.1415926;/错错误误最后不允许加最后不允许加最后不允许加最后不允许加“;”const定义的符号常量可以看作是一个定义的符号常量可以看作是一个只读变量,只读变量,不可在程序中修改它的值不可在程序中修改它的值。定义时必须初始化定义时必须初始化。注意注意注意注意bool类型的值true和false可以看成是C+语言预定义的两个符号常量,它们的值分别为1和0。符号常量有些数据在程序运行过程中是可以改变的,有些数据在程序运行过程中是可以改变的,有些数据在程序运行过程中是可以改变的,有些数据在程序运行过程中是可以改变的,我们称之为我们称之为我们称之为我们称之为

9、变量变量变量变量。一个变量对应着计算机中的一组内存单元,一个变量对应着计算机中的一组内存单元,一个变量对应着计算机中的一组内存单元,一个变量对应着计算机中的一组内存单元,这组内存单元在这组内存单元在这组内存单元在这组内存单元在C+C+语言中用一个标识符来语言中用一个标识符来语言中用一个标识符来语言中用一个标识符来标识,即标识,即标识,即标识,即变量名变量名变量名变量名。变量变量变量变量变量定义任何一个变量在被引用之前必须定义。与与C语言不同的是语言不同的是C+可以在程序中随时定义变可以在程序中随时定义变量,不必集中在执行语句之前。量,不必集中在执行语句之前。良好编程习惯:每个逗号(,)后都应该

10、插入一个空格,以增强程序可读性。程序中常需要对一些变量预先设置初值,这一过程序中常需要对一些变量预先设置初值,这一过程称为初始化。在程称为初始化。在C/C+C/C+中,可以在定义变量时同时使中,可以在定义变量时同时使变量初始化。变量初始化。C+C+变量的初始化还有另外一种形式,它与变量的初始化还有另外一种形式,它与C C语言语言不同。例如:不同。例如:int nX(1),nY(3);int nX(1),nY(3);表示表示nX和和nY是整型变量,它们的初值分别为是整型变量,它们的初值分别为1和和3。变量的初始化内容内容基本基本C+语法格式语法格式数据类型数据类型运算符和表达式运算符和表达式基本

11、语句基本语句2.3运算符和表达式同C语言(算术、关系、逻辑、位、赋值、sizeof、条件、逗号)操作数的类型转换(隐式、显式)注意运算符的优先级和结合性良好编程习惯:在二元运算符的两端分别添加一个空格。这样可突出显示运算符,增强程序可读性。2.3运算符和表达式良好编程习惯:在编写含有多个运算符的表达式时,务必参考运算符优先级表。如果表达式过于复杂,无法确定顺序,可将表达式分割成几个小语句,或者干脆用括号强行规定顺序。内容内容基本基本C+语法格式语法格式数据类型数据类型运算符和表达式运算符和表达式基本语句基本语句分类分类分类分类简单语句简单语句结构语句结构语句表达式语句表达式语句转移语句转移语句

12、空语句空语句gotogoto语句语句breakbreak语句语句continuecontinue语句语句returnreturn语句语句复合语句复合语句选择语句选择语句循环语句循环语句ifif语句语句switchswitch语句语句whilewhile语句语句do-whiledo-while语句语句forfor语句语句2.4基本语句C+语言和面向对象程序设计语言和面向对象程序设计程序设计基础程序设计基础结构化程序设计结构化程序设计面向对象程序设计面向对象程序设计程序健壮性设计程序健壮性设计第三章结构化程序设计函数数组指针和引用其他复合数据类型本章要求目标:回顾C+与C相同部分知识点,掌握不同部

13、分知识点内联函数变量的存储分配C+程序的多模块结构标识符的作用域本章要求(续)知识点带默认参数值的函数函数重载动态变量指向常量的指针和指针常量引用内容函数函数数组指针和引用其他复合数据类型3.1函数函数是一个能完成某一独立功能的子程序,也就是程序模块。每个C+程序至少包含一个函数,即main函数(主函数)。3.1函数(续)在在在在面向对象的程序设计面向对象的程序设计面向对象的程序设计面向对象的程序设计中,一个中,一个中,一个中,一个C+C+程序是由类的实例(对象)程序是由类的实例(对象)程序是由类的实例(对象)程序是由类的实例(对象)构成。函数主要用于定义对象的操构成。函数主要用于定义对象的操

14、构成。函数主要用于定义对象的操构成。函数主要用于定义对象的操作接口。作接口。作接口。作接口。在在在在面向过程的程序设计面向过程的程序设计面向过程的程序设计面向过程的程序设计中,一个较中,一个较中,一个较中,一个较为复杂的程序一般通过模块化,分为复杂的程序一般通过模块化,分为复杂的程序一般通过模块化,分为复杂的程序一般通过模块化,分解成主模块与若干子模块的组合,解成主模块与若干子模块的组合,解成主模块与若干子模块的组合,解成主模块与若干子模块的组合,即一个主函数与若干子函数。程序即一个主函数与若干子函数。程序即一个主函数与若干子函数。程序即一个主函数与若干子函数。程序是以函数为单位,由一个或多个

15、函是以函数为单位,由一个或多个函是以函数为单位,由一个或多个函是以函数为单位,由一个或多个函数组成的。数组成的。数组成的。数组成的。在面向过程的程序设计中,一个在面向过程的程序设计中,一个在面向过程的程序设计中,一个在面向过程的程序设计中,一个C+C+程序由一个或程序由一个或程序由一个或程序由一个或多个函数组成。当程序开始运行时,系统自动调用主多个函数组成。当程序开始运行时,系统自动调用主多个函数组成。当程序开始运行时,系统自动调用主多个函数组成。当程序开始运行时,系统自动调用主函数。主函数可以调用子函数,子函数还可以调用其函数。主函数可以调用子函数,子函数还可以调用其函数。主函数可以调用子函

16、数,子函数还可以调用其函数。主函数可以调用子函数,子函数还可以调用其他子函数。他子函数。他子函数。他子函数。调用其他函数的函数称为主调函数,被其他函数调用调用其他函数的函数称为主调函数,被其他函数调用调用其他函数的函数称为主调函数,被其他函数调用调用其他函数的函数称为主调函数,被其他函数调用的函数称为被调函数。的函数称为被调函数。的函数称为被调函数。的函数称为被调函数。3.1函数(续)3.1函数(续)主程序(main)函数1(function1)函数2(function2)函数3(function3)函数4(function4)函数5(function5)函数6(function6)函数7(f

17、unction7)函数的定义函数的定义函数的定义函数的定义在在在在C+C+程序中,定义一个函数的格式如下:程序中,定义一个函数的格式如下:程序中,定义一个函数的格式如下:程序中,定义一个函数的格式如下:类型类型类型类型 函数名(形式参数表)函数名(形式参数表)函数名(形式参数表)函数名(形式参数表)语句序列语句序列语句序列语句序列 该函数的类型,该函数的类型,该函数的类型,该函数的类型,即该函数返回即该函数返回即该函数返回即该函数返回值的类型。值的类型。值的类型。值的类型。没有形参没有形参没有形参没有形参的函数,可以在形参表的位置填上的函数,可以在形参表的位置填上的函数,可以在形参表的位置填上

18、的函数,可以在形参表的位置填上voidvoid或或或或保保保保留空白留空白留空白留空白,但形参表两边的,但形参表两边的,但形参表两边的,但形参表两边的圆括号不可省略圆括号不可省略圆括号不可省略圆括号不可省略。形式参数表由形式参数表由形式参数表由形式参数表由0 0个、个、个、个、1 1个或多个参数组成,内容如下:个或多个参数组成,内容如下:个或多个参数组成,内容如下:个或多个参数组成,内容如下:类型类型类型类型1 1 形式参数名形式参数名形式参数名形式参数名1 1,类型类型类型类型2 2 形式参数名形式参数名形式参数名形式参数名2 2,类型类型类型类型n n 形式参数名形式参数名形式参数名形式参

19、数名n n函数的定义函数的定义函数的定义函数的定义double rectanglearea(double a,double b)double rectanglearea(double a,double b)double s;double s;s=a*b;s=a*b;return s;return s;函数的定义示例函数的定义示例函数的定义示例函数的定义示例每个函数都是一个功能独立的模块,绝对不允每个函数都是一个功能独立的模块,绝对不允许在一个函数体内定义另一个函数。许在一个函数体内定义另一个函数。函数定义注意:声明函数,一般采用声明函数原型。声明函数,一般采用声明函数原型。声明函数,一般采用声

20、明函数原型。声明函数,一般采用声明函数原型。形式如下:形式如下:形式如下:形式如下:类型类型类型类型 函数名(形式参数表);函数名(形式参数表);函数名(形式参数表);函数名(形式参数表);函数原型中的函数原型中的函数原型中的函数原型中的类型、函数名和形参表类型、函数名和形参表类型、函数名和形参表类型、函数名和形参表必须与定义该函必须与定义该函必须与定义该函必须与定义该函数时数时数时数时完全一致完全一致完全一致完全一致,但函数原型中可以,但函数原型中可以,但函数原型中可以,但函数原型中可以不包含不包含不包含不包含参数名,而参数名,而参数名,而参数名,而只包含只包含只包含只包含形参的类型。形参的

21、类型。形参的类型。形参的类型。例如:例如:例如:例如:double rectanglearea(double a,double b)double rectanglearea(double a,double b)double rectanglearea(double a,double b)double rectanglearea(double a,double b);double rectanglearea(doubledouble rectanglearea(doubledouble rectanglearea(doubledouble rectanglearea(double,double)

22、double)double)double);函数的声明函数的声明函数的声明函数的声明除除除除主函数主函数主函数主函数mainmainmainmain由系统自动调用外,其他函数都由主函数由系统自动调用外,其他函数都由主函数由系统自动调用外,其他函数都由主函数由系统自动调用外,其他函数都由主函数直接或间接调用的。直接或间接调用的。直接或间接调用的。直接或间接调用的。函数的调用函数的调用函数的调用函数的调用函数的调用的一般形式如下:函数的调用的一般形式如下:函数的调用的一般形式如下:函数的调用的一般形式如下:函数名(实际参数表)函数名(实际参数表)函数名(实际参数表)函数名(实际参数表)程序中调用的

23、所有函数都要有定义,如果函数定程序中调用的所有函数都要有定义,如果函数定义在其他文件中(如义在其他文件中(如C+的标准库)或定义在的标准库)或定义在本源文件使用点之后,则在调用前需要对被调用本源文件使用点之后,则在调用前需要对被调用的函数进行声明。的函数进行声明。main()调fun()结束fun()返回保存:返回地址当前现场恢复:主调程序现场返回地址函数的调用函数的调用函数的调用函数的调用进程内存空间ESPEIP0 xc00000000 x80000000LinuxWin32.参数参数n参数参数1返回地址返回地址被保存的被保存的%ebp被保存寄存器、被保存寄存器、本地变量本地变量和临时变量和

24、临时变量参数构造区域参数构造区域较早的帧调用者的帧当前帧地址增大栈底栈顶帧指针%ebp栈指针%esp函数调用过程的三个步骤调用参数和返回地址(当前EIP)压栈,当前EBP压栈跳转到函数入口,开始执行被调函数恢复调用者原有栈,并跳到堆栈中保存的返回地址低地址方向其他数据,例如被调函数的局部变量EIP被调函数的参数其他数据,例如上层函数的局部变量SHE指针高地址方向EBPWindows系统的栈espespespespespespespespespespesp函数的调用函数的调用函数的调用函数的调用函数调用过程示例21Ret-addebpretValStack frameespespespespma

25、inebpespfuncebpespespespespesp函数的调用函数的调用如返回地址返回地址被改写,函数返回时,流程会转入到被改写的地址!低地址方向其他数据,例如被调函数的局部变量EIP被调函数的参数其他数据,例如上层函数的局部变量SEH指针高地址方向EBP缓冲区溢出缓冲区(buffer)用于临时存储数据的一段内存区域charbuffer256;buffer=malloc64;溢出(overflow)数据过长导致无法存储在预期区域内,覆盖了存储其他数据的区域strcpy(smallBuffer,bigString)缓冲区溢出缓冲区溢出:缓冲区溢出:当计算机向缓冲区内填充数据时超过了缓冲区

26、本身的容量,溢出的数据覆盖到了合法数据上。缓冲区溢出缓冲区溢出分类栈缓冲区溢出(stackoverflow)溢出发生在栈内存中覆盖栈结构堆缓冲区溢出(heapoverflow)溢出发生在堆内存中覆盖指定的四字节指针栈缓冲区溢出一个典型的问题程序voidvulfunc(char*str)charbuffer8;strcpy(buffer,str);voidmain(intargc,char*argv)if(argc1)vulfunc(argv1);安全函数可以限制所操作的数据长度,正确正确使用则不会导致缓冲区问题的函数strncpy(),memcpy(),snprintf(),strncat()

27、,栈缓冲区溢出strncpy(DstBuffer,SrcBuffer,sizeof(DstBuffer)-1);栈缓冲区溢出没有正确地使用安全函数strcpy(DstBuffer,SrcBuffer,sizeof(SrcBuffer)-1)strncpy等字符串截断拷贝函数的陷阱如果源字符串长度大于或等于限定长度参数,strncpy会按照限定长度拷贝到目标,但并不会在最后加上字符串结束符0这个陷阱可能导致不易察觉的缓冲区溢出非安全函数没有内嵌边界保护支持,必须要使用额外代码进行边界检查的函数strcat(),strcpy(),sprintf(),vsprintf(),bcopy(),gets(

28、),scanf(),栈缓冲区溢出边界检查(BoundaryCheck)在向缓冲区中存储数据时,确定数据长度是否会超出缓冲区边界if(sizeof(SrcBuffer)sizeof(DstBuffer)strcpy(DstBuffer,SrcBuffer);elseprintf(“DstBufferistoosmall.n”);栈缓冲区溢出没有使用安全函数,也没有进行边界检查没有正确地使用安全函数设计和计算失误MultiByteToWideChar()缓冲区溢出存在的原因攻击者使远程服务程序或者本地程序崩溃攻击者以被攻击的程序运行时的身份执行任意代码攻击者控制远程系统缓冲区溢出的后果永远不相信用

29、户输入永远不相信用户输入实参与形参结实参与形参结实参与形参结实参与形参结合方法合方法合方法合方法传值调用传值调用传值调用传值调用:传址调用传址调用传址调用传址调用引用调用引用调用引用调用引用调用简称值调用(默认)。简称值调用(默认)。简称值调用(默认)。简称值调用(默认)。函数的调用函数的调用函数的调用函数的调用XN被调函数:被调函数:主调函数:主调函数:3 2.5AD=power(A,3)2.53doublepower(doubleX,intN)函数的调用函数的调用函数的调用函数的调用-传值调用传值调用传值调用传值调用例:例:输入两输入两 整数交换后输出整数交换后输出#includevoid

30、 Swap(int a,int b);int main()int x(5),y(10);coutx=x y=yendl;Swap(x,y);coutx=x y=yendl;return 0;void Swap(int a,int b)int t;t=a;a=b;b=t;运行结果运行结果:x=5 y=10 x=5 y=10例:例:输入两输入两 整数交换后输出整数交换后输出例:输入两例:输入两 整数交换后输出整数交换后输出void swap(int*a,int*b)int temp;temp=*a;*a=*b;*b=temp;void main()int m=3,n=5;swap(&m,&n);c

31、outm=m n=nendl;数组作为函数参数数组作为函数参数o数组元素作实参,与单个变量一样。数组元素作实参,与单个变量一样。o数组名作参数,形、实参数都应是数组名,数组名作参数,形、实参数都应是数组名,类型要一样,传送的是数组首地址。对形参类型要一样,传送的是数组首地址。对形参数组的改变会直接影响到实参数组。数组的改变会直接影响到实参数组。程程序序的的执执行行过过程程中中,调调用用函函数数时时先先要要保保存存主主调调函函数数的的现现场场和和返返回回地地址址,然然后后程程序序转转移移到到被被调调函函数数的的起起始始地地址址继继续续执执行行。被被调调函函数数执执行行结结束束后后,先先恢恢复复主

32、主调调函函数数的的现现场场,取取出出返返回回地地址址并并将将返返回回值值赋赋给给函函数数调调用用本本身身,最最后后在在返返回回地地址址处处开开始始继继续续执执行行。当当函函数数体体比比较较小小时时,且且执执行行的的功功能能比比较较简简单时,这种函数调用方式的系统开销相对较大。单时,这种函数调用方式的系统开销相对较大。思考思考思考思考内联函数内联函数内联函数内联函数在程序编译时,编译系统将程序中出现内联函在程序编译时,编译系统将程序中出现内联函数调用的地方用函数体进行替换。由于在编译数调用的地方用函数体进行替换。由于在编译时将函数体中的代码被替代到程序中,因此会时将函数体中的代码被替代到程序中,

33、因此会增加目标程序代码量增加目标程序代码量,进而增加空间开销,而,进而增加空间开销,而在时间开销上不象函数调用时那么大,可见它在时间开销上不象函数调用时那么大,可见它是以目标代码的增加为代价来换取时间的节省。是以目标代码的增加为代价来换取时间的节省。内联函数的使用会增加程序的代码量。内联函数的使用会增加程序的代码量。内联函数的使用会增加程序的代码量。内联函数的使用会增加程序的代码量。注注注注内联函数一般来说仅适用于只有一、两条语句内联函数一般来说仅适用于只有一、两条语句内联函数一般来说仅适用于只有一、两条语句内联函数一般来说仅适用于只有一、两条语句的小函数。的小函数。的小函数。的小函数。内联函

34、数的定义:在函数定义时,在函数的类型内联函数的定义:在函数定义时,在函数的类型前增加关键字前增加关键字inline。形式如下:形式如下:形式如下:形式如下:inline inline 类型类型类型类型 函数名(形参表)函数名(形参表)函数名(形参表)函数名(形参表)././函数体函数体函数体函数体 说明:仅在声明函数原型时加说明:仅在声明函数原型时加说明:仅在声明函数原型时加说明:仅在声明函数原型时加上关键字上关键字上关键字上关键字inlineinline,并不能达到,并不能达到,并不能达到,并不能达到内联效果。内联效果。内联效果。内联效果。内联函数内联函数内联函数内联函数#includein

35、line double CalArea(double radius)return 3.14*radius*radius;int main()double r(3.0);double area;area=CalArea(r);coutareaendl;return 0;内联函数示例内联函数示例内联函数示例内联函数示例(1)(1)对于内联函数,编译程序并不生成独立的函对于内联函数,编译程序并不生成独立的函数代码,而是用内联函数的函数体来替换对内联数代码,而是用内联函数的函数体来替换对内联函数的调用。因此,在调用内联函数时一定要见函数的调用。因此,在调用内联函数时一定要见到内联函数的定义,仅仅对其声

36、明是不行的。到内联函数的定义,仅仅对其声明是不行的。注意注意注意注意(2)(2)需要定义成的内联函数不能含有循环、switch和复杂嵌套的if语句。(3)(3)递归函数是不能被用来做内联函数的。(4)(4)编译器是否将用户定义成的内联函数作为真正的内联函数处理由它自行决定。注意注意注意注意(4)(4)内联函数名具有文件作用域内联函数名具有文件作用域 ,在一个文件中,在一个文件中定义的内联函数对于另一个文件是不可见的。定义的内联函数对于另一个文件是不可见的。对对于一个多文件结构的程序,如果在一个源文件中于一个多文件结构的程序,如果在一个源文件中定义了一个内联函数,而在另一个源文件中对其定义了一个

37、内联函数,而在另一个源文件中对其声明并使用,这将导致程序连接时刻的错误。声明并使用,这将导致程序连接时刻的错误。注意注意注意注意全局变量与局部变量全局变量与局部变量全局变量与局部变量全局变量与局部变量 在在C+中,根据变量的定义位置,中,根据变量的定义位置,把变量分为全局变量和局部变量。把变量分为全局变量和局部变量。全局变全局变量是指定义在函数外部的变量,它能被所量是指定义在函数外部的变量,它能被所有函数使用。局部变量是指在复合语句有函数使用。局部变量是指在复合语句(函数)中定义的变量,它们只能在定义(函数)中定义的变量,它们只能在定义它们的复合语句(包括内层的复合语句)它们的复合语句(包括内

38、层的复合语句)中使用。中使用。全局变量可以定义在函数外的任何地方,如果在全局变量可以定义在函数外的任何地方,如果在使用一个全局变量时未见到它的定义,则在使用使用一个全局变量时未见到它的定义,则在使用前需要对该全局变量进行声明。前需要对该全局变量进行声明。变量声明格式:extern ;变量定义要给变量分配空间,变量声明则否。在整个程序中,一个变量的定义只有一个,而该变量的声明可以有多个。全局变量与局部变量全局变量与局部变量全局变量与局部变量全局变量与局部变量局部变量可以放在复合语句的任何位置,但是,在局部变量可以放在复合语句的任何位置,但是,在复合语句中局部变量定义之前不能使用他们。复合语句中局

39、部变量定义之前不能使用他们。int main()x /error int x;x /ok全局变量与局部变量全局变量与局部变量全局变量与局部变量全局变量与局部变量函数的形参也可看成局部变量,它们函数的形参也可看成局部变量,它们只能在相应的函数中使用。只能在相应的函数中使用。全局变量与局部变量全局变量与局部变量全局变量与局部变量全局变量与局部变量变量是变量是内存空间内存空间的一种抽象,程序中定义的每个的一种抽象,程序中定义的每个变量在程序运行时刻都有与之对应的变量在程序运行时刻都有与之对应的内存空间内存空间。但是,何时给变量分配空间以及相应空间分配在但是,何时给变量分配空间以及相应空间分配在哪里?

40、这要视变量的性质而定。通常把程序运行哪里?这要视变量的性质而定。通常把程序运行时一个变量占有内存空间的时间段称为该时一个变量占有内存空间的时间段称为该变量的变量的生存期生存期。变量的存储分配(生存期)变量的存储分配(生存期)n 静态静态 内存空间从程序开始执行就进行分配,直到程序结束才收回。全局变量具有静态生存期全局变量具有静态生存期。n 自动自动 内存空间在程序执行到它们所在的复合语句(函数)时才分配,当定义它们的复合语句执行结束时,它们的空间将会收回。局部变量和函数的参数一般一般具有自动生存期。n 动态动态 内存空间用new操作分配、用delete操作收回。变量的三种生存期变量的三种生存期

41、1,malloc与free是C+/C语言的标准库函数,new/delete是C+的运算符。它们都可用于申请动态内存和释放内存。2,对于非内部数据类型的对象而言,光用maloc/free无法满足动态对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free。3,因此C+语言需要一个能完成动态内存分配和初始化工作的运算符new,以一个能完成清理与释放内存工作的运算符delete。注意new/delete不是库函数。4,C+程序经常要调用C函

42、数,而C程序只能用malloc/free管理动态内存。5、new可以认为是malloc加构造函数的执行。new出来的指针是直接带类型信息的。而malloc返回的都是void指针 另外,在定义另外,在定义局部变量局部变量时,可以为它们加上时,可以为它们加上存储类型存储类型修饰符修饰符auto、static或或register来指来指定它们的生存期。定它们的生存期。变量的三种生存期变量的三种生存期变量的三种生存期变量的三种生存期局部变量的默认存储类型为局部变量的默认存储类型为auto,即定义,即定义局部变量时,如果未指定存储类,则其存局部变量时,如果未指定存储类,则其存储类为储类为auto。定义为

43、。定义为auto存储类的局部变存储类的局部变量具有自动生存期;量具有自动生存期;定义为定义为static存储类的局部变量具有静态存储类的局部变量具有静态生存期;生存期;static存储类的局部变量的作用是它能在存储类的局部变量的作用是它能在函数调用时获得上次调用结束时该局部变函数调用时获得上次调用结束时该局部变量的值。量的值。#include int z=0;void f()int x=0;static int y=0;x+;y+;z+;cout“x=“x“,y=”y“,z=”zendl;void main()f();z+;f();变量的三种生存期变量的三种生存期定义为定义为register存

44、储类的局部变量也具有存储类的局部变量也具有自动生存期。它与自动生存期。它与auto存储类的局部变量存储类的局部变量的区别是:的区别是:register存储类是存储类是建议建议编译程编译程序把相应的局部变量的空间分配在序把相应的局部变量的空间分配在CPU的的寄存器中,目的是为了提高对局部变量的寄存器中,目的是为了提高对局部变量的访问效率。访问效率。当一个程序准备运行时,当一个程序准备运行时,操作系统将为其分配一块操作系统将为其分配一块内存空间,其中包括四个内存空间,其中包括四个部分:部分:静态数据区静态数据区(static codestatic code)、代码)、代码区(区(codecode)

45、、栈区)、栈区(stackstack)和堆区()和堆区(heap heap,或称自由存储区或称自由存储区,free,free storestore)。)。静态数据区静态数据区代码区代码区栈区栈区堆区堆区程序内存分配示意图 变量的三种生存期变量的三种生存期静态数据区用于全局变量、静态数据区用于全局变量、static存储类的局部变存储类的局部变量。量。代码区用于存放程序的指令,对代码区用于存放程序的指令,对C+程序而言,代程序而言,代码区存放的是所有函数代码;码区存放的是所有函数代码;栈区用于栈区用于auto存储类的局部变量、函数的形式参数存储类的局部变量、函数的形式参数以及函数调用时的有关信息(

46、如函数返回地址等)以及函数调用时的有关信息(如函数返回地址等)的内存分配;的内存分配;堆区用于动态变量的内存分配。堆区用于动态变量的内存分配。变量的三种生存期变量的三种生存期静态数据区静态数据区代码区代码区栈区栈区堆区堆区Win32进程内存空间系统核心内存区间0 xFFFFFFFF0 x80000000(4G2G)为Win32操作系统保留用户内存区间0 x000000000 x80000000(2G0G)堆:动态分配变量(malloc),向高地址增长静态内存区间:全局变量、静态变量代码区间:从0 x00400000开始栈:向低地址增长单线程进程(栈底地址:0 x0012FFXXXX)多线程进程

47、拥有多个堆/栈变量的初始值变量的初始值全局变量、static存储类的局部变量(存放在静态数据区的变量)在变量定义时有默认值。int型为0,浮点型为0.0,char型为空。auto存储类的局部变量在定义时没有值,此时是一个不可预料的值,因此我们必须在使用前对它进行赋值或初始化。全局变量,是在全局变量,是在main()函数执行前就分配好了的。函数执行前就分配好了的。注意注意C+C+程序的多模块结构程序的多模块结构程序的多模块结构程序的多模块结构 逻辑上,一个逻辑上,一个C+程序由一些全局函数(区程序由一些全局函数(区别于类定义中的成员函数)、全局常量、全局变别于类定义中的成员函数)、全局常量、全局

48、变量量/对象以及类的定义构成,其中必须有且仅有一对象以及类的定义构成,其中必须有且仅有一个个main的全局函数。函数内部还可以包含形参、的全局函数。函数内部还可以包含形参、局部常量、局部变量局部常量、局部变量/对象的定义以及语句。对象的定义以及语句。C+函数内部不能再定义函数。函数内部不能再定义函数。C+程序的多模块结构程序的多模块结构为了便于组织、管理和理解为了便于组织、管理和理解C+程序,特别是为程序,特别是为了避免对程序的一点修改导致对整个程序的重新了避免对程序的一点修改导致对整个程序的重新编译和便于多人合作开发一个程序编译和便于多人合作开发一个程序在物理上我们通常可以按照某种规则对构成

49、在物理上我们通常可以按照某种规则对构成C+程序的若干逻辑单位(全局函数、全局常量、全程序的若干逻辑单位(全局函数、全局常量、全局变量局变量/对象、类等)进行分组,分别把它们放到对象、类等)进行分组,分别把它们放到若干源文件中。编译程序对每个源文件分别进行若干源文件中。编译程序对每个源文件分别进行编译编译C+程序的多模块结构程序的多模块结构分组的原则是按照模块进行,一个模块一般包含分组的原则是按照模块进行,一个模块一般包含两部分:接口和实现。接口给出在本模块中定义两部分:接口和实现。接口给出在本模块中定义的、提供给其他模块使用的一些程序实体(如函的、提供给其他模块使用的一些程序实体(如函数、全局

50、变量等)的声明;模块的实现给出了模数、全局变量等)的声明;模块的实现给出了模块中实体的定义。块中实体的定义。C+程序的多模块结构程序的多模块结构在在C+中,一个模块通常由两个源文件构成,中,一个模块通常由两个源文件构成,一个是一个是.h文件,用于存放模块接口的定义;文件,用于存放模块接口的定义;另一个是另一个是.cpp文件用于存放模块的实现。文件用于存放模块的实现。在一个模块中要用到另一个模块中定义的在一个模块中要用到另一个模块中定义的程序实体时,需要在前者的程序实体时,需要在前者的.cpp文件中用文件中用文件包含命令把后者的文件包含命令把后者的.h文件包含进来。文件包含进来。在编译前,用命令

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

当前位置:首页 > 技术资料 > 其他杂项

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁