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语言==>传值调用和传址调用是什么?二者有何区别? -> 正文阅读

[C++知识库]初识C语言==>传值调用和传址调用是什么?二者有何区别?

今天学习C语言的时候,接触到了两个全新的概念
话不多说,就此和大家分享一下c语言中函数的传调用和传调用,希望有所帮助
欢迎dalao无情指正

引子 : 交换函数

我们先来写一个简单的函数

目的是交换a和b

#include <stdio.h>
int main()
{
	int a = 10;
	int b = 20;
	int tmp = 0;
	printf("a=%d b=%d\n", a, b);//显示a和b最初的值
	tmp = a;
	a = b;
	b = tmp;
	printf("a=%d b=%d\n", a, b);//查看交换结果
	return 0;
}

运行的结果如图

在这里插入图片描述
需要注意的是,这是在主函数main里面直接进行的交换程序,而我们想要的其实是一个可以在任何地方使用的交换函数

#include <stdio.h>
int main()
{
	int a = 10;
	int b = 20;
	printf("a=%d b=%d\n", a, b);
	swap1(a, b);
	printf("a=%d b=%d\n", a, b);
	return 0;
}

若想达成以上目的,我们要先把上述代码优化成以下形式。其中swap1就是我们即将要写的自定义函数

void swap1(int x, int y)
{
	int tmp = 0;
	tmp = x;
	x = y;
	y = tmp;
}
  • void表示自定义函数无返回类型

这个自定义函数看起来没什么问题对吧!

但是结果却告诉我们a和b并没有被交换

在这里插入图片描述

这是为什么?

查错方法

这里给大家介绍一个老师教授的查错方法。虽然我估计大家都知道(小声bb)

那就是用vs编译器自带的监视器了(快捷键f10,我用的是最新的vs2019,官网即可免费下载使用)

在这里插入图片描述

  • 左边有个很Q的黄色小箭头,告诉你正在监视那一步
  • 每按一次f10代码就会往下走一行
  • 当遇到swap此类函数时,按f11进入函数,f10会直接跳过函数

在这里插入图片描述

可以看到代码在第25行的时候,x和y已经获得了a和b的值,tmp此时为0

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A6AjR3UI-1628935108900)(C:\Users\S2522\AppData\Roaming\Typora\typora-user-images\image-20210814162153683.png)]

下一行继续,tmp变成10

在这里插入图片描述

再下一行,x获得y的值,x=20

在这里插入图片描述

然后y获得tmp里面保存的x的值,y=10

在这里插入图片描述

可当我们下一步跳出函数,回到主函数的时候

会发现a和b仍然是10和20,并没有发生交换
在这里插入图片描述

聪明的你肯定已经想到这是为什么了

函数中的x和y与主函数的a和b是独立的,x和y的变化无法影响a和b

那怎么样函数中的x和y才能影响函数外的a和b,从而达到我们交换的目的呢?

这里需要涉及一个新的大家都知道的概念

& 取地址操作符

先用一个简单的例子让大家了解&取地址操作符的作用

在我们的c语言中,每个字符都对应了一个它独自的地址

而&符号就是取出这个字符的地址

int main()
{
	int a = 10;
	int* pa = &a;//pa指针变量
	*pa = 20;//解引用操作
	printf("%d\n", *pa);
	return 0;
}

这里面的*pa获取了a的地址,在打印的时候会顺着地址找到a,显示a的结果

让我们继续

我们将上述交换函数代码的主函数改成如下形式

int main()
{
	int a = 10;
	int b = 20;
	printf("a=%d b=%d\n", a, b);
    //swap1(a, b);
	swap2(&a, &b);
	printf("a=%d b=%d\n", a, b);
	return 0;
}

比较swap1和swap2,会发现swap2括号中的a和b前面都多了一个**&操作符**

这个操作符会让swap2不再读取a和b的数值,即10和20

而是会读取a和b在内存中的地址

相对应的,swap2函数也要改成如下形式

其实形式和swap1基本一样,只是x和y被替换成了**pa 与 pb

void swap2(int* pa, int* pb)
{
	int tmp = 0;
	tmp = *pa;
	*pa = *pb;
	*pb = tmp;
}
  • *表明 pa和pb都是指针变量
  • pa和pb保存的是a和b的地址

这时候我们再运行代码,a和b被很好的调换了

我们的目的也达成了

在这里插入图片描述

实参和形参

要想了解为什么两个函数会有这样的不同

我们需要学习实参(实际参数)和形参(形式参数)
在这里插入图片描述

void swap1(int x, int y)
{
	int tmp = 0;
	tmp = x;
	x = y;
	y = tmp;
}

void swap2(int* pa, int* pb)
{
	int tmp = 0;
	tmp = *pa;
	*pa = *pb;
	*pb = tmp;
}

int main()
{
	int a = 10;
	int b = 20;
	printf("a=%d b=%d\n", a, b);
	//swap1(a, b);
	swap2(&a, &b);
	printf("a=%d b=%d\n", a, b);
	return 0;
}

在这串代码中,a和b是实参

x、y、*pa、 *pb都是形参

可以借用另外一个代码的例子进一步给大家了解实参

int get_max(int x, int y)
{
	if (x > y)
		return x;
	else
		return y;
}
int main()
{
	int a = 10;
	int b = 20;
	int max = get_max(a, b); 
	printf("max= %d\n", max);
    max = get_max(100,300);
    max = get_max(100,300+1);//实参可以是表达式
	max = get_max(100, get_max(3, 5));//也可以是函数
	printf("max = %d\n", max);
	return 0;
}

在这串代码中,抛去上面的a和b

max = get_max(100,300);是我们使用这个函数的基本方式

  • 这里面的100和300是实参
  • 同时**300+1和get_max(3, 5)**也是实参
  • 对应的函数中的x和y就是形参

当实参传给形参的时候
形参其实是实参的一份临时拷贝
对形参的改变是不会改变实参的

这样解释大家应该对实参和形参有一定的认识了

接下来就有请我们的标题人物隆重登场

传值调用,传址调用

这两个调用方式十分重要,而且两个字从读音到长相(bushi)都十分相似

所以大家一定要注意区分!
在这里插入图片描述

简而言之

当我们需要在函数内部操作函数外部的变量的时候→传址调用

如果我们只需要外部变量的值,不需要改变外部变量→传值调用

以上面的交换函数为例子

void swap1(int x, int y)//传值调用
{
	int tmp = 0;
	tmp = x;
	x = y;
	y = tmp;
}

void swap2(int* pa, int* pb)//传址调用
{
	int tmp = 0;
	tmp = *pa;
	*pa = *pb;
	*pb = tmp;
}

因为swap1里面的x和y是传值调用,x和y只获取了a和b的值,自然无法影响函数外面的a和b

而swap2中的*pa 和 *pb获取的是a和b的地址(址→地址)所以可以影响函数外的a和b,实现它们的交换

注:x,y,*pa , *pb 都是局部变量,它们在出了函数外之后就无法使用,也失去了使用它们的意义

结束语

本篇小博客到这里也结束啦,感谢你看到最后!

如果感觉看完之后仍有不明白的地方

可以去观看这期视频里面的讲解,swap函数的讲解在1小时17分【点我跳转】

我也是刚学C语言的小白,博文有错在所难免,请各位大佬无情指正

这篇博文虽然字不多,但依旧花了我2小时的时间,如果觉得不错就点个赞再走吧!

求求了,跪谢!

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-15 15:19:21  更:2021-08-15 15:19:37 
 
开发: 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/26 17:11:01-

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