C语言值传递与地址传递的理解。

前言

  在C语言的函数传参中有着值传递和地址传递两种方式,但今天我想通过本文来讲这两种传递方式合并为一种,即——拷贝传递(复制传递)
  简单来说,拷贝复制就是将传入的参数本身拷贝一份后,再传入调用的函数中。

一、知识补充

(一)指针相关知识

请观察下面代码以及结果(注:所有的地址我只写了后4位)

int a = 0 ;
int *p = &a ;

printf("变量a的地址     = %p\n",&a);
printf("变量p指向的地址 = %p\n",p);
printf("变量a本身的地址 = %p\n",&p);

结果为:
在这里插入图片描述
从以上的结果可以得到下面的内存分布
在这里插入图片描述
结论:

  1. 指针也是个变量,他也要占内存
  2. 指针变量里存放的是一个地址
  3. 所谓的指针指向就是根据指针变量的值去找到对应的地址。

(二)函数参数的本质

(注:这个本质是我的个人理解。)
观察下面代码:

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 复制了一份,并存放到了其它内存中。

(三)引入拷贝变量

  通过上面的两个例子,我们成功的引出了——拷贝复制。
简单来说拷贝复制就是把传递的参数给拷贝一份,赋值给调用的函数。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值