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

2023-12-19

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

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

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

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

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

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

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

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

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

即使 x y 已经交换了,但是并未影响 a b


将指针作为参数传递

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

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

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

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

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

现在终于能解释为何在使用 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;

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

c语言:指针作为参数传递 的相关文章

  • socket网络编程几大模型?看看CHAT是如何回复的?

    CHAT回复 网络编程中常见的有以下几种模型 1 阻塞I O模型 Blocking I O 传统的同步I O模型 一次只处理一个请求 2 非阻塞I O模型 Non blocking I O 应用程序轮询调用socket相关函数检查请求 不需
  • 软件测试|使用Python读写yaml文件,你会了吗?

    简介 YAML YAML Ain t Markup Language 是一种可读的数据序列化格式 它常用于配置文件和数据交换 Python 提供了许多库来处理 YAML 文件 在本文中 我们将探讨如何使用 PyYAML 库来读取和写入 YA
  • 软件测试|教你如何使用Python绘制出奥运五环旗

    简介 我们之前介绍过使用turtle来绘制正多边形 但是绘制正多边形只是turtle模块最基础的使用 我们可以使用turtle模块绘制出更多不一样的精彩图形 本文就来给大家介绍一个比较简单的turtle绘图实例 绘制奥运五环旗 初始化参数
  • 基于java的学生成绩在线管理系统设计与实现

    基于java的学生成绩在线管理系统设计与实现 I 引言 A 研究背景和动机 基于Java的学生成绩在线管理系统设计与实现的研究背景和动机是设计一个可以方便管理学生成绩的系统 该系统可以方便地记录学生的成绩 并为老师和学生提供查询和统计功能
  • 【计算机毕业设计】电商个性化推荐系统

    伴随着我国社会的发展 人民生活质量日益提高 于是对电商个性化推荐进行规范而严格是十分有必要的 所以许许多多的信息管理系统应运而生 此时单靠人力应对这些事务就显得有些力不从心了 所以本论文将设计一套电商个性化推荐系统 帮助商家进行商品信息 在
  • 【gee】下载modis土地利用类型

    var china ee FeatureCollection projects assets china boundary var lc dataset ee ImageCollection MODIS 061 MCD12Q1 filter
  • Hutool改变我们的coding方式(二)

    Hutool改变我们的coding方式 Hutool 简介 Hutool如何改变我们的coding方式 文档 安装 Maven
  • 计算机Java项目|springboot校园台球厅人员与设备管理系统

    作者简介 Java领域优质创作者 CSDN博客专家 CSDN内容合伙人 掘金特邀作者 阿里云博客专家 51CTO特邀作者 多年架构师设计经验 腾讯课堂常驻讲师 主要内容 Java项目 Python项目 前端项目 人工智能与大数据 简历模板
  • 计算机Java项目|在线图书管理

    作者简介 Java领域优质创作者 CSDN博客专家 CSDN内容合伙人 掘金特邀作者 阿里云博客专家 51CTO特邀作者 多年架构师设计经验 腾讯课堂常驻讲师 主要内容 Java项目 Python项目 前端项目 人工智能与大数据 简历模板
  • 计算机Java项目|电影购票系统

    作者简介 Java领域优质创作者 CSDN博客专家 CSDN内容合伙人 掘金特邀作者 阿里云博客专家 51CTO特邀作者 多年架构师设计经验 腾讯课堂常驻讲师 主要内容 Java项目 Python项目 前端项目 人工智能与大数据 简历模板
  • 春眠不觉晓,Java数据类型知多少?基础牢不牢看完本文就有数了

    俺滴座右铭是不在沉默中爆发 就在沉默中灭亡 一起加油学习 珍惜现在来之不易的学习时光吧 等工作之后 你就会发现 想学习真的需要挤时间 厚积薄发啦 我们知道Java是面向对象的静态型编程语言 在Java的世界里万物皆对象 但我认为是万物皆数据
  • 计算机Java项目|基于SpringBoot个人空间平台的设计与实现

    作者简介 Java领域优质创作者 CSDN博客专家 CSDN内容合伙人 掘金特邀作者 阿里云博客专家 51CTO特邀作者 多年架构师设计经验 腾讯课堂常驻讲师 主要内容 Java项目 Python项目 前端项目 人工智能与大数据 简历模板
  • 详解toLowerCase(判断字符串相等)

    一 toLowerCase 函数简介 toLowerCase 是一个在多个编程语言中都存在的字符串方法 它的作用是将字符串中的所有大写字母转换为对应的小写字母 常用于文本处理 搜索和比较等情况 以确保字符串的一致性和非大小写敏感的操作 二
  • 【go语言】读取toml文件

    一 简介 TOML 全称为Tom s Obvious Minimal Language 是一种易读的配置文件格式 旨在成为一个极简的数据序列化语言 TOML的设计原则之一是保持简洁性 易读性 同时提供足够的灵活性以满足各种应用场景 TOML
  • 用栈实现队列(OJ中报错的处理)

    用栈实现队列 ERROR AddressSanitizer myQueueFree函数中栈的释放处现了问题 没有调用StackDestory而是直接free了 这个是栈初始化时 capacity与malloc申请的空间大小没有匹配 请你仅使
  • 基于节点电价的电网对电动汽车接纳能力评估模型研究(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码 数据
  • 基于节点电价的电网对电动汽车接纳能力评估模型研究(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码 数据
  • 初学者如何快速入门Python(内附详细攻略),一文讲清

    目前python可以说是一门非常火爆的编程语言 应用范围也非常的广泛 工资也挺高 未来发展也极好 Python究竟应该怎么学呢 我自己最初也是从零基础开始学习Python的 给大家分享Python的学习思路和方法 一味的买书看书 看视频 是
  • 计算机Java项目|有机蔬菜商城

    作者简介 Java领域优质创作者 CSDN博客专家 CSDN内容合伙人 掘金特邀作者 阿里云博客专家 51CTO特邀作者 多年架构师设计经验 腾讯课堂常驻讲师 主要内容 Java项目 Python项目 前端项目 人工智能与大数据 简历模板
  • 在 Python 中实现 List 抽象

    在 Python 中 创建一个包含多个对象的 list 很常见 例如 对于一组具有相同功能的对象 比如播放声音 希望能够使用类似 my list play 的语法来触发 list 中所有对象的 play 方法 另一个例子是 当希望关闭 li

随机推荐

  • DTO/DO/VO分层与拷贝

    作者简介 大家好 我是smart哥 前中兴通讯 美团架构师 现某互联网公司CTO 联系qq 184480602 加我进群 大家一起学习 一起进步 一起对抗互联网寒冬 这一篇其实没太多实质内容 本来不打算写的 但想到当初从传统通信行业跳到互联
  • 迪普防火墙开局登录

    文章内容来自迪普官方 产品文档 杭州迪普科技股份有限公司
  • H3C 交换机指示灯说明

    端口模式指示灯 mode 为了使用户通过交换机各类型端口的 端口状态指示灯 能够获取更多的设备信息 本系列交换机 S5560S 28F EI 和 S5560S 52F EI 除外 的同一个 10 100 1000BASE T 自适应以太网端
  • H3C AC双链路备份基本组网典型配置举例

    1 6 1 双链路备份基本组网典型配置举例 1 组网需求 AP 通过 Router A 与 AC 1 和 AC 2 连接 要求使用双链路备份对 AC 进行备份 AC 1 工作在主用状态 AC 2 工作在备用状态 当 AC 1
  • 基于SpringBoot+Vue的科研项目验收管理系统设计实现(源码+lw+部署文档+讲解等)

    文章目录 前言 详细视频演示 具体实现截图 技术栈 后端框架SpringBoot 前端框架Vue 持久层框架MyBaitsPlus 系统测试 系统测试目的
  • AWS解决方案架构师学习与备考

    系列文章目录 送书第一期 用户画像 平台构建与业务实践 送书活动之抽奖工具的打造 获取博客评论用户抽取幸运中奖者 送书第二期 Spring Cloud Alibaba核心技术与实战案例 送书第三期 深入浅出Java虚拟机 送书第四期 AI时
  • 2015,TEVC,Adaptive MOPSO Based on Parallel Cell Coordinate System

    Abstract 在多目标粒子群优化 MOPSO 的设计中 管理收敛性和多样性是至关重要的 以搜索真实Pareto最优前沿的准确和良好分布的近似 粒子群优化算法由于其快速收敛性 在进化过程中会导致多样性的快速丢失 现有的MOPSOs在 le
  • OneNote笔记使用记录

    1 快捷键 2 快速设置行距 Ctrl 1 设置一倍行距 Ctrl 2 两倍行距 Ctrl 5 1 5 倍行距 3 切换样式标题 Ctrl Alt 1 标题 1 Ctrl Alt 2 标题 2 Ctrl Alt 3 标题 3 Ctrl Sh
  • vtk用户指南 第十一章 随时间变化的数据

    11 1时序支持简介 创建可视化工具包的目的是允许人们可视化 从而探索具有空间范围的数据中的特征 它允许人们回答一些问题 比如 在这些数据中 最大价值的区域在哪里 它们有什么形状和价值 以及 这些形状是如何分布的 VTK提供了大量的技术来显
  • 阿里云一二级域名配置

    一级域名配置 二级域名配置
  • 2023中国品牌节金谱奖荣誉发布 酷开科技获颁OTT行业科技创新奖

    11月17日 19日 以 复苏与腾飞 为主题的2023第十七届中国品牌节 在杭州市云栖小镇国际会展中心成功举行 在18日晚间的荣耀盛典上 TopBrand 2023中国品牌节金谱奖 荣誉发布 酷开科技斩获OTT行业科技创新奖 酷开科技作为O
  • 面试150-13(Leetcode238除自身以外数组的乘积)

    代码 class Solution public int productExceptSelf int nums int n nums length int res new int n int product 1 int zerocnt 0
  • 再看参数校验

    作者简介 大家好 我是smart哥 前中兴通讯 美团架构师 现某互联网公司CTO 联系qq 184480602 加我进群 大家一起学习 一起进步 一起对抗互联网寒冬 写一个接口 大致就几个步骤 参数校验 编写Service Dao SQL
  • 如何开发一个免费的App

    开发一个免费App意味着能够在项目启动初期 以更低成本的方式进行业务的迭代和市场化验证 互联网发展到2023年 尤其在生成式AI及大模型技术 跃进式 增长的背景下 一个创新式商业模式的起步变得异常艰难 但如果用好工具 那么不仅能事半功倍 还
  • 网络安全设备概念的熟悉和学习

    什么是网络安全 网络安全技术有哪些 Web应用防火墙 WAF 为什么需要WAF 什么是WAF 与传统防火墙的区别 WAF不是全能的 入侵检测系统 IDS 什么是IDS 跟防火墙的比较 部署位置选择
  • 【网络安全】—Shell编程入门(1)

    文章目录 基础 变量概念介绍 特殊变量进阶 数值计算实践 条件测试比较 条件判断语句 流程控制语句 循环语句应用
  • threejs 解析外部模型关键帧动画

    参考资料 threejs中文网 threejs qq交流群 814702116 解析外部模型关键帧动画 前面几节课 用到的关键帧动画 是借助threejs提供的两个类 KeyframeTrack AnimationClip 自己写代码实现
  • SQL Server 大数据量分页

    1 ROW NUMBER OVER 方式 SQL2012以下推荐使用 SELECT FROM SELECT ROW NUMBER OVER ORDER BY menuId AS RowId FROM sys menu AS r WHERE
  • “jar“:CreateProcess error = 2,系统找不到指定的文件

    起因 系统配置的java环境为jar 或java环境不完整导致 修复 将jar exe拷贝至java环境的bin目录中即可
  • c语言:指针作为参数传递

    探究实参与形参它们相互独立 由于主调函数的变量 a b 与被调函数的形参 x y 它们相互独立 函数 swap 可以修改变量 x y 但是却无法影响到主调函数中的 a b 现在利用取地址运算符 分别打印它们的首地址 让我们从内存的角度 来分