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