我写了关于sizeof
运算符的代码。如果我写这样的东西:
#include <stdio.h>
int main() {
char a[20];
printf("%zun", sizeof(a));
return 0;
}
输出:
20 // Ok, it's fine
但是,如果我像这样使用逗号运算符:
#include <stdio.h>
int main() {
char a[20];
char b;
printf("%zun", sizeof(b, a));
return 0;
}
输出:
8 // Why the output 8?
所以,我有一个问题:
- 为什么编译器在第二个示例中给出输出
8
? comma
操作员变成sizeof()
操作员的行为是什么?
号运算符对sizeof
没有特殊含义。
sizeof(b, a)
检查完整的表达式(b, a)
,计算出结果类型,并在不实际计算(b , a)
的情况下计算该类型的大小。 正如 chqrlie 在注释中指出的那样,()
是计算(结果)大小的表达式的一部分。
在本例中,b
是char
,a
是数组。 如果要计算表达式b, a
,将首先计算b
,丢弃结果。 然后a
将转换为值等于&a[0]
的指针(char *
),这将是表达式(b, a)
的结果。
由于b, a
的结果是 char *
类型,sizeof(b,a)
等于 sizeof (char *)
。 这是一个实现定义的值,但对于编译器来说,其值为 8
(这可能意味着代码正在构建为 64 位应用程序)。
在大多数情况下,数组衰减为指针。因此,带有逗号运算符的b,a
类型是char*
(不再是char[20]
)。指针在您的机器上是 8 个字节。
顺便说一句,我认为在某些逗号运算符上使用sizeof
确实让读者感到困惑。我建议对简单表达式或类型使用 sizeof
。
(我刚刚发现这是C和C++之间的棘手区别之一;请参阅此解释)
C语言是一种弃用左值的语言。C 中的逗号运算符不产生左值,也不保留数组的"数组性"。这意味着当右侧操作数是数组时,它会立即进行数组到指针的转换。出于这个原因,在 C 中,逗号运算符的结果是类型 char *
的右值。这就是您应用sizeof
的内容。这就是为什么你会得到8
作为结果,这是你平台上的指针大小。
C++语言是一种保持价值的语言。C++ 中逗号运算符的右操作数不受左值到右值的转换,如果操作数是数组,则保持其右值和数组类型。在C++逗号运算符的结果是 char[20]
类型的左值。这就是您应用sizeof
的内容。这就是为什么你会得到20
结果。
sizeof
根据其操作数的类型确定大小。在sizeof(a)
中,a
不会衰减到指向它的第一个元素的指针,a
的类型将char[20]
。在sizeof(b, a)
中,a
是逗号运算符的右操作数,在这种情况下,它将衰减为指向它的第一个元素的指针,表达式的类型b , a
char *
。因此,sizeof(b, a)
将返回char *
数据类型的大小。
在C++中,,
运算符的结果是一个左值(不像在 C 中它产生一个右值)。在这种情况下sizeof(b, a)
将返回数组a
的大小。