简单示例

printf("hello\  // 编译器会删除该反斜杠, 然后将两个物理行转换成一个逻辑行
        world\n");
printf("hello world\n");  // 转换结果

明示常量#define

宏定义仅进行替换, 不会求值, 不会求值, 不会求值

#define PI 3.1415926  // 类对象宏
#define message "hello world\n"
#define PX(x) printf("X is %d\n", x)  // 类函数宏
#define FMT "X is %d\n"

int x = 1101;
PX(x);
printf("%s", message);
printf(FMT, x);
#define PX(x) printf("the "#x"" is %d\n", x)  // 注意双引号

int val = 1101;
PX(val);  // the val is 1101

…和__VA_ARGS__

#define PR(...) printf("message" __VA_ARGS__)

PR("hello world\n");  // printf("message" "hello world\n");

#undef

用于取消已经定义的#define指令

#define LIMIT 400
#undef LIMIT  // 移除了上面的定义 现在可以把LIMIT重新定义为新的值

预定义宏

含义
__DATE__预处理的日期(”Mmm dd yyyy” 形式的字符串字面量,如 Nov 23 2013)
__FILE__表示当前源代码文件名的字符串字面量
__LINE__表示当前源代码文件中行号的整型常量
__STDC__设置为 1 时,表明实现遵循 C 标准
__STDC_HOSTED__本机环境设置为 1;否则设置为 0
__STDC_VERSION__支持 C99 标准,设置为 199901L;支持 C11 标准,设置为 201112L
__TIME__编译代码的时间,格式为 “hh:mm:ss”
printf("Current date: %s\n", __DATE__);  // Current date: Aug 14 2024
printf("Current time: %s\n", __TIME__);  // Current time: 16:28:00
printf("This file is: %s\n", __FILE__);
// This file is: C:\Users\John2\Documents\VS_Code\C\learn\header\define.c
printf("This is line number: %d\n", __LINE__);  // This is line number: 12
#ifdef __STDC__
    printf("This compiler conforms to the C standard\n");
#else
    printf("This compiler does not conform to the C standard\n");
#endif  // This compiler conforms to the C standard

#if __STDC_HOSTED__
    printf("This is a hosted environment\n");
#else
    printf("This is a freestanding environment\n");
#endif  // This is a hosted environment

#if __STDC_VERSION__ >= 201112L
    printf("C11 standard supported\n");
#elif __STDC_VERSION__ >= 199901L
    printf("C99 standard supported\n");
#else
    printf("C89/C90 standard supported\n");
#endif  // C11 standard supported

__func__

C99 标准提供一个名为 __func__的预定义标识符, 它展开为一个代表函数名的字符串(该函数包含该标识符). 那么, __func__ 必须具有函数作用域, 而从本质上看宏具有文件作用域。因此, __func__ 是 C 语言的预定义标识符, 而不是预定义宏

void why_me()
{
    printf("This function is %s\n", __func__);
}  // This function is why_me

#line和#error

#line用于重置当前行号和文件名

#line 1101 "hello.c"

#error让预处理器发出一条错误信息, 并且中断程序

#if __STDC_VERSION__ != 201112L
#error Not C11
// 下面是编译效果
$gcc newish.c
newish.c:14.2: error: #error Not C11
gcc newish.c -std=c11
$成功运行

#pragma编译指示

#pragma c9x on  // 让编译器支持C9X

评论

发表回复