指针进阶(三)

2023-11-06

指针进阶(三)

指针习题组:

01:

int main()
{
    int a[5] = { 1, 2, 3, 4, 5 };
    int *ptr = (int *)(&a + 1);
    printf( "%d,%d", *(a + 1), *(ptr - 1));
    return 0;
}

运行结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ecSWtNwr-1690364128380)(C:\Users\30539\AppData\Roaming\Typora\typora-user-images\image-20230720233855042.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uH8bof1S-1690364128382)(C:\Users\30539\AppData\Roaming\Typora\typora-user-images\image-20230721095622604.png)]

原因:这里a是数组名,存放的是数组的首地址,&a是整个数组的地址,+1操作跳过了整个数组,所以ptr的指向如图所示,ptr被强制类型转换之前的类型是:int(*)[5];是数组指针,现在被强制转化成了 int*类型,所以进行加减操作时,跳过的是整型的大小了,解引用操作也是向后访问一个整型的大小。第5行中的a是数组首元素的地址,也就是int*类型的地址,+1操作会跳过一个整型。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SfEuwrsX-1690364128382)(C:\Users\30539\AppData\Roaming\Typora\typora-user-images\image-20230721100332417.png)]

指向如图所示,再解引用操作,最终的得到了2和5.

02:

这里告知结构体的大小是20个字节
struct Test
{
    int Num;
    char *pcName;
    short sDate;
    char cha[2];
    short sBa[4];
}*p;
//假设p 的值为0x100000。 如下表表达式的值分别为多少?
//已知,结构体Test类型的变量大小是20个字节
int main()
{
    printf("%p\n", p + 0x1);//0x100014
    printf("%p\n", (unsigned long)p + 0x1);//0x100001
    printf("%p\n", (unsigned int*)p + 0x1);//0x100004
    return 0;
}

原因:p是结构体指针变量,由于结构体的大小是20个字节,所以对p进行加减操作时,会跳过20个字节。代码第14行,就会加上20,转化成16进制就是加上14。当p被转化成 unsigned long类型时,进行加减操作时会发生代数上的简单的加减,所以代码第15行只是单纯的加上1。当p被转化为 unsigned in*类型时,进行加减操作时跳过4个字节,所以代码第16行的运行结果就是0x100004。

03:

int main()
{
    int a[4] = { 1, 2, 3, 4 };
    int *ptr1 = (int *)(&a + 1);
    int *ptr2 = (int *)((int)a + 1);
    printf( "%x,%x", ptr1[-1], *ptr2);//4 33554432
    return 0;
}

此时的ptr1和ptr2都是int*类型的变量,访问时会访问一个整型的大小。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8104apkp-1690364128382)(C:\Users\30539\AppData\Roaming\Typora\typora-user-images\image-20230721102659899.png)]

04:

#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;
}

运行结果:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QiWDqPLf-1690364128383)(C:\Users\30539\AppData\Roaming\Typora\typora-user-images\image-20230721103713960.png)]

原因:注意初始化数组时,括号里的是逗号表达式,所以数组中存储的是:135000 ,p指针变量等同于第一个一维数组的数组名,p[0]等同于a[0][0],结果为1.

05:

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;
}

运行结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u4JD15dV-1690364128383)(C:\Users\30539\AppData\Roaming\Typora\typora-user-images\image-20230721104519133.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9T5AEftG-1690364128383)(C:\Users\30539\AppData\Roaming\Typora\typora-user-images\image-20230726162041816.png)]

原因分析:由于p的类型是; int(*)[4];所以p在进行加减操作时,跳过的是4个元素,而a的类型是 int(*)[5];所以a进行加减操作时,跳过的是5个元素,由图可知,p[4][2]和a[4][2]之间相差了4个元素,由于p处于低地址,所以得到的答案是-4,又因为地址就是内存中实际存储的补码,所以-4以%p打印出来时,-4将会被看作无符号数进行打印,因为在内存中地址是没有正负之分的。所以打印结果就是 FFFFFFFFFFFFFFFC

06:

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;
}

运行结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AVvnTQyR-1690364128384)(C:\Users\30539\AppData\Roaming\Typora\typora-user-images\image-20230721104441043.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-awvzqggi-1690364128384)(C:\Users\30539\AppData\Roaming\Typora\typora-user-images\image-20230726162835603.png)]

原因分析:ptr1和ptr2的指向如图所示,但由于他们都是int*类型的指针,所以进行加减操作时,会跳过一个整型,打印结果就是5和10了。

07:

#include <stdio.h>
int main()
{
    char *a[] = {"work","at","alibaba"};
    char**pa = a;
    pa++;
    printf("%s\n", *pa);
    return 0;
}

