【问题标题】:Why do I get different results when I apply sizeof operator?为什么我在应用 sizeof 运算符时会得到不同的结果?
【发布时间】:2011-08-11 14:29:31
【问题描述】:

我有这个程序

#include <stdio.h>
int main()
{
   char arr[100];
   printf("%d", (int)sizeof(0,arr));
}

这在编译为 C 文件时打印 4,并在 C++ 文件中打印 100。为什么?我正在使用 gcc。

【问题讨论】:

  • 请注意,使用逗号运算符的唯一原因是产生求值的副作用,但 sizeof 操作的表达式不会被求值。
  • 声明的数组在 C 中的每个 场合都衰减为一个指针,except 当它作为sizeof 或@987654325 的操作数出现时@-操作员。在您的情况下,情况并非如此,因此它被转换为指针。在 C++ 中,仅在需要时才转换数组。
  • 一个很好的例子,说明为什么用 C++ 编译器编译 C 是一种错误的做法。
  • 像这样(或几乎以任何其他方式)使用逗号运算符是一种错误的做法。

标签: c++ c arrays sizeof


【解决方案1】:

在 C 中,逗号运算符右侧操作数的结果具有类型和 。在 C 中,逗号运算符不会产生左值。因此存在左值到右值的转换,导致数组类型衰减为指针类型。所以在 C 中你得到的是sizeof(char*) 的结果。

在 C++ 中,逗号表达式的结果是一个左值。没有这样的转换[如在 C 中],你得到的是 sizeof(arr) 即 100

【讨论】:

  • 这是一个非常甜蜜的答案,我不知道 C 中存在这种行为。
  • 即使逗号运算符在 C 中产生了一个左值,它仍然会打印 100。因为在他的例子中,逗号运算符的右操作数是非左值char*
  • 是的,数组衰减规则指定只要数组名称被用作&amp;sizeof 的操作数,就会发生这种衰减。由于它被用作,(逗号运算符)的操作数,因此无论, 是否保留左值,它都已经衰减。
  • 答案没有解释为什么直接应用sizeof 时C 中的结果不同,因为这也是一个表达式。解释是:sizeof的转换规则中有一个特定的例外。 C++ 中不存在该异常,这无疑是因为转换规则不同。
【解决方案2】:

sizeof 是运算符而不是函数

因此,您正在执行逗号运算符,它返回正确的操作数作为其结果。

在 C++ 中,这是一个引用,所以它仍然是一个数组并且具有完整大小。

在 C 中,在表达式(任何带有运算符的内容)中,类型 array of x 通常会转换为 pointer to x。但是有两个运算符有一个特定的例外:sizeof&amp;

所以sizeof 是否首先到达那里很重要,因为转换规则有例外。 (参见 C99 第 6.3.2.1 节。

你可以用另一种方式看到,这里程序在 C 和 C++ 中返回相同的东西。

#include <stdio.h>
int main(void) {
  char arr[100];

  printf("%d\n", (int)sizeof arr);
  printf("%d\n", (int)sizeof(arr + 0));
  return 0;
}

我的 Mac 上的结果:

100
8

† 6.3.2.1(3) 除非它是 sizeof 运算符或一元 & 运算符的操作数,或者是 用于初始化数组的字符串字面量,类型为“type”的表达式是 转换为类型为“pointer to type”的表达式,它指向 数组对象并且不是左值。

【讨论】:

  • “在 C++ 中,这是一个参考”——你的意思是“这是一个左值”;表达式永远没有引用类型
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-04-06
  • 1970-01-01
  • 2021-07-10
  • 1970-01-01
  • 1970-01-01
  • 2023-03-13
  • 2020-03-23
相关资源
最近更新 更多