代码示例:1.3.10 API 封装与工程目录规范
全部示例均标注编译命令、适用环境与实测状态;完整验证记录见《03.5-代码编译运行验证记录》。
examples/ex1-rb.c · ring buffer 模块 API 封装(.h 声明 + .c 实现 + 使用方,三文件真实编译链接)
/* ex1-rb.c —— ring_buffer 模块实现(1.3.10) * 模块内部细节对使用者隐藏:仅 ex1-rb.h 的声明是公开 API;内部辅助函数用 static 限定。 * 编译(本文件与使用方一并编译链接): * gcc ex1-rb.c ex1-main.c -o ex1 -std=c11 -Wall -Wextra -Wpedantic */ #include "ex1-rb.h" static size_t rb_tail_index(const ring_buffer *rb) { return (rb->head + rb->count) % RB_CAPACITY; } void rb_init(ring_buffer *rb) { rb->head = 0; rb->count = 0; } int rb_push(ring_buffer *rb, int value) { if (rb->count >= RB_CAPACITY) { return -1; } rb->data[rb_tail_index(rb)] = value; rb->count++; return 0; } int rb_pop(ring_buffer *rb, int *out) { if (rb->count == 0 || out == NULL) { return -1; } *out = rb->data[rb->head]; rb->head = (rb->head + 1) % RB_CAPACITY; rb->count--; return 0; } size_t rb_count(const ring_buffer *rb) { return rb->count; } /* 模块自测:使用者编译后运行 rb_self_test() 即知模块是否自洽 */ int rb_self_test(void) { ring_buffer buf; int v = 0; rb_init(&buf); if (rb_push(&buf, 10) != 0) return 1; if (rb_push(&buf, 20) != 0) return 2; if (rb_pop(&buf, &v) != 0 || v != 10) return 3; if (rb_count(&buf) != 1) return 4; return 0; }examples/ex2-calc.c · 标准目录构建(calc 模块:obj/ 目标文件 + bin/ 可执行文件)
/* ex2-calc.c —— calc 模块实现(1.3.10 ex2,标准目录演示) * 文件在真实工程中位于 src/calc.c,头文件在 inc/calc.h; * 本示例为适配验证脚本平铺到 examples/ 顶层,目录布局与命令见正文。 */ #include "ex2-calc.h" static int last_error = 0; int calc_add(int a, int b) { return a + b; } int calc_sub(int a, int b) { return a - b; } int calc_mul(int a, int b) { return a * b; } int calc_div(int a, int b) { if (b == 0) { last_error = 1; return 0; } last_error = 0; return a / b; } int calc_last_error(void) { return last_error; }examples/ex3-multiple-definition.txt · 头文件放普通全局定义的后果(diagnostic:multiple definition 真实报错)
# 1.3.10 ex3(diagnostic 讲解文本):头文件放普通全局定义 → multiple definition # 实验结构(本机实测,gcc 15.2.0): # bad.h: int shared_counter = 0; ← 普通定义放进了头文件(错误示范) # a.c: #include "bad.h" → 定义了一份 shared_counter # b.c: #include "bad.h" → 又定义了一份 shared_counter # 链接: gcc a.c b.c m2.c -o m2 -std=c11 -Wall -Wextra -Wpedantic # 真实报错(见 examples.yaml ex3 expected_output): # multiple definition of \`shared_counter'; ... first defined here # collect2.exe: error: ld returned 1 exit status # # 正确做法: # 1. 头文件只放声明:extern int shared_counter; # 2. 定义只放一个 .c:int shared_counter = 0; # 3. 或需要每翻译单元独立副本时用 static(内部链接,语义不同,见 1.3.5) # # 记忆点:头文件 = 接口契约(类型/宏/函数声明/extern 声明),不是变量的家。