HOME/CPP Primer/

2.1 基本内置类型

Article Outline
TOC
Collection Outline

2.1 基本内置类型

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位有效数字

布尔类型(bool)的取值是真(true)或者假(false)。

基本的字符类型是char,一个char的空间应确保可以存放机器基本字符集中任意字符对应的数字值。也就是说,一个char的大小和一个机器字节一样。

其他字符类型用于扩展字符集,如 wchar_t、char16_t、char32_t。 wchar_t类型用于确保可以存放机器最大扩展字符集中的任意一个字符,类型char16_t和char32_t则为Unicode字符集服务(Unicode是用于表示所有自然语言中字符的标准)。

带符号类型和无符号类型

除去布尔型和扩展的字符型之外,其他整型可以划分为带符号的(signed)和无符号的(unsigned)两种。带符号类型可以表示正数、负数或0,无符号类型则仅能表示大于 等于0的值。

类型int、short、long和long long都是带符号的,通过在这些类型名前添加unsigned就可以得到无符号类型,例如unsigned long。

字符型被分为了三种:char、signed char和unsigned char。字符的表现形式却只有两种:带符号的和无符号的。类型char实际上会表现为上述两种形式中的一种,具体是哪种由编译器决定。

2.1.2 类型转换

  • 当我们把一个非布尔类型的算术值赋给布尔类型时,初始值为0则结果为false,否则结果为true。
  • 当我们把一个布尔值赋给非布尔类型时,初始值为fa1se则结果为0,初始值为true则结果为1。
  • 当我们把一个浮点数赋给整数类型时,进行了近似处理。结果值将仅保留浮点数中小数点之前的部分。
  • 当我们把一个整数值赋给浮点类型时,小数部分记为0。如果该整数所占的空间超过了浮点类型的容量,精度可能有损失。
  • 当我们赋给无符号类型一个超出它表示范围的值时,结果是初始值对无符号类型表示数值总数取模后的余数。例如,8比特大小的unsigned char可以表示0至255区间内的值,如果我们赋了一个区间以外的值,则实际的结果是该值对256取模后所得的余数。因此,把-1赋给8比特大小的unsigned char所得的结果是255。
  • 当我们赋给带符号类型一个超出它表示范围的值时,结果是未定义的(undefined)。此时,程序可能继续工作、可能崩溃,也可能生成垃圾数据。

含有无符号类型的表达式

例如,当一个算术表达式中既有无符号数又有int值时,那个int值就会转换成无符号数。

unsigned u = 10;
int i = -42;
std::cout << i + i << std::endl; // 输出-84
std::cout << u + i << std::endl; // 如果int占32位,输出4294967264

当从无符号数中减去一个值时,不管这个值是不是无符号数,我们都必须确保结果不能是一个负值:

unsigned u1 = 42, u2 = 10;
std::cout << u1 - u2 << std::endl; // 正确:输出32
std::cout << u2 - u1 << std::endl; // 正确:不过结果是取模后的值

2.1.3 字面值常量

整型和浮点型字面值

我们可以将整型字面值写作十进制数、八进制数或十六进制数的形式。以0开头的整数代表八进制数,以0x或0X开头的代表十六进制数。

尽管整型字面值可以存储在带符号数据类型中,但严格来说,十进制字面值不会是负数。如果我们使用了一个形如-42的负十进制字面值,那个负号并不在字面值之内,它的作用仅仅是对字面值取负值而已。

浮点型字面值表现为一个小数或以科学计数法表示的指数,其中指数部分用E或e标识。默认的,浮点型字面值是一个double。

字符和字符串字面值

由单引号括起来的一个字符称为char型字面值,双引号括起来的零个或多个字符则构成字符串型字面值。

字符串字面值的类型实际上是由常量字符构成的数组。编译器在每个字符串的结尾处添加一个空字符('\0'),因此,字符串字面值的实际长度要比它的内容多1。例如,字面值'A'表示的就是单独的字符A,而字符串"A"则代表一个字符的数组,该数组包含两个字符:一个是字母A、零一个是空字符。

如果两个字符串字面值位置紧邻且仅由空格、缩进和换行符分隔,则它们实际上是个整体。

std::cout << "a really, really long string literal "
             "that spans two lines" << std::endl;

转义序列

有两类字符程序员不能直接使用:一类是不可打印的字符,如退格或其他控制字符,因为它们没有可视的图符:另一类是在C++语言中有特殊含义的字符(单引号、双引号、问号、反斜线)。在这些情况下需要用到转义序列,转义序列均以反斜线作为开始,C++语言规定的转义序列包括:

换行符 \n
横向制表符 \t
报警(响铃)符 \a
纵向制表符 \v
退格符 \b
双引号 \"
反斜线 \\
问号 \?
单引号 \'
回车符 \r
进纸符 \f

在程序中,转义序列被当作一个字符使用

指定字面值的类型

通过添加表中所列的前缀和后缀,可以改变整型、浮点型和字符型字面值的默认类型。

字符和字符串字面值

前缀 含义 类型
u Unicode16字符 char16_t
U Unicode32字符 char32_t
L 宽字符 wchar_t
u8 UTF-8 char

整型字面值

后缀 最小匹配类型
u or U unsigned
l or L long
ll or LL long long

浮点型字面值

后缀 最小匹配类型
f or F float
l or L double

布尔字面值和指针字面值

true和false是布尔类型的字面值。

nullptr是指针类型的字面值。