一级指针传参
形参指针的指向没有被改变
void test(int* p1)
{*p1 = 8;
}int main()
{int a = 5;int* p = &a;test(p);printf("%d\n", a);
}
输出
8
总结:
- 由代码和上图可知,实参p是个指针,其值为变量a的地址,将其传参给形参p1,即为传地址。
- 形参p1接收到实参p传来的地址,又重新申请了一个内存用来存参数的值。由图可知,实参p和形参p1同时指向变量a, 所以在函数test内通过形参p1来改变其所指向的变量a的值,等到函数test调用结束后,形参p1的内存自动被销毁回收,但是实参p还是指向a, 还是可以通过指针p来获取已经被改变的a的值。
形参指针的指向被改变
void test(int* p1)
{int b = 3;p1 = &b; //改变了指针的指向*p1 = 8;
}int main()
{int a = 5;int* p = &a;test(p);printf("%d\n", a);}
输出
5
总结:
- 由代码执行结果可知,在test函数调用过程中,形参p1的指向内存空间被改变,所以通过指针无法改变a的值。
二级指针传参
先举个一级指针传参的反例
void getMemory(char* p, int num)
{p = malloc(sizeof(char) * num);
}int main()
{ char* str = NULL;getMemory(str, 20);strcpy(str, "hello");printf("%d\n", str);}
上述代码出错
总结:
1.由图可知,在str将其值(地址)传给getMemory的指针变量p后,p的指向被改变了,但是str的指向没有变,还是指向NULL,所以在strcpy中str为NULL,无法拷贝字符串,程序出错,如何解决上述问题,需要使用二级指针传参,如下面例子所示
void getMemory(char** p, int num)
{*p = malloc(sizeof(char) * num);
}int main()
{ char* str = NULL;getMemory(&str, 20);strcpy(str, "hello");printf("%s\n", str);
}
hello
总结: 使用二级指针,传入的是一级指针的指针(一级指针的地址),当&str传给getMemory时,p和&str都是指向str, 当执行*p=malloc(sizeof(char)*num)后,就相当于str= *(&str)=malloc(sizeof(char)*num), 则str指向了新申请的堆空间,等到getMemory调用结束后,p局部变量被系统销毁, 但是str是main的局部变量,main函数没有结束运行,则str指向的空间还在,所以strcpy可以正常拷贝。