C语言中的指针链



什么是C语言中的指针链?

C语言中的指针链是一系列相互指向的指针。指针变量可以存储另一个变量的地址,这个变量可以是任何类型,包括另一个指针,在这种情况下,它被称为指向指针的指针

指针链是指存在多个级别的指针。理论上,链的级别没有限制,如下图所示:

Chain of Pointers

指针链的声明

这可以用以下代码表示:

int a = 10;
int *x = &a;
int **y = &x;
int ***z = &y;

在上面的例子中,“x”是指向“int”类型的指针,如符号“int *”所示。要在“y”中存储“x”的地址,“y”应该是指向指向int的指针,即“int **”。

类似地,“z”是“指向指向指向int的指针”的指针,因此其声明中星号出现了三次,即“int ***”。

解引用是如何工作的?

我们知道“*x”返回存储在“x”中的地址处的值,即“a”的值。

根据相同的逻辑,“*y”应该返回它的值(参考上图),它是1000,这反过来又是“a”的地址。因此,“y”的双重解引用(即“**y”)应该给出“a”的值。

此外,“z”的三重解引用(即“***z”)应该给出“a”的值。

示例

下面的例子展示了“双重解引用”和“三重解引用”是如何工作的:

#include <stdio.h>

int main(){

   int a = 10;

   int *x = &a;
   int **y = &x;
   int ***z = &y;

   printf("a: %d\n", a);

   printf("a: %d\n", *x);   // dereferencing x;
   printf("a: %d\n", **y);  // double dereferencing y;
   printf("a: %d\n", ***z); // triple dereferencing z;

   return 0;
}

输出

请注意,所有三种解引用情况都打印了“a”的值:

a: 10
a: 10
a: 10
a: 10

浮点型指针链

我们可以遵循相同的逻辑来创建一个浮点型指针链,并应用多级解引用来获取浮点型变量的值。

示例

下面的例子展示了如何使用浮点型指针链:

#include <stdio.h>

int main(){

   float a = 10.25;

   float *x = &a;
   float **y = &x;
   float ***z = &y;

   printf("a: %f\n", a);
   printf("a: %f\n", *x);
   printf("a: %f\n", **y);
   printf("a: %f\n", ***z);

   return 0;
}

输出

运行代码并检查其输出:

a: 10.250000
a: 10.250000
a: 10.250000
a: 10.250000

通过解引用更新原始变量

我们还可以通过解引用来更新原始变量的值。请看下面的语句:

*x = 11.25;

它会相应地更改“a”的值。类似地,它可以使用后续级别的指针进行更新。

示例

下面的程序展示了如何使用不同级别的解引用来更新原始变量:

#include <stdio.h>

int main(){

   float a = 10.25;;

   float *x = &a;
   float **y = &x;
   float ***z = &y;

   printf("a: %f\n", a);

   // update with first pointer
   *x = 11.25;
   printf("a: %f\n", *x);

   // update with second pointer
   **y = 12.25;
   printf("a: %f\n", **y);

   // update with third pointer
   ***z = 13.25;
   printf("a: %f\n", ***z);

   return 0;
}

输出

运行代码并检查其输出:

a:10.250000
a:11.250000
a:12.250000
a:13.250000

字符型指针链

字符串表示为“char”类型的数组或指向“char”类型的指针:

char *a = "Hello";

因此,我们可以创建一个字符型指针链。

注意:唯一的区别是,这里的原始变量本身就是一个指针,因此与前面的例子相比,上层指针多了一个星号

示例

下面的例子展示了字符型指针链是如何工作的:

#include <stdio.h>

int main(){

   char *a = "Hello";

   char **x = &a;
   char ***y = &x;
   char ****z = &y;

   printf("a: %s\n", a);
   printf("a: %s\n", *x);
   printf("a: %s\n", **y);
   printf("a: %s\n", ***z);

   return 0;
}

输出

运行这段代码时,会产生以下输出:

a: Hello
a: Hello
a: Hello
a: Hello

指针链对于创建链表和其他数据结构很有用。

广告