上一次我们主要说明数组,指针,指针数组,数组指针这几个很基本的概念,
不过有一点上一次我没有提及,那就是我们使用typedef定义指向数组指针
的数组,这个叫法是不是很拗口呀,不过我们看具体的程序就清楚了。
file://----------数组--------------
int a[2]={10,20};
int b[2]={30,40};
file://简单的指向两个元素数组的指针
int (*p2arr)[2]=&a;
file://---------注意这里的变化--------
file://这里我们声明简单的类型P2ARR.可以这样描述
file://P2ARR是一种用户自定义的类型。她的功能描述
file://是用来描述整数数组的,这个数组只能含有两个元素
typedef int (*P2ARR)[2];
P2ARR pp=&b;
pp=p2arr;//类型一致
file://这里我们定义指向指向数组指针的数组
P2ARR ap2a[2]={&a,&b};
file://如果我们采用下面的写法则是错误的,原因看下面分析
file://P2ARR ap2a[2]={a,b};//------错误写法-------
---------还有一点注意----------------
有人可以能会说,定义数阻指针的数组,下面这样的形式
好像也可以做到的。
int (*p2arr)[2][2];
咋一看,好像是的,但是仔细想想。原来上面是定义
一个指针,这个指针是指向二维数组的指针,还是
数组指针,而不是数组指针数组。这一点,应该很容易明白的。
上一次我讲到int []数组声明与int *类型在函数参数等方面转换的例子。
这里有一点补充的,我们实际上现在还是不清楚数组来C++编译器层面的
表示,也就是我们不知道编译器使用什么样的结构形式来表示数组的。所以
上面这些转换只能转换而已,我们不能有更多的假设。
----------我的想象,我的猜想--------
我是这样相像的,C++采用类似JAVA中Array类的形式来管理数组。当然其中
有许多c++语言的特征,比如operator *,operator ->等重载,但是这些类型
转换运算符的使用,只有编译器认为需要的时候才会调用的,因为数组表示本身
就是编译器内部结构的嘛。目前到这里,我们也只能认为在函数参数使用等情况
下才发生int []到int *的转换。
看下面的程序。
#include <iostream>
using namespace std;
void change(int pa[],int index)
{
pa[index]=200;
}
int main()
{
int a[3]={1,2,3};
change(a,0);//这里编译器已经把 int a[3],转换成int *指针传给了函数
file://这个是语言实现细节,请参考《the c++ programming language》
cout<<a[0];
return 0;
}
但是我们上面的标注行
//P2ARR ap2a[2]={a,b};//------错误写法-------
则是应该这样理解:数组就是数组,指针就是指针,虽然编译器需要的时候
会进行一定的转换,但是我们不能认为那些转换是“想当然“的。
上面这一行,编译器就没有为我们进行类型转换的,所以我们要自己动手了。
//P2ARR ap2a[2]={&a,&b};//------正确写法-------
上面这些文字,主要一点就是说明了,有些行为是编译器完成的,而且还有一些
诡秘。但是我们要知道编译器做了那些,那些是要完成自己做的。重要的一点,
就是我们学会如何去简单使用typedef定义类型.