• 1. C++程序设计 授课:丁 伟 E-mail:nyxiaoyou@163.com QQ:80299295 TEL:13803779980 62232828(办)
  • 2. 总 目 录 第1篇 基 本 知 识 第1章 绪论 第2章 C++编程入门 第3篇 键盘输入和屏幕输出 第2篇 面向过程的程序设计 第4章 选择与循环 第5章 数组和结构体 第6章 字符串 第7章 函数 第3篇 基于对象的程序设计 第8章 对象和类 第9章 指针和动态内存分配 第10章 运算符重载 第4篇 面向对象的程序设计 第11章 继承 第12章 多态性 第13章 模板 第14章 文件和流
  • 3. Chapter One: Introduction(绪论)What is a computer program? (什么是计算机程序?) Developing a computer program(开发计算机程序) Learning C++(学习 C++) Web site for this book(本书的网站) Brief history of C++(C++简史) ANSI/ISO C++ standard(ANSI/ISO C++标准)
  • 4. 计算机诞生初期,人们要使用计算机必须用机器语言或汇编语言编写程序。世界上第一种计算机高级语言诞生于1954年,它是FORTRAN语言。先后出现了多种计算机高级语言。其中使用最广泛、影响最大的当推BASIC语言和C语言。 BASIC语言是1964年在FORTRAN语言的基础上简化而成的,它是为初学者设计的小型高级语言。 C语言是1972年由美国贝尔实验室的D.M.Ritchie研制成功的。它不是为初学者设计的,而是为计算机专业人员设计的。大多数系统软件和许多应用软件都是用C语言编写的。*1.1 从C到C++
  • 5. 但是随着软件规模的增大,用C语言编写程序渐渐显得有些吃力了。 C++是由AT&T Bell(贝尔)实验室的Bjarne Stroustrup博士及其同事于20世纪80年代初在C语言的基础上开发成功的。C++保留了C语言原有的所有优点,增加了面向对象的机制。 C++是由C发展而来的,与C兼容。用C语言写的程序基本上可以不加修改地用于C++。从C++的名字可以看出它是C的超集。C++既可用于面向过程的结构化程序设计,又可用于面向对象的程序设计,是一种功能强大的混合型的程序设计语言。
  • 6. C++对C的“增强”,表现在两个方面: (1) 在原来面向过程的机制基础上,对C语言的功能做了不少扩充。 (2) 增加了面向对象的机制。 面向对象程序设计,是针对开发较大规模的程序而提出来的,目的是提高软件开发的效率。
  • 7. 例1.1 输出一行字符: “This is a C++ program.”。 程序如下: #include //包含头文件iostream using namespace std; //使用命名空间std int main( ) { cout<<″This is a C++ program.″; return 0; } 在运行时会在屏幕上输出以下一行信息: This is a C++ program. *1.2 最简单的C++程序
  • 8. 用main代表“主函数”的名字。每一个C++程序都必须有一个 main 函数。main前面的int的作用是声明函数的类型为整型。程序第6行的作用是向操作系统返回一个零值。如果程序不能正常执行,则会自动向操作系统返回一个非零值,一般为-1。 函数体是由大括号{ }括起来的。本例中主函数内只有一个以cout开头的语句。注意C++所有语句最后都应当有一个分号。 再看程序的第1行“#include ”,这不是C++的语句,而是C++的一个预处理命令,它以“#”开头以与C++语句相区别,行的末尾没有分号。
  • 9. #include 是一个“包含命令”,它的作用是将文件iostream的内容包含到该命令所在的程序文件中,代替该命令行。文件iostream的作用是向程序提供输入或输出时所需要的一些信息。iostream是i-o-stream 3个词的组合,从它的形式就可以知道它代表“输入输出流”的意思,由于这类文件都放在程序单元的开头,所以称为“头文件”(head file)。在程序进行编译时,先对所有的预处理命令进行处理,将头文件的具体内容代替 #include命令行,然后再对该程序单元进行整体编译。
  • 10. 程序的第2行“using namespace std; ” 的意思是“使用命名空间std”。C++标准库中的类和函数是在命名空间std中声明的,因此程序中如果需要用到C++标准库(此时就需要用#include命令行),就需要用“using namespace std; ”作声明,表示要用到命名空间std中的内容。 在初学C++时,对本程序中的第1,2行可以不必深究,只需知道: 如果程序有输入或输出时,必须使用“#include ”命令以提供必要的信息,同时要用“using namespace std;” ,使程序能够使用这些信息,否则程序编译时将出错。
  • 11. 例1.2 求a和b两个数之和。 可以写出以下程序: // 求两数之和 (本行是注释行) #include //预处理命令 using namespace std; //使用命名空间std int main( ) //主函数首部 { //函数体开始 int a,b,sum; //定义变量 cin>>a>>b; //输入语句 sum=a+b; //赋值语句 cout<<″a+b=″<
  • 12. 本程序的作用是求两个整数a和b之和sum。第1行“//求两数之和”是一个注释行,C++规定在一行中如果出现“//”,则从它开始到本行末尾之间的全部内容都作为注释。 如果在运行时从键盘输入 123 456↙ 则输出为 a+b=579
  • 13. 例1.3 给两个数x和y,求两数中的大者。 在本例中包含两个函数。 #include //预处理命令 using namespace std; int max(int x,int y) //定义max函数,函数值为整型,形式参数x,y为整型 { //max函数体开始 int z; //变量声明,定义本函数中用到的变量z为整型 if(x>y) z=x; //if语句,如果x>y,则将x的值赋给z else z=y; //否则,将y的值赋给z return(z); //将z的值返回,通过max带回调用处 } //max函数结束 int main( ) //主函数
  • 14. { //主函数体开始 int a,b,m; //变量声明 cin>>a>>b; //输入变量a和b的值 m=max(a,b); //调用max函数,将得到的值赋给m cout<<″max=″<
  • 15. C++程序的结构和书写格式归纳如下: (1) 一个C++程序可以由一个程序单位或多个程序单位构成。每一个程序单位作为一个文件。在程序编译时,编译系统分别对各个文件进行编译,因此,一个文件是一个编译单元。 (2) 在一个程序单位中,可以包括以下几个部分: ① 预处理命令。上节4个程序中都包括#include命令。 ② 全局声明部分(在函数外的声明部分)。在这部分中包括对用户自己定义的数据类型的声明和程序中所用到的变量的定义。1.3 C++程序的构成和书写形式
  • 16. ③ 函数。函数是实现操作的部分,因此函数是程序中必须有的和最基本的组成部分。每一个程序必须包括一个或多个函数,其中必须有一个(而且只能有一个)主函数(main函数)。 但是并不要求每一个程序文件都必须具有以上3个部分,可以缺少某些部分(包括函数)。 (3) 一个函数由两部分组成: ① 函数首部,即函数的第一行。包括函数名、函数类型、函数属性、函数参数(形参)名、参数类型。 一个函数名后面必须跟一对圆括号, 函数参数可以缺省,如int main( )。
  • 17. ② 函数体,即函数首部下面的大括号内的部分。如果在一个函数中有多个大括号,则最外层的一对{ }为函数体的范围。 函数体一般包括: 局部声明部分 (在函数内的声明部分)。包括对本函数中所用到的类型、函数的声明和变量的定义。 对数据的声明既可以放在函数之外(其作用范围是全局的),也可以放在函数内(其作用范围是局部的,只在本函数内有效)。 执行部分。由若干个执行语句组成,用来进行有关的操作,以实现函数的功能。
  • 18. (4) 语句包括两类。一类是声明语句,另一类是执行语句。 C++对每一种语句赋予一种特定的功能。语句是实现操作的基本成分,显然,没有语句的函数是没有意义的。C++语句必须以分号结束。 (5) 一个C++程序总是从main函数开始执行的,而不论main函数在整个程序中的位置如何。 (6) 类(class)是C++新增加的重要的数据类型,是C++对C的最重要的发展。有了类,就可以实现面向对象程序设计方法中的封装、信息隐蔽、继承、派生、多态等功能。在一个类中可以包括数据成员和成员函数,他们可以被指定为私有的(private)和公用的(public)属性。私有的数据成员和成员函数只能被本类的成员函数所调用。
  • 19. (7)C++程序书写格式自由,一行内可以写几个语句, 一个语句可以分写在多行上。C++程序没有行号,也不像FORTRAN或COBOL那样严格规定书写格式(语句必须从某一列开始书写)。 (8) 一个好的、有使用价值的源程序都应当加上必要的注释,以增加程序的可读性。C++还保留了C语言的注释形式,可以用“/*……*/”对C++程序中的任何部分作注释。在“/*”和“*/”之间的全部内容作为注释。 用“//”作注释时,有效范围只有一行,即本行有效,不能跨行。而用“/*……*/”作注释时有效范围为多行。只要在开始处有一个“/*”,在最后一行结束处有一个“*/”即可。因此,一般习惯是: 内容较少的简单注释常用“//”,内容较长的常用“/*……*/ ”。
  • 20. 一个程序从编写到最后得到运行结果要经历以下一些步骤。 1. 用C++语言编写程序 用高级语言编写的程序称为“源程序”(source program)。C++的源程序是以.cpp作为后缀的(cpp是c plus plus 的缩写)。 2. 对源程序进行编译 为了使计算机能执行高级语言源程序,必须先用一种称为“编译器(complier)”的软件(也称编译程序或编译系统),把源程序翻译成二进制形式的“目标程序(object program)”。1.4 C++程序的编写和实现
  • 21. 编译是以源程序文件为单位分别编译的。目标程序一般以.obj或.o作为后缀(object 的缩写)。编译的作用是对源程序进行词法检查和语法检查。编译时对文件中的全部内容进行检查,编译结束后会显示出所有的编译出错信息。一般编译系统给出的出错信息分为两种,一种是错误(error);一种是警告(warning) 。 3. 将目标文件连接 在改正所有的错误并全部通过编译后,得到一个或多个目标文件。此时要用系统提供的“连接程序(linker)”将一个程序的所有目标程序和系统的库文件以及系统提供的其他信息连接起来,最终形成一个可执行的二进制文件,它的后缀是.exe,是可以直接执行的。
  • 22. 4. 运行程序 运行最终形成的可执行的二进制文件(.exe文件),得到运行结果。 5. 分析运行结果 如果运行结果不正确,应检查程序或算法是否有问题。
  • 23. 在了解了C++语言的初步知识后,读者最好尽快在计算机上编译和运行C++程序,以加深对C++程序的认识,并初步掌握C++的上机操作。 读者可以使用不同的C++编译系统,在不同的环境下编译和运行一个C++程序。 在本书的实验中Visual C++ 6.0和GCC两种典型的环境下运行C++程序的方法。 请大家选择一种(如能做到两种更好) C++编译系统,在该环境下输入和运行习题中的程序,掌握上机的方法和步骤。 (第一章结束) 1.5 关于C++上机实践
  • 24. Lecture 2: Beginning to Program in C++(C++编程入门)2.1 C++的数据类型 2.2 常量 2.3 变量 2.4 C++的运算符 2.5 算术运算符与算术表达式 2.6 赋值运算符与赋值表达式 2.7 逗号运算符与逗号表达式
  • 25. 计算机处理的对象是数据,而数据是以某种特定的形式存在的(例如整数、浮点数、字符等形式)。不同的数据之间往往还存在某些联系(例如由若干个整数组成一个整数数组)。数据结构指的是数据的组织形式。例如,数组就是一种数据结构。不同的计算机语言所允许使用的数据结构是不同的。处理同一类问题,如果数据结构不同,算法也会不同。例如,对10个整数排序和对包含10个元素的整型数组排序的算法是不同的。 C++可以使用的数据类型如下:2.1 C++的数据类型
  • 26. 数据类型 基本类型 整型 短整型(short int) 整型(int) 长整型(long int) 字符型(char) 浮点型 单精度型(float) 双精度型(double) 长双精度型(long double) 布尔型(bool) 构造类型 枚举类型(enum) 数组类型 结构体类型(struct) 共用体类型(union) 类类型(class) 指针类型 引用类型 空类型(void) 布尔型就是逻辑型,空类型就是无值型。
  • 27. C++的数据包括常量与变量,常量与变量都具有类型。由以上这些数据类型还可以构成更复杂的数据结构。例如利用指针和结构体类型可以构成表、树、栈等复杂的数据结构。 C++并没有统一规定各类数据的精度、数值范围和在内存中所占的字节数,各C++编译系统根据自己的情况作出安排。
  • 28. 常量的值是不能改变的,一般从其字面形式即可判别是否为常量。常量包括两大类,即数值型常量(即常数)和字符型常量。如12,0,-3为整型常量,4.6,-1.23为实型常量,包含在两个单撇号之间的字符为字符常量,如′a′,′x′。这种从字面形式即可识别的常量称为“字面常量”或“直接常量”。2.2 常量 2.2.1 什么是常量
  • 29. (1) 一个整数,如果其值在-32768~+32767范围内,认为它是short int型,它可以赋值给short int型、int型和long int型变量。 (2) 一个整数,如果其值超过了上述范围,而在-2147483648~+2147483647范围内,则认为它是long int型,可以将它赋值给一个int或long int型变量。 (3) 如果某一计算机系统的C++版本(例如Visual C++)确定int与long int型数据在内存中占据的长度相同,则它们能够表示的数值的范围相同。因此,一个int型的常量也同时是一个long int型常量,可以赋给int型或long int型变量。 (4) 常量无unsigned型。但一个非负值的整数可以赋值给unsigned整型变量,只要它的范围不超过变量的取值范围即可。
  • 30. 数值常量就是通常所说的常数。在C++中,数值常量是区分类型的,从字面形式即可识别其类型。 1. 整型常量(整数)的类型 在上一节中已知道: 整型数据可分为int,short int,long int以及unsigned int,unsigned short,unsigned long等类别。整型常量也分为以上类别。为什么将数值常量区分为不同的类别呢?因为在进行赋值或函数的参数虚实结合时要求数据类型匹配。 那么,一个整型常量怎样从字面上区分为以上的类别呢?2.2.2 数值常量
  • 31. 2. 浮点数的表示方法 一个浮点数可以用两种不同的方式表示: (1) 十进制小数形式。如21.456,-7.98等。它一般由整数部分和小数部分组成,可以省略其中之一(如78.或.06,.0),但不能二者皆省略。C++编译系统把用这种形式表示的浮点数一律按双精度常量处理,在内存中占8个字节。如果在实数的数字之后加字母F或f,表示此数为单精度浮点数,如1234F,-43f,占4个字节。如果加字母L或l,表示此数为长双精度数(long double),在GCC中占12个字节,在Visual C++ 6.0中占8个字节。
  • 32. (2) 指数形式(即浮点形式) 一个浮点数可以写成指数形式,如3.14159可以表示为0.314159×101,3.14159×100,31.4159×10-1, 314.159×10-2等形式。在程序中应表示为: 0.314159e1,3.14159e0,31.4159e-1 ,314.159e-2,用字母e表示其后的数是以10为底的幂,如e12表示1012。 其一般形式为 数符 数字部分 指数部分 上面各数据中的0.314159,3.14159, 31.4159, 314.159 等就是其中的数字部分。可以看到: 由于指数部分的存在,使得同一个浮点数可以用不同的指数形式来表示,数字部分中小数点的位置是浮动的。
  • 33. 1. 普通的字符常量 用单撇号括起来的一个字符就是字符型常量。如′a′,′#′,′%′,′D′都是合法的字符常量,在内存中占一个字节。注意: ①字符常量只能包括一个字符,如′AB′ 是不合法的。②字符常量区分大小写字母,如′A′和′a′是两个不同的字符常量。③撇号(′)是定界符,而不属于字符常量的一部分。如cout<<′a′;输出的是一个字母“a”,而不是3个字符“′a′ ”。2.2.3 字符常量
  • 34. 2. 转义字符常量 除了以上形式的字符常量外,C++还允许用一种特殊形式的字符常量,就是以 “\”开头的字符序列。例如,′\n′代表一个“换行”符。“cout<<′\n′; ” 将输出一个换行,其作用与“cout<
  • 35. 3. 字符数据在内存中的存储形式及其使用方法 将一个字符常量存放到内存单元时,实际上并不是把该字符本身放到内存单元中去,而是将该字符相应的ASCII代码放到存储单元中。如果字符变量c1的值为′a′,c2的值为′b′,则在变量中存放的是′a′的ASCII码97,′b′ 的ASCII码98,如图2.4(a)所示,实际上在内存中是以二进制形式存放的,如图2.4(b)所示。 图2.4
  • 36. 既然字符数据是以ASCII码存储的,它的存储形式就与整数的存储形式类似。这样,在C++中字符型数据和整型数据之间就可以通用。一个字符数据可以赋给一个整型变量,反之,一个整型数据也可以赋给一个字符变量。也可以对字符数据进行算术运算,此时相当于对它们的ASCII码进行算术运算。 例2.1 将字符赋给整型变量。(屏幕输入输出) #include using namespace std; int main( ) {int i,j; //i和j是整型变量 i=′A′; //将一个字符常量赋给整型变量i j=′B′; //将一个字符常量赋给整型变量j cout<
  • 37. 执行时输出 65 66 i和j被指定为整型变量。但在第5和第6行中,将字符′A′和′B′分别赋给i和j,它的作用相当于以下两个赋值语句: i=65;j=66; 因为′A′和′B′的ASCII码为65和66。在程序的第5和第6行是把65和66直接存放到i和j的内存单元中。因此输出65和66。 可以看到:在一定条件下,字符型数据和整型数据是可以通用的。但是应注意字符数据只占一个字节,它只能存放0~255范围内的整数。
  • 38. 例2.2 字符数据与整数进行算术运算。下面程序的作用是将小写字母转换为大写字母。 #include using namespace std; int main( ) {char c1,c2; c1=′a′; c2=′b′; c1=c1-32; c2=c2-32; cout<
  • 39. 运行结果为 A B ′a′的ASCII码为97,而′A′的ASCII码为65,′b′为98,′B′为66。从ASCII代码表中可以看到每一个小写字母比它相应的大写字母的ASCII代码大32。C++符数据与数值直接进行算术运算,′a′-32得到整数65,′b′-32得到整数66。将65和66存放在c1,c2中,由于c1,c2是字符变量,因此用cout输出c1,c2时,得到字符A和B(A的ASCII码为65,B的ASCII码为66)
  • 40. 4. 字符串常量 用双撇号括起来的部分就是字符串常量,如″abc″,″Hello!″,″a+b″,″Liping″都是字符串常量。字符串常量″abc″在内存中占4个字节(而不是3个字节),见图2.5。 图2.5 编译系统会在字符串最后自动加一个′\0′作为字符串结束标志。但′\0′并不是字符串的一部分,它只作为字符串的结束标志。如 cout<<″abc″<
  • 41. 为了编程和阅读的方便,在C++程序设计中,常用一个符号名代表一个常量,称为符号常量,即以标识符形式出现的常量。 例2.3 符号常量的使用。 #define PRICE 30 //注意这不是语句,末尾不要加分号 int main ( ) { int num,total; num=10; total=num * PRICE; cout<<″total=″<
  • 42. 程序中用预处理命令#define指定PRICE在本程序单位中代表常量30,此后凡在本程序单位中出现的PRICE都代表30,可以和常量一样进行运算,程序运行结果为 total=300 请注意符号常量虽然有名字,但它不是变量。它的值在其作用域(在本例中为主函数)内是不能改变的,也不能被赋值。如用赋值语句“PRICE=40;”给PRICE赋值是错误的。 使用符号常量的好处是: (1) 含义清楚。 (2) 在需要改变一个常量时能做到“一改全改”。 如 #define PRICE 35
  • 43. 其实在前面的例子中已经多次用到了变量。在程序运行期间其值可以改变的量称为变量。一个变量应该有一个名字,并在内存中占据一定的存储单元,在该存储单元中存放变量的值。请注意区分变量名和变量值这两个不同的概念,见图2.6。 图2.6 2.3 变量 2.3.1 什么是变量
  • 44. 先介绍标识符的概念。和其他高级语言一样,用来标识变量、符号常量、函数、数组、类型等实体名字的有效字符序列称为标识符(identifier)。简单地说,标识符就是一个名字。变量名是标识符的一种,变量的名字必须遵循标识符的命名规则。 C++规定标识符只能由字母、数字和下划线3种字符组成,且第一个字符必须为字母或下划线。下面列出的是合法的标识符,也是合法的变量名: sum, average, total, day, month, Student_name, tan, BASIC, li_ling 2.3.2 变量名规则
  • 45. 在C++语言中,要求对所有用到的变量作强制定义,也就是必须“先定义,后使用”,如例2.2和例2.3那样。定义变量的一般形式是 变量类型 变量名表列; 变量名表列指的是一个或多个变量名的序列。如 float a,b,c,d,e; 定义a,b,c,d,e为单精度型变量,注意各变量间以逗号分隔,最后是分号。 可以在定义变量时指定它的初值。如 float a=83.5,b,c=64.5,d=81.2,e; //对变量a,c,d指定了初值,b和d未指定初值2.3.3 定义变量
  • 46. C语言要求变量的定义应该放在所有的执行语句之前,而C++则放松了限制,只要求在第一次使用该变量之前进行定义即可。也就是说,它可以出现在语句的中间,如 int a; //定义变量a(在使用a之前定义) a=3; //执行语句,对a赋值 float b; //定义变量b(在使用b之前定义) b=4.67; //执行语句,对b赋值 char c; //定义变量c(在使用c之前定义) c=′A′; //执行语句 ,对c赋值 C++要求对变量作强制定义的目的是:
  • 47. (1) 凡未被事先定义的,不作为变量名,这就能保证程序中变量名使用得正确。例如,如果在声明部分写了 int student; 而在执行语句中错写成statent。如 statent=30; 在编译时检查出statent未经定义,作为错误处理。输出“变量statent未经声明”的信息,便于用户发现错误,避免变量名使用时出错。 (2) 每一个变量被指定为一确定类型,在编译时就能为其分配相应的存储单元。如指定a和b为int型,一般的编译系统对其各分配4个字节,并按整数方式存储数据。
  • 48. (3) 指定每一变量属于一个特定的类型,这就便于在编译时,据此检查该变量所进行的运算是否合法。例如,整型变量a和b,可以进行求余运算: a%b %是“求余”,得到a/b的余数。如果将a和b指定为实型变量,则不允许进行“求余”运算,在编译时会给出有关的出错信息。
  • 49. 允许在定义变量时对它赋予一个初值,这称为变量初始化。初值可以是常量,也可以是一个有确定值的表达式。如 float a,b=5.78*3.5,c=2*sin(2.0); 表示定义了a,b,c为单精度浮点型变量,对b初始化为5.78*3, 对c初始化为2*sin(2.0),在编译连接后,从标准函数库得到正弦函数sin(2.0)的值,因此变量c有确定的初值。变量a未初始化。 如果对变量未赋初值,则该变量的初值是一个不可预测的值,即该存储单元中当时的内容是不知道的。2.3.4 为变量赋初值
  • 50. 在定义变量时,如果加上关键字const,则变量的值在程序运行期间不能改变,这种变量称为常变量(constant variable)。例如, const int a=3; //用const来声明这种变量的值不能改变,指定其值始终为3 在定义常变量时必须同时对它初始化(即指定其值),此后它的值不能再改变。常变量不能出现在赋值号的左边。例如上面一行不能写成 const int a; a=3; //常变量不能被赋值2.3.5 常变量
  • 51. C++的运算符十分丰富,使得C++的运算十分灵活方便。例如把赋值号(=)也作为运算符处理,这样,a=b=c=4就是合法的表达式,这是与其他语言不同的。C++提供了以下运算符: (1) 算术运算符 +(加)-(减) *(乘) /(除) %(整除求余)++(自加) --(自减) (2) 关系运算符 >(大于)<(小于) ==(等于)>=(大于或等于)<=(小于或等于)!=(不等于)2.4 C++的运算符
  • 52. (3) 逻辑运算符 &&(逻辑与) ||(逻辑或) !(逻辑非) (4) 位运算符 <<(按位左移) >>(按位右移) &(按位与) |(按位或) ∧(按位异或) ~(按位取反) (5) 赋值运算符 (=及其扩展赋值运算符) (6) 条件运算符 (?:) (7) 逗号运算符 (,) (8) 指针运算符 (*) (9) 引用运算符和地址运算符 (&) (10) 求字节数运算符(sizeof) (11) 强制类型转换运算符( (类型) 或类型( ))
  • 53. (12) 成员运算符 (.) (13) 指向成员的运算符 (->) (14) 下标运算符 ([ ]) (15) 其他 (如函数调用运算符()) 在本章中主要介绍算术运算符与算术表达式,赋值运算符与赋值表达式,逗号运算符与逗号表达式,其他运算符将在以后各章中陆续介绍。
  • 54. +(加法运算符,或正值运算符。如3+5,+3) -(减法运算符,或负值运算符。如5-2,-3) * (乘法运算符。如3*5) /(除法运算符。如5/3) %(模运算符,或称求余运算符,%两侧均应为整型数据,如7%4的值为3)。2.5 算术运算符与算术表达式 2.5.1 基本的算术运算符
  • 55. 需要说明,两个整数相除的结果为整数,如5/3的结果值为1,舍去小数部分。但是,如果除数或被除数中有一个为负值,则舍入的方向是不固定的。例如,-5/3在有的C++系统上得到结果-1,有的C++系统则给出结果-2。多数编译系统采取“向零取整”的方法,即5/3的值等于1,-5/3的值等于-1,取整后向零靠拢。 如果参加+, -, *, / 运算的两个数中有一个数为float型数据,则运算的结果是double型,因为C++在运算时对所有float型数据都按double型数据处理。
  • 56. 用算术运算符和括号将运算对象(也称操作数)连接起来的、符合C++语法规则的式子,称C++算术表达式。运算对象包括常量、变量、函数等。例如,下面是一个合法的C++算术表达式: a*b/c-1.5+′a′ C++语言规定了运算符的优先级和结合性。在求解表达式时,先按运算符的优先级别高低次序执行,例如先乘除后加减。如有表达式a-b*c,b的左侧为减号,右侧为乘号,而乘号优先于减号,因此,相当于a-(b*c)。如果在一个运算对象两侧的运算符的优先级别相同,如a-b+c,则按规定的“结合方向”处理。2.5.2 算术表达式和运算符的优先级与结合性
  • 57. 在表达式中常遇到不同类型数据之间进行运算,如 10+′a′+1.5-8765.1234*′b′ 在进行运算时,不同类型的数据要先转换成同一类型,然后进行运算。转换的规则按图2.7所示。 图2.72.5.3 表达式中各类数值型数据间的混合运算
  • 58. 在C和C++中,常在表达式中使用自增(++)和自减(--)运算符,他们的作用是使变量的值增1或减1,如 ++i(在使用i之前,先使i的值加1,如果i的原值为3,则执行j=++i后,j的值为4) --i (在使用i之前,先使i的值减1,如果i的原值为3,则执行j=--i后,j的值为2) i++ (在使用i之后,使i的值加1,如果i的原值为3,则执行j=i++后,j的值为3,然后i变为4) i--(在使用i之后,使i的值减1,如果i的原值为3,则执行j=i--后,j的值为3,然后i变为2) ++i是先执行i=i+1后,再使用i的值;而i++是先使用i的值后,再执行i=i+1。2.5.4 自增和自减运算符
  • 59. 在表达式中不同类型的数据会自动地转换类型,以进行运算。有时程序编制者还可以利用强制类型转换运算符将一个表达式转换成所需类型。例如: (double)a (将a转换成double类型) (int)(x+y) (将x+y的值转换成整型) (float)(5%3) (将5%3的值转换成float型) 强制类型转换的一般形式为 (类型名)(表达式) 注意: 如果要进行强制类型转换的对象是一个变量,该变量可以不用括号括起来。如果要进行强制类型转换的对象是一个包含多项的表达式,则表达式应该用括号括起来。如果写成2.5.5 强制类型转换运算符
  • 60. (int)x+y 则只将x转换成整型,然后与y相加。 以上强制类型转换的形式是原来C语言使用的形式,C++把它保留了下来,以利于兼容。C++还增加了以下形式: 类型名(表达式) 如int(x) 或 int(x+y) 类型名不加括号,而变量或表达式用括号括起来。这种形式类似于函数调用。但许多人仍习惯于用第一种形式,把类型名包在括号内,这样比较清楚。 需要说明的是在强制类型转换时,得到一个所需类型的中间变量,但原来变量的类型未发生变化。例如:
  • 61. (int)x 如果x原指定为float型,值为3.6,进行强制类型运算后得到一个int型的中间变量,它的值等于3,而x原来的类型和值都不变。 例2.4 强制类型转换。 #include using namespace std; int main( ) { float x; int i; x=3.6; i=(int)x; cout<<″x=″<
  • 62. 运行结果如下: x=3.6,i=3 x的型仍为float型,值仍等于3.6。 由上可知,有两种类型转换,一种是在运算时不必用户指定,系统自动进行的类型转换,如3+6.5。第二种是强制类型转换。当自动类型转换不能实现目的时,可以用强制类型转换。此外,在函数调用时,有时为了使实参与形参类型一致,可以用强制类型转换运算符得到一个所需类型的参数。
  • 63. 赋值符号“=”就是赋值运算符,它的作用是将一个数据赋给一个变量。如“a=3”的作用是执行一次赋值操作(或称赋值运算)。把常量3赋给变量a。也可以将一个表达式的值赋给一个变量。2.6 赋值运算符与赋值表达式 2.6.1 赋值运算符
  • 64. 如果赋值运算符两侧的类型不一致,但都是数值型或字符型时,在赋值时会自动进行类型转换。 (1) 将浮点型数据(包括单、双精度)赋给整型变量时,舍弃其小数部分。 (2) 将整型数据赋给浮点型变量时,数值不变,但以指数形式存储到变量中。 (3) 将一个double型数据赋给float变量时,要注意数值范围不能溢出。 (4) 字符型数据赋给整型变量,将字符的ASCII码赋给整型变量。2.6.2 赋值过程中的类型转换
  • 65. (5) 将一个int、short或long型数据赋给一个char型变量,只将其低8位原封不动地送到char型变量(发生截断)。例如 short int i=289; char c; c=i; //将一个int型数据赋给一个char型变量 赋值情况见图2.8。为方便起见,以一个int型数据占两个字节(16位)的情况来说明。 图2.8
  • 66. (6) 将signed(有符号)型数据赋给长度相同的unsigned(无符号)型变量,将存储单元内容原样照搬(连原有的符号位也作为数值一起传送)。 例2.5 将有符号数据传送给无符号变量。 #include using namespace std; int main( ) { unsigned short a; short int b=-1; a=b; cout<<″a=″<
  • 67. 运行结果为 65535 赋给b的值是-1,怎么会得到65535呢?请看图2.9所示的赋值情况。 图2.9 -1的补码形式为1111111111111111(即全部16个二进制位均为1),将它传送给a,而a是无符号型变量,16个位全1是十进制的65535。如果b为正值,且在0~32767之间,则赋值后数值不变。
  • 68. 不同类型的整型数据间的赋值归根结底就是一条:按存储单元中的存储形式直接传送。 C和C++使用灵活,在不同类型数据之间赋值时,常常会出现意想不到的结果,而编译系统并不提示出错,全靠程序员的经验来找出问题。这就要求编程人员对出现问题的原因有所了解,以便迅速排除故障。
  • 69. 在赋值符“=”之前加上其他运算符,可以构成复合的运算符。如果在“=”前加一个“+”运算符就成了复合运算符“+=”。例如,可以有 a+=3 等价于 a=a+3 x*=y+8 等价于 x=x*(y+8) x%=3 等价于 x=x%3 以“a+=3”为例来说明,它相当于使a进行一次自加3的操作。即先使a加3,再赋给a。同样,“x*=y+8”的作用是使x乘以(y+8),再赋给x。 为便于记忆,可以这样理解:2.6.3 复合的赋值运算符
  • 70. ① a+= b (其中a为变量,b为表达式) ② a+= b (将有下划线的“a+”移到“=”右侧) ③ a = a + b (在“=”左侧补上变量名a) 注意,如果b是包含若干项的表达式,则相当于它有括号。如 ① x %= y+3 ② x %= (y+3) ③ x = x%(y+3)(不要错认为x=x%y+3)
  • 71. 凡是二元(二目)运算符,都可以与赋值符一起组合成复合赋值符。C++可以使用以下几种复合赋值运算符: +=,-=,*=,/=,%=,<<=,>>=,&=,∧=,|= 其中后5种是有关位运算的。 C++之所以采用这种复合运算符,一是为了简化程序,使程序精炼,二是为了提高编译效率(这样写法与“逆波兰”式一致,有利于编译,能产生质量较高的目标代码)。专业的程序员在程序中常用复合运算符,初学者可能不习惯,也可以不用或少用。
  • 72. 由赋值运算符将一个变量和一个表达式连接起来的式子称为“赋值表达式”。 它的一般形式为 <变量> <赋值运算符> <表达式> 如“a=5”是一个赋值表达式。对赋值表达式求解的过程是:先求赋值运算符右侧的“表达式”的值,然后赋给赋值运算符左侧的变量。一个表达式应该有一个值。赋值运算符左侧的标识符称为“左值”(left value,简写为lvalue)。并不是任何对象都可以作为左值的,变量可以作为左值,而表达式a+b就不能作为左值,常变量也不能作为左值,因为常变量不能被赋值。2.6.4 赋值表达式
  • 73. C++提供一种特殊的运算符——逗号运算符。用它将两个表达式连接起来。如 3+5,6+8 称为逗号表达式,又称为“顺序求值运算符”。逗号表达式的一般形式为 表达式1,表达式2 逗号表达式的求解过程是:先求解表达式1,再求解表达式2。整个逗号表达式的值是表达式2的值。如,逗号表达式 a=3*5,a*4 赋值运算符的优先级别高于逗号运算符, 因此应先求解a=3*5(也就是把“a=3*5”作为一个表达式)。经计算和赋值后得到a的值为15,然后求解a*4,得60。整个逗号表达式的值为60。 (2o)2.7 逗号运算符与逗号表达式(增加内容)
  • 74. Computer Term  word processor字处理器 a predefined set of instructions预定的指令集 computer program a text editor文本编辑器 machine language programming language程序设计语言 low-level language high-level language高级语言 compiler linker analysis phase design phase编译连接分析阶段,设计阶段 source file源文件 source code program code statements报表 object code对象的代码 object file a compile-time error编译错误 a syntax error语法错误 a run-time error logic error逻辑错误 executable file bugs debugging可执行文件的错误调试
  • 75. Constants(常量) Variables(变量) Simple output to the screen(简单的屏幕输出) Comments(注释) Data types(数据类型) Data type sizes(数据类型的大小) Operators(运算符) Operator precedence(运算符的优先级) Type conversions and casts(类型转换和强转)