数组指针与指针数组

一:前言

数组指针和指针数组是两个很容易让初学者感到模糊的概念,同时也是重点,所以希望读者能耐心阅读,仔细理解。

那么,什么是数组指针,什么又是指针数组呢?

int(*p)[2];//数组指针
int* p[2];//指针数组


在继续分析两者的区别前,需要读者了解3个问题:

1.二维数组是特殊的一维数组。

int a[2][2];
for (int i = 0; i < 2; i++)
    for (int j = 0; j < 2; j++)
	cout << &a[i][j] << endl;
我们发现输出的地址是连续的,很简单,不作解释。

2.数组地址。

int a[2];
int aa[2][2];
监视下类型图为:


a是一维数组的数组名,值是一个地址,大小等于首元素地址,注意a不是变量,a[ 0 ]和a[ 1 ]才是变量,也就是不可以有a++之类的操作,类型是int[ 2 ](很多人认为a是指针类型int*,严格来说,不对,关于这点在下面会讲)。

&a是一维数组的数组地址,值是连续两个int元素的地址,只不过大小也等于首元素大小,类型是int[ 2 ]*。

aa是二维数组的数组名,值是一个地址,大小等于首元素地址,同样aa不是变量,类型是int[ 2 ][ 2 ]。

&aa是二维数组的数组地址,也就是连续四个int元素的地址,大小也是等于首元素地址,类型是int[ 2 ][ 2 ]*。

aa[ 0 ]是二维数组的第一行小数组的数组名,这里可以看做是a,类型和a是一样的。

&aa[ 0 ]是二维数组的第一行小数组的数组地址,也就是aa[ 0 ][ 0 ]和aa[ 0 ][ 1 ]的地址。

3.数组类型可以转化为指针类型。

int a[2];
int *p;
p = a;

int aa[2][2];
int(*pp)[2];
pp = aa;
在VS调试下,监视变量图为:


我们知道,运算符=成立的前提是左右类型相同或者右类型可以转化为左类型。

在上图,a和p的类型是不同的,但是a=p却是成立的,同样的,aa=pp也是成立的。这是因为array type 可以转化为pointer type。即int[ ]转化为int*,int[ ][ ]转化为int[ ]*。如何使一个数组名退化成指针呢?只需对其进行数值计算即可,例如,a+0,aa+0。(其中a[0]等价*(a+0),aa[0]等价*(aa+0))

这也就解释了上面我所说的,a不是int*类型,只是可以转化而已,可以转化并不代表a就是int*类型的。打个比方,int和short可以转化,但是int不是short,只是可以转化而已。a的类型就是int[ 2 ],描述为a是一个数组,由两个int组成。


二:数组指针

int a[2];
int aa[2][2];
int(*p)[2];

p = a;//error
p = &a;//right

p = aa;//right
p = aa[0];//error
p= &aa[0];//right

int bb[2][3];
p = bb;//error

p是一个数组指针,类型是int[2] * ,含义是指向一个连续两个int元素的地址,也就是数组地址,数组地址在上面讲过,就是连续元素的地址,值为第一个元素地址。
p = a是错误的,因为a的类型是int[2],p的类型是int[2] * 。
p = &a是正确的,因为&a是数组地址。p = aa是正确的,因为array type 可以转换为pointer type。
p = aa[0]是错误的,因为aa[0]的类型是int[2],和a的类型一样。
p = &aa[0]是正确的,这个和p = &a是一样的道理。
p = bb是错误的,因为p是指向连续两个元素的地址,而bb是3个,无法转化。

关于数组指针的应用,应该就是传递参数的时候了,看下面的代码: 

int a[2][3] = { 1,2,3,4,5,6 };

void func(int(*p)[3])
{
	cout << p[0][1] << endl;
}

func(a);//2

三:指针数组

指针数组就是存放指针变量的数组。这个数组里的每个元素存储的都是地址。 这个很好理解。

int * p[2];//指针数组
int a[2] = { 0 };
p[0] = &a[0];
p[1] = &a[1];

关于指针数组的应用,举一个来自《the c programming language》的一个例子,对字符串进行排序,看了下面这个例子,相信你就体会到了指针数组的好处了。




四:总结

数组指针:指向数组的地址的指针变量,记住是数组地址;(写法例如int (*p)[2])

指针数组:一个单纯的数组,数组里存储的是指针变量。(写法例如int * p[2])

数组指针,数组+指针=指向数组的指针,实质是指针;

指针数组,指针+数组=存储指针的数组,实质是数组。

关于对这两个概念的理解,参考  http://www.cnblogs.com/JackyTecblog/archive/2012/08/27/2658447.html




  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值