C++官方参考链接:Constants - C++ Tutorials (cplusplus.com)
常量
常量是具有固定值的表达式。
字面量
字面量是最明显的常量。它们用于表示程序源代码中的特定值。在前面的章节中,我们已经使用了一些方法来给变量赋特定的值,或者表达我们想要程序输出的消息,例如,当我们编写:
a = 5;
这段代码中的5是一个字面量常量。
字面量常量可以分为:整型、浮点型、字符型、字符串型、布尔型、指针型和用户定义的字面量。
整型数字
1776
707
-273
这些是标识整数值的数值常量。注意,它们没有包含在引号或任何其他特殊字符中;它们是一组简单的连续数字,用十进制表示一个整数;例如,1776总是表示1776的值。
除了十进制数字(我们大多数人每天都在使用的数字),C++还允许使用八进制数字(以8为基数)和十六进制数字(以16为基数)作为字面量常量。对于八进制字面量,数字前面会有一个0(零)字符。对于十六进制,它们前面都有字符0x (0,x)。例如,下面的字面量常量彼此等价:
75 // decimal
0113 // octal
0x4b // hexadecimal
所有这些都代表同一个数字:75分别以10为基数表示、以8为基数和以16为基数表示。
这些字面量常量有一个类型,就像变量一样。默认情况下,整型字面值为int类型。但是,可以将某些后缀加到整数字面值后指定不同的整数类型:
Suffix | Type modifier |
---|---|
u or U |
unsigned |
l or L |
long |
ll or LL |
long long |
unsigned可以与其他两个中的任意一个以任意顺序组合,形成unsigned long或unsigned long long。
例如:
75 // int
75u // unsigned int
75l // long
75ul // unsigned long
75lu // unsigned long
在上述所有情况下,后缀可以使用大写字母或小写字母指定。
浮点数字
它们表示实数,带有小数和/或指数。它们可以包含一个小数点,一个e字符(表示“X为指数,10为底数”,其中X是e字符后面的整数值),或者同时包含一个小数点和一个e字符:
3.14159 // 3.14159
6.02e23 // 6.02 x 10^23
1.6e-19 // 1.6 x 10^-19
3.0 // 3.0
这是用C++表示的四个有效的数字,都带有小数。第一个数字是PI,第二个是阿伏伽德罗的数字,第三个是电子的电荷(一个非常小的数字)——它们都是近似的——最后一个是用浮点字面量表示的数字3。
浮点字面量的默认类型是double。float或long double的浮点字面量可以通过添加以下后缀之一来指定:
Suffix | Type |
---|---|
f or F |
float |
l or L |
long double |
例如:
3.14159L // long double
6.02e23f // float
任何可以是浮点数值常量的一部分的字母(e、f、l)都可以用小写字母或大写字母书写,意义没有区别。
字符和字符串字面量
字符和字符串字面量用引号括起来:
'z'
'p'
"Hello world"
"How do you do?"
前两个表达式表示单字符字面量,后两个表示由几个字符组成的字符串字面量。请注意,为了表示单个字符,我们将其括在单引号(')中,而为了表示一个字符串(通常由多个字符组成),我们将字符括在双引号(")中。
单字符和字符串字面量都需要用引号括起来,以区别于可能的变量标识符或保留的关键字。注意这两个表达的区别:
x
'x'
在这里,x单独指的是一个标识符,比如变量或复合类型的名称,而'x'(用单引号括起来)指的是字符字面量'x'(表示小写x字母的字符)。
字符和字符串字面量也可以表示在程序源代码中很难或不可能表示的特殊字符,如换行符(\n)或制表符(\t)。这些特殊字符前面都有一个反斜杠字符(\)。
这里有一个单字符转义码列表:
转义代码 描述
\n 换行符
\r 回车
\t 水平制表符
\v 垂直制表符
\b 退格
\f 换页
\a 警报(嘟)
\' 单引号(')
\" 双引号(")
\? 问号(?)
\\ 反斜杠(\)
例如
'\n'
'\t'
"Left \t Right"
"one\ntwo\nthree"
在内部,计算机用数字代码表示字符:最典型的是,它们使用ASCII字符编码系统的一种扩展(参考ASCII代码(ASCII code )获取更多信息)。字符也可以通过书写反斜杠字符(\)和表示为八进制(8为基数)或十六进制(16为基数)数字的代码来用字面量表示。对于八进制值,反斜杠后面直接跟着数字;而对于十六进制,在反斜杠和十六进制数字之间插入一个x字符(例如:\x20或\x4A)。
可以通过一个或多个空白(包括制表符、换行符和其他有效的空白字符)将多个分隔的字符串字面量连接起来,形成单个字符串字面量。例如:
"this forms" "a single" " string "
"of characters"
上面的字符串字面量相当于:
"this formsa single string of characters"
请注意,引号内的空格是字面量的一部分,而引号外的空格不是。
一些程序员还使用一种技巧将长字符串字面量包含在多行中:在C++中,行尾的反斜杠(\)被认为是行延续字符,它将该行和下一行合并成一行。因此有以下代码:
x = "string expressed in \
two lines"
相当于:
x = "string expressed in two lines"
上面描述的所有字符字面量和字符串字面量都由char类型的字符组成。可以使用以下前缀之一指定不同的字符类型:
前缀 字符类型
u char16_t
U char32_t
L wchar_t
注意,与整数字面值的类型后缀不同,这些前缀是区分大小写的:小写表示char16_t,大写表示char32_t和wchar_t。
对于字符串字面量,除了上面的u、U和L之外,还有两个额外的前缀:
前缀 描述
u8 字符串字面量在可执行文件中使用UTF-8编码
R 字符串字面量是一个原始字符串
在原始字符串中,反斜杠和单引号和双引号都是有效的字符;字面量的内容由一个初始的R"sequence(和一个常量)sequence"分隔,其中sequence是任何字符序列(包括空序列)。字符串的内容位于圆括号内,忽略分隔序列本身。例如:
R"(string with \backslash)"
R"&%$(string with \backslash)&%$"
上面的两个字符串等价于"string with \\backslash"。前缀R可以与其他任何前缀组合,如u、L或u8。
其他字面量
C++中有三个关键字字面量:true,false和nullptr:
*true和false是bool类型变量的两个可能值。
*nullptr是空指针值。
bool foo = true;
bool bar = false;
int * p = nullptr;
类型的常量表达式
有时,给一个常量赋一个名称只是为了方便:
const double pi = 3.1415926;
const char tab = '\t';
然后,我们可以使用这些名称,而不是它们定义的字面量:
#include <iostream>
using namespace std;
const double pi = 3.14159;
const char newline = '\n';
int main ()
{
double r=5.0; // radius
double circle;
circle = 2 * pi * r;
cout << circle;
cout << newline;
}
输出:
预处理器定义(#define)
命名常量值的另一种机制是使用预处理器定义。它们的形式如下:
#define identifier replacement
在这个指令之后,代码中出现的任何identifer都被解释为replacement,其中replacement是任何字符序列(直到行结束)。这种替换由预处理器执行,并且发生在程序编译之前,因此导致某种盲目的替换:所涉及的类型或语法的有效性不进行任何检查。
例如:
#include <iostream>
using namespace std;
#define PI 3.14159
#define NEWLINE '\n'
int main ()
{
double r=5.0; // radius
double circle;
circle = 2 * PI * r;
cout << circle;
cout << NEWLINE;
}
输出:
注意,#define行是预处理器指令,因此是单行指令——与C++语句不同——不要求在行结束使用分号(;);指令会自动扩展到行结束。如果分号包含在该行中,它是replacement序列的一部分,并且也包含在所有被替换的出现中。