C语言经典指针运算笔试题图文解析
指针运算常常出现在面试题中,画图解决是最好的办法。
题目1:
#include <stdio.h>
int main()
{int a[5] = { 1, 2, 3, 4, 5 };int* ptr = (int*)(&a + 1);printf("%d,%d", *(a + 1), *(ptr - 1));return 0;
}
//程序的结果是什么?
&a得到的是整个数组的地址,其值和首元素地址相同,但类型为 int (*) [5] ,对其 +1 ,跳过 5 * 4 = 20字节。
然后对其强制类型转换为int*,此时其 -1 ,跳过 4 字节。
故对其解引用得到数组中下标为 4 的元素,值为5。
而数组名代表首元素地址,其 +1 就得到数组下标为 1 的元素的地址,对其解引用就得到对应元素,值为2。
题目2:
struct Test
{int Num;char* pcName;short sDate;char cha[2];short sBa[4];
}*p = (struct Test*)0x100000;int main()
{printf("%p\n", p + 0x1);printf("%p\n", (long)p + 0x1);printf("%p\n", (int*)p + 0x1);return 0;
}
p是类型为结构体类型的指针,那么其每 +-1 跳过一个结构体变量大小的空间,而此结构体变量大小为20个字节,那么p + 0x1 = 0x100014,以地址的形式打出也是0x100014,因为地址就是以16进制表示的。
当对其强制类型转换为long类型后,p不再代表地址,而是代表整数0x100000,对其 +0x1,就是简单的整数运算,得0x100001。
当对其强制类型转换为int*类型后,p变为指向整形类型的指针变量,对其 +1,跳过4字节,故值为0x100004。
题目3:
#include <stdio.h>
int main()
{int a[3][2] = { (0, 1), (2, 3), (4, 5) };int* p;p = a[0];printf("%d", p[0]);return 0;
}
一上来看到这样的数组形式,就会想当然的认为这个二维数组为:
这样的二维数组其书写格式应该为:a[3][2] = {{0,1},{2,3},{4,5}}。
而原书写对行的划分使用的是小扩号,应理解为逗号表达式,其结果为a[3][2] = {1,3,5}。由于给出的元素没有达到二维数组元素总个数,剩下拿0来补齐,那么实为:
a[0] 为第一行首元素地址,p[0] == *(p + 0),那么这里最后访问到的应该为第一行第一列的元素,即1。
题目4:
//假设环境是x86环境,程序输出的结果是啥?
#include <stdio.h>
int main()
{int a[5][5];int(*p)[4];p = a;printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);return 0;
}
a为一个五行五列存放元素为int类型的二维数组,p为int(*)[4]类型的数组指针,意味着其 +1 一次跳过4个int类型变量空间大小。
假设&p[4][2] = 0x00000001,那么&a[4][2] = 0x00000011,&p[4][2] - &a[4][2] = 0xFFFFFFFC,此为-4的16进制转换:
我们知道,两指针相减的绝对值可以得到两指针间元素的个数,那么这里的元素个数就为4,由于是低地址位指针减高地址位指针,所以结果为负值。
题目5:
#include <stdio.h>
int main()
{int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };int* ptr1 = (int*)(&aa + 1);int* ptr2 = (int*)(*(aa + 1));printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1));return 0;
}
&aa得到的是整个二维数组的地址,类型为int(*)[2][5],意味着 &aa + 1 一次跳过整个二维数组的内存空间大小。aa得到的是二维数组首元素的地址,即为第一行元素组成的数组的地址,类型为int(*)[5], 意味着对其 +1 直接指向第二行元素组成的数组,由于数组地址与数组首元素地址相同,此时aa + 1指向第二行元素组成的数组的首元素。
ptr1 此时指向的就为图示&aa + 1的位置,但由于其类型为int*,意味着其 -1仅跳过4字节,ptr1-1解引用得10;*(aa + 1)为int*类型,仍然是一个指针,只不过不再指向一个数组,而是一个整形变量,故ptr2指向了图示位置,解引用得5。
题目6:
#include <stdio.h>
int main()
{char* a[] = { "work","at","alibaba" };char** pa = a;pa++;printf("%s\n", *pa);return 0;
}
a为数组名,代表数组首元素地址,而a数组为元素是字符串的数组,故每个元素实则为字符串首字符的地址,正因为是地址的地址,所以用二级指针pa来存。
对pa++解引用拿到"at"字符串的首字符的地址,故:
题目7:
#include <stdio.h>
int main()
{char* c[] = { "ENTER","NEW","POINT","FIRST" };char** cp[] = { c + 3,c + 2,c + 1,c };char*** cpp = cp;printf("%s\n", **++cpp);printf("%s\n", *-- * ++cpp + 3);printf("%s\n", *cpp[-2] + 3);printf("%s\n", cpp[-1][-1] + 1);return 0;
}
同题六作图:
注:此题作图一定注意++ 、+的区别,一个会改变自身,一个不会。
**++cpp,首先对cpp + 1解引用得到c数组中第3个元素的地址,再解引用访问c数组中第3个元素,此元素为POINT字符串首字符的地址。
*--*++cpp+3,其先对cpp + 1,然后解引用得到cp第3个元素,即c第2个元素地址,然后对其--得到c第1个元素的地址,再解引用得到ENTER字符串的首字符地址,再+3就得到第4个字符的地址,从此字符开始打印,结果为ER。(ps. ((*(--*(++cpp)))+3) )
*cpp[-2]+3,cpp[-2]得到cp数组第一个元素,即c数组最后一个元素地址,再解引用得到FIRST字符串首字符地址,+3就得到S字符的地址,从此地址打印,得到ST。
cpp[-1][-1]+1,cpp[-1]得到cp的第2个元素,即c数组第3个元素的地址,再[-1]即对此地址-1解引用,得到字符串NEW的首字符地址,再+1得到E字符的地址,从此字符开始打印,结果为EW。
相关文章:

