一个形如42的值被称作字面值常量(literal),这样的值一望而知。每个字面值常量都对应一种数据类型,字面值常量的形式和值决定了它的数据类型。
我们可以将整型字面值写作十进制(基数为10)、八进制(基数为8)或十六进制(基数为16)数的形式。以0开头的整数代表八进制数,以0x或0X开头的代表十六进制数。
整型字面值具体的数据类型由它的值和符号决定。默认情况下,十进制字面值的带符号数,八进制和十六进制字面值既可能是带符号的也可能是无符号的。十进制字面值的类型是int、long和long long中尺寸最小的那个(例如,三者当中最小是int),当然前提是这种类型要能容纳下当前的值。八进制和十六进制字面值的类型是能容纳其数值的int、unsigned int、long、unsigned long、long long和unsigned long long中的尺寸最小者。如果一个字面值连与之关联的最大的数据类型都放不下,将产生错误。类型short没有对应的字面值。
尽管整型字面值可以存储在带符号数据类型中,但严格来说,十进制字面值不会是负数。如果我们使用了一个形如-42的负十进制字面值,那个负号并不在字面值之内,它的作用仅仅是对字面值取负值而已。
指定字面值的类型列表如下:
注:以上内容主要整理自《C++ Primer(Fifth Edition)》
测试代码如下所示:
int test_literal_1()
{
int d = 42; // decimal notation
int o = 052; // octal notation
int x = 0x2a; // hexadecimal notation
int X = 0X2A; // hexadecimal notation
std::cout << "d:" << d << ", o:" << o << ", x:" << x << ", X:" << X << "\n"; // d:42, o:42, x:42, X:42
auto v1 = 42U; // or 42u: 将从unsigned int, unsigned long和unsigned long long中选择能匹配的空间最小的一个作为其数据类型
auto v2 = 42L; // or 42l: 字面值的类型至少是long
auto v3 = 42UL; // or 42ul: 数据类型将根据具体数值情况或者取unsigned long,或者取unsigned long long
std::cout << "v1:" << v1 << ", v2:" << v2 << ", v3:" << v3 << "\n"; // v1:42, v2:42, v3:42
std::cout << "v1 type:" << typeid(v1).name() << ", v2 type:" << typeid(v2).name() << ", v3 type:" << typeid(v3).name() << "\n"; // v1 type:unsigned int, v2 type:long, v3 type:unsigned long
return 0;
}
C++14中增加了对二进制字面值常量(binary literal)的支持:以2为基数的数字,数字间可用分隔符’分隔,带有0b或0B前缀后面跟着一个或多个二进制数字(0, 1)。
自C++14起,在整数和浮点数序列中,任意两位数字之间允许使用可选的分隔符’,在确定字面值常量时将忽略它们。
测试代码如下:
int test_literal_14_1()
{
auto v1 = 0b110;
auto v2 = 0b1111'1111;
auto v3 = 0B1111'1111;
std::cout << "v1:" << v1 << ", v2:" << v2 <<", v3:" << v3 << "\n"; // v1:6, v2:255, v3:255
std::cout << "v1 type:" << typeid(v1).name()
<< ", v2 type:" << typeid(v2).name()
<< ", v3 type:" << typeid(v3).name() << "\n"; // v1 type:int, v2 type:int, v3 type:int
auto v4 = 0b10U;
auto v5 = 0B10L;
auto v6 = 0b0000'0010ULL;
std::cout << "v4:" << v4 << ", v5:" << v5 << ", v6:" << v6 << "\n"; // v4:2, v5:2, v6:2
std::cout << "v4 type:" << typeid(v4).name()
<< ", v5 type:" << typeid(v5).name()
<< ", v6 type:" << typeid(v6).name() << "\n"; // v4 type:unsigned int, v5 type:long, v6 type:unsigned __int64
return 0;
}
执行结果如下所示:注意:std::type_info::name在windows和linux输出的差异
GitHub:https://github.com/fengbingchun/Messy_Test