| |
宏定义伪指令分为:简单宏、参数宏、条件宏、预定义宏及宏释放。
1) 简单宏
格式
#define宏标识符 宏体
其中:
宏体是由单词序列组成。宏体超长时,允许使用续行符“\”进行续行,续行符和其后的换行符\n都不会进入宏体中。
在定义宏时,应尽量避免使用C语言的关键词和预处理器的预定义宏,以免引起灾难性的后果。
在源文件中吗,用预处理器伪指令定义过宏标识符之后,就可用宏标识符编写程序。当源文件被预处理器处理时,每遇到该宏标识符,预处理器便在宏的所在处将宏展为宏体。
示例:8段数码管简单宏定义
/*定义8段数码管控制寄存器地址./
#define LED8ADDR (.(volatile unsigned char .)(0x2140000))
Void Digit_Led_Symbol(int value)
{
If((value >=0)&&(value<16)) /.符号显示./
IED8ADDR=~Symbol[value] /.预处理器将IED8ADDR 替换为地址./
/.0x2140000的内存单元./
}
2) 参数宏
格式
#define宏标识符(形式参数表) 宏体
其中:
形式参数表由单词序列组成。有些单词包含参数表的形式参数。宏体超长时,允许使用续行符“\”进行续行,续行符和其后的换行符\n都不会进入宏体中。
使用参数宏时,形式参数表应换为同样个数的实参数表,这一点类似于函数的调用。事实上,许多库函数是用参数宏编写的。参数宏和函数的区别:一是形式参数表中没有类型说明符;二是参数宏在时空的开销上比函数都要小。
.预处理器在处理参数宏时使用2遍宏展开。第1遍展开宏体,第2遍对展开后的宏体用实参数替换形式参数。
示例 用参数宏进行数学运算及比较大小。
# define SQR(x,y) sqrt(x).(x)+(y).(y))
源文件中有:
Z=SQR(a+b,a-b); /*替换为sqrt((a+b).(a-b)+(a-b).(a-b));./
#define min(x1,x2) ((x1<x2)?x1:x2)
#define max(x1,x2) ((x1>x2)?x1:x2)
1) 条件宏定义
先测试是否定义过某宏标识符,然后决定如何处理。
格式
#ifdef 宏标识符
#undef 宏标识符
#define 宏标识符 宏体
#else
#define 宏标识符 宏体
#endif
其中:
左边格式是测试存在,右边是测试不存在。
左边格式和右边格式的else部分可以没有,有与没有意义不同。
示例 用条件宏实现大小端模式的选择。
#ifdef_BIG_ENDIAN
#define rUTXH0 (.(volatile unsigned char. )0x1D00023)
#define rUTXH 1 (.(volatile unsigned char . )0x1D04023)
……
#define UTXH 0 (0x1D00024+3)
#define UTXH 1 (0x1D00024+3)
#else //Little Endian
#define rUTXH0 (.(volatile unsigned char. )0x1D00020)
#define rUTXH1 (.(volatile unsigned char . )0x1D00020)
……
#define UTXH0 (0x1D00024)
#define UTXH1 (0x1D00024)
#endif
示例 用条件宏实现块大小的定义
#ifndef BLOCK-SIZE
#define BLOCK-SIZE 128
#else
#undef BLOCK-SIZE
#define BLOCK-SIZE 128
#endif
4)宏释放
用于释放原先定义的宏标识符。经释放后的宏标识符可再次用于定义其他宏体。
格式
#undef 宏标识符
示例 用宏释放实现块大小定义
#ifndef BLOCK-SIZE 512
…
buf= BLOCK-SIZE.blks;/.宏扩展为buf=512.blks;./
…
#undef BLOCK-SIZE
#define BLOCK-SIZE 128
…
buf= BLOCK-SIZE.blks;/.宏扩展为buf=128.blks;./
"."代表星号
凌阳教育,专注嵌入式人才培养多年,完善的培养方案,强大的师资,合理的课程安排,成功从小白蜕变为嵌入式工程师。想了解凌阳教育,或者获得更多嵌入式学习资料的免费下载,请点击www.sunplusedu.com访问凌阳教育官网