I:C++基础部分
2.1、基本内置类型
{ 算 术 类 型 { 字 符 整 型 布 尔 值 浮 点 数 空 类 型 \left\{ \begin{array}{c}算术类型 \left\{ \begin{array}{c}字符\\ 整型\\ 布尔值\\ 浮点数\end{array} \right.\\ 空类型\end{array} \right. ⎩⎪⎪⎪⎪⎨⎪⎪⎪⎪⎧算术类型⎩⎪⎪⎨⎪⎪⎧字符整型布尔值浮点数空类型
注意:空类型不对应具体的值,仅用于一些特定的场合。例如,当函数不返回任何值时使用空类型作为返回类型。
2.1.1、算术类型
算术类型分为两类:整型和浮点型。算术类型的尺寸(数据所占比特数)在不同机器上有所差别。表列出了C++标准规定的尺寸的最小值,同时允许编译器赋予这些类型更大的尺寸
类型 | 含义 | 最小尺寸 |
---|---|---|
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位有效数字 |
其中布尔类型的取值有两种真(true)或假(false)
带符号类型和无符号类型
除去布尔型和扩展的字符型之外,其他整型可以划分为带符号的(signed)和无符号的(unsigned)两种。其中,带符号类型可以表示正数、负数或0,无符号类型则仅能表示大于0的值。
注意:类型int、short、long和long long都是带符号的,通过在这些名前添加unsigned就可以得到无符号类型。
注意:字符型分为三种:char、signed char和unsigned char。尽管字符型有三种,但是字符的表现形式却只有两种:带符号和无符号的。类型char实际上会表现为上述两种形式中的一种,具体是哪种由编译器决定。
注意:无符号类型中所有比特都用来存储值。
建议:在使用中该如何选择类型?
1、当明确数值不为负,选择无符号类型
2、使用int执行整数运算
3、在算术表达式中不要使用char或bool,只有在存放字符或布尔值时才使用它们。
4、执行浮点运算选用double,这是因为float通常精度不够而且双精度浮点数和单精度浮点数的计算代价相差无几。
2.1.2、类型转换
对象的类型定义了对象能包含的数据和能参与的运算,其中一种运算被大多数类型支持,就是将对象从一种给定的类型转换为另一种相关类型。
注意:当在程序的某处我们使用了一种类型而其实对象应该取另一种类型时,程序会自动进行类型转换。
1、当我们把一个非布尔类型的算术值赋给布尔类型时,初始值为0则结果为false,否则结果为true。
2、当我们把一个布尔值赋给非布尔类型时,初始值为false则结果为0,初始值为true则结果为1。
3、当我们把一个浮点数赋给整数类型时,进行了近似处理。结果值将仅保留浮点数中小数点之前的部分。
4、当我们把一个整数值赋给浮点类型时,小数部分记为0。如果该整数所占的空间超过了浮点类型的容量,精度可能有损失。
5、当我们赋给无符号类型一个超出它表示范围的值时,结果是初始值对无符号类型表示数值综述取模后的余数。
建议:避免无法预知和依赖于实现环境的行为
无法预知的行为源与编译器无须(有时是不能)检测的错误。即使代码编译通过了,如果程序执行了一条未定义的表达式,仍有可能产生错误。
程序也应该尽量避免依赖于实现环境的行为。如果我们把int的尺寸看成是一个确定不变的已知值,那么这样的程序就称作不可移植的。当程序移植到别的机器上后,依赖于实现环境的程序就可能发生错误。
含有无符号类型的表达式
例如,当一个算术表达式中即有无符号数又有int值时,那个int值就会转换成无符号数。
注意,当从无符号数中减去一个值时,不管这个值是不是无符号数,我们都必须确保结果不能是一个负值
例如
for(unsigned u=10;u>=0;–u)
std::count<<u<<std::endl;
当u为0时,此时减1不是变为-1,而是由于无符号数的原因,自动变为一个合法的无符号数。
建议:切勿混用带符号类型和无符号类型
[1] Lippman S B , Josée Lajoie, Moo B E . C++ Primer (5th Edition)[J]. 2013.