C语言经典指针运算笔试题图文解析
指针运算常常出现在面试题中,画图解决是最好的办法。 题目1: #include <stdio.h> int main() {int a[5] { 1, 2, 3, 4, 5 };int* ptr (int*)(&a 1);printf("%d,%d", *(a 1), *(ptr - 1));return 0; } //程序的结果是什么&…...
使用 KubeKey v3.1.1 离线部署原生 Kubernetes v1.28.8 实战
今天,我将为大家实战演示,如何基于操作系统 openEuler 22.03 LTS SP3,利用 KubeKey 制作 Kubernetes 离线安装包,并实战离线部署 Kubernetes v1.28.8 集群。 实战服务器配置 (架构 1:1 复刻小规模生产环境,配置略有不…...

DOS 命令
Dos: Disk Operating System 磁盘操作系统, 简单说一下 windows 的目录结构。 ..\ 到上一级目录 常用的dos 命令: 查看当前目录是有什么内容 dir dir d:\abc2\test200切换到其他盘下:盘符号 cd : change directory 案例演示:切换…...

如何用Java程序实现一个简单的消息队列?
在Java程序中,可以使用内置的java.util.concurrent.BlockingQueue作为消息队列存放的容器,来实现一个简单的消息队列。 具体实现如下,在这个例子中,我们创建了一个生产者线程和一个消费者线程,他们共享同一个阻塞队列…...

OpenAI 宕机事件:GPT 停摆的影响与应对
引言 2024年6月4日,OpenAI 的 GPT 模型发生了一次全球性的宕机,持续时间长达8小时。此次宕机不仅影响了OpenAI自家的服务,还导致大量用户涌向竞争对手平台,如Claude和Gemini,结果也导致这些平台出现故障。这次事件的广…...
linux常用的基础命令
ls - 列出目录内容。 cd - 更改目录。 pwd - 打印当前工作目录。 mkdir - 创建新目录。 rmdir - 删除空目录。 touch - 创建新文件或更新现有文件的时间戳。 cp - 复制文件或目录。 mv - 移动或重命名文件或目录。 rm - 删除文件或目录。 cat - 显示文件内容。 more - 分页显示…...

618家用智能投影仪推荐:这个高性价比品牌不容错过
随着科技的不断进步,家庭影院的概念已经从传统的大屏幕电视逐渐转向了更为灵活和便携的家用智能投影仪。随着618电商大促的到来,想要购买投影仪的用户们也开始摩拳擦掌了。本文将从投影仪的基础知识入手,为您推荐几款性价比很高的投影仪&…...
自愿离婚协议书
自愿离婚协议书 男方(夫): 女方(妻): 双方现因 原因,导致夫妻情感已破裂,自愿离婚…...

WPS JSA 宏脚本入门和样例
1入门 WPS window版本才支持JSA宏的功能。 可以自动化的操作文档中的一些内容。 参考文档: WPS API 参考文档:https://open.wps.cn/previous/docs/client/wpsLoad 微软的Word API文档:Microsoft.Office.Interop.Word 命名空间 | Microsoft …...

Printing and Exporting
打印 大多数DevExpress。NET控件(XtraGrid、XtraPivotGrid、XttraTreeList、XtraScheduler、XtraCharts)提供打印和导出功能。 所有可打印的DevExpress.NET控件是使用XtraPrinting库提供的方法打印的。 若要确定预览和打印选项是否可用,请检…...

c++【入门】正多边形每个内角的度数
限制 时间限制 : 1 秒 内存限制 : 128 MB 题目 根据多边形内角和定理,正多边形内角和等于:(n - 2)180(n大于等于3且n为整数)(如下图所示是三角形、四边形、五边形、六边形的形状)…...

spring boot3登录开发-邮箱登录/注册接口实现
⛰️个人主页: 蒾酒 🔥系列专栏:《spring boot实战》 🌊山高路远,行路漫漫,终有归途 目录 写在前面 上文衔接 内容简介 功能分析 所需依赖 邮箱验证登录/注册实现 1.创建交互对象 2.登录注册业务逻辑实…...
数据结构-二叉搜索树
二叉搜索树:BST(Binary Search Tree) 二叉搜索树是二叉树,可以为空,如果不为空,满足以下性质: 非空左子树的所有键值小于其根节点的键值非空右子树的所有键值大于其根节点的键值左、右字数本身也都是二叉搜索树 二叉…...

JUnit:Java开发者不可或缺的单元测试框架
在软件开发过程中,测试是确保代码质量的关键环节。单元测试作为测试体系的基础,对提升代码质量、降低bug率、增强软件稳定性具有重要作用。JUnit 作为 Java 语言事实上的标准单元测试框架,已经成为 Java 开发者进行单元测试的首选工具。本文将…...
NG32单片机GPIO口配置方式
目录 一、引言 二、GPIO口基本结构 三、GPIO口配置方式 四、工作原理 五、总结 一、引言 NG32单片机是一款集成度高、功能强大的微控制器。其中,GPIO(General Purpose Input/Output)口作为单片机与外部设备通信的重要接口,具…...

SpringCloud-OpenFeign拓展-连接池、最佳使用方法、日志输出
目录 1 OpenFeign连接池 1.1 常见连接类型 1.2 连接池使用方法 1.2.1 引入依赖 1.2.2 开启连接池功能 1.2.3 配置完成,重启实例即可,底层将更改设置。 2 OpenFeign最佳使用方法 2.1 每个微服务都是单独的project,内部有三个独立模块 …...
跨链协议中Cosmos IBC、Polkadot/XCM、Celer Network的区别以及用途
跨链协议是实现不同区块链之间通信和价值转移的关键技术。Cosmos IBC、Polkadot/XCM 和 Celer Network 是三个在跨链领域内具有代表性的协议,它们各自有着独特的设计理念和应用场景。下面是这三个协议的详细对比: Cosmos IBC (Inter-Blockchain Communi…...

电子画册制作与传统画册相比,有哪些优势?
在当今数字化时代,电子画册作为一种新兴的媒体形式,其制作与传统画册相比具有显著的优势。以下是对这些优势的详细探讨。 首先,电子画册的制作过程通常更加便捷和经济。相较于传统画册需要经历的繁琐的印刷过程,电子画册的制作大多…...

postman如何导入证书
1、打开postman,点击Settings。 2、添加证书。 3、填写要访问平台的URL路径及端口、证书文件、证书密码。 4、添加完之后即可立即调用postman。...

RocketMQ教程(八):RocketMQ的集群搭建
传送门:RocketMQ教程汇总,让你从入门到精通 集群架构 RocketMQ 的各个组件都可以搭建成集群部署,Broker 还可以搭建成主从架构,下面介绍的主要是 Broker 集群。 数据复制策略 复制策略是Broker的Master与Slave间的数据同步方式。分为同步复制与异步复制: 同步复制 消…...
浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)
✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义(Task Definition&…...

网络六边形受到攻击
大家读完觉得有帮助记得关注和点赞!!! 抽象 现代智能交通系统 (ITS) 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 (…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》
引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...
day52 ResNet18 CBAM
在深度学习的旅程中,我们不断探索如何提升模型的性能。今天,我将分享我在 ResNet18 模型中插入 CBAM(Convolutional Block Attention Module)模块,并采用分阶段微调策略的实践过程。通过这个过程,我不仅提升…...

Docker 运行 Kafka 带 SASL 认证教程
Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明:server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

基于当前项目通过npm包形式暴露公共组件
1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹,并新增内容 3.创建package文件夹...
MVC 数据库
MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...