运行结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4fekL26H-1690364128384)(C:\Users\30539\AppData\Roaming\Typora\typora-user-images\image-20230721104401489.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nBkq5E3I-1690364128384)(C:\Users\30539\AppData\Roaming\Typora\typora-user-images\image-20230726164400744.png)]

原因分析:pa的指向如图所示,pa中存储的是数组首元素的地址,这里的a数组中存放的三个字符串的首字符的地址,所以每个元素都是char*类型的。pa的类型是char**类型的,所以pa在进行加减操作时会跳过一个char*类型。pa++之后就指向的数组中的第二个元素,*pa就是第二个字符串首元素的地址。所以打印出了 at。

08:

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;
}

运行结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nteqlXRh-1690364128385)(C:\Users\30539\AppData\Roaming\Typora\typora-user-images\image-20230721104314675.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HVF4NsQ4-1690364128385)(C:\Users\30539\AppData\Roaming\Typora\typora-user-images\image-20230726171403853.png)]

原因分析:

  • 在printf语句之前,数据关系如图所示。++cpp之后,cpp就指向cp中的c+2了,**++cpp就拿到了 POINT 这个字符串的首字符的地址,打印出POINT。
  • 接着,cpp再次进行++操作,此时cpp则指向了cp中的c+1了,*++cpp的类型是char**类型,进行–操作时,会向后跳过一个char*类型的数据,指向ENTER这个字符串,在进行解引用操作,此时类型就成了char*类型,再进行+3操作,就跳过了三个字符,此时则指向了ENTER这个字符串中的第三个字符,结果打印出ER。
  • cpp[-2]又指向的cp中的c+3了。*cpp[2]的类型是char*类型,再进行+3操作会跳过三个字符,此时就指向了FIRST这个字符串中的第三个字符,打印出ST。
  • cpp[-1]指向的是cp中的c+2, cpp[-1][-1]的类型为char* 类型,指向的是c中的NEW这个字符串,+1操作,指向NEW中的第二个字符,打印出EW。

这道题特别要注意的点是,cpp在前两次的++过程中,相应的cpp的指向是会被改变的,但是后面cpp[-1]这种操作,并不会改变cpp的指向。

完结

本章的内容就到这里啦,若有不足,欢迎评论区指正,下期见!

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

