Skip to content

Commit ca5543f

Browse files
docs(vol1): fix -Wall -Wextra warnings in ch06/07A exercise answers
练习答案代码质量修正,纯格式/调用/注释调整,零逻辑改动。 07A-pointer-essentials.md: - 练习1: sizeof/size_t 改用 %zu(原 %d 触发 -Wformat 警告) - 练习1: %p 参数加 (void*) 强转(标准要求 void*,消除 UB) - 练习1: 输出示例换真实地址格式,补 char=48 与栈地址间隔两点说明 - 练习2: size_t 索引改用 %zu;补 #include <stddef.h> 06-scope-and-storage.md: - 练习2: 让两个同名 static helper_a 各被模块公共函数调用(消除 unused-function 警告,顺便把"同名 static 互不干扰"演示得更透彻) - 练习3: config 改用 static 初始化器呼应题目提示,flag 只负责打印 全部 5 段经 -Wall -Wextra -std=c17 编译零警告、运行输出正确。
1 parent 76c6b9f commit ca5543f

2 files changed

Lines changed: 30 additions & 15 deletions

File tree

documents/vol1-fundamentals/c_tutorials/06-scope-and-storage.md

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -535,8 +535,9 @@ main.c
535535

536536
int main(void) {
537537

538+
a_greet(); // 调用 a 模块的公共函数,触发它内部的 helper_a
538539
printf("%d\n",kSharedValue); //输出应当是0
539-
set_kSharedValue(100);
540+
set_kSharedValue(100); // 内部会调用 b 模块自己的 helper_a
540541
printf("%d\n",kSharedValue); //输出应当是100
541542

542543
return 0;
@@ -550,6 +551,7 @@ a.h
550551
#define MODERNCPP_PRE8_2_A_H
551552
552553
extern int kSharedValue;
554+
void a_greet(void);
553555
554556
#endif //MODERNCPP_PRE8_2_A_H
555557
```
@@ -573,7 +575,12 @@ a.c
573575

574576
int kSharedValue = 0;
575577
static void helper_a(void) {
576-
printf("need help?");
578+
printf("need help?\n");
579+
}
580+
581+
// a.c 暴露的公共函数,内部调用文件私有的 helper_a
582+
void a_greet(void) {
583+
helper_a();
577584
}
578585
```
579586
@@ -586,9 +593,10 @@ b.c
586593
587594
588595
static void helper_a(void) {
589-
printf("need help?");
596+
printf("need help?\n");
590597
}
591598
void set_kSharedValue(int value) {
599+
helper_a();
592600
kSharedValue = value;
593601
}
594602
```
@@ -629,13 +637,14 @@ int main(void) {
629637
}
630638
631639
const Config* get_config(void) {
632-
static Config config;
640+
// config 用 static 初始化器:程序加载时一次性初始化,正好呼应题目说的
641+
// "static 局部变量只在第一次进入函数时被初始化"
642+
static Config config = {5, 500, "localhost"};
643+
// 但题目还要求第一次调用时打印 "Initializing..."——静态初始化器本身
644+
// 没有运行时钩子去打印,所以再用一个 static flag 控制只打印一次
633645
static int initialized = 0;
634646
if (!initialized) {
635647
printf("Initializing...\n");
636-
config.max_connections = 5;
637-
config.timeout_ms = 500;
638-
config.server_name = "localhost";
639648
initialized = 1;
640649
}
641650
return &config;

documents/vol1-fundamentals/c_tutorials/07A-pointer-essentials.md

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -280,22 +280,27 @@ int main(void) {
280280
double value_double = 0.0;
281281
char value_char = '0';
282282

283-
printf("(int) value:%d address:%p size:%d\n", value_int, &value_int, sizeof(int));
284-
printf("(double) value:%.2f address:%p size:%d\n", value_double, &value_double, sizeof(double));
285-
printf("(char) value:%d address:%p size:%d\n", value_char, &value_char, sizeof(char));
283+
printf("(int) value:%d address:%p size:%zu\n", value_int, (void*)&value_int, sizeof(int));
284+
printf("(double) value:%.2f address:%p size:%zu\n", value_double, (void*)&value_double, sizeof(double));
285+
printf("(char) value:%d address:%p size:%zu\n", value_char, (void*)&value_char, sizeof(char));
286286
return 0;
287287
}
288288

289289
```
290290
291-
输出结果可能为:
291+
输出结果可能为(地址每次运行都会变)
292292
293293
```text
294-
(int) value:0 address:00000000005ffe8c size:4
295-
(double) value:0.00 address:00000000005ffe80 size:8
296-
(char) value:48 address:00000000005ffe7f size:1
294+
(int) value:0 address:0x7ffd8cecdbec size:4
295+
(double) value:0.00 address:0x7ffd8cecdbf0 size:8
296+
(char) value:48 address:0x7ffd8cecdbeb size:1
297297
```
298298

299+
两点值得留意:
300+
301+
- `char``value` 显示成 `48`,因为 `'0'` 的 ASCII 码就是 48。C 语言里 `char` 本质上是一个小整数,用 `%d` 打印看到的就是它的整数值(想直接看到字符 `'0'`,把格式符换成 `%c` 即可)。
302+
- 三个地址的间隔并不等于各自的类型大小。按声明顺序是 `int`(4) → `double`(8) → `char`(1),但实际地址排列成了 `char``int``double`,相邻差值也不是 4、8、1。原因有两个:编译器会为了内存对齐给局部变量重排位置、插入填充字节;而且栈布局根本不保证按声明顺序排列变量。所以"地址间隔正好等于类型大小"这个直觉,在真实编译器里通常不成立——这正是这道题想让你亲眼看到的。
303+
299304
### 练习 2:指针遍历数组
300305

301306
用指针算术遍历一个 `int` 数组并打印所有元素。要求不使用 `[]` 运算符,只用指针加减和解引用:
@@ -311,6 +316,7 @@ void print_int_array(const int* data, size_t count);
311316
312317
```c
313318
#include <stdio.h>
319+
#include <stddef.h> // size_t
314320
315321
void print_int_array(const int* data, size_t count);
316322
@@ -322,7 +328,7 @@ int main(void) {
322328
323329
void print_int_array(const int* data, size_t count) {
324330
for (size_t i = 0; i < count;i++) {
325-
printf("data[%d] = %d\n", i, *(data + i));
331+
printf("data[%zu] = %d\n", i, *(data + i));
326332
}
327333
}
328334

0 commit comments

Comments
 (0)