逗号的行为"逗号" sizeof()运算符中的运算符在C中

时间:2017-10-18 09:38:25

标签: c arrays sizeof comma c11

我编写了关于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()运营商的行为是什么?

4 个答案:

答案 0 :(得分:12)

逗号运算符对sizeof没有特殊含义。

sizeof(b, a)检查完整的表达式(b, a),计算出结果类型,并计算该类型的大小,而不实际评估(b , a)。正如chqrlie在注释中所指出的,()是表达式的一部分,其中(结果)的大小被评估。

在这种情况下,bchara是一个数组。如果要评估表达式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的大小。