我的编程空间,编程开发者的网络收藏夹
学习永远不晚

你知道C语言函数调用常用的2种方式吗

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

你知道C语言函数调用常用的2种方式吗

本篇博客会讲解C语言函数调用的2种方式,分别是:传值调用和传址调用。这2种函数调用方式有什么区别呢?为什么会有不同的效果呢?分别有哪些用途呢?下面我会一一展开。

区别

传值调用,即通过传递变量的值来调用函数。

传址调用,即通过传递变量的地址来调用函数。

比如,假设有2个变量a和b,对于变量a和b来说test(a, b)就是传值调用,test(&a, &b)就是传址调用。

原理

这时你可能很好奇:这2种调用方式的原理是什么呢?其实非常简单。

先举个传值调用的例子:

// 函数定义
int Add(int x, int y)
{
	return x + y;
}
// 调用
int a = 3, b = 5;
int sum = Add(a, b);

在上面的代码中,我们分别把a和b的值传递给了Add函数中的x和y。此时,我们称:a和b是“实际参数”,简称实参;x和y是“形式参数”,简称形参。传值调用的方式,会把实参的值传递给形参,也就是说,把a中的3传递给x,此时x就是3,把b中的5传递给y,此时y就是5。在Add函数内部,把x+y的值带回来,也就返回3+5的值,即返回8,再把返回值赋值给sum,sum就是8。

再举个传址调用的例子:

// 函数定义
int Add(int* p1, int* p2)
{
	return *p1 + *p2;
}
// 调用
int a = 3, b = 5;
int sum = Add(&a, &b);

以上就是典型的传址调用,但是很显然在这个场景下,我们只想“求和”,使用传址调用有点多此一举,但是还是分析一下原理:我们把a和b的地址传给了p1和p2,此时p1存储了a的地址,p2存储了b的地址,p1就指向了a,p2就指向了b。我们想在Add函数内部求和,就要先对p1解引用,拿到a的值,再对p2解引用,拿到b的值,再把拿到的a和b的值加起来返回,此时sum就被赋值为函数的返回值,即8。

以上只是非常粗略的带大家了解了传值调用和传址调用的区别。下面用一个经典的例子进行更加深入的讲解。这个例子就是:写一个函数,交换2个整数的值。

使用传值调用的方式,写出来的函数如下:

// 定义
void Swap(int x, int y)
{
	int tmp = x;
	x = y;
	y = tmp;
}

// 调用
int a = 3, b = 5;
Swap(a, b);

下面我通过调试的方式,来带大家看一下这个程序会如何执行。

代码即将执行Swap(a, b);,此时a的值是3,b的值是5。接下来执行这条语句:

代码来到第17行,此时a和b的值并没有交换?到底发生了啥?

重新开始调试,这次我进入到Swap函数内部看一眼。

按照前面的分析,此时x和y拿到了a和b的值,接下来进行交换:

代码执行到第10行,此时可以发现,x和y其实已经交换了,但是a和b并没有变化?这又是为什么呢?

此时再回到main函数,发现a和b的值并没有被交换。

发现这个问题后,我们可以干一件事,使用下面的代码,把a、b、x、y的地址打印出来:

#include <stdio.h>
void Swap(int x, int y)
{
	printf("&x = %p, &y = %p\n", &x, &y);
	int tmp = x;
	x = y;
	y = tmp;
}
int main()
{
	int a = 3, b = 5;
	printf("&a = %p, &b = %p\n", &a, &b);
	Swap(a, b);
	return 0;
}

输出结果如下:

可以发现,当把a的值传递给x,把b的值传递给y时,x和y,a和b已经是不同的空间了,此时相当于,内存中有4个变量,分别是a、b、x、y,由于值传递,x的值和a相同,y的值和b相同,此时交换了x和y,对a和b的值并没有影响!所以函数调用结束后,a和b的值并没有交换。

这时,我们就可以总结:当我们使用传值调用,实参的值传递给形参后,形参只是实参的一份临时拷贝,改变形参的值并不影响实参的值!

那Swap函数的正确实现形式是怎样的呢?相信聪明的你已经想到了,使用传址调用就行了嘛!

// 定义
void Swap(int* p1, int* p2)
{
	int tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}
// 调用
int a = 3, b = 5;
Swap(&a, &b);

为什么以上的代码就能实现“交换”的效果呢?这就是传址调用的神奇之处!

分析一下:把a的地址传递给p1,把b的地址传递给p2,此时p1就指向了a,p2就指向了b,这时再对p1和p2解引用,就能把a和b的值给修改了!

我们还是通过调试来观察一下细节:

进入到函数内部:

再回到main函数:

成功交换了a和b的值!

用途

根据以上的讲解,可以总结一下传值调用和传址调用的用途:

  • 传值调用适用于不需要修改函数外部变量的场景。
  • 传址调用适用于需要修改函数外部变量的场景。

这是因为,传值调用时,形参是实参的一份临时拷贝,改变形参并不影响实参,所以在函数内部没有能力改变外面的变量的值;传址调用就不一样了,形参保存了函数外部变量的地址,就可以通过解引用的方式,修改函数外部变量的值了。

总结

1.传值调用适用于不需要修改函数外部变量的场景,因为函数内部变量和外部变量并没有建立联系,是独立的空间。

2.传址调用适用于需要修改函数外部变量的场景,因为函数内部存储了指向函数外部变量的指针,建立了联系,可以通过解引用的方式改变函数外部的变量。

以上就是你知道C语言函数调用常用的2种方式吗的详细内容,更多关于C语言函数调用的资料请关注编程网其它相关文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

你知道C语言函数调用常用的2种方式吗

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

你知道C语言函数调用常用的2种方式吗

本篇博客会讲解C语言函数调用的2种方式,分别是:传值调用和传址调用。这2种函数调用方式有什么区别呢?为什么会有不同的效果呢?分别有哪些用途呢?下面就来一一展开
2023-05-18

JavaScript调用C语言的几种方式

本文主要介绍了JavaScript调用C语言的几种方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
2023-02-17

c++中的函数调用有哪几种方式

c++ 函数调用方式有五种:值传递、引用传递、指针传递、返回值、虚函数调用。值传递传递副本,不会影响实际参数;引用传递传递引用,修改参数会影响实际参数;指针传递传递地址,修改参数会影响实际参数;返回值函数返回给调用函数;虚函数调用特定于面向
c++中的函数调用有哪几种方式
2024-05-01

c语言调用子函数的方法是什么

在C语言中,调用子函数的方法可以通过以下步骤实现:1. 首先,在主函数或其他需要调用子函数的函数中,声明子函数的原型。原型包括子函数的返回类型、函数名和参数列表。```c// 子函数的原型返回类型 函数名(参数列表);```2. 然后,在主
2023-10-08

c语言子函数调用的方法是什么

在C语言中,可以使用以下两种方法调用子函数:1. 值传递(Call by Value):将实参的值复制给形参,子函数中对形参的修改不会影响实参的值。```c// 声明子函数void func(int);// 调用子函数int main()
2023-09-13

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录