在C和C++中使用逗号而不是分号的效果

Sma*_*acL 62 c c++

我在很多时候注意到重构各种C和C++代码时使用的是逗号,而不是使用分号来分隔语句.像这样的东西;

int a = 0, b = 0;
a = 5, b = 5;
Run Code Online (Sandbox Code Playgroud)

我期待的地方

int a = 0, b = 0;
a = 5; b = 5;
Run Code Online (Sandbox Code Playgroud)

我知道C和C++允许使用逗号分隔语句(特别是循环标题),但这两段代码之间有什么区别?我的猜测是,逗号已经留下了剪切和粘贴的结果,但这是一个错误,是否会影响执行?

Fra*_*ank 93

它对您发布的代码没有任何影响.通常,逗号分隔表达式就像分号一样,但是,如果将整数作为表达式,则逗号运算符表示表达式求值为最后一个参数.

这是一个例子:

b = (3, 5);
Run Code Online (Sandbox Code Playgroud)

将评估3,然后评估5,并将后者分配给b.所以b = 5.请注意,括号在这里很重要:

b = 3, 5;
Run Code Online (Sandbox Code Playgroud)

b = 3然后将评估,然后5和整个表达式的结果是5 b == 3.

当迭代器代码不简单时i++,逗号运算符在for循环中特别有用,但是您需要执行多个命令.在这种情况下,分号与for循环语法不兼容.

  • +1:对于`评估到最后一个参数 (11认同)

x4u*_*x4u 22

逗号是一个运算符,它返回一个值,该值始终是第二个(右)参数,而分号只是结束语句.这允许逗号运算符在其他语句中使用,或者将多个语句连接成一个.

这里调用函数f(x),然后x > y对if语句求值.

if( y = f(x), x > y )
Run Code Online (Sandbox Code Playgroud)

一个例子,它只用于避免需要阻止

if( ... )
   x = 2, y = 3;

if( ... ) {
   x = 2;
   y = 3;
}
Run Code Online (Sandbox Code Playgroud)


Unc*_*ens 8

逗号运算符从左到右计算所有操作数,结果是最后一个操作数的值.

如果你想在"增量"部分做多个动作,它在for循环中最有用,例如(反转一个字符串)

for (int lower = 0, upper = s.size() - 1; lower < upper; ++lower, --upper)
    std::swap(s[lower], s[upper]);
Run Code Online (Sandbox Code Playgroud)

另一个例子,它可能是一个选项(查找字符串中的所有出现):

#include <string>
#include <iostream>

int main()
{
    std::string s("abracadabra");
    size_t search_position = 0;
    size_t position = 0;

    while (position = s.find('a', search_position), position != std::string::npos) {
        std::cout << position << '\n';
        search_position = position + 1;
    }
}
Run Code Online (Sandbox Code Playgroud)

特别地,逻辑不能用于这个条件,因为这两个零和非零可以意味着字在字符串中找到.另一方面,使用逗号在position = s.find()每次评估条件时调用,但是这部分条件的结果只是被忽略.

当然还有其他方法来编写循环:

while ((position = s.find('a', search_position)) != std::string::npos)
Run Code Online (Sandbox Code Playgroud)

要不就

while (true) {
    position = s.find('a', search_position);
    if (position == std::string::npos)
        break;
    ...
}
Run Code Online (Sandbox Code Playgroud)


cat*_*alk 6

一种用法是在代码打高尔夫球中:

if (x == 1) y = 2, z = 3;
if (x == 1) { y = 2; z = 3; }
Run Code Online (Sandbox Code Playgroud)

第一行较短,但在常规开发中使用时看起来太混乱了。

  • ...无论谁写出这样的代码,很快就会得到他们应得的。 (5认同)

Mic*_*urr 6

正如弗兰克所提到的,您的示例中如何使用逗号运算符不会导致错误。由于以下几个原因,逗号运算符可能会令人困惑:

  • 它并不经常出现,因为它只在某些特殊情况下才有必要
  • 逗号的其他几种语法用法可能看起来像逗号运算符 - 但它们不是(用于分隔函数参数/参数的逗号,用于分隔变量声明或初始值设定项的逗号)

由于它令人困惑且通常是不必要的,因此除了一些非常特殊的情况外,应避免使用逗号运算符:

  • 在一个或多个for语句的控制表达式中执行多个操作可能很有用
  • 它可以在预处理器宏中使用,以评估单个语句中的多个表达式。这样做通常是为了允许宏做不止一件事并且仍然是单个表达式,因此宏将“适合”仅允许表达式的位置。

根据定义,逗号运算符几乎是一种hackish运算符-它可以在仅允许一个的情况下进行两件事。它几乎总是丑陋的,但有时这就是你所拥有的。这是您应该使用它的唯一一次 - 如果您有其他选择,请不要使用逗号运算符。

在我的脑海里,我想不出太多使用运算符的其他原因,因为在大多数其他情况下,您可以通过评估单独语句中的表达式来获得类似的效果(尽管我确信有人会评论我忽略的另一种用途)。