数组名结合指针的面试题的讲解

2024-03-14 16:52

本文主要是介绍数组名结合指针的面试题的讲解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

笔试题
第一题:
已知条件:
已知p为结构体指针变量,值为0x100000,并且结构体的大小为20字节,并且打印格式均为%p,%p不会在乎正负数,它会以补码的形式直接打印,0x1为16进制的1。
第一问:p+0x1,
p为结构体指针,指针的+1-1,是一种指针的关系运算,跳过的大小取决于指针本身的类型,如果是整形指针,它+1跳过四个字节,所以p+1会跳过20个字节大小,所以0x100000需要加上20个字节大小,但不是0x100020,要先把20转化为16进制,得到14,所以应该是00100014
第二问:它将16进制的0x100000强转成了无符号long 型,也就是强转成了整形,所以如果200+1就等于201,500+1就等于501,所以结果为00100001
第三问:它将p强转成了整形指针类型,这个时候+1-1,就应该是按照整形指针的权限来就是+-,所以应该是+4,结果为:00000004
第二题:

第一问:int *ptr1 = (int *)(&a + 1),

&a代表拿出了整个数组的地址,然后+1,此时指针会跳过整个数组,现在的类型是int * [4],它将其强转为了int *,然后问ptr1 [-1]是多少,ptr1 [-1]就是*(ptr+(-1)),就等与*(ptr-1),此时指针应该往回走1个单位,它是int*,所以往回走四个字节,刚好指向了4,所以结果为4。

vs是小端存储,所以从左往右存储数组的时候,是如图所示的存储方式。

第二问如图所示:int *ptr2 = (int *)((int)a + 1), 

第一步:(int)a + 1,a为首元素地址,假设此时地址是0x0012ff40,现在被强转成了整数,然后对这个整数进行+1,结果就是0x0012ff41,然后又将这个整数强转成了int*的指针,此时的0x0012ff41就是一个新的地址了,它和原来的数组首地址0x0012ff40相比,它向后走了一个字节(如图ptr2所指向的位置),此时%x打印,应该向后访问四个字节的内容,由于是小端存储,所以数据应该是2000000

 第三题:

问题:这是一个二维数组,3行四列,但是由于不是{ { },{ },{ }},而是{()()()},这是一个逗号表达式,保留下来的结果应该是1,3,5。所以这个二维数组应该如图所示:

然后 p = a[0];p是int*,这一步就是将a[0],也就是第一行的首地址赋给了p,所以p现在时第一行数组的首元素地址,然后p[0],也就是*p,所以直接打印出了1。 

第四题:

如图所示:

第二问(%d)数组的存储是从低地址到高地址的,p指向的是一个4个整形的一维数组,p+1,p+2,p+3,p+4如图所示,每次跳过四个整形(16字节),所以p [4] [2]应该指向图中&p [4] [2]所对应的位置,此时和&a[4][2]进行相减,其结果的绝对值是中间相差的元素个数,因为以%d打印,所以应该是-4。

第一问(%p),是将-4以%p的形式打印,%p没有符号之分,直接将-4的补码以16进制进行打印

 如图所示:-4的原返补码,以及16进制

第五题:

首先第一步char**pa = a; a是一个字符串数组的地址,这个地址被存放进了pa,类型是char**

如图所示:

因为a是数组名,其代表首元素地址,也就是"work"的地址,然后pa++,它就跳过了首元素,指向了第二个元素,所以结果为  at

第六题:

第一问:*(ptr1 - 1)

首先:int *ptr1 = (int *)(&aa + 1);,这一步&aa取出了整个二维数组的地址,然后+1代表跳过了整个二维数组的地址,如图所示

图中的红色ptr1就是跳过了二维数组指向的地址。然后此时把这个东西强转成了int*,它的类型从int(*)[2][5],变成了int*,然后以%d的形式打印*(ptr1-1),就是将红色的ptr1往后跳了四个自己,因为此时的红色ptr1是int*,解引用往后跳过4个字节,也就是一个整形的位置,所以指向了10。

