关于C中指针的问题?

时间:2009-06-15 08:53:47

标签: c pointers

int a[A][B];
int* p = a[i];  //i<A-1

然后下面句子的实际操作是什么?

p++;
p+=B;

8 个答案:

答案 0 :(得分:13)

p++ - &gt;转到矩阵中的下一列

p+=B - &gt;转到矩阵中的下一行(在同一列)。

答案 1 :(得分:4)

对于多维数组,必须记住从左到右应用维度,这使得可视化更容易一些。例如:

int p[A][B][C];

这将构建为:

[][]--[][][][]--[][]_ _ _[][]--[][]   [][]--[][][][]--[][]_ _ _[][]--[][]
|---A----||---A----|     |---A----|---|---A----||---A----|     |---A----|
|---------------A*B---------------|   |---------------A*B---------------|
|---------------------------------A*B*C---------------------------------|

所以,如果你有p [i] [j] [k],我实际上(p + i + Bj + BCk)

答案 2 :(得分:0)

初始化后,a存储A B ints,p指向B 第i个(基于0)。 后面的操作使它指向B *(i + 1)+ 1'。

答案 3 :(得分:0)

p = a[A-1]

相同
p = &a[A-1][0]

所以

p++

结果

p == &a[A-1][1]

然后做

p+=B

将导致

p == &a[A-1][1+B] == &a[A][1] // outside allocated memory

答案 4 :(得分:0)

只是为了进一步加强对话(虽然我实际上无法直接回复cbailey的帖子而没有足够的代表......)

在堆栈上和堆上声明多维数组之间存在很大差异。

由于abelenky可能会进入,在堆栈上声明一个多维数组将始终导致连续的内存。我相信C标准实际上在某个地方说明了这一点,但即使它没有,地球上的每个编译器都会确保它是连续的。 这意味着在一天结束时,您可能也在使用单维数组,因为编译器无论如何都会转换为该数组。

就使用多维数组时的安全性而言,无论它们是在堆还是堆栈上分配,您都不希望以原始海报的方式迭代它们。

答案 5 :(得分:0)

这是一个元答案,很像Justicle和原始海报一样。

数组退化为指针,但它们不是同一个东西。只是因为a [3] [7] [1]的语法是相同的,如果a是指向指针指向int的指针而不是数组的数组 - -int并不意味着实际操作是相同的。

您可以创建一个任何类型的数组(定义良好的大小)。数组解除引用语法和指针语法是相同的,例如

a[i] == *(a+i) == i[a]

无论a是什么数组类型。

此主题中所有问题的答案都可以从中得出。

int a[3][2][17];      //a is an array of length 17.
int (*b)[3][2] = a[5]; //b is a pointer to the fifth element of a
int (*c)[3] = b[1];    //c points to the first element of b.
b += 1; // b now points to the sixth element of a. (c is unchanged)
c += sizeof(*b); // c points to the first element of b again.

请注意,如果不连续,这一切都不会起作用。如果它不起作用,那么数组的数组将与其他任何数组的工作方式不同。

答案 6 :(得分:-1)

如果你以记忆形式绘制a [A] [B]矩阵,也就是一个向量,并以p指向[i]的开头,然后应用这些操作,那么答案很简单。

答案 7 :(得分:-1)

要回答这个问题,首先需要了解多维数组如何在C中存储在内存中。

int a[A][B];

不考虑它在内存中的优化方式,第一个索引(A)实际上是指向第二个索引(B)的指针数组。 虽然内存可能是连续的,但无法保证

因此:

int a[A][B];
int **b;

上面的 a b 之间的区别在于a的内存在进入范围时会被分配。

考虑到这一点,回答你的问题:

int* p = a[i]; // p = a[i][0]
p++; // p = a[i][1]
p+=B; // p = a[i][1+B]

使用现代编译器,可能已经分配了一个连续的内存块,相当于:

p = a[i+1][1];

但是不能保证内存是连续的,所以可能的情况是你现在有一个无效的指针。