数组指针中有三条规律(适用于任何维数数组):(来源于李戈老师的计算概率)
数组名相当于指向数组第一个元素的指针;
&E相当于把E的管辖范围上升了一个级别;
*E相当于把E的管辖范围下降了一个级别;
我再增加一条,[]也是把管辖区域下降一个级别。
这三条规律真的很好用!
如果a是一维数组的名字,a指向数组首元素a[0],a+1指向第二个元素,a等于&a[0];
如果a是二维数组的名字,a指向数组首元素a[0],即第一行,a+1指向第二个元素,即第二行,a等于&a[0]。
例1:
#include <iostream>
using namespace std;
int main()
{
int a[3]={0,1,2};
int (*p)[3];
int (**pp)[3];
p=&a;
pp=&p;
//这边如果p=a,编译出错,不能将int[3]赋值给int(*)[3]类型
//a是指针,指向a[0],是a[0]的地址
//p是指针,指向有3个元素的int数组,作用域比a高一级,所以应该把a上升一级再赋值给p
//a上升一级是&a
cout<<a<<endl;//0x61fe90
cout<<a+1<<endl;//0x61fe94,a的作用域是a[0],占4个字节,所以a+1和a的字节之差是4
cout<<p<<endl;//0x61fe90
cout<<p+1<<endl;//0x61fe9c,a[0],a[1],a[2]共占12个字节
//指针p+1和p的字节之差,取决于指向的内容占几个字节,即指针的作用域
//p的作用域是整个数组,占12个字节,所以p+1和p的字节之差是12
cout<<pp<<endl;//0x61fe8c
cout<<pp+1<<endl;//0x61fe90
//pp指向的内容是个指针变量,占4个字节,所以pp+1比pp高4个字节
}
例2:来自http://www.nowcoder.com/profile/826954/myFollowings/detail/1103956
#include<iosteam.h>
void main(){
int n[][3] = {10,20,30,40,50,60};
int (*p)[3];
p=n;
count<<p[0][0]<<","<<*(p[0]+1)<<(*p)[2]<<endl;
}
输出10,20,30
定义p指向一个数组,该数组有3个元素。
n是数组n[2][3]首元素的地址,即n的作用域是第一行。
p=n,则p的作用域也是第一行。
p[0]作用域是第一行第一个元素,p[0][0]就是第一行第一个元素的值,即10。
p[0]作用域是第一行第一个元素,p[0]+1作用域是第一行第二个元素,*(p[0]+1)就是第一行第二个元素的值,即20。
*p,把p的管辖区域下降了一级,因为p的作用域是第一行,那么*p的作用域是第一行第一个元素,(*p)[0]就是第一行第一个元素的值,(*p)[2]就是第一行第三个元素的值,即30。