我想打印包含在多维数组中的值。我知道如果我们编写类似arr[3][4]
的内容,那么arr[0]
是指向该多维数组中第一个元素的指针。
我想问一下为什么这个代码在程序打印多维数组中包含的数字后给我垃圾值?
这是代码:
#include <stdio.h>
#define ROW 3
#define COLL 4
int main(void) {
int arr[ROW][COLL]={{1,2,3,4},
{5,6,7,8},
{9,10,11,12}};
int *ptr;
for(ptr=arr[0];ptr<arr[ROW]+COLL;ptr++){
printf("%d ",*ptr);
}
printf("\n");
return 0;
}
这是我编译上面代码时的结果:
1 2 3 4 5 6 7 8 9 10 11 12 -1079481492 134513936 0 -1079481352
但将for循环更改为以下内容后:
for(ptr=arr[0];ptr<=arr[ROW-1]+COLL-1;ptr++)
代码工作并给出多维数组中包含的确切数字。
答案 0 :(得分:2)
因为arr[ROW]
是一个越界访问。 arr
中的最后一个有效位置是arr[ROW-1]
。因此,代码的第一个版本调用未定义的行为。
答案 1 :(得分:0)
指向最后一个元素的指针是
arr[ROW-1] + COLL - 1
所以你应该循环
for (ptr = arr; ptr < arr[ROW-1] + COLL; ptr++) {
答案 2 :(得分:0)
数组的元素从0开始索引,因此矩阵中的最后一个元素是arr[ROW-1][COLL-1]
。
当指针到达arr[2] + COLL
时,没有这样的元素,因为最后一行中最后一个元素的第二个坐标是[COLL-1]
。
数组的元素存储在1D中,因此arr[0] + 4
是acctualy arr[1][0]
。
当您递增ptr++
时,它会告诉编译器在当前之后访问下一个内存位置。因此,当ptr
指向a[0] + 4
时它起作用,因为编译器访问a[0][0]
之后的第五个值,这实际上是下一行arr[1][0]
中的第一个值,因为它们的内存地点彼此相邻。
当ptr
指向arr[4] + i, i = 0, 1, 2, 3
时,输出结果不正确,因为这些元素不在您的数组中。
答案 3 :(得分:0)
因为您的第一个元素1位于arr[0]+0
,
5位于arr[1]+0
,
9位于arr[2]+0
,
10是arr[2]+1
,
11位于arr[2]+2
,
和12,这是数组的最后一个元素是arr[2]+3
。
但是你的for循环即使在数组结束后也会继续移动,也就是说,直到达到内存位置arr [3] +4。给你四个垃圾值,因为我们在arr [2] +3之后没有在内存中存储任何东西。
所以for循环应该是这样的:
for (ptr=arr; ptr <= arr[ROW-1]+COLL-1; ptr++);
相当于:
for (ptr=arr[0]; ptr <= arr[ROW-1]+COLL-1; ptr++);
as arr [0]和arr指向内存中的相同位置。 注意 - 尝试阅读如何在多维数组中分配内存。