1、需要双重指针的原因
当我们希望在函数内部改变指针的指向时,如果仅传递指针本身,函数修改的只是这个指针的副本,对原始指针的值没有影响。使用双重指针,函数可以通过指向指针的指针访问和更改原始指针的地址,从而实现“改变指针的指向”。
1)使用单重指针无法更改指针地址
changePointer
函数使用的是单重指针 int *ptr
。即使在函数中分配了新的内存地址并将 ptr
重新指向它,主函数中的 p
指针并没有发生变化,因为 changePointer
中的 ptr
只是 p
的一个副本。
#include <stdio.h>
#include <stdlib.h>
void changePointer(int *ptr) {
ptr = (int *)malloc(sizeof(int)); // 试图修改指针的地址
if (ptr != NULL) {
*ptr = 10; // 赋值
}
}
int main() {
int *p = NULL;
printf("Before changePointer: %p\n", (void*)p);
changePointer(p);
if (p != NULL) {
printf("After changePointer: %p\n", (void*)p);
printf("Value at new address: %d\n", *p);
} else {
printf("After changePointer: p is still NULL\n");
}
return 0;
}
2)使用双重指针更改指针地址
使用了双重指针 int **ptr
。在 changePointer
函数中,我们改变了指针 p
的地址,使它指向了一块新分配的内存。主函数中的 p
被成功更新,并且新的地址生效了。
#include <stdio.h>
#include <stdlib.h>
void changePointer(int **ptr) {
*ptr = (int *)malloc(sizeof(int)); // 修改了指针的地址
if (*ptr != NULL) {
**ptr = 10; // 赋值
}
}
int main() {
int *p = NULL;
printf("Before changePointer: %p\n", (void*)p);
changePointer(&p);
if (p != NULL) {
printf("After changePointer: %p\n", (void*)p);
printf("Value at new address: %d\n", *p);
}
// 释放分配的内存
free(p);
return 0;
}
2、使用双重指针更改指针的地址
C语言中,函数中使用双重指针可以更改指针的地址,即让传入的指针变量指向一个新的地址。这种方法特别有用,例如在动态分配内存的场景中。当我们将一个指针传递给函数时,传递的是指针的副本,所以我们在函数内对指针赋值(更改地址)不会影响到原始指针。通过传入指针的地址(即双重指针),可以在函数中直接操作指针变量的地址,达到修改指针地址的目的。
#include <stdio.h>
#include <stdlib.h>
void allocateMemory(int **ptr) {
*ptr = (int *)malloc(sizeof(int)); // 修改了指针的地址
if (*ptr != NULL) {
**ptr = 20; // 为新地址上的数据赋值
}
}
int main() {
int *p = NULL;
printf("Before allocateMemory: p = %p\n", (void*)p);
// 传递指针的地址,便于在函数中修改指针的地址
allocateMemory(&p);
if (p != NULL) {
printf("After allocateMemory: p = %p\n", (void*)p);
printf("Value at new address: %d\n", *p);
}
// 释放分配的内存
free(p);
return 0;
}
3、不使用双重指针的情况
如果直接传递指针,则无法更改原始指针的地址。修改的是指针的副本,对主函数中的 p
没有影响。
#include <stdio.h>
#include <stdlib.h>
void changePointer(int* ptr) {
ptr = (int*)malloc(sizeof(int)); // 分配新内存,但不会影响原始指针
if (ptr != NULL) {
*ptr = 42;
}
}
int main() {
int* p = NULL;
changePointer(p); // 传递指针的副本
if (p != NULL) {
printf("New value: %d\n", *p); // 不会执行,因为 p 仍然为 NULL
free(p);
} else {
printf("Pointer is still NULL\n"); // 输出这行
}
return 0;
}