请先看下面的代码:
- #include <stdio.h>
- #include <stdlib.h>
- int main(){
- char *lines[5] = {
- "COSC1283/1284",
- "Programming",
- "Techniques",
- "is",
- "great fun"
- };
- char *str1 = lines[1];
- char *str2 = *(lines + 3);
- char c1 = *(*(lines + 4) + 6);
- char c2 = (*lines + 5)[5];
- char c3 = *lines[0] + 2;
- printf("str1 = %s\n", str1);
- printf("str2 = %s\n", str2);
- printf(" c1 = %c\n", c1);
- printf(" c2 = %c\n", c2);
- printf(" c3 = %c\n", c3);
- return EXIT_SUCCESS;
- }
运行结果:
看下面的分析之前,请先了解指针数组和指向指针的指针的基本概念,如果你不了解,先看下面的文章:
为了更加直观,把上面的数组改成下面的形式:
- #include <stdio.h>
- #include <stdlib.h>
- int main(){
- char *string0 = "COSC1283/1284";
- char *string1 = "Programming";
- char *string2 = "Techniques";
- char *string3 = "is";
- char *string4 = "great fun";
-
- char *lines[5];
- lines[0] = string0;
- lines[1] = string1;
- lines[2] = string2;
- lines[3] = string3;
- lines[4] = string4;
- char *str1 = lines[1];
- char *str2 = *(lines + 3);
- char c1 = *(*(lines + 4) + 6);
- char c2 = (*lines + 5)[5];
- char c3 = *lines[0] + 2;
- printf("str1 = %s\n", str1);
- printf("str2 = %s\n", str2);
- printf(" c1 = %c\n", c1);
- printf(" c2 = %c\n", c2);
- printf(" c3 = %c\n", c3);
- return EXIT_SUCCESS;
- }
这样,或许会清晰很多,char *lines[5]; 定义了一个指针数组,数组的每一个元素都是指向char类型的指针。最后5行,为数组的每一个元素赋值,都是直接赋给指针。
而lines,是一个指向指针的指针,它的类型为 char **,所以 *lines 是一个指向字符的指针,**lines是一个具体的字符。这一点很重要,一定要明白。
指针是可以进行运算的,lines 为lines[5]数组的首地址,即第0个元素的地址;lines+0, lines+1, lines+2 ... 分别是第0, 1, 2 ...个元素的首地址,*(lines+0)或lines[0], *(lines+1)或lines[1], *(lines+2)或lines[2] ... 分别是字符串 str0, str1, str2 ... 的首地址。所以:
*lines == *(lines+0) == lines[0] == str0
*(lines+1) == lines[1] == str1
*(lines+2) == lines[2] == str2
...
注意:lines为指向指针的指针,所以*(lines+n)为指针,**(lines+n)才为具体的字符。
上面的题目中:
如果你觉得上面的代码难以理解,可以先看 C语言数组灵活多变的访问形式,容易很多。