收藏 分享(赏)

第02章基本C++语言.ppt

上传人:wspkg9802 文档编号:9204608 上传时间:2019-07-29 格式:PPT 页数:87 大小:557.50KB
下载 相关 举报
第02章基本C++语言.ppt_第1页
第1页 / 共87页
第02章基本C++语言.ppt_第2页
第2页 / 共87页
第02章基本C++语言.ppt_第3页
第3页 / 共87页
第02章基本C++语言.ppt_第4页
第4页 / 共87页
第02章基本C++语言.ppt_第5页
第5页 / 共87页
点击查看更多>>
资源描述

1、第2章基本C+语言,2.1 C+程序结构 2.2 数据类型和基本输入输出 2.3 运算符和表达式 2.4 基本语句 作业1 2.5 函数和预处理 2.6 构造类型 2.7 指针和引用 作业2,2.1C+程序结构,2.1.1几个C+程序 例Ex_Simple2 在屏幕上输出一个由星号形成的三角形。/ 输出星号的三角形阵列#include void DoDraw(int num); / 声明一个全局函数void main() int num=5; / 定义并初始化变量DoDraw(num); / 函数的调用void DoDraw(int num) / 函数的定义for (int i=0; inum

2、; i+) / 循环语句 for (int j=0; j=i; j+)cout*;coutn;,2.1C+程序结构,例Ex_Simple3 用类的概念重写例Ex_Draw。/ 输出星号的三角形阵列#include class CDrawArray / 定义一个类 public:void DoDraw(int num); / 声明类的公有成员函数;void CDrawArray:DoDraw(int num) / 成员函数的实现 for (int i=0;inum;i+) for (int j=0;j=i;j+)cout*;coutn;void main() int num=5;CDrawArr

3、ay myDraw; / 定义类的一个对象myDraw.DoDraw(num); / 调用此对象的成员函数,2.1C+程序结构,2.1.2C+程序的基本组成 C+程序往往由预处理命令、语句、函数、变量和对象、输入与输出以及注释等几个基本部分组成的。(1) 预处理命令在程序的一开始出现含有以“#”开头的命令,它们是预处理命令。三类预处理命令:宏定义命令、文件包含命令和条件编译命令。(2) 语句可以是用来判断的条件语句,可以是用来反复运行的循环语句等。(3) 函数一个程序由若干个函数组成。有的是系统中所提供的库函数,有的是根据自己需要自己编制设计的函数。程序中必须有一个且只能有一个主函数main。

4、(4) 变量和对象变量的类型有整型(int)、字符型(char)以及浮点型(float)等。对象通常是指“类”的实例(具有该“类”类型的变量),如myDraw是类CDrawArray的对象。(5) 输入与输出使用输入与输出可以要求键入一些数值或把计算的结果显示在屏幕上。(6) 注释程序的目的不仅在于实现某种功能、解决某个问题,而且还在于数据结构和算法的交流。注释能提高程序的可读性,帮助用户对程序的理解。,2.1C+程序结构,2.1.3C+程序的书写风格 标识符命名 用来标识变量名、函数名、数组名、类名、对象名、类型名、文件名等的有效字符序列。标识符命名的好坏也会影响程序的可读性,命名时注意:

5、(1) 合法性标识符由大小写字母、数字字符(09)和下划线组成,第一个字符必须为字母或下划线。任何标识符中都不能有空格、标点符号及其他字符。注意,标识符的大小写是有区别的。用户定义的标识符不能和系统的关键字同名。(2) 有效性标识符的长度(组成标识符的字符个数)是任意的,最好不超过32个,因为有的编译系统只能识别前32个字符,也就是说前32个字符相同的两个不同标识符被有的系统认为是同一个标识符。(3) 易读性在定义标识符时,若能做到“见名知意”就可以达到易读性的目的。,2.1C+程序结构,缩进和注释 缩进是指程序在书写时不要将程序的每一行都由第一列开始,在适当的地方加进一些空行或空格。它同注释

