Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 条件语句中逗号的优点是什么?_C++_If Statement_Comma - Fatal编程技术网

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++中,、也可以是一个普通的<强>操作符< /St> >就像“代码> +/COD>”,因此它可以被使用在任何地方,在这里允许表达式(C++中甚至可以重载它)。br/> 与大多数其他运算符的不同之处在于,尽管对两侧都进行了计算,但它不会以任何方式组合左右表达式的输出,而只是返回右表达式
之所以引入它,是因为有人(可能是丹尼斯·里奇)出于某种原因决定,C需要一种语法来在一个位置编写两个(或更多)不相关的表达式,而通常只能编写一个表达式

if(<expr>) { ... }
 with type of <expr> boolean
现在,
if
语句的条件(除其他外)就是这样一个地方,因此,您也可以在那里使用
操作符-这样做是否有意义是一个完全不同的问题!特别是,与函数调用或变量声明不同的是,逗号在这里没有特殊意义,它总是这样做:它对表达式进行左右求值,但只返回右表达式的结果,然后由
if
语句使用

我现在能想到的只有两点,使用(非重载
-运算符是有意义的:

  • 如果要在
    for
    循环的头中增加多个迭代器:

    for ( ... ; ... ; ++i1, ++i2){
        *i2=*i1;
    }
    
  • 如果要在C++11 constexpr函数中计算多个表达式


  • 再次重复这一点:在
    if
    while
    语句中使用逗号运算符(正如您在示例中所示)是不明智的。这只是另一个例子,C语言和C++语言的语法允许你编写代码,这不符合第一次浏览时所期望的方式。还有很多…

    一个也没有。在该代码中,
    a
    上的比较是完全冗余的。

    对于
    if
    语句,将某些内容放入逗号表达式而不是外部是没有实际意义的

    对于
    while
    语句,在进入循环或循环时,将逗号表达式放入条件会执行第一部分。如果没有代码复制,就无法轻松复制

    那么s
    do
    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()) {
        //...
    }