1.修改指针指向的地址
需要用二级指针或引用来修改参数中的指针内容(修改指针指向的地址)
(1)通过二级指针修改:
#include <stdio.h>
#include <string.h>
#include <malloc.h>
void func1(int **p2); //形参使用二级指针
int main()
{
int *p1;
int num1 = 11111111;
p1 = &num1; // 首先指向num1
printf("1111 p1_addr[%p]->v_addr[%p]=%d\n", &p1, p1, *p1); //此时指针指向num1
func1(&p1); // 传参传入指针地址
printf("3333 p1_addr[%p]->v_addr[%p]=%d\n", &p1, p1, *p1); //指向的地址已经修改为num2了
return 0;
}
void func1(int **p2)
{
int num2 = 22222222;
*p2 = &num2;
printf("2222 p2_addr[%p]->p1_addr[%p]->v_addr[%p]=%d\n", &p2, p2, *p2, **p2);
}
运行结果:
形参的二级指针指向实参一级指针的地址,通过修改二级指针指向的地址的值(也就是一级指针指向的地址)来修改一级指针指向的地址
(2)通过指针的引用修改:
#include <stdio.h>
#include <string.h>
#include <malloc.h>
void func1(int *(&p2)); //使用指针的引用
int main()
{
int *p1;
int num1 = 11111111;
p1 = &num1;
printf("1111 p1_addr[%p]->v_addr[%p]=%d\n", &p1, p1, *p1);
func1(p1); // 传入指针
printf("3333 p1_addr[%p]->v_addr[%p]=%d\n", &p1, p1, *p1);
return 0;
}
void func1(int *(&p2))
{
int num2 = 22222222;
p2 = &num2;
printf("2222 p2_addr[%p]->v_addr[%p]=%d\n", &p2, p2, *p2);
}
运行结果:
通过引用修改,不同的别名实际是同一个地址,修改p2的同时也会修改p1
2.修改指针指向的地址的值
直接使用一级指针作为形参即可修改实参指针指向地址的内容,此时会生成第二个指针,形参的指针与实参的指针指向同一个地址,于是形参指针修改地址内容时,实参指针取值也同时变化。
#include <stdio.h>
#include <string.h>
#include <malloc.h>
void func1(char *p2);
int main()
{
char *p1 = (char *)malloc(8*sizeof(char));
memcpy(p1, "aaaaaaaa", 8);
printf("1111 p1_addr[%p]->v_addr[%p]=%s\n", &p1, p1, p1);
func1(p1);
printf("3333 p1_addr[%p]->v_addr[%p]=%s\n", &p1, p1, p1);
free(p1);
if(p1 != NULL)
{
p1 = NULL;
}
return 0;
}
void func1(char *p2)
{
memcpy(p2, "bbbbbbbb", 8);
printf("2222 p2_addr[%p]->v_addr[%p]=%s\n", &p2, p2, p2);
}
运行结果:
通过2222打印可以看出栈区是另外一个指针但是指向的地址是同一块