第1个回答 2013-06-26
你必须明白,任何指针的值是一个地址这很简单,但指针还承载着很多其他信息,不然就没有int *、char *、double *……之分了。若有int a[4]={1,2,3,4},*p,(*q)[4];则p=a和q=&a虽然都使p和q指向了同一个地址,但二者承载的其他信息不同:前者是使p指向a[0],并使p+1指向a[1]……依次类推,p+3指向a[3];而后者是使q指向数组a的首地址,当然其值与a[0]的地址相同,但承载的其他信息是q+1指向下一行,因为这里没有下一行,它就指向了a[4]的地址(当然这里没有定义a[4],实际是跳出数组了)。你可以这样试试——
void main(void){
int a[4]={1,2,3,4},*p,(*q)[4];
p=a;
q=&a;
printf("p=%p p+1=%p\nq=%p q+1=%p\n",p,p+1,q,q+1);
}
关于(*p)[3]表示7的问题:你已使p=&a,那么*p就等于a(*p是取p中的内容,请不要与声明时的*p相混淆,尽管它们写法一样),再取a的第3个元素是7自然正确。就是说printf("%d\n",(*p)[3]);中的(*p)[3]被编译器解释成为“取指针p的内容,再取以这个内容为首地址的数组的第3个元素”,结果与a[3]等效。
第2个回答 2013-06-22
问题1:你这种理解是对的;比如数组int b[2][2]={1,2,3,4};对于int *p=b[0];那么p指向的数据就是{1,2};同理,*p=b[1];p指向{3,4};
问题2:在32位系统中,确实a 和 &a传递的值都是数组的首地址(4BYTES);但是有个传递给什么类型数据的问题,如果是传递给简单的指针如int *p;那么这两种形式没有差别;汇编代码完全是一样的;但是你这里是传递给指针数组int (*p)[4];就有类型匹配的问题在里面;这时的p表示的是指针数组的首地址,而不是一个简单的变量你要明白;
问题3:依然是行指;(*p)[3]表示的是数组的第4个元素要注意;
问题4:二维以上数组的数组名是没有任何意义的;比如二维;a[2][4];有意义的首地址是a[0]和a[1];
程序2:明确地告诉你:不能!
注意score是二维数组;二维数组的数组名称不能像一维那样代表首地址;如果非得取首地址;那么是如下的取法:(加*)
int a[2][2]={1,2,3,4};
00401028 C7 45 F0 01 00 00 00 mov dword ptr [ebp-10h],1
0040102F C7 45 F4 02 00 00 00 mov dword ptr [ebp-0Ch],2
00401036 C7 45 F8 03 00 00 00 mov dword ptr [ebp-8],3
0040103D C7 45 FC 04 00 00 00 mov dword ptr [ebp-4],4
18: int *p=*a;
00401044 8D 45 F0 lea eax,[ebp-10h]//第一个数据的地址传递给eax
00401047 89 45 EC mov dword ptr [ebp-14h],eax//eax传递给参数*p
第3个回答 2013-06-22
先跟你说最后的问题吧。其他的你百度hi我,或者其他方式解答。
a[n],*[a+n]等价能理解吧?所以a是一个指针,代表数组的首地址,指向一个数组类型(如int float)的变量。
那么b[N][M],可以试着这样理解:把b[N]看作a,那么b[n][m]与*(b[n]+m)等价。由于a是一个指针,
所以b[N]代表的,是一个指针数组。b所代表的,是指向一个指针数组的指针,并且是b[N]的首地址。
average第一个参数需要的是一个float指针,所以赋值*score 即 score[N]指针数组的首个指针,代表&score[0][0]。
可以改写成&score[0][0],但不能写成&score。
第4个回答 2013-06-22
根据数组下标记最好,比如说你定义一个a[5]={2,3,5,6,7},那么a[0]=2,a[1]=3,a[2]=5......
在一个变量前加一个*表示是一个指针变量,他是指向变量地址的指针的,所以要加一个&表示取地址;
这个还是那句话,你只管下标,
int (*p)[2][4];//也要改二维的
p=&a;
printf("%d\n",(*p)[0][3]);
&这个表示取地址,而12是个常量 这样就不能用&,而*score表示一个指针变量