本文主要介绍c语言中条件编译相关的预编译指令,包括 #define、#undef、#ifdef、#ifndef、#if、#elif、#else、#endif、defined。
#define 定义一个预处理宏
#undef 取消宏的定义
#if 编译预处理中的条件命令,相当于C语法中的if语句
#ifdef 判断某个宏是否被定义,若已定义,执行随后的语句
#ifndef 与#ifdef相反,判断某个宏是否未被定义
#elif 若#if或前面的#elif条件不满足,则执行#elif之后的语句,相当于C语法中的else-if
#else 与#if, #ifdef, #ifndef对应, 若这些条件不满足,则执行#else之后的语句,相当于C语法中的else
#endif #if, #ifdef, #ifndef这些条件命令的结束标志.
defined 与#if, #elif配合使用,判断某个宏是否被定义
条件编译是根据实际定义宏(某类条件)进行代码静态编译的手段。可根据表达式的值或某个特定宏是否被定义来确定编译条件。
程序员可以通过定义不同的宏来决定编译程序对哪些代码进行处理;
条件编译指令将决定哪些代码被编译,而哪些不被编译的;
可以根据表达式的值或者某个特定的宏是否被定义来确定编译条件。
1、如果表达式为真,就编译语句段1,否则编译语句段2
#if表达式
//语句段1
#else
//语句段2
#endif
2、如果表达式1真,则编译语句段1,否则判断表达式2;如果表达式2为真,则编译语句段2,否则编译语句段3
#if表达式1
//语句段1
#elif表达式2
//语句段2
#else
//语句段3
#endif
3、如果在此之前已定义了这样的宏名,则编译语句段。
#ifdef 宏名
//语句段
#endif
4、如果在此之前没有定义这样的宏名,则编译语句段。
注意事项: 在情况3和4中 #else可以用于#ifdef和#ifndef中,但#elif不可以。对应下面的情况5 和 6
#ifndef宏名
//语句段
#endif
5、如果有定义这样的宏名,则编译语句段1,否则,编译语句段2
#ifdef宏名
//语句段1
#else
//语句段2
#endif
6、如果没有定义这样的宏名,则编译语句段1,否则,编译语句段2
#ifndef宏名
//语句段1
#else
//语句段2
#endif
下面做展示案例1
1、 宏定义了PM #ifdef PM 则执行紧接着的程序块1,否则执行#else 紧接着的程序块2
void test01()
{
float r = 100;
#ifdef PM
float c;
float s;
c = 2 * PI*r;
s = PI * r*r;
printf("=================\n");
#else
PM;
printf("PM宏定义\n");
printf("Hello World!\n");
printf("面积为%f\n周长为%f\n", s, c);
#endif
}
2、宏定义了PM #ifndef PM 则不执行紧接着的程序块1,执行#else 紧接着的程序块2
void test02()
{
float r = 100;
#ifndef PM
float c;
float s;
c = 2 * PI*r;
s = PI * r*r;
printf("=================\n");
#else
PM;
printf("PM宏定义\n");
printf("Hello World!\n");
PR("PW\n");
printf("面积为%f\n周长为%f\n", s, c);
#endif
}
3、#if 非零整型常量 一般常用1 则执行紧接着的程序块1,否则执行#else 紧接着的程序块2
void test03()
{
float r = 100;
#if 0 // #if 非零整型常量 一般常用1 则执行紧接着的程序块1,否则执行#else 紧接着的程序块2
float c;
float s;
c = 2 * PI*r;
s = PI * r*r;
printf("=================\n");
#else
PM;
printf("PM宏定义\n");
printf("Hello World!\n");
printf("PW\n"); // 宏名除了双括号里面的内容不能替换
printf("面积为%f\n周长为%f\n", s, c);
#endif
//#undef PR
PR("我爱你\n"); //报错 “PR” : 找不到标识符
}
总代码
// 条件编译示例.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#define PI 3.1415926
#define PM float c;float s; c=2*PI*r; s=PI*r*r
#define PR printf
#define PW Hello World
#include <iostream>
void test01()
{
float r = 100;
#ifdef PM
float c;
float s;
c = 2 * PI*r;
s = PI * r*r;
printf("=================\n");
#else
PM;
printf("PM宏定义\n");
printf("Hello World!\n");
printf("面积为%f\n周长为%f\n", s, c);
#endif
}
void test02()
{
float r = 100;
#ifndef PM
float c;
float s;
c = 2 * PI*r;
s = PI * r*r;
printf("=================\n");
#else
PM;
printf("PM宏定义\n");
printf("Hello World!\n");
PR("PW???\n");
printf("面积为%f\n周长为%f\n", s, c);
#endif
}
void test03()
{
float r = 100;
#if 0 // #if 非零整型常量 一般常用1 则执行紧接着的程序块1,否则执行#else 紧接着的程序块2
float c;
float s;
c = 2 * PI*r;
s = PI * r*r;
printf("=================\n");
#else
PM;
printf("PM宏定义\n");
printf("Hello World!\n");
printf("PW!!!\n"); // 宏名除了双括号里面的内容不能替换
printf("面积为%f\n周长为%f\n", s, c);
#endif
//#undef PR
PR("我爱你\n"); //报错 “PR” : 找不到标识符
}
int main()
{
//test01();
test02();
//test03();
system("pause");
return 0;
}
下面展示案例2
#ifdef 和 #ifndef
作用:这二者主要用于防止头文件重复包含。我们一般在.h头文件前面加上这么一段:
//防止头文件重复包含funcA.h
#ifndef FUNCA_H
#define FUNCA_H
//头文件内容
#end if
这样,如果a.h包含了funcA.h,b.h包含了a.h、funcA.h,重复包含,会出现一些type redefination之类的错误。
#if defined 等价于 #ifdef #if !defined 等价于 #ifndef