【C语言】指针笔试题解析

大家好,我是苏貝,本篇博客带大家了解指针和数组笔试题解析,如果你觉得我写的还不错的话,可以给我一个赞👍吗,感谢❤️
在这里插入图片描述


1.

下面程序的结果是什么?

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

结果:2,5
&a表示取出整个数组a的地址,再+1表示跳过该数组,取出后面同类型的地址,即5个int型的地址即橙色区域,对&a+1进行强制类型转化后赋值给ptr,所以ptr指向的是数组后面的第一个地址。ptr-1表示数组a的最后一个元素的地址,对地址进行解引用找到最后一个元素5。a是首元素地址,a+1表示第二个元素的地址,对地址进行解引用找到第二个元素2
在这里插入图片描述

2.

//这里告知结构体的大小是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);//1printf("%p\n", (unsigned long)p + 0x1);//2printf("%p\n", (unsigned int*)p + 0x1);//3return 0;
}

结果:0x100014 ;0x100001;0x100004
1.0x是16进制的前缀,所以0x1也就是1,可知p是结构体指针,p+1即结构体指针+1表示跳过一个结构体的大小,所以p的地址要加20=0x14,所以结果为0x100014 ;
2.p原本存储的是地址,但按题目要将p进行强制类型转化成unsigned long类型,即此时p里面存储的不再是地址而是数字0x100000,再+1得0x100001,再将数字0x100001作为地址打印
3.p原本是结构体指针,现被强制类型转化为整型指针,所以p+1跳过4个字节,所以p的地址要加4=0x4,所以结果为0x100004 ;

3

数据以小端存储模式存储

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);return 0;
}

结果:4,2000000
由第1题知,ptr1指向的是数组后面的第一个地址,ptr1[-1]== * (ptr-1)即数组第四个元素4;
数组名a原本是首元素地址,设首元素地址为0x11223300,后来将a强制类型转化为int型,所以此时的0x11223300为数字而非地址,+1变为0x11223301,再将(int)a + 1强制类型转化为int * 类型,即又把0x11223301当成地址赋值给指针变量ptr2,这个地址在首元素地址后1个,又因为数据以小端存储模式存储(数据的低位保存在内存的低地址中,而数据的高位,保存在内存的高地址中),画出数组第1、2个元素的内存图(如下),对ptr进行解引用找到从ptr指向的内容到后面的3个字节的内容(下图中有黄色线条区域),将内存图的数据转化为现实数据即0x02000000,以16进制输入得2000000
在这里插入图片描述

4

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

结果:1
(0, 1), (2, 3), (4, 5)都是逗号表达式,所以数组a的元素为1,3,5,0,0,0,a[0]是一个一维数组,存储的是数组a第一行的元素,数组名是首元素地址,即将第一行第一个元素的地址传给p,p[0]= * (p+0)=1

5

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

结果:0xFFFFFFFC,-4
下图中橙色部分是&p[4][2],蓝色部分是&a[4][2],指针-指针的绝对值=两指针之间的元素个数=4,因为&p[4][2]<&a[4][2],所以 &p[4][2] - &a[4][2]= -4。-4在内存中以补码的形式存储,-4的原码:10000000 00000000 00000000 00000100;-4的反码:11111111 11111111 11111111 11111011;-4的补码:11111111 11111111 11111111 11111100;以地址的形式进行打印,得到FFFFFFFC;以十进制进行打印就是-4。
但我们要知道,p的类型是int( * )[4],而数组名a即首元素地址的类型为int( * )[5],两者的类型不同,在编译时编辑器会报警告
在这里插入图片描述

6

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

结果:10,5
由题目1知,ptr1-1指向的是数组最后一个元素的地址,对地址解引用找到最后一个元素10;* (aa+1) == aa[1],且前面没有sizeof和&,所以aa[1]表示第二行的首元素地址即第6个元素即元素6的地址,该地址本身就是int * 型的,所以强制类型转化无意义,ptr2指向的是第6个元素即元素6的地址。ptr2-1指向的是第5个元素的地址,对地址解引用找到第5个元素5

7

int main()
{char* a[] = { "work","at","alibaba" };char** pa = a;pa++;printf("%s\n", *pa);return 0;
}

结果:at
未进行pa++操作前,a,pa的关系如图,pa指向的是数组a的首元素地址
在这里插入图片描述
pa++后,pa指向的是数组a的第二个元素的地址

在这里插入图片描述
对pa解引用找到第二个元素,类型为char * ,即第二个元素中存储的是字符串at中a的地址。要打印字符串,通过第二个元素找到字符串at,遇’\0’停止

8

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

结果:POINT; ER ;ST; EW

