我编写了关于sizeof
运算符的代码。如果我写下这样的话:
#include <stdio.h>
int main() {
char a[20];
printf("%zu\n", sizeof(a));
return 0;
}
输出:
20 // Ok, it's fine
但是,如果我使用逗号运算符,请执行以下操作:
#include <stdio.h>
int main() {
char a[20];
char b;
printf("%zu\n", sizeof(b, a));
return 0;
}
输出:
8 // Why the output 8?
所以,我有一个问题:
8
?comma
运营商对sizeof()
运营商的行为是什么?答案 0 :(得分:12)
逗号运算符对sizeof
没有特殊含义。
sizeof(b, a)
检查完整的表达式(b, a)
,计算出结果类型,并计算该类型的大小,而不实际评估(b , a)
。正如chqrlie在注释中所指出的,()
是表达式的一部分,其中(结果)的大小被评估。
在这种情况下,b
是char
,a
是一个数组。如果要评估表达式b, a
,将首先评估b
,结果将被丢弃。然后a
将转换为指针(char *
),其值等于&a[0]
,这将是表达式(b, a)
的结果。
由于b, a
的结果属于char *
类型,sizeof(b,a)
等于sizeof (char *)
。这是一个实现定义的值,但对于您的编译器,其值为8
(这可能意味着代码正在构建为64位应用程序)。
答案 1 :(得分:11)
在大多数情况下,数组会衰减为指针。因此,带逗号运算符的b,a
类型为char*
(不再是char[20]
)。指针在你的机器上是8个字节。
BTW,我认为在某些逗号运算符上使用sizeof
对读者来说真的很困惑。我建议在简单表达式或类型上使用sizeof
。
(我刚刚发现这是C和C ++之间的一个棘手的差异;请参阅this explanation)
答案 2 :(得分:4)
C语言是一种 lvalue-discarding 语言。 C中的逗号运算符不会产生左值,也不会保留数组的“数组”。这意味着当右侧操作数是一个数组时,它会立即进行数组到指针的转换。因此,在C语言中,逗号运算符的结果是char *
类型的右值。这是您应用sizeof
的内容。这就是为什么你得到8
作为结果,这是你平台上的指针大小。
C ++语言是一种左值保留语言。 C ++中逗号运算符的右边操作数是 not 进行左值到右值的转换,如果操作数是一个数组,它保持其左值和它的数组类型。在C ++中,逗号运算符的结果是类型为char[20]
的左值。这是您应用sizeof
的内容。这就是为什么你得到20
的结果。
答案 3 :(得分:1)
sizeof
根据其操作数的类型确定大小。在sizeof(a)
中,a
不会衰减指向它的第一个元素,a
的类型将为char[20]
。在sizeof(b, a)
中,a
是逗号运算符的右操作数,在此上下文中它将衰减指向它的第一个元素,表达式b , a
的类型将是char *
。因此,sizeof(b, a)
将返回char *
数据类型的大小。
在C ++中,,
运算符的结果是左值(与C不同,它产生一个右值)。在这种情况下,sizeof(b, a)
将返回数组a
的大小。