【问题标题】:Why I get the length of an array like this? [duplicate]为什么我得到这样的数组的长度? [复制]
【发布时间】:2016-06-24 12:01:22
【问题描述】:

如果我有:

int a[] = {1,2,3};
int len = sizeof(a) / sizeof(int);

我得到 3,但我不明白为什么。

他们总是告诉我数组是一个指针,不存储它的长度,而只存储指向第一个元素的指针。

有人可以更好地向我解释一下吗?

【问题讨论】:

  • 谁教你数组是指针是非常错误的,正如你从这个例子中看到的那样。忽略它。我不确定有什么要解释的。 sizeof(a) 为您提供数组的大小(以字节为单位)。
  • 我想我的陈述过于简单化了我的意思。没有错,但过于简单化了。取点。将删除 cmets
  • @UnderDog 或者完全错误。至少,它是一种会导致如此多的混乱以致适得其反的心理模型。
  • @juanchopanza,我不会弯下腰在这样的水平上争论。这不是完全错误,这是我想说的过于简单化的版本。它“可以”被视为指向第一个元素的常量指针。我会拉上拉链并继续前进。看来你有很多时间来发表这种贬低的言论。
  • @UnderDog 鉴于这是一个关于为什么数组 不是 指针的问题,我不认为指出你的过度简化是错误的等级。对此已经有太多的困惑,看到更多的人在做这件事变得乏味。

标签: c pointers


【解决方案1】:

在大多数表达式中,数组衰减为指向数组第一个元素的指针。有两种情况没有,因此结果不一样。

int array[5];
int* ptr = array;   // Array decays to a pointer, OK.

// Same
int a = array[0];
int a = ptr[0];

// Same
void foo(int*);
foo(array);
foo(ptr);

// Not same
size_t s = sizeof(array);  // s is 5*sizeof(int)
size_t s = sizeof(ptr);    // s is sizeof(int*)

// Not same
int (*p1)[5] = &array;     // p1 is a pointer to "an array of 5 ints"
int **p1 = &ptr;           // p1 is a pointer to "an int*"

【讨论】:

    【解决方案2】:

    sizeof a 以存储单元(字节)为单位返回整个数组的大小。 sizeof (int) 返回存储单元中单个整数的大小。因为a 是一个由 3 个整数组成的数组,所以sizeof a / sizeof (int) 给你 3。

    他们总是教我一个数组,它是一个指针

    “他们”教错了你。除非它是sizeof 或一元& 运算符的操作数,否则数组表达式 将被转换(“衰减”)为指针表达式,指针表达式的值将是数组的第一个元素的地址,但数组 object 不是指针。

    当您声明a 时,您在内存中得到的内容如下所示:

      +---+
    a:|   | a[0]
      +---+
      |   | a[1]
      +---+
      |   | a[2]
      +---+
    

    没有与数组元素分开的对象a;任何地方都没有指针。

    【讨论】:

      【解决方案3】:

      他们总是教我一个数组,它是一个指针

      那是你的问题,就在那里。 当您调用函数并将数组作为参数传递时,它会被转换为指向第一个元素的指针。否则,它们是不等价的。特别是,数组有地址、类型和大小,而指针只有地址和类型。

      这是第一次学习 C 的人中很常见的混淆,甚至一些教科书也弄错了。

      edit:在其他一些情况下,数组“衰减”为指针,通常是在表达式中使用它们时。有关更详尽的处理方法,请参阅其他很好的答案之一。

      【讨论】:

      • "当您调用函数并将数组作为参数传递时,它会被转换为指向第一个元素的指针。"如果参数是指针。关键是参数必须是指针,而指针只是一个指针。
      • @juanchopanza:没有“如果”;将数组作为函数参数传递 always 会导致它衰减为指针。如果你声明int f(int a[]),就好像你写了int f(int *a),而函数内部sizeof(a)会返回一个指针的大小。
      • @dan04 关键是函数不能将数组作为参数。因此,甚至不必考虑处理数组的可能性,因为参数是指针。无论是这样,还是将数组作为参数传递都会导致编译器错误。
      • 当然,不仅仅是“当你调用一个函数并将一个数组作为参数传递时”。每当数组出现在表达式中时,而不是在 &sizeof 的右侧。
      • @SteveSummit,这是一个很好的观点。我会稍微修改一下答案。
      【解决方案4】:

      数组可以衰减为指针,但这并不意味着数组就是指针。详情请见this SO question

      sizeof 返回其操作数的数据类型的大小(以字节为单位)。在这种情况下,数据类型是长度为 3 的 int 数组。但是,由于 int 可以在不同平台上以不同方式表示,因此您必须除以 sizeof(int) 才能获得长度。

      有关sizeof 的更多详细信息,请参阅here

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-03
        • 1970-01-01
        • 1970-01-01
        • 2020-05-02
        相关资源
        最近更新 更多