简体   繁体   English

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

[英]Understanding c-pointers for rows in 2-dimensional array

I have the following code: 我有以下代码:

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;
}

I have a hard time understanding what p is here, and the consequences of the operations on p in the end. 我很难理解这里的p以及最后对p进行操作的后果。 Can someone give me a brief explanation of what happens. 有人可以简要介绍一下发生的情况吗? I know c-pointers in their simple settings, but here it get slightly more complicated. 我知道c指针的简单设置,但是这里变得稍微复杂一些。

a is an array of int[m] , and p is a pointer to int[m] . aint[m]的数组, p是指向int[m]的指针。 It's initialized to a , which decays to a pointer to its first element. 它初始化为a ,其衰变成一个指针,它的第一个元素。

Dereferencing p yields int[m] , which decays to int* (pointer to its first element). p引用产生int[m] ,它衰减为int* (指向其第一个元素的指针)。 So (*p)[2] adds 2 to the int* that was the result of the decay. 因此(*p)[2]2加到int* ,这是衰减的结果。 So it's setting the third of the first 4 integers ( int[m] , with m being 4) to 9 . 因此,它将前4整数( int[m]m为4)中的第三个设置为9

Adding to p would advance the address stored in it by units of sizeof(int[m]) bytes, which at runtime (since m is not a compile time constant) evaluates to 4 * sizeof(int) . 加到p会以sizeof(int[m])个字节为单位提高存储在其中的地址的sizeof(int[m]) ,在运行时(由于m不是编译时间常数),其结果为4 * sizeof(int) So (*(p+1))[2] would access the third of the second 4 integers. 因此(*(p+1))[2]将访问第二个4整数中的第三个。 In total, p has 3 such arrays of 4 ints to point to: a+0 , a+1 and a+2 . 总共p具有3这样的4整数的数组,它们指向: a+0a+1a+2

Notice that you created a C99 VLA, variable length array. 请注意,您创建了C99 VLA可变长度数组。 You need to #define n and m to integer constants to get rid of those VLAs (which aren't quite portable among C compilers). 你需要#define nm到整型常量摆脱那些VLAS(这是不是C语言编译器之间相当便携式)的。

p is a pointer to a 4-element int arrays (ie a pointer to pointer to int , where the first dimension is 4 and the second is unknown). p是一个由4个元素组成的int数组的指针(即,指向int指针,其中第一个维是4,第二个维是未知的)。 When you increment p , it points to the next 4-element int array, ie the fifth int altogether. 当您增加p ,它指向下一个4个元素的int数组,即总共第五个int Then p is dereferenced with offset 2, which means that the seventh int changes, so you get 然后用偏移量2取消p的引用,这意味着第七个int更改,因此您得到

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

as the final state of the 4x3 array. 作为4x3阵列的最终状态。

Some small print statements should make clear what this code does: 一些小的打印语句应清楚此代码的作用:

#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;
}

Example output: 输出示例:

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

Clearly, p is a pointer to int[m] , so p++ will advance the pointer to the next row in a . 显然, p是一个指向int[m]所以p++将指针前进到下一行中的a That is why (*p)[2] will change a[1][2] . 这就是为什么(*p)[2]将更改a[1][2] If you didn't increment p , that line would change a[0][2] . 如果不增加p ,则该行将更改a[0][2]

Hope that was simple enough!? 希望那很简单!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM