#define MAX 100
#define MIN 1
int main()
{
int i = MAX;
int q = MIN;
printf("i=%d q=%d\n", i, q);
return 0;
}
#define do_forever for(; ; )
#define n printf(“hello world\n”)
这里可能有人会有疑问为什么最后不加;
#define MAX 100;
#define MIN 1 ;
#define n printf("hello world\n") ;
int main()
{
int i = MAX;
int q = MIN;
printf("i=%d q=%d\n", i, q);
n;
return 0;
}
那我们把代码改一下
#define MAX 100;
#define MIN 1 ;
#define n printf("hello world\n") ;
int main()
{
int i = MAX;
int q = MIN;
if (i == 100)
n;
else
{
printf("错误\n");
}
printf("i=%d q=%d\n", i, q);
n;
return 0;
}
再运行一下,这时候就会报错
原因是什么呢?
仔细观察一下if语句,我们不难发现
代码变成
if (i == 100)
printf(“hello world\n”) ;
;
else
{
printf(“错误\n”);
}
很明显多了个;
因此,最好#define 最后不要加; 容易发生问题
#define 机制包括了一个规定,允许把参数替换到文本中,这种实现通常称为宏(macro)或定义宏(define macro)。
下面是宏的申明方式:
#define name( parament-list ) stuff
其中的 parament-list 是一个由逗号隔开的符号表,它们可能出现在stuff中。
例如:
#define a(n) n*n
定义宏的过程中也有一下要注意的
#define a(n) n*n
int main()
{
printf("%d\n", a(1 + 2));
return 0;
}
相信不少人会认为结果是9,让我们来运行一下
结果为什么是5而不是9呢?
在预编译过程中,上面代码会变成
printf(“%d\n”, 1+2*1+2);
由此我们可以得知,上面的#define最好改成
#define a(n) (n)*(n)
那这样改就没问题了吗?
我们再来看下面的代码
#define a(n) (n)+(n)
int main()
{
printf("%d\n",10*a(1 + 2));
return 0;
}
运行一下
居然不是我们想要的60,而是33,不过相信大家都已经发现了问题的所在
在预编译过程中,上面代码会变成
printf(“%d\n”,10*(1 + 2)+(1+2));
自然就是33了
相信大家都知道要怎么改了
#define a(n) ((n)+(n))
int main()
{
printf("%d\n",10*a(1 + 2));
return 0;
}
所以用于对数值表达式进行求值的宏定义都应该用这种方式加上括号,避免在使用宏时由于参数中的操作符或邻近操作符之间不可预料的相互作用。
这里还有一个小的点,
#define name( parament-list ) stuff
参数列表的左括号必须与name紧邻。
如果两者之间有任何空白存在,参数列表就会被解释为stuff的一部分。
当宏参数在宏的定义中出现超过一次的时候,如果参数带有副作用,那么你在使用这个宏的时候就可能出现危险,导致不可预测的后果。副作用就是表达式求值的时候出现的永久性效果。
例如:
#define a(n,m) ((n)>(m)?(n):(m))
int main()
{
int i = 1;
int j = 2;
int k=a(i++,j++);
printf("%d\n", i);
printf("%d\n", j);
printf("%d\n", k);
return 0;
}
在预编译过程中,上面代码会变成
int k=((i++)>(j++)?(i++):(j++)
这里因为j>i,所以j++了2次
所以遇到这种情况要小心会不会带来副作用
一般来讲函数的宏的使用语法很相似。所以语言本身没法帮我们区分二者。因此我们平时的习惯是:
把宏名全部大写
函数不要全部大写