C++ 条件语句中逗号的优点是什么?
我们可以编写一个C++ 条件语句中逗号的优点是什么?,c++,if-statement,comma,C++,If Statement,Comma,我们可以编写一个if语句 if (a == 5, b == 6, ... , thisMustBeTrue) 并且只有最后一个条件可以满足才能进入if主体 为什么允许使用它?没有优势:逗号运算符只是一个表达式,其类型为其表达式列表中最后一个表达式的类型,if语句对布尔表达式求值 if(<expr>) { ... } with type of <expr> boolean if(){…} 布尔型 这是一个奇怪的运算符true,但它并没有什么魔力——只是它在函数调用中
if
语句
if (a == 5, b == 6, ... , thisMustBeTrue)
并且只有最后一个条件可以满足才能进入if
主体
为什么允许使用它?没有优势:逗号运算符只是一个表达式,其类型为其表达式列表中最后一个表达式的类型,if语句对布尔表达式求值
if(<expr>) { ... }
with type of <expr> boolean
if(){…}
布尔型
这是一个奇怪的运算符true,但它并没有什么魔力——只是它在函数调用中将表达式列表和参数列表混淆了
foo(<args>)
with <args> := [<expr>[, <expr>]*]
foo()
带:=[,]*]
请注意,在参数列表中,逗号绑定到分隔参数。简而言之:
尽管这样做是合法的,但在if
或while
语句的条件部分使用逗号运算符通常是没有意义的(编辑:尽管后者有时可能会有所帮助,正如user5534870在其回答中所解释的)
更详细的解释:
除了语法功能(例如初始化列表中的分离元素、变量声明或函数调用/声明),在C和C++中,之所以引入它,是因为有人(可能是丹尼斯·里奇)出于某种原因决定,C需要一种语法来在一个位置编写两个(或更多)不相关的表达式,而通常只能编写一个表达式
if(<expr>) { ... }
with type of <expr> boolean
现在,if
语句的条件(除其他外)就是这样一个地方,因此,您也可以在那里使用,
操作符-这样做是否有意义是一个完全不同的问题!特别是,与函数调用或变量声明不同的是,逗号在这里没有特殊意义,它总是这样做:它对表达式进行左右求值,但只返回右表达式的结果,然后由if
语句使用
我现在能想到的只有两点,使用(非重载),
-运算符是有意义的:
for
循环的头中增加多个迭代器:
for ( ... ; ... ; ++i1, ++i2){
*i2=*i1;
}
再次重复这一点:在
if
或while
语句中使用逗号运算符(正如您在示例中所示)是不明智的。这只是另一个例子,C语言和C++语言的语法允许你编写代码,这不符合第一次浏览时所期望的方式。还有很多…一个也没有。在该代码中,a
上的比较是完全冗余的。对于if
语句,将某些内容放入逗号表达式而不是外部是没有实际意义的
对于while
语句,在进入循环或循环时,将逗号表达式放入条件会执行第一部分。如果没有代码复制,就无法轻松复制
那么sdo
…while
语句怎么样?我们只需要担心循环本身,对吗?事实证明,即使在这里,也不能通过将第一部分移动到循环中来安全地替换逗号表达式
首先,循环体中变量的析构函数在那时还没有运行,这可能会有所不同。另一方面,循环中的任何
continue
语句只有在其确实处于条件中而不是在循环体中时才会到达逗号表达式的第一部分。稍微更改示例,假设是这样的
if ( a = f(5), b = f(6), ... , thisMustBeTrue(a, b) )
(注意=
而不是=
)。在这种情况下,逗号保证从左到右的求值顺序。与此相反
if ( thisMustBeTrue(f(5), f(6)) )
您不知道是在f(6)
之前还是之后调用f(5)
更正式地说,逗号允许您以与使用相同的方式编写表达式序列(a,b,c)
编写一系列语句a;Bc代码>。
就像一个代码>创建一个(完整表达式的结尾)逗号也是如此。只有序列点控制求值顺序,请参见
但当然,在这种情况下,你会写这个
a = f(5);
b = f(6);
if ( thisMustBeTrue(a, b) )
那么什么时候逗号分隔的表达式序列比更适合代码>分离的语句序列?我几乎不会说。可能是在宏中,当您希望右侧替换为单个表达式时。下面的内容有点牵强,这取决于您希望的迂回程度
if(<expr>) { ... }
with type of <expr> boolean
考虑这样一种情况,即函数通过修改通过引用或指针传递的参数(可能来自设计糟糕的库,或者确保返回后不赋值,不会忽略此值,等等)来返回值
void calculateValue(FooType&result){/*…*/}
那么如何使用依赖于结果的条件语句呢
您可以声明要修改的变量,然后使用if检查它:
FooType result;
calculateValue(result);
if (result.isBared()) {
//...
}
这可以缩短为
FooType result;
if (calculateValue(result) , result.isBared()) {
//...
}
这真的不值得然而,对于而循环,可能有一些小的优势。如果calculateValue
应该/可以被调用,直到结果不再是bar
'd为止,我们将得到如下结果:
FooType result;
calculateValue(result); //[1] Duplicated code, see [2]
while (result.isBared()) {
//... possibly many lines
//separating the two places where result is modified and tested
//How do you prevent someone coming after you and adds a `continue`
//here which prevents result to be updated in the and of the loop?
calculateValue(result); //[2] Duplicated code, see [1]
}
可以浓缩为:
FooType result;
while (calculateValue(result) , result.isBared()) {
//all your (possibly numerous) code lines go here
}
这边
FooType result;
ErrorType error;
while (Success == fallibleCalculation(result) && result.isBared()) {
//...
}