C语言允许在源程序中包含编译预处理命令,他们以"#"开头,包括宏定义、文件包含和条件编译。本博客主要详细介绍宏定义、文件包含和条件编译。
目录
一、宏定义
1、无参数的宏定义
是指用一个指定的标识符来代表一个字符串,一般格式如下:
#define 宏名 字符串
说明:①#表示预处理命令,在C语言中以“#”开头的均为预处理命令。
②define表示宏定义命令。
③宏名常用大写字母表示,这样易于区别程序中的宏名和普通变量名。
④字符串表示宏的内容文本,也称为宏体,是一个ASCII 码的字符序列,可以是常
数、表达式、格式串等。
注意:(1)宏定义是用宏名替换一个字符串,即原样替换,不做语法检查。如有错误,
只能在展开后编译源程序时才被发现。
(2)宏定义不是C语句,在行末不必加分号,如果加上分号则连分号也一起替换。
#define PI 3.14;
//则语句“area=PI*R*R;"宏扩展为"area=3.14;*R*R;",编译时将出现语法错误
(3)宏名在源程序中若用引号括起来,则预处理时不对其进行宏替换。例如:
//语句"printf("PI");的输出结果为字符串PI而不是前面所定义的值
(4)宏定义必须写在函数之外,其作用域为从宏定义开始到源程序末尾结束。若要终止其作用域可以用#undef命令。
(5)宏定义允许嵌套,即可以引用已定义的宏名,层层置换。
(6)宏定又是预处理命令,它与变量的含义不同,不分配内存空间,只做字符替换。
2.带参数的宏定义
是指宏名后面带有参数。在编译预处理时,不仅要对宏名进行字符串替换,还要对参数进行替换。宏定义中的参数称为形式参数(简称形参),宏调用中的参数称为
实际参数(简称实参),这点与函数有此相似。带參数的宏定义的一般格式为:
#define 宏名(形参列表) 字符串
说明:
①宏名和括号之间不能有空格,否则将空格以后的字符串均作为替换的字符串。
例如,有如下宏定义:
#define MAX (a,b) (a>b)? (a): (b)
//则MAX被当作无参数宏的宏名,“(a,b) (a>b)? (a): (b)"为要替换的字符串。
②形参列表由个或多个参数构成,参数只有参数名,没有数据类型说明符,参数
之间用逗号隔开,参数名必须是合法的标识符。
在处理带参数的宏时,预处理程序首先将宏的内容文本中的形参替换成实参,这样就形成
宏的实际内容文本,然后再用宏的实际内容文本替换源程序中的宏名。带参数的宏调用的一
最格式如下:
宏名(实参列表)
说明:
①实参列表由一个或多个参数构成,与宏的形参列表一一对应 ,实参可以是常量、
变量或表达式,参数之间用逗号隔开。
②带参数的宏在使用时,若参数为表达式,应将宏参数用“( )”括起来。例如,有
如下宏定义:
#define SQRT(a) a*a
3.函数与宏定义的区别
(1)宏定义中形参不分配存储空间,因此不必进行数据类型说明;而函数在调用时要为
参分配临时的存储空间,因此形参需要进行数据类型说明。
(2) 函数调用时,先计算实参表达式的值,然后再将其传递给对应的形参;而带参数的工
定义则对实参表达式不做计算而是将字符串进行原样替换。
(3)丽数通过函数名只能返回一个计算结果; 而宏定义可以得到多个计算结果。
二、文件包含
文件包含是指一个源文件可以将另个源 文件的内容包含进来。一般格式如下
linclude <文件名>
或
include“文件名"
文件包含#include命令的预处理就是将被包含的文件的内容插人源程序中,如图:
说明:
①文件包含命令可以使用尖括号“< >”和双引号" "
这两种形式的区别在于:
使用双引号则表示首先在源文件当前目录中查找,若未找到才到存放C库函数头文件
所在的目录中查找。使用尖括号表示在存放C库函数头文件所在的目录中查找(由用
户在设置编译环境时进行设置)。
②一个include 命令只能指定一个被包含文件,若有多个文件包含,则用多个include命令。
③文件包含允许嵌套。
三、条件编译
1. #ifdef...#else...#endif
语法格式如下:
#ifdef 宏名
程序段1
#else
程序段2
#endif
功能:如果”宏名”已经用#define命令定义过,则编译“程序段1”;否则编译”程序段2”。
说明:①如果没有“程序段2”,则本格式中的#else部分可以没有,但#endif必须存在,即
可以写成:
#ifdef 宏名
程序段1
#endif
②"#ifdef 宏名”的含义是判断是否定义了宏。
2.#ifndef...#else...#endif
#ifndef 宏名
程序段1
#else
程序段2
#endif
功能:如果宏名没有用define命令定义过则编译“程序段1”,否则编译“程序段2,刚好与第一种格式的功能相反。
例如:
#ifndef A
a=32;
#else
a=16;
#endef
//上述条件编译命令表示,如果宏名A没有用#define定义过,则编译“a=32",否则编译“a=16”。
3.#if...#else...#endif
#if 常量表达式程序段1
#else
程序段2
#endif
功能:如果常量表达式的值为真(非0)则编译“程序段1”否则编译程序段2。
说明:1.常量表达式中不能包含变量名,通常会用到宏名,可以不加括号()
2.如果没有程序段2则本格式中的#else部分可以省略,但#endif必须存在。
4.#if...#elif...#endif
#if 常量表达式1
程序段1
#elif 常量表达式2
程序段2
#else
程序段3
#endif
功能:如果常量表达式1的值为真(非0)则编译程序段1,否则判断常量表达式2,如果值为真(非0)则编译程序段2,否则编译程序段3。
本期博客到这里结束啦~如果对你有用的话点个赞收藏吧!