[英]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]
. a
是int[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+0
, a+1
和a+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
n
和m
到整型常量摆脱那些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.