C++面向对象实用教程.ppt_第1页
C++面向对象实用教程.ppt_第2页
C++面向对象实用教程.ppt_第3页
C++面向对象实用教程.ppt_第4页
C++面向对象实用教程.ppt_第5页
已阅读5页,还剩378页未读 继续免费阅读

下载本文档

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

文档简介

1、第一章C+基础,1.1从C到C+,1.2C+程序创建,1.3C+程序结构,1.4C+简单程序设计,1.1 从C到C+,本书以C+标准第二版(ISO/IEC 14882:2003)为基础,但仍称之为ANSI/ISO C+。,总之,从1983年AT/ 定义变量 6coutr;/ 从键盘上输入变量r的值 8area = 3.14159 * r * r;/ 计算面积 9cout圆的面积为:arean; / 输出面积 10return 0;/ 指定返回值 11,1.2 C+程序创建,(2) 选择“文件”“保存”菜单或按快捷键Ctrl+S或单击标准工具栏的“”按钮,弹出“保存为”文件对话框。将文件定位到“

2、D:C+程序第1章”文件夹中,文件名指定为“Ex_Simple.cpp”(注意扩展名.cpp不能省略,cpp是C Plus Plus的缩写,即“C+”的意思)。 此时在文档窗口中所有代码的颜色都发生改变,这是Visual C+ 6.0的文本编辑器所具有的语法颜色功能,绿色表示注释,蓝色表示关键词等。 4. 编译和运行 (1) 单击编译工具条 上的生成工具按钮“ ”或直接按快捷键F7,系统弹出一个对话框,询问是否为该程序创建默认的活动工作区间文件夹,单击是按钮,系统开始对Ex_Simple进行编译、连接,同时在输出窗口中显示编连的有关信息,当出现: 表示Ex_Simple.exe可执行文件已经正

3、确无误地生成了。 (2) 单击编译工具条 上的运行工具按钮“ ”或直接按快捷键Ctrl+F5,就可以运行刚刚生成的Ex_Simple.exe了,结果弹出这样的控制台窗口(其属性已被修改过):,1.2 C+程序创建,此时等待用户输入一个数。当输入10并按Enter键后,控制台窗口显示为:,其中,“Press any key to continue”是Visual C+自动加上去的,表示Ex_Simple运行后,按一个任意键将返回到Visual C+开发环境,这就是C+程序的创建、编连和运行过程。,在以后的C+程序运行结果中,本书不再完整显示其控制台窗口,也不再显示“Press any key t

4、o continue”,仅将控制台窗口中运行结果部分裁剪下来列出,并加以单线阴影边框,本书作此约定。,1.3 C+程序结构,代码中,main表示主函数,由于每一个程序执行时都必须从main开始,而不管该函数在整个程序中的具体位置,因此每一个C+程序或由多个源文件组成的C+项目都必须包含一个且只有一个main函数。 在main函数代码中,“int main()”称为main函数的函数头,函数头下面是用一对花括号“”和“”括起来的部分,称为main函数的函数体,函数体中包括若干条语句(按书写次序依次顺序执行),每一条语句都由分号“;”结束。由于main函数名的前面有一个int,它表示main函数的

5、类型是整型,须在函数体中使用关键字return,用来将其后面的值作为函数的返回值。由于return语句运行后,函数体return后面的语句不再被执行,因此除非想要函数提前结束,否则return语句应写在函数体的最后。 main函数体的第1条(行号为5)语句是用来定义两个双精度实型(double)变量r和area,第2条(行号为6)语句是一条输出语句,它将双引号中的内容(即字符串)输出到屏幕上,cout表示标准输出流对象(屏幕),“”是提取符,用来将用户键入的内容保存到后面的变量r中;最后一条(行号为9)语句是采用多个“”将字符串和变量area的内容输出到屏幕中,后面的“n”是换行符,即在内容输

6、出后回车换行。,1.3.1main函数,1.3.2 头文件包含,行号为2的代码是C+文件包含#include的编译指令,称为预处理指令。#include后面的iostream.h是C+编译器自带的文件,称为C+库文件,它定义了标准输入/输出流的相关数据及其操作。由于程序用到了输入/输出流对象cin和cout,因而需要用#include将其实现合并到程序中。又由于它们总是被放置在源程序文件的起始处,所以这些文件被称为头文件(Header File)。C+编译器自带了许多这样的头文件,每个头文件都支持一组特定的“工具”,用于实现基本输入输出、数值计算、字符串处理等方面的操作。 在C+中,头文件包含

7、有两种格式。一是将文件名用尖括号“”括起来,用来包含那些由编译系统提供的并放在指定子文件夹中的头文件,这称为标准方式。二是将文件名用双引号括起来的方式,称为用户方式。这种方式下,系统先在用户当前工作文件夹中查找要包含的文件,若找不到再按标准方式查找(即再按尖括号的方式查找)。所以,一般来说,用尖括号的方式来包含编译器自带的头文件,以节省查找时间;而用双引号来包含用户自己编写的头文件。,1.3.3 新头文件格式和名称空间,C语言头文件以“.h”为扩展名,iostream.h是C语言的头文件格式的C+头文件。尽管ANSI/ISO C+仍支持这种头文件格式,但已不建议再采用,而是使用没有.h这个扩展

8、名C+头文件。例如: #include 但为了使iostream中的定义对程序有效,还需使用下面名称空间编译指令来指定: using namespace std;/ 注意不要漏掉后面的分号 using是一个在代码编译之前处理的指令。namespace称为名称空间,它是ANSI/ISO C+一个新的特性,用于解决在程序中同名标识存在的潜在的危机。 又由于iostream是ANSI/ISO C+标准组件库,它所定义的类、函数和变量均放入名称空间std中,因此需要在程序文件的开始位置处指定“using namespace std;”,以便能被后面的程序所使用。,1.3.3 新头文件格式和名称空间,第

9、1种方式是在使用前用下列代码来指定: using std:cout;/ 指定以后的程序中可以使用cout对象 using std:cin; / 指定以后的程序中可以使用cin对象 第2种方式是在调用时指定它所属的名称空间,即如下述格式来使用: std:coutr; 显然,用下列两句代码来替代C语言风格的头文件包含#include 是一种最为简捷的做法,这也是本书所采用的方法: #include using namespace std;,事实上,cin和cout就是std中已定义的流对象,若不使用“using namespace std;”,则还可有下列2种方式来指定。,1.3.4 注释,通常,

10、必要的注释内容应包含: 在源文件头部进行必要的源程序的总体注释:版权说明、版本号、生成日期、作者、内容、功能、与其它文件的关系、修改日志等,头文件的注释中还应有函数功能简要说明。 在函数的头部进行必要的函数注释:函数的目的/功能、输入参数、输出参数、返回值、调用关系(函数、表)等。 其他的少量注释。如全局变量的功能、取值范围等。千万不要陈述那些一目了然的内容,否则会使注释的效果适得其反。 需要说明的是,C+中的“/*.*/”是用来实现多行的注释,它是将由“/*”开头到“*/”结尾之间所有内容均视为注释,称为块注释。块注释(“/*.*/”)的注解方式可以出现在程序中的任何位置,包括在语句或表达式

11、之间。而“/”只能实现单行的注释,它是将“/”开始一直到行尾的内容作为注释,称为行注释。,1.4 C+简单程序设计,和C语言一样,C+的数据包括常量和变量两类,其类型也分为基本类型、派生类型以及复合类型三类。 C/C+的基本数据类型有字符型(char)、整型(int)和浮点型(float、double)三种。这些基本数据类型还可用short、long、signed和unsigned来修饰。表1.1列出C+中的基本数据类型,其字宽(以字节数为单位)和取值范围是在Visual C+ 6.0时的情况。,1.4.1数据和数据类型,1. 基本数据类型,1.4.1 数据和数据类型,表1.1 C+的基本数据

12、类型,注:表中int表示可以省略,即在int之前有signed、unsigned、short、long时,可以省略int关键字。,1.4.1 数据和数据类型,需要注意的是: (1) C+还可以有布尔型(bool),即值为true或false,事实上,在计算机内,编译系统将true表示成整数1,false表示成整数0,因此也可把布尔型看成是一个整型。 (2) 无符号(unsigned)和有符号(signed)的区别在于数值最高位的含义。对于signed类型来说,最高位是符号位,其余各位表示数值大小;而unsigned类型的各个位都用来表示数值大小;因此相同基本数据类型的signed和unsign

13、ed的数值范围是不同。例如,无符号字符型值的范围为0255,而有符号字符型值的范围为 -128 -127。 (3) char、short、int和long可统称为整型。默认时,char、short、int和long本身是有符号(signed)的。 2. 常量 在程序运行过程中,其值不能被改变的量称为常量。常量可分为不同的类型,如1、20、0、-6为整型常量,1.2、-3.5为浮点型常量,a、b为字符常量,“123”为字符串常量。常量一般从其字面形式即可判别。需要说明的是: (1) 转义字符 C/C+还可以用一个“”开头的字符来表示特殊含义的字符常量。例如前例中n,代表一个换行符,而不是表示字母

14、n。这种将反斜杠()后面的字符转换成另外意义的方法称为转义表示法,n称为转义字符。表1.2列出了常用的转义字符。,1.4.1 数据和数据类型,表1.2 常用转义字符,表1.2中,ooo和xhh都是用ASCII码表示一个字符,例如101和x41都是表示字符A。,1.4.1 数据和数据类型,变量是指在程序执行中其值可以改变的量。变量有三个基本要素:C+合法的变量名、变量类型和变量的数值。需要说明的是: (1) 命名规则 C+规定标识符由大小写字母、数字字符(09)和下划线组成,且第一个字符必须为字母或下划线。任何标识符中都不能有空格、标点符号、运算符及其他非法字符。标识符的大小写是有区别的,并且不

