将逗号分隔的多个整数分配给 C 中的一个 int - 为什么这样做有效?做什么的?
Assigning multiple integers separated by comma to an int in C - Why does that work? What for?
我在一次考试中看到了这个,当我尝试时,我感到很惊讶。我在网上试过,它也有效。所以我认为是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;
}
这是工作中的逗号运算符。它计算左侧的表达式,创建一个序列点,丢弃表达式的值,然后计算右侧的表达式,并将 returns 作为值。当示例中有多个表达式时,将依次计算每个表达式,只保留最后一个。对于示例,编译器会进行评估,因为每个值在编译时都是已知的。请注意,函数的参数列表不是逗号运算符的使用。
这不是逗号运算符的有效用例。更接近有效的用例可能是一些具有副作用的操作(例如函数调用)需要排序并分配最终值:
int i = (getchar(), getchar(), getchar());
这会将 i
设置为标准输入中的第三个字符,如果标准输入中没有剩下三个字符可供读取,则设置为 EOF。仍然不是一个现实的用例,但比分配常量列表更好。
这些不是 "multiple integers",而是逗号运算符。整个括号内的部分是一个表达式,每个子表达式(用逗号分隔)严格从左到右计算。除了最右边的子表达式之外的所有结果都将被忽略。整个表达式的结果是最后一个(最右边)表达式的结果。这里是整数值5
.
请注意,此运算符主要用于只允许单个表达式添加更多副作用的情况。例如。在一个循环中:
int cnt = 0;
for ( const char *cp = "Hello" ; *cp != '[=10=]' ; cp++, cnt++ ) ;
这会计算 C 字符串中的字符数,在每次迭代后递增指针和 cnt
。此处忽略结果。
因此,这 没有 与元组或类似 Python 相关的方式。实际上,在任何情况下都无法避免使用此运算符,应谨慎使用 — 并且某些编码标准禁止使用它。
之所以有效,是因为您使用的是 "comma operator",它计算左侧和右侧的子表达式,并具有右侧表达式的值。
所以在(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++) {
..它同时出现在初始化表达式和循环表达式中的位置。
除了其他答案之外,您还需要注意 ,
是逗号运算符而不是分隔符的情况。例如,以下是无效的:
int i = 1,2,3,4,5;
在这种情况下,,
是变量声明之间的分隔符。它将 i
声明为 int
并将其初始化为 1,然后它尝试将 2
解析为变量名,但失败了。
Why is that working?
因为它是一个有效的 C 语法。 (1,2,3,4,5)
中的逗号是逗号运算符
C11: 6.5.17 逗号运算符
Syntax
1 expression:
assignment-expression
expression , assignment-expression
Semantics
2 The left operand of a comma operator is evaluated as a void expression; there is a sequence point between its evaluation and that of the right operand. Then the right operand is evaluated; the result has its type and value.114)
What is the use case for such an assignment syntax?
参见下面的示例
3 EXAMPLE As indicated by the syntax, the comma operator (as described in this subclause) cannot appear in contexts where a comma is used to separate items in a list (such as arguments to functions or lists of initializers). On the other hand, it can be used within a parenthesized expression or within the second
expression of a conditional operator in such contexts. In the function call
f(a, (t=3, t+2), c)
the function has three arguments, the second of which has the value 5.
我在一次考试中看到了这个,当我尝试时,我感到很惊讶。我在网上试过,它也有效。所以我认为是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;
}
这是工作中的逗号运算符。它计算左侧的表达式,创建一个序列点,丢弃表达式的值,然后计算右侧的表达式,并将 returns 作为值。当示例中有多个表达式时,将依次计算每个表达式,只保留最后一个。对于示例,编译器会进行评估,因为每个值在编译时都是已知的。请注意,函数的参数列表不是逗号运算符的使用。
这不是逗号运算符的有效用例。更接近有效的用例可能是一些具有副作用的操作(例如函数调用)需要排序并分配最终值:
int i = (getchar(), getchar(), getchar());
这会将 i
设置为标准输入中的第三个字符,如果标准输入中没有剩下三个字符可供读取,则设置为 EOF。仍然不是一个现实的用例,但比分配常量列表更好。
这些不是 "multiple integers",而是逗号运算符。整个括号内的部分是一个表达式,每个子表达式(用逗号分隔)严格从左到右计算。除了最右边的子表达式之外的所有结果都将被忽略。整个表达式的结果是最后一个(最右边)表达式的结果。这里是整数值5
.
请注意,此运算符主要用于只允许单个表达式添加更多副作用的情况。例如。在一个循环中:
int cnt = 0;
for ( const char *cp = "Hello" ; *cp != '[=10=]' ; cp++, cnt++ ) ;
这会计算 C 字符串中的字符数,在每次迭代后递增指针和 cnt
。此处忽略结果。
因此,这 没有 与元组或类似 Python 相关的方式。实际上,在任何情况下都无法避免使用此运算符,应谨慎使用 — 并且某些编码标准禁止使用它。
之所以有效,是因为您使用的是 "comma operator",它计算左侧和右侧的子表达式,并具有右侧表达式的值。
所以在(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++) {
..它同时出现在初始化表达式和循环表达式中的位置。
除了其他答案之外,您还需要注意 ,
是逗号运算符而不是分隔符的情况。例如,以下是无效的:
int i = 1,2,3,4,5;
在这种情况下,,
是变量声明之间的分隔符。它将 i
声明为 int
并将其初始化为 1,然后它尝试将 2
解析为变量名,但失败了。
Why is that working?
因为它是一个有效的 C 语法。 (1,2,3,4,5)
中的逗号是逗号运算符
C11: 6.5.17 逗号运算符
Syntax
1 expression:assignment-expression expression , assignment-expression
Semantics
2 The left operand of a comma operator is evaluated as a void expression; there is a sequence point between its evaluation and that of the right operand. Then the right operand is evaluated; the result has its type and value.114)
What is the use case for such an assignment syntax?
参见下面的示例
3 EXAMPLE As indicated by the syntax, the comma operator (as described in this subclause) cannot appear in contexts where a comma is used to separate items in a list (such as arguments to functions or lists of initializers). On the other hand, it can be used within a parenthesized expression or within the second expression of a conditional operator in such contexts. In the function call
f(a, (t=3, t+2), c)
the function has three arguments, the second of which has the value 5.