鱼C论坛

 找回密码
 立即注册
查看: 1293|回复: 11

[已解决]C语言 为什么等于1呢

[复制链接]
发表于 2020-2-22 20:25:25 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
#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);
}
最佳答案
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

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-2-22 20:28:47 | 显示全部楼层
本帖最后由 zltzlt 于 2020-2-22 20:38 编辑

发错了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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))
        试试呢。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

//这一句宏展开 ...

        (X) * (X) 和原来的写法完全一样,必须改成 (X * X) 才对!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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))
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-2-23 09:34:53 | 显示全部楼层
a=10/(2+2+0+2+1)=10/7=1
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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))最好
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-3-2 13:03:57 | 显示全部楼层
jackz007 发表于 2020-2-22 23:06
(X) * (X) 和原来的写法完全一样,必须改成 (X * X) 才对!

(X*X)是(k+m*k+m)也不对
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-3-7 11:56:23 | 显示全部楼层
把宏定义写成((x)×(x))
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-4-2 16:01:01 | 显示全部楼层
写宏的时候能括号的尽量括号,看下甲鱼 关于宏的那一章
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-15 13:05

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表