15、能和系统的关键字同名,以下是常用的C+标准关键字(C语言本身有32个,斜体为C+新增的):,asm auto bool break casecatch char class constcontinue defaultdelete do double elseenum externfloat for frient gotoif inlineint long mutable namespace new operatorprivate protected public registerreturn shortsigned sizeof static structswitch templatethis

16、 throw try typedefunion unsignedusing virtual void volatilewhile,1.4.1 数据和数据类型,(2) 变量定义的位置 与C语言相比,C+变量的定义比较自由。C+变量满足即用即定义的编程习惯,即变量定义得的位置可以不固定。但一定要遵循“先定义后使用”的原则。 (3) 变量的初始化 程序中常需要对一些变量预先设置初值,这一过程称为初始化。在C/C+中,可以在定义变量时同时使变量初始化。例如: double x = 1.28;/ 指定x为双精度浮点变量,初值为1.28 int nNum1, nNum2 = 3, nNum3;/ 指定某一

17、个变量的初值 C+变量的初始化还有另外一种形式,它与C语言不同。例如: int nX(1), nY(3); 表示nX和nY是整型变量,它们的初值分别为1和3。 4. 符号常量 同变量相似,标识符常量在使用前同样需要先作声明。在C+中,标识符常量可以有const修饰的只读变量、#define定义的常量及enum类型的枚举常量等三种形式。 (1) const只读变量 在变量定义时,可以使用关键字const来修饰,这样的变量是只读的,即在程序中对其只能读取不能修改。由于不可修改,因而它是一个标识符常量,且在定义时必须初始化。需要说明的是,通常将标识符常量中的标识符写成大写字母以与其他标识符相区别。例

18、如: const float PI = 3.14159265f;/ 指定f使其类型相同,否则会有警告错误,1.4.1 数据和数据类型,因字符不能作为C+的标识符,因此这里用PI来表示。PI被定义成一个float类型的只读变量,由于float变量只能存储7位有效位精度的实数,因此PI的实际值为3.141592。 若将PI定义成double,则全部接受上述数字。事实上,const还可放在类型名之后,如下列语句: double const PI = 3.14159265; 这样,就可在程序中使用PI这个标识符常量来代替3.14159265。例如: 例Ex_PI 标识符常量:const修饰的只读变量

19、#include using namespace std; const double PI = 3.14159265;/ PI是一个只读变量 int main() double r = 100.0, area; area = PI * r * r;/ 引用PI cout圆的面积是:area n; return 0;/ 指定返回值 ,1.4.1 数据和数据类型,程序运行的结果如下: 由于const标识符常量的值不能修改,因此下列语句是错误的: const float PI;/ 此时PI的值无法确定 PI = 3.14159265;/ 错误:只读变量不能放在赋值运算符的左边 (2) #define

20、标识符常量 在C+中,为了保持与C语言的兼容,允许程序用编译预处理指令#define来定义一个标识符常量。例如: #define PI 3.14159265 这条指令的格式是#define后面跟一个标识符再跟一串字符,中间用空格隔开。由于它不是C+语句,因此行尾没有分号。 在程序编译时,编译器首先将程序中的PI用3.14159265来替换,然后再进行代码编译,故将#define称为编译预处理指令。 显然,#define定义的常量不是真正的标识符常量,因为在编译预处理完成后,标识符PI的生命期也就结束了,不再属于程序中的元素名称。而且,标识符后面的内容实际上是一个字符串,编译器本身不会对其进行任

21、何语法检查,仅仅是用来在程序中作与标识符的简单替换。例如,若有: #define PI 3.141MNP+59 虽是一个合法的定义,但它此时已经失去了一个标识符常量的作用。正因为如此,在C+编程中,标识符常量都是用const来定义,而不使用#define。,1.4.1 数据和数据类型,(3) 枚举常量 枚举常量是在由关键字enum指定的枚举类型中定义的。枚举类型是属于构造类型,它是一系列的有标识符的整型常量的集合,因此枚举常量实质上是整型标识符常量。 定义时,先写关键字enum,然后是要定义的枚举类型名、一对花括号(),最后以分号结尾。enum和类型名之间至少要有一个空格,花括号里面是指定的各

22、个枚举常量名,各枚举常量名之间要用逗号分隔。即如下列格式: enum ; 例如: enum COLORS Black, Red, Green, Blue, White ; 当然,这些枚举常量默认的值可单独重新指定,也可部分指定,例如: enum COLORS Black = 5, Red, Green = 3, Blue, White = 7 ; 由于Red没有赋值,则其值自动为前一个枚举常量值增1,即为6。同样,Blue为4,这样各枚举常量的值依次为5,6,3,4,7。以后就可直接使用这些枚举常量了,显然,用enum一次可以定义多个标识符常量,不像const和#define每次只能定义一个。

