【问题标题】:Multidimensional arrays: don't the pointers point to their own addresses?多维数组:指针不是指向自己的地址吗?
【发布时间】:2014-10-15 02:11:58
【问题描述】:

我是一名正在学习 C 的学生,正在努力解决一些问题。

假设您有一些多维数组int multi[2][2]multi 的值将是指向multi[0] 地址的指针。为简单起见,假设地址为 1000。取消引用multi[0] 会提取另一个地址,这个地址就是multi[0][0] 的地址。反过来,取消引用会为我们获取值(如果在左侧,则返回分配地址。)

现在,multi + 1 返回第二个指针的地址。假设我们有 4 个字节的整数(其中每个嵌套数组有两个),所以multi + 1 返回的地址将为 1008。此地址将包含multi[1][0] 的地址,即 1008。

所以我在这里看到了一个模式:这是否意味着multi[0]multi[1] 等中的地址包含一个指向它自己的地址的指针?

【问题讨论】:

  • 为什么不参考&multi[0]亲眼看看呢?
  • "multi[0], multi[1] 中的地址" -- 里面没有任何地址,里面有数组。这些数组包含整数。这里唯一可以找到的地址是编译器在表达式中使用数组时生成的地址……数组被转换为指针,因为在 C 中,数组不是第一类对象。

标签: c pointers multidimensional-array


【解决方案1】:

数组和指针是不同的。这个话题在书中往往表现不佳。

对于int multi[2][2],这是一个4 连续整数块。不涉及指针。 C 的类型系统将此块划分为两个子数组,每个子数组包含2 ints。

这些表达式:multimulti[0] 表示数组。当您在 sizeof& 以外的上下文中使用表示数组的表达式时,将执行转换,该转换的结果是指向数组第一个元素的指针。

这个指针是一个 rvalue,即它具有与x + y 相同的状态:这是一个您可以使用的值,但它不消耗任何存储空间(至少,它是不作为数组的一部分存储);而且你不能在上面使用& 运算符。

【讨论】:

    【解决方案2】:

    multi的值是指向multi[0]地址的指针

    如果multi是一个数组,用在表达式中,它会被转换为指向multi[0]的指针,其值是multi[0]的地址。数组在表达式中使用时,总是被转换为指向其第一个元素的指针……因此,C 中的数组不是第一类对象,不能传递给函数(只有它们的地址可以)或赋值(memcpy用于复制数组)。

    解引用multi[0]会提取另一个地址,这个地址就是multi[0][0]的地址

    没有“提取”。取消引用multi[0] 会生成一个数组,该数组转换为指向其第一个元素的指针。这个指针的值是multi[0][0] 的地址。所有这些地址都具有相同的值,因为它们指向内存中完全相同的位置......四个ints 中的第一个。

    现在,multi + 1 返回第二个指针的地址。

    同样,内存中没有指针multi + 1 指的是一个数组......两个ints 的两个数组中的第二个。在表达式中使用该数组它转换为指向其第一个元素multi[1][0]的指针。

    假设我们有 4 个字节整数(其中每个嵌套数组有 3 个),所以 multi + 1 返回的地址将为 1012。

    呃,你声明了int multi[2][2],这是两个数组,每个数组包含两个数组。所以multi + 1 是 1008。

    这个地址将包含multi[1][0]的地址,即1012。

    谈论包含地址的地址是没有意义的。 指针 包含地址,但我们这里没有指针在内存中,我们只有ints。 multi[1][0] 是一个int,它的地址是1008。multi[1] 是一个ints 的数组,它的地址也是1008……当然,因为它的地址和它的第一个元素的地址是一样的.

    所以在这里我看到了一个模式:这不是说 multi[0]、multi[1] 等中的地址包含指向它自己地址的指针吗?

    multi[0]multi[1] 中没有地址,有数组ints)。数组个地址,但在这种情况下它们不包含个地址。 “看到模式”的方法是根据记忆中的内容进行思考。在这里,您只需要一个包含 4 个ints 的块——两个数组,每个数组有两个ints;数组在 C 中没有开销或其他无关内容,它们只有数据......你声明的就是你得到的。数组是一个抽象,一组由其类型和大小决定的项,它们只存在于编译时和程序员的脑海中。因此,multi[0] 包含一个数组,在 C 程序的抽象模型中,但内存中只有四个 ints,其中前两个组成了该数组。

    情况会有所不同

    int* multi[2];
    

    你有一个由两个指向int 的指针组成的数组;每个指针将指向ints 的数组(一旦将其设置为ints 的数组的地址,通常从malloc 获得)。为子数组分配内存并分配两个指针后,您可以像使用上面的 multi 一样使用此 multi,但 multi[0]multi[1] 的类型、大小和内存布局相当两种情况不同。

    【讨论】:

      猜你喜欢
      • 2013-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-01
      • 1970-01-01
      • 2013-05-12
      相关资源
      最近更新 更多