“为推进进度,暂搁置浮点数的表示范围!”
每个字面值常量都对应一种数据类型,字面值常量的形式和值决定了它的数据类型。
整形和浮点型字面值
我们可以将整形字面值写作十进制数、八进制数、或十六进制数的形式。以0开头的整数代表八进制数,以0x或0X开头的代表十六进制数。例如,我们能用下面的任意一种形式来代表数值20:
20 /* 十进制 */ 024 /* 八进制 */ 0x4 /* 十六进制 */
整形字面值具体的数据类型由它的值和符号决定。默认情况下,十进制字面值是带符号数,八进制和十六进制字面值既可能是带符号的也可能是无符号的。十进制字面值的类型是int、long和long long中尺寸最小的那个,当然前提是这种类型要能容纳下当前的值。八进制和十六进制字面值的类型是能容纳其数值的int、unsigned int、long、unsigned long、long long和unsigned long long中尺寸的最小者。
当一个字面值连与之关联的最大的数据类型都放不下时,将会产生错误。类型short没有对应的字面值。
尽管整形字面值可以存储在带符号数据类型中,但严格来说,十进制字面值不会是负数。当我们使用了一个形如-42的负十进制字面值,那个负号并不在字面值之内,它的作用仅仅是对字面值取负值而已。
浮点型字面值表现为一个小数或以科学计数法表示的指数,其中指数部分用E或e标识:3.14159、3.14159E0、0.、0e0、.001等,默认的浮点型字面值是一个double。
整形和浮点型字面值的表示还可以通过后缀指定数据类型:
整形字面值 | 浮点型字面值 | ||
后缀 | 最小匹配类型 | 后缀 | 类型 |
u or U | unsigned | f or F | float |
l or L | long | l or L | long double |
ll or LL |
对于一个整形字面值来说,我们能分别指定他是否带符号以及占用多少空间。如果后缀中有U,则该字面值属于无符号类型,也就是说,以U为后缀的十进制数、八进制数、或十六进制数都将从unsigned int、unsigned long和unsigned long long中选择能匹配的空间最小的一个作为其数据类型。如果后缀中有L,则字面值的类型至少是long;如果后缀中有LL,则字面值的类型将是long long和unsigned long long中的一种。显然我们可以将U与L或LL合在一起使用。例如,以UL为后缀的字面值的数据类型将根据具体数值或者取unsigned long,或者取unsigned long long。
举例:
42ULL // 无符号整型字面值,类型是unsigned long long
1E-3F // 单精度浮点型字面值,类型是float
3.14159L // 扩展精度浮点型字面值,类型是long double
字符和字符串字面值
由单引号括起来的一个字符称为char型字面值,双引号括起来的零个或多个字符则构成字符串型字面值。
'a' // 字符字面值
"Hello World!" // 字符串字面值
字符串字面值的类型是由常量字符构成的数组(array)。由于编译器在每个字符串的结尾处添加了一个空字符('\0'),字符串字面值的实际长度要比它的内容多 1 。
字面值 'A' 表示的就是单独的字符A,而字符串 “A” 则代表了一个字符的数组,该数组包含两个字符:一个是字母A、另一个是空字符。
如果两个字符串字面值位置紧邻且仅由空格、缩进和换行符分隔,则它们实际上是一个整体。在实际使用时表现为:当书写的字符串字面值比较长、写在一行里不太合适时,就可以采取分开书写的方式,如下所示:
// 分开书写的字符串字面值
std::cout << "a really, really long string literal "
"that spans two lines" << std::endl;
在C++中,有两类字符程序员不能直接使用:一类是不可打印(nonprintable)的字符,如退格或其他控制字符,因为它们没有可视的图符;另一类是在C++语言中有特殊含义的字符(单引号、双引号、问号、反斜线)。在这些情况下需要用到转义序列(escape sequence),转义序列均以反斜线作为开始,C++语言规定的转义序列包括:
换行符 | \n | 横向制表符 | \t | 报警(响铃)符 | \a |
纵向制表符 | \v | 退格符 | \b | 双引号 | \" |
反斜线 | \\ | 问号 | \? | 单引号 | \' |
回车符 | \r | 进纸符 | \f |
在程序中,上述转义序列被当作一个字符使用:
std::cout << '\n' ; //转到新的一行
std::cout << "\tHi!\n"; //输出一个制表符,输出“Hi!”,转到新的一行
转义序列除了上述表示方法,还可以使用 \x 后紧跟一个或多个十六进制数字,或者 \ 后紧跟1个、2个或者3个八进制数字的形式进行表示,这样的表示方法叫做泛化的转义序列,其中数字部分表示的是字符对应的数值。
假设使用的是Latin-1字符集,以下是一些示例:
\7(响铃) \12(换行符) \40(空格)
\0(空格符) \115(字符M) \x4d(字符M)
我们可以像使用普通字符那样使用C++定义的转义序列:
std::cout << "Hi \x4dO\115!\n"; //输出Hi MOM!,转到新的一行
std::cout << '\115' << '\n'; //输出M,转到新的一行
注意:如果反斜线\后面跟着的八进制数字超过了3个,只有前3个数字与\构成转义序列。\x要用到后面跟着的所有数字。例如,"\1234"表示2个字符,即八进制数123对应的字符以及字符4;“\x1234”表示一个16位的字符,该字符由这4个十六进制数所对应的比特唯一确定(不过,大多数机器的char型数据占8位,所以这个可能会报措)。
一般来说,超过8位的十六进制字符都是与下表中某个前缀作为开头的扩展字符集一起使用的。
字符和字符串字面值 | ||
前缀 | 含义 | 类型 |
u | Unicode 16 字符 | char16_t |
U | Unicode 32 字符 | char32_t |
L | 宽字符 | wchar_t |
u8 | UTF-8(仅用于字符串字面常量) | char |
举例:
L'a' // 宽字符型字面值,类型是wchar_t
u8"hi!" // utf-8字符串字面值(utf-8 用8位编码一个Unicode字符)
布尔字面值和指针字面值
true 和 false 是布尔类型的字面值,如下所示;nullptr 是指针字面值,这个以后再说。
举例:bool test = false。