23、例如,若在程序中使用TRUE表示true,FALSE表示false,则可定义为: enum FALSE, TRUE ;/ 或enum TRUE = true, FALSE = false ;,1.4.2 数据的基本输入输出,在C+中,输入输出操作是由“流”来处理的。所谓流,它是C+的一个核心概念,数据从一个位置到另一个位置的流动抽象为“流”。当数据从键盘流入到程序中时,这样的流称为输入流,而当数据从程序中流向屏幕或磁盘文件时,这样的流称为输出流。当流被建立后就可以使用一些特定的操作从流中获取数据或向流中添加数据。从流中获取数据的操作称为“提取”操作,向流中添加数据的操作称为“插入”操作。 为了

24、方便用户对基本输入输出流进行操作,C+提供了四个标准流对象:cin、cout、cerr和clog,它们都是在库文件iostream中预定义,使用时要在程序中添加其头文件包含指令。其中,cin用来处理标准输入,即键盘输入。cout用来处理标准输出,即屏幕输出。cerr和clog都是用来处理标准出错信息,并将信息显示在屏幕上。 通过使用提取运算符“”和插入运算符“ .;,1.4.2 数据的基本输入输出,其中,提取运算符“”可以连续写多个,每个提取运算符后面跟一个获得输入值的变量或对象。例如: int nNum1, nNum2, nNum3; cinnNum1nNum2nNum3; 要求用户从键盘上

25、输入三个整数。输入时,必须在3个数值之间加上一些空格来分隔,空格的个数不限,最后用回车键结束输入;或者在每个数值之后按回车键。例如,上述输入语句执行时,用户可以输入: 12 9 20 或 12 9 20 此后变量nNum1、nNum2和nNum3的值分别为12、9和20。 需要说明的是,提取运算符“”能自动将cin输入值转换成相应变量的数据类型。如: charc; int i; float f; longl; cin c i f l; 上述语句运行后,若输入: 1 2 9 20,1.4.2 数据的基本输入输出,则变量c等于字符1,i等于2,f等于9.0f,l等于20L。注意,输入字符时,不能像

26、字符常量那样输入1,而是直接输入字符,否则不会有正确的结果。例如,当输入: 1 2 9 20 由于c是字符型变量,占一个字节,故无论输入的字符后面是否有空格,c总是等于输入的第1个字符,即为一个单引号。此后,i就等于“1”,由于i需要输入的是一个整数,而此时的输入值有一个单引号,因而产生错误,但单引号前面有一个“1”,于是C+就将1提取给i,故i的值为1。一旦产生错误,输入语句运行中断,后面的输入就变为无效,因此f和l都不会有正确的值。,注意:从键盘输入数据的个数、数据类型及顺序,必须与cin中列举的变量一一匹配。,与cin相对应,通过cout可以输出一个整数、实数、字符及字符串,如下列格式:

27、,2. 输出流(cout),cout .;,1.4.2 数据的基本输入输出,cout中的插入运算符“ using namespace std; int main() coutABCDt1234tendl; return 0; 执行该程序,结果如下: 程序中,转义字符“t”是制表符,endl是C+中控制输出流的一个操作算子(预定义的对象),它的作用和n等价,都是结束当前行,并将屏幕输出的光标移至下一行。,在外观上,提取运算符“”和插入运算符“a”格式;而将数据流入到cout时,则流的方向一定指向cout,即如“cout”格式。,1.4.2 数据的基本输入输出,格式算子oct、dec和hex能分别

28、将输入或输出的整数转换成八进制、十进制及十六进制。例如: 例Ex_ODH 格式算子的使用 #include using namespace std; int main() int nNum; couthexnNum; coutOcttoctnNumendl; coutDectdecnNumendl; coutHexthexnNumendl; return 0; 程序运行的结果如下:,3. 使用格式算子oct、dec和hex,1.4.3 运算符和表达式,算术运算符包括双目的加减乘除四则运算符、求余运算符以及单目的正负运算符。C+中没有幂运算符,幂运算符是通过函数来实现的。算术运算符如下所示: +

29、(正号运算符,如+4,+1.23等) -(负号运算符,如-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等) C+中算术运算符和数学运算的概念及运算方法是一致的,但要注意以下几点: (1) 两个整数相除,结果为整数,如7/5的结果为1,它是将保留整数部分,而不是四舍五入;若除数和被除数中有一个是浮点数,则进行浮点数除法,结果是浮点型。如7/5.0、7.0/5、7.0/5.0的结果都是1.4。

30、(2) 求余运算要求参与运算的两个操作数都是整型,其结果是两个数相除的余数。例如40%5的结果是0,40%11的结果是7。要理解负值的求余运算,例如40%-11结果是7,-40%11结果是-7,-40%-11结果也是-7。,1. 算术运算符,1.4.3 运算符和表达式,在C+语言中,赋值符“=”是一个双目运算符,结合性从右至左,其作用是将赋值符右边操作数的值赋给左边的操作数。每一个合法的表达式在求值后都有一个确定的值和类型。赋值表达式的值是赋值符右边操作数的值,赋值表达式的类型是赋值符右边操作数的类型。例如对浮点型变量fTemp的赋值表达式“fTemp = 18”完成后,该赋值表达式的类型是浮

