C语言函数中的传值和传指针到底有什么区别

strongerHuang 2019-09-08 10:14 次阅读

函数传参有三种传参方式:传值、传址、传引用。

我们可能听过C语言中的传值和传指针,在其他语言中,也有传引用一说,那么他们到底有什么区别呢?如果你还不能准确地分辨,就该好好了解一下了。

传值

我们在初学C语言的时候就被老师教过,下面的方式是无法交换a和b的值的:

#include void swap(int a,int b) {     int temp = a;     a = b;     b = temp;     printf("swap a = %d,b = %d ",a,b); } int main(void) {     int a = 10;     int b = 20;     printf("before swap:a = %d,b = %d ",a,b);     swap(a,b);     printf("after  swap:a = %d,b = %d ",a,b);     return 0; }

运行结果如下:

before swap:a = 10,b = 20                                                                                                                                                                    internal swap a = 20,b = 10                                                                                                                                                                  after  swap:a = 10,b = 20 

可以看到,a和b的值最终并没有被交换。开始时a,b的值为10,20,而最终还是同样的值。

为什么呢?因为函数参数在传递的时候,都是传原数据的副本,也就是说,swap内部使用的a和b只是最初始a和b的一个副本而已,所以无论在swap函数内部对a和b做任何改变,都不会影响初始的a和b的值。

正因如此,我们常常被告知,不要把直接把结构体直接作为参数,这样效率会很低。由于结构体本身占用字节数较大,如果直接作为参数,那么将会产生一个较大的”副本“,如此一来,效率也就很低了。

我们再结合下面的图来理解:

值传递

首先图中方框中的上部分a和b代表了main函数中的a和b,即原始数据,而方框中的下部分a和b代表了函数的参数a和b,即原始数据的“副本”。(后面的图都是如此,上部分代表原始值,下部分代表函数参数值)。

调用swap函数前后的情形如下:

调用swap前后

由于在swap中永远只是对a和b的副本进行操作,因此完全不影响原始的a和b的值。最终也不可能达到交换a和b的值的目的。

传指针

那么为解决上面的问题,我们知道,需要传指针。其代码如下:

#include void swap(int *a,int *b) {     int temp = *a;     *a = *b;     *b = temp;     printf("swap a = %d,b = %d ",*a,*b); } int main(void) {     int a = 10;     int b = 20;     printf("before swap:a = %d,b = %d ",a,b);     swap(&a,&b);     printf("after  swap:a = %d,b = %d ",a,b);     return 0; }

运行结果:

before swap:a = 10,b = 20                                                                                                                                                                    swap a = 20,b = 10                                                                                                                                                                           after  swap:a = 20,b = 10 

可以看到在这种情况下,a,b的值才是真正交换了。

为什么又有传值,又有传指针

看到这里,不知道你是否会疑惑,为什么给函数传递参数的时候,一会是传值,一会是传指针呢?为什么传指针就能改变参数的值呢?实际上,C语言里,参数传递都是值传递!也就是说,你认为的传指针也是传值,只不过它的值是指针类型罢了。

我们再通过图来理解前面为什么传指针就可以交换a,b的值:

从图中可以看出,虽然传递给函数的是指向a和b的指针的副本,但是它的副本同样也是指向a和b,因此虽然不能改变指针的指向,但是能改变参数a和b指向的内容,即改变原始a和b的值。

再看传指针

如果是为指针p申请一段内存,下面的代码能达到目的吗?

#include #include void getMemery(int *p) {     /*申请1024个int大小*/     p = malloc(sizeof(int)*1024);     if(NULL == p)     {         printf("malloc failed ");         p = NULL;     } } int main(void) {     int *p = NULL;     getMemery(p);     printf("address of p is %p ",p);     return 0; }

通过前面的内容分析,肯定是达不到预期效果的。
运行结果:

address of p is (nil)

这是为什么呢?我们还是利用前面所知来分析,由于传递给getMemory函数的参数都是一个副本,因此函数内的p也是外部p的一个副本,因此即便在函数内部,将p指向了一块新申请的内存,仍然不会改变外面p的值,即p还是指向NULL。

getMemory

如何修改呢?我们需要传入p的地址,即指向int类型指针的指针。

#include #include void getMemery(int **p) {     /*申请1024个int大小*/     *p = malloc(sizeof(int)*1024);     if(NULL == *p)     {         printf("malloc failed ");         *p = NULL;     } } int main(void) {     int *p = NULL;     getMemery(&p);     printf("address of p is %p ",p);     free(p);     p = NULL;     return 0; }

