指针 (八)例题深度解析

news2024/11/18 22:39:27

有关于指针的基本知识点我们都已经讲解完了,不出意外的话,这一篇就是我们指针的最后一期了,今天我们就来看一看一些有关于指针运算的例题:

每一道题诸君都应该有着自己先独立思考的能力,咱们不要怕面对,不管分析的对不对,努力去迈出那第一步,咱们就已经成功了一半了,加油加油加油!

题目一:

解析:

第一行咱就不说了昂,整数数组嘛,我相信能看到这一期的诸君已经能够一瞬间理解第一行了。第二行:先取出 a 的地址,这个时候数组名 a 表示的是整个数组的地址,再 + 1 就是跳过整个数组,这个时候地址指向的就是紧接着数组后面的这个位置。(int*)的含义就是强转,将数组第二个元素的地址强制类型转换为 int 类型,然后再将其赋给我们的指针变量—— ptr,接下来就是打印了

(1)*(a + 1):这里的数组名 a 就表示首元素地址,+ 1 就是第二个元素的地址,再解引用,打印的就是 2

(2)*(ptr - 1):上面分析了指针变量 ptr 里存放的是整个数组后面这个位置的地址,- 1 自然就是向后移一位,对其解引用自然就是 5

题目二:

解析:

上面这个结构体的最后,是将这个地址—— 0x100000 先强转为 struct test 类型,再赋给我们创建的指针变量 *p 

第一个打印: p 是我们的指针变量,里面放着我们赋值的 0x100000,加一个0x1,虽然这个数是16进制位,但 16 进制的 1 依旧是 1 ,又由于我们的指针变量 p 是一个结构体指针,我们这里设定的这个结构体大小为 20 字节,+ 1 跳过的是一整个结构体,也就是 20 字节,那么 20 字节在16进制中的表示是什么呢?是 14,所以这里的打印结果应该是 0x100014

第二个打印:将我们的 p 强制类型转换为 “ unsigned long ” 类型。这是整型类型,我们再加 0x1 也是整型,所以直接相加。打印结果为 0x100001

第三个打印:将我们的 p 强制类型转换为 “ unsigned int* ” 指针类型。这里的加 0x1 的意思是加上一个整型类型,打印结果为 0x100004

题目三:

解析:

创建了一个二维数组,再创建一个指针变量 p ,将数组首元素地址赋值给我们的变量 p ,再将其打印出来。这道题大家可以先思考一下,可能很多人得出的答案都是:0,心想这么简单的的题,一下就算出来了。众所周知昂,越是简单的题越是藏着坑,这题也有一个小坑,那就是关于二维数组内元素的表现形式,我们二维数组元素内,是可以使用括号来更明显的分段帮助理解的,但是呢,我们应该用大括号——{},而不是小括号——(),我们小括号的运算逻辑是从左向右依次运算,如果有多个运算结果,那么只取最右端为结果,所以我们二维数组内实际的元素只有三个:1、3、5,那么我们的首元素自然就是 1 了

我们所想的真正的二维函数是这样的:

题目四:

解析:

这里创建了一个二维数组,紧接着创建一个数组指针,将二维数组名(首元素地址,也就是这个二维数组第一行的地址)先强转为指针数组类型,再赋值给我们的数组指针变量 p ,且 p 每行是 4 个整型大小。接着就是打印,前一个为地址打印,后一个就是普通打印

我们的二维数组在内存中实际上是连续储存的,所以为了更好的理解,我们可以将其看做是一个一维数组的格式。我直接在图上给大家演示:

有图可知,我们找出了p [4] [2] 和 a [4] [2] 所指向数组中的位置

我们再来看需要打印的:&p [4] [2] - &a [4] [2] = - 4(地址相减得到的是地址之间的元素个数)

由于第一个打印是地址,那么我们 - 4 的地址是什么呢?这个就要涉及到我们的原、反、补了

综上所述,我们最终的打印结果应该是:

题目五:

解析:

首先给出一个二维数组 aa [2] [5] ,然后设立了两个指针变量 ptr1、ptr2,我们分别来看

