当前位置: 首页 > news >正文

c语言:指针作为参数传递

探究实参与形参它们相互独立

由于主调函数的变量ab与被调函数的形参xy它们相互独立。函数 swap 可以修改变量xy,但是却无法影响到主调函数中的ab

现在利用取地址运算符,分别打印它们的首地址,让我们从内存的角度,来分析一下它们。

a在内存中为首地址10484860开始的 sizeof(int) 字节。

b在内存中为首地址10484856开始的 sizeof(int) 字节。

x在内存中为首地址10484832开始的 sizeof(int) 字节。

y在内存中为首地址10484836开始的 sizeof(int) 字节。

调用 swap 函数时,a的值1,传给xb的值2,传给y。

图中,红色数值为数据对象首地址,黑框内的为变量名和值。

即使xy已经交换了,但是并未影响ab 


将指针作为参数传递

由于在被调函数内部无法直接修改主调函数的变量。那么我们采用迂回战术,在函数 main 中取得ab 的指针。将两个指针传递到函数 swap 。那么,在函数 swap 内部可以根据这两个信息修改ab

这下,我们就需要用到指针类型作为参数了。

现在将 x y 改为了 int * 类型的指针。在主调函数中,对 a b 进行取地址获取指针并传入函

swap 。在函数 swap 内部,通过这两个指针交换目标数据对象的值。注意,不是交换指针xy的值, 而是交换目标数据对象ab的值。所以,需要在指针前使用取值运算符*

图中,红色数值为数据对象首地址,黑框内的为变量名和值。

现在终于能解释为何在使用 scanf 函数时,需要对变量先取地址再传入参数了。

int n; scanf("%d", &n);

scanf 会从读取从键盘的输入,转换后存储到变量n当中。被调函数 scanf 无法直接修改在主调函数中的变量n。因此,我们将变量n的指针传入 scanf 函数。通过指针使得被调函数间接地修改主调函数中的变量。


指针不仅仅是首地址

再次强调,指针内保存的不仅仅是目标数据对象首地址,指针的类型也非常重要。要在内存中找到一个数据对象,需要有以下两个信息。

  1. 数据对象的首地址
  2. 数据对象占用存储空间大小

指针的值保存着数据对象首地址,指针类型对应着目标数据对象的类型,用于标记目标数据对象的空间大小和指针运算时的步长。

char * ,目标数据对象大小为 sizeof(char) 。运算时,步长为sizoef(char)。

short * ,目标数据对象大小为 sizeof(short) 。运算时,步长为sizoef(short)

int * ,目标数据对象大小为 sizeof(int) 。运算时,步长为sizoef(int)

long * ,目标数据对象大小为 sizeof(long) 。运算时,步长为sizoef(long)

long long * ,目标数据对象大小为 sizeof(long long) 。运算时,步长为sizoef(long long)

float * ,目标数据对象大小为 sizeof(float) 。运算时,步长为sizoef(float)

double * ,目标数据对象大小为 sizeof(double) 。运算时,步长为sizoef(double)

若要用函数 swap 交换两个int类型的变量,必须传入指向这两个int类型变量的指针。函数内部可以通过指针知道对象的首地址和类型。但是,这样也使得函数 swap ,只能交换int类型的变量了。

如果,想让函数 swap 函数更加通用一点,可以交换更多类型的变量。应该怎么做呢?


仅有首地址的指针类型void *

由于指针类型定死了指针所指向的数据类型。为了让函数可以交换更多的数据类型,我们仅需要指针类型中保存的首地址,目标数据大小通过额外的参数传入。

void swap(void *x, void *y, int size)

int * 修改为 void * 。类型为 void * 的指针仅保存首地址,不保存目标数据对象的空间大小。所以, 不能对 void * 类型的指针进行取值。同样的,它也没有步长,所以不能对 void * 类型的指针进行加减运算。

int n;

void *p = &n;   // int *赋值给void *,类型信息被丢弃,仅保存首地址。

*p;     // 仅有首地址,未保存目标数据对象大小,无法取值。

p + 1; // 仅有首地址,没有步长,无法进行加减运算。

