【问题标题】:Why is `*(multi + row)` producing a pointer address instead of a value?为什么 `*(multi + row)` 会产生指针地址而不是值?
【发布时间】:2013-06-10 11:09:38
【问题描述】:

为什么*(multi + row) 生成的是指针地址而不是值?我很困惑,但必须有一个很好的解释,但我仍然不知道。

#include <stdio.h>
#define ROWS 5
#define COLS 10
int multi[ROWS][COLS];
int main(void)
{
    int row, col;
    for (row = 0; row < ROWS; row++)
    {
        for (col = 0; col < COLS; col++)
        {
            multi[row][col] = row*col;
        }

    }
    for (row = 0; row < ROWS; row++)
    {
        for (col = 0; col < COLS; col++)
        {
            printf("\n%d ",multi[row][col]);
            printf("%d ",*(*(multi + row) + col));
        }
    }
    return 0;
}

【问题讨论】:

标签: c pointers multidimensional-array


【解决方案1】:

它没有。 multi 是一个二维数组,因此当您对其执行指针算术运算时,解引用它会衰减到的指针会产生一个数组(它是 COLS 元素宽)。

步骤:

  1. int multi[ROWS][COLS]; - 这里multi 是一个二维数组。

  2. multi + row - 这里的multi 衰减为int (*)[COLS] 类型的指针

  3. *(multi + row) - 这相当于multi[row],即。 e.这个表达式的类型是int[COLS]

【讨论】:

    【解决方案2】:

    因为 multi 是一个二维数组,其计算结果为块指针。

    *(*(multi + row));
    

    应该给你一个价值。

    *(multi + row);
    

    计算指向索引由“行”确定的行的指针

    更新

    块指针仍然像其他指针一样包含地址,但它的算术运算是在块而不是单个元素上进行的,例如指向数组第一行的指针。如果你增加它,它会跳过一行数组(而不是像普通指针那样的一个元素)。

    【讨论】:

    • 我正在添加块指针的解释。为什么人们投票的速度如此之快?刚刚添加了那个。请耐心等待您的评估。
    • 就C标准而言,这种数据类型被称为“指向[N个元素]数组的指针”。
    • 我很确定这些术语是可以互换的。大约 11 年前,我在我的第一门 C 语言编程课程中学会了它。让我找一个参考,并在这里添加。谢谢。
    【解决方案3】:

    multi 具有“数组的数组”形式的类型,因此在大多数情况下,它会衰减为“指向数组的指针”形式的类型。添加row后,它仍然是“指向数组的指针”类型,但可能指向的数组不是multi中的第一个数组(第一行)。

    现在,将* 运算符应用于“指向数组的指针”会产生一个数组类型,该类型再次衰减为指向其初始元素的指针。此指针的类型为“指向int 的指针”。

    【讨论】:

      【解决方案4】:

      因为它是一个二维数组,所以在获取值之前需要经过两个间接级别。

      【讨论】:

        【解决方案5】:

        multiarrayinteger arrayint (multi[rows])[cols]

        multi 可以衰减 指向integer array 的指针。所以 multi 可以衰减到int (*multi)[cols]

        所以当你这样做 multi+rows 时,你实际上是在这样做

        sizeof(int [cols]) + sizeof(int[cols])...`row` times 
        

        当你取消引用它时,你会得到一个array of ints 类型的元素,即你在multi+row 中得到的整数数组的第一个元素的address。现在向这个取消引用的指针添加偏移量,然后再次取消引用,您将获得元素即

        *(multi+row) /*call this x*/-->gives an element of type int[] and int[] can decay to int*.
        *(x+cols) --> gives you the element.
        

        【讨论】:

        • 谢谢!!有没有办法对其进行逆向工程?我的意思是说:你如何声明一个双指针并最终初始化所有数组元素?
        • 如果你使用双指针,那么它也是一样的。像这样声明int **multi; 并按照我上面的说明使用它。但这有两个直接的问题。 1)您需要已经分配了内存,否则UB。 2)你需要做所有关于你索引的地方的簿记。如果可以创建二维数组,请不要使用双指针。
        • 谢谢!!当然这会有所帮助。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-04-04
        • 2011-11-18
        • 1970-01-01
        • 2020-08-29
        • 2020-09-09
        • 2016-01-06
        • 1970-01-01
        相关资源
        最近更新 更多