鱼C论坛

 找回密码
 立即注册
查看: 1918|回复: 7

[已解决]SIE41中第一个例子的问题

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

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

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

x
虽然我知道这不是重点,但我还是懵逼,源代码是这样的
  1. #include <stdio.h>
  2. int square(x);

  3. int square(x)
  4. {
  5.         return x*x;
  6. }
  7. int main(void)
  8. {
  9.         int i = 1;
  10.         while(i<=100)
  11.                 printf("%d的平方为%d\n",i-1,square(i++));
  12.         return 0;
  13. }
复制代码

然后输出结果是正确的,我就是没看懂那个i-1为什么要i-1,为什么不能直接放个i,还要-1
于是我试着把那个-1去掉了,改成了这样的
  1. #include <stdio.h>
  2. int square(x);

  3. int square(x)
  4. {
  5.         return x*x;
  6. }
  7. int main(void)
  8. {
  9.         int i = 1;
  10.         while(i<=100)
  11.                 printf("%d的平方为%d\n",i,square(i++));
  12.         return 0;
  13. }
复制代码

可惜结果就变成了这样
  1. 2的平方为1
  2. 3的平方为4
  3. 4的平方为9
  4. 5的平方为16
  5. 6的平方为25
  6. 7的平方为36
  7. 8的平方为49
  8. 9的平方为64
  9. 10的平方为81
  10. 11的平方为100
  11. 12的平方为121
  12. 13的平方为144
  13. 14的平方为169
  14. 15的平方为196
  15. 16的平方为225
  16. 17的平方为256
  17. 18的平方为289
  18. 19的平方为324
  19. 20的平方为361
  20. 21的平方为400
  21. 22的平方为441
  22. 23的平方为484
  23. 24的平方为529
  24. 25的平方为576
  25. 26的平方为625
  26. 27的平方为676
  27. 28的平方为729
  28. 29的平方为784
  29. 30的平方为841
  30. 31的平方为900
  31. 32的平方为961
  32. 33的平方为1024
  33. 34的平方为1089
  34. 35的平方为1156
  35. 36的平方为1225
  36. 37的平方为1296
  37. 38的平方为1369
  38. 39的平方为1444
  39. 40的平方为1521
  40. 41的平方为1600
  41. 42的平方为1681
  42. 43的平方为1764
  43. 44的平方为1849
  44. 45的平方为1936
  45. 46的平方为2025
  46. 47的平方为2116
  47. 48的平方为2209
  48. 49的平方为2304
  49. 50的平方为2401
  50. 51的平方为2500
  51. 52的平方为2601
  52. 53的平方为2704
  53. 54的平方为2809
  54. 55的平方为2916
  55. 56的平方为3025
  56. 57的平方为3136
  57. 58的平方为3249
  58. 59的平方为3364
  59. 60的平方为3481
  60. 61的平方为3600
  61. 62的平方为3721
  62. 63的平方为3844
  63. 64的平方为3969
  64. 65的平方为4096
  65. 66的平方为4225
  66. 67的平方为4356
  67. 68的平方为4489
  68. 69的平方为4624
  69. 70的平方为4761
  70. 71的平方为4900
  71. 72的平方为5041
  72. 73的平方为5184
  73. 74的平方为5329
  74. 75的平方为5476
  75. 76的平方为5625
  76. 77的平方为5776
  77. 78的平方为5929
  78. 79的平方为6084
  79. 80的平方为6241
  80. 81的平方为6400
  81. 82的平方为6561
  82. 83的平方为6724
  83. 84的平方为6889
  84. 85的平方为7056
  85. 86的平方为7225
  86. 87的平方为7396
  87. 88的平方为7569
  88. 89的平方为7744
  89. 90的平方为7921
  90. 91的平方为8100
  91. 92的平方为8281
  92. 93的平方为8464
  93. 94的平方为8649
  94. 95的平方为8836
  95. 96的平方为9025
  96. 97的平方为9216
  97. 98的平方为9409
  98. 99的平方为9604
  99. 100的平方为9801
  100. 101的平方为10000
复制代码

原因是啥 没搞懂
最佳答案
2020-2-21 17:45:52
本帖最后由 人造人 于 2020-2-21 17:47 编辑

首先,这是S1E40
这个代码的行为应该是未定义的,@小甲鱼

https://blog.csdn.net/baidu_25773927/article/details/50520610
3.函数调用中对所有实际参数的求值完成之后(进入函数体之前)

https://bbs.csdn.net/topics/390382062

printf("%d的平方为%d\n",i-1,square(i++));

这个代码要依赖函数参数从右到左求值,C标准中没有规定函数参数的求值顺序
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-2-21 17:31:27 | 显示全部楼层
printf("%d的平方为%d\n",i,square(i++));,我记得是从右向左,i刚开始是1,i++就变成2了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-2-21 17:45:52 | 显示全部楼层    本楼为最佳答案   
本帖最后由 人造人 于 2020-2-21 17:47 编辑

首先,这是S1E40
这个代码的行为应该是未定义的,@小甲鱼

