Skip to content

Commit 175fb4f

Browse files
committed
Optimize Article
1 parent 89f3cec commit 175fb4f

2 files changed

Lines changed: 186 additions & 22 deletions

File tree

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

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,18 @@
1010

1111
在 C++ 中,定义一个变量必须为其指定一个数据类型,如果没有指定数据类型则会出现错误。
1212

13-
**定义语法**: 数据类型   变量名称;
13+
**定义语法**:
14+
15+
```CPP
16+
数据类型 变量名称;
17+
```
1418

1519
```CPP
1620
short age; // 定义了一个名为 age 的变量,但没有对其进行初始化
1721
```
1822

1923
```{important}
20-
对于未进行初始化的变量其值也是未定义的(垃圾值)
24+
对于未进行初始化的变量其值也是未定义的(垃圾值),使用未初始化的变量会导致未定义行为。
2125
```
2226

2327
## 初始化变量
@@ -26,16 +30,24 @@ short age; // 定义了一个名为 age 的变量,但没有对其进行初始
2630

2731
**传统写法**
2832

29-
**定义且初始化语法**: 数据类型   变量名称   =   变量的值;
33+
**定义且初始化语法**:
34+
35+
```CPP
36+
数据类型 变量名称 = 变量的值;
37+
```
3038

3139
```CPP
3240
short age = 18; // 定义一个名为 age 的变量,并设定初始值 (默认) 为 18
3341
```
3442

35-
**现代写法**
43+
**现代写法(列表初始化)**:
44+
45+
```CPP
46+
数据类型 变量名称{变量的值};
47+
```
3648
3749
```CPP
38-
short age{18}; // 使用 { } 进行初始化
50+
short age{18};
3951
```
4052

4153
{ }(列表初始化) 是从 C++ 11 开始的核心语法,它的特性就是禁止 "隐式缩窄"。
@@ -60,15 +72,23 @@ int arr[]{1, 2, 3, 4};
6072

6173
## 多变量定义
6274

63-
**定义语法**: 数据类型   变量名称,   变量名称,   N+;
75+
**定义语法**:
76+
77+
```CPP
78+
数据类型 变量名称, 变量名称, N+;
79+
```
6480

6581
```CPP
6682
short a, b, c; // 在数据类型相同的情况下定义多个变量。
6783
```
6884

6985
## 多变量初始化
7086

71-
**初始语法**: 数据类型   变量名称   =   变量的值,   变量名称   = 变量的值,   N+;
87+
**初始语法**:
88+
89+
```CPP
90+
数据类型 变量名称 = 变量的值, 变量名称 = 变量的值, N+;
91+
```
7292