31、点型,表达式的值经类型转换后变成18.0。下面将讨论复合赋值和多重赋值的问题。 (1) 复合赋值 在C/C+语言中,规定了10种复合赋值运算符: +=,-=,*=,/=,%=,(赋值表达式值为15,a值为15,c值为7,b值为8),2. 赋值运算符,1.4.3 运算符和表达式,关系运算是逻辑运算中比较简单的一种。所谓“关系运算”实际上是比较两个操作数是否符合给定的条件。若符合条件,则关系表达式的值为“真”,否则为“假”。在C+编译系统中,往往将“真”表示为“true”或1,将“假”表示为“false”或0。而非0的数被认为是“真”,0被认为是“假”。 由于关系运算需要两个操作数,所以关系运算符

32、都是双目运算符。 C+提供了下列6种关系运算符: (大于),=(大于等于),= =(相等于), ! =(不等于) 其中,前4种的优先级相同且高于后面的两种。例如: a = b c等效于a = ( b c ) 但关系运算符的优先级低于算术运算符。例如: a = b c等效于a = ( b c ) 4. 逻辑运算符 逻辑运算符用于将多个关系表达式或逻辑量(“真”或“假”)组成一个逻辑表达式。C+提供了下列3种逻辑运算符: !逻辑非(单目) 注意,只有在表达式2后面才能出现分号结束符,“表达式1”和“表达式2”中都不能有分号。 7. 增1和减1运算符 单目运算符增1(+)和减1(-)为整型变量加1或

33、减1提供一种非常有效的方法。+和-既可放在变量的左边也可以出现在变量的右边,分别称为前缀运算符和后缀运算符。例如: i+; 或 +i;(等效于i = i + 1; 或i += 1;) i-; 或 -i;(等效于i = i - 1; 或i -= 1;) 需要特别注意的是,若前缀运算符和后缀运算符仅用于某个变量的增1和减1,则这两个都是等价的,但如果将这两个运算符和其他运算符组合在一起,在求值次序上就会产生根本的不同: (1) 如果用前缀运算符对一个变量增1(减1),则在将该变量增1(减1)后,用新的值在表达式中进行其他的运算。 (2) 如果用后缀运算符对一个变量增1(减1),则用该变量的原值在表

34、达式进行其他的运算后,再将该变量增1(减1)。,6. 三目运算符,1.4.3 运算符和表达式,例如: a = 5; 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。 8. 逗号运算符 逗号运算符是优先级最低的运算符,它可以使多个表达式放在一行上,从而大大简化了程序。在计算时,C+将从左至右逐个计算每个表达式,最终整个表达式的结果是最后计算的那个表达式的类型和值。例如: j = ( i = 12 , i + 8

35、); 式中,i = 12 ,i + 8 是含逗号运算符的表达式,计算次序是先计算表达式i = 12,然后再计算i + 8,整个表达式的值是最后一个表达式的值,即i + 8的值20, 从而j的结果是20。 再如: d = (a = 1, b = a + 2; c = b + 3); d的结果为6。,1.4.3 运算符和表达式,9. sizeof运算符 sizeof的目的是返回操作数所占的内存空间大小(字节数),它具有下列两种格式: sizeof() sizeof() 例如: sizeof(“Hello”)/ 计算字符串常量“Hello”的实际长度(字符个数),结果为6 sizeof(int)/

36、计算整型int所占内存的字节数(在不同计算机中占用字节数可能不同),1.4.4 基本语句,C+提供了相应的语句如表达式语句、复合语句、选择语句和循环语句等,满足了结构化程序设计所需要的三种基本结构:顺序结构、选择结构和循环结构。 1. 表达式语句、空语句和复合语句 表达式语句、空语句及复合语句是一些系统顺序执行(操作)的语句,故又称为顺序语句。 表达式语句是最简单的语句,任何一个表达式加上分号就是一个表达式语句。例如: x+y; nNum=5; 如果表达式仅由分号“;”构成,即是一个空表达式,那么构成的语句称为空语句。空语句仅为语法的需要而设置,并不执行任何动作。 复合语句是由两条或两条以上的

37、语句组成的,并由一对花括号( )括起来的语句。它又称为块语句。复合语句中的语句可以是单条语句(包括空语句),也可以再包含复合语句。 需要注意的是,在复合语句中定义的变量只作用于该复合语句的范围,而在复合语句外,这些变量却不能被调用。,1.4.4 基本语句,选择结构是用来判断所给定的条件是否满足,并根据判定的结果(真或假)决定哪些语句被执行。C+中构成选择结构的语句有条件语句(if)和开关语句(switch)。 条件语句if具有下列形式: 这里的if、else是C+的关键字。当“表达式”为“真”(true)或不为0时,将执行语句1。当“表达式”为“假”(false或0)时,则执行语句2。 需要注

