This question already has answers here:
Closed last year.
Why are these constructs using pre and post-increment undefined behavior?
(14个答案)
有人能给我解释一下为什么这个代码会打印减少的数量吗?因为(4
但关键问题是,
您可能认为必须从左到右计算代码,
如果是从左到右,那么我们有
评估结果为
评估结果为
评估结果为
这是错误的,所以你可能希望它打印“嗨”。但是,如果从右到左估计的话
评估结果为
评估结果为
这是真的。
(你会注意到我已经删除了一些额外的括号,因为它们什么都不做。)
我赶紧补充说,这并不是唯一的两种可能性。规则规定,一旦一个表达式没有定义,任何事情都可能发生——行为不必是我们认为“合理”的任何事情。
那为什么还没有定义呢?在本例中,这是因为您有一个变量--
那你怎么解决呢?答案很简单,这是一个老笑话的意思:不要那样做。不要在修改和使用单个变量(或其他对象)的情况下编写表达式。写
像这样的问题经常出现。其他人已经将您重定向到的规范的SO答案是在问题Why are these constructs (using ++) undefined behavior in C?下收集的。关于未定义表达式的规则,我可以说得更多,但在这个问题上,你可以找到那些细节。
(14个答案)
有人能给我解释一下为什么这个代码会打印减少的数量吗?因为(4
int main()
{
int amount = 4;
if((amount%5) <= (--amount))
printf("%d", amount);
else
printf("Hi");
}
最佳答案
原来这段代码是未定义的。你有这个表情
(amount%5) <= (--amount)
但关键问题是,
amount%5
部分在被amount
部分递减后是使用--amount
的旧值还是新值?答案是:我们不知道。没办法说。C语言中没有规则可以告诉我们。您可能认为必须从左到右计算代码,
amount%5
部分必须先发生,然后--amount
部分才有机会发生。但事情不是这样的。既然没有定义,任何事情都有可能发生。如果是从左到右,那么我们有
if(amount%5 <= --amount)
评估结果为
if(4%5 <= --amount)
评估结果为
if(4 <= --amount)
评估结果为
if(4 <= 3)
这是错误的,所以你可能希望它打印“嗨”。但是,如果从右到左估计的话
if(amount%5 <= 3)
评估结果为
if(3%5 <= 3)
评估结果为
if(3 <= 3)
这是真的。
(你会注意到我已经删除了一些额外的括号,因为它们什么都不做。)
我赶紧补充说,这并不是唯一的两种可能性。规则规定,一旦一个表达式没有定义,任何事情都可能发生——行为不必是我们认为“合理”的任何事情。
那为什么还没有定义呢?在本例中,这是因为您有一个变量--
amount
,它在表达式中出现两次,其中一个是修改(即--amount
部分),另一个使用变量的值。C标准明确地告诉我们,在这种情况下(a)我们无法判断amount
的使用是使用旧值还是修改后的值,而且(b)表达式中的这个缺陷——这个同时修改和使用——使整个表达式(实际上是它所在的整个程序)未定义。那你怎么解决呢?答案很简单,这是一个老笑话的意思:不要那样做。不要在修改和使用单个变量(或其他对象)的情况下编写表达式。写
--amount
是可以的,只是不要在一个表达式中这样做,该表达式也在其他地方使用变量amount
的值。像这样的问题经常出现。其他人已经将您重定向到的规范的SO答案是在问题Why are these constructs (using ++) undefined behavior in C?下收集的。关于未定义表达式的规则,我可以说得更多,但在这个问题上,你可以找到那些细节。
关于c - 代码给我C错误的结果,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50184737/