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