阅读前3行代码,我们可以画出下面表示c、cp、cpp关系的图(修正:ENTRY改为ENTER)
在这里插入图片描述
在进行第四条语句时,因为++的优先级高于 * ,所以cpp先自增1,此时cpp指向的是数组cp的第二个元素,对cpp解引用找到数组cp的第二个元素,类型为char * * ,再对元素解引用找到数组c的第三个元素,类型为char * ,要打印字符串,通过第三个元素找到字符串POINT,遇’\0’停止
在这里插入图片描述
在进行第5条语句之前,c、cp、cpp关系的图如上(修正:ENTRY改为ENTER)。进行第5条语句,+的优先级在该语句中最低,所以最后再+3。cpp先自增1,此时cpp指向的是数组cp的第三个元素,对cpp解引用找到数组cp的第三个元素,类型为char * * ,内容为c+1,自减1后变成c,所以此时数组cp的第三个元素指向数组c的第一个元素,类型为char * ,要打印字符串,通过第一个元素找到字符串ENTER,+3后找到字符串ENTER的E,遇’\0’停止,所以结果为ER
在这里插入图片描述
在进行第6条语句之前,c、cp、cpp关系的图如上(修正:ENTRY改为ENTER)。cpp[-2]== * (cpp-2)找到数组cp的第一个元素,类型为char * * ,对元素解引用找到数组c的第四个元素,,类型为char * ,要打印字符串,通过第四个元素找到字符串FIRST,+3后找到字符串FIRST的S,遇’\0’停止,所以结果为ST

第6条语句并没有改变c、cp、cpp的关系。进行第7条语句,cpp[-1][-1]== * (* (cpp-1)-1),cpp-1指向数组cp的第二个元素,对元素解引用找到数组cp的第二个元素,再-1指向数组c的第二个元素,对元素解引用找到数组c的第二个元素,要打印字符串,通过第二个元素找到字符串NEW,+1后找到字符串NEW的E,遇’\0’停止,所以结果为EW


好了,那么本篇博客就到此结束了,如果你觉得本篇博客对你有些帮助,可以给个大大的赞👍吗,感谢看到这里,我们下篇博客见❤️

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Nginx负载均衡详解

一、负载均衡介绍 1、负载均衡的定义 单体服务器解决不了并发量大的请求&#xff0c;所以&#xff0c;我们可以横向增加服务器的数量&#xff08;集群&#xff09;&#xff0c;然后将请求分发到各个服务器上&#xff0c;将原先请求集中到单个服务器上的情况改为将请求分发到多…

React useRequest解读

源码结构&#xff1a; 可以看到虽然是一个hooks&#xff08;具有一定功能且具备状态的单一函数&#xff09; 但是各种文件功能分得也是很细的&#xff0c;方便抽离和复用 useRequest.ts 抽离的原则还是单一功能原则 可以看出 真正的hooks实现是在Implement里 对于类型type的引…

【前端面试题】浏览器面试题

文章目录 前言一、浏览器面试问题1.cookie sessionStorage localStorage 区别2.如何写一个会过期的localStorage&#xff0c;说说想法2.如何定时删除localstorage数据2.localStorage 能跨域吗2.memory cache 如何开启2.localstorage的限制2.浏览器输入URL发生了什么2.浏览器如何…

孙哥Spring源码第25集

第25集、处理代理中获取代理进行方法调用 0、问题所在 1、实现ApplicationContextAware接口实现代理 它的处理是在ApplicationContextAware中处理的 2、ExposeProxy分析 整体 分析 如何设置成了false就会有下面的问题 3、使用EnableAspectJAutoProxy解决代理问题 4、到底如何…

WEB使用VUE3实现地图导航跳转

我们在用手机查看网页时可以通过传入经纬度去设置目的地然后跳转到对应的地图导航软件&#xff0c;如果没有下载软件则会跳转到下载界面 注意&#xff1a; 高德地图是一定会跳转到一个新网页然后去询问用户是否需要打开软件百度和腾讯地图是直接调用软件的这个方法有缺陷&…

JavaScript中的代理对象(proxy)

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 创建代理对象⭐ 使用代理对象⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 欢迎来到前端入门之旅&#xff01;感兴趣的可以订阅本专栏哦&#xff01;这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友…

【车载开发系列】ECU Application Software程序刷新步骤

【车载开发系列】ECU Application Software程序刷新步骤 ECU Application Software程序刷新步骤 【车载开发系列】ECU Application Software程序刷新步骤一. Boot Software&#xff08;引导软件&#xff09;1&#xff09;boot manager&#xff08;启动管理器&#xff09;2&…

ElasticSearch(二)

1.DSL查询文档 elasticsearch的查询依然是基于JSON风格的DSL来实现的。 1.1.DSL查询分类 Elasticsearch提供了基于JSON的DSL&#xff08;Domain Specific Language&#xff09;来定义查询。常见的查询类型包括&#xff1a; 查询所有&#xff1a;查询出所有数据&#xff0c;…

