步骤:创建项目、设置断点、运行调试
在生成发布版本前,需要清除早期生成过程中创建的中间文件和输出文件,确保其是最终版本。
操作:①生成->清理解决方案;②debug->release;③生成->生成解决方案
从键盘输入数据:iostream类的对象cin的>>操作,可以从标准输入设备(键盘)读入数据。
数据的存储:为了存储数据,需要预先为这些数据分配内存空间。
单步执行:调试 > 逐过程 F10 /逐语句 F11
设置断点:直接运行到断点前语句 F5
跟踪某一变量的值:在运行调试时,可以通过局部变量、监视窗口来跟踪某一变量的值。如F11进入某一函数体。
最常见的错误:类型错、逻辑错,记录错误信息能够提高调试效率
两个debug功能用法:step into + run to cursor 跟踪到函数体内某处
C++是面向对象的高级语言:对象 > 类 > 封装接口 > 消息通信
程序设计方法:面向过程、面向对象、泛型
C++程序开发过程:算法设计、源程序编辑、编译、连接、运行调试
计算机组成:输入设备、内存储器、外存储器、CPU、输出设备
计算机软件:应用软件、系统软件(Windows、Linux)、中间件
软件:程序+文档
机器语言 -> 汇编语言(助记符)-> 高级语言
面向对象的观点和方法:将客观事物看做对象,对象间通过消息传送进行沟通,支持分类和抽象。
对象:系统中用来描述客观事物的一个实体
类:同一类对象基于分类和抽象的思维形成的
封装:隐蔽对象的内部细节,对外形成一个边界,只保留有限的对外接口,使用方便,安全性好
继承:意义在于软件复用,改造、拓展已有类形成新的类
多态:同样的消息作用在不同对象上有可能引起不同的行为
源程序:用源语言写的,有待翻译的程序
目标程序:源程序通过翻译程序加工以后生成的机器语言程序
可执行程序:连接目标程序以及库中的某些文件,生成的一个可执行文件,如windows系统平台上的.exe文件
三种不同类型的翻译程序:1. 汇编程序(将汇编语言源程序翻译成目标程序) 2. 编译程序(将高级语言源程序翻译成目标程序,例如C++)3. 解释程序(将高级语言源程序翻译成机器指令,边翻译边执行,例如JAVA)
计算机中的信息:控制信息(指挥计算机操作)、数据信息(计算机程序加工的对象)
信息的存储单位:位(bit,b 数据的最小单位,表示一位二进制信息)、字节(byte,B 八位二进制数字组成)
1KB = 1024B
1MB = 1024K
1GB = 1024M
程序中的常用数值:二进制、八进制、十进制、十六进制
R进制->十进制:各位数字与它的权相乘,其积相加
十进制整数->R进制整数:除R取余法
十进制小数->R进制小数:乘R取整法
源码:0的表示不唯一
补码:0的表示唯一,符号位可作为数值参加运算,减法运算可转化为加法运算,补码运算的结果仍是补码
模数:n位二进制整数的模数为2^n,n位小数的模数为2
补数:一个数减去另一个数(加一个负数)等于第一个数加第二个数的补数
补码计算:反码作为中间码。负数补码=反码+1,正数补码=原码
反码计算:对于负整数,原码符号位不变,其余各位取反,对于正整数,原码就是补码。
如果负数之和得正数,或正数之和得负数,说明运算结果溢出
实数的浮点表示:计算机中采用浮点方式表示小数
字符在计算机中的表示:通过编码表示,ASCII码(7位二进制数表示一个字符,最多表示2^7=128个字符),汉字编码(中国国家编码)
C++能够处理的基本数据类型:整数类型、实数类型、字符类型、布尔类型
C++支持的基本运算:算数运算、逻辑运算
C++中的数据输入/输出可以调用预定义的功能模块实现,但程序要能够自定义类型。
枚举类型:通过列出所有可取值来定义一种新类型
C++特点:兼容C,支持面向过程的程序设计;支持面向对象的方法;支持泛型程序的设计方法。
所有标准库的共同命名空间std,使用时要有名有姓,如std::cout。要是嫌麻烦,可以在程序开始添加
using namespace std
打开std命名空间,就不用带姓了。
C++字符集:包括大小写的英文字母A-Z、数字字符0-9、特殊字符
单词:关键字(C++预定义的单词)、标识符(程序员声明的单词,它命名程序正文中的一些实体)、文字、分隔符((),{},:,; 用于分隔各个词法记号或程序正文)、运算符(操作符)、空白符(空白、制表符、垂直制表符、换行符、回车符和注释的总称)
标识符的构成规则:大小写、下划线开始;可以由大小写、下划线或数字0~9构成;大小写字母代表不同标识符;不能是C++关键字或操作符
基本数据类型:整数类型、实数类型、字符类型、布尔类型
程序中的数据:常量(源程序写明,值在程序运行期间不可改变)、变量(在程序运行过程中允许改变的数据)
整数类型:基本整数类型int,按符号分(signed,unsigned),按数据范围分(short, long, long long)
C++没有规定每种数据类型的字节数和取值范围,只规定它们之间的字节数大小顺序满足:(signed/unsigned)signed char ≤ (unsigned) short int ≤ (unsigned) int ≤ (unsigned) long int ≤ long long int
字符类型(char):单字节里容纳单个字符的编码,实质上存储的也是整数
浮点数类型:单精度(float),双精度(double),扩展精度(long double)
字符串类型:有字符串常量,基本类型中没有字符串变量,采用字符数组存储字符串(C风格的字符串),标准C++类库中的String类(C++风格的字符串)
布尔类型(bool):只有true, false,常用来表示关系比较、相等比较或逻辑运算的结果
整数常量:十进制、八进制(0+0~7)、十六进制(0x+0-9,A-F)、后缀(后缀L/l表示类型至少是long,后缀LL/ll表示类型是long long,后缀U/u表示unsigned)
浮点数常量:以文字形式出现的实数,一般形式(如12.5)、指数形式(如0.34E+2)、后缀(浮点常量默认double型,如果后缀F/f可以使其成为float型,如12.3f),浮点数是近似存储的
C风格字符串常量:一对双引号括起来的字符序列,在内存中按串中字符的排列次序顺序存放,每个字符占一个字节,在末尾添加‘\0’作为结尾标记。
变量定义初始化:例如int a=0
或int a(0)
或int a={0}
或int a{0}
其中使用大括号的初始化方式称为列表初始化,列表初始化时不允许信息的丢失,例如用double值初始化int变量就会造成数据丢失。
符号常量:const 数据类型说明符 常量名=常量值 / 数据类型说明符 const 常量名=常量值,例如const float PI = 3.1415926
符号常量在定义时要初始化,在程序中间不能改变其值。
从键盘输入数据:iostream类的对象cin的>>操作,可以从标准输入设备(键盘)读入数据。
数据的存储:为了存储数据,需要预先为这些数据分配内存空间。
单步执行:调试 > 逐过程 F10 /逐语句 F11
设置断点:直接运行到断点前语句 F5
10种复合运算符:+=, -=, *=, /=, %=, <<=, >>=, &=, ^=, |=
逗号运算:格式 表达式1,表达式2 先求解表达式1,再求解表达式2,最终结果为表达式2的值。例:
a=3*5,a*4 //最终结果为60
关系运算:比较简单的逻辑运算,其结果类型为bool,值为true或false。优先级:<, <=, >, >=优先级相同(高) == !=优先级相同(低)
逻辑运算:结果类型为bool,值为true或false。优先级:!(非) > &&(与)> ||(或) ||,&&有短路特性,很可能只计算表达式1的结果,不再求解表达式2。
条件运算:解决了最简单的选择结构,C++的特色语句之一。x=a>b?a:b (如果a>b为true,x为a,如果a>b为false,x为b)优先级:高于赋值运算符,低于逻辑运算符。
sizeof:计算某种类型、变量、对象占多少字节的运算。
sizeof(short) ;
sizeof x
按位与(&):将两个运算量的每一个位进行逻辑与操作。在编写底层硬件接口程序,或写程序要存储一些状态和标记时很有用,如把某位置0、取出指定位
按位或(|):将两个运算量的每一个位进行逻辑或操作。如将某位置置1。
按位异或(^):将两个运算量的每一个位进行逻辑异或操作。如使特定位翻转(与0异或保持原值,与1异或取反)。
取反(~):单目运算符,对一个二进制按数位取反。
移位(<<,>>):左移后,低位补0,高位舍弃;右移后,低位舍弃,高位无符号数补0,有符号数补“符号位”。左移相当于除以2的效果,右移相当于乘以2的效果。如果左移一位发现正负变了,说明在乘以2下溢出了。大多数时候不是做高效率乘法,而是标志位移位。
隐含转换:混合运算时数据类型的转换。基本原则是编译系统将低类型数据转换为高类型数据。
高优先级是表示数据比较宽的类型。
混合运算时数据类型的转换:将一个非布尔类型的算数值赋给布尔类型时,算数值为0则结果为false,否则结果为true,反之亦然;将一个浮点数赋给整数类型时,结果值只保留浮点数中的整数部分,小数部分将丢失,将一个整数值赋给浮点类型时,小数部分记为0,如果整数所占空间超过了浮点类型的容量,精度可能有损失。
显示类型转换(强制转换):类型说明符(表达式) / (类型说明符)表达式 / 类型转换操作符<类型说明符>(表达式) 类型转换操作符可以是const_cast, dynamic_cast, reinterpret_cast, static_cast,
如int(z); (int)z; static_cast
三种完全等价。
输入输出流里有大量预先定义好的类
I/O流:数据从一个对象到另一个对象的流动抽象为“流”,流在使用前要被建立,使用后要被删除。数据的输入与输出是通过I/O流来实现的,cin和cout是预定义的流类对象,cin用来处理标准输入,即键盘输入,cout用来处理标准输出,即荧幕输出。从流中获取数据的操作称为提取操作,向流中添加数据的操作成为插入操作。
预定义的插入符:<<作用在流类对象cout上,cout << 表达式 << 表达式…
预定义的提取符:>>作用在流类对象cin上,cin >> 表达式 >> 表达式…
提取符可以连续写多个,每个后面跟一个表达式,该表达式通常是用于存放输入值的变量,如
int a,b;
cin >> a >> b
不管条件如何,先执行一次循环。
适合做计数循环。
break:从循环体和switch语句跳出,不宜用在别处。
continue:结束本次循环并判断是否执行下一次循环。
goto:使程序执行跳转到语句标号所指定语句,不提倡。
自定义类型:
typedef 已有类型名 新类型名表 例:
typedef int Natural
using 新类型名=已有类型名 例:
using Area=double
枚举类型:适合做数据合法性检验,如星期几,列出整数的子集(0,1,2,3,4,5,6),定义一个新类型。
定义枚举类型语法形式:enum 枚举类型名 {变量值列表} 是不限定作用域的枚举类型 例:enum Weekday {SUN, MON, TUE, WED, THU, FRI, SAT}
不限定作用域枚举类型说明:枚举元素是常量,不能对它们赋值,在上例中,不能写赋值表达式SUN=0
;枚举元素具有默认值,它们依次为0,1,2,…;也可以在声明时另行指定枚举元素的值,如enum Weekday{SUN=7, MON=1, TUE, WED, THU, FRI, SAT};
枚举值可以进行关系运算;整数值不能直接赋值给枚举变量,如需要,应进行强制类型转换;枚举值可以赋给整型变量
两种定义枚举变量的方式:预先定义了枚举类型GameResult
GameResult result;
enum GameResult omit = CANCEL;
auto类型:编译器通过初始值自动推断变量的类型,如auto val = val1 + val2
,如果val1 + val2是int类型,则val是int类型。
decltype类型:定义一个变量与某一表达式的类型相同,但并不用该表达式初始化变量,如decltype(i) j = 2
,表示j以2作为初始值,类型与i一致。
语法:
类型标识符 函数名(形式参数表)
{
语句序列
}
形式参数定义: name1, name2, …, namen
注:形参不占存储空间,是被初始化的内部变量,寿命和可见性仅限于函数内部
类型标识符:表示返回值类型,由return语句给出返回值,若无返回值,写void,不必写return语句。
调用函数前需要先声明函数原型
语法:类型标识符 被调用函数名(含类型说明的形参表)
函数调用语法:函数名(实参列表)
函数调用时用实参初始化形参,分配存储空间
函数调用形式:嵌套调用、递归调用。如果有函数的多次调用,可以在运行调试时从调用栈观察。
例:将一个8进制数转换为10进制数
例:求圆周率
功能分解,已知
需要给arctanx一个限制条件,如加的某项的值不大于10^-15,为循环终止条件
例:寻找并输出11~999之间的数m,它满足m,m²,m³均为回文数(各位数字左右对称的整数)
判断回文思路:将一个数颠倒,判断和原来的数是否相等,除10取余取出最低位
例:计算分段函数:
例:投骰子
投骰子,模拟生成随机数:每个骰子有六面,点数分别为1,2,3,4,5,6。游戏者在程序开始时输入一个无符号整数,作为产生随机数的种子,每轮投两次骰子,第一轮如果和数为7或11则为胜,游戏结束;和数为2,3或12为负,游戏结束;和数为其他值则将此值作为自己的点数,继续第二轮、第三轮,直到某轮和数等于点数则取胜,若在此前出现和数为7则为负。
功能分解:由rolldice函数负责模拟投骰子,计算和数并输出和数。
rand函数:函数原型int rand(void);
,所需头文件,求出并返回一个伪随机数
srand函数:函数原型 void srand(unsigned int seed);
,参数seed产生随机数的种子,所需头文件,为使rand()
产生一序列伪随机整数而设置起始点。使用1作为seed参数,可以重新初化rand()
。
主函数调用函数1,函数1调用函数2。函数调用时,用栈来保存当前现场和返回地址。
例3-7 求两数平方和
函数自己调用自己
例:从n个人里选k个人组成一个委员会
思路:n个人里选k个人的组合数=n-1个人里选k个人的组合数 + n-1个人里选k-1个人的组合数,当n=k或k=0时,组合数为1
例:汉诺塔问题
思路:①将A上n-1个盘子移到B上(借助C);②把A上剩下一个盘子移到C上;③将n-1个盘子从B移到C
在函数被调用时才分配形参的存储单元;实参可以是常量、变量或表达式;实参类型必须与形参相符;值传递是传递参数值,即单向传递;引用传递可以实现双向传递;常引用作参数可以保障实参数据的安全(如结构体)。
引用(&)是标识符的别名,定义一个引用时,必须同时对它进行初始化,使它指向一个已存在的对象。例如:
int i,j;
int &ri = i; //定义int引用ri,并初始化为变量i的引用
j = 10;
ri = j; //相当于i=j
一旦一个引用被初始化后,就不能改为指向其它对象。引用可以作为形参。
C++标准中提供了两种方法:
1、如果所有的实参类型相同,可以传递一个名为initializer_list的标准库类型;
2、如果实参的类型不同,我们可以编写可变参数的模板(第9章)initializer_list。
initializer_list:是一种标准库类型,用于表示某种特定类型的值的数组,该类型定义在同名的头文件中。
使用模板时,需要在模板名字后面跟一对尖括号,括号内给出类型参数。例如:
initializer_list<string> ls; // initializer_list的元素类型是string
initializer_lsit<int> li; //initializer_list的元素类型是int
initializer比较特殊的一点是,其对象中的元素永远是常量值,我们无法改变initializer_list对象中元素的值。含有initializer_list形参的函数也可以拥有其他形参。
initializer_list使用举例:在编写代码输出程序产生的错误信息时,最好统一用一个函数实现该功能,使得对所有错误的处理能够整齐划一,然而错误信息的种类不同,调用错误信息输出函数时传递的参数也会各不相同。使用initializer_list编写一个错误信息输出函数,使其可以作用于可变数量的形参。
内联函数声明:使用关键字inline,编译时在调用处用函数体进行替换,节省了子函数参数传递,控制转移等开销。
注意:内联函数体内不能有循环语句和switch语句;内联函数的定义必须出现在内联函数第一次被调用之前;对内联函数不能进行异常接口声明。
constexpr函数语法规定:constexpr修饰的函数在其所有参数都是constexpr时一定返回constexpr。例:
constexpr int get_size() {return 20;}
constexpr int foo = get_size(); //正确:foo是一个常量表达式
可以预先设置默认的参数值,调用时如给出实参,则采用实参值,否则采用预先设置的默认参数值。例:
int add(int x=5, int y=6){
return x+y;
}
int main(){
add(10,20); //10+20
add(10); //10+6
add(); //5+6
}
默认参数值的说明次序:有默认参数的形参必须列在形参列表的最右,即默认参数值的右面不能有无默认值的参数;调用时实参与形参的结合次序是从左向右。
默认参数值与函数的调用位置:如果一个函数有原型声明,且原型声明在定义之前,则默认参数值应在函数原型声明中给出;如果只有函数的定义,或函数定义在前,则默认参数值可以在函数定义中给出。
例:求长方形的体积
函数重载:C++允许功能相近的函数在相同的作用域内以相同函数名声明,从而形成重载。方便使用,便于记忆。
注意:重载函数的形参必须不同,个数不同或类型不同,编译程序将根据实参和形参的类型及个数的最佳匹配来选择调用哪一个函数。不要将不同功能的函数声明为重载函数,以免出现调用结果的误解、混淆。
C++系统库中提供了几百个函数,例如求平方根函数(sqrt),求绝对值函数(abs)。
使用系统函数时要包含对应的头文件,例如cmath。