7393
```CPP
7494
short a = 123, b = 456, c = 789;

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

Lines changed: 159 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
- 宏(#define,预处理阶段)
88
- const(运行期只读)
99
- constexpr(编译期常量)
10+
- consteval
11+
- constinit
12+
- 枚举常量
1013

1114
## 宏常量
1215

@@ -71,19 +74,11 @@ const 数据类型 常量名称{值};
7174
7275
常量可以理解为就是在变量的前面增加了 `const` 关键字然后让变量从读写变成了只读。
7376
74-
普通常量有数据类型、作用域、编译器检查相比宏常量更加安全。
75-
76-
```{caution}
77-
需要注意的是对于下方这种定义,编译器在编译的时候不保证知道常量的值。
78-
79-
```CPP
80-
// rand() 随机数函数,返回伪随机数。
81-
const int x{rand()}; // 在编译期 x 的值未知,只有在运行期才知道。
82-
```
77+
普通常量有数据类型、作用域、编译器检查相比宏替换更加安全。
8378
8479
普通常量的常见使用场景:
8580
86-
- 函数参数保护:
81+
- 参数保护:
8782
8883
```CPP
8984
void foo(const std::string& s); // 防止函数内部修改参数
@@ -100,8 +95,9 @@ const int max_users{1000};
10095
自 C++ 11 起支持使用 **`constexpr`** 定义常量,用于定义必须在编译期就能确定值的常量。
10196
10297
定义语法:
103-
104-
constexpr   数据类型   常量名称{值};
98+
```CPP
99+
constexpr 数据类型 常量名称{值};
100+
```
105101

106102
```CPP
107103
constexpr int a{10};
@@ -148,10 +144,158 @@ constexpr int a{10}; // 能在编译阶段算出来否则直接报错
148144
constexpr int x{rand()}; // 编译失败,rand() 函数只有在运行期才会有返回值
149145
```
150146
147+
## consteval
148+
149+
自 C++ 20 起引入了consteval,用于定义必须在编译期执行的函数
150+
151+
代码演示:
152+
153+
```CPP
154+
consteval int square(int x) {
155+
return x * x;
156+
}
157+
158+
constexpr int a = square(5); // OK,编译期计算
159+
// int b = square(rand()); // 错误:square必须在编译期计算
160+
```
161+
162+
与 constexpr 不同,consteval 函数总是在编译期执行,不能用于运行期计算。
163+
164+
## constinit
165+
166+
constinit 同样是 C++ 20 引入的,用于确保变量在编译期初始化
167+
168+
代码演示:
169+
170+
```CPP
171+
constinit int x = 42; // 编译期初始化
172+
173+
// constinit int y = rand(); // 错误:必须编译期初始化
174+
```
175+
176+
与 const 和 constexpr 不同,constinit 变量在运行期可以修改
177+
178+
代码演示:
179+
180+
```CPP
181+
constinit int x = 42;
182+
x = 100; // constinit不影响运行期修改
183+
```
184+
185+
## 枚举常量
186+
187+
枚举(Enumeration)是 C++ 中一种用户自定义类型,用于定义一组命名的整型常量。它能让代码更具可读性、类型更安全,特别适合表示一组相关的离散值(如状态、方向、选项等)。
188+
189+
C++ 提供了两种枚举形式:
190+
191+
- 传统枚举(enum,C++98 起)
192+
- 枚举类(enum class / enum struct,C++11 起,推荐使用)
193+
194+
### 传统枚举
195+
196+
#### 基本定义与使用
197+
198+
代码演示:
199+
200+
```CPP
201+
// 定义一个表示颜色的枚举
202+
enum Color {
203+
Red, // 默认值为 0
204+
Green, // 自动递增为 1
205+
Blue // 自动递增为 2
206+
};
207+
208+
int main() {
209+
Color c = Red; // 使用枚举值
210+
211+
if (c == Red) {
212+
std::cout << "颜色是红色" << std::endl;
213+
}
214+
}
215+
```
216+
217+
#### 手动指定枚举值
218+
219+
你可以手动为枚举值指定底层整数值,未指定的会自动从最后一个指定值递增。
220+
221+
```CPP
222+
enum Status {
223+
OK = 0,
224+
Warning = 1,
225+
Error = 2,
226+
FatalError // 自动为 3
227+
};
228+
229+
// 也可以不连续指定
230+
enum Weekday {
231+
Monday = 1,
232+
Tuesday = 2,
233+
Wednesday = 3,
234+
Thursday = 4,
235+
Friday = 5,
236+
Saturday = 6,
237+
Sunday = 7
238+
};
239+
```
240+
241+
传统枚举虽然简单,但存在两个显著问题
242+
243+
作用域污染:
244+
245+
枚举值会直接暴露在枚举所在的作用域中,容易导致命名冲突
246+
247+
```CPP
248+
enum Color { Red, Green, Blue };
249+
enum TrafficLight { Red, Yellow, Green }; // 错误!Red 和 Green 重复定义
250+
```
251+
252+
隐式转换为 int:
253+
254+
枚举值会隐式转换为整数,可能导致类型不安全
255+
256+
```CPP
257+
enum Color { Red, Green, Blue };
258+
Color c = Red;
259+
260+
int num = c; // 隐式转换为 int(值为 0)
261+
if (c == 0) { // 直接和整数比较
262+
// ...
263+
}
264+
```
265+
266+
### 枚举类(enum class / enum struct)
267+
268+
为了解决传统枚举的问题,C++11 引入了枚举类(也叫 “强类型枚举”)。它是现代 C++ 中推荐使用的枚举形式。
269+
270+
#### 基本定义与使用
271+
272+
枚举类使用 enum class(或 enum struct,两者完全等价)
273+
274+
```CPP
275+
// 定义枚举类
276+
enum class Color {
277+
Red,
278+
Green,
279+
Blue
280+
};
281+
282+
int main() {
283+
// 访问枚举值时必须加上枚举类名::前缀
284+
Color c = Color::Red;
285+
286+
if (c == Color::Red) {
287+
std::cout << "颜色是红色" << std::endl;
288+
}
289+
}
290+
```
291+
151292
## 如何选择
152293
153-
1. 能在编译期确定的值 → 使用 constexpr
154-
2. 需要运行期确定但不希望修改 → 使用 const
155-
3. 仅用于编译控制(如平台/调试) → 使用 #define
294+
- 能在编译期确定的值 → 使用 constexpr
295+
- 需要运行期确定但不希望修改 → 使用 const
296+
- 仅用于编译控制(如平台 / 调试) → 使用 #define
297+
- 表示一组相关常量 → 使用枚举
298+
- 需要确保编译期初始化但运行期可修改 → 使用 constinit
299+
- 函数必须在编译期执行 → 使用 consteval
156300
157301
优先级: 在现代 C++ 中,优先选择 constexpr,其次 const,在现代 C++ 中,应避免使用宏定义常量。

0 commit comments

Comments
 (0)