基本内置类型
C++定义了一套包括算数类型(arithmetic type)和空类型(void)在内的基本数据类型。
- 其中算数类型包括了:字符、整数型、布尔值和浮点数。
- 空类型不对应具体的值,仅用于一些特殊的场合。例如,最常见的是,当函数不返回任何值时使用空类型作为返回类型。
算数类型
算数类型分为两类:
- 整型(integral type,包括字符和布尔类型在内)
- 浮点型
算数类型的尺寸(也就是该类型数据所占的比特数)在不同的机器上有所差别。如下表展示了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)
注:除字符和布尔类型之外,其他整型用于表示(可能)不同尺寸的整数。C++语言规定一个int至少和一个short一样大,一个long至少和一个int一样大,一个long long至少和一个long一样大。
其中,long long是在C++11中新定义的。
内置类型的机器实现
计算机以比特序列存储数据,每个比特非0即1。
大多数计算机以2的整数次幂个比特来作为快来处理内存,可寻址的最小内存块称为(字节),存储的基本单元称为字(word)它通常是由几个字节组成。在C++语言中,一个字节要至少能容纳机器基本字符集中的字符。大多数机器的字节由8比特构成,字则由32或64比特构成,也就是4或8字节。
大多数计算机将内存中的每个字节与一个数字(地址)关联起来,一个字节为8比特。字为32比特的机器上,我们可以看到一个自的内存区域如下:
736424 | 00111011 |
736425 | 00011011 |
左侧是字节的地址,右侧是字节中8比特的具体内容。
带符号类型和无符号类型
除去布尔型和扩展的字符型之外,其他整型可以划分为带符号的(signed)和无符号的(unsigned)两种。
带符号类型可以表示正数,负数,或0,无符号类型仅能表示大于等于0的值。
类型int,long,short,long long 都是带符号的,通常在这些类型名前添加unsigned就可以得到无符号类型。
与其他整型不同,字符型被分为了三种:char、signed char 和 unsigned char。
特别需要注意的是:类型char和类型signed char并不一样。尽管字符型有三种,但是字符的表现形式却只需要两种:带符号和无符号的。类型char实际上会表现为上述两种形式中的一种,具体是哪种由编译器决定。
C++标准并没有规定带符号类型如何表示,但是约定了在表示范围内正值和负值的量应该平衡。因此8比特的signed char理论上应该可以表示-127至127区间内的值,大多数现代计算机将实际的表示范围定为-128至127。
无符号类型中所有比特都用来存储值,例如,8比特的unsigned char可以表示0至255区间内的值。
如何选择类型
和C语言一样,C++的设计准则之一也是尽可能地接近硬件。C++地数据类型必须满足各种硬件特质,所以它们常常显得繁杂而令人不知所措。事实上,大多数程序员能够(也应该)对数据类型地使用做出限定从而简化选择地过程。以下是选择类型的一些经验准则:
- 当明确知晓数值不可能为负时,选用无符号类型。
- 使用int执行整数运算。在实际应用中,short常常显得太小而long一般和int有一样的尺寸。如果你的数值超过了int的表示范围,选用long long。
- 在算术表达式中不要使用char和bool,只有在存放字符或布尔值时才能使用它们。因为类型char在一些机器上是有符号的,而在另一些机器上又是无符号的,所以如果使用char进行运算特别容易出问题。如果你需要使用一个不大的整数,那么明确指定它的类型signed char或者unsigned char。
- 执行浮点数运算选用double,这是因为float通常精度不够而且双精度浮点数和单精度浮点数的计算代价相差无几。事实上,对于某些机器来说,双精度运算甚至比单精度还快。long double提供的精度在一般情况下是没有必要的,况且它带来的运行时消耗也不容忽视。