C语言值传递和地址传递详解

 更新时间:2022年01月19日 09:01:35   作者:At3uki  
大家好,本篇文章主要讲的是C语言值传递和地址传递详解,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览

一. 值传递

我们举一个例子:

写一个函数找出两个整数中的最大值。

#include<stdio.h>

//get_max函数
int get_max(int x,int y)
{
  return (x>y)?x:y;
}

int main()
{
  int num1 = 10;
  int num2 = 20;
  int max = get_max(num1,num2);
  printf("max = %d\n",max);
  return 0;
}

运行结果是:

max = 20

我们来分析一下这个函数调用过程:

num1,num2作为实参传入get_max()函数,形参x,y被实例化(分配内存单元),num1和num2的值按照函数形参表顺序对应地传给了x和y,也就是x=10,y=20,然后函数将x和y中较大的一个的值返回。函数调用完毕,x和y被自动销毁。

我们看一下函数的特征,如果函数的形参和实参一致,这就是值传递。

二.地址传递

再举一个例子:

写一个函数交换两个整形变量的内容。

很多初学者一看觉得太简单了,按照值传递我们来写一遍。

#include <stdio.h>
//值传递
void Swap1(int x, int y) {
    int tmp = 0;
    tmp = x; 
    x = y; 
    y = tmp; 
}
int main()
{
	int num1 = 1;
	int num2 = 2;
	
  printf("交换前::num1 = %d num2 = %d\n",num1,num2);
  Swap1(num1, num2);
	printf("swap1::num1 = %d num2 = %d\n", num1, num2);
	return 0; 
}

但此时的结果是什么呢?

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SPPXxlHu-1642493097747)(../source/images/image-20220118152647618.png)]

num1,num2值并没有变啊,并没有交换啊,为什么呢?

因为当实参传给形参的时候,形参是实参的一份临时拷贝,对形参的修改不会影响实参

我们来打印一下各变量的地址

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AnfGU4Nm-1642493097749)(../source/images/image-20220118153528486.png)]

可以看到,实参有自己的地址,形参也有自己的地址,实参只把自己的值传给了形参,地址各有各的,实参的地址上放的值并没有变啊,并且形参在函数调用完后就自动销毁了,也就是说函数内与函数外的变量并没有建立真正的实质的联系。就想象你copy了一个自己的仿生人,他吃了东西,进你的胃了吗?肯定他吃他饱,跟你毫无相关是吧(狗头

那么这个问题怎么解决呢?地址传递

#include <stdio.h>
//值传递
void Swap1(int x, int y) {
    int tmp = 0;
    tmp = x; 
    x = y; 
    y = tmp; 
}
int main()
{
	int num1 = 1;
	int num2 = 2;
	
  printf("交换前::num1 = %d num2 = %d\n",num1,num2);
  Swap1(num1, num2);
	printf("swap1::num1 = %d num2 = %d\n", num1, num2);
	return 0; 
}

​ 我们来看一下结果

在这里插入图片描述

地址传递做了什么?

做地址传递时 函数参数是指针变量,指针变量里面装着的就是地址嘛,所以实参直接就把自己的地址传过去了,px里放的num1地址,py里放的num2地址, *px就是num1本身, *py就是num2本身,实参本身进行了赋值交换,这次不是你的仿生人了,就是你自己体验人生。

我们看一下函数特征:如果传入的实参是形参的指针,那就是地址传递。

其实有一个问题我好久才想明白:

为什么上一个例子(返回两数中较大的一个)没有用地址传递也成功了呢?这两种方式使用的界限是什么呢?

后来这个疑问终于被解答了:

因为第一个例子里num1,num2的值并不需要改变,函数中x,y比较后如果返回x,x的值和a的值是一样的,这个对结果是不影响的,也就是说,这种问题不需要改变实参的值,形参和实参不需要建立那么实质的联系

但要搞清楚的是,函数返回的是num1本身吗?是num1地址上的值吗?不,只是num1的拷贝x地址上的值。

综上,在需要改变实参的值时一定要使用地址传递才行。

总结

到此这篇关于C语言值传递和地址传递详解的文章就介绍到这了,更多相关C语言值传递 地址传递内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++ map的简单使用实现

    C++ map的简单使用实现

    map是STL的一个关联容器,它以<key,value>一对一的形式存储,且map的内部自建一个红黑树,使得其可以自动排序,本文就介绍一下C++ map的简单使用,感兴趣的可以了解一下
    2021-05-05
  • Linux下C语言的几道经典面试题小结(分享)

    Linux下C语言的几道经典面试题小结(分享)

    下面小编就为大家带来一篇Linux下C语言的几道经典面试题小结(分享)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-05-05
  • c++利用stl set_difference对车辆进出区域进行判定

    c++利用stl set_difference对车辆进出区域进行判定

    这篇文章主要介绍了set_difference,用于求两个集合的差集,结果集合中包含所有属于第一个集合但不属于第二个集合的元素,需要的朋友可以参考下
    2017-03-03
  • C++顺序表实现图书管理系统

    C++顺序表实现图书管理系统

    这篇文章主要为大家详细介绍了C++顺序表实现图书管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-10-10
  • C++ OpenGL实现球形的绘制

    C++ OpenGL实现球形的绘制

    这篇文章主要主要为大家详细介绍了如何利用C++和OpenGL实现球形的绘制,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起动手尝试一下
    2022-07-07
  • C语言中socket相关网络编程函数小结

    C语言中socket相关网络编程函数小结

    这篇文章主要介绍了C语言中socket相关网络编程函数小结,是C语言入门学习中的基础知识,需要的朋友可以参考下
    2015-09-09
  • Qt编写提示进度条的实现示例

    Qt编写提示进度条的实现示例

    进度条在很地方都可以使用到,Qt自带的进度条或者操作系统的进度条样式,不够炫,本文就介绍一下Qt编写自定义控件的提示进度条的实现示例,感兴趣的可以了解一下
    2021-12-12
  • C语言文件读写操作介绍与简单示例

    C语言文件读写操作介绍与简单示例

    这篇文章主要给大家介绍了关于C语言文件读写操作的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • C++基于递归和非递归算法判定两个二叉树结构是否完全相同(结构和数据都相同)

    C++基于递归和非递归算法判定两个二叉树结构是否完全相同(结构和数据都相同)

    这篇文章主要介绍了C++基于递归和非递归算法判定两个二叉树结构是否完全相同,若判断二叉树的结构和数据都相同则为完全相同.涉及C++二叉树的创建、遍历、比较等相关操作技巧,需要的朋友可以参考下
    2017-05-05
  • Linux网络编程之基于UDP实现可靠的文件传输示例

    Linux网络编程之基于UDP实现可靠的文件传输示例

    这篇文章主要介绍了Linux网络编程之基于UDP实现可靠的文件传输示例,是很实用的技巧,需要的朋友可以参考下
    2014-08-08

最新评论