一、 #ifdef、#ifndef

  1. #ifdef:是当宏定义的时候保留代码
  2. #ifndef:当宏未定义的时候保留代码
#include <stdio.h>

#define WINDOWS_XP // 这是一个无宏体

int main(void)
{
#ifdef WINDOWS_XP
    printf("procedure word needed by windows_xp\n");
#endif

#ifdef LINUX
    printf("procedure word needed by Linux\n");
#endif
}

虽然这里也可以给宏加上宏体,但是我们这里的代码没必要,只需要判断是否定义即可

gcc -E main.c -o main.i

当我们预编译以后,经过条件编译,只剩WINDOWS_XP宏下保留的代码了

......
__attribute__ ((__dllimport__)) size_t __attribute__((__cdecl__)) _fread_nolock_s(void *_DstBuf,size_t _DstSize,size_t _ElementSize,size_t _Count,FILE *_File);
# 1398 "C:/Program Files/mingw64/x86_64-w64-mingw32/include/stdio.h" 2 3

# 1 "C:/Program Files/mingw64/x86_64-w64-mingw32/include/_mingw_print_pop.h" 1 3
# 1400 "C:/Program Files/mingw64/x86_64-w64-mingw32/include/stdio.h" 2 3
# 2 "main.c" 2




# 5 "main.c"
int main(void)
{
    printf("procedure word needed by windows_xp\n");
}

搭配 #else

#include <stdio.h>

#define WINDOWS_XP 

int main(void)
{
#ifndef WINDOWS_XP
    printf("procedure word needed by windows_xp\n");
#else
    printf("procedure word needed by Linux\n");
#endif
}

与 #elif

#include <stdio.h>

#define WINDOWS_XP

int main(void)
{
#ifndef WINDOWS_XP
    printf("procedure word needed by windows_xp\n");
#elif 1  // 非0即为真
    printf("procedure word needed by Linux\n");
#endif
}

二、#if

基本格式

#if 表达式
...

#endif

#if 后的“表达式”有两种:

  1. 第一种:为整形常量,或者整形常量表达式
  2. 第二种:为由defined!defined组建表达式

第一种:表达式为整形常量

格式

#if 整形常量,或者整形常量表达式
...
#endif

例子

#if 1 //1为真(非零为真),保留代码
...
#endif

当然也可以定义成宏

#define NUM 0

#if NUM
...
#endif
#define NUM 0

#if NUM == 1  // 写>  <   >=  <=这些符号都是成立的
...

#endif

第二种:表达式由defined、!defined组建

(a)#if defined

基本功能

  • #ifdef是一样的,这个时候是通过判断宏存不存在来判定真假

例子

#define MACRO

#if defined MACRO //如果定义了这个宏(宏存在),就保留代码
    printf("1111111\n");
#endif

#ifdef不同之处

  • #ifdef是独立的关键字,但是#if defined是两个两个关键字的组合
  • #if defined可以实现宏的“&&、||”运算,但是#ifdef不行
#define MACRO1 
#define MACRO2

#if defined MACRO1 && defined MACRO2  //如果这两个宏都定义了的话,才保留代码
    printf("1111111\n");
#endif

(b)#if !defined

!defined是两个独立的关键字,功能与#if defined刚好相反

例子1

#define MACRO

#if !defined MACRO //如果没有定义这个宏(宏不存在),就保留代码
    printf("1111111\n");
#endif

· 例子2

#define MACRO1
#define MACRO2

//只有当这两个宏都没有定义时,才保留代码
#if !defined MACRO1 && !defined MACRO2
    printf("1111111\n");
#endif

defined!defined也可以混用

#define MACRO1
#define MACRO2

#if (defined MACRO1 && defined MACRO2) || !defined MACRO3
    printf("1111111\n");
#endif

可以按照你自己的要求随意的组合


与#else 搭配

直接举例讲解

1)例子1:
#define NUM 0

#if NUM    //0为假,不保留代码
    printf("1111111\n");
#else
    printf("2222222\n");
#endif
2)例子2
#define MACRO1 
#define MACRO2

#if !defined MACRO1 && defined MACRO2
    printf("1111111\n");
#else    // 如果前面的条件不成立,就保留#else后面的代码
    printf("2222222\n");
#endif
(3)与#elif 搭配

直接举例演示。

1)例子1

#if 1
    printf("1111111\n");
#elif 1
    printf("2222222\n");
#endif

2)例子2

#if !defined MACRO
    printf("1111111\n");
#elif defined MACRO1
    printf("2222222\n");
#endif

3)例子3

#if 0  // #if !defined MACRO
    printf("1111111\n");
#elif NUM == 100
    printf("2222222\n");
#elif !definedMACRO1 || defined MACRO2
    printf("3333333\n");
#else  // #else可以没有
    printf("4444444\n");
#endif

#if、#elif、#else、!、defined 这些关键字怎么组合使用,完全取决于你自己的想要怎么用