4

为了提高使用有序数组的 clique-partitioning 程序的性能,我在for循环的停止条件中包含了对要循环到的数组元素的访问。

int myValue = 13;

for (int i=0; array[i] < myValue; i++)
{
    //performing operations on the array
}

这显然是不安全的,因为我的数组可能只包含小于的值myValue,所以我尝试了这个

int myValue = 13;

for (int i=0; i < array.size() && array[i] < myValue; i++)
{
    //performing operations on the array
}

在这个实现中,一切似乎都很顺利,但是如果我切换条件,我就会陷入与第一个示例相同的问题。

int myValue = 13;

for (int i=0; array[i] < myValue && i < array.size(); i++)
{
    //performing operations on the array
}

所以,我推断这显然是由于编译器设置两个条件的顺序的方式,因为在最后一种情况下,即使我要求只有在i不大于数组大小的情况下才进入循环,我' m 之前读取的值可能超出数组的范围。

我的问题是:像我在第二个实现中所做的那样总是安全的,还是编译器有时会切换我的控制条件导致不安全的代码?

谢谢。

4

2 回答 2

7

如果可以,&&(逻辑与)运算符总是短路。你的第二个例子是安全的。

请注意,这仅适用于原始类型,而不适用于那些重载布尔运算符的类型。

因为没有标准报价,任何自尊的C++答案都是不完整的:

5.14.1(逻辑与) && 运算符从左到右分组。操作数都根据上下文转换为 bool 类型(第 4 条)。如果两个操作数都为真,则结果为真,否则为假。与 & 不同,&& 保证从左到右的评估:如果第一个操作数为假,则不评估第二个操作数。

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

于 2012-11-01T00:13:29.597 回答
0

我不会做任何一个例子。做这个:

for (int i=0; i < array.size(); i++) {
    if (array[i] >= myValue) {
        break;
    }

    // do stuff
}

这样,您就不会感到困惑或缺乏安全感。它与其他示例具有相同的速度,但以后调试起来要简单得多。

于 2012-11-01T00:17:50.987 回答