跳转到内容

C 语言预定义宏

来自代码酷
Admin留言 | 贡献2025年4月29日 (二) 04:48的版本 (Page creation by admin bot)

(差异) ←上一版本 | 已核准修订 (差异) | 最后版本 (差异) | 下一版本→ (差异)

模板:Note

简介[编辑 | 编辑源代码]

预定义宏是C语言标准规定的一系列由编译器实现的特殊宏,它们在预处理阶段被自动展开,提供编译环境、日期时间等系统级信息。这些宏的名称通常以双下划线开头和结尾(如__FILE__),是调试和跨平台开发的重要工具。

标准预定义宏列表[编辑 | 编辑源代码]

以下是C99/C11标准中必须实现的宏:

宏名称 描述 示例展开值
__DATE__ 编译日期("Mmm dd yyyy"格式) "Jun 15 2023"
__TIME__ 编译时间("hh:mm:ss"格式) "14:30:45"
__FILE__ 当前源文件名(字符串字面量) "example.c"
__LINE__ 当前行号(整型字面量) 42
__STDC__ 若编译器符合ANSI C标准则展开为1 1
__STDC_VERSION__ C标准版本(如199901L表示C99) 201112L

详细说明与示例[编辑 | 编辑源代码]

基础调试宏[编辑 | 编辑源代码]

最常用的调试组合是__FILE____LINE__

#include <stdio.h>

int main() {
    printf("Debug: %s line %d\n", __FILE__, __LINE__);
    return 0;
}

输出示例:

Debug: test.c line 5

编译环境检测[编辑 | 编辑源代码]

通过__STDC__系列宏可检测编译器合规性:

#if __STDC_VERSION__ >= 201112L
    printf("Using C11 or later\n");
#elif __STDC_VERSION__ >= 199901L
    printf("Using C99\n");
#else
    printf("Using ANSI C (C89)\n");
#endif

特殊平台宏[编辑 | 编辑源代码]

不同编译器会扩展额外的预定义宏(非标准):

编译器 示例宏 用途
GCC/Clang __linux__ Linux平台检测
MSVC _WIN32 Windows平台检测
通用 __cplusplus C++模式检测

实际应用案例[编辑 | 编辑源代码]

调试日志系统[编辑 | 编辑源代码]

#define LOG(msg) \
    fprintf(stderr, "[%s %s] %s:%d - %s\n", \
            __DATE__, __TIME__, __FILE__, __LINE__, msg)

int main() {
    LOG("Memory allocation failed");
    return 0;
}

输出示例:

[Jun 15 2023 14:30:45] alloc.c:8 - Memory allocation failed

跨平台代码[编辑 | 编辑源代码]

#if defined(_WIN32)
    #include <windows.h>
    #define SLEEP(ms) Sleep(ms)
#elif defined(__unix__)
    #include <unistd.h>
    #define SLEEP(ms) usleep(ms * 1000)
#endif

高级用法[编辑 | 编辑源代码]

构建版本标识[编辑 | 编辑源代码]

结合多个宏生成唯一版本字符串:

#define STRINGIFY(x) #x
#define BUILD_VERSION "v1.0-" STRINGIFY(__DATE__)

// 展开结果示例:v1.0-Jun_15_2023

条件编译优化[编辑 | 编辑源代码]

使用__GNUC__检测GCC特性:

#if __GNUC__ >= 5
    // 使用GCC5+的特性
    #define likely(x) __builtin_expect(!!(x), 1)
#else
    #define likely(x) (x)
#endif

注意事项[编辑 | 编辑源代码]

  • 预定义宏的值在预处理阶段确定,运行时不会改变
  • 避免重定义标准预定义宏(如#define __LINE__ 100),这是未定义行为
  • 平台特定宏需要查阅编译器文档

可视化关系[编辑 | 编辑源代码]

graph TD A[预定义宏] --> B[标准宏] A --> C[编译器扩展宏] B --> D[__FILE__] B --> E[__LINE__] B --> F[__DATE__] C --> G[GCC的__linux__] C --> H[MSVC的_WIN32]

数学表示[编辑 | 编辑源代码]

在条件编译中,宏展开可视为函数: f(x)={1if __STDC__ is defined0otherwise

页面模块:Message box/ambox.css没有内容。