38、意的是: 条件语句中的表达式一般为逻辑表达式或关系表达式。当然,表达式的类型也可以是任意的数值类型(包括整型、浮点型、字符型等)。例如: if (3)coutThis is a number 3; 执行结果是输出“This is a number 3”。因为3是一个不为0的数,条件总为“真”。 适当添加一些花括号(“ ”)来增加程序的可读性。 条件语句中的语句1和语句2也可是if条件语句,这就形成了if语句的嵌套。 else总是和其前面最近的if配套的。,if () else ,1.4.4 基本语句,3. 开关语句 当程序有多个条件判断时,若使用if语句则可能使嵌套太多,降低了程序的可读性。开

39、关语句switch能很好地解决这种问题,它具有下列形式:,switch ( ) case :语句1 case :语句2 . case :语句n default :语句n+1 ,其中switch、case、default都是关键字,当表达式的值与case中某个表达式的值相等时,就执行该case中“:”号后面的所有语句。若case中所有表达式的值都不等于表达式的值,则执行default:后面的语句,若default不存在,则跳出switch 结构。 (1) 使用时要注意: switch后面的表达式可以是整型、字符型或枚举型的表达式,而case后面的常量表达式的类型必须与其匹配。,1.4.4 基本语

40、句,(2) 多个case可以共有一组执行语句,但不能在case后加多个常量,如: switch(.) case B: case b: cout) while是关键字,是此循环的循环体,它可以是一条语句,也可以是复合语句。当表达式为非0时便开始执行while循环体中的语句,然后反复执行,每次执行都会判断表达式是否为非0,若等于0,则终止循环。,1.4.4 基本语句,5. do.while循环语句 do.while循环语句具有下列形式: do while () ; 其中do和while都是C+关键字,是此循环的循环体,它可以是一条语句,也可以是复合语句。当语句执行到while时,将判断表达式是否为

41、非0值,若是,则继续执行循环体,直到下一次表达式等于0为止。 do.while循环语句至少执行一次循环体,而while循环语句可能一次都不会执行。 6. for循环语句 for循环语句具有下列形式: for (表达式1;表达式2;表达式3) 其中for是关键字,是此循环的循环体,它可以是一条语句,也可以是复合语句。一般情况下,表达式1用作循环变量的初始化,表达式2是循环体的判断条件,当等于非0时,开始执行循环体,然后计算表达式3,再判断表达式2的值是否为非0,若是,再执行循环体,再计算表达式3,如此反复,直到表达式2等于0为止。,1.4.4 基本语句,需要注意的是: (1) 表达式1、表达式2

42、、表达式3都可以省略,但分号“;”不能省略。若省略表达式1,不影响循环体的正确执行,但循环体中所需要的一些变量及其相关的数值要在for语句之前定义。若省略表达式2,则表达式2的值被认为是“真”, 循环无终止地进行下去,这时应在循环体中使用break语句。若省略表达式3,应在设计循环结构时保证表达式2的值有等于0的可能,以便能终止循环。例如下面的几种方式,其作用和结果都是一样的: 方式1:intnNum=1, nTotal=0; for ( ; nNum50) break; ,1.4.4 基本语句,(2) 表达式1和表达3可以是一个简单的表达式,也可以是逗号表达式,即包含两个或两个以上的简单表达

43、式,中间用逗号分隔。甚至还可以定义变量,例如: int nTotal = 0; for (int nNum=1; nNum=50 ; nNum+) nTotal += nNum; (3) 由于循环体是由任何类型的语句组成的,因此在循环体内还可以包含前面的几种循环语句,这样就形成了循环的嵌套。 以上是C+几种类型的循环语句,使用时可根据实际需要进行适当选择。但不管是怎样的循环结构,在编程时应保证循环有终止的可能。否则,程序将陷入死循环。 7. break、continue语句 在C+程序中,若需要跳出循环结构或重新开始循环,就得使用break和continue语句,其格式如下: break; c

44、ontinue; break语句既可以从一个循环体跳出,即提前终止循环,也可以跳出switch结构。 continue是用于那些依靠条件判断而进行循环的循环语句,如for、while语句。对于for语句来说,continue的目的是将流程转到for语句的表达2和表达式3。,1.4.4 基本语句,例Ex_Continue 把1100之间的不能被7整除的数输出 #include using namespace std; void main() for (int nNum=1; nNum=100; nNum+) if (nNum%7 = 0) continue; coutnNum ; coutn;