ptr1:&aa,取出二维数组aa的地址,这里取出的就是整个二维数组的地址,+ 1 自然就是跳过整个数组,也就是说此时我们的 ptr1 指向的是我们二维数组后的那个位置

ptr2:单独出现数组名,没有sizeof,所以这里就是我们的首元素地址,就是 aa [0],在二维数组中的第一行地址,再 + 1 自然就是 aa [1] 咯,也就是第二行第一位元素的地址

有细心的小伙伴可能发现了,在赋值给指针变量的时候还有一个 int * 的强转,不过这个强转没啥用哈,这个数组本身就是 int 整型的

最后我们来看一下打印结果:

题目六:

这里编译器报警告了昂,这是因为我使用的是C++文件,程序审核比较严格,我们题目是将三个字符串放进这个指针数组里面,原则上这是不被允许的

解析:

这个题涉及到二级指针,我们干看着不太容易理解,我直接在图上为诸君解析一下:

我们将这字符串强行赋给指针数组中,实际上是存放的这三个字符串首字符地址,类型都是 char*,然后再将数组 a 赋值给我们的二级指针 pa ,a 是数组名,也就是首元素地址,所以这里 pa 里存放的是 a 中下标为 0 的地址,pa++ = pa+1,也就是跳过一个字节,此时指向了我们下标为 2 的位置,对其解引用得到了第二个字符的首元素地址,再将其打印,又因为我们的字符串的末尾是隐藏着一个 '\0' 的

所以最终的打印结果就是:at (这里因为编译器会报错,所以我就不打印了)

题目七:

解析:

对于题目中各个指针数组的解析,上面那题讲解的很清楚了,咱就不过多赘述了

* * + + CPP:这里是前置 ++ ,也就是先做 ++ 运算,再对其解引用,本来的 cpp,应该是指向的指针数组 cp 中的首元素,++ 过后,跳过一个字节,此时指向的第二个元素,也就是 C + 2 的下标,对其一次解引用就是 cp 中的 C + 2 ,二次解引用就是 c 中的第三位元素的地址 —— p 的地址,所以打印结果应该为:POINT

* - - * + + C P P + 3:这一个运算就比较复杂了,涉及到我们 C 语言运算符的优先级考虑,之前出过两期操作符详解,感兴趣的小伙伴可以去回顾一下哈:C语言中操作符详解(二)-CSDN博客

言归正传,首先,我们的三级指针 cpp 在第一个打印中已经经过了一次运算:++ cpp,这个运算是会保留的哈,并不是说只是走个过程,所以我们在第二个打印这里的 cpp 已经是指向了 C + 2 的位置,然后考虑我们的运算符优先级,++、-- 的优先级是最高的,然后是解引用 *,再是普通的+。按照这个顺序我们来思考。先做 ++ ,此时指针来到我们的 C + 1 位置,对其解引用,找到这个元素: C + 1,再进行 - - ,这不就是 C 了么。再对其解引用找到字符串 “ ENTER ” 首字母 E 的地址,最后 + 3 就是跳过三个字节来到倒数第二这个 E ,然后打印,所以最后的打印结果就是:ER

* C P P [ -2 ] + 3:这个就更有意思了,下标出现了一个 - 2,大家可能看的一头雾水,心想,这是什么啊?哪还有下标为 - 2 的道理哦。其实道理嘛,万变不离其宗,咱们得透过表相看本质,只要我们来举个简单的例子,聪明的诸君立马就会如醍醐灌顶般理解了:

arr [ 0 ] 是不是就等于 * (arr + 0),同理,arr [ 1 ] == *(arr + 1)

那么 arr [ -2 ] == *(arr - 2)

诸君是不是一下就明白了

OK,咱们继续,由于经过上面的两次计算,此时我们的 cpp 已经指向了 C + 1 的位置,在这个基础上 - 2 也就是回到了 C + 3 的位置,对其解引用也就是找到了我们 c 中 F 的位置,再 + 3 就是向后跳过三个字节,所以最终的打印结果为:ST