运行结果如下:

address of p is 0x144f010

从运行结果可以看到,p的值被改变了,而不再是初始的NULL。

可配合下面的图进行理解:

getMemory

总结

本文总结如下:

函数的参数都是原数据的“副本”,因此在函数内无法改变原数据

函数中参数都是传值,传指针本质上也是传值

如果想要改变入参内容,则需要传该入参的地址(指针和引用都是类似的作用),通过解引用修改其指向的内容

以上结论不限于C语言

原文标题:C语言函数参数的传值和传指针有什么区别?

文章出处:【微信号:strongerHuang,微信公众号:strongerHuang】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
分享:

评论

相关推荐

云龙51单片机视频教程

目前国内公认的最好的视频教程,通俗易懂,容易上手,非常适合初学者,被大量的培训机构采用。只要你认真看,认真听,保证让你学
发表于 08-02 00:00 15156次 阅读
云龙51单片机视频教程

如何利用UCOS引发任务调度?

我看资料中的任务调度往往发生在程序延时中,程序释放CPU引发任务的调度,但是我希望程序能够更快的运行,不想使用延时函数,...
发表于 10-24 04:36 12次 阅读
如何利用UCOS引发任务调度?

keil编程stm32中出现错误该怎么办?

[C] 纯文本查看 复制代码 NVIC_INT_CTRL   EQU     0xE000ED04   ...
发表于 10-24 03:41 11次 阅读
keil编程stm32中出现错误该怎么办?

请求信号量的时候一直出现以下错误是怎么回事?

