1、双重指针
一个普通指针(int *p
)指向一个整数,而双重指针(int **pp
)指向一个指针,该指针再指向一个整数。
#include <stdio.h> int main() { int x = 10; int *p = &x; int **pp = &p; printf("x = %d\n", x); // 10 printf("*p = %d\n", *p); // 10 printf("**pp = %d\n", **pp); // 10 return 0; }
2、使用双重指针的原因
如果函数只需要读取指针指向的数据,而不需要修改指针本身,那么使用单个指针即可。如果只操作一维数组,不涉及动态分配二维数组,也不需要使用 **
。在某些情况下,可以使用 struct
代替双重指针,使代码更具可读性。
1)函数修改指针本身
C 语言中,函数参数按值传递,即函数无法直接修改传递的指针本身。但是,使用双重指针,可以间接修改指针,使其指向新的内存地址。
#include <stdio.h> #include <stdlib.h> void allocateMemory(int **ptr) { *ptr = (int *)malloc(sizeof(int)); // 让 ptr 指向新分配的内存 if (*ptr != NULL) { **ptr = 100; // 在新分配的内存中存储值 } } int main() { int *p = NULL; allocateMemory(&p); // 传递指向指针 p 的指针 printf("Allocated value: %d\n", *p); // 100 free(p); return 0; }
2)处理动态二维数组
C 语言没有内置的二维数组支持,因此通常使用指针的数组或**
指向指针的指针(双重指针)**
来创建动态二维数组。
#include <stdio.h> #include <stdlib.h> int main() { int rows = 3, cols = 4; // 分配行指针 int **array = (int **)malloc(rows * sizeof(int *)); // 为每一行分配列 for (int i = 0; i < rows; i++) { array[i] = (int *)malloc(cols * sizeof(int)); } // 赋值 array[1][2] = 42; printf("array[1][2] = %d\n", array[1][2]); // 释放内存 for (int i = 0; i < rows; i++) { free(array[i]); } free(array); return 0; }
3)处理字符串数组
C 语言中,字符串是 char *
,而字符串数组是 char **
(即指向 char *
的指针)。
#include <stdio.h> int main(int argc, char *argv[]) { for (int i = 0; i < argc; i++) { printf("Argument %d: %s\n", i, argv[i]); } return 0; }
4)处理指针数组
如需要修改多个指针的值,可以使用双重指针。
#include <stdio.h> void modifyStrings(char **strArray) { strArray[0] = "Modified!"; } int main() { char *messages[] = { "Hello", "World" }; modifyStrings(messages); printf("%s\n", messages[0]); // 输出 "Modified!" return 0; }