理解二维数组中行的c指针

时间:2010-04-19 21:24:02

标签: c arrays pointers multidimensional-array

我有以下代码:

int main() {
    int n = 3, m = 4, a[n][m], i, j, (* p)[m] = a;
    for (i = 0; i < n; i++)
        for (j = 0; j < m; j++)
            a[i][j] = 1;
    p++;
    (*p)[2] = 9;
    return 0;
}

我很难理解p在这里是什么,以及最后操作对p的影响。有人能给我一个简短的解释,说明会发生什么。我知道简单设置中的c指针,但这里稍微复杂一些。

3 个答案:

答案 0 :(得分:2)

aint[m]的数组,p是指向int[m]的指针。它被初始化为a,它衰减到指向其第一个元素的指针。

取消引用p会产生int[m],它会衰减到int*(指向其第一个元素的指针)。因此(*p)[2]2添加到int*,这是衰变的结果。因此,它将第一个4整数(int[m],其中m为4)设置为9

添加到p将以sizeof(int[m])个字节为单位提升存储在其中的地址,在运行时(因为m不是编译时常量),计算结果为{{1} }。因此4 * sizeof(int)将访问第二个(*(p+1))[2]整数中的第三个。总的来说,4p3整数数组,指向:4a+0a+1

请注意,您创建了一个C99 VLA,可变长度数组。您需要a+2 #definen整数常量来摆脱那些VLA(在C编译器中不太可移植)。

答案 1 :(得分:2)

p是指向4个元素int数组的指针(即指向int指针的指针,其中第一个维度为4,第二个维度为未知)。当您递增p时,它会指向下一个4元素int数组,即第五个int数组。然后使用偏移量2取消引用p,这意味着第七个int更改,因此您获得

  1 1 1 1
  1 1 9 1
  1 1 1 1

作为4x3阵列的最终状态。

答案 2 :(得分:2)

一些小的印刷语句应该清楚这段代码的作用:

#include <stdio.h>

int main() {
    int n = 3, m = 4, a[n][m], i, j, (* p)[m] = a;
    for (i = 0; i < n; i++)
        for (j = 0; j < m; j++)
            a[i][j] = 1;

    printf("p points to %u, sizeof(int)*m = %d", p, sizeof(int)*m);
    p++;
    printf(", p++ points to %u\n", p);

    (*p)[2] = 9;

    for (i = 0; i < n; i++)
        for (j = 0; j < m; j++)
            printf("a[%d][%d] = %d\n", i, j, a[i][j]);

    return 0;
}

示例输出:

p points to 2293536, sizeof(int)*m = 16, p++ points to 2293552
a[0][0] = 1
a[0][1] = 1
a[0][2] = 1
a[0][3] = 1
a[1][0] = 1
a[1][1] = 1
a[1][2] = 9
a[1][3] = 1
a[2][0] = 1
a[2][1] = 1
a[2][2] = 1
a[2][3] = 1

显然,p是指向int[m]的指针,因此p++会将指针前进到a中的下一行。这就是为什么(*p)[2]会改变a[1][2]的原因。如果您没有增加p,则该行会更改a[0][2]

希望这很简单!?