请求信号量的时候  一直出现这个错误 OSSemPend(Sem_DMARx,0,&err); if(err==OS_ERR_NONE) { ...
发表于 10-24 01:17 5次 阅读
请求信号量的时候一直出现以下错误是怎么回事?

如何得知是哪个对象触发了呢?

通过OSPendMulti函数等待多个内核对象,通过返回值可以知道多少个内核事件触发了 ,   如何得知是哪个对象触发了呢...
发表于 10-24 00:04 2次 阅读
如何得知是哪个对象触发了呢?

为什么UCOS III事件标志组Pend函数不能正常执行?

本人使用OSFlagPend函数等待一个事件标志组中的两个标志全部清零,按照以下写法出现了问题。当运行到该函数时,标志组的值为...
发表于 10-23 23:33 4次 阅读
为什么UCOS III事件标志组Pend函数不能正常执行?

请问谁有51单片机的音乐喷泉程序吗?

谁有关于51单片机的音乐喷泉的程序 c语言或者汇编的 急求谢谢...
发表于 10-23 23:27 2次 阅读
请问谁有51单片机的音乐喷泉程序吗?

请问程序卡死在OSTimeDlyHMSM函数里面是怎么回事?

为了学习UCOS我写了一个程序,有3个任务,其中任务一是按键扫描,任务二是图片显示,任务三是不停的闪烁LED,当KEY_U...
发表于 10-23 22:34 14次 阅读
请问程序卡死在OSTimeDlyHMSM函数里面是怎么回事?

请问C语言中volatile有的作用是什么?

C语言中volatile有什么用作用是什么? 看到一个数组,别人这样写: volatile unsigned short adc_dma_buf[40]; u32 ADCV...
发表于 10-23 22:16 10次 阅读
请问C语言中volatile有的作用是什么?

如何使用netconn进行编程最大接收字节数目?

小弟的程序是在原子的netconn webserver基础上进行修改的,但是配置文件没有修改. 当sever端和client端建立连接之后... server端...
发表于 10-23 20:54 5次 阅读
如何使用netconn进行编程最大接收字节数目?

为什么YouTask不能一直循环运行?

我的问题是:YouTask为啥不能一直循环运行?什么原因?谁能帮我解决了,我就给谁微信发10元红包。拜托各位大神了!代码压缩包见...
发表于 10-23 20:16 10次 阅读
为什么YouTask不能一直循环运行?

红外遥控器控制电机转动的C语言程序免费下载

本文档的主要内容详细介绍的是红外遥控器控制电机转动的C语言程序免费下载。
发表于 10-23 18:04 16次 阅读
红外遥控器控制电机转动的C语言程序免费下载

21天学通C语言PDF电子书免费下载

本书包括四周的课程,前三周详细介绍了C语言,第四周是附加课程,简要地介绍了最流行的面向对象语言--C....
发表于 10-21 08:00 54次 阅读
21天学通C语言PDF电子书免费下载

cdll和windll有什么不同

Python要想调用C语言写的动态连接库。不仅要兼容C接口的调用习惯,还须要兼容C语言的数据类型。幸....
发表于 10-20 09:42 25次 阅读
cdll和windll有什么不同

51单片机C语言程序设计教程PDF电子书和例程代码及课后作业

本书遵循由浅入深、循序渐进的原则,讲解单片机开发的必备知识以及开发经典案例。本书以Y L51 单片机....
发表于 10-18 17:46 124次 阅读
51单片机C语言程序设计教程PDF电子书和例程代码及课后作业

51单片机C语言入门学习杂记教程免费下载

学习单片机实在不是件易事,一来要购买高价格的编程器,仿真器,二来要学习编程语言,还有众多种类的单片机....
发表于 10-18 17:31 100次 阅读
51单片机C语言入门学习杂记教程免费下载

使用javascript修改onclick动作的四种方式详细实例说明

本文档的主要内容详细介绍的是使用javascript修改onclick动作的四种方式详细实例说明。 ....
发表于 10-18 16:56 46次 阅读
使用javascript修改onclick动作的四种方式详细实例说明

PIC单片机位域结构的应用解析

有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位。例如在存放一个开关量时,....
发表于 10-18 16:39 72次 阅读
PIC单片机位域结构的应用解析

学习嵌入式需要具备怎样的基础

驱动分为两种,一种是没有操作系统的驱动程序,也就是直接用c语言来对硬件进行编程,那么另外一种就是有操....
发表于 10-18 10:19 70次 阅读
学习嵌入式需要具备怎样的基础

电容触摸控制芯片FT5216的驱动C语言程序合集免费下载

本文档的与内容详细介绍的是电容触摸控制芯片FT5216的驱动C语言程序合集免费下载,IAR+MSP4....
发表于 10-18 08:00 57次 阅读
电容触摸控制芯片FT5216的驱动C语言程序合集免费下载

如何使用C#设置PDF页面旋转

在处理PDF文件,遇到一些页面是倒置的不便于阅读的情况时,我们希望通过一定方法来旋转这些页面。因此,....
发表于 10-17 17:46 55次 阅读
如何使用C#设置PDF页面旋转

矩阵化简的C语言程序免费下载

本文档的主要内容详细介绍的是矩阵化简的C语言程序免费下载。
发表于 10-17 16:38 60次 阅读
矩阵化简的C语言程序免费下载

n阶行列式计算C语言程序免费下载

本文档的主要内容详细介绍的是n阶行列式计算C语言程序免费下载。
发表于 10-17 16:38 78次 阅读
n阶行列式计算C语言程序免费下载

MATLAB绘图教程的实例总结免费下载

本文档的主要内容详细介绍的是MATLAB绘图教程的实例总结免费下载。
发表于 10-17 16:00 88次 阅读
MATLAB绘图教程的实例总结免费下载

LCD的C语言程序免费下载

 本文档的主要内容详细介绍的是LCD的C语言程序免费下载。
发表于 10-17 15:14 50次 阅读
LCD的C语言程序免费下载

NTC和PTC热敏电阻的详细资料简介

热敏电阻的基本电气特性是它们随其温度变化而改变电阻。它们不整定,也不产生信号,热敏电阻温度会随周围温....
发表于 10-17 14:24 108次 阅读
NTC和PTC热敏电阻的详细资料简介

LUA脚本的绘图API函数的使用方法及使用函数的注意事项

物联型串口屏通过 LUA 脚本配合工程可以完成大部分的内部逻辑处理,可以做到让 MCU 只参与数据处....
发表于 10-17 08:00 64次 阅读
LUA脚本的绘图API函数的使用方法及使用函数的注意事项

LUA如何实现回调函数的触发使用以及编写程序的注意事项

物联型串口屏通过 LUA 脚本配合工程可以完成大部分的内部逻辑处理,可以做到让 MCU 只参与数据处....
发表于 10-17 08:00 45次 阅读
LUA如何实现回调函数的触发使用以及编写程序的注意事项

LUA脚本API函数中的回调函数使用方法和注意事项资料和程序免费下载

本文档的主要内容详细介绍的是LUA脚本API函数中的回调函数使用方法和注意事项资料和程序免费下载。 ....
发表于 10-17 08:00 54次 阅读
LUA脚本API函数中的回调函数使用方法和注意事项资料和程序免费下载

如何使用LUA脚本在串口屏中实现简单的逻辑运算以及字符处理

物联型串口屏通过 LUA 脚本配合工程可以完成大部分的内部逻辑处理,可以做到让 MCU 只参与数据处....
发表于 10-17 08:00 64次 阅读
如何使用LUA脚本在串口屏中实现简单的逻辑运算以及字符处理

如何在LUA脚本中使用的定时器循环设置教程免费下载

本文将介绍在 LUA 脚本中使用定时器循环设置按钮的状态。在按下按钮后,定时器启动,定时器以设定的时....
发表于 10-16 08:00 55次 阅读
如何在LUA脚本中使用的定时器循环设置教程免费下载

100例C语言经典算法题目和实例程序免费下载

本文档的主要内容详细介绍的是100例C语言经典算法题目和实例程序免费下载。
发表于 10-15 17:01 110次 阅读
100例C语言经典算法题目和实例程序免费下载

Matlab工具箱应用指南信息工程篇PDF电子书免费下载

20 世纪60 年代以来随着计算机和信息科学的飞速发展信号处理逐渐发展成一门独立的学科成为信息科学的....
发表于 10-15 16:31 70次 阅读
Matlab工具箱应用指南信息工程篇PDF电子书免费下载

OpenCV库的特点和主要功能及实现光流方法的运动说明

序列图像的光流计算是计算机视觉研究领域运动估计的重要组成部分。本文介绍了OpenCV库的特点和主要功....
发表于 10-15 11:56 75次 阅读
OpenCV库的特点和主要功能及实现光流方法的运动说明

OpenCV如何在图像上绘制出矩形并标出起点的坐标详细资料说明

涉及到两方面的内容:1. 用鼠标画出矩形。2.在图像上绘制出点的坐标1. 用鼠标绘制矩形,涉及到鼠标....
发表于 10-15 11:54 69次 阅读
OpenCV如何在图像上绘制出矩形并标出起点的坐标详细资料说明

CH5XX芯片加密建议和C语言例程免费下载

本文档的主要内容详细介绍的是WCH5XX芯片在加密上的建议和C语言例程免费下载,保护自己的代码和固件....
发表于 10-15 08:00 113次 阅读
CH5XX芯片加密建议和C语言例程免费下载

STC89C52单片机的C语言进行文件分裂的工程文件免费下载

本文档的主要内容详细介绍的是STC89C52单片机的C语言进行文件分裂的工程文件免费下载。
发表于 10-14 08:00 66次 阅读
STC89C52单片机的C语言进行文件分裂的工程文件免费下载

数据结构与算法分析—C语言描述

《数据结构与算法分析:C语言描述》曾被评为20世纪顶尖的30部计算机著作之一,作者在数据结构和算法分....
发表于 10-14 08:00 62次 阅读
数据结构与算法分析—C语言描述

C语言与Matlab接口编程与实例PDF电子书免费下载

本书以简洁的语言、丰富的实例系统地介绍了C语言与MATLAB接口函数(称之为:CMEX函数)的编程....
发表于 10-14 08:00 61次 阅读
C语言与Matlab接口编程与实例PDF电子书免费下载

单片机C语言数组的详细实例程序应用介绍

 数组是由具有相同类型的数据元素组成的有序集合。数组是由数组名来表示的,数组中的数据由特定的下标来唯....
的头像 Wildesbeast 发表于 10-13 11:48 238次 阅读
单片机C语言数组的详细实例程序应用介绍

C语言抓取网页内容的常用类详细说明

C#是微软公司发布的一种面向对象的、运行于.NET Framework和.NET Core(完全开源....
发表于 10-12 14:58 100次 阅读
C语言抓取网页内容的常用类详细说明

热成像的伪彩色编码源代码免费下载

本文档的主要内容详细介绍的是热成像的伪彩色编码源代码免费下载。红外热成像中需要的将温度值转变为彩色的....
发表于 10-12 08:00 123次 阅读
热成像的伪彩色编码源代码免费下载

PID控制的原理和计算公式及实例代码总结

PID控制是比例控制、积分控制与微分控制的总称,是目前在工程领域应用范围最广的一种控制方法。在计算机....
发表于 10-11 15:47 123次 阅读
PID控制的原理和计算公式及实例代码总结

嵌入式学习需要具备哪一些知识的基础

c语言也被称为是上帝的语言,那么在嵌入式驱动当中是使用最广泛的语言开发。
发表于 10-11 15:05 78次 阅读
嵌入式学习需要具备哪一些知识的基础

NRF24L01的模块资料和C语言程序和使用与开发攻略合集免费下载

本文档的主要内容详细介绍的是NRF24L01的模块资料和C语言程序和使用与开发攻略合集免费下载包括了....
发表于 10-10 08:00 100次 阅读
NRF24L01的模块资料和C语言程序和使用与开发攻略合集免费下载

TMS320F2812 DSP的中文资料免费下载使用

TMS320F2812 数字讯号处理器是针对数字控制所设计的DSP,整合了DSP 及微控制器的最佳特....
发表于 10-10 08:00 515次 阅读
TMS320F2812 DSP的中文资料免费下载使用

单片机C语言编程的八个基本规则解析

在数字滤波中有一种叫做“去极值平均滤波”技术,就是对采集的数据按照从大到小或者从小到大进行排序,然后....
发表于 10-09 14:24 193次 阅读
单片机C语言编程的八个基本规则解析

PETSc科学计算可移植扩展工具包的用户手册免费下载

Portable, ExtensibleToolkit for Scientific Computa....
发表于 10-09 08:00 115次 阅读
PETSc科学计算可移植扩展工具包的用户手册免费下载

流畅的Python中文版PDF电子书免费下载

如果你是本书的目标读者,那你应该可以从本书的任意一章开始阅读,但是如果按照我写作时的构思来的话,本书....
发表于 10-09 08:00 79次 阅读
流畅的Python中文版PDF电子书免费下载

工程控制论钱学森版电子书免费下载

工程控制论的研究对象和理论范畴在不断扩大。近20年来该学科的各个方面都有了很大的发展。到目前为止,它....
发表于 10-09 08:00 114次 阅读
工程控制论钱学森版电子书免费下载

篮球计时计分器的C语言和工程文件免费下载

本文档的主要内容是使用单片机设计的篮球计时计分器的C语言和工程文件免费下载。
发表于 10-09 08:00 106次 阅读
篮球计时计分器的C语言和工程文件免费下载

使用Simulink进行S-Function建模的教程PPT课件免费下载

本文档的主要内容详细介绍的是使用Simulink进行S-Function建模的教程PPT课件免费下载....
发表于 10-08 08:00 48次 阅读
使用Simulink进行S-Function建模的教程PPT课件免费下载

机械系统动力学的大作业资料免费下载

本文档的主要内容详细介绍的是机械系统动力学的大作业资料免费下载。
发表于 10-08 08:00 59次 阅读
机械系统动力学的大作业资料免费下载

经典的信号与系统复习资料免费下载

本文档的主要内容详细介绍的是经典的信号与系统复习资料免费下载。
发表于 10-08 08:00 50次 阅读
经典的信号与系统复习资料免费下载

关于正弦函数和余弦函数的计算公式详细说明

本文档的主要内容详细介绍的是关于正弦函数和余弦函数的计算公式详细说明。
发表于 10-08 08:00 148次 阅读
关于正弦函数和余弦函数的计算公式详细说明

Keil编译的常见错误详细说明

本文档的主要内容详细介绍的是Keil编译的常见错误详细说明。
发表于 09-30 17:28 151次 阅读
Keil编译的常见错误详细说明

单片机C语言的400例程序合集免费下载

本文档的主要内容详细介绍的是单片机C语言的400例程序合集免费下载包括了:IO输出-点亮1个LED灯....
发表于 09-30 08:00 324次 阅读
单片机C语言的400例程序合集免费下载

单片机C语言中变量的定义方法解析

#pragma rambank0 ;即以关键词#pragma开始,rambank0指明资料区块为第0....
发表于 09-29 16:26 149次 阅读
单片机C语言中变量的定义方法解析

C程序设计语言第二版新版电子教材免费下载

本书是由C语言的设计者Brian W. Kernighan和Dennis M. Ritchie编写的....
发表于 09-29 08:00 180次 阅读
C程序设计语言第二版新版电子教材免费下载

MYSQL的用户定义函数UDF的培训教程免费下载

本文档的主要内容详细介绍的是MYSQL的用户定义函数UDF的培训教程免费下载。
发表于 09-29 08:00 122次 阅读
MYSQL的用户定义函数UDF的培训教程免费下载