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

指针 (四)

一 . 指针的使用和传值调用

(1)strlen 的模拟实现

库函数 strlen 的功能是求字符串长度,统计的是字符串中 ' \0 ' 之前的字符个数,函数原格式如下:

我们的参数 str 接收到一个字符串的起始地址,然后开始统计字符串中 ' \0 ' 之前的字符个数,最终返回长度。现在我们来模拟实现 strlen 函数,只要从起始地址开始,向后逐个遍历字符,每遇到一个字符,判断其是否为 ' \0 ',若不是,则计数器 + 1,是则停止

(2)传值调用和传址调用

这两个的区别,我们可以通过一道题深入理解:

写一个函数,交换两个整型变量的值:

1 . 传值调用:

上图就是传值调用,看似没有问题,但我们的运行结果却出乎了我们的意料,a、b 的值并没有按照我们预想的那样交换,这是为什么呢?我们可以通过调试中的监视来观察观察:

在上方两个调试的图中,我们可以看到,在我们的 Swap1 中,的的确确是将我们的 x、y 的值进行了交换,但是我们也可以看到,a、b (实参)的地址和 x、y (形参)的地址是截然不同的,这就证明,a、b 和 x、y 有着本质上的区别,我们改变的是在 Swap1 中的 x、y ,并不是我们想要改变的 a、b(地址不同,证明 a、b 和 x、y 向内存申请的空间并不是同一块空间,这两者之间没有必要联系

这里就引出一个重要概念:当实参传递给形参的时候,形参会单独创建一份临时空间来接收实参,对形参的修改不影响实参!!!

我们想要通过一个函数来达到交换变量值的目的,我们应该打破表象看本质,从变量的地址下手,用另一种方法——传址调用

1 . 传址调用:

如图,使用传址调用时,我们通过调试可以看到,a、b 和 *pa、*pb 的地址是一样的,通过地址去改变这两个变量的值,就可以从本质上去修改它俩的值

总结:传址调用,可以让函数和主调函数之间建立真正的联系,在函数内部可以修改主调函数中的变量;所以未来函数中只是需要主调函数中的变量值来实现计算,就可以采用传值调用;如果函数内部要修改主调函数中的变量的值,就需要传址调用

二 . 数组名的理解

之前我们提到过使用指针访问数组内容,我们知道了,数组名其本质就是首元素的地址,如下图:

这个时候就有小伙伴发出真挚的疑问了:讲道理,如果数组名就代表着首元素的地址,我们之前所见到的sizeof(arr)为什么是 40 而不是 4/8 呢?如下图:

这里呢就是我们的一个例外情况了哈,有关于数组名的使用有两个例外:(重点重点重点!!!)

(1)sizeof(数组名):当 sizeof ()中单独放置数组名,这里的数组名就表示整个数组,计算的是整个数组的字节大小

(2)& 数组名 :这里的数组名表示整个数组,取得是整个数组的地址(整个数组的地址与数组首元素的地址是有区别的)

&arr[0]和&arr[0]+1相差4个字节,arr 和 arr+1 相差4个字节,是因为 &arr[0] 和 arr 都是首元素的地址,+1就是跳过一个元素
&arr 和 &arr+1 相差40个字节,这就是因为&arr是数组的地址,+1 操作是跳过整个数组的

 三 . 指针访问数组

关键点的解读都在代码中为诸君做了注释,我就不过多赘述了

四 . 一维数组传参的本质

不知道大家有没有注意过,我们跟数组打了那么多次交道,sizeof()我们也用过多次,但我们一直都是在函数外部计算数组的元素个数,然后再通过传参的方式将 sz (元素个数)传递给函数。那么我们可不可以通过传参过来的数组直接在函数内部计算数组中的元素个数呢?不妨一试:

可以看到我们这个输出结果并不像我们预想的那样,问题就出在我们数组的传参上

在上面第二点我们提到过,数组名的本质是首元素地址。所以函数形参的部分理论上应该是使用指针变量来接收首元素的地址,那么在函数内部,我们这个时候使用 sizeof()计算的就不是一个数组的字节大小了,而是计算的一个地址的字节大小

不管我们怎么去传参,本质都是以指针形式表现的,如图:

总结:在函数内部我们使用sizeof()计算的都是对其首元素地址的字节大小(4 或 8由编译环境决定)。所以在函数内部是没法求数组的元素个数的

五 . 二级指针

众所周知,指针变量那也是变量,是变量就有地址,我们指针本身就是指向一个地址的,那么它本身作为一个变量而言,它的地址又存放在哪里呢?

这就是我们所谓的二级指针,这文字理解起来有点绕昂,跟俄罗斯套娃一样,咱们上图理解:

如图,这段代码的含义就是:

(1)创建了一个整型变量 a 并赋值为 10

(2)取出 a 的地址存放在指针(一级指针)pa 中

(3)同理再取出 pa 的地址存放在指针(二级指针)ppa 中

总结:二级指针的本质存放的就是一级指针的地址

文字、图片的表达能力终究有限,还望诸君见谅,自己细心一层一层地捋开指针之间的嵌套关系

六 . 指针数组

指针数组?到底是指针还是数组呢?一时半会捋不清的小伙伴们不妨类比一下我们学习过的知识:整型数组——存放整型的数组;字符数组——存放字符的数组

由此观之,指针数组就是用来存放指针的数组

指针数组当中的每一个元素都是一个指针,或者说每个元素都是指向内存中一块空间的地址

(1)指针数组模拟二维数组

不知道大家可还记得二维数组,我们可以先来回顾一下

想更仔细了解的,可以点链接查看我之前的博客哦,里面较为详细的介绍了二维数组的相关知识:二维数组 和 变长数组_变长二维数组-CSDN博客

接下来我们利用指针数组来模拟实现我们的二维数组:

前面提到过:指针数组就是用来存放指针的数组,我们这里三个数组——arr1、arr2、arr3,又新创建了一个 *parr ,而在这其中,将这三个数组放进去,又因为数组名就是首元素的地址,所以这里三个数组放到 parr 中时都是属于 int* 类型的指针,看下图更好理解:

应该注意的是:以上代码只是我们运用指针数组模拟实现的二维数组,并不是真正意义上的二维数组,因为它们的每一行并非连续的

这里没有什么生冷硬的知识,都是将我们学到过的知识点串联起来就可以得出,相信以诸君的聪明才智,定能轻松拿捏!

OKK,今天有关于指针的小部分知识就跟大家聊到这里,咱们下期再见咯。与诸君共勉!!!

相关文章:

指针 (四)

一 . 指针的使用和传值调用 (1)strlen 的模拟实现 库函数 strlen 的功能是求字符串长度,统计的是字符串中 \0 之前的字符个数,函数原格式如下: 我们的参数 str 接收到一个字符串的起始地址,然后开始统计…...

便利店(超市)管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图详细视频演示技术栈系统测试为什么选择我官方认证玩家,服务很多代码文档,百分百好评,战绩可查!!入职于互联网大厂,可以交流,共同进步。有保障的售后 代码参考数据库参…...

Excel中的“块”操作

在Excel中,有offset、index、indirect三个对“区域”操作的函数,是较高版本Excel中“块”操作的利器。 (笔记模板由python脚本于2024年08月20日 19:25:21创建,本篇笔记适合喜欢用Excel处理数据的coder翻阅) 【学习的细节是欢悦的历程】 Pytho…...

yolo V8训练 长条状目标

1、说明 目标数据集合中有很多长条状图片&#xff0c;如果直接Resize 会严重拉伸&#xff0c;因此采用把长条图像裁剪成2段&#xff0c;然后将裁剪后的2段图片拼接在一起。 2、代码 2.1 C 代码 &#xff08;部署&#xff0c;模型推理时C &#xff09; #include <stdio.h…...

数据结构与算法 - 设计

1. LRU缓存 请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。 实现 LRUCache 类&#xff1a; LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存int get(int key) 如果关键字 key 存在于缓存中&#xff0c;则返回关键字的值&#xff0…...

62 网络设备的暗藏的操控者SNMP

一 SNMP 简介 SNMP(Simple Network Management Protocol,简单网络管理协议)广泛用于网络设备的远程管理和操作。SNMP允许管理员通过NMS对网络上不同厂商、不同物理特性、采用不同互联技术的设备进行管理,包括状态监控、数据采集和故障处理。 二 SNMP 网络架构 NMS(Netwo…...

华硕飞行堡垒键盘全部失灵【除电源键】

华硕飞行堡垒FX53VD键盘全部失灵【除电源键】 前言一、故障排查二、发现问题三、使用方法总结 前言 版本型号&#xff1a; 型号 ASUS FX53VD&#xff08;华硕-飞行堡垒&#xff09; 板号&#xff1a;GL553VD 故障情况描述&#xff1a; 键盘无法使用&#xff0c;键盘除开机键外…...

前端字符串将其分割成长度为 32 的子字符串数组

技巧分享&#xff1a;将字符串切割后&#xff0c;对list数据进行数据处理 要实现这个需求&#xff0c;可以编写一个简单的 JavaScript 函数来处理字符串并将其分割成长度为 32 的子字符串数组。下面是一个具体的实现示例&#xff1a; function splitStringIntoChunks(str) {l…...

小学二年级数学精选试题

小学二年级数学精选试题...

练习题 - 探索正则表达式re功能

在编程的世界里,正则表达式(Regular Expression, 简称re)是一种强大的工具,它能帮助我们有效地处理文本数据。从简单的查找到复杂的字符串操作,正则表达式都能轻松应对。特别是在数据清理、文本分析以及自动化处理等场景中,正则表达式更是不可或缺的利器。本篇文章将深入…...

【Oracle 11G 配置使用教程1】

Oracle11G配置使用教程1 引言图像方式创建数据库一、打开 Database Configuration Assistant二、创建数据库操作三、选择数据库模版四、配置数据库标识五、配置数据库标识六、创建数据库 配置监听一、打开创建监听程序二、打开创建监听程序三、重新配置监听程序四、选择监听程序…...

【ubuntu24.04】docker pull 配置

Docker 镜像加速器 的方式,看起来不行。阿里云的要先登录。手动拉取tar包的方式,官方dockerhub看起来本身没提供。docker pull 的 代理与 环境变量的代理不同因此,docker pull gitlab/gitlab-ce:17.3.0-ce.0 使用了全局代理也会失败参考官方文档: Use a proxy server with …...

《机器学习》—— 通过下采样方法实现银行贷款分类问题

文章目录 一、什么是下采样方法&#xff1f;二、通过下采样方法实现银行贷款分类问题三、下采样的优缺点 一、什么是下采样方法&#xff1f; 机器学习中的下采样&#xff08;Undersampling&#xff09;方法是一种处理不平衡数据集的有效手段&#xff0c;特别是在数据集中某些类…...

Synchronized重量级锁原理和实战(五)

在JVM中,每个对象都关联这一个监视器,这里的对象包含可Object实例和Class实例.监视器是一个同步工具,相当于一个凭证,拿到这个凭证就可以进入临界区执行操作,没有拿到凭证就只能阻塞等待.重量级锁通过监视器的方式保证了任何时间内只允许一个线程通过监视器保护的临界区代码. …...

linux常用网络工具汇总三

linux常用网络工具汇总 6. 抓包工具6.1 wireshark安装界面介绍使用过滤器TCP协议示例关于wireshark的缺点 6.2 tcpdump命令格式关键字使用关于tcpdump的缺点 6.3 fiddler6.4 burpsuite 6. 抓包工具 6.1 wireshark Wireshark&#xff08;前称Ethereal&#xff09;是一个网络封…...

Linux中nano编辑器详解

nano 是一个简单的文本编辑器&#xff0c;通常预装在大多数 Linux 发行版中。它非常适合初学者使用&#xff0c;因为它有一个用户友好的界面和易于理解的命令集。下面是对 nano 编辑器的详细说明。 启动 nano 要启动 nano 并打开一个文件进行编辑&#xff0c;你可以在终端中输…...

26-vector arraylist和linkedlist的区别

‌Vector, ArrayList, 和 LinkedList 是Java中常见的三种列表实现&#xff0c;它们各自具有不同的特点和适用场景。‌ ‌同步性与线程安全‌&#xff1a; ‌Vector‌ 是同步的&#xff0c;即线程安全的&#xff0c;它的所有方法都是同步的&#xff0c;可以由两个线程安全地访问…...

20-redis穿透击穿雪崩

Redis中的缓存穿透、‌缓存击穿和缓存雪崩是三种常见的缓存问题&#xff1a;‌ 缓存穿透&#xff1a;‌指缓存和数据库中都没有的数据&#xff0c;‌但用户还是源源不断地发起请求&#xff0c;‌导致每次请求都会直接访问数据库&#xff0c;‌从而可能压垮数据库。‌缓存击穿&…...

Docker使用教程

Docker 名词解释 镜像&#xff08;image&#xff09;&#xff1a;Docker镜像就是一个模板&#xff0c;可以通过这个模板来创建容器服务。容器&#xff08;container&#xff09;&#xff1a;Docker利用容器技术&#xff0c;独立运行一个或者一组应用&#xff0c;通过镜像创建…...

poi-tl循环放图片+文字说明

这几天有个任务&#xff0c;服务端导出word要求从数据库取到多张图片&#xff0c;然后输出到word中&#xff0c;并且说明一共几张&#xff0c;当前是第几张。 网上翻了很久也没有找到示例&#xff0c;不过最终难题还是得到了攻克。 因为之前的代码是有一个导出的map&#xff0c…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析

这门怎么题库答案不全啊日 来简单学一下子来 一、选择题&#xff08;可多选&#xff09; 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘&#xff1a;专注于发现数据中…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1

每日一言 生活的美好&#xff0c;总是藏在那些你咬牙坚持的日子里。 硬件&#xff1a;OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写&#xff0c;"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

【HTML-16】深入理解HTML中的块元素与行内元素

HTML元素根据其显示特性可以分为两大类&#xff1a;块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战

在现代战争中&#xff0c;电磁频谱已成为继陆、海、空、天之后的 “第五维战场”&#xff0c;雷达作为电磁频谱领域的关键装备&#xff0c;其干扰与抗干扰能力的较量&#xff0c;直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器&#xff0c;凭借数字射…...

大数据学习(132)-HIve数据分析

​​​​&#x1f34b;&#x1f34b;大数据学习&#x1f34b;&#x1f34b; &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 用力所能及&#xff0c;改变世界。 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4…...

.Net Framework 4/C# 关键字(非常用,持续更新...)

一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...

基于matlab策略迭代和值迭代法的动态规划

经典的基于策略迭代和值迭代法的动态规划matlab代码&#xff0c;实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...

Pinocchio 库详解及其在足式机器人上的应用

Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库&#xff0c;专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性&#xff0c;并提供了一个通用的框架&…...

人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式

今天是关于AI如何在教学中增强学生的学习体验&#xff0c;我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育&#xff0c;这并非炒作&#xff0c;而是已经发生的巨大变革。教育机构和教育者不能忽视它&#xff0c;试图简单地禁止学生使…...

日常一水C

多态 言简意赅&#xff1a;就是一个对象面对同一事件时做出的不同反应 而之前的继承中说过&#xff0c;当子类和父类的函数名相同时&#xff0c;会隐藏父类的同名函数转而调用子类的同名函数&#xff0c;如果要调用父类的同名函数&#xff0c;那么就需要对父类进行引用&#…...