指针可以用不同的间接引用层级。把变量声明为指针的指针并不少见,有时候称它们为双重指针。一个很好的例子就是用传统的argv
和argc
参数来给main
函数传递程序参数,第5章将详细讨论。
下例使用了三个数组。第一个数组是用来存储书名列表的字符串数组:
char *titles[] = {"A Tale of Two Cities",
"Wuthering Heights","Don Quixote",
"Odyssey","Moby-Dick","Hamlet",
"Gulliver's Travels"};
还有两个数组分别用来维护一个“畅销书”列表和一个英文书列表。这两个数组保存的是titles
数组里书名的地址,而不是书名的副本。两个数组都声明为字符指针的指针。数组元素会保存titles
数组中元素的地址,这样可以避免对每个书名重复分配内存,确保每个书名的位置唯一。如果需要修改书名,只改一个地方就可以了。
另外两个数组声明如下。每个数组元素包含一个指向char
指针的指针。
char **bestBooks[3];
char **englishBooks[4];
接下来初始化这两个数组,然后打印其中一个元素,如下所示。在赋值语句中,右边的值是通过先做下标索引再取地址的操作得到的。比如说第二个语句把titles
数组中第4个元素的地址赋给bestBooks
的第2个元素:
bestBooks[0] = &titles[0];
bestBooks[1] = &titles[3];
bestBooks[2] = &titles[5];
englishBooks[0] = &titles[0];
englishBooks[1] = &titles[1];
englishBooks[2] = &titles[5];
englishBooks[3] = &titles[6];
printf("%s\n",*englishBooks[1]); // Wuthering Heights
本例的内存分配如图1-10所示。
用多层间接引用可以为代码的编写和使用提供更多的灵活性,否则有些操作实现起来会困难一些。在本例中,如果书名的地址变了,那么只需要修改titles
数组即可,不需要修改其他两个数组。
间接引用没有层数限制,当然,使用的层数过多会让人迷惑,很难维护。