前言
在C语言的函数传参中有着值传递和地址传递两种方式,但今天我想通过本文来讲这两种传递方式合并为一种,即——拷贝传递(复制传递)
简单来说,拷贝复制就是将传入的参数本身拷贝一份后,再传入调用的函数中。
一、知识补充
(一)指针相关知识
请观察下面代码以及结果(注:所有的地址我只写了后4位)
int a = 0 ;
int *p = &a ;
printf("变量a的地址 = %p\n",&a);
printf("变量p指向的地址 = %p\n",p);
printf("变量a本身的地址 = %p\n",&p);
结果为:
从以上的结果可以得到下面的内存分布
结论:
- 指针也是个变量,他也要占内存
- 指针变量里存放的是一个地址
- 所谓的指针指向就是根据指针变量的值去找到对应的地址。
(二)函数参数的本质
(注:这个本质是我的个人理解。)
观察下面代码:
void fun(int num)
{
printf("num = %d\n",num);
printf("mun的大小 = %d\n",sizeof(num));
printf("mun的地址 = %p\n",&num);
}
int main(int argc, char const *argv[])
{
fun(1);
}
结论:
函数定义后,其参数是有内存的。所以函数的参数相当于申请变量。
二 、引入拷贝传递
(一)先看看值传递
观察下面的代码
void fun1(int num)
{
printf("#######在fun1函数中##########\n\n");
printf("num的值 = %d\n", num);
printf("num的地址 = %p\n", &num);
}
int main()
{
int a = 100;
fun1(a); // 值传递
printf("\n######在main函数中###########\n\n");
printf("a的值 = %d\n", a);
printf("a的地址 = %p\n", &a);
return 0;
}
程序运行结果。
我么可以得到一个内存图:
这里我们可以得出以下结论:
- 改变fun1()中的num不会影响main()的a的本质是——他们的地址不同。
- fun1()中的num只是简单的把main()中a的值拷贝了一份,并存放在另外的内存中
(二)再看看地址传递
void fun2(int *q)
{
printf("q指向地址的内容 = %d\n", *q);
printf("q指向的地址 = %p\n", q);
printf("q本身的地址 = %p\n", &q);
}
int main()
{
int a = 100;
int *p = &a ;
fun2(p); //fun2(&a);
printf("\n######在main函数中###########\n\n");
printf("a的地址 = %p\n", &a);
printf("p指向的地址 = %p\n", p);
printf("p本身的地址 = %p\n", &p);
return 0;
}
结果为:
得到内存图:
我们可以得出以下结论:
- fun2()中的q指针可以影响到mian()中的变量a本质是——q内存放的a的地址。
- 观察指针p和指针q我们又有
- 指针q 就是把指针p 复制了一份,并存放到了其它内存中。
(三)引入拷贝变量
通过上面的两个例子,我们成功的引出了——拷贝复制。
简单来说拷贝复制就是把传递的参数给拷贝一份,赋值给调用的函数。