Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/visual-studio-2010/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么布尔表达式中元素的顺序会改变结果?_C_Parsing_Compilation - Fatal编程技术网

C 为什么布尔表达式中元素的顺序会改变结果?

C 为什么布尔表达式中元素的顺序会改变结果?,c,parsing,compilation,C,Parsing,Compilation,如果x为0,则打印0。如果y是0,我们会得到一个错误 为什么会这样?我唯一能想到的是布尔表达式的编译顺序很重要。如果x为0,则得到(false)和(error value),其中false位于左侧,如果y为0,则得到(error value)和(false)。为什么这会影响打印的内容 int main(void) { int x = 1; int y = 0; int a = (x/y > 0)&&(y/x > 0); printf("%d\n", a

如果x为0,则打印0。如果y是0,我们会得到一个错误

为什么会这样?我唯一能想到的是布尔表达式的编译顺序很重要。如果x为0,则得到(false)和(error value),其中false位于左侧,如果y为0,则得到(error value)和(false)。为什么这会影响打印的内容

int main(void) {
  int x = 1;
  int y = 0;
  int a = (x/y > 0)&&(y/x > 0);
  printf("%d\n", a);
  return 0;
}

与C中的大多数其他运算符不同,运算符
&&
以“短电流”的方式定义了从左到右的求值顺序。也就是说,如果第一个条件失败,第二个条件甚至不会得到评估,因此它没有失败的机会。请注意,“短路”评估不仅仅是一个(可选)优化问题;这是语言的保证。因此,以下表达式永远不会导致错误:

int x = 1,  y = 0;
int result = (y/x) && (x/y); // OK; y/x yields 0 (meaning false), such that the second operand will not be evaluated.

顺便说一句:操作员
|
也保证了这种短路行为。

x/y的行为未定义为
y
0

编译器知道
y
0
,并且明显优化了表达式。它还知道
(y/x>0)
0
,并且由于
&
,整个表达式的结果是
0

一个不太激进的优化编译器会在运行时产生一个零除错误。建议您检查程序集以查看编译器所做的工作


最终分数:编译器1,程序员0。

被零除应触发SIGFPE。@lilicent:不使用整数除法。如果x为零,表达式为零且&“短路”。如果y为0,则除以0并调用未定义的行为。没什么了。@Bathsheba SIGFPE也是因为整数算术错误而被提出的。@Bathsheba SIGFPE比浮点算术更包容。甚至整数除法溢出也是SIGFPE。这被标记为C。虽然在这种情况下,语言是相同的。这是真的,但我相信错误是在逻辑运算的第一个操作数中。我应该补充一点,逻辑OR
|
也显示了相同的类型behavior@StefanoBuora:OP状态为“要么<代码>(false)&&(错误值)要么<代码>(错误值)&&(false)”,这表明其
x=0;y=1
x=1;y=0,但不是x=0;y=0
@Downvoter:我错过了什么?我看不到任何其他解释。我不是投票人,但我相信你正确地指出了问题,你在评论中对编译器错误、运行时错误甚至SIGFPE的描述应该得到改进。此外,你的回答没有回答OPs问题,这是错误的“为什么布尔表达式中元素的顺序会改变结果?”而不是“为什么偏离零会产生错误?”?“。这可能是一个有趣的附加信息,但它缺少对
&
运算符的解释,例如Stephan Lechner的答案。这就是为什么我投了反对票,a)你们的假设是并没有错误,即使OP明确指出有错误,b)根本并没有解决OP的问题。@MaxVollmer:公平竞争。我认为,随着编译器优化变得越来越积极,未来的许多答案将采用这种形式。我不认为这与蜡的抒情性有关。<代码> & & <代码>的短路和排序特性,因为一旦遇到UB,所有的赌注都被关闭。结合Stephan和我的部分回答(IMHO-out-focus)。我会投赞成票。请注意,答案不一定对OP有用-这不是一个论坛。如果你想这样做,让我知道,我会重新打开-对我来说,副本不是特别准确,尽管可以从两个副本中收集答案。