但是, void * 有一个好处,那就是任意类型的指针都可以直接赋值给它。而其他类型的指针是不能相互赋值的,由于赋值会改变目标数据对象的类型。

char *pc; int *pn;

pc = pn;    // 编译出错,目标数据对象类型不同,无法直接赋值。

void *p;

p = pn;     // 编译通过,任意类型的指针都可以直接赋值给它。

p = pc;     // 编译通过,任意类型的指针都可以直接赋值给它。

规律

  1. 不同指针类型不能相互赋值,相互赋值后会造成目标数据对象类型的改变,无法通过编译。
  2. void * 类型为特例,它可以接受任意指针类型的赋值,也可以赋值给任意类型的指针。

我们将函数定义修改为:

void swap(void *x, void *y, int size)

{

// 指针转为char *,单个字节操作内存

char *pX = (char *)x; char *pY = (char *)y; char temp;

for (int i = 0; i < size; i++)

{

temp = pX[i]; pX[i] = pY[i]; pY[i] = temp;

}

}

由于 void * 不能取值和加减,所以我们将其转换为 char * char * 可以提供单个单个操作内存的能力。

C语言中 void * 类型不但可以接受任意类型的指针,也可以自动转换为任意类型的指针。

但在C++中,规则稍微严格了一点, void * 仅能接受任意类型的指针,不能自动转换为其他类型的指针。为了保证代码的兼容性,我们将 void * 强制转为 char * ,避免在C++中编译出错。

char *pX = (char *)x; char *pY = (char *)y;

相关文章:

c语言:指针作为参数传递

探究实参与形参它们相互独立 由于主调函数的变量a&#xff0c;b与被调函数的形参x&#xff0c;y它们相互独立。函数 swap 可以修改变量x&#xff0c;y&#xff0c;但是却无法影响到主调函数中的a&#xff0c;b。 现在利用取地址运算符&#xff0c;分别打印它们的首地址&#x…...

YOLOv5性能评估指标->mAP、Precision、Recall、FPS、Confienc (讲解论文关注的主要指标)

简介 这篇博客&#xff0c;主要给大家讲解我们在训练yolov5时生成的结果文件中各个图片及其中指标的含义&#xff0c;帮助大家更深入的理解&#xff0c;以及我们在评估模型时和发表论文时主要关注的参数有那些。本文通过举例训练过程中的某一时间的结果来帮助大家理解&#xf…...

陶建辉在 CIAS 2023 谈“新能源汽车的数字化”

近年&#xff0c;中国的新能源汽车发展迅猛&#xff0c;在全球竞争中表现出色&#xff0c;已经连续 8 年保持全球销量第一。在新兴技术的推动下&#xff0c;新能源汽车的数字化转型也正在加速进行&#xff0c;从汽车制造到能源利用、人机交互&#xff0c;各个环节都在进行数字化…...

PSP - 结构生物学中的机器学习 (NIPS MLSB Workshop 2023.12)

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/135120094 Machine Learning in Structural Biology (机器学习在结构生物学中) 网址&#xff1a;https://www.mlsb.io/ Workshop at the 37th Co…...

某领先的集成电路研发中心:建立跨网交换平台 杜绝数据泄露风险

1、客户介绍 某技术领先的集成电路研发中心&#xff0c;是产学研合作的国家级集成电路研发中心&#xff0c;致力于解决重大共性技术的研发及服务支撑问题。该中心积极探索国际化道路&#xff0c;不断提升国际影响力&#xff0c;与多家国际著名集成电路企业和研发机构建立技术合…...

map|动态规划|单调栈|LeetCode975:奇偶跳

作者推荐 【贪心算法】【中位贪心】.执行操作使频率分数最大 涉及知识点 单调栈 动态规划 map 题目 给定一个整数数组 A&#xff0c;你可以从某一起始索引出发&#xff0c;跳跃一定次数。在你跳跃的过程中&#xff0c;第 1、3、5… 次跳跃称为奇数跳跃&#xff0c;而第 2、…...

从安全性角度,看“可信数字底座”有何价值