6、一样,也是为了提高程序的可读性。注释要注意的是: (1) 注释应在编程的过程中同时进行,不要指望程序开发完成后再补写注释。那样只会多花好几倍的时间,更为严重的是,时间长了以后甚至会读不懂自己写的程序。 (2)必要的注释内容应包含:源程序的总体注释(文件名、作用、创建时间、版本、作者及引用的手册、运行环境等)、函数注释(目的、算法、使用的参数和返回值的含义、对环境的一些假设等)及其他的少量注释。千万不要陈述那些一目了然的内容,否则会使注释的效果适得其反。,2.2数据类型和基本输入输出,2.2.1基本数据类型 使用基本数据类型时需要注意: (1)无符号和有符号的区别在于数值最高位的含义。对sign

7、ed类型,最高位是符号位,其余各位表示数值大小;unsigned类型的各个位都用来表示数值大小;相同基本数据类型的signed和unsigned的数值范围是不同。 (2) char、short、int和long可统称为整型。缺省时,char、short、int和long本身是有符号(signed)的。,2.2数据类型和基本输入输出,2.2.2常量 整型常量 (1) 十进制整型常量:即十进制整数,如34、128等。(2) 八进制整型常量:以0开头的数,由0至7的数字组成。(3) 十六进制整型常量:以0x或0X开头的数,由0至9、A至F或a至f组成。需要注意的是:整型常量中的长整型(long)要以

8、L或小写字母l作为结尾。整型常量中的无符号型(unsigned)要以U或u作为结尾。 浮点型常量 (1) 十进制数形式:由整数部分和小数部分组成。(2) 指数形式:采用科学表示法,能表示出很大或很小的浮点数。若浮点型常量是以F(或f)结尾的,则表示单精度类型(float),以L(或小写字母l)结尾的,表示长双精度类型(long double)。若一个浮点型常量没有任何说明,表示双精度类型(double)。,2.2数据类型和基本输入输出,字符常量 字符常量是用单引号括起来的一个字符。,2.2数据类型和基本输入输出,例Ex_DrawBox 用转义序列符绘制矩形框。#include void Dra

9、wBox(int nWidth, int nHeight);void main() DrawBox(20, 6); void DrawBox(int nWidth, int nHeight) int i;/ 绘制矩形框的顶边cout311; /字符的扩展ASCII是311for (i=1; inWidth; i+)cout315;/字符的扩展ASCII是315cout“273n“; /字符的扩展ASCII是273/ 绘制矩形框的两边for (i=1; inHeight; i+) cout272; /字符的扩展ASCII是272for (int j=1; jnWidth; j+) cout ;c

10、out“272n“;cout310; /字符的扩展ASCII是310for (i=1; inWidth; i+) cout315;cout“274n“; /字符的扩展ASCII是274,2.2数据类型和基本输入输出,字符串常量 字符串常量是一对双引号括起来的字符序列。可以包含空格、转义序列符或其他字符。由于双引号是字符串的分界符,因此如果需要在字符串中出现双引号则必须用“”表示。例如:“Please press ”F1” to help!”这个字符串被解释为:Please press “F1” to help!字符串常量必须在同一行书写,若一行写不下,则需要用来连接,不要将字符常量和字符串常量

11、混淆不清,它们主要的区别如下: (1) 字符常量用单引号括起来,占一个字节;字符串常量是用双引号括起来,至少占用两个字节。例如a是字符常量,占有的一个字节用来存放字符a的ASCII码值,而“a”是字符串常量,它的长度不是1而是2,除了字符a之外,它的末尾还有个0字符。每个字符串的末尾都有一个这样的字符。 (2) 字符常量实际上是整型常量的特殊形式,它可以参与常用的算术运算;而字符串常量则不能。例如:int b= a+3;/ 结果b为100,这是因为将a的ASCII码值97参与运算,2.2数据类型和基本输入输出,符号常量 例Ex_PI1 用#define定义符号常量。#include #defi

12、ne PI 3.14159void main() double r = 100.0, area;area = PI * r * r;coutconst double PI = 3.14159;void main() double r = 100.0, area;area = PI * r * r;cout“圆的面积是:“area “n“;,2.2数据类型和基本输入输出,2.2.3变量 变量的定义 定义变量是用下面的格式语句进行定义的: ; 需要说明的是: (1) 在同一个程序块中,不能有两个相同的变量名。 (2) 没有字符串变量类型,字符串是用字符类型的数组或指针来定义的。 (3) 与其他语言

