C语言defined预处理操作符的用法(非常详细)

 
defined 是C语言中的一个预处理操作符,用来判断某个宏(Macro)是否已被定义。defined 只能和 #if、#elif 命令搭配使用,不能单独使用。

defined 操作符的用法如下:
#if defined(MACRO_NAME)
    //代码段
    //如果 MACRO_NAME 被定义了,则编译这部分代码
#endif
MACRO_NAME 是宏的名字,如果该宏已被定义,那么就编译 #if 后面的代码段,否则就不编译。

你也可以去掉括号,直接写作#if defined MACRO_NAME;但是为了更加规范,也为了避免不必要的错误,笔者还是建议加上括号。

示例

假设现在要开发一个C语言程序,让它输出红色的文字,并且要求跨平台,在 Windows 和 Linux 下都能运行,怎么办呢?

这个程序的难点在于,不同平台下控制文字颜色的代码不一样,我们必须要能够识别出不同的平台。Windows 有专有的宏_WIN32,Linux 有专有的宏__linux__,我们可以根据这两个宏来判断当前的编译平台。

请看下面的代码:
#include <stdio.h>
#include <stdlib.h>

int main() {
    #if defined(_WIN32)
        system("color 0c");
        printf("https://c.biancheng.net\n");
    #elif defined(__linux__)  //defined也可以和#elif搭配使用
        printf("\033[22;31mhttps://c.biancheng.net\n\033[22;30m");
    #else
        printf("https://c.biancheng.net\n");
    #endif

    return 0;
}
如果是 Windows 平台,会检测到 _WIN32 宏已被定义,那么就编译 6~7 行代码,忽略其它代码;如果是 Linux 平台,会检测到 __linux__ 宏被定义,那么就编译第 9 行代码,忽略其它代码;如果既不是 Windows 也不是 Linux,那么就编译 #else 后面的代码(第 11 行),使用系统默认的文字颜色(一般是白色)。

请注意第 8 行代码,defined 也可以和 #elif 搭配使用,它的用法和 #if 是一样的。

defined 的进阶用法

defined 操作符是有运算结果的,它的结果是布尔类型(两个值),所以 defined 可以和逻辑运算符、关系运算符一起使用,从而编写出更加复杂的条件判断。请看下面的代码:
#include <stdio.h>

#define NUM1
#define NUM2 10

int main() {
    #if defined(NUM1) && defined(NUM2)
        printf("正确:NUM1 和 NUM2 都被定义了");
    #endif

    #if !defined(NUM1) || !defined(NUM2)
        printf("错误:缺少宏定义");
    #endif

    return 0;
}
运行结果:

正确:NUM1 和 NUM2 都被定义了

对于 7~9 行代码,只有 NUM1 和 NUM2 两个宏都被定义了,才会编译第 8 行代码。对于 11~13 行代码,只要有一个宏没有定义,就编译第 12 行代码。

请注意第 3 行代码,我们虽然定义了 NUM1 宏,但它是空的,并没有实际内容。当我们使用 defined 进行判断时,得到的结果依然是,这说明 defined 只检测宏是否被定义,而不检测宏的内容。