IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> c语言函数的值传递机制(swap函数怎么通过形参改变实参的值) -> 正文阅读

[C++知识库]c语言函数的值传递机制(swap函数怎么通过形参改变实参的值)

swap函数中体现出的c语言函数的值传递机制(形参中int * &是什么意思)

目前初学C语言,对于深层内存机制了解不是十分透彻,只是将自己的理解方式简单记录一下。

我们知道交换两个变量的数值非常简单,只需要一个中间变量swap

void main(){
	int a=3, b=5,swap;
	swap = a;
	a = b;
	b = swap;
}

这样就完成了a和b两个变量的数值交换,但是当我们把这段代码原封不动的搬进一个函数swap里好像又不是这么回事了。

无法达到预想目的swap函数

void swap(int x, int y){
	int swap;
	swap = x;
	x = y;
	y = swap;
}

void main(){
	int a=3, b=5;
	printf("交换前:a=%d,b=%d\n",a,b);
	swap(a,b);
	printf("交换后:a=%d,b=%d\n",a,b);
}

// 输出结果:
交换前a=3,b=5
交换后a=3,b=5
请按任意键继续. . .

这时我们惊奇的发现明明一模一样的代码搬进了函数里但是变量a与b却并没有按照预想中的一样交换数值。
那么这段代码在内存中是什么样子的呢

刚刚进入swap函数时:
在这里插入图片描述
每个函数都有一个独立的变量空间,当执行到swap(a,b)时,swap中定义的形参x、y只是拿到了a、b两个变量中存储的值的复制品,它们甚至不知道a、b的存在,这两组变量是完全独立互不影响的。

当函数执行完之后:
在这里插入图片描述
当一个函数执行完毕时也就是它的变量空间销毁的时刻,因为main函数执行完毕意味着程序的结束,所以main中的变量一直伴随着程序存在。

图片上是swap函数刚刚执行完毕即将销毁变量空间时里面的变量值,我们可以看到事实上在swap的变量空间中已经完成了交换,但是功能的完成也意味着自己的销毁,无法影响a、b的值也无法展示出来,只能默默的毁灭。

能够成功完成使命的swap函数

通过上面的例子我们知道形参是无法影响实参的值的,因为它们在两个空间中,注定不能相遇。但是好在C语言有指针的存在。
这里我决定先画出来原理再写代码。

在这里插入图片描述

指针是通过存储变量地址来指向变量,那么即使*x、*y拿到的是地址的复制品也不影响它们存在的期间指向a、b的事实,那么现在实际上有两个指针(*a,*x)指向a,两个指针(*b,*y)指向b,这两个指针地位是一样的,都可以直接读取和修改a、b的值,所以我们就可以通过这点来改变a、b的值。

实际代码如下:

void swap(int *num1, int* num2){
	int swap;
	swap = *num1;
	*num1 = *num2;
	*num2 = swap;
}
void main(){
	int a=3, b=5;
	int *c=&a, *d=&b
	printf("交换前a=%d,b=%d\n",a,b);
	swap(c,d);
	printf("交换后a=%d,b=%d\n",a,b);
}
// 输出结果:
交换前a=3,b=5
交换后a=5,b=3
请按任意键继续. . .

在调用swap函数时我们没有直接传入a、b,而是传入了&a、&b(即a、b的地址,亦即最左侧的那栏c、d)
下面是swap刚执行完即将销毁时各个变量的值:
在这里插入图片描述

我们可以看到在swap函数中我们没有改变x和y的值,而是通过*x 和 *y直接修改了它们指向的a、b变量中存储的值。也就达到了交换值的目的。

现在我们也就不难发现另一种写法中的错误了:

又一种错误写法

void swap(int *num1, int *num2){
	int *swap;
	swap = num1;
	num1 = num2;
	num2 = swap;
}

void main(){
	int a=3, b=5;
	int *c=&a, *d=&b
	printf("交换前a=%d,b=%d\n",a,b);
	swap(c,d);
	printf("交换后a=%d,b=%d\n",a,b);
}
// 输出结果:
交换前a=3,b=5
交换后a=3,b=5
请按任意键继续. . .

在这个swap函数中刚开始执行时内存结构和正确的情况是相同的,我们直接来看一下执行结束时的结果:

在这里插入图片描述
我们可以看到swap函数中只是交换了x、y中存储的地址值,也就是改变了x、y指向的变量的值,main函数的变量空间还是没有任何改变。

最后再看看(int * &)是什么意思

这个语法是C++中的引用类型,但不知道为什么C语言也可以用,我们直接来看看代码和最后的结果。

void swap(int* &num1, int* &num2){
	int * temp;
	temp = num1;
	num1 = num2;
	num2 = temp;
}

void main(){
	int a =3,b = 5;
	int *c=&a, *d=&b;
	printf("交换前a=%d,b=%d\n",a,b);
	swap3(c,d);
	printf("交换后a=%d,b=%d\n",a,b);
}
// 输出结果:
交换前a=3,b=5
交换后a=5,b=3
请按任意键继续. . .

和刚刚的代码效果一样啊,那这多加的一个&有什么用呢?看看内存结构就一目了然了。

在这里插入图片描述
其实效果很简单,就是让实参与形参同步变化。实质上是将实参这个空间直接给形参,即形参和实参公用一个空间(或者说是给实参空间又起了一个别名)。这个加了&的就叫引用变量。实际内存中就是这样的:
在这里插入图片描述
这样就可以实现形参与实参的同步改变了,因为它们实际上是一个人的两个名字,叫哪个说的都是同一个人。在swap函数结束时销毁掉的也只是x、y这两个名字,而不是那个人。

这样的话是不是就有一个大胆的想法,交换函数哪儿还用这么麻烦还要用指针,这个想法还真没问题。

利用引用变量来直接完成swap函数

void swap4(int & x,int & y){
	int temp;
	temp = x;
	x = y;
	y = temp;
}

void main(){
	int a=3, b=5;
	printf("交换前:a=%d,b=%d\n",a,b);
	swap(a,b);
	printf("交换后:a=%d,b=%d\n",a,b);
}
// 输出结果:
交换前a=3,b=5
交换后a=5,b=3
请按任意键继续. . .

但是引用变量在C语言中使用好像和C语言文件的后缀有关系,.cpp文件可以成功编译。不管怎样我们最终的目的并不是单纯的写一个可以实现值交换的函数,而是理解C语言函数的值传递机制。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-10-04 12:40:48  更:2021-10-04 12:41:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/29 4:22:53-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计