6.7.5 二级指针与指针数组
前面介绍过指针数组都是指针类型的元素,而数组名又代表其首元素的内存地址,因此,指针数组的数组名其实就是一个二级指针。例如:
const char *pstrArr[3] = {"apple", "orange", "pear"};
定义了一个长度为 3 的 char*类型的指针数组 pstrArr,并将 3 个字符串常量的首地址作为数组元素的初始值。
我们可以将 pstrArr 看成一个二级指针,可通过二级指针的解引用来访问所指向的对象,例如:
printf("%s\n", *pstrArr);
对 pstrArr 进行解引用后,即访问到了第一个字符串“apple”的首地址,即字符 a 的内存地址,因此,可以使用“%s”的格式,以字符串形式打印输出。
编译运行程序,结果如下:
apple
如果我们对 pstrArr 进行两次解引用,则会访问到字符串“apple”的首字符 a。例如:
printf("%c\n", **pstrArr);
由于两次解引用后访问到的是字符,因此,在 printf 函数中,不应该再以“%s”的格式来打印输出了,应改为“%c”,即以字符的格式来打印输出。
编译运行程序,结果如下:
a
我们也可以通过指针的运算,用一个 for 循环语句打印出所有的字符串。例如:
for(int i = 0; i < 3; ++i) printf("%s\n", *(pstrArr + i));
for 循环语句被执行时,变量 i 的值从 0 自增至 2,分别会使表达式“pstrArr + i”指向指针数组中第 1~3 个元素的指针,通过解引用即可访问到指针数组的各元素,数组元素中保存了字符串常量的首地址,因此,可以通过该值将字符串打印输出到控制台窗口,如图 6.16 所示。
图 6.16 访问指针数组中的字符串
编译运行程序,结果如下:
apple orange pear
由于数组名是一个指针常量,它的值不允许被修改,因此,上例中是使用指针运算的方式来访问数组各元素。也可以定义一个二级指针,并通过指针移动的方式来访问数组各元素。例如:
const char **ppArr = pstrArr;
定义一个 char**类型的二级指针 ppArr,并将指针数组名作为初始值初始化给 ppArr。注意最前面有一个 const 修饰符,由于指针数组在定义时使用了 const 修饰符,因此,在定义二级指针时也需要加上,不然编译器就会给出警告信息。
下面通过指针移动的方式来访问指针数组元素,并打印出各字符串,例如:
for(int i = 0; i < 3; ++i) printf("%s\n", *ppArr++);
这里将指针移动与指针的解引用合并在一起,表达式为“*ppArr++”,由于解引用运算符和后缀的自增运算符都是一目运算符,在优先级相同的情况下,结合性为从右至左,因此,后缀的自增运算符首先被执行,通过自增运算后 ppArr 已经变为指向数组下一个元素的指针,但是在解引用时依然是 ppArr 自增之前的值,这是后缀自增自减运算符的特性。因此,通过指针的移动和指针的解引用之后,同样可以访问指针数组各元素。
编译运行程序,结果如下:
apple orange pear
可见,与之前的结果是一致的。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论