2

我很想知道如何在 C/C++ 或其他编程语言中实现诸如“if”之类的条件语句。

因此,如果我以以下两种方式编写 if 语句,它将如何在计算成本方面有所不同:

方式一:

if(statement1)
    return true;
if(statement2)
    return true;
if(statement3)
    return true;

方式二:

if(statement1 || statement2 || statement3)
    return true;

第二种方式,是先对所有语句进行求值,然后再对其结果进行 OR 运算,还是先考虑 OR 运算,然后一旦任何语句求值为真,就返回真值?后者通过不必评估条件中的每个语句来节省计算成本/时间,因为一旦它获得第一个为真,工作就完成了。但这取决于条件句中的操作。如果它是一个 AND,它就变成了完全不同的情况。组合运算(AND+OR+XOR..)

那么背后到底是怎么做的呢?实现是否可能取决于条件内的布尔运算?

4

6 回答 6

4

我很想知道如何在 C/C++ 或其他编程语言中实现诸如“if”之类的条件语句。

这取决于您计算机的汇编语言。例如,对于 x86 指令列表,该指令CMP将设置一个标志,该标志由诸如J**( JNE, JA, ...) 之类的指令读取。

这通常是“实现”条件的方式。

第二种方式,是先对所有语句进行求值,然后再对其结果进行 OR 运算,还是先考虑 OR 运算,然后一旦任何语句求值为真,就返回真值?

在 C 中,&&二元||运算符使用短路求值。也就是说,在 中E1 || E2,如果E1为真,E2则不进行评估。

于 2013-06-06T16:40:34.753 回答
2

实现取决于编译器和优化设置。在某些情况下,方式 II(具有 OR 条件的方式)由于“短路”而更快:如果 || 左侧的操作数 运算符为真,则不检查其余条件。另一方面,在方式 I 中,条件是按顺序执行的 - 除非使用某种优化(或智能编译器)将其转换为方式 II(在这种情况下,两种方式都同样快)。

于 2013-06-06T16:57:57.780 回答
2

第二种方式,是先对所有语句进行求值,然后再对其结果进行 OR 运算,还是先考虑 OR 运算,然后一旦任何语句求值为真,就返回真值?

逻辑运算符在 C++ 中总是短路的。在 的情况下||,如果第一个操作数为真,则不计算第二个操作数。这意味着您的两个示例应该是等效的;代码将评估表达式,直到其中一个为真,然后返回真。

这不仅比总是评估两者可能更有效;它还允许类似的东西

if (!p || *p == whatever)

如果第一个为真,则评估第二个将是错误的。

如果它是一个 AND,它就变成了完全不同的情况。

在这种情况下,仅当第一个操作数为假时才评估第二个操作数。

组合运算(AND+OR+XOR..)

C++ 中没有逻辑异或;只有&&||。将它们组合起来相当简单;&&具有更高的优先级,并且在每个子表达式中,操作数从左到右进行计算,并根据需要进行短路。

于 2013-06-06T16:46:22.957 回答
1

根据标准:


5.15 逻辑或运算符

   logical-or-expression:
     logical-and-expression
     logical-or-expression || logical-and-expression

1 || 运算符组从左到右。操作数都根据上下文转换为 bool(第 4 条)。如果其中一个操作数为真,则返回真,否则返回假。与 |、|| 不同 保证从左到右的评估;此外,如果第一个操作数的计算结果为真,则不计算第二个操作数。

2 结果是布尔值。如果计算第二个表达式,则与第一个表达式关联的每个值计算和副作用在与第二个表达式关联的每个值计算和副作用之前排序。


其他事实 - 编译器是否遵守规则。

于 2013-06-06T16:49:54.270 回答
1

取决于编译器。您可以使用 gcc -o 来查看会发生什么,这将生成一个目标文件。打开目标文件,您会看到编译器对其进行了优化。通常,它会创建一个跳转表(用于长条件),但有时它只使用条件处理器指令。

于 2013-06-06T16:39:44.503 回答
1

智能编译器会将 Way I 转换为 Way II。

方式二检查每个语句并在遇到真理时立即返回真。

于 2013-06-06T16:40:09.577 回答