C语言有参函数调用时参数间数据传递问题

2023-10-30

C语言有参函数调用时参数间数据传递问题

C语言中在发生有参函数调用时,实参变量与形参变量之间的数据都是单向的“值传递”方式。包括指针变量和数组名作参数的情况。

C语言要求函数的实参要有确定的值,在函数调用时给形参分配相应的内存单元,同时将实参的“值”赋(复制)给形参,实现数据从实参到形参的传递(‘值传递’方式)。因为是复制,所以在操作副本(形参)过程中不会影响到原本(实参)内容。

首先,作为函数实参的量包括常量、变量和表达式。其中变量又包括简单变量、数组元素、数组名、指针变量等。不同类型变量作参数实现的数据传递方式相同,效果不同。所谓方式相同即都是参数间数据单向的“值传递”,效果不同是指被调函数能否改变主调函数中变量的值。

情况一:简单变量或数组元素作为函数参数

数组元素本身属于简单变量,在向形参传递数据时,根据前述规则只需将变量中的“值”复制一份放到形参变量中去操作,此时在被调用函数中操作的对象(形参)与实参并不在同一内存单元,并且在调用结束后形参所占内存单元被释放,因此调用函数不会影响到实参变量的值。同时被调函数也不会影响到主调函数中其他变量的值。

例:1
#include<stdio.h>
void main()
{
int a=1,f(int a);
printf("%d%d",a,f(a));
}
f(int a)
{
return(++a);
}
例2
#include<stdio.h>
void main()
{
int a[3]={1,2,3},f(int a);
printf("%d%d",a[0],f(a[0]));
}
f(int a)
{
return(++a);
}

情况二:指针变量或数组名作为函数参数

1.指针变量作函数参数

指针变量作实参在调用时仍然符合前述“值传递”规则,将其“值”赋给形参,相当于复制。此时数据在实参与形参间传递仍是单向的,调用函数不会影响实参的“值”(即指针变量中所存地址)。而与简单变量不同的是指针变量复制给形参的“值”本身是一个地址,这个地址为形参访问其所指变量创造了可靠条件。我的理解是,实参是一个抽屉的钥匙,在传参时,实参复制了一把钥匙传给形参。而被调函数拿到钥匙副本后,进行的操作可以分为两类:1、对钥匙本身做了一些操作(对指针本身进行操作);2、通过钥匙对抽屉里的内容进行了一些操作( 对指针所指的变量进行操作);两种操作都不可能影响实参的值(即钥匙原本),却有可能改变实参所指向变量的值(即抽屉里的内容)。

例1
#include<stdio,h>
void main()
{
void swap(intp1,intp2);
int a,b;
int pointer1,intpointer2;
scanf("%d,%d",&a,&b);
pointer1=&a; pointer2=&b;
if(a<b) swap(pointer1,pointer2);
printf("%d,%d",a,b);
}
void swap(intp1,intp2)
{
int temp;
temp=p1;
p1=p2;
p2=temp;
}
例2
#include<stdio,h>
void main()
{
void swap(int
p1,int
p2);
int a,b;
int pointer1,intpointer2;
scanf("%d,%d",&a,&b);
pointer1=&a; pointer2=&b;
if(a<b)
swap(pointer1,pointer2);
printf("%d,%d",a,b);
}
void swap(int
p1,int
p2)
{
int temp;
temp=p1;
p1=p2;
p2=temp;
}

2.数组名作函数参数

数组名本身是一个特殊的指针变量,其值是数组的首地址,因此作实参时其传给形参的是内存中某指定单元的地址,调用过程中形参数组与实参数组占用同一段内存单元,因此对形参数组的操作也就是对实参数组的操作,对实参数组与形参数组来说数据传递表现为“双向”的,而对实参变量与形参变量而言数据的传递仍然是单向的。


#include<stdio,h>
void main()
{
int a[3]={1,2,3};
void f(int a[]);
f(a);
for(i=0;i<3;i++)
printf("%d",a[i]);
}
void f(int a[])
{
for(i=0;i<3;i++)
a[i]++;
}

情况三:引用作为函数参数:

首先申明引用和指针最大的不同是:应用本身不是变量,不存在自己的变量空间,引用只是一个作为变量别名的标志。

引用必须依托于一个已实际存在的变量,正如一个人的如果连正名都没有,就无所谓小名了。正因为引用只是为了方便为同一个变量所取的小名,所以在任何地方通过引用对变量的操作和通过变量名进行操作的结果是一样的。

综上,当引用作为函数参数时,对形参的操作既是对原变量的操作,可以改变实参的值。效果上虽然和通过指针改变实参一样,但两种机制完全不同,引用并没有另开辟其它空间,直接对“原本”进行了操作,节省了时间和空间。

