C语言#if、#elif、#else和#endif条件编译的用法(非常详细)
在C语言中,程序员可以根据不同的条件,有选择性地编译不同的代码块(忽略其它的代码块),从而产生不同的目标文件,这种机制称为条件编译。
借助条件编译,我们可以在同一份源代码中包含针对不同操作系统、硬件架构或功能配置的代码,而无需维护多个独立的源文件。
条件编译是预处理器的功能,不是编译器的功能。条件编译通过以
#if #else 命令和 if else 语句的用法非常类似,都是一种分支结构。但是,#if 命令要求判断条件为“常量表达式”,不能包含变量以及函数调用,而 if 语句后面的表达式没有限制,只要符合语法就行。这是 #if 和 if 的一个重要区别。
示例1:同时使用 #if、#elif 和 #else 命令:
示例2:只使用 #if 命令:
最后请注意,#endif 不能省略,它必须和 #if 配对出现,用以结束条件编译。
借助条件编译,我们可以在同一份源代码中包含针对不同操作系统、硬件架构或功能配置的代码,而无需维护多个独立的源文件。
条件编译是预处理器的功能,不是编译器的功能。条件编译通过以
#
开头的预处理命令来完成,包括 #if、#elif、#else、#endif、#ifdef 和 #ifndef。本文先介绍前四个命令,后两个命令请转到:C语言#ifdef和#ifndef命令的用法
条件编译的用法和示例
#if、#elif、#else 和 #endif 允许我们根据特定的条件(一个表达式的值),来决定哪些代码段应该被编译,哪些应该被忽略。它们的基本用法如下:#if 常量表达式1 //代码段1 //如果 常量表达式1 的值为真,则编译 代码段1,忽略其它代码 #elif 常量表达式2 //代码段2 //如果 常量表达式2 的值为真,则编译 代码段2,忽略其它代码 #elif 常量表达式3 //代码段3 //如果 常量表达式3 的值为真,则编译 代码段3,忽略其它代码 #else //代码段n //如果以上表达式的值都为假,则编译 代码段n,忽略其它代码 #endif整体上的执行流程为:如果
常量表达式1
的值为真(非 0),就对代码段1
进行编译,否则就计算常量表达式2
,结果为真的话就对代码段2
进行编译,为假的话就继续往下匹配,直到遇到值为真的表达式,或者遇到 #else。#if #else 命令和 if else 语句的用法非常类似,都是一种分支结构。但是,#if 命令要求判断条件为“常量表达式”,不能包含变量以及函数调用,而 if 语句后面的表达式没有限制,只要符合语法就行。这是 #if 和 if 的一个重要区别。
#if #else 是在预处理阶段进行替换,无法获取变量的值,所以表达式中不能包含变量。
#elif 和 #else 都可以省略,也就是写成下面的形式:#if 常量表达式 //代码段1 // 如果 常量表达式 的值为真,则编译 代码段1 #else //代码段2 //如果 常量表达式 的值为假,则编译 代码段2 #endif或者:
#if 常量表达式 //代码段 //如果 常量表达式 的值为真,则编译这里的 代码段 #endif
示例1:同时使用 #if、#elif 和 #else 命令:
#include <stdio.h> #define LEVEL 2 #if LEVEL == 1 #define MESSAGE "Low priority" #elif LEVEL == 2 #define MESSAGE "Medium priority" #elif LEVEL == 3 #define MESSAGE "High priority" #else #define MESSAGE "Unknown priority" #endif int main() { printf("Task priority: %s\n", MESSAGE); return 0; }运行结果:
Task priority: Medium priority
我们根据 LEVEL 宏的值来定义不同的 MESSAGE,如果 LEVEL 的值不是 1、2 或 3,那么会使用 #else 分支中定义的默认消息。本例中,第 5~13 行的代码,只有第 8 行代码被编译,其它代码在预处理完成以后就不存在了。示例2:只使用 #if 命令:
#include <stdio.h> #define DEBUG 1 int main() { #if DEBUG printf("Debug mode is enabled.\n"); #endif //TODO: return 0; }在这个例子中,如果 DEBUG 宏被定义为非零值,那么 printf 语句就会被编译到最终的程序中。否则,这行代码会被忽略。
条件编译的嵌套使用
条件编译命令可以嵌套使用,这使得我们能够创建更加复杂的判断逻辑,请看下面的例子(示例3):#define DEBUG 1 #define VERBOSE_DEBUG 1 #if DEBUG printf("Debug mode enabled.\n"); #if VERBOSE_DEBUG printf("Verbose debug information will be displayed.\n"); #endif #else printf("Running in release mode.\n"); #endif在这个例子中,我们有一个嵌套的条件编译结构。只有当 DEBUG 被定义为非零值时,内部的
#if VERBOSE_DEBUG
条件才会被检查。
关于 #if 和 #elif 后面的表达式
#if 和 #elif 后面的常量表达式
中,可以包含各种算术运算符、逻辑运算符和关系运算符,以实现更复杂的条件判断。请看下面的例子(示例4):
#include <stdio.h> #define M 20 #define N 40 int main(){ #if M+N>100 printf("The value is too large.\n",); #elif M+N<=100 && M+N>50 printf("The value is right.\n"); #else printf("The value is too small.\n"); #endif return 0; }运行结果:
The value is right.
虽然这些表达式看起来复杂,但是在程序运行之前就能推算出它们的值;而一旦包含了变量或者函数调用,就必须等到程序运行以后才能获取它们的值,这就超出预处理器的能力了。总结
C语言条件编译允许只编译源程序中满足条件的代码段,使生成的目标程序较短,从而减少了内存的开销,并提高了程序的效率。最后请注意,#endif 不能省略,它必须和 #if 配对出现,用以结束条件编译。