常量

现在我们需要接触一个新的术语叫做“常量”。在 C++ 中,常量(Constant)的定义是指那些在编译期间就能确定的值,且在运行期间这个确定的值不会发生变化。

说起来很抽象,什么叫编译期间就能确定的值呢?举个例子来看看:

42

你现在看到了一个数 42 。这个值在编译期间就能确定,它就是 42 ,不是别的数。而且运行期间这个数也不可能改变——不会说到了运行期间 42 这个东西的含义就不是“四十二”了而是“五十六”了,这个不可能。因此 42 就是一个常量。

其实我们现在已经遇到了许多常量了。像 42 这种,你一看就知道它是什么值的常量,叫做字面量。

字面量

字面量(Literal)是指在 C++ 代码中,它的写法能直接体现它所表达的值的常量。比如刚才的 42 就是——写作 42 ,含义就是“四十二”这个数。在 C++ 中,字面量也拥有其类型。比如 42 的类型就是 int 类型。

整型字面量

整型字面量主要分为十进制和其它进制两种写法。首先来看十进制写法。

在十进制下,字面量通过一种“推导”的规则来确定其类型。这个推导的规则是:永远推导为有符号类型,且优先推导为 int 类型;若不足将推导为更长的有符号类型。比如:

  • 123 将被推导为 int 类型的字面量,这是默认的;
  • 1000000000000000 将被推导为 long long 类型,因为 intlong 都“放不下”。

那么如何写一个无符号类型的十进制字面量呢?你可以通过后缀来指定字面量的类型。比如:

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 型的
// 注:字面量不包括分号;,此处加上分号只为演示作用。

总结下来,就是:

  • uU 后缀:指明该整数为无符号 unsigned 类型;
  • lL 后缀:指明该整数为 long 类型;
  • llLL 后缀:指明该整数为 long long 类型;
  • 其中无符号后缀和另外两个还可以组合为 ulull 等后缀。

是的,没有 short 类型的字面量。

实际上没有负的字面量;所谓的 -1 其实是一元减运算符 - 作用于操作数 1 的结果。

除了十进制写法,还有二进制、八进制和十六进制的写法。它们分别这样写:

0b101010;  // 以 0b 开头的就是二进制数
052;       // 以 0 开头的就是八进制数
0x2a;      // 以 0x 开头的就是十六进制数

较早的编译器可能不支持二进制整型字面量。

其中,十六进制数中的字母 abcde 换成大写也可以, 0x 写作大写的 0X 也可以。这些进制也可以加上 u l 或者 ll 的后缀来指明类型,但是它们类型推导的规则与十进制略有不同(即可以推导为无符号类型,这里不再叙述)。下面完整的代码演示了这些进制的写法:

#include <iostream>
using namespace std;
int main() {
    int d{42};        // 十进制
    int o{052};       // 八进制
    int x{0x2a};      // 十六进制
    int X{0X2A};      // 十六进制(大写)
    int b{0b101010};  // 二进制
    cout << d << " " << o << " " << x << " " << X << " " << b << endl;
}

需要注意这些不过是字面量写法上的不同,实际的值是一致的;因此上面代码中五个 int 型变量的初始化值实际是完全相同的。输出的结果当然也是相同的:

42 42 42 42 42

浮点类型字面量

我们已经遇到过很多次浮点类型的字面量了,比如经常用于举例的 3.14 。在 C++ 中,浮点类型字面量有两种写法:一是带有小数点的数,比如 3.14 2.72 等。

小数点不一定位于“中间”。位于两侧也是合法的,会自动在对应位置补上 0 。比如 .5 就代表 0.51. 就代表 1.0

第二是带有指数符号 e 的数。这是什么意思呢?你只需要把 xey 理解为 x×10yx\times 10^y就可以了。比如:

  • 1e101×10101\times 10^{10},即 10000000000;
  • 1.3e-51.3×1051.3\times 10^{-5},即 0.000013。

和整型不同的是,浮点类型字面量没有自动推导类型的说法,不论是带小数点还是指数符号的字面量,统统理解为 double 类型。那么怎么样描述一个 float 类型或者 long double 类型的字面量呢?需要通过后缀来实现。

  • fF 后缀指明字面量是 float 类型;
  • lL 后缀指明字面量是 long double 类型。

比如 3.14f 就是 float 类型的字面量; 1e7L 就是 long double 类型的字面量。

布尔类型字面量

布尔类型就很简单啦,因为它只有真和假两种取值。所以 truefalse 就是唯二的布尔类型字面量了——正如之前所述,它们也是 C++ 关键字。

字符类型字面量

字符类型我们并没有完全学习,所以这里只说 char 类型的字面量。显然我们已经有所了解了,就是单引号引起的字符啦:

'非转义字符'
'反斜杠开头的转义字符'

非转义字符比如 '@' '#' '0' 'g' 都是 char 类型的字面量。转义字符如 '\n' '\t' '\'' '\\' 也是 char 类型的字面量。

还有吗?

当然还有。我们一直用的双引号引起的“一句话”(如 "Hello, world!" )也是字面量——因为它所表示的内容体现了它的含义——输出的时候就是输出这句话。这个“一句话”的真正叫法是字符串字面量(String literal),但是更多的需要等到字符串章节再做介绍了。

其它常量

除了字面量,还有许多东西满足常量的定义。比如字面量组成的简单的式子:

1 + 1

事实上,完全由字面量组成的式子的结果完全可以在编译期间就确定——这个式子的值为 2 ,毋庸置疑。那么在运行的过程中, 1 + 1 这个式子的值会发生变化吗?当然不会,一直是 2 。那么 1 + 1 就是一个常量。

还有一些经常会见到的常量,我将在下一节中介绍。

最近更新:
代码未运行