宏是C程序的预处理命令之一。在C语言程序开发中是经常使用的,使用其的主要目的是方便程序员的编程工作,并且能在一定程度上提高程序的效率。C语言中
提供的宏定义命令是#define。下面就使用宏的几个小细节进行一些讨论。
1.宏中使用()
在宏中,尽量多使用(),不要觉得无所谓或者觉得使用不使用没有什么影响。请切记,在宏中尽量多使用(),这样才能尽量的保证你的宏的正确性。
举个例子:
#define CAL(x,y) x+y
CAL(2,4)×CAL(2,5)
程序员的本意可能是要计算(2+4)×(2+5),但是事与愿违,这个宏展开来是这样的 2+4×2+5,与所要的结果完全不相符。
比较合理的定义应该是 #define CAL(x,y) ((x)+(y)),以避免不必要的歧义。
2.重复宏定义
尽量不要重复的定义宏,那样会另程序的可读性变的很差,并且容易出错,难以维护。重复的宏定义以最后一次定义为准。
例子:
#define PI 3.14
#define PI 10.48
那么在程序中PI的值应该是10.48,因为这是最后的定义。
3.危险的宏定义
宏定义在使用不当的时候会很危险,胡乱的定义会混淆程序员的思维,例如:
#define int char
#define break continue
这样的宏定义是相当的危险,会使程序变的相当的混乱,难以阅读,难以维护。
4.宏中的#与##
宏中的#可以将字符转变成字符串,而##则可以进行宏参数拼接。
例如:
#define SUM(a,b) printf(" a add b is %d \n ", ((a)+(b)));
在程序中这样使用该宏:SUM(1,2) 则输出为 a add b is 3
请注意引号中的a和b被当作了普通的文本,而不是可以被替换的符号。如果想让a和b成为被替换的符号,可以这样定义该宏:
#define SUM(a,b) printf(" #a add #b is %d \n ", ((a)+(b)));
在程序中这样使用该宏:SUM(1,2) 则输出为 1 add 2 is 3
和#运算符一样,使用##也可以用于宏的替换部分,该符号可以把两个符号拼接成一个符号。例子如下:
#define NAME(x,y) x##y
在程序中这样使用该宏:NAME(Steve, Johnson) 则该宏会被展开成这样: SteveJohnson
5.宏定义注意分号;的使用
宏定义中注意分号的使用,在宏定义中胡乱使用分号会使程序出现一些莫名其妙的错误。
例如:
#define SUM(a,b) ((a)+(b));
在程序中这样使用该宏:SUM(a1,b1)+SUM(a2,b2)
这样宏展开后就会变成((a1)+(b1));+((a2)+(b2)) 这样程序就会出错。
6.一个有趣的关于宏的测试题:
<span style="font-size:14px;">#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define num 10
#define f(x) #x
#define g(x) f(x)
int main()
{
printf("f(num)=%s g(num)=%s \n",f(num),g(num));
}
</span>
这是一个很有趣的关于宏的小题目,大家可以想想输出结果是什么。
我们可以使用命令 gcc -E marco.i marco.c > a.txt 去将预处理的结果存到a.txt文件里去查看,main函数经过预处理的结果是:
int main()
{
printf("f(num)=%s g(num)=%s \n","num","10");
}
我们可以看到f(x) 由于有#符号,因此num没有被替换成10,而g(x) 应该先被替换成f(x),于此同时将num替换成了10,变成了#10,因此结果是num 和 10。
c语言 #define 中的UL
U和L是 整数文字量的后缀修饰,用于显示指明整数文字量的类型为unsigned int(U)和long int(L)。类似的还有浮点数文字量的后缀修饰F或f,用于指明文
字量表示的是一个float,而不是默认情况下的double。经常发现一些C语言中通过#define 定义的数据中包含有UL符号,不理解为什么,把他去掉发现也没有什
么区别。现在才明白UL是标记该宏长整型 十进制 数据,而不是字符,也不是int型数据。
C语言中默认宏中的数字是整型数据
如下面的例子:
#define LENGTH (20UL*1024*1024)
你要输出他的话就要这样:
printf(“LENGTH is %ld/n”,LENGTH);
例如;
#include <stdio.h>
#define SECONDS_PER_YEAR 60*60*24*365UL
//加UL是为了防止将它赋值给一个int 型变量而产生溢出,但我在VC2010 //上运行,竟然没有出错,不知为什么?
#include "stdio.h" //在VC2010上运行,将输出SECONDS_PER_YEAR=31536
#define SECONDS_PER_YEAR 60*60*24*365
int main(){
int s = SECONDS_PER_YEAR;
printf("SECONDS_PER_YEAR=%d\n",s);
}
int main(void)
{
unsigned long int a = SECONDS_PER_YEAR;
printf("a = %ld/n",a);
return 0;
}
输出结果为 a = 31536000;
注意:不能将
#define SECONDS_PER_YEAR 60*60*24*365UL 写成
#define SECONDS_PER_YEAR (60*60*24*365)UL在
编译GCC程序,提示这个错误 error: expected ‘,’ or ‘;’ before ‘UL’;是因为UL写在了括号外面,无法与数据进行匹配