很多时候,我看到(有时会写)与此示例类似的代码:
int a=0, b=2;
if( a && (b=func())!=0 ) {
//...
问题是:标准是否保证这些陈述?
b
将不会被触及(并保留值2
)func()
将不会被称为反之亦然,如果我们写if( func()!=0 && a )
- 是否会调用标准保证func()
?
我对定义这是合法的特定标准段感兴趣。
UPD:我的拼写错误,从int a=1
更改为int a=0
答案 0 :(得分:4)
来自C-90标准。
6.5.13逻辑AND运算符
...
4与按位二进制&操作员,&&运营商保证从左到右的评估; 在评估第一个操作数后有一个序列点。如果是第一个操作数 比较等于0,不评估第二个操作数。
与Logical OR运算符类似。
答案 1 :(得分:4)
确切的问题;
问题是:标准是否保证这些陈述?
更新的问题;给定a=0
。如果a==0
,则是,短路评估将启动,func()
将不会被调用;第二个操作数不会被评估。
如果a=1
(原来是),则相反;将调用func()
- a
为1
因此为“true”,因此评估第二个操作数(它是逻辑AND),b
将更改。如果运算符为||
(逻辑或),则短路评估将启动,func()
将不会被调用。
反之亦然,如果我们写
if( func()!=0 && a )
- 是否会调用标准保证func()
?
是的,始终会评估第一个操作数。
是的,C ++保证短路评估;
§5.14逻辑AND运算符
1
&&
运算符组从左到右。操作数都在上下文中转换为bool(第4条)。如果两个操作数都为真,则结果为true,否则为false。与&
不同,&&
保证从左到右的评估:如果第一个操作数为假,则不评估第二个操作数。2结果是一个布尔。如果计算第二个表达式,则在每个值计算和与第二个表达式相关的副作用之前,对与第一个表达式关联的每个值计算和副作用进行排序。
§5.15逻辑OR运算符
1
||
运算符组从左到右。操作数都在上下文中转换为bool(第4条)。如果其任一操作数为true,则返回true,否则返回false。与|
不同,||
保证从左到右的评估;此外,如果第一个操作数的计算结果为true,则不计算第二个操作数。2结果是一个布尔。如果计算第二个表达式,则在每个值计算和与第二个表达式相关的副作用之前,对与第一个表达式关联的每个值计算和副作用进行排序。
C的相应引号是;
§6.5.13逻辑AND运算符
4与按位二进制
&
运算符不同,&&
运算符保证从左到右的评估;如果计算第二个操作数,则在第一个和第二个操作数的计算之间存在一个序列点。如果第一个操作数比较等于0,则不评估第二个操作数。
§6.5.14逻辑OR运算符
4与按位
|
运算符不同,||
运算符保证从左到右的评估;如果计算第二个操作数,则在第一个和第二个操作数的计算之间存在一个序列点。如果第一个操作数将不等于0,则不计算第二个操作数。
答案 2 :(得分:2)
该标准保证&&
序列中的语句从左到右进行评估,并且只要其中一个语句的计算结果为false,就不会评估其右侧的语句。< / p>
答案 3 :(得分:2)
&&
运算符要求两个操作数都为true。如果第一个操作数的计算结果为false,则不会计算第二个操作数。但是因为a
是1,它被认为是真的,并且第二个表达式(操作数)被计算。因此调用func()
并将其分配给b
然后b
的结果测试为非零。
答案 4 :(得分:-1)
问题是:标准是否保证这些陈述?
b将不被触及(并保持值2)
不会调用func()
不,实际上他们两个都错了。因为它的运算符&&
所以在这种特殊情况下不能应用快捷逻辑。
如果您将其更改为||
,那么您的陈述是正确的 - 只有这样,第一个操作数(在这种情况下为a = 1
)的评估才足够,其余部分将被忽略。
当问题变为a = 0
然后是,两个陈述都是正确且有保证的。