Linux C 编程教程第 21 部分:字符指针、指针数组和指向指针的指针
在此页
- C 中的字符指针、指针数组和指向指针的指针
- 结论
指针的概念确实是C程序设计语言中非常重要的概念之一。到目前为止,我们已经讨论了 C 中指针的几个方面。在此基础上进行扩展,在本教程中,我们将讨论更多的指针概念。
C 中的字符指针、指针数组和指向指针的指针
让我们从具有以下代码行的字符指针开始:
char p[] = "I like HowtoForge"
char *p = "I like HowToForge"
第一行定义了一个数组 p,其大小等于双引号中的字符数。但是下一行定义了一个指向字符串常量的指针 p。
这里的区别在于第一个 p 是一个数组,您可以轻松修改或更改数组的内容。但是因为第二个 p 指向一个字符串常量,所以你不能改变字符串的内容。
例如,下面的一段代码试图修改一个字符串常量:
#include <stdio.h>
int main()
{
char *p = "I like HowToForge";
p[0] = 'U';
return 0;
}
这是我系统上这段代码产生的输出:
Segmentation fault
这个错误表明程序执行突然结束,那是因为我们试图改变一些不变的东西。
另外,请记住,虽然可以使指针 p 指向不同的字符串,但您不能更改数组 p 的基地址(如果您还记得的话,我们已经在之前的教程中讨论过这一点)。
现在转到指针数组,就像你见过整数、字符和其他类型的数组一样,也可以有一个指针数组。例如,下面的程序定义了一个整数指针数组 arr 并为其赋值。
#include <stdio.h>
int main()
{
int *arr[3];
int a = 0, b = 1, c = 2;
arr[0] = &a;
arr[1] = &b;
arr[2] = &c;
return 0;
}
请注意,分配给数组的值是地址。这是因为 arr 是一个指针数组,而指针只存储地址。现在,如果你想访问保存在这些地址的值,你将不得不使用 * 运算符。
以下示例(不过是前一个示例的扩展)展示了这一点:
#include <stdio.h>
int main()
{
int *arr[3];
int a = 0, b = 1, c = 2;
arr[0] = &a;
arr[1] = &b;
arr[2] = &c;
for(int i=0; i < 3; i++)
printf("\n arr[%d] is: %d",i,*(arr[i]));
return 0;
}
继承人的输出:
arr[0] is: 0
arr[1] is: 1
arr[2] is: 2
类似于整数指针数组(就像我们在这里讨论的那样),您可以让数组存储字符指针等。
现在,让我们继续讨论指向指针的指针。到目前为止我们已经迭代了很多次,指针存储了一个地址。现在,到目前为止,在这个正在进行的 C 编程教程系列中,我们只看到了一个指向非指针变量的指针,但事实上指针也可以指向其他指针。
这意味着一个指针可以存储另一个指针的地址。例如,下面是一个双指针或指向指针的指针:
int **ptr;
这是一段使用双指针的代码:
#include <stdio.h>
int main()
{
int *ptr;
int **p;
int a = 10;
ptr = &a;
p = &ptr;
printf("\n Pointer 'p' points to pointer 'ptr' which further points to value: %d", **p);
return 0;
}
继承人的输出:
Pointer 'p' points to pointer 'ptr' which further points to value: 10
所以这是一个双指针的例子。在类似的行上,您可以有一个指向指针的指针,例如定义为 int ***ptr。此类指向……级别的指针的最大数量是特定于实现的(尽管在某些情况下限制为 12)。
然而,实际上,您可能只会遇到指向最高级别三的指针的指针,因为级别越多,逻辑就越难以理解和维护。
结论
我们在这里讨论了三个重要的指针相关概念。建议您在您的系统上尝试我们在此讨论的示例和概念,以更好地了解这些东西是如何工作的。如有任何疑问或疑问,请在下方给我们留言。