将多个用逗号分隔的整数分配给 C 中的 int - 为啥会这样?做啥的? [复制]

Posted

技术标签:

【中文标题】将多个用逗号分隔的整数分配给 C 中的 int - 为啥会这样?做啥的? [复制]【英文标题】:Assigning multiple integers separated by comma to an int in C - Why does that work? What for? [duplicate]将多个用逗号分隔的整数分配给 C 中的 int - 为什么会这样?做什么的? [复制] 【发布时间】:2015-10-21 05:09:26 【问题描述】:

我在考试中看到了这一点,当我尝试它时,我感到很惊讶。我在网上试过,它也有效。所以我认为是C语言。

为什么会这样?这种赋值语法的用例是什么?

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv) 
    int i = (1,2,3,4,5);
    printf("%d", i);
    return 0;

【问题讨论】:

链接指向一些不相关的 C++ 程序。请更新您的问题以显示程序的输出。 (应该是5。) 对于它的价值,有些语言支持多值表达式,如 'r,theta = toPolar(x,y)'。但 C 和 C++ 没有。 该链接仅显示了我对其进行测试的在线工具。最初显示的程序是该站点的默认程序。我只复制并粘贴了我的问题的显示代码以在那里测试它(我怀疑我的编译器是否很奇怪)。 【参考方案1】:

这些不是“多个整数”,而是逗号运算符。整个带括号的部分是一个表达式,每个子表达式(用逗号分隔)严格从左到右求值。除了最右边的子表达式之外的所有结果都将被忽略。整个表达式的结果是最后一个(最右边)表达式的结果。这里是整数值5

请注意,此运算符主要用于仅允许单个表达式添加更多副作用的情况。例如。在这样的循环中:

int cnt = 0;
for ( const char *cp = "Hello" ; *cp != '\0' ; cp++, cnt++ )  ;

这会计算 C 字符串中的字符数,每次迭代后递增指针和 cnt。此处忽略结果。

因此,这与 Python 中的元组或类似的方式没有相关。实际上,没有任何情况下该运算符的使用是不可避免的,应谨慎使用 - 并且某些编码标准禁止使用它。

【讨论】:

在您的示例中,只有第二个, 是逗号运算符,第一个是逗号分隔符。 @MattMcNabb:好的,谢谢。我做了一个更好的例子(好吧,尽可能多;我有更好的例子,但它们不容易被剥离。 请不要回答离题的问题。您的回答将禁止向 roomba 提出问题,并导致社区的手动工作被删除。【参考方案2】:

这就是逗号运算符的作用。它计算左侧的表达式,创建一个序列点,丢弃表达式的值,然后计算右侧的表达式,并将其作为值返回。当示例中有多个表达式时,依次计算每个表达式,只保留最后一个。对于示例,编译器会进行评估,因为每个值在编译时都是已知的。请注意,函数的参数列表不是逗号运算符的使用。

这不是逗号运算符的有效用例。更接近有效的用例可能是一些具有副作用的操作(例如函数调用),这些操作需要排序并分配最终值:

int i = (getchar(), getchar(), getchar());

这会将i 设置为标准输入中的第三个字符,或者如果标准输入中没有三个字符可供读取,则设置为EOF。仍然不是一个实际的用例,但比分配一个常量列表要好。

【讨论】:

在实践中,逗号运算符是 C/C++ 中最没用的部分之一,因为您可以而且应该为这种排序使用单独的语句。 @Kevin 在 C 中几乎没用,但在 C++ 中因为它可以重载,sometimes it'll be useful @Kevin 实际上,在 C++ 中,逗号运算符对于模板元编程非常有用。 @Svalorzen:这几乎不是逗号运算符的错。 TMP 一团糟。【参考方案3】:

除了其他答案之外,您还需要注意 , 是逗号运算符而不是分隔符的情况。例如,以下是无效的:

int i = 1,2,3,4,5;

在这种情况下,, 是变量声明之间的分隔符。它将i声明为int并将其初始化为1,然后尝试将2解析为变量名,但失败了。

【讨论】:

2 不是一个有效的声明,因此逗号在该代码中既不是分隔符也不是运算符。该代码是语法错误,因为它不匹配任何语法规则。 代码无法编译 ***.com/q/17251584/995714 ***.com/q/20163411/995714 ***.com/q/8519884/995714【参考方案4】:

之所以有效,是因为您使用的是“逗号运算符”,它计算左侧和右侧的子表达式,并具有右侧表达式的值。

所以在(1,2,3,4,5) 中,1 被评估并丢弃结果,然后2,3,4,5... 其中(因为下一个逗号)2 被评估并丢弃结果,然后3,4,5 ... 其中3 被评估并丢弃,然后4,5... 其中4 被评估并丢弃,然后5 成为表达式的结果。

至于什么时候有用,主要是当您需要评估几个(子)表达式的副作用但对它们的值不感兴趣(可能是最后一个除外)时的快捷方式。在for 循环表达式中有时会很方便,例如在增加两个变量时:

for (i=0,j=1; j < len; i++,j++) 

..它同时出现在初始化表达式和循环表达式中。

【讨论】:

【参考方案5】:

为什么会这样?

因为它是有效的 C 语法。 (1,2,3,4,5) 中的逗号是逗号运算符

C11:6.5.17 逗号运算符

语法 1个表达式:

assignment-expression
expression , assignment-expression

语义 2 逗号运算符的左操作数被评估为 void 表达式;在它的求值和右操作数的求值之间有一个序列点。然后对右操作数求值;结果有它的类型和值。114)


这种赋值语法的用例是什么?

请看下面的例子

3 示例 如语法所示,逗号运算符(如本小节所述)不能出现在使用逗号分隔列表中的项目(例如函数的参数或初始化程序列表)的上下文中。另一方面,它可以用在带括号的表达式中或第二个表达式中 在这种情况下条件运算符的表达式。在函数调用中

f(a, (t=3, t+2), c)

该函数有三个参数,第二个的值为 5。

【讨论】:

以上是关于将多个用逗号分隔的整数分配给 C 中的 int - 为啥会这样?做啥的? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

用逗号分隔符和 sscanf 分隔整数

正则表达式匹配两个或多个逗号分隔的整数

如何动态地将大小分配给 C++ 中的数组?

创建多个用逗号分隔的空列表

CROSS APPLY返回逗号分隔值以及GROUP BY

c ++在std :: vector中存储逗号分隔的最快方法是啥