上次梳理了二维数组的原理,那么,二维数组与哪种类型的指针相似呢?
就是数组指针。
数组指针为一个指向数组整体的指针,看似是只有它孤零零的一个指针,其实不然,除了这个指向数组整体的指针之外,还有数组内嵌的指针存在,同样有点“我主外,你主内"的感觉。
对“我”的运算呢是数组整体地址偏移,对“你”的运算呢是数组内元素的地址偏移,这和二维数组的原理是一样的。
不过不能随意定义数组指针,数组指针所指数组的单位长度是有要求的。
值得注意的是,若想要用数组指针来指向二维数组时,必须设置数组指针所指数组的单位长度与二维数组的内层一维数组的单位长度相同才可以。
为指针赋值时,注意一定要给与指针地址!只能是地址!
例如:定义一级指针 并 赋值
一级指针需要指向(存储)数据的地址。
int num = 520; //定义整形数据元素num 并赋值为520
int *p ; //定义一级指针p
p = # //将数据元素num的地址赋值给一级指针p
int *p; //定义数据类型为整形的一级指针p
p = &a[1]; //将一维数组a的首地址赋值给指针p
二级指针需要指向(存储)一级指针的地址。
char **q; //定义二级指针q
p = &p; //将一级指针p的地址赋值给二级指针q
我们再来定义一个存放字符串地址的指针数组:
char *tBooks[] = { //定义一个存储了字符串地址的指针数组
"《数据结构》",
"《计算机组成原理》",
"《C语言程序设计》",
"《哆啦A梦》"
};
这个指针数组较为特殊,他的每个指针元素保存的地址是字符串的的地址,而字符串的地址就是一个字符串的内嵌指针,所以他保存的地址不是数据元素的地址,而是指针的地址,即它(指针元素)指向指针,是一个二级指针,而指向它的数组的内嵌指针是一个三级指针。
如果我们要定义一个二级指针 target;
我们应该把谁的值赋给**target呢?
char **target; //定义二级指针target
target = &tBooks[3]; //将指针数组中存放的字符串地址的二级指针元素的地址赋值给二级指针target
先记住:二级指针指向(存取)一级指针的地址!始终存取的是下一级指针的地址!!
以下是对于赋值操作的解释:
上面虽然定义的是指针数组,但是数组内指针指向(存储)的是字符串地址,字符串地址本身就是内嵌的字符指针,所以,指针数组里面的指针实际上是二级指针,即取得数组元素Books[3](本质上是数组内嵌指针的运算)后得到的是什么呢?得到的是地址!是字符串的地址,字符串地址就是一个字符串指针,是直接指向数据元素的指针,是一级指针,存取这个字符串指针的地址的是数组的指针元素,所以我们需要它的(二级指针)的地址,我们使用取址符&对其取址。
记住&tBooks[0]与&tBooks的区别,对此题目来讲,&tBooks取得数组内嵌指针的地址,数内嵌指针是三级指针,&tBooks[0]取得数组第1个指针元素的地址,第一个指针元素是二级指针,他们虽然取得数值相同,代表意义不同。