以下内容源于网络资源的学习与整理,欢迎交流。
总结
值传递,只是把原参的复制品传给形参,在子函数中修改这个形参,不会改变主函数中的原参。
地址传递,由于形参和原参表示同一个内容,在子函数中修改形参,也会改变主函数中的原参。
代码示例1
#include<stdio.h>
void F1(int *pp)
{
pp++;
*pp = 9;
}
void F2(int **pp)
{
(*pp)++;
}
int* F3(int *pp)
{
pp++;
return pp;
}
//以上函数中,接收数据的参量都是pp,而不会是*pp或者**pp
int main(void)
{
int *p;
int a[2] = { 4,5 };
p = a;
printf("1--------%d\n", *p);//开始值为4
F1(p);
printf("2--------%d\n", *p);//4
//由于只是传值,在子函数F1的内部改变复制品的值,并不会改变原品p的值
//可以理解为用两个变量指向同一个地址,即形参pp和实参p指向同一个地址
//其中形参pp++,另外一个实参p并不会受影响
//但是可以修改指针所指的值,如F1代码中将a[1]的值改为9;
//经过F1(p)函数后,p依然指向指向a[0],但原来的a[1]=5被修改成a[1]=9
printf("2`-------%d\n", a[1]);//9
F2(&p);
printf("3--------%d\n", *p);//9
//传址,pp=&p(指针的地址,即pp是指向指针的指针),pp=&p,则*pp=*(&p)=p;
//如果要修改指针p,则应该传入指针p的地址(&p),\
//此时进行(*pp)++操作,其实是对实参指针p进行操作
getchar(); getchar();
return 0;
}
代码示例2
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
/*void getmemory(char **p)
{
*p = (char *)malloc(100);
strcpy(*p, "helloworld");
}
int main()
{
char* str = NULL;
getmemory(&str);
printf("%s", str);
free(str);
getchar();
return 0;
}*/
char* getmemory(char *p)
{
p = (char *)malloc(100);
strcpy(p, "helloworld");
return p;
}
int main()
{
char* str = NULL;
str = getmemory(str);
printf("%s", str);
free(str);
getchar();
return 0;
}
分析说明
如果要在子函数中修改主函数传过来的指针的指向,那么主函数应该向子函数传入指针的地址(而非指针本身);此时在子函数中进行*操作后可以获得原来指针,而不是原来指针的复制品,之后可以根据需要修改指针。
或者,将返回值类型改为指针类型,然后返回修改后的指针,给原来主函数的指针。比如代码示例1中的F3函数,此时在主函数中需要添加p=F3(p)代码;又比如代码示例2。