常量
现在我们需要接触一个新的术语叫做“常量”。在 C++ 中,常量(Constant)的定义是指那些在编译期间就能确定的值,且在运行期间这个确定的值不会发生变化。
说起来很抽象,什么叫编译期间就能确定的值呢?举个例子来看看:
42
你现在看到了一个数 42
。这个值在编译期间就能确定,它就是 42
,不是别的数。而且运行期间这个数也不可能改变——不会说到了运行期间 42
这个东西的含义就不是“四十二”了而是“五十六”了,这个不可能。因此 42
就是一个常量。
其实我们现在已经遇到了许多常量了。像 42
这种,你一看就知道它是什么值的常量,叫做字面量。
字面量
字面量(Literal)是指在 C++ 代码中,它的写法能直接体现它所表达的值的常量。比如刚才的 42
就是——写作 42
,含义就是“四十二”这个数。在 C++ 中,字面量也拥有其类型。比如 42
的类型就是 int
类型。
整型字面量
整型字面量主要分为十进制和其它进制两种写法。首先来看十进制写法。
在十进制下,字面量通过一种“推导”的规则来确定其类型。这个推导的规则是:永远推导为有符号类型,且优先推导为 int
类型;若不足将推导为更长的有符号类型。比如:
123
将被推导为int
类型的字面量,这是默认的;1000000000000000
将被推导为long long
类型,因为int
和long
都“放不下”。
那么如何写一个无符号类型的十进制字面量呢?你可以通过后缀来指定字面量的类型。比如:
42; // 这是 int 型的字面量 42
42u; // 这是 unsigned int 型的字面量 42
42U; // 这也是 unsigned int 型的字面量 42
42l; // 这是 long 型的字面量 42
42L; // 这也是 long 型的字面量 42
42ll; // 这是 long long 型的字面量 42
42ul; // 这是 unsigned long 型的
42ull; // 这是 unsigned long long 型的
// 注:字面量不包括分号;,此处加上分号只为演示作用。
总结下来,就是:
u
或U
后缀:指明该整数为无符号unsigned
类型;l
或L
后缀:指明该整数为long
类型;ll
或LL
后缀:指明该整数为long long
类型;- 其中无符号后缀和另外两个还可以组合为
ul
和ull
等后缀。
是的,没有
short
类型的字面量。
实际上没有负的字面量;所谓的
-1
其实是一元减运算符-
作用于操作数1
的结果。
除了十进制写法,还有二进制、八进制和十六进制的写法。它们分别这样写:
0b101010; // 以 0b 开头的就是二进制数
052; // 以 0 开头的就是八进制数
0x2a; // 以 0x 开头的就是十六进制数
较早的编译器可能不支持二进制整型字面量。
其中,十六进制数中的字母 abcde
换成大写也可以, 0x
写作大写的 0X
也可以。这些进制也可以加上 u
l
或者 ll
的后缀来指明类型,但是它们类型推导的规则与十进制略有不同(即可以推导为无符号类型,这里不再叙述)。下面完整的代码演示了这些进制的写法:
需要注意这些不过是字面量写法上的不同,实际的值是一致的;因此上面代码中五个 int
型变量的初始化值实际是完全相同的。输出的结果当然也是相同的:
42 42 42 42 42
浮点类型字面量
我们已经遇到过很多次浮点类型的字面量了,比如经常用于举例的 3.14
。在 C++ 中,浮点类型字面量有两种写法:一是带有小数点的数,比如 3.14
2.72
等。
小数点不一定位于“中间”。位于两侧也是合法的,会自动在对应位置补上
0
。比如.5
就代表0.5
,1.
就代表1.0
。
第二是带有指数符号 e
的数。这是什么意思呢?你只需要把 xey
理解为 就可以了。比如:
1e10
指 ,即 10000000000;1.3e-5
指 ,即 0.000013。
和整型不同的是,浮点类型字面量没有自动推导类型的说法,不论是带小数点还是指数符号的字面量,统统理解为 double
类型。那么怎么样描述一个 float
类型或者 long double
类型的字面量呢?需要通过后缀来实现。
f
或F
后缀指明字面量是float
类型;l
或L
后缀指明字面量是long double
类型。
比如 3.14f
就是 float
类型的字面量; 1e7L
就是 long double
类型的字面量。
布尔类型字面量
布尔类型就很简单啦,因为它只有真和假两种取值。所以 true
和 false
就是唯二的布尔类型字面量了——正如之前所述,它们也是 C++ 关键字。
字符类型字面量
字符类型我们并没有完全学习,所以这里只说 char
类型的字面量。显然我们已经有所了解了,就是单引号引起的字符啦:
'非转义字符' '反斜杠开头的转义字符'
非转义字符比如 '@'
'#'
'0'
'g'
都是 char
类型的字面量。转义字符如 '\n'
'\t'
'\''
'\\'
也是 char
类型的字面量。
还有吗?
当然还有。我们一直用的双引号引起的“一句话”(如 "Hello, world!"
)也是字面量——因为它所表示的内容体现了它的含义——输出的时候就是输出这句话。这个“一句话”的真正叫法是字符串字面量(String literal),但是更多的需要等到字符串章节再做介绍了。
其它常量
除了字面量,还有许多东西满足常量的定义。比如字面量组成的简单的式子:
1 + 1
事实上,完全由字面量组成的式子的结果完全可以在编译期间就确定——这个式子的值为 2
,毋庸置疑。那么在运行的过程中, 1 + 1
这个式子的值会发生变化吗?当然不会,一直是 2
。那么 1 + 1
就是一个常量。
还有一些经常会见到的常量,我将在下一节中介绍。