45、运行结果如下:,1.4.5 编译预处理,C+提供的预处理命令主要有3种:宏定义命令、文件包含命令、条件编译命令。这些命令在程序中都是以“#”来引导,每一条预处理命令必须单独占用一行;由于它不是C+的语句,因此在结尾没有分号“;”。 1. 宏定义 宏定义就是用一个指定的标识符来代替一个字符串,C+中宏定义是通过宏定义命令#define来实现的,它有2种形式:不带参数的宏定义和带参数的宏定义。 在前面的程序中,曾用#define定义一个标识符常量,如: #define PI 3.141593 其中,#define是宏定义命令,PI称为宏名。在程序编译时,编译器首先将程序中的PI用3.141593来

46、替换,然后再进行代码编译。需要注意的是: (1) #define、PI和3.141593之间一定要有空格,且一般将宏名定义成大写,以与普通标识符相区别。,1.4.5 编译预处理,(2) 宏后面的内容实际上是字符串,编译器本身不对其进行任何语法检查,仅仅是用来在程序中作与宏名的简单替换。例如,若有: #define PI 3.141ABC593 它是一个合法的宏定义。 (3) 宏被定义后,使用下列命令后可重新定义: #undef 宏名 (4) 一个定义过的宏名可以用来定义其它新的宏,但要注意其中的括号,例如: #define WIDTH 80 #define LENGTH ( WIDTH + 1

47、0 ) 宏LENGTH等价于: #define LENGTH ( 80 + 10 ) 但其中的括号不能省略,因为当 var = LENGTH * 20; 若宏LENGTH定义中有括号,则预处理后变成: var = ( 80 + 10 ) * 20; 若宏LENGTH定义中没有括号,则预处理后变成: var = 80 + 10 * 20; 显然,两者的结果是不一样的。,1.4.5 编译预处理,2. 带参数的宏定义 带参数的宏义命令的一般格式为: #define (参数名表) 字符串 例如: #defineMAX(a,b) (a)(b)?(a):(b) 其中(a,b)是宏MAX的参数表,如果在程序

48、出现下列语句: x = MAX(3, 9); 则预处理后变成: x = (3)(9)?(3):(9);/ 结果为9 很显然,带参数的宏相当于一个函数的功能,但却比函数简洁。但要注意: (1)定义有参宏时,宏名与左圆括号之间不能留有空格。否则,编译器将空格以后的所有字符均作为替代字符串,而将该宏视为无参数的宏定义。 (2)带参数的宏内容字符串中,参数一定要加圆括号,否则不会有正确的结果。例如: #defineAREA(r) (3.14159*r*r) 如果在程序出现下列语句: x = AREA(3+2); 则预处理后变成: x = (3.14159*3+2*3+2);/ 结果显然不等于3.141

49、59*5*5,1.4.5 编译预处理,3. 条件编译命令 一般情况下,源程序中所有的语句都参加编译,但有时也希望程序按一定的条件去编译源文件的不同部分,这就是条件编译。条件编译使得同一源程序在不同的编译条件下得到不同的目标代码。C+提供的条件编译命令有几种常用的形式,现分别介绍如下: 第一种形式 #ifdef #else #endif 其中,#ifdef、#else和#endif都是关键字,程序段是由若干条预处理命令或语句组成的。这种形式的含义是:如果标识符被#define命令定义过,则编译程序段1,否则编译程序段2。 例Ex_UseIfdef 使用#ifdef条件编译命令 #include

50、using namespace std; #define LI int main() #ifdef LI coutHello, LI!n; #else coutHello, everyone!n; #endif return 0;,1.4.5 编译预处理,程序的运行结果为: (2) 第二种形式 #ifndef #else #endif 这与前一种形式的区别仅在于,如果标识符没有被#define命令定义过,则编译程序段1,否则就编译程序段2。 (3) 第三种形式 #if #elif . #else #endif,1.4.5 编译预处理,其中,#if 、#elif、#else和#endif是关键字

51、。它的含义是,如果表达式1为true或不为0就编译程序段1,否则如果表达式2为true或不为0就编译程序段2,.,如果各表达式都不为true就编译程序段n。例如: 例Ex_UseIf 使用#if条件编译命令 #include using namespace std; #define A -1 int main() #ifA0 cout0n; #elif A0 couta0n; #else couta=0n; #endif return 0; ,1.4.5 编译预处理,程序的运行结果为: 若将#define A -1改为 #define A 0 则程序的运行结果为: 4. 文件包含命令 所谓文件

52、包含是指将另一个源文件的内容合并到源程序中。文件包含命令是很有用的,它可以节省程序设计人员的重复劳动。例如,在编程中,有时要经常使用一些符号常量(如PI=3.14159265, E=2.718),用户可以将这些宏定义命令组成一个文件,然后其他人都可以用#include命令将这些符号常量包含到自己所写的源文件中,避免了这些符号常量的再定义。 C+语言提供了#include命令用来实现文件包含的操作,它有下列两种格式: #include / 1 #include “文件名”/ 2,1.4.5 编译预处理,要注意: (1) 一条#include命令只能包含一个文件,若想包含多个文件须用多条包含命令一