指针进阶(三) 的相关文章

  • Java中ArrayList的交集和并集

    有什么方法可以做到这一点吗 我正在寻找 但没有找到 另一个问题 我需要这些方法 以便我可以过滤文件 有些是AND过滤器 有些是OR过滤器 就像集合论中的那样 所以我需要根据所有文件和保存这些文件的联合 相交 ArrayList 进行过滤 我
  • 按键时关闭 ModalWindow

    我希望能够在用户按下某个键 在我的例子中是 ESC 时关闭 ModalWindow 我有一个用于按键的 Javascript 侦听器 它调用取消按钮 ID 的单击事件 jQuery modalWindowInfo closeButtonId
  • Spring应用中Eureka健康检查的问题

    我正在开发一个基于 Spring 的应用程序 其中包含多个微服务 我的一个微服务充当尤里卡服务器 到目前为止一切正常 在我所有其他微服务中 用 EnableEurekaClient 我想启用这样的健康检查 应用程序 yml eureka c
  • Mockito:如何通过模拟测试我的服务?

    我是模拟测试新手 我想测试我的服务方法CorrectionService correctPerson Long personId 实现尚未编写 但这就是它将执行的操作 CorrectionService将调用一个方法AddressDAO这将
  • 为什么 JTables 使 TableModel 在呈现时不可序列化?

    所以最近我正在开发一个工具 供我们配置某些应用程序 它不需要是什么真正令人敬畏的东西 只是一个具有一些 SQL 脚本生成功能并创建几个 XML 文件的基本工具 在此期间 我使用自己的 AbstractTableModel 实现创建了一系列
  • 动态选择端口号?

    在 Java 中 我需要获取端口号以在同一程序的多个实例之间进行通信 现在 我可以简单地选择一些固定的数字并使用它 但我想知道是否有一种方法可以动态选择端口号 这样我就不必打扰我的用户设置端口号 这是我的一个想法 其工作原理如下 有一个固定
  • 如何获取之前的URL?

    我需要调用我的网络应用程序的 URL 例如 如果有一个从 stackoverflow com 到我的网站 foo com 的链接 我需要 Web 应用程序 托管 bean 中的 stackoverflow 链接 感谢所有帮助 谢谢 并不总是
  • 在 Jar 文件中运行 ANT build.xml 文件

    我需要使用存储在 jar 文件中的 build xml 文件运行 ANT 构建 该 jar 文件在类路径中可用 是否可以在不分解 jar 文件并将 build xml 保存到本地目录的情况下做到这一点 如果是的话我该怎么办呢 Update
  • 从最终实体获取根证书和中间证书

    作为密码学的菜鸟 我每天都会偶然发现一些简单的事情 今天只是那些日子之一 我想用 bouncy castle 库验证 java 中的 smime 消息 我想我几乎已经弄清楚了 但此时的问题是 PKIXparameters 对象的构建 假设我
  • 检测并缩短字符串中的所有网址

    假设我有一条字符串消息 您应该将 file zip 上传到http google com extremelylonglink zip http google com extremelylonglink zip not https stack
  • Hibernate 的 PersistentSet 不使用 hashCode/equals 的自定义实现

    所以我有一本实体书 public class Book private String id private String name private String description private Image coverImage pr
  • 如何访问JAR文件中的Maven资源? [复制]

    这个问题在这里已经有答案了 我有一个使用 Maven 构建的 Java 应用程序 我有一个资源文件夹com pkg resources 我需要从中访问文件 例如directory txt 我一直在查看各种教程和其他答案 但似乎没有一个对我有
  • 如何在谷歌地图android上显示多个标记

    我想在谷歌地图android上显示带有多个标记的位置 问题是当我运行我的应用程序时 它只显示一个位置 标记 这是我的代码 public class koordinatTask extends AsyncTask
  • Java 和 Python 可以在同一个应用程序中共存吗?

    我需要一个 Java 实例直接从 Python 实例数据存储中获取数据 我不知道这是否可能 数据存储是否透明 唯一 或者每个实例 如果它们确实可以共存 都有其单独的数据存储 总结一下 Java 应用程序如何从 Python 应用程序的数据存
  • 关键字“table”附近的语法不正确,无法提取结果集

    我使用 SQL Server 创建了一个项目 其中包含以下文件 UserDAO java public class UserDAO private static SessionFactory sessionFactory static se
  • Opencv Java 灰度

    我编写了以下程序 尝试从彩色转换为灰度 Mat newImage Imgcodecs imread q1 jpg Mat image new Mat new Size newImage cols newImage rows CvType C
  • 找不到符号 NOTIFICATION_SERVICE?

    package com test app import android app Notification import android app NotificationManager import android app PendingIn
  • 长轮询会冻结浏览器并阻止其他 ajax 请求

    我正在尝试在我的中实现长轮询Spring MVC Web 应用程序 http static springsource org spring docs 2 0 x reference mvc html但在 4 5 个连续 AJAX 请求后它会
  • 如何将双精度/浮点四舍五入为二进制精度?

    我正在编写对浮点数执行计算的代码的测试 不出所料 结果很少是准确的 我想在计算结果和预期结果之间设置一个容差 我已经证实 在实践中 使用双精度 在对最后两位有效小数进行四舍五入后 结果始终是正确的 但是usually四舍五入最后一位小数后
  • 如果没有抽象成员,基类是否应该标记为抽象?

    如果一个类没有抽象成员 可以将其标记为抽象吗 即使没有实际理由直接实例化它 除了单元测试 是的 将不应该实例化的基类显式标记为抽象是合理且有益的 即使在没有抽象方法的情况下也是如此 它强制执行通用准则来使非叶类抽象 它阻止其他程序员创建该类

