如果在C中处理具有复杂条件的语句?

时间:2017-03-22 15:22:39

标签: c

考虑以下(有些荒谬)if语句:

int i = 0;
int j = 0;

//get i, j from the user, or a file, or something

if(i < 6 && j > 4)
...
else if(j > 6)
...

现在,这会编译成如下所示:

  • 比较i&lt; 6,分支到else if,如果不是
  • 比较j&gt; 4,分支到else if,如果不是
  • else if:比较j&gt; 6(即使上面的第二个比较是假的,这可能不是真的)

还是有一些预测简化逻辑的智能方法吗?

2 个答案:

答案 0 :(得分:2)

关于precedence

你的第一个表达式是这样处理的(大括号使它明确易读):

(i < 6) && (j > 4)

但是,如果不知道操作发生的顺序,就不知道了。

示例,以下哪一项是等效的:

&x[5]
&(x[5])
(&x)[5]

正如您所指出的,C语言使用Short-Circuit Evaluation。 这意味着一旦它知道语句的结果,它就会停止处理。

x = 3;
if ((x < 6) || do_foo()) {
    /* ... */
}
if ((x < 10) && do_bar()) {
    /* ... */
}

在这种情况下,do_foo()函数未被调用,但调用了do_bar()函数。

出于这个原因,从一个明确的意图,以及一个有目的的编程观点(你可能是一个优先专家,在一个条件中)放置任何“可能做某事”的陈述是一个坏主意。但下一个人可能不是。)

答案 1 :(得分:0)

如果编译器可以证明if的条件始终具有某个值,则可能会禁止从生成的代码进行检查。如果您在启用优化的情况下进行编译,通常会执行此操作,编译器将尝试在语义上分析代码并证明这类事情。

使用if(0) { /* ... */ }是用于删除部分代码的常用习惯用法,我知道优化编译器不会为其发出任何代码。

也就是说,我不知道是否有任何编译器会执行您提到的这种特定优化:在j&gt;情况下完全跳过else if 4,但我不会对GCC或Clang感到惊讶,因为他们执行相当激进的代码转换。