#include<stdio.h>
#include<stdlib.h>
int main(void)
{
int ar[2][2] = {1,2,3,4};
int **p= NULL , i=0, j=0;
p = ar; //compiler error. Confused ! Do i need to assign &a or anything.
puts("OUT: ");
for(i = 0; i < 2; i++)
{
for(j = 0 ; j < 2; j++)
{
printf("%2d", *(*(ar + i) + j));
printf("%2d", *(*(p + i) + j)); /* This is wrong . Compiler error */
}
}
exit(0);
}
我想创建一个指向2D数组的指针,而不是ar
循环中的for
我应该能够p
。我很困惑。我知道访问2d的其他方法
元素,但我对这个例子感到困惑。
答案 0 :(得分:0)
在第一种情况下,您有一个int[2]
数组,而在第二种情况下,您有一个int *数组。
如果您使用sizeof(ar[0])
,则会打印2*sizeof(int)
,而第二个会打印sizeof(int*)
。
printf("sizeof(ar) = %zu\n", sizeof(ar));
printf("sizeof(ar[0]) = %zu\n", sizeof(ar[0]));
printf("sizeof(ar[0][0]) = %zu\n", sizeof(ar[0][0]));
printf("sizeof(p) = %zu\n", sizeof(p));
printf("sizeof(*p) = %zu\n", sizeof(*p));
printf("sizeof(**p) = %zu\n", sizeof(**p));
自从我尝试使用代码后,将p = a
替换为p = ar
我只有这些错误:
$ gcc -Wall foobar.c
foobar.c: In function ‘main’:
foobar.c:6:3: warning: missing braces around initializer [-Wmissing-braces]
foobar.c:6:3: warning: (near initialization for ‘ar[0]’) [-Wmissing-braces]
foobar.c:12:5: warning: assignment from incompatible pointer type [enabled by default]
foobar.c:21:7: warning: too many arguments for format [-Wformat-extra-args]
它也失败了:
$ ./a.out
sizeof(ar) = 16
sizeof(ar[0]) = 8
sizeof(ar[0][0]) = 4
sizeof(p) = 8
sizeof(*p) = 8
sizeof(**p) = 4
OUT:
Segmentation fault
这是正常的,假设p没有很好地定义。
答案 1 :(得分:0)
ar[2][2]
不会分解为指向指针int **p=ar //is wrong
的指针,它将被分解为指向第一行的指针(如果我们以矩阵形式思考,我认为这很容易),这意味着在你的例子中你的2-d数组由2行组成,每行有2个整数(列)。
因此ar
将被分解为2个整数的指针,可以通过编程方式声明为
int (*p)[2]; //this is pointer to 2 ints
int (*p)[3]; //this is pointer to 3 ints,if your array was declared like this ar[2][3]
因此,在您的计划中,您需要将int **p=NULL
更改为int (*p)[2];
当我们说一个指向2个整数的指针时,这意味着当你添加一个(ex:- p+1) for above example
时,这将指向2-d数组的下两个整数(这意味着下一行)。
答案 2 :(得分:0)
comp.lang.c FAQ list, Question 6.18
的引用数组衰减为指针的规则(参见问题6.3)不是 递归地应用。 (一旦规则应用一次,结果 是规则不再适用的指针。)数组数组 (即C中的二维数组)衰变为指向数组的指针, 不是指向指针的指针。
int **
和int [2][2]
不兼容。您应该将ar
数组视为包含另一个数组的数组。在堆栈上分配的多维数组被存储在内存中。
语句int ar[2][2]
将由编译器更改为int (*ar)[2]
。注意圆括号的位置。这是因为运营商优先:
()
运算符的优先级高于[]
运算符[]
运算符的优先级高于*
运算符。。所以如果你省略它们,那么:
int *ar[2]; // ar is an array of length 2 that holds pointers to ints.
int (*ar)[2]; // ar is a pointer to array of length 2 that hold ints.
您可以通过以下方式解决问题:
int **p = NULL;
更改为int (*p)[2];
int ar[2][2]
更改为int **ar
,然后使用malloc()
想一想如何下载2d数组。例如,声明:
printf("%2d ", *(*(ar + 1) + 1)); // print the ar[1][1]
将1
添加到ar
指针,该指针指向int [2]
。 8个字节被添加到数组开头的地址,然后在取消引用后添加1
将只添加4个字节,因为它现在引用了int。
答案 3 :(得分:-1)
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
int main(void)
{
const int row=4, col=4;
int ar[row][col] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
int **p= NULL ;
int *np = &ar[0][0];
p = &np;
for(int i = 0; i < row; i++)
{
for(int j = 0 ; j < col; j++)
{
printf("address of a[%d][%d] is %x\n",i,j,&ar[i][j]);
printf("%2d\n", *(*(ar + i) + j));
printf("%2d\n", *(*(p)+ i*col + j));
}
}
_getch();
exit(0);
}
我试过这样,它对我有用。