负数补码 = 反码 + 1
正数补码 = 原码
基本数据类型:
(整数;实数;字符;布尔)类型
(signed/unsigned) signed char
<= (unsigned) short int
<= (unsigned) int
<= (unsigned) long int
<= long long int
整数常量:
- 十进制
- 八进制
- 十六进制
后缀:L / LL / U
浮点常量默认为double型,如果后缀F(或f)可以使其成为float
初始化:
int a = 0
int a(0)
int a = {0}
int a{0}
其中使用大括号的初始化方式称为列表初始化,列表初始化时不允许信息的丢失。例如使用double值初始化int变量,就会造成数据的丢失。
逗号运算符:
表达式1,表达式2
求解顺序及结果:
先求解表达式1,再求解表达式2
最终结果为表达式2的值
例:
a = 3 * 5, a * 4最终结果为60
条件运算:
表达式1?表达式2:表达式3
条件表达式的最终类型为2和3中较高的类型
sizeof运算符:
sizeof(类型名) 或 sizeof 表达式
位运算符:
- 按位与(&):只有当对应位都为1,则新值中相应位为1,否则为0
- 按位或(|):如果对应位至少有一个为1,则新值中相应位为1,否则为0
- 按位异或(^): 若对应位相同,则结果该位为0;若对应位不同,则结果该位为1
- 按位取反(~):单目运算符,对一个二进制位按位取反
位运算:
- 左移运算(<<)
左移后,低位补0,高位舍弃 - 右移运算(>>)
右移后:
低位:舍弃
高位- 无符号数:补0
- 有符号数:补“符号位”
隐含转换就时把低类型数据转换为高类型数据
显式转换:
类型说明符(表达式)
(类型说明符)表达式
类型转换操作符<类型说明符>(表达式)
类型转换操作符:const_cast、dynamic_cast、reinterpret_cast、static_cast
例:int(z),(int)z,static_cast
其他控制语句
- break语句:
使程序从循环体和switch语句内跳出,继续执行逻辑上的吓一条语句。不宜用在别处。 - continue语句:
结束本次循环,接着判断是否执行下一次循环 - goto语句:
使程序的执行流程跳转到居于标号所指定的语句。不提倡使用。
类型别名:为已有类型另外命名
- typedef 已有类型名 新类型名表
typedef double Area,Volume;
typedef int Natural;
Natural i1,i2;
Area a;
Volume v;
- using 新类型名 = 已有类型名
using Area = double
using Volume = double
不限定作用域枚举类型说明:
- 枚举元素使常量,不能对它们赋值
enum Weekday {SUN, MON, TUE, WED, THU, FRI, SAT}
不能写赋值表达式:SUN = 0 - 枚举元素具有默认值,它们依次为:0,1,2,......
- 也可以在声明时另行指定枚举元素的值
如:enum Weekday{SUN=7,MON=1,TUE,WED,THYU,FRI,SAT}
- 枚举值可以进行关系运算
- 整数值不能直接赋给枚举变量
如需要将整数赋值给枚举变量,应进行强制类型转换 - 枚举值可以赋给整型变量
auto类型与decltype类型
- auto:编译器通过初始值自动推断变量的类型
例如:auto val = val1 + val2
- decltype:定义一个变量与某一表达式类型相同,但并不用该表达式初始化变量
例如:decltype(i)j = 2
表示j以2作为初始值,类型与i一致
struct结构的作用是把一组相互关联的数据整合在一起
函数定义的语法形式:
类型标识符 函数名(形式参数表)
{
语句序列
}
函数原型:类型标识符 被调用函数名(含类型说明的形参表)
递归调用:函数直接或间接调用自身
回文:各位数字左右对称的整数
rand函数:
函数原型:int rand(void);
所需头文件:
功能和返回值:求出并返回一个伪随机数
srand函数:
原型:void srand(unsigned int seed)
参数:seed产生随机数的种子
所需头文件:
功能:为使rand()产生一序列伪随机数而设置起始点。使用1作为seed参数可以重新初化rand()
用递归法计算从n个人中选k个人组成一个委员会的不同组合数
分析
- 由n个人里选k个人的组合数=由n-1个人里选k个人的组合数+由n-1个人里选k-1个人的组合数
- 当n=k或k=0时组合数为1
将n个盘子从A针移到C针可以分解为三个步骤:
- 将A上的n-1个盘子移到B针上(借助C针);
- 把A针上剩下的一个盘子移到C针上;
- 把n-1个盘走从B针移到C针上(借助A针)
函数的参数传递:
- 在函数被调用时才分配形参的存储单元
- 实参可以是常量、变量或表达式
- 实参类型必须与形参相符
- 值传递是传递参数值,即单向传递
- 引用传递可以实现双向传递
- 常引用作参数可以保障实参数据的安全
引用类型:
- 引用(&)是标识符的别名
- 定义一个引用时,必须同时对它进行初始化,使它指向一个已存在的对象
- 例如:
int i,j;
int &ri = i;//定义int引用ri,并初始化为变量i的引用
j = 10;
ri = j;//相当于i = j
- 一旦一个引用被初始化后,就不能改为指向其它对象
- 引用可以作为形参
内联函数:
通常的做法是省略原型,将整个定义(即函数头和所有函数代码)放在本应提供原型的地方
- 编译时在调用处用函数体进行替换
- 节省了参数传递
- 控制转移等开销
注意: - 内联函数体内不能有循环语句和switch语句;
- 内联函数的定义必须出现在内联函数第一次被调用之前;
- 对内联函数不能进行异常接口声明。
默认参数值:
- 可以预先设置默认的参数值,调用时如给出实参,则采用实参值,否则采用预先设置的默认参数值。
- 例:
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
}
默认参数值的说明次序:
- 有默认参数的形参必须列在形参列表的最右,即默认参数值的右面不能有无默认值的参数;
- 调用时实参与形参的结合次序是从左向右。
- 例:
int add(int x,int y = 5,int z = 6);//正确
int add(int x = 1,int y = 5,int z);//错误
int add(int x = 1,int y,int z = 6);//错误
默认参数值与函数的调用位置:
- 如果一个函数有原型声明,且原型声明在定义之前,则默认参数值应在函数原型声明中给出;如果只有函数的定义,或函数定义之前,则默认参数值可以函数定义中给出。
- 例:
int add(int x = 5,int y = 6);
//原型声明在前
int main(){
add();
}
int add(int x,int y){
//此处不能再指定默认值
return x + y;
}
int add(int x = 5, int y = 6){
//只有定义,没有原型声明
return x + y;
}
int main(){
add();
}
函数重载的概念:
- C++允许功能相近的函数在相同的作用域内以相同函数名声明,从而形成重载。方便使用,便于记忆。
注意事项:
- 重载函数的形参必须不同:个数不同或类型不同。
- 编译程序将根据实参和形参的类型及个数的最佳匹配来选择调用哪一个函数。
- 不要将不同功能的函数声明为重载函数,以免出现调用结果的误解 、混淆
角度值转化为弧度 :
弧度 = 角度值*PI / 180
类与对象
- 对象: 现实中对象的模拟,具有属性和行为
- 同一类对象的共同属性和行为。
- 定义对象时,通过构造函数初始化
- 删除对象时,通过析构函数释放资源
面向对象程序设计的基本特点:抽象、封装、继承、多态
类定义的语法形式
class 类名称
{
public:
公有成员(外部接口)
private:
私有成员
protected:
保护型成员
};
构造函数的作用
- 在对象好被创建时使用特定的值构造对象,将对象初始化为一个特定的初始状态
构造函数的调用时机
- 在对象创建时被自动调用
类内初始值
private:
int hour = 0,minute = 0,second = 0;
私有类型成员
- 如果紧跟在类名称的后面声明私有成员,则关键字private可以省略
类的成员函数
- 在类中声明函数原型;
- 可以在类外给出函数体实现,并在函数名前使用类名加以限定;
- 也可以直接在类中给出函数体,形成内联成员函数;
- 允许声明重载函数和带默认参数值的函数
内联成员函数
- 内联函数体中不要有复杂结构
(如循环语句和switch语句)。 - 在类中声明内联成员函数的方式:
- 将函数体放在类的声明中
- 在类外实现函数的时候使用inline关键字
默认构造函数
- 调用时可以不需要实参的构造函数
- 参数表为空的构造函数
- 全部参数都有默认值的构造函数
下面两个都是默认构造函数,如在类中同时出现,将产生编译错误:
Clock();
Clock(int newH=0,int newM=0,int newS=0);
隐含生成的构造函数
如果程序中未定义构造函数,编译器将自动生成一个默认构造函数
- 参数列表为空,不为数据成员设置初始值;
- 如果类内定义了成员的初始值,则使用内类定义的初始值;
- 如果没有定义类内的初始值,则以默认方式初始化;
- 基本类型的数据默认初始化的值是不确定的。
"=defalut"
- 如果程序中已定义构造函数,默认情况下编译器就不再隐含生成默认构造函数。如果此时依然希望编译器隐含生成默认构造函数,可以使用“=default”。
- 例:
class Clock{
public:
Clock() = default;//指示编译器提供默认构造函数
Clock(int newH, int newM, int newS); //构造函数
private:
int hour,minute,second;
}
数组:数组是一种数据形式,能够存储多个同类型的值。
数组的初始化规则:只有定义数组时才能使用初始化,此后就不能使用了,也不能将一个数组付给另一个数组:
int cards[4] = {3, 6, 8, 10}; //okay
int hand[4]; //okay
hand[4] = {5, 6, 7, 9}; //not allowed
hand = cards; //not allowed
然而,可以用下标分别给数组中的元素赋值。
常量表达式是指值不会改变并且在编译过程就能得到计算结果的表达式。显然,字面值属于常量表达式,用常量表达式初始化的const对象也是常量表达式。
一个对象(或表达式)是不是常量表达式由它的数据类型和初始值共同决定
C++11新标准规定,允许将变量声明为constexpr类型以便由编译器来验证变量的值是否是一个常量表达式。声明为constexpr的变量一定是一个常量,而且必须用常量表达式初始化