Pointers on C——8 Arrays.21

来源:互联网 发布:starry nigh观星软件 编辑:程序博客网 时间:2024/06/02 05:29

8.3 Arrays of Pointers

指针数组


Aside from its type, a pointer variable is like any other variable. Just as you can create arrays of integers, you can also declare arrays of pointers. Here is an example:

除了类型之外,指针变量和其他变量恨相似。正如你可以创建整型数组一样,你也可以声明指针数组。这里有一个例子:


int *api[10];


To figure out this complex declaration, pretend that it is an expression and evaluate it.

为了弄清这个复杂的声明,我们假定它是一个表达式,并对它进行求值。


Subscripts have a higher precedence than indirection, so in this expression, the subscript would be applied first. Therefore, api is an array of something (and oh, by the way, there are ten of them). After getting one element of the array, the indirection is applied next. There arenʹt any more operators, so the result of this expression is an integer.

下标引用的优先级高于间接访问,所以在这个表达式中,首先执行下标引用。因此, api 是某种类型的数组(噢!顺便说一下,它包含的元素个数为10) 。在取得一个数组元素之后,随即执行的是间接访问操作。这个表达式不再有其他操作符,所以它的结果是一个整型值。


So what is api? We got an integer by applying indirection to an element of an array, so api must be an array of pointers to integers.

那么api 到底是什么东西?对数组的某个元素执行间接访问操作后,我们得到一个整型值,所以api 肯定是个数组,它的元素类型是指向整型的指针。


Where would you ever use an array of pointers? Here is one example:

什么地方你会使用指针数组呢?这里有一个例子:


char const *keyword[] = {

"do",

"for",

"if",

"register",

"return",

"switch",

"while"

};

#define N_KEYWORD ( sizeof( keyword ) / sizeof( keyword[0] ) )


/*

** Determine whether the argument matches any of the words in

** a list of keywords, and return the index to the one it matches.

** If no match is found, return the value -1.

*/

#include <string.h>

int

lookup_keyword( char const * const desired_word,

char const *keyword_table[], int const size )

{

char const **kwp;

/*

** For each word in the table ...

*/

for( kwp = keyword_table; kwp < keyword_table + size; kwp++ )

/*

** If this word matches the one we're looking for,

** return its position in the table.

*/

if( strcmp( desired_word, *kwp ) == 0 )

return kwp - keyword_table;

/*

** Not found.

*/

return -1;

}

Program 8.2 Keyword lookup


Notice the use of sizeof to automatically count the number of elements in the array. sizeof( keyword ) gives the number of bytes in the entire array, and sizeof(keyword[0] ) is the number of bytes in one element. The resulting division gives the number of elements.

注意sizeof 的用途,它用于对数组中的元素进行自动计数。sizeof(keyword) 的结果是整个数组所占用的字节数,而sizeof(keyword[0])的结果则是数组每个元素所占用的字节数。这两个值相除,结果就是数组元素的个数。


This array would be useful in a program that counts keywords in C source files.Each word from the input would be compared to the strings in the list, and all matches would be counted. Program 8.2 goes through the list of keywords looking for a match with the argument string. When a match is found, the offset into the list is returned.The calling program must know that zero means do, one means for, and so forth, and it also has to know that ‐1 is returned for a nonkeyword. This information would probably be obtained via symbols defined in an included file.

这个数组可以用于一个计算C 源文件中关键字个数的程序中。输入的每个单词将与列表中的字符串进行比较,所有的匹配都将被计数。程序8.2遍历整个关键字列表,查找是否存在与参数字符串相同的匹配。当它找到一个匹配时,函数就返回这个匹配在列表中的偏移量。调用程序必须知道0代表do , 1 代表for 等,此外它还必须知道返回值如果是-1 表示没有关键字匹配。这个信息很可能是通过头文件所定义的符号获得的。


We could also store the keywords in a matrix, like this:

我们也可以把关键字存储在一个矩阵中,如下所示:


char const keyword[][9] = {

"do",

"for",

"if",

"register",

"return",

"switch",

"while"

};


What is the difference between this declaration and the preceding one? The second declaration creates a matrix whose rows are each long enough to hold the longest keyword (plus its terminating NUL byte). The matrix looks like this:

这个声明和前面那个声明的区别在什么地方呢?第2 个声明创建了一个矩阵,它每一行的长度刚好可以容纳最长的关键字(包括作为终止符的NUL 字节)。这个矩阵的样子如下所示:



The first declaration creates an array of pointers, which are initialized to point to various string literals, as illustrated below.

第1 个声明创建了一个指针数组,每个指针元素都初始化为指向各个不同的字符串常量,如下所示:

Notice the difference in the amount of memory used. The matrix looks inefficient because every row must be long enough to store the longest keyword. But it does not need any pointers. On the other hand, the array of pointers takes space, but each of the string literals is only as long as it needs to be.

注意这两种方法在占用内存空间方面的区别。矩阵看上去效率低一些,因为它的每一行的长度都被固定为刚好能容纳最长的关键字。但是,它不需要任何指针。另一方面,指针数组本身也要占用空间,但是每个字符串常量占据的内存空间只是它本身的长度。


What would we need to change in Program 8.2 to use the matrix instead of the array of pointers? It may surprise you to learn that only the declarations for the table parameter and the local variable would be different. The code wouldnʹt change at all.Because the value of an array name is a pointer, the body of the function will work with either a pointer variable or an array name.

如果我们需要对程序8.2 进行修改,改用矩阵代替指针数组,我们应该怎么做呢?答案可能会令你吃惊,我们只需要对列表形参和局部变量的声明进行修改就可以了,具体的代码无需变动。由于数组名的值是一个指针,所以无论传递给函数的是指针还是数组名,函数都能运行。


Which is better? It depends on the specific words you wish to store. If they are all nearly the same length, the matrix is more compact because there is no space needed for pointers. However, if the words are different lengths, or worse yet, most of them are short but a few are quite long, then the array of pointers may be more compact. It depends on whether the space consumed by the pointers is less than the space wasted by using fixed‐length rows for each word.

哪个方案更好一些呢?这取决于你希望存储的具体字符串。如果它们的长度都差不多,那么矩阵形式更紧凑一些,因为它无需使用指针。但是,如果各个字符串的长度千差万别,或者更糟,绝大多数字符串都很短,但少数几个却很长,那么指针数组形式就更紧凑一些。它取决于指针所占用的空间是否小于每个字符串都存储于固定长度的行所浪费的空间。


In practice, these differences are so slight as to be unimportant for all but the largest of tables. More often than not, the array of pointers is used, but with a twist:

实际上,除了非常巨大的表,这些差别非常之小,所以根本不重要。人们时常选择指针数组方案,但略微对其作些改变:


char const *keyword[] = {

"do",

"for",

"if",

"register",

"return",

"switch",

"while",

NULL

};


Here we add a NULL pointer to the end of the table. The NULL lets functions that search the table detect the end of the table without knowing its size in advance, like this:

这里,我们在表的末尾增加了一个NULL 指针。这个NULL 指针使函数在搜索这个表时能够检测到表的结束,而无需预先知道表的长度,如下所示:


for( kwp = keyword_table; *kwp != NULL; kwp++ )


上一章 Pointers on C——8 Arrays.20