第二问:*(ptr2 - 1)

首先* ( aa + 1 )这一步,aa为数组名,现在代表数组首元素地址,也就是一维数组1,2,3,4,5的首地址,然后+1.此时指向了第二个一维数组6,7,8,9,10的首地址,此时aa+1的类型是int(*)[5],然后就是对一个数组指针进行了解引用,所以结果是一个一维数组,然后又因为一维数组名代表首元素地址,也就是第一个元素6的地址,类型为int*,所以此时题目的将int*强转成int*是没有意义的,然后 * ( ptr2 - 1 )这一步,让ptr2往回走1个单位,因为ptr2是int*,所以它往回走四个字节,也就是一个整形的地址,指向了5的地址,所以结果是5。

第七题: 

已知条件:

将3,4,5语句翻译如下图所示:

第一问 :printf("%s\n", **++cpp);

根据操作符得知从右往左读即可。

第一步:这是一个++cpp前置++,计算就是以++后的结果来计算的,cpp是一个三级指针,它存放的是二级指针数组的地址(cp的首地址),++让它由指向cp的首地址变成了指向cp中的第二个元素。

第二步:此时的一个*,对这个cpp指向的地址(也就是cp中的第二个元素的首地址)进行解引用,得到了cp中的第二个元素的内容c+2。

第三步:而c+2也是一个地址,它指向的是数组c中的第三个元素(如图),此时的最后一个*,对c+2这个地址进行解引用,得到了数组c中的第三个元素的内容,也就是字符串POINT的首地址,此时以%s形式打印,当然是得到POINT这个字符串啦。

第二问:printf("%s\n", *--*++cpp+3);
根据操作符的先后顺序,可知+3放在最后,其余的从右往左读即可。
\
第一步: ++ cpp,由于cpp在第一问的时候由于前置++指向了cp中的第二个元素,前置++的结果是在cpp上进行的,所以我们要保留第一问的操作,然后再进行前置++。此时cpp指向了cp中的第三个元素。
\
第二步:然后对cpp指向的数组cp中的第二个元素进行*的解引用 ,此时得到的是cp中的第三个元素的内容c+1。
\
第三步:对这个c+1进行前置--,即--(c+1),所以结果为c。
\
第四步:然后对c再次进行*,按照数组cp中元素c指向了数组c中的第一个元素,所以此时的结果是数组c中的第一个元素内容,也就是字符串ENTER的首地址。
\
第五步:此时最后一步+3,让这个地址让后移动3个单位,指向了ENTER中的第二个E的地址,再以%s的形式打印,也就是ER。
\
第三问:printf("%s\n", *cpp[-2]+3);
根据操作符的先后顺序,可知+3放在最后,其余的从右往左读即可。
\
第一步:cpp[-2],可以理解为*(cpp-2),由第二问可知cpp已经更新到了指向cp中的第三个元素的首地址,所以此时的cpp-2让指针往回走两个单位,指向了cp中的第一个元素的地址。此时cpp的移动不会影响到第四问cpp指向的元素,因为cpp-2的值没有赋给cpp,而++cpp这种是赋值了。
\
第二步:再进行*,得到了第一个元素的内容c+3,此时 * cpp [ - 2 ]的这一颗*,对c+3进行了解引用,得到了c+3所指向的数组c中的最后一个元素(FIRST的首地址),然后最后一步+3,与第二问类型,让指针指向了S的地址,再以%s打印,得到了ST。
\
第四问:printf("%s\n", cpp[-1][-1]+1);
根据操作符的先后顺序,可知+1放在最后,其余的从右往左读即可。
\
第一步: cpp [ - 1 ][ - 1 ]可以理解为 *(*(cpp-1)-1),由第三问可知,cpp还是指向了数组cp第三个元素的首地址,此时-1再*,得到的是c+2。
\
第二步:然后再对c+2进行-1再*,得到的是数组c中的第二个元素内容,也就是NEW的首地址,然后+1,与前面类似,指针指向了E的首地址,再以%s的形式打印,得到的是EW。

