@HJR 发表于 2020-2-22 20:25:25

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:28:47

本帖最后由 zltzlt 于 2020-2-22 20:38 编辑

发错了

jackz007 发表于 2020-2-22 21:25:18

本帖最后由 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-22 22:25:31

本帖最后由 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

jackz007 发表于 2020-2-22 23:06:20

major_lyu 发表于 2020-2-22 22:25
你要理解与函数调用不同的是,宏展开是单纯的字符替换,不会先对宏参数进行求值在展开.

//这一句宏展开 ...

      (X) * (X) 和原来的写法完全一样,必须改成 (X * X) 才对!

major_lyu 发表于 2020-2-22 23:36:24

本帖最后由 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))

@HJR 发表于 2020-2-23 09:34:53

a=10/(2+2+0+2+1)=10/7=1

无所谓-浪 发表于 2020-2-29 15:24:38

本帖最后由 无所谓-浪 于 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 12:57:34

本帖最后由 大河之jian 于 2020-3-2 13:01 编辑

由于/比/=优先级别高,所以先算/两边的为2+1*2+1/2+1*2+1,算出来为7
a/=7=1.4
由于a是以整型输出,所以小数点后面的省略,因此结果为1

大河之jian 发表于 2020-3-2 13:03:57

jackz007 发表于 2020-2-22 23:06
(X) * (X) 和原来的写法完全一样,必须改成 (X * X) 才对!

(X*X)是(k+m*k+m)也不对

就是要努力呀 发表于 2020-3-7 11:56:23

把宏定义写成((x)×(x))

召唤师 发表于 2020-4-2 16:01:01

写宏的时候能括号的尽量括号,看下甲鱼 关于宏的那一章
页: [1]
查看完整版本: C语言 为什么等于1呢