文章目录 每日一句正能量前言概念对比安全技术对比思考与建议 每日一句正能量 不管现在有多么艰辛&#xff0c;我们也要做个生活的舞者。 前言 万向区块链此前提出“可信数字底座”这一概念和技术&#xff0c;即将区块链与物联网、人工智能、隐私计算等数字化技术相融合&#…...

软件设计模式:UML类图

文章目录 前言一、&#x1f4d6;设计模式概述1.软件设计模式的产生背景2.软件设计模式3.设计模式分类 二、&#x1f4e3;UML图1.类图概述2.类的表示法3.类与类之间的关系关联关系&#xff08;1&#xff09;单向关联&#xff08;2&#xff09;双向关联&#xff08;3&#xff09;…...

力扣题目学习笔记(OC + Swift)15. 三数之和

15. 三数之和 给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足 nums[i] nums[j] nums[k] 0 。请 你返回所有和为 0 且不重复的三元组。 注意&#xff1a;答案中不可以包含重复的三元…...

想将电脑屏幕共享到iPhone上,但电脑是Linux系统,可行吗?

常见Windows系统或macOS系统的电脑投屏到手机&#xff0c;难道Linux系统的电脑要投屏就是个难题吗&#xff1f; 想要将Linux系统投屏到iPhone、iPad、安卓设备、鸿蒙设备&#xff0c;其实你可以利用软件AirDroid Cast和Chrome浏览器&#xff01;连接同一网络就可以直接投屏。 第…...

大华 DSS 城市安防数字监控系统 SQL 注入漏洞

漏洞简介 大华DSS数字监控系统itcBulletin接口对传入的数据没有预编译和充足的校验&#xff0c;导致该接口存在SQL注入漏洞&#xff0c;可通过注入漏洞获取数据库敏感信息。 资产测绘 app“dahua-DSS” 漏洞复现 POC: POST /portal/services/itcBulletin?wsdl HTTP/1.1 H…...

vue中的侦听器和组件之间的通信

目录 一、侦听器 监听基本数据类型&#xff1a; 监听引用数据类型&#xff1a; 计算属性和watch区别&#xff1f; 二、组件通信/传值方式 1.父子组件传值 父组件给子组件传值&#xff1a; &#xff08;1&#xff09;props &#xff08;2&#xff09;provide inject &…...

maven-shade-plugin有什么用

maven-shade-plugin 是 Maven 的一个插件&#xff0c;用于创建可执行的 JAR 文件&#xff0c;并且可以将所有依赖项打包到一个 JAR 文件中。 该插件的主要用途是创建包含所有依赖项的“fat” JAR&#xff08;也称为“uber” JAR&#xff09;&#xff0c;使得应用程序可以作为一…...

本地部署 OpenVoice

本地部署 OpenVoice OpenVoice 介绍Qwen-Audio Github 地址部署 OpenVoice克隆代码库创建虚拟环境使用 pip 安装 pytorch使用 pip 安装依赖下载 checkpoint运行 Web UI OpenVoice 介绍 通过 MyShell 进行即时语音克隆。 Qwen-Audio Github 地址 https://github.com/myshell-…...

【模式识别】解锁降维奥秘:深度剖析PCA人脸识别技术

​&#x1f308;个人主页&#xff1a;Sarapines Programmer&#x1f525; 系列专栏&#xff1a;《模式之谜 | 数据奇迹解码》⏰诗赋清音&#xff1a;云生高巅梦远游&#xff0c; 星光点缀碧海愁。 山川深邃情难晤&#xff0c; 剑气凌云志自修。 目录 &#x1f30c;1 初识模式识…...

大模型赋能“AI+电商”,景联文科技提供高质量电商场景数据

据新闻报道&#xff0c;阿里巴巴旗下淘天集团和国际数字商业集团都已建立完整的AI团队。 淘天集团已经推出模特图智能生成、官方客服机器人、万相台无界版等AI工具&#xff0c;训练出了自己的大模型产品 “星辰”&#xff1b; 阿里国际商业集团已成立AI Business&#xff0c;…...

深度比较(lodash 的 isEqual 方法)

