浅析数组与指针的联系与区别2

来源:互联网 发布:软件测试入门书籍 编辑:程序博客网 时间:2024/05/19 12:37

有时候遇到声明几个相同类型的指针的情况,我们能否像声明相同变量那样声明一个数组呢?答案是肯定的。我们会很自然的写成,比如int *p[3],但是偶然我们发现别人的程序里有int (*p)[3]的出现,这两者是否相同呢?答案是否定的。下面将通过一个例子说明这两者的区别和联系,为了方便对照下面把解释写在代码的注释中。

#include <iostream>using namespace std;int main(){int arr[3] = {0,1,2};/*[]的优先级比*的高,所以先p1[3],后*。这样就不难理解为什么是3个指针变量*/int *p1[3];//声明3个(注意是3个)int类型的指针/*加()后,先运算(*p2),可人为的理解为先声明一个指针变量p2,然后指向一个有三个元素的数组*/int (*p2)[3];//声明1个(注意是1个!)int类型的指针且这个指针指向一个有且必须有3个元素的数组int *p3;//int (*p2)[4];//当执行p2=&arr时会报错,因为arr为三个元素,p2指向的是一个四个元素的地址//p1 =arr;//会报错。p1为指针数组第一个元素的地址,是指针的指针。arr为数组第一个元素的地址,是一个指针,不能赋值/*想要p1分别指向arr三个元素中的一个,可采用如下方法,注意p1中的每个元素都是一个指针*/p1[0] = &arr[0];p1[1] = &arr[1];*(p1+2) = &(*(arr+2));//与p1[2] = &arr[2]等效,上篇已经说过cout<<&arr[0]<<": "<<arr[0]<<endl;cout<<p1[0]<<": "<<*p1[0]<<endl;cout<<&arr[1]<<": "<<arr[1]<<endl;cout<<p1[1]<<": "<<*p1[1]<<endl;cout<<&arr[2]<<": "<<arr[2]<<endl;cout<<p1[2]<<": "<<*p1[2]<<endl;cout<<"============================"<<endl;p2 = &arr;//p2是一个指向具有三个元素的数组的指针,也就是说p2是arr指针的指针//对p2取值是一个指针,*p2+i为arr中第i个元素的指针cout<<*p2<<": "<<**p2<<endl;//cout<<*p2+0<<": "<<*(*p2+0)<<endl;cout<<*p2+1<<": "<<*(*p2+1)<<endl;cout<<*p2+2<<": "<<*(*p2+2)<<endl;cout<<"============================"<<endl;p3 = arr;//将arr首地址赋给p3/******************************************************************下面若干行代码说明数组首地址和数组地址之间的区别,虽然它们的值相同,但是占用的空间不同,数组首地址占用一个元素的空间,数组地址占用的却是整个数组的空间,这点对比下面+1代码可以看出******************************************************************/cout<<arr<<endl;//数组首地址cout<<p1[0]<<endl;//数组首地址cout<<*p2<<endl;//数组首地址cout<<p3<<endl;//数组首地址cout<<"============================"<<endl;cout<<arr+1<<endl;//数组首地址+1cout<<p1[0]+1<<endl;//数组首地址+1cout<<*p2+1<<endl;//数组首地址+1cout<<p3+1<<endl;//数组首地址+1cout<<"============================"<<endl;cout<<&arr<<endl;//取数组的地址,数组用首地址表示数组的地址cout<<p2<<endl;//取数组的地址cout<<"============================"<<endl;cout<<&arr+1<<endl;//数组的地址+1cout<<p2+1<<endl;//数组的地址+1cout<<"============================"<<endl;/*下面两行代码为了说明一个恒等式p2[i][j]=*((*p2+i)+j)*/cout<<*p2+2<<": "<<*(*p2+2)<<endl;cout<<&p2[0][2]<<": "<<p2[0][2]<<endl;return 0;}

总结:
(1)数组用首元素的地址作为数组的地址,虽然值相同,但是占用的空间大小不同。数组地址表示的是整个数组的空间大小。
(2)*p[3]是声明了包含三个指针元素的数组;(*p)[3]声明了一个指针,指向了一个具有三个元素(注意是三个)的数组。
(3)恒等式p[i][j] = *((*p+i)+j)

0 0