代码示例:1.1.2 预处理指令深入
全部示例均标注编译命令、适用环境与实测状态;完整验证记录见《03.5-代码编译运行验证记录》。
examples/ex1-safe-macros.c · 安全宏演示(括号/do-while(0)/#与##/副作用)
/* ex1-safe-macros.c —— 安全宏演示(1.1.2) * 适用环境:Linux / Windows(MinGW) 标准:C11(纯标准,无 GNU 扩展) * 编译:gcc ex1-safe-macros.c -o ex1 -std=c11 -Wall -Wextra -Wpedantic * 运行:Linux: ./ex1 Windows: ex1.exe */ #include <stdio.h> /* 1) 对象宏(宏常量):纯文本替换,没有类型 */ #define PI 3.14159 #define MAX_BUFFER 256 /* 2) 函数宏:每个参数和整体都要加括号(对比 BAD_SQUARE 反例) */ #define SQUARE(x) ((x) * (x)) #define BAD_SQUARE(x) x * x /* 3) 多语句宏:用 do { ... } while (0) 包裹,配合 if/else 使用也安全 */ #define PRINT_PAIR(a, b) do { printf("%s = %d\n", #a, (a)); printf("%s = %d\n", #b, (b)); } while (0) /* 4) # 字符串化、## 标识符拼接 */ #define STR(x) #x #define CONCAT(a, b) a##b /* 5) 副作用演示用:参数含 ++ 时会被求值两次 */ #define MAX(a, b) ((a) > (b) ? (a) : (b)) int main(void) { int n = 5; int a = 3; int m; printf("PI = %f\n", PI); printf("SQUARE(5) = %d\n", SQUARE(n)); printf("SQUARE(2 + 3) = %d\n", SQUARE(2 + 3)); /* ((2+3)*(2+3)) = 25 */ printf("BAD_SQUARE(2 + 3) = %d\n", BAD_SQUARE(2 + 3)); /* 2 + 3*2 + 3 = 11 —— 反例 */ PRINT_PAIR(n, SQUARE(n)); /* do-while(0):多语句宏,任何位置使用都安全 */ printf("CONCAT(MAX, _BUFFER) = %d\n", CONCAT(MAX, _BUFFER)); /* → MAX_BUFFER → 256 */ printf("STR(hello) = \"%s\"\n", STR(hello)); /* → "hello" */ m = MAX(++a, 0); /* ++a 被求值两次:3 → 4 → 5 */ printf("MAX(++a, 0) = %d, a = %d\n", m, a); return 0; }examples/ex2-conditional-compile.c · DEBUG/RELEASE 条件编译(两遍编译输出不同)
/* ex2-conditional-compile.c —— DEBUG/RELEASE 条件编译演示(1.1.2) * 适用环境:Linux / Windows(MinGW) 标准:C11 * 两遍编译(输出不同,均已实测): * gcc ex2-conditional-compile.c -o ex2-release -std=c11 -Wall -Wextra -Wpedantic * gcc ex2-conditional-compile.c -o ex2-debug -std=c11 -Wall -Wextra -Wpedantic -DDEBUG * 运行:Linux: ./ex2-release / ./ex2-debug Windows: ex2-release.exe / ex2-debug.exe */ #include <stdio.h> #define VERSION "1.0.0" #ifdef DEBUG #define LOG(msg) do { printf("[DEBUG] %s:%d %s\n", __FILE__, __LINE__, msg); } while (0) #else #define LOG(msg) do { } while (0) #endif int main(void) { printf("version %s build\n", VERSION); LOG("进入 main"); printf("正常业务输出\n"); LOG("业务完成"); return 0; }examples/ex3-0b-diagnostic.c · 0b 二进制字面量标准归属演示(diagnostic)
/* ex3-0b-diagnostic.c —— 演示:0b 二进制字面量不是 C11 标准(1.1.2,diagnostic) * gcc 15.2.0 实测(MinGW-w64): * gcc ex3-0b-diagnostic.c -o ex3 -std=c11 -Wall -Wextra -Wpedantic * → warning: binary constants are a C23 feature or GCC extension [-Wpedantic](仍能编译,exit 0) * gcc ex3-0b-diagnostic.c -o ex3 -std=c11 -Wall -Wextra -Wpedantic -Werror * → error: binary constants are a C23 feature or GCC extension [-Werror=pedantic](编译失败) * 默认模式(本机 gcc 15 默认 gnu23):0b 为 C23 标准语法,零警告 * 结论(err-7.1-22):0b 不是 C99/C11 标准,是 GNU 扩展 / C23 特性;严格工程(-Werror)下等于不可用 */ int main(void) { int x = 0b1010; /* GNU 扩展 / C23 二进制字面量;C11 没有 */ (void)x; return 0; }