我在很多时候注意到重构各种C和C ++代码时使用的是逗号,而不是使用分号来分隔语句。像这样的东西;
int a = 0, b = 0;
a = 5, b = 5;
我期望的地方
int a = 0, b = 0;
a = 5; b = 5;
我知道C和C ++允许使用逗号来分隔语句(特别是循环标题),但这两段代码之间有什么区别?我的猜测是,逗号是由于cut&amp ;;而留下的。粘贴,但这是一个错误,它是否会影响执行?
答案 0 :(得分:89)
它对您发布的代码没有任何影响。通常,逗号分隔表达式就像分号一样,但是,如果将整数作为表达式,则逗号运算符表示表达式求值为最后一个参数。
以下是一个例子:
b = (3, 5);
将评估3,然后评估5并将后者分配给b。所以b = 5
。请注意,括号在这里很重要:
b = 3, 5;
将评估b = 3
,然后评估5,整个表达式的结果为5,不过b == 3
。
当迭代器代码不是简单的i++
时,逗号运算符在for循环中特别有用,但是您需要执行多个命令。在这种情况下,分号与for循环语法不兼容。
答案 1 :(得分:22)
逗号是一个运算符,它返回一个始终是第二个(右)参数的值,而分号只是结束语句。这允许逗号运算符在其他语句中使用,或者将多个语句连接成一个。
这里调用函数f(x),然后为if语句计算x > y
。
if( y = f(x), x > y )
仅用于避免需要块
的示例if( ... )
x = 2, y = 3;
if( ... ) {
x = 2;
y = 3;
}
答案 2 :(得分:8)
逗号运算符从左到右计算所有操作数,结果是最后一个操作数的值。
如果你想在“增量”部分做多个动作,例如(反转一个字符串),它在for循环中最有用
for (int lower = 0, upper = s.size() - 1; lower < upper; ++lower, --upper)
std::swap(s[lower], s[upper]);
另一个例子,它可能是一个选项(查找字符串中的所有匹配项):
#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;
}
}
特别是,逻辑和不能用于此条件,因为零和非零都可能意味着在字符串中找到了该字符。另一方面,使用逗号,每次评估条件时都会调用position = s.find()
,但这部分条件的结果只是被忽略。
当然还有其他方法来编写循环:
while ((position = s.find('a', search_position)) != std::string::npos)
或只是
while (true) {
position = s.find('a', search_position);
if (position == std::string::npos)
break;
...
}
答案 3 :(得分:4)
一种用法是代码打高尔夫球:
if (x == 1) y = 2, z = 3;
if (x == 1) { y = 2; z = 3; }
第一行较短,但在常规开发中使用时看起来太混乱了。
答案 4 :(得分:3)
作为Frank mentioned,在您的示例中如何使用逗号运算符不会导致错误。由于以下几个原因,逗号运算符可能会令人困惑:
由于它令人困惑并且经常是不必要的,除了一些非常特殊的情况外,应该避免使用逗号运算符:
for
语句的控制表达式中执行多个操作非常有用逗号运算符在定义上几乎是一个hackish运算符 - 它是攻击允许只有一个的两个东西。它几乎总是丑陋的,但有时候这就是你所拥有的。这是您应该使用它的唯一时间 - 如果您有其他选项,请不要使用逗号运算符。
在我的脑海中,我无法想到使用运算符的其他太多原因,因为在大多数其他情况下通过在单独的语句中评估表达式可以获得类似的效果(尽管我确定有人将评论我忽略的另一种用法。