这篇关于数组名结合指针的面试题的讲解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/809061

相关文章

Spring 中的切面与事务结合使用完整示例

《Spring中的切面与事务结合使用完整示例》本文给大家介绍Spring中的切面与事务结合使用完整示例,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考... 目录 一、前置知识:Spring AOP 与 事务的关系 事务本质上就是一个“切面”二、核心组件三、完

Unity新手入门学习殿堂级知识详细讲解(图文)

《Unity新手入门学习殿堂级知识详细讲解(图文)》Unity是一款跨平台游戏引擎,支持2D/3D及VR/AR开发,核心功能模块包括图形、音频、物理等,通过可视化编辑器与脚本扩展实现开发,项目结构含A... 目录入门概述什么是 UnityUnity引擎基础认知编辑器核心操作Unity 编辑器项目模式分类工程

MySQL连表查询之笛卡尔积查询的详细过程讲解

《MySQL连表查询之笛卡尔积查询的详细过程讲解》在使用MySQL或任何关系型数据库进行多表查询时,如果连接条件设置不当,就可能发生所谓的笛卡尔积现象,:本文主要介绍MySQL连表查询之笛卡尔积查... 目录一、笛卡尔积的数学本质二、mysql中的实现机制1. 显式语法2. 隐式语法3. 执行原理(以Nes

SpringBoot结合Knife4j进行API分组授权管理配置详解

《SpringBoot结合Knife4j进行API分组授权管理配置详解》在现代的微服务架构中,API文档和授权管理是不可或缺的一部分,本文将介绍如何在SpringBoot应用中集成Knife4j,并进... 目录环境准备配置 Swagger配置 Swagger OpenAPI自定义 Swagger UI 底

RabbitMQ消费端单线程与多线程案例讲解

《RabbitMQ消费端单线程与多线程案例讲解》文章解析RabbitMQ消费端单线程与多线程处理机制,说明concurrency控制消费者数量,max-concurrency控制最大线程数,prefe... 目录 一、基础概念详细解释:举个例子:✅ 单消费者 + 单线程消费❌ 单消费者 + 多线程消费❌ 多

从入门到进阶讲解Python自动化Playwright实战指南

《从入门到进阶讲解Python自动化Playwright实战指南》Playwright是针对Python语言的纯自动化工具,它可以通过单个API自动执行Chromium,Firefox和WebKit... 目录Playwright 简介核心优势安装步骤观点与案例结合Playwright 核心功能从零开始学习

Spring Boot 结合 WxJava 实现文章上传微信公众号草稿箱与群发

《SpringBoot结合WxJava实现文章上传微信公众号草稿箱与群发》本文将详细介绍如何使用SpringBoot框架结合WxJava开发工具包,实现文章上传到微信公众号草稿箱以及群发功能,... 目录一、项目环境准备1.1 开发环境1.2 微信公众号准备二、Spring Boot 项目搭建2.1 创建

nginx -t、nginx -s stop 和 nginx -s reload 命令的详细解析(结合应用场景)

《nginx-t、nginx-sstop和nginx-sreload命令的详细解析(结合应用场景)》本文解析Nginx的-t、-sstop、-sreload命令,分别用于配置语法检... 以下是关于 nginx -t、nginx -s stop 和 nginx -s reload 命令的详细解析,结合实际应

SpringBoot结合Docker进行容器化处理指南

《SpringBoot结合Docker进行容器化处理指南》在当今快速发展的软件工程领域,SpringBoot和Docker已经成为现代Java开发者的必备工具,本文将深入讲解如何将一个SpringBo... 目录前言一、为什么选择 Spring Bootjavascript + docker1. 快速部署与

Python中re模块结合正则表达式的实际应用案例

《Python中re模块结合正则表达式的实际应用案例》Python中的re模块是用于处理正则表达式的强大工具,正则表达式是一种用来匹配字符串的模式,它可以在文本中搜索和匹配特定的字符串模式,这篇文章主... 目录前言re模块常用函数一、查看文本中是否包含 A 或 B 字符串二、替换多个关键词为统一格式三、提