关于C语言指针 (*p)[]的问题

#include<stdio.h>
void main()
{
void aver(float *p,int n);
void ch(float (*p)[4],int n); /*就是这个(*p)[4]到底是什么意思啊,书上讲的太简单。为什么第一个函数不用这么写而第二个要。希望各位大神讲的具体点,感激不尽*/
float a[3][4]={{88,76,68,78},{90,44,70,45},{81,85,79,98}};
aver(a,12); /*书上是aver(*a,2) 但是不加*也可以是怎么回事*/
ch(a,2);
}
void aver(float *p,int n)
{
float sum=0,ave;
float *p_1;
p_1=p+n;
for(;p<p_1;p++)
sum=sum+(*p);
ave=sum/n;
printf("平均值是:%5.2f\n",ave);
}
void ch(float (*p)[4],int n)
{
int i;
printf("the score of No.%d are:\n",n);
for(i=0;i<4;i++)
printf("%5.2f\t",*(*(p+n)+i));
}

1、float (*p)[4],首先(*p)表示p是一个指针变量,它指向一个包含四个float型元素的一维数组。float *p则表示p是一个指针,指向一个float型元素,指针所指对象的类型决定了它递增时,在内存中移动的位数。如果说float型元素占四个字节,则float (*p)[4]中p+1,相当于向后移动4*4=16个字节,而float *p中,p+1,相当于向后移动四个字节。
2、aver(a,12); /*书上是aver(*a,2) 但是不加*也可以是怎么回事*/
对于这个问题,原因是a代表二维数组的首地址,*a代表的是a[0]的首地址。由于它们的地址的值是一样,作为参数传给了aver函数,而这个函数的定义中参数是一个float *p,它需要是的地址,所以结果也可以运行出来,这里是巧合,但是它们的类型是不一样的,例如a+1与*a+1二者的地址值是不一样的,所以严格来说aver(a,12)是不正确的。
不知是否明白,不清楚的地方请提出来,可以自己多调试下!追问

、第一问中,假如我定义的是float jj【8】【5】。那么,定义数组指针的时候应该是(*p)【5】吗?
第二问aver必须要a【0】的首地址是为什么?

追答

1、是的,定义数组指针时,(*p)[num]中的num,表示该指针p所指向的数组的长度,以便于告诉内存加一时需移动多少位。为了和数组一致,最好和二维数组的第二维数字相同,这样,p+1,就指向了下一行首元素,如果数字不一致,编译的时候不会报错,但是不便于操作。
2、因为a[0]的首地址相当于一维数组的首地址,加一,移动一列,相当于每一列的地址,它和aver函数的参数要求float *p的类型是一致的,而a表示的是二维数组的首地址,加一移动一行。在这个程序中,能够得到正常结果是因为:float *p_1;p_1=p+n;你在函数中定义了一个指针,它的类型和a[0]的类型是一致的,也就是说你将指向a指针的类型转化为了a[0]。由于都是地址,在C语言中,不会报错。
还有什么不明白的,加Q1281147324,我举几个例子给你,自己上机多调试下。

温馨提示:答案为网友推荐,仅供参考
第1个回答  2011-07-30
这个很简单啊!
举例 int a[10]={0}
func(a)实参将一维数组名穿进去,那么形参肯定是int *b,或者 int a[]这样的(a[0].a[1]....a[9都表示一个整数])
int a[10][10]={0}
fun(a)实参将二维数组名穿进去,那么形参肯定是int b[][10]或者是int (*b)[10]这样的!因为a[0]...a[9]并不是一个整数,他们都代表一个数组,因此指针必须是指向数组的指针
OK????追问

要不就是你答非所问。。要不就是我蒙了。。完全不知道你在讲什么。。(*a)[10]你能再详细点吗。为什么是用第二个【10】,而不是第一个,你既然说他是代表数组

追答

还没懂我的意思啊!。。。。
第一个函数明显是错误的!二维素组做实参传递,形参肯定也要数组指针啊!我说的很清楚啦!

追问

我是照c程序设计 谭浩强的书写的。他写错了吗?

追答

aver(a,12); 这个是错误的!

追问

我汗。。你能把你QQ给我吗。。

追答

61753470

第2个回答  2011-07-30
那是一个指针数组追问

能详细说说吗

追答

我不是这个帐号的主人,不过今天我看到了,以前他回答问题,我就帮他解答一下,因为a是二维数组,所以在这里不管aver(a,12);或aver(*a,2) 都是正确的,这里可能会涉及到指针自动转换问题,这里a和*a都表示指针,而且指向的同一个起始地址。虽然它们两个的实际含义不一样,当然如果涉及到指针移动,情况就不一样了,如a+1 和*a+1它所表示的意思就完全不一样的!
如有疑问!QQ:183477927

相似回答