53、一指定。例如: #include #include . (2) 在ANSI/ISO C+中,#include后面的文件名不再有.h扩展名,取而代之是直接使用文件名,如以前的程序中iostream是C+头文件的文件名。需要说明的是,为了能在C+使用C语言中的库函数,又能使用C+新的头文件包含格式,ANSI/ISO将有些C语言的头文件去掉.h,并在头文件前面加上“c”变成C+的头文件,如表1.3所示,实际上它们的内容是基本相同的。,表1.3 保留C语言库函数的常用ANSI/ISO C+头文件,1.4.5 编译预处理,文件重复包含在比较大的程序中经常出现。例如,设有a.h和b.h,其内容如图1.3所

54、示。,5. 文件重复包含处理,图1.3 头文件a.h和b.h内容,在主文件test.cpp中,其内容如下: #include #include a.h/ a.h文件包含 #include b.h/ b.h文件包含 using namespace std; int main() coutatbendl; return 0; ,1.4.5 编译预处理,则程序编译时会出现a重复定义编译错误。这是由于主文件test.cpp包含了头文件a.h和b.h,而b.h文件中又包含了头文件a.h,这样主文件包含进来的代码就是有两个“int a = 10;”语句,从而发生了编译错误。 解决上述问题的最通用的方法是将

55、头文件中的代码使用条件编译命令来限定。例如,对于a.h和b.h文件内容可改写为图1.4所示的代码。,C+中,头文件是不允许相互包含的。所谓相互包含是指a.h文件中包含了b.h,而b.h文件中又包含了a.h。,图1.4 改写头文件a.h和b.h内容,1.4.5 编译预处理,这样,当第一次包含a.h或b.h时,相应的宏名A_H或B_H被定义,而当第二次包含a.h或b.h时,因为文件宏名已定义,因而#ifndef和#endif的代码不会再包含进来,从而保证了每个头文件只包含一次。 以上是C+的最常用的预处理命令,它们都是在程序被正常编译之前执行的,而且它们可以根据需要放在程序的任何位置,但为了保证程

56、序结构的清晰性,提高程序的可读性,最好将它们放在程序的开头。,作为技巧,每个头文件所定义的宏名应与文件名相同,并将文件名中的点“.”用下划线代替,且宏名应大写以示区别。这样约定能避免两个不同文件的宏名相同后,其中一个头文件无法被打开。,第2章 函数和作用域,2.1函数定义和调用,2.2C+函数特性,2.3作用域和存储类型,2.4名称空间,2.5综合应用实例:Fibonacci数列,2.1 函数定义和调用,C+的任何一个程序都可由一个主函数和若干个子函数组合而成。主函数可以调用子函数,子函数还可以调用其他子函数。C+规定主函数名必须是main,而其他函数可以是库函数或自定义函数。 主函数main

57、不仅是程序的入口函数,而且与其他函数相比较还有许多使用上的限制。例如,它不能被其他函数调用,不能用inline和static来说明等。ANSI/ISO C+还规定主函数main的函数类型必须是int,以保证程序的移植性。 库函数,又称标准函数,是ANSI/ISO C+编译系统已经预先定义好的函数,程序设计时可根据实际需要,直接使用这类函数,而不必重新定义。调用时,必须在程序中包含相应的头文件,并指明使用名称空间std。 自定义函数是用户根据程序的需要,将某一个功能相对独立的程序定义成的一个函数,或将解决某个问题的算法用一个函数来组织。与变量的使用规则相同,在C+程序中一定要先说明和定义函数,然

58、后才能调用函数。 C+中每一个函数的定义都是由4个部分组成的,即函数名、函数类型、形式参数表和函数体,其定义的格式如下:,2.1.1函数定义,2.1.1 函数定义,其中,函数名应是一个合法有效的C+标识符;函数头的形式参数又简称为形参。参数表中的每一个形参都是由形参的数据类型和形参名来构成,形数个数可以是0,表示没有形式参数,但圆括号不能省略,也可以是1个或多个形参,但多个形参间要用逗号分隔。由花括号构成的是函数的函数体部分,它可以有若干条语句,用于实现这个函数执行的功能。 根据上述定义格式,可以编写一个函数sum,如图2.1所示,注意它们的书写规范。,图2.1 定义一个函数sum,2.1.1 函数定义,需要说明的是: (1) C/C+不允许在一个函数体中再定义函数,即禁止嵌套定义,但允许嵌套调用。 (2) 函数体也可不含有任何语句,这样的函数称为空函数,它仅为程序结构而设定,本身没有任何操作。 (3) 函数类型决定了函数所需要的返回值类型,它可以是除数组类型之外的任何有效的C+数据类型,包括引用、指针等。一旦指定了函数类型,则须在函数体中通过return语句来指定函数的返回值,且返回值的类型应与函数类型相同,若返回值的类型与函数类型不相同,则程序按类型自动转换方式转换成函数的类型或将ret

温馨提示

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

评论

0/150

提交评论