随机推荐

  • 【Springboot WebSocket STOMP使用 2】STOMP使用@SendToUser实现用户个人请求-响应

    背景 STOMP协议的模型是 订阅 发布 式的 所以一般场景是同一个主题的广播 而有些场景下用户既想保持当前的WebSocket Session复用 又想消息的响应只有我自己能收到 指定其他某一个用户也行 不过得用其他api方法 不需要别人
  • 九月十月百度人搜,阿里巴巴,腾讯华为笔试面试八十题(第331-410题)

    九月十月百度人搜 阿里巴巴 腾讯华为小米搜狗笔试面试八十题 引言 自发表上一篇文章至今 事实上 上篇文章更新了近3个月之久 blog已经停了3个多月 而在那之前 自开博以来的21个月每月都不曾断过 正如上一篇文章支持向量机通俗导论 理解SV
  • 嵌入式Linux下使用OpenCV

    By Toradex 秦海 1 简介 OpenCV的全称是Open Source Computer Vision Library 是一个跨平台的计算机视觉库 OpenCV是由英特尔公司发起并参与开发 以BSD许可证授权发行 可以在商业和研究
  • 机器学习之实战matlab神经网络工具箱

    上节在 机器学习之从logistic到神经网络算法 中 我们已经从原理上介绍了神经网络算法的来源与构造 并编程实战了简单神经网络对于线性与非线性数据的分类测试实验 看过上节的可能会发现 上节实现的算法对于非线性数据的分类效果并不是非常完美
  • Java并发编程系列8 - 多线程实战

    主要基于小米最近的多线程项目 抽离出里面的多线程实例 前言 Java多线程的学习 也有大半个月了 从开始学习Java多线程时 就给自己定了一个小目标 希望能写一个多线程的Demo 今天主要是兑现这个小目标 这个多线程的示例 其实是结合最近小
  • JVM_09 类加载与字节码技术(字节码指令2)

    1 条件判断指令 几点说明 byte short char 都会按 int 比较 因为操作数栈都是 4 字节 goto 用来进行跳转到指定行号的字节码 源码 public class Demo3 3 public static void m
  • ES 的聚合机制和模糊匹配

    一 Elasticsearch对于大数据量 上亿量级 的聚合如何实现 Elasticsearch 提供的首个近似聚合是cardinality 度量 它提供一个字段的基数 即该字段的distinct或者unique值的数目 它是基于HLL算法
  • node.js入门学习

    文章目录 一 第一个node js应用 二 node js文件系统 1 读取文件 2 写入文件 三 node js模块化 新建一个module1 js文件 在require js文件中引入module1 js文件 四 node js发起GE
  • 参考文献期刊首字大写_sci论文参考文献格式

    学术论文的写作都离不开参考文献的引用与借鉴 参考文献的引用与借鉴可以让我们的文章更具可读性 也更具权威性与科学性 所以学术界对参考文献的引用有着明确的格式要求 凡是引用他人的文献都要在文章中做相应标注 这对原作者来说也是一种权利的保护 参考
  • 【OLED驱动】:stm32F103的四线模拟IIC驱动的0.96寸OLED屏幕显示数字,字母,汉字,图片的例程

    文章目录 前言 一 四线OLED是什么 二 IIC原理 1 四线0 96寸OLED是IIC驱动来实现显示 2 IIC协议的OLED屏幕 3 STM32驱动代码 4 IIC使用代码 总结 前言 最近在做一个开源方案 平衡车 即将开源硬件和软件
  • C++报错不允许使用不完整的类型

    include pch h include
  • #define _CRT_SECURE_NO_WARNINGS 1问题

    文章目录 前言 一 为什么用了scanf strcyp strlen strcat等函数会报错 二 操作步骤 1 下载notepad 2 修改 总结 前言 当我们的代码出现这样的报错时 不要慌张 应该是你用了scanf strcyp str
  • Merkle Tree(默克尔树)算法解析

    Merkle Tree 默克尔树 算法解析 1 Merkle Tree概念 Merkle Tree 通常也被称作Hash Tree 顾名思义 就是存储hash值的一棵树 Merkle树的叶子是数据块 例如 文件或者文件的集合 的hash值
  • 记一次jvm项目调优

    问题描述 运维一直说 fy core 项目这个项目每天都会发生多次full gc full gc 会停顿600ms左右 理论上生产环境不允许发生full gc 所以决定把full gc都优化掉 以下是该grafana对应的资源表现 可以看出
  • react生命周期componentDidMount中设置setState在esIint报错

    react生命周期componentDidMount中设置setState在esIint报错 项目背景 由于需要在页面渲染出来的时 对state中的数据进行初始化并需要出发render重绘 componentDidMount let sel
  • 5G“邂逅”云计算,运营商云网融合大势所趋

    近几年 国内运营商纷纷发力布局云计算市场 力求在云领域打造出自己的地盘 近期 中国电信天翼云与中科曙光战略合作 双方将共同探索在 5G 云 领域的建设 去年8月中国移动在苏州成立中国移动云能力中心 中国联动也于去年年底发布沃云云计算战略 而
  • navicat使用触发器在插入记录修改某个字段的值

    最近项目遇到了一个问题 查用户的某些字段有NULL会报错 所以想在注册的时候用的触发器提前设置一个默认值 避免空指针 先在本地建一个测试表t 1 就给三个基本字段 然后右击表选择设计表找到 触发器 开始编辑 现在的写法是正确的 我之前是这样
  • B站马士兵python入门基础版详细笔记(4)

    前言 这篇文章是B站学习python入门基础班的视频的第四章内容 主要讲述的是if else语句 但是不包括循环结构 循环结构在下一章笔记中有记叙 一 顺序结构 什么是顺序结构呢 比如说 把大象装冰箱需要分几步 print 程序开始 pri
  • 数模比赛提分tips

    1 对于模型的建立和求解 这一部分是文章的重点 要特别突出你的创造性的工作 在这部分写作需要注意的事项有 一定要有分析 而且分析应在所建立模型的前面 一定要有明确的模型 不要让别人在你的文章中去找你的模型 关系式一定要明确 思路要清晰 易读
  • 指针进阶(三)

    指针进阶 三 指针习题组 01 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是数组名 存放的是数组的首地址 a是整个