淡笑无痕丶 发表于 2020-2-21 17:21:22

SIE41中第一个例子的问题

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

int square(x)
{
        return x*x;
}
int main(void)
{
        int i = 1;
        while(i<=100)
                printf("%d的平方为%d\n",i-1,square(i++));
        return 0;
}
然后输出结果是正确的,我就是没看懂那个i-1为什么要i-1,为什么不能直接放个i,还要-1
于是我试着把那个-1去掉了,改成了这样的
#include <stdio.h>
int square(x);

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

最后的魁拔 发表于 2020-2-21 17:31:27

printf("%d的平方为%d\n",i,square(i++));,我记得是从右向左,i刚开始是1,i++就变成2了

人造人 发表于 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标准中没有规定函数参数的求值顺序

良弓无箭 发表于 2020-2-21 17:46:59

这个问题很复杂,怎么说呢?咱们一起探讨一下,我说的不一定对。
这段代码的结果为 2 1;因为结果为2 1,所以我以为在函数体内是从右向左计算。
#include<stdio.h>
int main()
{
      int i=1;
      printf("%d %d",i,i++);
}

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

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

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

这段代码的结果为1 0 1;所以如果有两个或两个以上的自增自减运算符的话是从右向左计算的。
#include<stdio.h>
int main()
{
      int i=1;
      printf("%d %d %d",i,i++,i--);
}
下面这段代码的结果为2 1 2 1,就验证了我的猜想。
#include<stdio.h>
int main()
{
      int i=1;
      printf("%d %d %d %d",i,i++,i--,i++);
}
下面这段代码的结果是2 1 2 0 1;
#include<stdio.h>
int main()
{
      int i=1;
      printf("%d %d %d %d %d",i,i++,i,i++,i--);
}

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

人造人 发表于 2020-2-21 17:51:53

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

很抱歉,你的答案是错误的,你可以试试gcc和vs这两个系列的编译器
这两个系列都分别试一下debug和release版本,然后你发现了什么?

良弓无箭 发表于 2020-2-21 18:13:18

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

嗯,行,我知道了。我只是用Dev C++做的,毕竟不同的编译器对自增和自减运算符的处理不一样。

4goodworld 发表于 2020-2-21 21:34:53

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
你或许会问为什么,我想说,你自己反编译看看,这个是编译器定下的规则,可能不同版本、不同类型的编译器结果还不一样
所以很多情况下++和--会带来很多困扰,建议不要“乱用”

淡笑无痕丶 发表于 2020-2-21 22:07:05

4goodworld 发表于 2020-2-21 21:34
这个其实就是自增++ 自减--问题引起的,根据之前提问,以及个人实践,总结起来可能编译器的锅
通俗理解 ...

看到诸多前辈激烈探讨
后生我自惭形秽,恨不能追上各位脚步
但也有一些拙见
根据各位探讨的结果
也就是说在不同的编译器中,对于自增自减运算符的不同处理导致了这样的差异。那么是否有必要有意识地去规避这样的用法,避免在不同的编译器中引起错误呢?
页: [1]
查看完整版本: SIE41中第一个例子的问题