我有以下代码:
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指针,但这里稍微复杂一些。
答案 0 :(得分:2)
a
是int[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]
整数中的第三个。总的来说,4
有p
个3
整数数组,指向:4
,a+0
和a+1
。
请注意,您创建了一个C99 VLA,可变长度数组。您需要a+2
#define
和n
整数常量来摆脱那些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]
。
希望这很简单!?