挂件板死机刷固件

用ESP32-DevKitC_V4刷固件的工具flash_download_tool_3.9.5.exe 挂件板子端口接线依次为V&#xff08;接3V3&#xff09;、R&#xff08;接TXD&#xff09;、T&#xff08;接RXD&#xff09;、G&#xff08;接GND&#xff09;、L&#xff08;悬空&#xff09; 1.选择ESP8266&…

springboot 捕获数据库唯一索引导致的异常

在一些业务场景中,需要保证数据的唯一性,一般情况下,我们会先到数据库中去查询是否存在,再去判断是否可以插入新的数据.如果是在高并发的情况下,可能还是会出现重复的情况.这时候可能就需要用到锁.也可以在数据库中设置唯一索引. 如果使用唯一索引,在插入相同数据的情况下会抛出…

大二毕设.3-网盘系统

目录 技术选型&#xff1a; 功能概括&#xff1a; 基本演示&#xff1a; 实现讲解&#xff1a; 技术选型&#xff1a; 前端: Vue3 Element Plus后端: SpringBoot Mybatis-Plus MySQL Redis Caffeine FastDFS/OSS SpringCloud Stream RocketMQ Zookeeper 功能概括&…

【李沐深度学习笔记】基础优化方法

课程地址和说明 基础优化方法p2 本系列文章是我学习李沐老师深度学习系列课程的学习笔记&#xff0c;可能会对李沐老师上课没讲到的进行补充。 基础优化方法 在讲具体的线性回归实现之前&#xff0c;要先讲一下基础的优化模型的方法 梯度下降 当模型没有显示解&#xff08…

【操作系统笔记二】链接阶段ELF文件

链接阶段&#xff1a;符号解析 链接阶段主要包含&#xff1a; 符号解析重定位 一般情况下&#xff0c;每个 C 文件可以看成一个程序模块&#xff0c;比如下边的main.c就是一个程序模块 #include <stdio.h>extern int shared; int sum(int *a, int n); int array[2] …

三维模型轻量化引擎HOOPS纹理技术概览

随着计算机图形学和虚拟现实技术的飞速发展&#xff0c;大规模三维模型的应用领域不断扩展&#xff0c;如游戏开发、建筑设计、工程模拟等。然而&#xff0c;这些大规模模型往往具有复杂的几何结构和高分辨率的纹理&#xff0c;导致文件大小庞大&#xff0c;不利于在线传输和实…

Stellar Toolkit for MySQL 9.0 Crack 3in1

面向数据库管理员的 MySQL 工具包 Stellar Toolkit for MySQL是一款三合一软件套件&#xff0c;用于修复损坏的 MySQL 和 MariaDB 数据库、从 MySQL 数据库的 InnoDB 和 MyISAM 表恢复数据以及分析 MySQL 数据库日志文件。该软件还可以以最高的安全性和完整性相互转换 MySQL/Ma…

面试官:你了解axios的原理吗?有看过它的源码吗?

面试官&#xff1a;你了解axios的原理吗&#xff1f;有看过它的源码吗&#xff1f; 一、axios的基本使用 关于 axios 的基本使用&#xff0c;上篇文章已经有所涉及&#xff0c;这里再稍微回顾一下&#xff1a; 发送请求 import axios from axios;axios(config) // 直接传入…

Java内存模型介绍

文章目录 Java内存模型前言Java内存模型基本介绍指令重排相关概念主存和本地内存相关介绍JMM中的8种同步规则和8种同步操作happens-before 原则内存屏障总结 Java内存模型 前言 本文主要介绍一下JMM中的一些常见概念&#xff0c;通过本文让你能够快速的对JMM有一个大致的了解 …

如何看待Unity新的收费模式?

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

在uniapp中使用 秋云ucharts图表,运行到小程序

步骤一&#xff1a;通过使用 HBuilderX 直接导入项目&#xff08;uni_modules 版本&#xff09; 步骤二&#xff1a;在uCharts官网 - 秋云uCharts跨平台图表库 演示中&#xff0c;先弄个demo试着运行&#xff0c; 步骤三&#xff1a;查看自己需要的配置&#xff0c; 下面是我的…

保姆级 Keras 实现 Faster R-CNN 十三 (训练)

保姆级 Keras 实现 Faster R-CNN 十三 训练 一. 将 Faster R-CNN 包装成一个类二. 修改模型结构1. 修改 input_reader 函数2. 增加 RoiLabelLayer 层 三. 损失函数1. 自定义损失函数2. 自定义精度评价函数 四. 模型编译五. 模型训练六. 预训练模型七. 保存模型与参数八. 代码下…