Cprogramming 简明教程

Pointer to Pointer (Double Pointer) in C

What is a Double Pointer in C?

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

A pointer to pointer which is also known as a double pointer in C is used to store the address of another pointer.

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

A variable in C that stores the address of another variable is known as a pointer. A pointer variable can store the address of any type including the primary data types, arrays, struct types, etc. Likewise, a pointer can store the address of another pointer too, in which case it is called "pointer to pointer" (also called "double pointer").

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

A "pointer to a pointer" is a form of multiple indirection or a chain of pointers. Normally, a pointer contains the address of a variable. When we define a "pointer to a pointer", the first pointer contains the address of the second pointer, which points to the location that contains the actual value as shown below −

pointer to pointer

Declaration of Pointer to a Pointer

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

The declaration of a pointer to pointer (double pointer) is similar to the declaration of a pointer, the only difference is that you need to use an additional asterisk (*) before the pointer variable name.

Example

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

For example, the following declaration declares a "pointer to a pointer" of type int −

int **var;

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

When a target value is indirectly pointed to by a "pointer to a pointer", accessing that value requires that the asterisk operator be applied twice.

Example of Pointer to Pointer (Double Pointer)

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

The following example demonstrates the declaration, initialization, and using pointer to pointer (double pointer) in 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。下图提供了一个视觉描述 -

Assume that an integer variable "a" is located at an arbitrary address 1000. Its pointer variable is "b" and the compiler allocates it the address 2000. The following image presents a visual depiction −

normal pointer

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

Let us declare a pointer to int type and store the address of an int variable in it.

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

dereference operator 通过指针获取值。

The dereference operator fetches the value via the pointer.

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

Example

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

Here is the complete program that shows how a normal pointer works −

#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 变量的值、其地址和通过取消引用指针获得的值 -

It will print the value of int variable, its address, and the value obtained by the dereference pointer −

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

How Does a Double Pointer Work?

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

Let us now declare a pointer that can store the address of "b", which itself is a pointer to int type written as "int *".

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

Let’s assume that the compiler also allocates it the address 3000.

double pointer

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

Hence, "c" is a pointer to a pointer to int, and should be declared as "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"的地址)-

You get the value of "b" (which is the address of "a"), the value of "c" (which is the address of "b:), and the dereferenced value from "c" (which is the address of "a") −

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

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

Here, "c" is a double pointer. The first asterisk in its declaration points to "b" and the second asterisk in turn points to "a". So, we can use the double reference pointer to obtain the value of "a" from "c".

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

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

This should display the value of 'a' as 10.

Example

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

Here is the complete program that shows how a double pointer works −

#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;
}

运行代码并检查其输出:

Run the code and check its output −

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语言中的"指针的指针"或"双指针"的行为就像一个普通指针。因此,双指针变量的大小总是等于普通指针。

A "pointer to pointer" or a "double pointer" in C behaves just like a normal pointer. So, the size of a double pointer variable is always equal to a normal pointer.

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

We can check it by applying the sizeof operator to the pointers "b" and "c" in the above program −

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

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

This shows the equal size of both the pointers −

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

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

Note: The size and address of different pointer variables shown in the above examples may vary, as it depends on factors such as CPU architecture and the operating system. However, they will show consistent results.

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

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

Theoretically, there is no limit to how many asterisks can appear in a pointer declaration.

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

If you do need to have a pointer to "c" (in the above example), it will be a "pointer to a pointer to a pointer" and may be declared as −

int ***d = &c;

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

Mostly, double pointers are used to refer to a two−dimensional array or an array of strings.