C ++任务 - 时尚还是性能?

时间:2010-05-19 19:46:53

标签: c variable-assignment

多年来编写Java代码时,当我看到这个C ++语句时,我感到非常惊讶:

int a,b;
int c = (a=1, b=a+2, b*3);

我的问题是:这是编码风格的选择,还是有真正的好处? (我正在寻找一个实用的用例)

我认为编译器会看到它与以下内容相同:

int a=1, b=a+2;
int c = b*3;

(这是什么官方名称?我认为它是标准的C / C ++语法。)

9 个答案:

答案 0 :(得分:17)

这是comma operator,使用了两次。你对结果是正确的,我没有看到以这种方式使用它的重点。

答案 1 :(得分:9)

看起来像是(逗号)运算符的模糊使用。

这不是用C ++做事的代表性方式。

答案 2 :(得分:6)

逗号运算符的唯一“好样式”用法可能在for语句中,该语句具有多个循环变量,使用如下所示:

// Copy from source buffer to destination buffer until we see a zero
for (char *src = source, *dst = dest; *src != 0; ++src, ++dst) {
    *dst = *src;
}

我把“好风格”放在恐慌引号中,因为几乎总有比使用逗号操作符更好的方法。

我想看到这种情况的另一个背景是使用三元运算符,当你想要有多种副作用时,例如,

bool didStuff = DoWeNeedToDoStuff() ? (Foo(), Bar(), Baz(), true) : false;

同样,有更好的方式来表达这种事情。从我们只能在显示器上看到24行文字的日子开始,这些成语都是延续,并且在每行中挤出很多东西都具有一些实际意义。

答案 3 :(得分:3)

Dunno它的名字,但Job Security Coding Guidelines似乎遗漏了!

说真的:C ++允许你在许多情况下做很多事情,即使它们不一定是合理的。强大的力量带来了巨大的责任......

答案 4 :(得分:2)

这称为'混淆C'。这是合法的,但旨在使读者感到困惑。它似乎有效。除非你试图模糊,否则最好避免。

布袋

答案 5 :(得分:2)

你的示例代码使用了两个不太知名的初学者(但也没有真正隐藏)C表达式的特性:

  • 逗号运算符:一个普通的二元运算符,其作用是返回它的两个操作数中的最后一个。如果操作数是表达式,则从左到右计算它们。
  • 赋值作为返回值的运算符。 C赋值不是与其他语言一样的语句,并返回已分配的值。

这两个功能的大多数用例都涉及某种形式的混淆。但是有一些合法的。关键是您可以在任何可以提供表达式的地方使用它们:在if循环迭代块中的if或while条件内,在函数调用参数中(使用coma时必须使用括号以避免与实际函数参数混淆) ,在宏参数等

最常用的逗号可能是在循环控制中,当你想一次更改两个变量,或者在执行循环测试或循环迭代之前存储一些值。

例如,由于逗号运算符,可以按如下方式编写反向函数:

void reverse(int * d, int len){
    int i, j;

    for (i = 0, j = len - 1 ; i < j ; i++, j--){
       SWAP(d[i], d[j]);
    }
}

我想到的另一个合法的(没有混淆的,真的)使用昏迷算子是我在一些项目中找到的DEBUG宏定义为:

#ifdef defined(DEBUGMODE)
#define DEBUG(x) printf x
#else
#define DEBUG(x) x
#endif

你可以像使用它一样:

DEBUG(("my debug message with some value=%d\n", d));

如果DEBUGMODE打开,那么你将得到一个printf,如果没有,将不会调用包装函数,但括号内的表达式仍然有效C.重点是打印代码的任何副作用都将适用于发布代码和调试代码,如下所示:

DEBUG(("my debug message with some value=%d\n", d++));

使用上述宏,无论调试模式如何,d都将递增。

可能还有一些其他罕见的情况,其中逗号和赋值有用,并且在使用它们时代码更容易编写。

我同意赋值运算符是一个很好的错误来源,因为它很容易与条件中的==混淆。

我同意,由于逗号在其他上下文(函数调用,初始化列表,声明列表)中也使用了不同的含义,因此对于运算符来说它不是一个非常好的选择。但基本上它并不比使用&lt;和&gt;对于C ++中的模板参数,它存在于很久以前的C中。

答案 6 :(得分:1)

它严格的编码风格,不会对你的程序产生任何影响。特别是因为任何体面的C ++编译器都会将其优化为

int a=1; 
int b=3;
int c=9;

在运行时分配期间甚至不会执行数学运算。 (有些变量甚至可以完全消除)。

至于编码风格的选择,我更喜欢第二个例子。大多数情况下,较少的嵌套更好,并且您不需要额外的括号。由于几乎所有C ++程序员都知道所使用的逗号,所以你可以选择一种风格。否则,我会说每个作业都在自己的行上。

答案 7 :(得分:1)

  

这是编码风格的选择,还是有真正的好处? (我正在寻找一个实用的用例)

它既是编码风格的选择,也有实际的好处。

与您的同等示例相比,它显然是一种不同的编码风格。

好处是我已经知道我永远不想雇用写作者,而不是作为程序员。

一个用例:Bob带着一段包含该行的代码来找我。我让他转到营销部门。

答案 8 :(得分:0)

您发现程序员编写的可疑滥用逗号运算符可能希望C ++具有多个赋值。它没有。我想起了老锯,你可以用任何语言写FORTRAN。显然你可以尝试用C ++编写Dijkstra的保护命令语言。

要回答你的问题,这纯粹是(坏)风格的问题,编译器并不关心 - 编译器将生成完全相同的代码,而不是C ++程序员认为理智和明智的代码。

如果您创建两个小示例函数并使用-S选项进行编译,则可以自己查看。