C++中的literal和C中的constant差异
在 C++ 和 C 语言中,"literal"(字面值)和 "constant"(常量)的概念有显著差异,主要体现在术语定义、类型系统和语言特性上。以下是基于 C++14 和 C11 标准的详细对比分析:
1. 术语定义差异
|
概念 |
C++ (ISO/IEC 14882:2014) |
C (ISO/IEC 9899:2011) |
|---|---|---|
|
Literal |
直接表示固定值的符号(token) |
无独立定义,属于常量的一种形式 |
|
Constant |
广义常量(包括字面值、const变量等) |
所有不可修改的值(包括字面值、枚举常量等) |
-
C++ 明确区分:
-
Literal:源代码中直接书写的固定值(如
42,"text") -
Constant:更广泛的概念,包括:
-
字面值
-
const/constexpr变量 -
枚举常量
-
常量表达式结果
-
-
-
C 中:
-
"Constant" 是统称,涵盖:
-
字面值(Literals)
-
枚举常量(Enumeration constants)
-
#define宏定义的常量 -
const限定的变量
-
-
2. 类型系统差异
整数字面值
|
字面值 |
C++ 类型规则 |
C 类型规则 |
|---|---|---|
|
|
最小匹配类型: |
同 C++ |
|
|
最小匹配类型: |
无符号类型优先级更高 |
关键区别:
C 对十六进制/八进制字面值的无符号性处理更激进(如 0xFFFF在 C 中默认为 unsigned int,而 C++ 可能为 int)。
字符/字符串字面值
|
字面值 |
C++ |
C |
|---|---|---|
|
|
类型 |
类型 |
|
|
类型 |
类型 |
关键区别:
-
C 中字符串字面值可尝试修改(尽管是未定义行为):
char* str = "hello"; // C 允许(但修改会UB) str[0] = 'H'; // 未定义行为! -
C++ 禁止:
const char* str = "hello"; // 必须加 const // str[0] = 'H'; // 编译错误
3. 特有字面值类型
|
字面值类型 |
C++ |
C |
|---|---|---|
|
布尔字面值 |
|
无(C99 用 |
|
指针字面值 |
|
|
|
用户自定义字面值 |
支持(如 |
不支持 |
|
原始字符串字面值 |
支持( |
不支持 |
4. 常量表达式能力
|
特性 |
C++ |
C |
|---|---|---|
|
编译时计算 |
|
仅支持简单常量表达式(C11 有 |
|
数组大小 |
可用 |
只能用字面值或枚举常量 |
|
模板元编程 |
依赖字面值和常量表达式 |
不支持 |
示例:
// C++
constexpr int size = 10;
int arr[size]; // 合法
// C
#define SIZE 10 // 必须用宏或枚举
int arr[SIZE]; // 合法
5. 标准中的具体位置
-
C++14:
-
§2.13 [lex.literal]:字面值定义和分类
-
§5.19 [expr.const]:常量表达式规则
-
§7.1.5 [dcl.constexpr]:
constexpr说明符
-
-
C11:
-
§6.4.4:常量(包括字面值)
-
§6.6:常量表达式
-
§6.7.2.1:枚举常量
-
6. 代码行为对比示例
示例 1:字符串修改
// C 语言(编译通过但运行时未定义行为)
#include <stdio.h>
int main() {
char* s = "hello";
s[0] = 'H'; // 未定义行为!
printf("%s\n", s);
}
// C++(编译错误)
int main() {
const char* s = "hello";
// s[0] = 'H'; // 错误:尝试修改常量
}
示例 2:布尔类型
// C99(需要stdbool.h)
#include <stdbool.h>
bool flag = true; // 实际是宏:#define true 1
// C++
bool flag = true; // 原生布尔类型
示例 3:空指针
// C
int* ptr = NULL; // #define NULL ((void*)0)
// C++
int* ptr = nullptr; // 类型安全的空指针
总结:核心差异
|
维度 |
C++ Literal |
C Constant |
|---|---|---|
|
术语定位 |
独立概念(直接值表示) |
"常量"的子集 |
|
类型安全 |
更强(如字符串只读、 |
较弱(字符串可修改、 |
|
扩展性 |
支持用户自定义字面值 |
不支持 |
|
布尔/空指针 |
原生支持 |
通过宏模拟 |
|
常量表达式 |
强大的 |
仅基础编译时计算 |
|
字符字面值 |
类型 |
类型 |
理解这些差异对编写跨语言代码至关重要,尤其在涉及类型转换、内存操作和编译时计算时。
更多推荐


所有评论(0)