C P P [ -1 ] [ -1 ] + 1:这里又出现了二维数组的形式,不过不要怕,咱们一层一层地来剖析它。有的小伙伴看到二维数组的形式就怕了,不要怕嘛,这些都是纸老虎,经过我们上一道题的解析,再来看这个不也是一样的原理么:c p p [ -1 ] [ -1 ] == *(*(c p p - 1)- 1),我们此时的 c p p 可还是指向的 C + 1 的位置,因为第三次打印不是自加或自减的形式,其运算过程并不会对其本身造成改变,所以先 - 1 指向了 C + 2 的位置,再 - 1 得到 C + 1,然后再解引用找到我们 c 中 N 的地址,再 + 1 跳过一个字节,所以最终打印结果为:EW

OKK,咱们有关于指针的知识点到此就告一段落啦,这部分很难理解,文字毕竟是生硬的,大家应该多找一些网课看一看,并且自己多加练习,我也会继续努力,咱们一起加油!好了,那咱们闲话少说,下期再见吧,与诸君共勉!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2200305.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

算法笔记day02

目录 游游的you 腐烂的苹果 孩子们的游戏 游游的you 游游的you__牛客网 这里需要注意 oooo 是3分而不是两分。 算法思路: 拼出you可以得2分,先拼出所有的you,在将所有的o拼在一起即可。 选3个字母个数最小的就是能拼出you的个数。 #in…

LeetCode讲解篇之34. 在排序数组中查找元素的第一个和最后一个位置

文章目录 题目描述题解思路题解代码题目链接 题目描述 题解思路 这题让我们求目标值的左边界和右边界,我们可以采用二分查找搜索有序数组内大于等于目标值的最左边的下标 然后我们只需要在有序数组查找一下大于等于target的最左边下标 如果该下标越界或者下标对应…

陈奂仁「仓鼠艺术奥德赛」游戏体验上线:踏上沉浸式艺术之旅

今年 2 月,陈奂仁(Hanjin)在 The Sandbox 推出「仓鼠涂鸦」系列,将艺术与实用性融为一体。该系列包括 1,500 个以仓鼠为灵感的人物化身,其中更包括 8 款向著名艺术家致敬、独一无二的 NFT。这些人物化身通过「表情」&a…

芝法酱学习笔记(0.6)——nexus与maven私库

一、私库的需求 在一个公司中,后端程序员通常几十上百个。在没有镜像私库的情况下,每当引入新库时,大家都会从maven中央仓库下载一遍这个库。这样无疑十分浪费。再加之国家的防火墙政策,许多人下载lib包可能还会十分缓慢。不同程…

【黑马点评】8-12达人探店、好友关注、附近商户、用户签到、UV统计功能

【黑马点评】8-12达人探店、好友关注、附近商户、用户签到、UV统计功能 8 达人探店8.1 达人探店-发布探店笔记8.2 达人探店-查看探店笔记8.3 达人探店-点赞功能8.4 点赞排行榜 9 好友关注9.1 好友关注-关注和取消关注9.2 好友关注-共同关注9.3 好友关注-Feed流实现方案9.4 好友…

懒人笔记-QT程序UOS打包篇

懒人笔记-uos打包篇 前言1、deploy2、组织打包目录2.1 控制文件2.1.1 control的内容:2.1.2 postinst的内容:2.1.3 postrm的内容: 2.2 执行程序2.3 开机自启(可选项) 3、输出deb安装包4、服务卸载4.1 服务卸载4.2 程序按…

信息论笔记

知识点 学习视频链接 信息论简介和概率论复习 信息的定义 信息、信号、消息的概念 香农信息 信息论的研究对象和目的 信源:产生消息和消息序列的源编码器:将消息变为适合信道传输的物理量信道:传输或者储藏信号的媒介译码器&#xf…

mysql事务使用和事务隔离级别与sqlserver的比较

在 MySQL 中,事务 (Transaction) 是一个将一组 SQL 语句作为一个整体执行的机制。事务确保要么所有操作都执行成功,要么在遇到错误时回滚到之前的状态,从而保证数据库数据的一致性和完整性。 事务的四大特性(ACID) 事…

