0
#include<stdio.h>
#include<stdlib.h>
int main() {
int a=3;
//case 1
printf("%d %d %d\n",(--a),(a--),(--a));//output is 0 2 0 
printf("%d\n",a);//here the final value of 'a'
//end of case 1
a=3;
//case 2 
printf("%d\n",(++a)+(a--)-(--a));//output is 5 value of a is 2
printf("%d\n",a);//here the final value of 'a'
//end of case 2
a=3;
//case 3 
printf("%d\n",(++a)*(a--)*(--a));//output is 48  value of a is 2
printf("%d\n",a);//here the final value of 'a'
//end of case 3
//case 4 
int i=3,j;
i= ++i * i++ * ++i;
printf("%d\n",i);//output is 81
i=3;
j= ++i * i++ * ++i;
printf("%d\n",j);//output is 80
//end of case 4
return 0;
}

我很清楚这些输出是如何产生的,因为我花了近 3 个小时盯着它看,但我想详细了解的是为什么以这种方式进行或评估它。

  1. 这是一个棘手的判断 printf 从右到左求值,所以首先 --a 推 2 ,然后 a-- 再次推 2 ,因为它是发布的,然后 a 变成 1 ,然后 --a 先是 a 0 然后把它推到 and我只是猜测输出将是 0 2 2 但令我惊讶的是它是 0 2 0 然后我得到 a=0 的最终值被赋予了我使用 pre increment 和 decrement 的所有地方。为什么会这样?

  2. 这我把它作为正常的评估,然后打印 a 是 4 然后在 a-- 再次将 a 作为 4 并再次在 --aa 中作为 3 所以 4+4-3=5 完成然后 a 的最终值发生从中间完成的后减量中成为一个 -1 所以 a 再次变为 2 为什么会发生这种情况?

  3. 此执行与上面相同,需要 4 * 4 * 3 = 48,最终 a 值为 2。

  4. 这并不棘手,但我想详细回答我想的是,首先 i 在 ++i 中变为 4,在 i++ 处 i 变为 4,然后在 ++ii 处变为 5,然后 4*4*5 = 80在这种情况下,我将其存储在 i 本身中,然后 i 变为 80,然后为后增量加 1。因此,当我将 80 存储在另一个变量 j 中然后看到它是 80 并且最终 i 值为 6 时,我可以做出一个明确的决定。

因此,从逻辑上讲,我从所有这些情况下仅打印和查看内容来判断,还有更多完全基于此的内容,我可以继续发布,所以我想要的是在组装层面它是如何发生的以及为什么要发布增量作为一个单独的状态或某事如何可以针对每个我无法继续打印的不同程序进行一般判断,并且找到模式可以有人在这里详细帮助我。最糟糕的是,我只是在 ideone 中执行了代码,并给了我完全不同的输出,如果你有兴趣,你甚至可以在 ideone 进行测试,所以为什么会发生这种情况,请有人告诉我,我在这件事上花了 3 个小时来帮助我专业人士。我使用 gcc 编译器。

4

1 回答 1

4

这都是未定义的行为,sequence points在这种情况下,不允许在同一个表达式中修改一个以上的变量。所以你根本不能依赖这个程序的输出。

c99 标准草案 6.5.2

在前一个和下一个序列点之间,对象的存储值最多只能通过表达式的评估修改一次。此外,应仅读取先验值以确定要存储的值。

它引用了以下未定义的代码示例:

i = ++i + 1;
a[i++] = i; 
于 2013-08-09T19:13:42.880 回答