Skip to content

Commit e29c753

Browse files
committed
Optimize Article
1 parent 52c3f26 commit e29c753

File tree

3 files changed

+154
-1
lines changed

3 files changed

+154
-1
lines changed

source/Language Core/Chapter-2/Section-03.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ short a = 123, b = 456, c = 789;
5656
* 变量名中只能使用英文字母、数字、下划线 (_) 来命名。
5757
* 变量名的第一个字符禁止使用数字。
5858
* 变量名严格区分⼤⼩写,例如"Name"和"name"是不同的变量。
59-
* 禁止使用 C++ 中的任意关键字作为变量名称
59+
* 禁止使用 C++ 中的任意[关键字](https://cppreference.com/w/cpp/keywords.html)作为变量名称
6060

6161
**通用语法**:
6262

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
# 常量
2+
3+
常量与变量大致类似,都是为内存中的数据进行命名标记。但不同的是常量一旦初始化后,不允许通过该名字修改对象。
4+
5+
常量的实现方式主要包括:
6+
7+
- 宏(#define,预处理阶段)
8+
- const(运行期只读)
9+
- constexpr(编译期常量)
10+
11+
## 宏常量
12+
13+
宏常量事实上并不算是一个常量而是在预处理阶段的文本替换。
14+
15+
```CPP
16+
#define PI 3.14 // 在预处理阶段代码中的 PI 会被替换为 3.14
17+
```
18+
19+
```CPP
20+
double x = PI * 2;
21+
// 替换
22+
double x = 3.14 * 2;
23+
```
24+
25+
```{caution}
26+
宏常量没有类型也就是说编译器根本不知道你定义的数据到底是什么类型的数据。
27+
28+
同时宏常量也没有作用域极大可能造成全局污染。
29+
```
30+
31+
在什么情况下需要使用宏常量?
32+
33+
- 条件编译:
34+
35+
```CPP
36+
#define DEBUG
37+
38+
#ifdef DEBUG
39+
// 在调试模式下执行特定内容
40+
#endif
41+
```
42+
43+
- 系统适配:
44+
45+
```CPP
46+
#ifdef _WIN32
47+
// Windows 平台执行特定代码
48+
#elif defined(__linux__)
49+
// Linux 平台执行特定代码
50+
#endif
51+
```
52+
53+
- 编译器适配
54+
- 架构适配 ……
55+
56+
## 普通常量
57+
58+
普通常量其实就是一个只读的变量,定义普通常量需要使用 **`const`** 关键字。
59+
60+
定义语法:
61+
62+
```CPP
63+
const 数据类型 常量名称 = 常量的值;
64+
```
65+
66+
可以理解为就是在变量的前面增加了 `const`
67+
68+
普通常量有数据类型、作用域、编译器检查相比宏常量更加安全。
69+
70+
```{caution}
71+
需要注意的是对于下方这种定义,编译器在编译的时候不保证知道常量的值。
72+
73+
```CPP
74+
const int x = rand(); // rand() 随机数函数,返回伪随机数。
75+
```
76+
77+
普通常量使用场景:
78+
79+
- 函数参数:
80+
81+
```CPP
82+
void foo(const std::string& s); // 防止参数被修改
83+
```
84+
85+
- 只读变量:
86+
87+
```CPP
88+
const int max_users = 1000;
89+
```
90+
91+
- 类成员 ……
92+
93+
## 编译期常量
94+
95+
自 C++ 11 起支持使用 **`constexpr`** 定义常量,它的本质就是在编译阶段就确定的值。
96+
97+
定义语法:
98+
99+
```CPP
100+
constexpr 数据类型 常量名称 = 常量的值;
101+
```
102+
103+
constexpr 必须编译期可计算,编译器可将其极限的优化。
104+
105+
使用场景:
106+
107+
- 编译期计算:
108+
109+
```CPP
110+
constexpr int square(int x) {
111+
return x * x;
112+
}
113+
114+
constexpr int a = square(5);
115+
```
116+
117+
- 数组大小:
118+
119+
```CPP
120+
constexpr int size = 100;
121+
int arr[size];
122+
```
123+
124+
从编译器视角看 const 与 constexpr 的实际区别:
125+
126+
- const 只保证值是只读不能修改的,而无法保证这个值在编译期一定存在。
127+
128+
例如:
129+
130+
```CPP
131+
const int x = rand(); // 合法但 x 的值只有在运行期才知道
132+
```
133+
134+
- constexpr 编译期就必须确定值
135+
136+
例如:
137+
138+
```CPP
139+
constexpr int a = 10; // 能在编译阶段算出来否则直接报错
140+
```
141+
142+
## 如何选择
143+
144+
1. 类型安全 + 普通常量: const
145+
2. 追求性能 / 编译期优化: constexpr
146+
3. 跨平台 / 编译控制: #define
147+
148+
优先级: 在现代 C++ 中,优先选择 constexpr,其次 const,尽量避免使用宏来定义常量。
149+
150+
- 能 constexpr 就 constexpr
151+
- 需要运行时值但不希望修改 → const
152+
- 宏只用于条件编译或平台适配

source/Language Core/Chapter-2/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@
66
Section-01
77
Section-02
88
Section-03
9+
Section-04
910
```

0 commit comments

Comments
 (0)