更新:已报告此问题的可能重复.虽然提交给该问题的答案部分地解决了这个问题,但为了解释为什么我们不能使用双指针来表示二维数组,它没有指定如何访问存储在指针中的值的正确存储器地址; 这是这个问题的主题.这个问题中的明确答案可以很好地向未来混淆的人澄清为什么这是一个被误解的概念以及如何解决它的替代方法.这对于希望跟踪输出以更好地理解概念的未来读者可能是有用的(如果你仔细观察OP在该问题中的评论,你会发现跟踪不够清楚,他不能理解.这里提出的问题的一部分提供了一个更好的跟踪示例,以便几乎任何人都可以轻松理解)
(问题的其余部分是未经编辑的荣耀,以便未来的读者能够反思类似的错误,如果他们恰好成功的话.)
我试过的:
下面是一个示例代码:
int main()
{
int a[2][2]={{5,7},
{0,1}};
int** ptr=(int**)a;
int i,j;
for(i=0;i<2;i++){
for(j=0;j<2;j++){
printf("%d printing from==>%x\n",&ptr[i][j],((&ptr[i])+j));
}
}
getch();
return(0);
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,我试图在指针ptr的帮助下打印矩阵a [] []中存在的值.在这样做时,我正在跟踪打印实际发生的位置(在内存地址中).我似乎遇到了以下形式的灾难性输出:
5打印从==> 12ff7c
9打印从==> 12ff80
7打印来自==> 12ff80
11打印来自==> 12ff84
然后我修改了这一行:
printf("%d printing from==>%x\n",&ptr[i][j],((&ptr[i])+j));
Run Code Online (Sandbox Code Playgroud)
有了这个:
printf("%d printing from==>%d\n",&ptr[i][j],*((&ptr[i])+j));
Run Code Online (Sandbox Code Playgroud)
要知道这些地址中实际存在哪些值:
5打印从==> 5
9打印从==> 7
7打印从==> 7
11打印从==> 0
我对此的看法是:&ptr [i] [j]相当于(*(&ptr [i])+ j))和((&ptr [i])+ j))并没有真正告诉我的地址甚至那些数字因为&ptr [i]定义了一个地址,在这种情况下增加了j(但是因为j在每个外部循环迭代中被重置为0;这将导致相同的内存地址被指向两次) 我错了这个链思想?
2D数组和指针指针是不同的动物!
例如,2D阵列int arr[N][M]是具有以下关系的N*M个连续元素的阵列&arr[i][j] == &arr[0][0] + i * M + j.
指针指针是指向指针数组的指针,每个指针指向另一个数组.
所以,你可以做什么?
使用显式索引将数组处理为一维数组
int main()
{
int a[2][2]={{5,7},
{0,1}};
int* ptr=a[0]; // a[0] decays to a pointer...
int i,j;
for(i=0;i<2;i++){
for(j=0;j<2;j++){
printf("%d printing from==>%x\n",ptr[j + 2 *i],ptr + j + 2 * i);
}
}
//getch();
return(0);
}
Run Code Online (Sandbox Code Playgroud)明确地创建一个指针数组
int main()
{
int a[2][2]={{5,7},
{0,1}};
int *b[] = { a[0], a[1] }; // array of pointers pointing to beginning or rows
int** ptr=b; // b decays to a pointer to pointer
int i,j;
for(i=0;i<2;i++){
for(j=0;j<2;j++){
printf("%d printing from==>%x\n",ptr[i][j],&(ptr[i][j]));
}
}
//getch();
return(0);
}
Run Code Online (Sandbox Code Playgroud)明确地使用指向确定大小的数组的指针:
int main()
{
int a[2][2]={{5,7},
{0,1}};
int (*ptr)[2] = a; // a decays to a pointer arrays of size 2
int i,j;
for(i=0;i<2;i++){
for(j=0;j<2;j++){
printf("%d printing from==>%x\n",ptr[i][j],&(ptr[i][j]));
}
}
//getch();
return(0);
}
Run Code Online (Sandbox Code Playgroud)另请注意,我在上面的代码中没有明确的强制转换,让编译器控制了无效级别是正确的.