_.isEqual() 是 Lodash 提供的一个函数&#xff0c;用于比较两个值是否相等。它会递归地比较两个对象的属性和值&#xff0c;以判断它们是否相等。 这个函数的作用是&#xff1a; 深度比较对象&#xff1a;递归比较两个对象的每一个属性和嵌套对象的属性&#xff0c;判断它们…...

Ansible常用模块详解(附各模块应用实例和Ansible环境安装部署)

目录 一、ansible概述 1、简介 2、Ansible主要功能&#xff1a; 3、Ansible的另一个特点&#xff1a;所有模块都是幂等性 4、Ansible的优点&#xff1a; 5、Ansible的四大组件&#xff1a; 二、ansible环境部署&#xff1a; 1、环境&#xff1a; 2、安装ansible&#…...

QT中网络编程之发送Http协议的Get和Post请求

文章目录 HTTP协议GET请求POST请求QT中对HTTP协议的处理1.QNetworkAccessManager2.QNetworkRequest3.QNetworkReply QT实现GET请求和POST请求Get请求步骤Post请求步骤 测试结果 使用QT的开发产品最终作为一个客户端来使用&#xff0c;很大的一个功能就是要和后端服务器进行交互…...

Java 并发编程 —— Fork/Join 框架的原理详解

目录 一. 前言 二. 并发和并行 2.1. 并发 2.2. 并行 2.3. 分治法 三. ForkJoin 并行处理框架的理论 3.1. ForkJoin 框架概述 3.2. ForkJoin 框架原理 3.3. 工作窃取算法 四. ForkJoin 并行处理框架的实现 4.1. ForkJoinPool 类 4.2. ForkJoinWorkerThread 类 4.3.…...

3-10岁孩子语文能力培养里程碑

文章目录 基础能力3岁4岁5岁6-7岁&#xff08;1-2年级&#xff09;8-9岁&#xff08;3-4年级&#xff09;10岁&#xff08;5年级&#xff09; 阅读推荐&父母执行3岁4-5岁6-7岁&#xff08;1-2年级&#xff09;8-9岁&#xff08;3-4年级&#xff09;10岁&#xff08;5年级&a…...

Vue+ElementUi 基于Tree实现动态节点添加,节点自定义为输入框列

VueElementUi 基于Tree实现动态节点手动添加&#xff0c;节点自定义为输入框列 代码 <el-steps :active"active" finish-status"success" align-center><el-step title"test1"/><el-step title"test2"/><el-st…...

Web前端-JavaScript(js数组和函数)

文章目录 1.数组1.1 数组的概念1.2 创建数组1.3 获取数组中的元素1.4 数组中新增元素1.5 遍历数组 2.函数2.1 函数的概念2.2 函数的使用函数声明调用函数函数的封装 2.3 函数的参数函数参数语法函数形参和实参数量不匹配时 2.4 函数的返回值2.4.1 案例练习 2.5 arguments的使用…...

判断数据是否为整数--函数设计与实现

#定义函数&#xff1a;is_num(s),判断输入的数据是否整数。 #(1)判断是否是数字 def is_num(s):if s.isdigit(): #isdigit()是一个字符串方法&#xff0c;用于检查字符串是否只包含数字字符。如果字符串只包含数字字符&#xff0c;则返回True&#xff1b;否则返回Falsereturn T…...

netty源码:(29)ChannelInboundHandlerAdapter

它实现的方法都有一个ChannelHandlerContext参数&#xff0c;它的方法都是直接调用ChannelHandlerContext参数对应的方法&#xff0c;该方法会调用下一个handler对应的方法。 可以继承这个类&#xff0c;重写感兴趣的方法,比如channelRead. 这个类有个子类&#xff1a;SimpleC…...

Shell脚本应用(二)

一、条件测试操作 Shell环境根据命令执行后的返回状态值〈$?&#xff09;来判断是否执行成功&#xff0c;当返回值为О时表示成功.否则〈非О值)表示失败或异常。使用专门的测试工具---test命令&#xff0c;可以对特定条件进行测试&#xff0e;并根据返回值来判断条件是否成立…...

Kafka基本原理及使用

