Cprogramming 简明教程

Pointer to Pointer (Double Pointer) in C

What is a Double Pointer in C?

pointer to pointer ,在C中也称为 double pointer ,用于存储另一个指针的地址。

C中存储另一个变量地址的 variable 称为 * pointer.* 指针变量可以存储任何类型的地址,包括基本数据类型、数组、struct类型等。同样,指针还可以存储另一个指针的地址,在这种情况下称为 "pointer to pointer" (也称为 "double pointer" )。

“指针的指针”是 multiple indirectionchain of pointers. 的一种形式。通常,指针包含变量的地址。当我们定义一个"指针的指针"时,第一个指针包含第二个指针的地址,该指针指向包含实际值的地址,如下所示 -

pointer to pointer

Declaration of Pointer to a Pointer

pointer to pointer ( double pointer )的声明类似于指针的声明,唯一的区别是您需要在指针变量名之前使用 additional asterisk ( * )。

Example

例如,以下声明声明了一个类型为 int − 的“指针的指针”

int **var;

当一个目标值被“指针的指针”间接指向时,访问该值需要应用两次星号运算符。

Example of Pointer to Pointer (Double Pointer)

以下示例演示了在C中声明、初始化和使用指向指针的指针(双指针):

#include <stdio.h>

int main() {
  // An integer variable
  int a = 100;

  // Pointer to integer
  int *ptr = &a;

  // Pointer to pointer (double pointer)
  int **dptr = &ptr;

  printf("Value of 'a' is : %d\n", a);
  printf("Value of 'a' using pointer (ptr) is : %d\n", *ptr);
  printf("Value of 'a' using double pointer (dptr) is : %d\n", **dptr);

  return 0;
}
Value of 'a' is : 100
Value of 'a' using pointer (ptr) is : 100
Value of 'a' using double pointer (dptr) is : 100

How Does a Normal Pointer Work in C?

假设一个整数变量 "a" 位于任意地址1000处。它的指针变量是 "b" ,并且编译器为它分配了地址2000。下图提供了一个视觉描述 -

normal pointer

让我们声明一个 int 类型指针,并在其中存储 int 变量的地址。

int a = 10;
int *b = &a;

dereference operator 通过指针获取值。

printf("a: %d \nPointer to 'a' is 'b': %d \nValue at 'b': %d", a, b, *b);

Example

以下是显示普通指针工作原理的完整程序 -

#include <stdio.h>

int main(){

   int a = 10;
   int *b = &a;
   printf("a: %d \nPointer to 'a' is 'b': %d \nValue at 'b': %d", a, b, *b);

   return 0;
}

它将打印 int 变量的值、其地址和通过取消引用指针获得的值 -

a: 10
Pointer to 'a' is 'b': 6422036
Value at 'b': 10

How Does a Double Pointer Work?

现在我们声明一个可以存储"b"地址的指针,而"b"本身是一个指向 int 类型的指针,写为 "int *".

假设编译器还为它分配了地址3000。

double pointer

因此, "c" 是一个指向 int, 的指针的指针,应该声明为 "int * 。*

int **c = &b;
printf("b: %d \nPointer to 'b' is 'c': %d \nValue at b: %d\n", b, c, *c);

你得到了"b"的值(即"a"的地址)、"c"的值(即"b"的地址)和"c"的解引用值(即"a"的地址)-

b: 6422036
Pointer to b is c: 6422024
Value at b: 6422036

这里,"c"是一个双指针。声明中的第一个星号指向"b",而第二个星号反过来指向"a"。因此,我们可以使用双引用指针从"c"获得"a"的值。

printf("Value of 'a' from 'c': %d", **c);

这应该将’a’的值显示为10。

Example

以下是一个完整的程序,展示了双指针如何工作−

#include <stdio.h>

int main(){

   int a = 10;
   int *b = &a;
   printf("a: %d \nAddress of 'a': %d \nValue at a: %d\n\n", a, b, *b);

   int **c = &b;
   printf("b: %d \nPointer to 'b' is c: %d \nValue at b: %d\n", b, c, *c);
   printf("Value of 'a' from 'c': %d", **c);

   return 0;
}

运行代码并检查其输出:

a: 10
Address of 'a': 1603495332
Value at a: 10

b: 1603495332
Pointer to 'b' is c: 1603495336
Value at b: 1603495332
Value of 'a' from 'c': 10

A Double Pointer Behaves Just Like a Normal Pointer

C语言中的"指针的指针"或"双指针"的行为就像一个普通指针。因此,双指针变量的大小总是等于普通指针。

我们可以通过对上述程序中的指针"b"和"c"应用 sizeof operator 来检查它-

printf("Size of b - a normal pointer: %d\n", sizeof(b));
printf("Size of c - a double pointer: %d\n", sizeof(c));

这显示了两个指针相等的大小-

Size of b - a normal pointer: 8
Size of c - a double pointer: 8

Note: 上述示例中显示的不同指针变量的大小和地址可能会有所不同,因为这取决于CPU 架构和操作系统等因素。但是,它们将显示一致的结果。

Multilevel Pointers in C (Is a Triple Pointer Possible?)

理论上,指针声明中可以出现的星号数量没有限制。

如果你确实需要指向 "c" 的指针(在上例中),它将是"指向指向指针的指针的指针",可以声明为−

int ***d = &c;

大多数情况下,双指针用于引用二维数组或字符串数组。