在C语言中,指针和数组是两个非常重要的概念,它们之间有着紧密的联系。首先,让我们回顾一下指针和数组的基本概念。
**指针** 是C语言中的一个关键特性,它存储的是变量的地址。指针的声明通常采用类型标识符后面跟一个星号(*),例如 `int *p` 表示`p`是一个指向整型变量的指针。赋值时,可以将变量的地址赋给指针,或者将同类型的指针赋给另一个指针。指针可以用来间接访问和修改其所指向的变量的值。
**数组** 是一组相同类型的数据的集合,它们在内存中连续存储。数组的声明形式如 `int a[3]`,表示`a`是一个包含3个整数的数组。数组名`a`在许多情况下可以被看作是一个指向数组首元素的指针常量,因此可以通过 `a` 来访问数组中的元素,如 `a[0]` 表示数组的第一个元素。
**指针和数组的关系**:
1. 数组名在很多场合下可被视为指向数组第一个元素的指针。这意味着,对于数组`a`,`a`和`&a[0]`实际上是等价的,都表示数组的起始地址。
2. 指针可以用来遍历数组。例如,如果`p`是一个指向整型的指针,`p = a` 将使`p`指向数组`a`的第一个元素,之后可以通过 `p++` 来访问数组的下一个元素。
**指针数组** 是数组的一个特殊形式,其中的每个元素都是一个指针。例如,`int *p[3]` 定义了一个包含三个整型指针的数组。数组中的每个元素都可以独立地指向不同的变量或内存位置。在给定的代码示例中,`p[0]`, `p[1]`, `p[2]` 分别可以指向不同的整数。
**指向指针的指针**,也就是二级指针,可以用来存储指针的地址。这使得我们可以动态地改变指针所指向的地址。在`例14.6`中,`char **pp` 类型的变量可以用来存储指向字符数组的指针,通过这种方式,我们可以改变指针指向的字符串,从而实现反序输出。
**例14.5** 展示了如何使用指针数组来输出多个字符串。在这里,`ps` 是一个字符指针数组,包含了四个字符串的首地址。通过遍历数组并调用 `puts()` 函数,我们可以依次打印出这些字符串。
**例14.6** 则展示了如何使用指向指针的指针来反向输出字符串数组。这里,`name` 是一个字符串数组,`int i` 从数组末尾开始遍历,每次迭代通过 `printf()` 输出当前指针`name[i]`所指向的字符串。
总结起来,理解和掌握C语言中的指针和数组,特别是它们之间的关系,对于编写高效的C程序至关重要。指针数组和指向指针的指针提供了更灵活的方式来处理数据,它们在函数参数传递、动态内存管理、数据结构如链表和树的实现等方面都有广泛的应用。