C语言-条件编译

发布时间 2023-10-23 11:16:33作者: Bonne_chance

C语言-条件编译

-问题
加入现在要开发一个C语言程序,跨平台输出红色字体,也就是在Windows和Linux下都能运行,怎么办呢?
这个程序的难点在不同平台下控制文字颜色的代码不一样,必须要先识别出不同的平台。
Windows有专有的宏_WIN32Linux有专有的宏__linux__

-错误的if-else操作

#include <stdio.h>
int main(){
  if(_WIN32){
    system("color 0c");
    printf("Hello World!\n");
}else if (__linux__){
    printf("\033[22;31mHello World\n\033[22;30m");
}
else{
  printf("Hello World!\n);
}

return 0;
}

以上代码是错误的,想法是没错的,但是不同的平台只支持对应的宏,也就是说在Windows下提示的__linux__是未定义的,在Linux_Win32是未定义的.

  • 改进的代码
#include <stdio.h>
int main(){
    #if _Win32
      system("color 0c");//1
      printf("Hello World!\n");//2
    #elif __linux__
      printf("\033[22;31mHello World\n\033[22;30m");//3
    #else
      printf("Hello World!\n");//4
    #endif

}   

#if#elif#else#endif都是预处理命令,整段代码的意思是:如果宏_Win32为真,就保留后面1、2两行,删除3、4两行,如果宏__linux__的值为真,就保留3行,如果所有的宏都为假,保留4.

这些操作都是在预处理阶段完成的,多余的代码以及所有的宏都不参与编译,不仅保证程序的正确性,还减少了编译后的文件体积。这种能够根据不同情况编译不同代码、产生不同目标文件的机制称为条件编译。条件编译时预处理程序的功能,不是编译器的功能。

  • #if的用法
    #if用法的一般格式为:
`#if` 整型常量表达式1
    程序段1
`#elif 整型常量表达式2
    程序段2
#elif 整型常量表达式3
    程序段3
#else
    程序段4
#endif

表达含义为:如果表达式1的值为真,就对程序段1进行编译,窦泽就计算表达式2,结果为真则对程序段2进行编译,为假就继续往下匹配,指导遇到值为真的表达式,或者遇到#else。

需要注意的是,#if命令要求判断条件为“整型常量表达式”,也就是说,表达式中不能包含变量,而且结果必须是整数,而if后面的表达式没有限制,只要符合语法即可。这是#ifif的重要区别。

#elif#else可以省略,具体如下:

#include <stdio.h>
int main(){
    #if _WIN32
        printf("This is Windows!\n");
    #else
        printf("Unknown platform!\n");
    #endif
   
    #if __linux__
        printf("This is Linux!\n");
    #endif
    return 0;
}
  • #ifdef的用法
    #ifdef用法的一般形式:
#ifdef  宏名
    程序段1
#else
    程序段2
#endif

解释: 如果当前的宏已经被定义过,则对“程序段1”进行编译,否则对“程序段2”进行编译。
也可以省略#else

#ifdef  宏名
    程序段
#endif

VS/VC有两种编译模式,DebugRelease。在学习过程中,通常使用Debug模式,这样编译程序调试,而在最终发布的程序,要使用Release模式,这样编译器会进行很多优化,提高程序运行效率,删除冗余信息。
为了能够清楚地看到当前程序的编译模式,不妨在程序中增加提示,如下代码:

#include <stdio.h>
#include <stdlib.h>
int main(){
    #ifdef _DEBUG
        printf("正在使用 Debug 模式编译程序...\n");//1
    #else
        printf("正在使用 Release 模式编译程序...\n");//2
    #endif
    system("pause");
    return 0;
}

当以Debug模式编译程序时,宏_DEBUG会被定义,预处理器会保留1,删除2,反之会删除1,保留2.

  • ifndef的用法
    #ifndef用法的一般格式为:
#ifndef 宏名
    程序段1 
#else 
    程序段2 
#endif

#ifdef相比,仅仅是将#ifdef改为#ifndef.它的意思是,如果当前的宏未被定义,则对“程序段1”进行编译,否则对“程序段2”进行编译,这与#ifdef的功能正好相反。

  • #if#ifdef#ifndef的区别
    #if后面跟的是“整型常量表达式”,而#ifdef#ifndef后面跟的只能是一个宏名,不能是其他的。
    -实例--#if
#include <stdio.h>
#define NUM 10
int main(){
    #if NUM == 10 || NUM == 20
        printf("NUM: %d\n", NUM);
    #else
        printf("NUM Error\n");
    #endif
    return 0;
}

运行结果是: NUM:10

-实例--#ifdef#ifdef可以认为是#if defined的缩写)

#include <stdio.h>
#define NUM1 10
#define NUM2 20
int main(){
    #if (defined NUM1 && defined NUM2)
        //代码A
        printf("NUM1: %d, NUM2: %d\n", NUM1, NUM2);
    #else
        //代码B
        printf("Error\n");
    #endif
    return 0;
}

结果:NUM1: 10, NUM2: 20
#ifdef 可以认为是 #if defined 的缩写。

参考:https://c.biancheng.net/view/1986.html