(拓)结构体数组作函数参数

用结构体数组作函数参数包含两类情况:结构体数组元素作实参和结构体数组名作实参。两类情况仍然服从数据的单向传递原则只不过前者传给形参的是某些变量的值,后者传给形参的是结构体数组的首地址。

1.结构体数组元素作实参

符合结构体变量作实参规则,采取单向“值传递”方式将结构体变量所占的内存单元的内容全部顺序复制给形参(函数调用期间形参也要占用内存单元)。注意当实参的成员中包含数组时形参相应的成员接受到的是一个地址。

2.结构体数组名实参

同整形数组数组名作实参一样传递给形参的是内存中已指定单元的地址,调用过程中形参数组与实参数组占用同一段内存单元,因此对形参数组的操作也就是对实参数组的操作。对数组的操作表现为双向性。

综上所述,对于有参函数调用时,实参变量与形参变量之间的数据都是单向的“值传递”方式。至于调用过程中是否会改变主调函数中变量的值,则只需根据具体算法看被调函数是否会找到主调函数中变量所在内存单元并对其原本进行操作。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C语言有参函数调用时参数间数据传递问题 的相关文章

  • seata 1.4.2 无法注册到 nacos2.1.1

    问题 使用docker 部署seata 一直出现数据库连接异常 异常 com mysql cj jdbc exceptions CommunicationsException Communications link failure nett
  • 电机速度曲线规划_S曲线

    导读 电机驱动是很常见的应用 在很多系统中都会碰到需要改变电机的速度以实现相应的控制功能 这就涉及到电机速度曲线规划的问题 本文仅代表记录自己的学习理解 如有错误 欢迎指正 想要S型速度曲线规划的仿真模块的学友请关注公众号 浅谈电机控制 留
  • 一个成熟期货交易系统需要解决哪些问题?

    一个成熟期货交易系统需要解决哪些问题 交易系统绝对不仅仅是时机选择 资金管理 情绪控制这么简单 他是一个系统性的思维 交易系统是一组包含了入场信号 风险控制 资金管理 加减仓机制 可以没有 离场方式等等基本元素的的规则组合 成熟的交易系统是
  • AngularJS概述&指令

    AngularJS 指令 AngularJS 应用组成如下 View 视图 即 HTML Model 模型 当前视图中可用的数据 Controller 控制器 即 JavaScript 函数 可以添加或修改属性 指令 描述 ng app 定
  • android studio cmake 编译找不到ninja解决方案

    https forum cocos com t android studio cmake ninja 77324
  • 偶数斐波那契数列

    斐波那契数列中的每一项都是前两项的和 由和开始生成的斐波那契数列的前项为 1 2 3 5 8 13 21 34 55 89 考虑该斐波那契数列中不超过四百万的项 求其中为偶数的项之和 解题思路 这里我们要是用for循环肯定会超过范围 所以我
  • 警告:隐式声明函数‘xxx’ [-Wimplicit-function-declaration]

    在c编译中 出现此类警告的原因 没有声明原始函数 一般的解决方式 在程序前面增加函数头说明即可 否则是用默认说明 隐式说明 来解释函数调用规则 比如返回值默认是int就是在你不说明时起作用的 以下是摘录的比较好的一篇说明 点击打开链接 1
  • HTML空格占位符 空行,整理,待以后查看

    32 普通的英文半角空格 160 nbsp xA0 no break space 普通的英文半角空格但不换行 12288 中文全角空格 一个中文宽度 8194 ensp en空格 半个中文宽度 8195 emsp em空格 一个中文宽度 8
  • java跨库分页_微服务架构跨库分页解决的四种方案

    引言 微服务架构是一项在云中部署应用和服务的新技术 大部分围绕微服务的争论都集中在容器或其他技术是否能很好的实施微服务 而红帽说API应该是重点 微服务可以在 自己的程序 中运行 并通过 轻量级设备与HTTP型API进行沟通 关键在于该服务
  • JS代码延时执行

    延时执行代码使用window对象的setTimeout函数 第一个参数为要延时执行的代码 第二个参数为延时时间 毫秒单位 例子
  • css置灰属性 模糊属性 滤镜遮罩属性 (一行代码实现)

    网站一行代码置灰 原因都知道 是为了纪念一位伟人 这种把整个页面都变成灰色 下面是css便捷属性 置灰实现方式 filter grayscale 1 效果 模糊度实现方式 filter blur 5px 效果 最后一种是 backdrop
  • 程序员必会的git语法及gitlab、github应用

    文章目录 3分钟掌握git语法及gitlab github应用 关于作者 作者介绍 前言 一 控制版本 1 1 什么是版本 1 2 什么是控制版本 1 3 版本管理工具 二 git 版本管理 2 1 git 介绍 2 2 git 安装 2
  • VSCode下使用markdown导出pdf,导出图片或插入LaTeX公式等使用记录(1)

    记录一下自己觉得比较好用的markdown插件 以及在VSCode下编辑并将markdown的渲染结果导出pdf为或png等格式 1 Markdown All in One VSCode下的markdown插件 目前这个用起来比较丝滑 而且
  • 微服务架构下的移动架构实践

    转载本文需注明出处 EAII企业架构创新研究院 违者必究 如需加入微信群参与微课堂 架构设计与讨论直播请直接回复此公众号 加群 姓名 公司 职位 微信号 大家好 我是普元信息移动产品的负责人 郝振明 很高兴又与大家见面了 今天和大家分享的主
  • 怎么使用51单片机实现人脸识别?

    使用 51 单片机实现人脸识别可以通过以下步骤来实现 准备必要的硬件设备 包括 51 单片机 摄像头和相应的连接线 安装并配置相应的开发环境 如 Keil IAR 等 准备人脸识别所需的人脸数据库 这可以通过手动收集人脸图像并进行标记来实现
  • linux内核态和用户态(通俗易懂)

    一 内核态 用户态概念 内核态 也叫内核空间 是内核进程 线程所在的区域 主要负责运行系统 硬件交互 用户态 也叫用户空间 是用户进程 线程所在的区域 主要用于执行用户程序 二 内核态和用户态的区别 内核态 运行的代码不受任何限制 CPU可
  • 在为水质担忧吗?——水质检测大屏展示系统启动(inscode直观运行)

    前言 作者主页 雪碧有白泡泡 个人网站 雪碧的个人网站 推荐专栏 java一站式服务 React从入门到精通 前端炫酷代码分享 从0到英雄 vue成神之路 uniapp 从构建到提升 从0到英雄 vue成神之路 解决算法 一个专栏就够了 架
  • 动态规划法求解编辑距离问题

    问题描述 设A和B是两个字符串 现在要用最少的字符操作次数 将字符串A转换为字符串B 这里所说的字符操作共有3种 1 删除一个字符 2 插入一个字符 3 将一个字符替换另一个字符 例如 A sfdqxbw B gfdgw 结果为4 问题求解
  • STM32超声波模块测距

    特别注意 单独t link只能提供3 3v电压 模块接5v电压只能收到3 3V 供电的时候请接上micro口 模块介绍 HC SR04超声波模块可提供2cm 400cm的距离感测功能 测量精度可以达到3mm 通过声音340m s t 2可以
  • TCP3次握手连接协议和4次握手断开连接协议

    TCP IP 状态机 如下图所示 在TCP IP协议中 TCP协议提供可靠的连接服务 采用三次握手建立一个连接 如图1所示 SYN包表示标志位syn 1 ACK包表示标志位ack 1 SYN ACK包表示标志位syn 1 ack 1 1 第