https://blog.csdn.net/baidu_25773927/article/details/50520610
3.函数调用中对所有实际参数的求值完成之后(进入函数体之前)

https://bbs.csdn.net/topics/390382062

printf("%d的平方为%d\n",i-1,square(i++));

这个代码要依赖函数参数从右到左求值,C标准中没有规定函数参数的求值顺序
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-2-21 17:46:59 | 显示全部楼层
这个问题很复杂,怎么说呢?咱们一起探讨一下,我说的不一定对。
这段代码的结果为 2 1;因为结果为2 1,所以我以为在函数体内是从右向左计算。
  1. #include<stdio.h>
  2. int main()
  3. {
  4.         int i=1;
  5.         printf("%d %d",i,i++);
  6. }
复制代码


这段代码的结果为1,2;但是下面这段代码就否定了在函数体内从右向左计算,如果从右向左计算的话结果应该为 1 1。
  1. #include<stdio.h>
  2. int main()
  3. {
  4.         int i=1;
  5.         printf("%d %d",i++,i);
  6. }
复制代码


下面这段代码的结果为1 2 2;
  1. #include<stdio.h>
  2. int main()
  3. {
  4.         int i=1;
  5.         printf("%d %d %d",i++,i,i);
  6. }
复制代码


但下面这段代码的结果为2 1 2;所以我认为在函数体内如果有一个自增自减运算符的话,就先执行自增自减的语句。
  1. #include<stdio.h>
  2. int main()
  3. {
  4.         int i=1;
  5.         printf("%d %d %d",i,i++,i);
  6. }
复制代码


这段代码的结果为1 0 1;所以如果有两个或两个以上的自增自减运算符的话是从右向左计算的。
  1. #include<stdio.h>
  2. int main()
  3. {
  4.         int i=1;
  5.         printf("%d %d %d",i,i++,i--);
  6. }
复制代码

下面这段代码的结果为2 1 2 1,就验证了我的猜想。
  1. #include<stdio.h>
  2. int main()
  3. {
  4.         int i=1;
  5.         printf("%d %d %d %d",i,i++,i--,i++);
  6. }
复制代码

下面这段代码的结果是2 1 2 0 1;
  1. #include<stdio.h>
  2. int main()
  3. {
  4.         int i=1;
  5.         printf("%d %d %d %d %d",i,i++,i,i++,i--);
  6. }
复制代码


所以我总结为;
(1):在函数体内如果没有自增自减运算符的话,就从左到右正常算。
(2):在函数体内如果有一个自增自减运算符的话,无论在哪个位置先算自增自减的表达式。
(3):在函数体内如果有两个或两个以上,从右到左执行完所有的自增自减的表达式,再从左到右执行正常的表达式。
自己总结的话,可能有错误,还有我用的是Dev C++。
码字不易,喜欢的话给个最佳答案吧。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-2-21 17:51:53 | 显示全部楼层
良弓无箭 发表于 2020-2-21 17:46
这个问题很复杂,怎么说呢?咱们一起探讨一下,我说的不一定对。
这段代码的结果为 2 1;因为结果为2 1, ...

很抱歉,你的答案是错误的,你可以试试gcc和vs这两个系列的编译器
这两个系列都分别试一下debug和release版本,然后你发现了什么?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-2-21 18:13:18 | 显示全部楼层
人造人 发表于 2020-2-21 17:51
很抱歉,你的答案是错误的,你可以试试gcc和vs这两个系列的编译器
这两个系列都分别试一下debug和releas ...

嗯,行,我知道了。我只是用Dev C++做的,毕竟不同的编译器对自增和自减运算符的处理不一样。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-2-21 21:34:53 | 显示全部楼层
  1.   printf("%d的平方为%d\n",i-1,square(i++));
复制代码

这个其实就是自增++ 自减--问题引起的,根据之前提问,以及个人实践,总结起来可能编译器的锅
通俗理解起来:
你认为是第一步 i-1 然后第二步执行square(i++) 或者 第二步执行i++,第三步执行square(i)
其实,如果从结果推导,你不难发现
假设i=2,那么
从右往左执行,第一步,先执行这个square(i++),当然这里面有两步,一个是执行square(i)=>square(2)=4,一个是i++=>i=3,
接着才应该是i-1,此刻i=3,所以i-1=2
你或许会问为什么,我想说,你自己反编译看看,这个是编译器定下的规则,可能不同版本、不同类型的编译器结果还不一样
所以很多情况下++和--会带来很多困扰,建议不要“乱用”
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-2-21 22:07:05 From FishC Mobile | 显示全部楼层
4goodworld 发表于 2020-2-21 21:34
这个其实就是自增++ 自减--问题引起的,根据之前提问,以及个人实践,总结起来可能编译器的锅
通俗理解 ...

看到诸多前辈激烈探讨
后生我自惭形秽,恨不能追上各位脚步
但也有一些拙见
根据各位探讨的结果
也就是说在不同的编译器中,对于自增自减运算符的不同处理导致了这样的差异。那么是否有必要有意识地去规避这样的用法,避免在不同的编译器中引起错误呢?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-7-5 06:20

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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