类型
算数类型
类型 | 含义 | 最小尺寸 |
---|---|---|
bool | 布尔类型 | 未定义 |
char | 字符 | 8位 |
wchar_t | 宽字符 | 16位 |
char16_t | Unicode字符 | 16位 |
char32_t | Unicode字符 | 32位 |
short | 短整型 | 16位 |
int | 整型 | 16位 |
long | 长整型 | 32位 |
long long | 长整型 | 64位 |
float | 单精度浮点数 | 6位有效数字 |
double | 双精度浮点数 | 10位有效数字 |
long double | 扩展精度浮点数 | 10位有效数字 |
内置类型的机器实现
计算机以比特序列存储数据,每个比特非0即1。大多数计算机以2的整数次幂个比特为块来处理内存,可寻址的最小内存块称为“字节(byte)”。存储的基本单元称为“字(word)”,它通常由几个字节组成。
除去布尔和扩展的字符外,其他整型可以划分为带符号的(signed)和无符号的(unsigned)两种。带符号的类型可以表示整数、负数或0,无符号类型则仅能表示大于等于0的值。
类型转换
当从无符号数中减去一个值时,不管这个值是不是无符号数,我们都必须确保结果不能是一个负值。
1 | // 错误:变量u永远也不会小于0,循环条件一直成立 |
字面值常量
转义序列
有两类程序员不能直接使用:一类是不可打印(nonprintable)的字符,如退格活其他控制字符,因为它们没有可视的图符;另一类是C++语言中有特殊含义的字符(单引号、双引号、问号、反斜线)。在这些情况下需要用到转义序列(escape sequence),转义序列均以反斜线作为开始,C++语言规定的转义序列包括:
换行符 \n 横向制表符\t 报警符\a 纵向制表符\v 退格符\b 双引号 \” 反斜线 \ 问号 \? 单引号 \’ 回车符 \r 进纸符\f
变量
变量提供一个具名的、可供程序操作的存储空间。
变量定义
初始化不是赋值,初始化的含义是创建变量时赋予其一个初始值,而赋值的含义是把对象的当前值擦出,而以一个新值来替代。
变量声明和定义的关系
为了支持分离式编译,C++语言将声明和定义区分开来。声明(declaration)使得名字为程序所知,一个文件如果想使用别处定义的名字则必须包含对那个名字的声明。而定义(definition)负责创建与名字关联的实体。
变量能且只能被定义一次,但是可以被多次声明。
标识符
变量命名规范
- 标识符要能体现实际含义。
- 变量名一般用小写字母,如index。
- 用户自定义的类名一般以大写字母开头,如Sales_item。
- 如果标识符由多个单词组成,则单词间应该应有明显区分。
名字的作用域
复合类型
复合类型(compound type)是指基于其他类型定义的类型。
引用
引用(reference)为对象起了另外一个名字,引用类型引用另外一种类型。(引用类型的初始值必须是一个对象)
引用必须初始化。
引用并非对象,相反的,它只是为一个已经存在的对象所起的另外一个名字。
指针
指针(pointer)是“指向(point to)”另外一种类型的复合类型。与引用类似,指针也实现了对其他对象的间接访问。然而指针与引用相比又有很多不同点。其一,指针本身就是一个对象,允许对指针赋值和拷贝,而且在指针的生命周期内它可以先后指向几个不同的对象。其二,指针无需在定义时赋值。
定义指针类型的方法将声明符写成*d的形式,其中d是变量名。
引用不是对象,没有实际地址,所以不能定义指向引用的指针。
指针值
- 指向一个对象。
- 指向紧邻对象所占空间的下一个位置。
- 空指针。
- 无效指针,也就是上述情况之外的其他值。
取地址符(操作符&)
解引用符(操作符*)
如果指针指向了一个对象,则允许使用解引用符(操作符*)来访问该对象。
建议:初始化所有指针。
指向指针的指针
指向指针的引用
const界定符
const对象一旦创建后其值就不能再改变,所以const对象必须初始化。
默认状态下,const对象仅在文件内有效
如果想在多个文件之间共享const对象,必须在变量的定义之前添加extern关键字。
const的引用
可以把引用绑定到const对象上,就像绑定到了其他对象上一样,我们称之为对常量的引用(reference to const)。与普通引用不同的是,对常量的引用不能被用作修改它所绑定的对象。
指针和const
与引用一样,也可以令指针指向变量或非变量。类似于常量引用,指向常量的指针(pointer to const)不能用于改变其所指对象的值。要想存放常量对象的地址,只能使用指向常量的指针。
处理类型
类型别名
类型别名(type alias)是一个名字,它是某种类型的同义词。使用类型别名有很多好处,它让复杂的类型名字变得简单明了、易于理解和使用,还有助于程序员清楚地知道使用该类型的真实目的。
有两种方法可用于定义类型别名。传统的方法是使用关键字typedef。
1 | typedef double wages; |
新标准规定了一种新的方法,使用别名生命(alias declaration)来定义类型的别名:
1 | using SI = Sales_item; // SI是Sales_item的同义词 |
auto类型说明符
C++11新标准引入了auto类型说明符,用它就能让编译器替我们去分析表达式所属的类型。
decltype类型指示
C++11新标准引入了第二种类型说明符decltype,它的作用是选择并返回操作数的数据类型。在此过程中,编译器分析表达式并得到它的类型,却不实际计算表达式的值。
Q
What is the difference between ++i and i++?
++i 等价于i=i+1。递增运算将运算对象的值增加1.
1 | i = 1; |
i++ 同样会自增i,但是返回的是原来的值。
1 | i = 1; |
1 | // 前缀形式: |
###
Reference
C++ Primer第五版