C 中 sizeof() 运算符中 "comma" 运算符的行为
Behavior of "comma" operator in sizeof() operator In C
我写了关于 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()
运算符的行为是什么?
在大多数情况下,数组会退化为指针。因此,带有逗号运算符的 b,a
的类型是 char*
(不再是 char[20]
)。指针在你的机器上是 8 个字节。
顺便说一句,我认为在某些逗号运算符上使用 sizeof
确实会使 reader 混淆。我建议在简单表达式或类型上使用 sizeof
。
(我刚刚发现这是 C 和 C++ 之间的棘手差异之一;参见 this explanation)
逗号运算符对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 位应用程序)。
sizeof
由其操作数的类型决定大小。在 sizeof(a)
中,a
不会衰减到指向其第一个元素的指针,并且 a
的类型将为 char[20]
。在 sizeof(b, a)
中,a
是逗号运算符的右操作数,在这种情况下,它将衰减为指向它的第一个元素的指针,表达式 b , a
的类型将是 char *
.因此,sizeof(b, a)
将 return 大小的 char *
数据类型。
在 C++ 中,,
运算符的结果是一个左值(不同于在 C 中它产生一个右值)。在那种情况下 sizeof(b, a)
将 return 数组的大小 a
.
C 语言是一种左值丢弃 语言。 C 中的逗号运算符不产生左值,也不保留数组的 "arrayness"。这意味着当右侧操作数是一个数组时,它会立即进行数组到指针的转换。由于这个原因,在 C 中,逗号运算符的结果是 char *
类型的右值。这就是您应用 sizeof
的对象。这就是为什么你得到 8
结果,这是你平台上的指针大小。
C++ 语言是一种左值保留 语言。 C++ 中逗号运算符的右手操作数是 not 进行左值到右值转换,如果操作数是数组,它会保持其左值性和数组类型。在 C++ 中,逗号运算符的结果是 char[20]
类型的左值。这就是您应用 sizeof
的对象。这就是为什么你得到 20
作为结果。
我写了关于 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()
运算符的行为是什么?
在大多数情况下,数组会退化为指针。因此,带有逗号运算符的 b,a
的类型是 char*
(不再是 char[20]
)。指针在你的机器上是 8 个字节。
顺便说一句,我认为在某些逗号运算符上使用 sizeof
确实会使 reader 混淆。我建议在简单表达式或类型上使用 sizeof
。
(我刚刚发现这是 C 和 C++ 之间的棘手差异之一;参见 this explanation)
逗号运算符对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 位应用程序)。
sizeof
由其操作数的类型决定大小。在 sizeof(a)
中,a
不会衰减到指向其第一个元素的指针,并且 a
的类型将为 char[20]
。在 sizeof(b, a)
中,a
是逗号运算符的右操作数,在这种情况下,它将衰减为指向它的第一个元素的指针,表达式 b , a
的类型将是 char *
.因此,sizeof(b, a)
将 return 大小的 char *
数据类型。
在 C++ 中,,
运算符的结果是一个左值(不同于在 C 中它产生一个右值)。在那种情况下 sizeof(b, a)
将 return 数组的大小 a
.
C 语言是一种左值丢弃 语言。 C 中的逗号运算符不产生左值,也不保留数组的 "arrayness"。这意味着当右侧操作数是一个数组时,它会立即进行数组到指针的转换。由于这个原因,在 C 中,逗号运算符的结果是 char *
类型的右值。这就是您应用 sizeof
的对象。这就是为什么你得到 8
结果,这是你平台上的指针大小。
C++ 语言是一种左值保留 语言。 C++ 中逗号运算符的右手操作数是 not 进行左值到右值转换,如果操作数是数组,它会保持其左值性和数组类型。在 C++ 中,逗号运算符的结果是 char[20]
类型的左值。这就是您应用 sizeof
的对象。这就是为什么你得到 20
作为结果。