13、相比,C+变量的定义比较自由。 变量的初始化程序中常需要对一些变量预先设置初值,这一过程称为初始化。可以在定义变量时同时使变量初始化,也可以在多个变量的定义语句中单独对某个变量初始化。需要注意的是,一个未初始化的变量不是没有数值,而是取决于变量在系统中的存储形式,它可能是系统的缺省值或无效值。,2.2数据类型和基本输入输出,2.2.4基本输入输出 输出流(cout) 通过cout可以输出一个整数、实数、字符及字符串,cout中的插入符“”可以连续写多个,每个后面可以跟一个要输出的常量、变量、转义序列符、对象以及表达式等。为了更好地调整输出格式,有时还可以使用下面的输出函数。(1) width(

14、)函数:width()函数有两种格式:int width();int width(int);(2) precision()函数:precision()也有两种格式:int precision();int precision(int); (3) fill()函数:fill()函数也有两种格式:char fill();char fill(char);,2.2数据类型和基本输入输出,例Ex_CoutFrm cout的格式输出。#include void main() int nNum = 1234;double fNum = 12.3456789;cout“1234567890“endl;cout.

15、width(10);coutnNumn;cout.width(10);coutfNumendl;coutcout.precision(4)endl;coutfNumendl;cout.fill(#);cout.width(10);coutfNumendl; 执行该程序,结果如下:1 2 3 4 5 6 7 8 9 01 2 3 41 2 . 3 4 5 761 2 . 3 5# # # # # 1 2 . 3 5,2.2数据类型和基本输入输出,输入流(cin) cin可以获得多个键盘的输入值,它具有下列格式:cin .其中,提取符“”可以连续写多个,每个后面跟一个表达式,该表达式通常是获得输入

16、值的变量或对象。 格式算子oct、dec和hex 能分别将输入或输出的数值转换成八进制、十进制及十六进制,例如: 例Ex_Algorism 格式算子的使用。#include void main() int nNum;couthexnNum;cout“Octt“octnNumendl;cout“Dect“decnNumendl;cout“Hext“hexnNumendl; 程序执行时,结果如下:Please input a Hex integer:7bOct 173Dec 123Hex 7b,2.3运算符和表达式,2.3.1算术运算符 算术运算符如下所示:+ (正号运算符,如+4,+1.23等)

17、- (负号运算符,如-4,-1.23等)* (乘法运算符,如6*8,1.4*3.56等)/ (除法运算符,如6/8,1.4/3.56等)% (模运算符或求余运算符,如40%11等)+ (加法运算符,如6+8,1.4+3.56等)- (减法运算符,如6-8,1.4-3.56等) 注意:(1) 除法运算两个整数相除,结果为整数,如7/5的结果为1,它是将小数部分去掉,而不是四舍五入;若除数和被除数中有一个是浮点数,则进行浮点数除法,结果是浮点型。如7/5.0、7.0/5、7.0/5.0的结果都是1.4。(2) 求余运算 求余运算要求参与运算的两个操作数都是整型,结果是两个数相除的余数。例如40%5

18、的结果是0,40%11的结果是7。要理解负值的求余运算,例如40%-11结果是7,-40%11结果是-7,-40%-11结果也是-7。,2.3运算符和表达式,(3) 优先级和结合性将表达式的求值中多种运算之间的先后关系(即运算符之间的优先关系)用运算符的优先级表示,优先级的数值越小优先级越高。在算术运算符中,单目运算符的优先级最高,其次是乘、除和求余,最后是加减。优先级相同的运算符,则按它们的结合性进行处理。运算符的结合性是指运算符和操作数的结合方式,有“从左至右”和“从右至左”。“从左至右的结合”指运算符左边的操作数先与运算符相结合,再与运算符右边的操作数进行运算;自右至左的结合次序是将运算

19、符右边的操作数先与运算符相结合。在算术运算符中,除单目运算符外,其余运算符的结合性都是从左至右的。(4) 关于书写格式在使用运算符进行数值运算时,若书写时没有在双目运算符两边加上空格,则有时编译系统会做出与自己想象中不同的理解。书写时,有时有意识地加上一些括号。这样不仅增强程序的可读性,而且,尤其当对优先关系犹豫时,加上括号是保证正确结果的最好方法。(5) 溢出处理某数除以0或当其它浮点溢出时,编译系统将报告错误并终止程序运行。但对整数溢出,系统却不认为是一个错误。,2.3运算符和表达式,2.3.2赋值运算符 复合赋值 10种复合赋值运算符:+=,-=,*=,/=,%=,=,|=,=,= 注意

20、: (1) 在复合赋值运算符之间不能有空格,例如 += 不能写成 + = 。 (2) 所有运算符高于逗号运算符,复合赋值运算符的结合性是从右至左的。 多重赋值 指在一个赋值表达式中出现两个或更多的赋值符(“=”),例如:nNum1 = nNum2 = nNum3 = 100;赋值符的结合性是从右至左,上述赋值的过程:首先对nNum3 = 100求值,将100赋值给nNum3,同时该赋值表达式取得值100;然后将该值赋给nNum2,该赋值表达式也取得值100;最后将100赋给nNum1。,2.3运算符和表达式,2.3.3数据类型转换 自动转换 将数据类型从低到高进行转换,例如:10 + a +

21、2*1.25 - 5.0/4L运算:(1) 2*1.25的运算,将2和1.25都转换成double型,结果为double型的2.5。(2) 长整型4L和5.0转换成double型,5.0/4L结果为double型,值为1.25。(3) 进行10 + a 的运算,先将a转换成整数97,运算结果为107。(4) 整数107和2.5相加,先将整数107转换成double型,值为109.5。(5)进行109.5 - 1.25的运算,结果为double型的108.25。 强制转换 强制类型有下列两种格式:()、() 。,2.3运算符和表达式,2.3.4关系运算符 是比较两个操作数是否符合给定的条件。若符

22、合条件,则关系表达式的值为“真”,否则为“假”。在编译系统中,往往将“真”表示为“true”或1,将“假”表示为“false”或0。而任何不为0的数被认为是“真”,0被认为是“假”。由于关系运算需要两个操作数,所以关系运算符都是双目运算符。提供了6种关系运算符:(大于),=(大于等于),= =(相等于), ! =(不等于)其中,前4种的优先级相同且高于后面的两种。例如:a = b c 等效于a = ( b c )但关系运算符的优先级低于算术运算符(其他可参见表2.6)。例如:a = b c 等效于a = ( b c ),2.3运算符和表达式,2.3.5逻辑运算符 将多个关系表达式或逻辑量组成一

23、个逻辑表达式。提供了3种逻辑运算符:! 逻辑非(单目):指将“真”变“假”,“假”变“真”。& 逻辑与(双目):指两个操作数都是“真”时,结果为“真”,否则为“假”。| 逻辑或(双目):指两个操作数中有一个是“真”时,结果为“真”,只有它们都为“假”时,结果才为“假”。“逻辑非”、“逻辑与”和“逻辑或”的优先级依次从高到低,且“逻辑非”的优先级还比算术运算符和关系运算符高,而“逻辑与”和“逻辑或”的优先级却比关系运算符要低。例如:0| 2 4 - !0表达式的运算过程是这样的:(1) 进行“!0”的运算,结果为1(“真”)。(2) 进行“8 4-1”的运算,即“8 3”,结果为0(“假”)。(

24、3) 进行“0|0” 的运算,结果为0(“假”)。表达式的值为0。,2.3运算符和表达式,2.3.6 位运算符 是对操作数按其在计算机内表示的二制数逐位地进行逻辑运算或移位运算,参与运算的操作数只能是整型常量或变量。提供了六种位运算符: (按位求反,单目运算符):将一个二进制数的每一位求反,即0变成1,1变成0。 (右移,双目运算符):将左操作数的二进制值向右移动指定的位数,右移后,移出的低位舍弃。无符号数高位补0;有符号数高位补符号位。& (按位与,双目运算符):将两个操作数对应的二进制位进行逻辑与操作。 (按位异或,双目运算符):将两个操作数对应的二进制位进行异或操作。| (按位或,双目运

25、算符):将两个操作数对应的二进制位进行逻辑或操作。 说明: (1) 左移和右移运算可替代乘和除以2的n次方运算,n为移位的位数。 (2) 当多个位运算符出现在同一个表达式中时,要注意它们的优先级别。,2.3运算符和表达式,2.3.7 三目运算符 C+中唯一的三目运算符是条件运算符,其格式如下:? :“条件表达式”是C+中可以产生“真”和“假”结果的任何表达式,如果条件表达式的结果为“真”,则执行表达式1,否则执行表达式2。例如:nNum = (a b) ? 10 : 8;注意,只有在表达式2后面才能出现分号结束符,“表达式1”和“表达式2”中都不能有分号。,2.3运算符和表达式,2.3.8增1

26、和减1运算符 +和-既可放在变量的左边也可以出现在变量的右边,称为前缀运算符和后缀运算符。例如:i+; 或 +i; (等效于i = i + 1; 或i += 1;)i-; 或 -i; (等效于i = i - 1; 或i -= 1;)若前缀运算符和后缀运算符仅用于某个变量的增1和减1,这两都是等价的,如果将这两个运算符和其他的运算符组合在一起,在求值次序上就会产生根本的不同: 如果用前缀运算符对一个变量增1(减1),在将该变量增1(减1)后,用新的值在表达式中进行其他的运算。 如果用后缀运算符对一个变量增1(减1),用该变量的原值在表达式进行其他的运算后,再将该变量增1(减1)。例如:a = 5

27、;b = +a - 1; / 相当于 a = a + 1; b = a 1;和a = 5;b = a+ -1; / 相当于 b = a 1; a = a + 1; 虽然它们中的a值的结果都是6,但b的结果却不一样,前者为5,后者为4。,2.3运算符和表达式,2.3.9逗号运算符 逗号运算符是优先级最低的运算符,它可以使多个表达式放在一行上,从而大大简化了程序。在计算时,C+将从左至右逐个计算每个表达式,最终整个表达式的结果是最后计算的那个表达式的类型和值。例如:j = ( i = 12 , i + 8);式中,i = 12 ,i + 8 是含逗号运算符的表达式,计算次序是先计算表达式i = 1

28、2,然后再计算i + 8,整个表达式的值是最后一个表达式的值,即i + 8的值20, 从而j的结果是20。再如:d = (a = 1, b = a + 2, c = b + 3);d的结果为6。,2.3运算符和表达式,2.3.10 sizeof运算符 sizeof的目的是返回操作数所占的内存空间大小(字节数),具有两种格式:sizeof()sizeof()例如:sizeof(“Hello”) / 计算字符串常量“Hello”的实际长度(字符个数), 结果为6sizeof(int) / 计算整型int所占内存的字节数需要说明的是,由于同一类型的操作数在不同的计算机中占用的存储字节数可能不同,因此

29、sizeof的结果有可能不一样。例如sizeof(int)的值可能是4,也可能是2。,2.4基本语句,2.4.1表达式语句、空语句和复合语句 表达式语句、空语句及复合语句是一些系统顺序执行(操作)的语句。任何一个表达式加上分号就是一个表达式语句。如果表达式是一个空表达式,那么构成的语句称为空语句,也就是说仅由分号“;”也能构成一个语句。空语句仅为语法的需要而设置,并不执行任何动作。复合语句由两条或两条以上的语句组成,并由一对花括号( )括起来。又称为块语句。复合语句中的语句可以是单条语句(包括空语句),也可以再包含复合语句。注意:在复合语句中定义的变量只作用于该复合语句的范围,而在复合语句外,

30、这些变量却不能被调用。例如:例Ex_Block 块语句的变量使用范围。#include void main() int i = 5, j = 6;coutijendl; / 输出的结果是5和6 int i = 2, j = 3, k = 4;coutijkendl; / 输出结果是2、3和4coutijendl; / 输出的结果仍然是5和6,但不能使用k,如coutk;/ 将发生错误。,2.4基本语句,2.4.2选择语句 条件语句 条件语句if具有下列形式:if () else (1)条件语句中的表达式一般为逻辑表达式或关系表达式。表达式的类型也可以是任意的数值类型(包括整型、浮点型、字符型等

31、)。 (2)适当添加花括号(“ ”)来增加程序的可读性。 (3)条件语句中的语句1和语句2也可是if条件语句,这就形成了if语句的嵌套。 (4)else总是和其前面最近的if配套的。,2.4基本语句,开关语句 具有下列形式:switch ( ) case :语句1case :语句2.case :语句ndefault :语句n+1 注意: (1) switch后面的表达式可以是整型、字符型或枚举型的表达式,而case后面的常量表达式的类型必须与其匹配。 (2) 多个case可以共有一组执行语句。 (3) 若同一个case后面的语句是复合语句,即有两条或两条以上的语句,则这些语句可以不用花括号(“

32、”)括起来。 (4) 由于case语句起标号作用,因此每一个case常量表达式的值必须互不相同,否则会出现编译错误。,2.4基本语句,2.4.3循环语句 while循环语句while循环语句具有下列形式:while () do.while循环语句 do.while循环语句具有下列形式:do while () for循环语句 for循环语句具有下列形式:for (表达式1;表达式2;表达式3) (1) 表达式1、表达式2、表达式3都可以省略,但分号“;”不能省略。 (2) 表达式1和表达3可以是一个简单的表达式,也可以是逗号表达式,即包含两个或两个以上的简单表达式,中间用逗号分隔。 (3) 由于

