int (*p)[4]和 int a[4]; int *p=a;有本质区别么, int (*p)[4]如何初始化

如题所述

有本质区别,

int (*p)[4]:p的类型是指向一个数组的指针

int *p=a:p是一个指向整数的指针

初始化:

int (*p)[4] = &a;

要理解这个先要清楚指针的类型问题。内存地址保存在任何类型的指针中都是一个数值而已,但指针变量本身是有类型的,可能两个不同类型的指针变量的值是一样的。

假设 int *p = a; int (*q)[4] = &a; 这里p和q的值肯定是一样的,但是指针指向的类型不同,p指向的是int,而q指向的是int[4]。类型对于指针的影响是指针运算的偏移量:假设p是一个指针,类型是T,那么p+1的偏移量就是:p的地址值+sizeof(T)。所以上面的例子里,p+1偏移的是一个int的大小,而q+1偏移的是一个int[4]的大小,也就是4个int那么大。

一般情况下数组的指针多用于函数参数指向二维数组,例如

int sum(int (*a)[10]) {
......
}
int main() {
......
int a[10][10];
sum(a);
......
}

数组传递给函数后会退化为指针:

int a[10]; 保存int类型元素的数组,退化为指向int类型的指针

int b[20][10]; 二维数组其实是数组的数组,也就是保存类型为数组的数组,退化为指向数组类型(int[10]类型)的指针,也就是int (*p)[10];

温馨提示:答案为网友推荐,仅供参考
第1个回答  2013-09-19
区分一下int* p[4]和int (*p)[4]
前者代表p是一个数组,里面装的是int*型的指针;
后者相反,p是一个指针,指向一个int[4]的数组。

所以归根结底,这里p是一个指针。那么,我的理解是,*p打印出来是这个int[4]的首地址,而不是这个数组里面的值。而且,p+1的话,地址相当于以int[4]为单位增加,而不是以int为单位增加。

而,int *p=a这个例子,*p打印出来是a[0]里的值,故而两者应当是不同的。

如果是int* p[4], p=a的话,就会出现数组p的首地址变成数组a的首地址。而p[0] 就会变成a[0]的值,但是此时p[0]的类型为int* ,而a[0]为int,这时如果dereference这个p[0]的话,就会出现segementation fault.

归根结底,无论int* p[4]还是int (*p)[4],都相当于二级指针,与a[4]这种一级指针肯定是不同的。

至于初始化,比较伤
&p是p自己的地址,已经不用管了,p是个地址,需要你来给出,*p也是地址,这个也需要你给出,**p才是数值。
指针这种东西,其实就没什么所谓的初始化,一开始都设为NULL,只有当确定有相对应的内存空间之后,才能去取地址使用。

比如有a[2][4],这个时候,p = &a[0][0]或许是可以的,但是p+2的时候,就不能保证是取到是什么数值了。

总之,就记成,指向int[4]的一个指针就好了,而int[4]是个数组类型(自己定义的),凡是数组,其实都是一串地址。
第2个回答  2013-09-19
设有:int a[4]={1,2,3,4};
int *p=a; // 这种形式是定义指针变量p后直接对其初始化让它指向数组a的首地址(即&a[0])

int (*p)[4]; // p是指向由4个整型元素的数组(即p指向一维数组)
p=&a;和p=a;都是对int (*p)[4];这种形式做初始化赋值工作。
第3个回答  推荐于2016-12-01
第一个是指针,指向的是有4个元素的数组,是一个数组指针(不是指针数组)。
int a[4];int *p=a,把a的首地址赋值给p,
p=a;
int main ()
{
int a[4]={0};
int (*pi)[4];
pi=a;
return 0;
}
第4个回答  2013-09-19
第一个是数组指针,数组名a实际上不等同于指针,但是你可以传递给p地址
初始化可以用memset()函数。
相似回答