RISC-V笔记——基础

1. 前言 RISC-V旨在支持广泛的定制和专业化。RISC-V的ISA是由一个基本整型ISA和其它对基本ISA的可选扩展组成。每个整型ISA可以使用一个或多个可选的ISA扩展进行扩展。 基本整型ISA精选了最小的一组指令,这些指令足以为编译器、汇编器、链接器和操作系统提供足够的…

iPhone相册怎么删除相同照片

我们都太喜爱用iPhone拍照了,我们的iPhone相册就像是一个永远不想清理的衣柜,堆满了各种美好瞬间和意外的重复照片。面对成百上千的照片,有时候我们不禁想:这些相同的照片到底是怎么混进来的?今天,就让我来…

SpringBoot集成RocketMQ实现六种消息

1. 简介 RocketMQ 支持多种消息类型以满足不同的业务需求 普通消息(Standard Message): 这是最常用的消息类型,适用于大多数场景。 可以设置延迟级别(Delay Levels),但不支持消息轨迹。 顺序消…

C/C++程序员为什么要了解汇编?了解汇编有哪些好处?如何学习汇编?

目录 1、概述 2、从汇编的角度去理解问题的若干实例说明 2.1、使用空指针去访问类的数据成员或调用类的虚函数为什么会引发崩溃? 2.2、从汇编代码的角度去理解多线程的执行细节,去理解多线程在访问共享资源时为什么要加锁 2.3、使用Windbg静态分析d…

【Matlab】Matlab 导入数据.csv或者.xlsx文件,然后使用这些数据来绘制图表

Matlab 导入数据.csv或者.xlsx文件,然后使用这些数据来绘制图表 初始数据 filename C:\Users\jia\Desktop\yadian\data\1Hz 2024_09_12 17_10_06.csv; 代码: clc;clear close all; % 读取Excel文件 filename C:\Users\jia\Desktop\yadian\data\1Hz …

一篇文章让你学懂python入门

1.编写程序输入三个整数,按升序输出 思路1:使用if-else结构进行大小比较,将三个数进行从小到大的排序 num1 int(input("请输入第一个整数:")) num2 int(input("请输入第二个整数:")) num3 int(input(&qu…

华为OD机试 - 采样过滤(Python/JS/C/C++ 2024 E卷 100分)

华为OD机试 2024E卷题库疯狂收录中,刷题点这里 专栏导读 本专栏收录于《华为OD机试真题(Python/JS/C/C)》。 刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,…

MySQL数据的增删改查

CRUD CRUD指的是创建(Create),读取(Retrieve),更新(Update)和删除(Delete),它是数据库或者持久层在软件系统中执行的基本功能,构成了大多数应用程序和服务器…

图神经网络之异构图转同构图

heterogeneous graph转homogeneous 异构图创建教程dgl.to_homogeneous语法格式例子 异构图创建教程 对于异构图创建,可以看异构图创建教程 dgl.to_homogeneous语法格式 dgl.to_homogeneous(G, ndataNone, edataNone, store_typeTrue, return_countFalse)G&#x…

K8s简介及环境搭建

一、Kubernetes简介 kubernetes 的本质是一组服务器集群,它可以在集群的每个节点上运行特定的程序,来对节点中的容器进行管理。目的是实现资源管理的自动化,主要提供了如下的主要功能: 自我修复:一旦某一个容器崩溃&a…

使用HashiCorp Nomad Cluster App管理高可用集群

容器化和Kubernetes如今已成为创建可扩展云原生应用程序的基本要素。但并非每个应用程序工作负载都需要容器或Kubernetes资源。HashiCorp Nomad是一个轻量级的工作负载调度程序,提供了与Kubernetes相似的优势,但不仅可以管理容器,还能管理其他…

SSL证书是否可以给多个域名使用?

在当今数字化的网络环境中,SSL证书在保障网站安全、保护用户数据传输方面发挥着至关重要的作用。那么,SSL 证书是否可以给多个域名使用呢?这是一个在网站开发、运营和安全管理领域备受关注的问题。 SSL 证书能够给多个域名使用吗&#xff1f…