目录 基本概念 单机版 环境准备 基本命令使用 集群版 消息模型 成员组成 1. Topic&#xff08;主题&#xff09;&#xff1a; 2. Partition&#xff08;分区&#xff09;&#xff1a; 3. Producer&#xff08;生产者&#xff09;&#xff1a; 4. Consumer&#xff08;…...

使用Python爬取GooglePlay并从复杂的自定义数据结构中实现解析

文章目录 【作者主页】&#xff1a;吴秋霖 【作者介绍】&#xff1a;Python领域优质创作者、阿里云博客专家、华为云享专家。长期致力于Python与爬虫领域研究与开发工作&#xff01; 【作者推荐】&#xff1a;对JS逆向感兴趣的朋友可以关注《爬虫JS逆向实战》&#xff0c;对分布…...

前后端分离下的鸿鹄电子招投标系统:使用Spring Boot、Mybatis、Redis和Layui实现源码与立项流程

在数字化时代&#xff0c;采购管理也正经历着前所未有的变革。全过程数字化采购管理成为了企业追求高效、透明和规范的关键。该系统通过Spring Cloud、Spring Boot2、Mybatis等先进技术&#xff0c;打造了从供应商管理到采购招投标、采购合同、采购执行的全过程数字化管理。通过…...

ChatGPT 有什么新奇的使用方式?

来看看 OpenAI 内部是如何使用 ChatGPT 的。 目前&#xff08;4月29日&#xff09;距离ChatGPT发布了已经半年&#xff0c;这期间大家基本上把能想到的ChatGPT的使用方法都研究遍了——从写作、写代码&#xff0c;到翻译、英语润色&#xff0c;再到角色扮演等等。 所以&#x…...

网站建设淄博/如何免费创建自己的网站平台

AQS即队列同步器AbstractQueuedSynchronizer&#xff08;以下简称同步器&#xff09;&#xff0c;是用来构建锁或者其他同步组件的基础框架。 AQS使用了一个int成员变量表示同步状态。 AQS通过内置的FIFO双向队列来完成获取锁线程的排队工作 同步器包含两个节点类型的应用&…...

微信如何做模板下载网站/百度快照搜索引擎

说明&#xff1a; 有时候服务器是内网服务器&#xff0c;无法连接互联网&#xff0c;即无法使用互联网的yum源&#xff0c;这是如果安装salt的话会有一点麻烦&#xff0c;下面说下我是怎么做的。 第一步&#xff1a;使用虚拟机或者可以联网的服务器安装一遍salt&#xff0c;安装…...

曲靖手机网站建设/网络营销专业如何

Java RMI基础Java远程方法调用&#xff0c;即Java RMI&#xff08;Java Remote Method Invocation&#xff09;是Java编程语言里&#xff0c;一种用于实现远程过程调用的应用程序编程接口。它使客户机上运行的程序可以调用远程服务器上的对象。远程方法调用特性使Java编程人员能…...

云南网站建设优选平台/长沙seo关键词

1 .责任分配矩阵展示项目资源在各个&#xff08;&#xff09;中的任务分配&#xff1f; A.工作包 B.项目活动 4 .在虚拟团队环境中&#xff0c;&#xff08;&#xff09;规划变得日益重要&#xff1f; A.资源 B.沟通 参考答案 A B...

龙岗做棋牌网站建设/谷歌推广开户

这两天体检&#xff0c;抽了下血给我这营养不良抽的浑身无力...刚开始可能String用到的比较多&#xff0c;但是String可能不适用于很多情况&#xff0c;于是就写一下StringBuilder和StringBuffer。Java平台提供了两种字符串类型&#xff1a;String和StringBuffer、StringBuilde…...

多多在线免费观看电视剧/搜索引擎优化的方法包括

简介 PSO(粒子群算法)是群智能算法的一种&#xff0c;其他的群智能算法还有蚁群算法&#xff0c;遗传算法等。其他的智能算法还有模拟退火。之前看过一段时间的PSO&#xff0c;商务智能课程最后的大作业便想用一下&#xff0c;刚好在github上看到有人用模拟退火解决TSP…...