CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
C 语言入门/课时/预处理器
RawBlame
课时目录12 节

C 语言入门

  1. 01C 是什么
  2. 02类型与变量
  3. 03控制流与运算符
  4. 04函数
  5. 05指针与内存
  6. 06数组与字符串
  7. 07结构体与联合体
  8. 08预处理器
  9. 09编译与构建
  10. 10并发与进程
  11. 11调试与测试
  12. 12综合练习

预处理器

宏、#include、条件编译。

30 分钟

预处理器

编译前,预处理器处理 #include、#define 与条件编译。对照 /roadmaps/c,读懂头文件守卫与跨平台宏是维护 C 项目的必备技能。

学习目标

  • 理解 #include 与头文件组织
  • 编写带参数的宏并知道其局限
  • 使用 #if、#ifdef 做条件编译
  • 区分宏与 const、内联函数

核心概念

宏与条件编译

/* config.h */
#ifndef CONFIG_H
#define CONFIG_H

#define VERSION "1.0.0"
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define LOG(fmt, ...) printf("[LOG] " fmt "\n", ##__VA_ARGS__)

#if defined(_WIN32)
#  define PATH_SEP '\\'
#else
#  define PATH_SEP '/'
#endif

#ifdef DEBUG
#  define DBG(msg) fprintf(stderr, "DEBUG: %s\n", msg)
#else
#  define DBG(msg) ((void)0)
#endif

#endif /* CONFIG_H */
/* main.c */
#include <stdio.h>
#include "config.h"

static int square(int x) {
    return x * x;
}

int main(void) {
    LOG("version=%s sep=%c", VERSION, PATH_SEP);
    DBG("entering main");

    int a = 3, b = 7;
    printf("MAX=%d square=%d\n", MAX(a, b), square(a));

    /* 宏陷阱:多次求值 */
    int i = 5;
    printf("MAX(i++, 10)=%d i=%d\n", MAX(i++, 10), i);

#if 0
    puts("disabled block");
#endif

    return 0;
}

最佳实践

做法说明
头文件守卫#ifndef / #define / #endif 防重复包含
宏参数加括号#define SQR(x) ((x)*(x))
复杂逻辑用 static inline 函数代替宏
平台差异#ifdef _WIN32 等集中管理

#include "local.h" 先搜当前目录;#include <stdio.h> 搜系统路径。

与 C++/Java 对照

特性C 预处理器C++Java
文本替换#define 宏有 + 模板/constexpr无
条件编译#ifdef有无(靠 profile/模块)
头文件#include 展开同左 + #pragma onceimport / module
常量宏或 constconstexprfinal static
泛型宏模拟模板泛型类

Java 无预处理器;配置靠构建工具与注解。C 宏强大但缺类型检查,现代 C 倾向 const + 内联函数。

练习

  • 为自定义头文件 math_utils.h 添加 include guard
  • 写宏 ARRAY_SIZE(arr) 计算数组元素个数
  • 用 #ifdef DEBUG 切换日志输出
  • 说明 MAX(i++, 10) 为何可能出错,并给出更安全写法

小结

预处理器在编译前改写源码;宏慎用,头文件守卫必用。 下一课学习编译与构建。

加载本节练习…
← 上一课结构体与联合体下一课 →编译与构建