以下内容源于网络资源的学习与整理,欢迎交流。
总结
值传递,只是把原参的复制品传给形参,在子函数中修改这个形参,不会改变主函数中的原参。
地址传递,由于形参和原参表示同一个内容,在子函数中修改形参,也会改变主函数中的原参。
代码示例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或者**ppint main(void)
{int *p;int a[2] = { 4,5 };p = a;printf("1--------%d\n", *p);//开始值为4F1(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]=9printf("2`-------%d\n", a[1]);//9F2(&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。