Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.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++_C_Operators - Fatal编程技术网

C++ 使用逗号运算符是否是一种良好的做法?

C++ 使用逗号运算符是否是一种良好的做法?,c++,c,operators,C++,C,Operators,我最近(事实上只是这样)遇到了C/C++逗号运算符的用法。据我所知,它在左侧和右侧操作符之间的直线上创建了一个序列点,这样您就有了一个可预测(定义)的求值顺序 我有点不明白为什么会在语言中提供这个,因为它看起来像是一个补丁,可以应用于本来不应该工作的代码。我发现很难想象有一个地方不太复杂(并且需要重构) 有人能解释一下这一语言功能的用途,以及它在实际代码中的使用位置(如果有的话)吗?逗号运算符只是分隔表达式,因此您可以执行多个操作,而不是只需要一个表达式就可以执行一个操作。它可以让你做像这样的事

我最近(事实上只是这样)遇到了C/C++逗号运算符的用法。据我所知,它在左侧和右侧操作符之间的直线上创建了一个序列点,这样您就有了一个可预测(定义)的求值顺序

我有点不明白为什么会在语言中提供这个,因为它看起来像是一个补丁,可以应用于本来不应该工作的代码。我发现很难想象有一个地方不太复杂(并且需要重构)


有人能解释一下这一语言功能的用途,以及它在实际代码中的使用位置(如果有的话)吗?

逗号运算符只是分隔表达式,因此您可以执行多个操作,而不是只需要一个表达式就可以执行一个操作。它可以让你做像这样的事情

             (x)              (y)
for (int i = 0, j = 0; ...; ++i, ++j)
请注意,
x
不是逗号运算符,而是
y


你真的不必去想它。它还有一些更神秘的用途,但我不认为它们是绝对必要的,所以它们只是好奇而已。

我认为唯一常见的例子是for循环:

for (int i = 0, j = 3; i < 10 ; ++i, ++j)
for(int i=0,j=3;i<10;++i,++j)
如报告中所述:

有时,您会发现自己处于C期望 单一表达,但你有两件事想说。最 常见的(事实上也是唯一常见的)示例是for循环, 特别是第一个和第三个控制表达式


我能想到的唯一合理使用是
for
构造

for (int count=0, bit=1; count<10; count=count+1, bit=bit<<1)
{
    ...
}

for(int count=0,bit=1;count它在
while()循环的情况下非常有用:

while (update_thing(&foo), foo != 0) {
    /* ... */
}
这避免了重复
update\u thing()
行,同时仍然在
while()
控制表达式中维护退出条件,您希望在其中找到它。它还可以很好地与
continue;
配合使用


它在编写计算结果为某个值的复杂宏时也很有用。

每个人都说它经常用于for循环,这是事实。但是,我发现它在for循环的条件语句中更有用。例如:

for (int x; x=get_x(), x!=sentinel; )
{
    // use x
}
在不使用逗号运算符的情况下重写它,至少需要做一些我不太熟悉的事情中的一件,例如在使用它的范围之外声明x,或者在第一次调用
get\u x()
时使用特殊的大小写


我还绘制了我可以使用C++11 constexpr函数的方法,因为我猜它们只能由单个语句组成。

中对于
循环构造,它是有意义的。虽然我通常发现在这个例子中它们更难阅读

这对于激怒你的同事和其他人也很方便

bool guess() {
  return true, false;
}

逗号运算符对于将序列放置在无法插入代码块的位置非常有用。正如所指出的,这在编写紧凑且可读的循环时非常方便。此外,它在宏定义中非常有用。以下宏增加警告的数量,如果设置了布尔变量,也将显示警告

#define WARN if (++nwarnings, show_warnings) std::cerr
以便您可以编写(示例1):

if(警告条件)

WARN我还使用逗号运算符将相关操作粘在一起:

void superclass::insert(item i) {
  add(i), numInQ++, numLeft--;
}

扮演魔鬼代言人的角色,将问题颠倒过来可能是合理的:

始终使用分号终止符是一种好的做法吗

有几点:

  • 用逗号替换大多数半结点将使大多数C和C++代码的结构更清晰,并消除一些常见错误。
  • 这更像是函数式编程,而不是命令式编程
  • Javascript的“自动分号插入”是其有争议的语法特性之一
这种做法是否会增加“常见错误”还不得而知,因为没有人会这样做

当然,如果你这么做了,你很可能会惹恼你的程序员同事,并因此成为一个贱民

Edit:请参阅2009年的优秀答案。此外,还介绍了C#/C/C++中的两个平行语法类别

作为一个简单的例子,
while(foo)a,b,c;
的结构是清楚的,但是
while(foo)a;b;c;
在没有缩进或大括号或两者的情况下会产生误导

编辑#2:如下所示:

C语言(以及C++)在历史上是两种完全不同的编程风格的混合体,可以称之为“语句编程”和“表达式编程”

但他声称“在实践中,语句编程会产生更多的可读代码”[emphasis added]显然是错误的。以他的例子来说,您认为以下两行中哪一行更可读

a = rand(), ++a, b = rand(), c = a + b / 2, d = a < c - 5 ? a : b;
a = rand(); ++a; b = rand(); c = a + b / 2; if (a < c - 5) d = a; else d = b; 
a=rand(),+a,b=rand(),c=a+b/2,d=a

答案:它们都是不可读的。正是空格赋予了可读性——Python万岁!第一个更短。但是分号版本确实有更多的黑色像素,如果你有Hazeltine终端,则是绿色像素——这可能是这里的真正问题?

尽管几个月后发布了r C++11被批准,我在这里没有看到任何关于
constexpr
函数的答案。对于一个不完全相关的问题,参考了关于逗号运算符及其在常量表达式中的有用性的讨论,其中特别提到了新的
constexpr
关键字

虽然C++14确实放宽了对
constexpr
函数的一些限制,但值得注意的是,逗号运算符可以在
constexpr
函数中授予可预测的有序操作,例如(从前面的讨论中):

这是不是我
a = rand(), ++a, b = rand(), c = a + b / 2, d = a < c - 5 ? a : b;
a = rand(); ++a; b = rand(); c = a + b / 2; if (a < c - 5) d = a; else d = b; 
template<typename T>
constexpr T my_array<T>::at(size_type n)
{
    return (n < size() || throw "n too large"), (*this)[n];
}
constexpr MyConstexprObject& operator+=(int value)
{
    return (m_value += value), *this;
}