“算术表达式”是不是允许在 C 中用逗号分隔,或者我们需要为每个单独的语句?

Posted

技术标签:

【中文标题】“算术表达式”是不是允许在 C 中用逗号分隔,或者我们需要为每个单独的语句?【英文标题】:Are "arithmetic expressions" separated by commas allowed in C or we need separate statements for each?“算术表达式”是否允许在 C 中用逗号分隔,或者我们需要为每个单独的语句? 【发布时间】:2013-04-17 07:08:27 【问题描述】:

在C语言中,是以下语句

a+=3,b=c*2,d=a+b;

相当于下面的语句块:

a+=3;
b=c*2;
d=a+b;

我相信你明白我的意思。我们可以在 C 中的同一语句中安全地使用多个用逗号分隔的数学表达式吗?在什么情况下这会造成问题?

【问题讨论】:

了解sequence points。 是的..它们是一样的.. 嗯,它们并不完全相同:前者可能会让你有些傻笑,快来代码审查日吧。 (许多 C/C++ 程序员不鼓励在这种情况下使用逗号运算符。);-) @DevSolar:希望代码的审阅者和作者都考虑到它出现的上下文。如果它只是在一个函数的中间,那么你应该使用三个语句。如果它出现在多个语句不能出现的地方(例如在for 循环的最后一个子句中),那么它可能是一个案例。 @SteveJessop:同意“为”。这就是我在写“类似这样的事情”时的想法。 ;-) 【参考方案1】:

如果你想像这样呈现的逗号表达式列表可能会更容易:

((a += 3, b = c * 2), d = a + b)

首先计算最里面的逗号表达式:

a += 3, b = c * 2

该表达式将分两步计算:

a += 3
b = c * 2

a += 3的结果会被编译器扔掉,但是赋值还是会发生,只是返回的结果被扔掉了。第一个逗号表达式的结果是b(将是c * 2(无论是什么)。

第一个逗号表达式的结果在下一个逗号表达式的左侧:

b = c * 2, d = a + b

然后将被排序为

b = c * 2
d = a + b

表达式b = c * 2 的结果被丢弃(但由于它仍在评估,赋值仍然发生),完整表达式的结果是d(即a + b)。

整个表达式的结果将是d

【讨论】:

【参考方案2】:

它们是一样的。

在 C 中,逗号运算符计算其左侧,忽略返回值(例如 x = y 的返回是新值),计算右侧并返回其结果(如果有)。逗号运算符的用途是在不使用(例如丢弃)其值的情况下评估并获取左侧内容的副作用。

【讨论】:

“忽略结果”是指在第一个带逗号的语句中,a+=3 和b=c*2 这两个表达式被忽略了吗?你的意思是a 不加3 和b没有赋值为 c 的两倍? @TSingh 所有表达式(赋值是一个表达式)都返回一个结果。表达式a += 3 会将3 添加到a,然后返回新值。如果在逗号表达式的左侧使用,则返回的结果将被忽略。 @T Singh“忽略结果”与“不评估”不同。 '忽略结果' 意味着'这个表达式完全评估并返回一个值。我不在乎它返回的值是多少,所以我忽略它。' @TSingh:在 C 标准的语言中,表达式a += 3 做了两件事。 main 结果是它返回值 3。副作用 是它将 3 存储在 a 中。这可能看起来很奇怪,因为人类主要使用赋值表达式来表示他们的副作用,而不是他们的主要结果。但是,这就是 C 标准描述行为的方式。逗号运算符丢弃主要结果。它不会丢弃副作用。 @JoachimPileborg 今天我从你们那里学到了一个非常有用但新的东西。我有一个想法,只有函数“返回”结果。我从来没有想过表达式也会返回值。你和 Eric 的个人资料显示为 C 的最佳“回答者”,因此我没有理由怀疑你说的话,我会把这个关于表达的事实告诉我。

以上是关于“算术表达式”是不是允许在 C 中用逗号分隔,或者我们需要为每个单独的语句?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Microsoft 的 C/C++ 编译器允许使用逗号分隔表达式的 if 语句? [复制]

在 Python 中用逗号分隔并去除空格

在mysql中用逗号分隔值连接三个表

在变量 BASH 的一行中用逗号分隔值

如何在vue js中用逗号分隔的字符串中发布子类别?

条目中用逗号分隔的循环子字符串