(C语言)关于#DEFINE的问题

2024-10-31 17:21:12
有5个网友回答
网友(1):

第一个定义:
#define MIN(x,y) (x)<(y)?(x):(y)
int i=10,j=15,k;
k=10*MIN(i,j)实际上被编译成:k = 10*(i)<(j)?(i):(j)
而10*i=100 大于昌锋 j=10,所以k=j=15;
如果想得出期望的结果,应该这样写:k=10*(MIN(I,j));

第二个定义:
#define M(x,y,z) x*y+z
int a=1,b=2,c=3;
M(a+b,b+c,c+a)被编译成: M= a+b*b+c+c+a =1+2*2+3+3+1 = 12;
如果想要得到期望的结果,应该这凯迅罩样定义:#define M(x,y,z) (x)*(y)+(z)

第三个定义:
#define M(x) x*(x-1)
int a=1,b=2;
M(1+a+b)被编译成: M= 1+a+b*(1+a+b-1) =1+1+2*(1+1+2-1) = 8
如果想要得到期盯闹望的结果,应该这样定义:#define M(x) (x)*(x-1)

网友(2):

首先,这个运行结果是正常的,是你在写宏定义的时候不太规范,解决方法:
在宏定义里把用到的所有的宏参数都加上括号
比如第二个改成:#define M(x,y,z) (x)*(y)+(z)
第三个改成:#define M(x) (x)*((x)-1)
这样的话程序就是按你想的方式运行了

原理:#define的功能
#define 是预编译指令,它相当于程序员与编译器间的一个协议,用#define可以定义很多东西,包括简短的代码段(长代码段也可以,就是麻烦点)。当出现“#define A B”这样的宏定义后,编译器编译程序前会把代码中所有出现的A换成B再进行编译,就是说#define的功能相当于就是语句(字符串)替换,宏里用到的参数也只是语句替换,而不是语句值的替换。具体点,举你说的例子

对袜友于M(x,y,z) x*y+z,当编译器遇到M(a+b,b+c,c+a)这样的宏时,会将它展开成 a+b * b+c + c+a,就是直接把a+b这个蔽好谈语句放到x的位置,把b+c这宏碰个语句放到y的位置,把c+a这个语句放到z的位置,而不是将a+b这个整体的值当做x的值再代入到x*y+z中运算,这点跟函数调用是不一样的。这样的话( a+b * b+c + c+a ),程序运行起来就是先算b*b的值,再算剩下的加法,最后得到的值就是 1+2*2+3+3+1=12。

而在宏定义里的参数上加上括号后,比如:#define M(x,y,z) (x)*(y)+(z),这样M(a+b,b+c,c+a)预编译后就是 (a+b) * (b+c) + (c+a),这样结果就想你想的那样了。

网友(3):

#define
m(x,y,z)
x*y+z
展开此稿裤宏时不能自行加括号,直接原亏坦形键空简展开即可
由int
a=1,b=2,c=3;
得m(a+b,b+c,c+a)=a+b*b+c+c+d=1+2*2+3+3+1=12

网友(4):

牢记:#define操作只是简单地作文字替换,基庆所搏斗握以在有操作符存在的时候一定要注意加括号。
1. #define MIN(x,y) (x)<(y)?(x):(y)
应该改成#define MIN(x,y) ((x)<(y)?(x):(y))
2.#define M(x,y,z) x*y+z
应该改成#define M(x,y,z) ((x)*(y)+(z))
3.#define M(x) x*(x-1)
应该改成#define M(x) ((x)*(x-1))

加了括号以后,可以防止“调用”时产生的运算符优先级出错。建议楼主销碰养成加括号的好习惯。

网友(5):

#define 是展开,是替换代扮搏知码。比厅消如最后一个M(1+a+b),展开就是银销1+a+b*(1+a+b-1) == 8