33、循环体是由任何类型的语句组成的,因此在循环体内还可以包含前面的几种循环语句,这样就形成了循环的嵌套。,2.4基本语句,2.4.4break和continue语句 若需跳出循环结构或重新开始循环,就得使用break和continue语句,格式:break;从一个循环体跳出,即提前终止循环,也可以跳出switch结构。continue;用于那些依靠条件判断而进行循环的循环语句。对于for语句来说,目的是将流程转到for语句的表达2和表达式3。例如:例Ex_Continue 把1100之间的不能被7整除的数输出。#include void main() for (int nNum=1; nNum=1

34、00; nNum+) if (nNum%7 = 0) continue;coutnNum” ”;cout”n”;当nNum能被7整除时,执行continue语句,流程转到for 语句中的nNum=100; nNum+,并根据表达式nNum=100的值来决定是否再做循环。而当nNum不能被7整除时,才执行coutnNum” ”语句。,作业,1。P357362:130题偶数题 2。P385:预习实验2,2.5函数和预处理,2.5.1函数的定义和调用 函数的定义 定义一个函数的格式如下: ( )函数体函数类型决定了函数所需要的返回值类型。函数名后面必须跟一对圆括号“( )”,以区别于变量名及其他用户

35、定义的标识名。函数的形式参数写在括号内,参数表中参数个数可以是0,一个或多个参数,圆括号不能省略。函数体由在一对花括号中的若干条语句组成,用于实现这个函数执行的动作。 函数的声明 声明一个函数可按下列格式进行:( ); int sum(int x, int y);和 int sum(int , int); 是等价的。,2.5函数和预处理,函数的调用 函数调用的一般形式为:( );所谓“实际参数”(简称“实参”),它与“形参”相对应,是实际调用函数时所给定的常量、变量或表达式,且必须有确定的值。例如:int a5 = 7, 9, 6, 3, 4;sum(a0, 6);或sum(a0*a1, a2

36、+a3);等都是合法的调用。需要注意的是:实参与形参的个数应相等,类型应一致,且按顺序对应,一一传递数据。C+中,调用一个函数的方式可以有很多,例如:sum(3, 4); / Aint c = 2 * sum(4,5); / Bc = sum(c, sum(c,4); / C其中,A是将函数作为一个语句,不使用返回值,只要求函数完成一定的操作;B把函数作为表达式的一部分,将返回值参与运算,结果c = 18;C是将函数作为函数的实参,等价于“c = sum(18, sum(18,4);”,执行sum(18,4)后,等价于“c = sum(18,22) ;”,最后结果为c = 40。,2.5函数和

37、预处理,2.5.2函数的参数传递 函数的参数传递有两种方式,一种是按值传递,另一种是地址传递或引用传递。 例Ex_SwapValue 交换函数两个参数的值。#include void swap(float x, float y) float temp;temp = x; x = y; y = temp;cout“x = “x“, y = “y“n“;void main() float a = 20, b = 40;cout“a = “a“, b = “b“n“;swap(a, b);cout“a = “a“, b = “b“n“;运行结果为:a = 20, b = 40x = 40, y =

38、20a = 20, b = 40值传递的最大好处是保持函数的独立性。在值传递的情况下,函数只有通过return来返回某个类型的值。,2.5函数和预处理,2.5.3作用域和存储类型 作用域 (1) 块作用域在块中声明的标识符,作用域从声明处开始,一直到结束块的花括号为止。具有块作用域的标识符称作局部标识符,块作用域也称作局部作用域 标识符的作用域完全相同时,不允许出现相同的标识符名。标识符具有不同的作用域时,允许标识符同名。 在for语句中声明的标识符,其作用域是包含for语句的那个内层块,而不是仅仅作用于for语句。 (2) 函数原型作用域在声明函数原型所指定的参数标识符的作用范围。这个作用范

39、围是在函数原型声明中的左、右括号之间。在函数原型中声明的标识符可以与函数定义中说明的标识符名称不同。由于所声明的标识符与该函数的定义及调用无关,所以可以在函数原型声明中只作参数的类型声明,而省略参数名。(3) 函数作用域C+语言中,只有goto语句中的标号标识符具有函数作用域。具有函数作用域的标识符在声明它的函数内随处可见,但在此函数之外不可见。goto语句的滥用导致程序流程无规则、可读性差。,2.5函数和预处理,(4) 文件作用域在函数外定义的标识符或用extern说明的标识符称为全局标识符。全局标识符的作用域称为文件作用域,它从声明之处开始,直到文件结束一直是可见的。在同一个作用域中,不能

40、对同名的标识符作多种不同的声明。当块作用域内的标识符与全局标识符同名时,局部标识符优先,且在块作用域内使用作用域运算符“:”来引用与局部标识符同名的全局标识符。这一点与块作用域不同,例如:例Ex_Process 在块作用内引用文件作用域的同名变量。#include int i = 10;void main() int i = 5, j;:i = :i + 4;j = :i + i;cout“:i = “:i“, j = “j“n“;cout“:i = “i“n“;运行结果为::i = 14, j = 19:i = 14,2.5函数和预处理,变量的存储类型 存储类型的声明格式: ; (1) 自动

41、类型(auto)一般说,自动存储类型声明的变量都是限制在某个程序范围内使用的。从系统角度来说,自动存储类型变量是采用堆栈方式分配内存空间。程序执行到超出该变量的作用域时,就释放它所占用的内存空间,其值也随之消失了。声明一个自动存储类型的变量是在变量类型前面加上关键字auto若自动存储类型的变量是在函数内或语句块中声明,可省略auto,(2) 静态类型(static)它和自动存储类型的变量的最大不同之处在于:静态类型变量在内存中是以固定地址存放的,而不是以堆栈方式存放的。只要程序还在继续执行,静态类型变量的值就一直有效,不会随它所在的函数或语句块的结束而消失。 静态类型的变量均有确定的初值,当声

42、明变量时没有指定其初值,则编译器将其初值置为0。 在程序中声明的全局变量总是静态存储类型,若在全局变量前加一个static,使该变量只在这个源程序文件内使用,称之为全局静态变量或静态全局变量。 静态函数也是在某个函数声明前加上static,它的目的也是使该函数只在声明的源文件中使用,对于其他源文件则无效。,2.5函数和预处理,(3) 寄存器类型(register)使用关键字register声明寄存器类型的变量的目的是将所声明的变量放入寄存器内,从而加快程序的运行速度。但有时,在使用这种声明时,若系统寄存器已经被其他数据占据时,寄存器类型的变量就会自动当作auto变量。(4) 外部类型(exte

43、rn)用关键字extern声明的变量称为外部变量。某个变量被声明成外部变量时,不必再次为它分配内存就可以在本程序中引用这个变量。只有在两种情况下要使用外部变量:第一种情况,在同一个源文件中,若定义的变量使用在前,声明在后,这时在使用前要声明为外部变量。 第二种情况,当由多个文件组成一个完整的程序时,在一个源程序文件中完全定义的变量要被其他若干个源文件引用时,引用的文件中要使用extern声明外部变量。,2.5函数和预处理,例Ex_ Extern2 不在同一个源文件中的外部变量使用。/ Ex_Extern2.cpp文件内容#include int n;void f();void main() n

44、 = 20;coutextern int n; / 外部变量声明,它在另一个文件中定义void f() n+;cout“n = “n“n“;项目Ex_StaticScope经运行后,结果如下:n = 20n = 21,2.5函数和预处理,2.5.4带默认形参值的函数 在设置函数的默认参数值时要注意:(1) 当函数既有声明又有定义后,不能在函数定义中指定默认参数。(2) 当一个函数中有多个默认参数时,则形参分布中,默认参数应从右到左逐渐定义。在函数调用时,系统按从左到右的顺序将实参与形参结合,当实参的数目不足时,系统将按同样的顺序用声明或定义中的默认值来补齐所缺少的参数。 (3)默认参数值可以是

45、全局变量、全局常量,甚至是一个函数。但不可以是局部变量,因为默认参数的函数调用是在编译时确定的,而局部变量的值在编译时无法确定。例如:int a = 1;int f1(int);int g1(int x = fun(a); / 正确,允许默认参数值为函数void f2() int i;void g2(int x = i); / 错误,处理g2()函数时,i不可见,2.5函数和预处理,2.5.5函数的递归调用 例Ex_Factorial 编程n的阶乘n!。n!=n*(n-1)*(n-2)*.*2*1;它一般也可用下式表示: #include long factorial(int n);void

46、main() coutfactorial(4)endl; / 结果为24long factorial(int n) long result = 0;if (n = 0) result = 1;elseresult = n*factorial(n-1);return result;,2.5函数和预处理,在函数factorial中,当n不等于0时,又调用了该函数本身。下面来分析此函数的执行过程: (1)因n = 4,不等于0,故执行“result = 4*factorial(3);”,函数返回的值为4*factorial(3),即factorial(4) = 4*factorial(3); (2)

47、调用“factorial(3);”, n = 3不等于0,执行“result=3*factorial(2);”,函数返回的值为3*factorial(2) ,即factorial(3) =3*factorial(2); (3)调用“factorial(2);”, n = 2不等于0,执行“result=2*factorial(1);”, 函数返回的值为2*factorial(1) ,即factorial(2) =2*factorial(1); (4)调用“factorial(1);”,n = 1不等于0,执行“result=1*factorial(0);”, 函数返回的值为1*factoria

48、l(0) ,即factorial(1) =1*factorial(0); (5)调用“factorial(0);”,n等于0,结果函数返回的值为1。,2.5函数和预处理,2.5.6内联函数 例Ex_Inline 用内联函数实现求两个浮点数的最大值。#include inline float fmax(float x, float y) return xy?x:y; void main() float a, b;coutab;cout“最大的数为:“fmax(a,b)“n“; 使用内联函数时,还需要注意的是: (1) 内联函数也要遵循定义在前,调用在后的原则。 (2) 需要定义成的内联函数不能含

49、有循环、switch和复杂嵌套的if语句。 (3) 递归函数是不能被用来做内联函数的。 (4) 编译器是否将定义成的内联函数作为真正的内联函数处理,由编译器自行决定。,2.5函数和预处理,2.5.7函数的重载 函数重载是指C+允许多个同名的函数存在,但同名的各个函数的形参必须有区别:形参的个数不同,或者形参的个数相同,但参数类型有所不同。需要说明的是:(1) 重载函数必须具有不同的参数个数或不同的参数类型,若只有返回值的类型不同是不行的。(2) 当函数的重载带有默认参数时,应该注意避免二义性。例如:int fun(int a, int b = 0);int fun(int a);是错误的。因为如果有函数调用fun(2)时,编译器无法准确地确定应调用哪个函数。,

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

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报