C语言 为什么等于1呢
#include "stdio.h"#define SQR(X) X*X
main()
{
int a=10,k=2,m=1;
a/=SQR(k+m)/SQR(k+m);
printf("%d\n",a);
} 本帖最后由 zltzlt 于 2020-2-22 20:38 编辑
发错了 本帖最后由 jackz007 于 2020-2-23 13:04 编辑
a /= SQR(k + m) / SQR(k + m)
把宏展开后是下面这样:
a = a / ((k + m) * (k + m) / (k + m) * (k + m))
= a / ((k + m) * (k + m))
= 10 / 9
= 1
所以,后面结果是 1,而不是正确答案 10
原因是当 SQR(X) 成为分母的时候,1 / SQR(X) 不会展开成我们所预期的 1 / (X * X),而是展开成 1 / X * X,于是,这样就出问题了。
为了避免出现这个问题,需要对宏定义进行修改:
#define SQR(X) X*X
改为
#define SQR(X) ((X)*(X))
试试呢。
本帖最后由 major_lyu 于 2020-2-23 11:23 编辑
你要理解与函数调用不同的是,宏展开是单纯的字符替换,不会先对宏参数进行求值在展开.
a/=SQR(k+m)/SQR(k+m);
//这一句宏展开的形式如下:
a/=k+m*k+m/k+m*k+m
带入数据a= 10/(2+1*2+1/2+1*2+1)=10/(2+2+0+2+1)=10/7=1
想要获得正确的值可以定义
#define SQR(X) ((X)*(X))
这样SQR(k+m)展开就是(k+m)*(k+m)了
a /= SQR(k+m)/SQR(k+m)展开就是
a = a / (((k+m)*(k+m))/((k+m)*(k*m)))= 10/((3*3)/(3*3))=10/1 =1
major_lyu 发表于 2020-2-22 22:25
你要理解与函数调用不同的是,宏展开是单纯的字符替换,不会先对宏参数进行求值在展开.
//这一句宏展开 ...
(X) * (X) 和原来的写法完全一样,必须改成 (X * X) 才对! 本帖最后由 major_lyu 于 2020-2-22 23:38 编辑
jackz007 发表于 2020-2-22 23:06
(X) * (X) 和原来的写法完全一样,必须改成 (X * X) 才对!
#define SQR(X)(X*X)
SQR(k+m)展开就是 (k+m*k+m);
a = a /((k+m*k+m)/(k+m*k+m)) = 10/1=10, 是和答案一样
但是,可以看到SQR宏的定义是想求参数的平方,按照你给的定义,你可以计算一下SQR(1+2)和SQR(3)看两个一样不?
如果要把SQR(X)的值当作整体代入,并且还要求参数表达式的值处于最高运算优先级,那么应该如下定义
#define SQR(X)((X)*(X)) a=10/(2+2+0+2+1)=10/7=1 本帖最后由 无所谓-浪 于 2020-2-29 15:28 编辑
a/=SQR(k+m)/SQR(k+m);
你这一句按程序走应该是:
a=10/((2+1)*(1+2)/(2+1)*(2+1))
=10/(3*1*3)
=10/9
=1 (输出为整型)
仅对该题而言
改为#define SQR(X) (X*X)足矣
若要确保精细
改为#define SQR(X) ((X)*(X))最好 本帖最后由 大河之jian 于 2020-3-2 13:01 编辑
由于/比/=优先级别高,所以先算/两边的为2+1*2+1/2+1*2+1,算出来为7
a/=7=1.4
由于a是以整型输出,所以小数点后面的省略,因此结果为1 jackz007 发表于 2020-2-22 23:06
(X) * (X) 和原来的写法完全一样,必须改成 (X * X) 才对!
(X*X)是(k+m*k+m)也不对
把宏定义写成((x)×(x)) 写宏的时候能括号的尽量括号,看下甲鱼 关于宏的那一章
页:
[1]