随机推荐

  • 关于stm32f429的MDA2D的M2M模式

    LTDC的使用问题 可参考官方例程的配置 需要注意的是 它只是一个LCD控制器 需要定义缓存的地址 可以设置在flash里 但是不便于操作 一般还是建议设置外部SDRAM里 LTDC中DMA2D的使用问题 429中LTDC的2D加速功能还比
  • 记Tomcat删除war包问题

    由于不清楚tomcat部署原理 误认为tomcat部署完成之后 可以把war删除 然后以后每次部署 只需要增量部署就行了 然后还怕由于war包的存在 增量部署的内容会被覆盖掉 不清楚war包什么时候会自动重新部署 于是 rm rf mm w
  • Python将.py文件打包成.exe可执行文件

    1 安装Pyinstaller库 pip install pyinstaller 2 在 py文件的所在文件夹Shift 右键 打开后输入pyinstaller F 要打包的文件名称 例如Mqtt py F参数表示覆盖打包 如果有旧的会覆盖
  • [电路设计]按键方案

    电路设计 按键方案 本文记录和介绍几种按键解决方案 包括普通按键 按键编码电路 ADC按键的工作原理 1 普通按键 一般使用的按键原理图如下图所示 由按键 上拉电阻和消抖滤波电容组成 按键断开时 K e y I i n
  • 级数求和公式

    级数求和公式是用于求解有限的或无限的等差 等比数列的总和 它的一般形式为 Sn a1 a2 a3 an 其中 a1 为该级数的首项 an 为该级数的末项 Sn 表示该级数的和 1 如果是有限等差数列 其求和公式为 Sn n a1 an 2
  • Spring Cloud Eureka注册中心组件搭建

    第一步 Idea 新建spring boot项目 选中Cloud 中 Eureka Server 第二部 配置文件 将application application 后缀改为application yml 也可以不修改 我是用的yml 粘贴
  • 计算机指令格式

    计算机的指令格式与机器的字长 存储器的容量及指令的功能都有很大的关系 从便于程序设计 增加基本操作并行性 提高指令功能的角度来看 指令中应包含多种信息 但在有些指令中 由于部分信息可能无用 这将浪费指令所占的存储空间 并增加了访存次数 也许
  • idea中处理依赖注入爆红问题

    1 这是idea里的编译异常 这里会出现依赖注入爆红的情况 有以下两种方式 1 1 方式一 在进行注入的时候 并没有UserMapper这个接口 所以爆异常 解决方式 需要创建一个UserMapper接口并交给Spring容器管理 1 2
  • 【转】伺服电机三环控制的原理(位置环,运动环,电流环)

    运动伺服一般都是三环控制系统 从内到外依次是电流环速度环位置环 1 首先电流环 电流环的输入是速度环PID调节后的那个输出 我们称为 电流环给定 吧 然后呢就是电流环的这个给定和 电流环的反馈 值进行比较后的差值在电流环内做PID调节输出给
  • 剑指offer(C++版本)

    剑指offer c 版本 二维数组查找 替换空格 从尾到头打印链表 重建二叉树 用两个栈实现队列 旋转数组的最小数字 斐波那契数列 跳台阶 矩阵覆盖 二进制1的个数 数值的整数次方 调整数组顺序使奇数位于偶数前面 链表中倒数第k个结点 反转
  • 【ANN预测】基于遗传算法优化 ANN附matlab代码

    作者简介 热爱科研的Matlab仿真开发者 修心和技术同步精进 matlab项目合作可私信 个人主页 Matlab科研工作室 个人信条 格物致知 更多Matlab仿真内容点击 智能优化算法 神经网络预测 雷达通信 无线传感器 电力系统 信号
  • qt在windows下交叉编译arm架构程序

    1
  • 《Kubernetes部署篇:Ubuntu20.04基于二进制安装安装kubeadm、kubelet和kubectl》

    一 背景 由于客户网络处于专网环境下 使用kubeadm工具安装K8S集群 由于无法连通互联网 所有无法使用apt工具安装kubeadm kubelet kubectl 当然你也可以使用apt get工具在一台能够连通互联网环境的服务器上下
  • 单淘汰赛制两队相遇算法

    对于这种单循环赛制acm也是常遇到这样的题那么 对于这样的比赛我们要怎么模拟所有的可能是一个问题 我们如何判断两个队在某一轮是否会遇到呢 我们其实可以利用二进制的性质 设某一轮比赛为i 求j和k两只队伍是否能比赛 下面我们用二进制来表示队伍
  • vp8-vp9-ivf文件格式

    经常遇到ivf格式 下面看看它的头 typedef struct ivf header 0 3 固定的 DKIF 字符串 4 5 version 应该为0 6 7 header的字节长度 8 11 编码器的FourCC e g VP80 1
  • 在内嵌窗口中调用父窗口的javascript代码

    noname1 html noname2 html
  • 【原创】【硬件电路】AltiumDesigner18规则检查含义

    文章首发于同名微信公众号 DigCore 欢迎关注同名微信公众号 DigCore 及时获取最新技术博文 Layout时最常用的错误检查 这需要在布局布线前做好规则设置 所谓磨刀不误砍柴工 尤其是在Layout时 如果违反规则 就会亮起绿色
  • vue.config.js配置详解

    1 vue inspect rule 命令获取vue config js中的chainWebpack配置项 2 vue inspect rule svg 筛选配置项 const path require path function reso
  • Rattle :基于R的数据挖掘工具(3):载入数据

    数据 数据是进行数据挖掘工作的基础 要是没有数据 那也就没什么可挖的了 当今时代 数据的丰富超乎想象 它可以是数字 也可以是文本 图像 声音 视频等各种形式的存在 但是要把数据变成知识和信息 并不是一件简单的事 关于数据的一般术语 一个数据
  • C语言有参函数调用时参数间数据传递问题

    C语言有参函数调用时参数间数据传递问题 C语言中在发生有参函数调用时 实参变量与形参变量之间的数据都是单向的 值传递 方式 包括指针变量和数组名作参数的情况 C语言要求函数的实参要有确定的值 在函数调用时给形参分配相应的内存单元 同时将实参