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