【指针笔试题下】你知道大厂面试题的指针题是什么样的吗?快来通过这些面试题目检测一下自己吧!

news2024/11/23 19:32:44

目录

前言

        笔试题1:

        笔试题2:

        笔试题3:

        笔试题4:

        笔试题5:

        笔试题6:

        笔试题7:

        笔试题8:

总结:


博客主页:张栩睿的博客主页

欢迎关注:点赞+收藏+留言

系列专栏:c语言学习

        家人们写博客真的很花时间的,你们的点赞和关注对我真的很重要,希望各位路过的朋友们能多多点赞并关注我,我会随时互关的,欢迎你们的私信提问,也期待你们的转发!

        希望大家关注我,你们将会看到更多精彩的内容!!!

前言:

        在学习了指针相关知识以后,我们可以通过这些笔试题来检测自己学的是否扎实。

笔试题1:

int main()
{
	int a[5] = { 1, 2, 3, 4, 5 };
	int* ptr = (int*)(&a + 1);
	printf("%d,%d\n", *(a + 1), *(ptr - 1));
	return 0;
}
程序结果是多少?

        &a+1从一个数组的地址变成了一个整形的地址,但是它们在数值上却没有发生任何变化,那把一个数组地址强制转换成整型地址的意义在哪呢?意义在于:不同类型的地址访问到的内存空间大小会有所不同,比如:一个整型地址只能访问到从当前地址开始,连续的四个字节的内容(一个地址指向一个字节);一个字符的地址只能访问到当前地址所指向的一个字节的内容;一个数组的地址可以访问到整个数组所占用的字节内容。把一个数组的地址强制转换成整型的地址,就好比把酒店中的总统套房改造成一个标间,虽然它们的门牌号都相同,但由于它们的房间类型发生了改变,所以里面房间的大小就会发生改变,从原来200平的总统套房,变成如今只有90平的标间。对地址类型的转变,主要体现在:地址加减整数上。比如:一个整型地址+1,会跳过4个字节(这里+1就表示跳过一个整型,一个整型就对应4个字节);上述代码中的数组地址+1,会跳过20个字节(数组中有5个整型元素,一个整型对应4个字节,5个整型就对应20个字节,这20个字节也就是a数组的大小)。       

解析:        

        对于ptr,&a得到的就是整个数组的地址,如果用一个指针变量来存储这个地址的话,指针变量的类型是:int (*) [5],&a+1跳过一整个数组,表示紧接着a数组后面的一个地址,这个地址还是表示一个数组的地址,然后把这个地址强制转换成整型指针,此时这个地址表示一个整型的地址。*(a + 1)其中a是数组名,表示首元素地址,也就是一个整型的地址,+1跳过一个整型,所以a+1表示数组中第二个元素的地址,解引用就会得到2。再看*(ptr - 1),此时的ptr指向数组a后面紧接着的地址,并且已经被强制转换成了整型指针,所以ptr-1会跳过一个整型,指向数组最后一个元素的地址,解引用就会得到5。
 所以最终这段代码会在屏幕上打印出:2 5

  笔试题2:

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

 解析:

        这里的p本质上是一个结构体类型的指针,这个结构体的大小是20个字节,+1跳过一个结构体的大小,也就是+20个字节,其中的0x表示十六进制,20的十六进制是14,所以这里的p+0x1就是:0x100000+0x14=0x100014。

        (unsigned long)p把指针变量p强制类型转换成整型变量,此时p的值0x100000就不再表示地址了,而是表示一个整数0x100000,(unsigned long)p + 0x1就是我们小学就学过的整数加法,结果等于0x100001。

        (unsigned int*)p把结构体类型的指针强制类型转换成整型指针,此时p的值0x100000还表示一个地址,但表示的是一个整型的地址,不再是结构体类型的地址,所以+1跳过一个整型,也就是+4个字节,(unsigned int*)p + 0x1就是0x100000+0x4=0x100004。最终%p打印的是地址,所以结果为:00100014、00100001、00100004.

        这里我们要注意的是我们平常说的%p打印地址其实是有不足的,实际上,%p是将数据按16进制的形式输出,即使不是地址,也是可以输出的

笔试题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;
 }

解析:

        &a拿到的是整个数组的大小,+1跳过一个数组的大小。 ptr[-1]就等价于*(ptr-1)。

       (int*)((int)a + 1)这里a本来表示数组首元素地址,这里先把其转换成整型,然后+1,这里进行的是整数加法,然后再把这个结果转换成整型指针,放到ptr2这个指针变量里面,ptr2的指向如下图所示。还需注意的是,在当前的编译环境下,数据是按照小端字节序的模式存到内存里面的,所以在从内存中读数据的时候也要注意。%x是以十六进制的形式打印。解引用ptr2,顺着他的地址往后访问四个字节。前面的0对于%x来说是没有意义的,所以不会打印出来。

最终结果是:4,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;
}

 解析:

        这题有个大坑,一个不注意就以为答案是0.其实a在初始化时花括号中的是逗号表达式。所以a中的元素其实是 {1,3}{5,0}{0,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;
}

        本题需要注意的点有:首先p是一个数组指针,指向的数组类型是:int [4]。也就是说p指向一个整型数组,这个数组有四个元素,其次a是二维数组名,表示首元素的地址,二维数组的首元素是a[0],也就是二维数组中第一行那个一维数组,所以a表示首元素地址,就是二维数组中第一行那个一维数组的地址,它的类型是int(*)[5],把这个类型的地址放到类型为int(*)[4]的指针变量里面,是可以强行放进去的。&p[4][2]其中p[4][2]就是&*(*(p+4)+2),这里需要注意p指向的数组只有四个元素,所以p+1跳过四个元素,这里p+4就会跳过16个元素。

        -4为原码,在内存中存的是补码,而%p打印的是16进制数,而且对于地址没有原反补的概念,所以会直接把-4的补码打印出来。

所以结果是:        FFFFFFFC、-4

笔试题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;
}

        本题需要注意的是:&aa拿到的是整个二维数组的地址&aa+1跳过整个二维数组,它的类型是int [2][5],然后把这个地址强制转换成int*型;aa数组名表示首元素地址,是第一行一维数组的地址,aa+1表示第二行一维数组的地址,解引用得到第二行的一维数组也就是aa[1],aa[1]是第二行一维数组的数组名,数组名表示首元素地址,也就是aa[1][0]的地址,aa[1][0]就是6,这里也就是6的地址,所以这原本就是一个整形的地址,(*(aa + 1))前面的强制类型转换就可有可无。本题最终的结果就是:10、5

笔试题7:

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

解析:

        本题需要注意的是:首先a是一个字符指针数组,说明a数组里面存放的是字符的地址,而字符串常量的值就是首字符的地址,所以a数组里面存放的就是"work"中'w'的地址、"at"中'a'的地址、"alibaba"中'a'的地址,数组名a表示首元素地址,a[0]里面存放的是'w’的地址,所以a[0]的地址就是'w'的地址的地址,也就是指针的地址,所以这用了一个二级指针变量pa来接收。char** pa应该这样来理解:首先* pa中的*告知我们pa是一个指针变量,char*告诉我们这个指针变量指向一个char*类型的数据,所以对pa++,会跳过一个char*类型的数据,此时pa指向a数组中的第二个元素a[1],也就是说此时pa指向'a'的地址,所以对pa解引用就会得到'a'的地址,然后以%s的格式打印,最终在屏幕上打印出:at

 笔试题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;
}

解析:

        根据图解,我们可以轻易看出指针所指的类型,c是一级指针数组,cp是二级指针数组,存储的是一级指针数组的地址,cpp是三级指针,指向二级指针数组的首元素地址。

1. printf("%s\n", **++cpp);

        第一个printf,先++cpp,cpp最初指向的是cp首元素地址,++后,cpp指向第二个元素地址。对cpp第一次解引用,得到cp数组中c+2的值,也就cp[1],而cp[1]指向c数组的第三个元素的地址,所以再进行第二次解引用,就可以得到c[2],c[2]装的是p的地址。打印出:POINT

2. printf("%s\n", *--*++cpp+3);

         第二个printf注意:此时cpp已经指向了cp第二个元素的地址(++的副作用),再++就指向ccp数组中的第三个元素,也就是指向cp数组中的第三个元素的地址,先对他解引用,得到cp[2],cp[2]就是c+1的地址,也就是c[1]的地址,--以后就指向c的首元素地址,解引用就表示c[1],也就是E的地址,+3以后就是Enter第二个E的地址,打印出:ER

 

3. printf("%s\n", *cpp[-2]+3);

         第三个printf,[]的优先级高于*,所以这里表示*(cpp-2),得到cp[0],也就是c[3]的地址,解引用以后就得到F的地址,这个时候+3就得到S的地址,所以结果是:ST

 

4. printf("%s\n", cpp[-1][-1]+1);

        第四个printf ,也就是*(*(cpp-1)-1)+1,所以结果是:EW.

 总结:

        总的来说,对于这些笔试题,我们只要弄清楚他们的类型,比如弄清楚指针的类型和指向,就可以知道步长,比如数组,要弄清楚数组名的意义,还有数组内元素的类型。通过这些题目,相信大家对指针和数组都有了深入的了解,我们对指针的学习先告一段落了,大家一定要记得多多复习哦!

        辛苦各位小伙伴们动动小手,三连走一波 最后,本文仍有许多不足之处,欢迎各位认真读完文章的小伙伴们随时私信交流、批评指正!

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

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

相关文章

JVM--Garbage First(G1) 垃圾收集器

G1 (Garbage-First)是一款面向服务器的垃圾收集器,主要针对配备多颗处理器及大容量内存的机器. 以极高概率满足GC停顿时间要求的同时,还具备高吞吐量性能特征。G1垃圾回收器是在Java7 update 4之后引入的一个新的垃圾回收器,在 JDK9 中更被指定为官方GC收集器一、G1…

【零基础】学python数据结构与算法笔记12

文章目录前言74.AVL树的概念75.AVL:旋转76.AVL:旋转实现177.AVL:旋转实现278.AVL:插入79.AVL树应用与数据结构总结总结前言 学习python数据结构与算法,学习常用的算法, b站学习链接 74.AVL树的概念 首先看一下二叉搜索树的效率 平均情况下&#xff0c…

networkx学习(三) 小世界网络

networkx学习(三) 小世界网络 1.小世界网络模型 K-近邻规则网络的生成与可视化

彻底分析Arduino库安装和开发板库安装路径和方式

参考:https://blog.csdn.net/weixin_43794311/article/details/128631564,https://blog.csdn.net/t01051/article/details/103766886 一个最简单的安装esp8266和esp32的方法 在网址:https://arduino.me/download,下载对应的开发…

dp(七)把数字转化为字符串 (力扣版+牛客版) 跳台阶问题+最小花费跳台阶

目录 l剑指 Offer 46. 把数字翻译成字符串力扣版本 把数字翻译成字符串_牛客题霸_牛客网牛客版 滚动数组优化 跳台阶【一】 (大数取模)一 八个零七 最小花费爬楼梯 l剑指 Offer 46. 把数字翻译成字符串力扣版本 给定一个数字,按照对应的格…

【微信小程序入门到精通】—小程序实战构建售货平台首页

目录前言一、步骤阐述二、新建项目并梳理结构三、配置导航栏四、tabBar 实现五、轮播图实现总结前言 对于目前形式,微信小程序是一个热门,那么我们该如何去学习并且掌握之后去做实际项目呢? 为此我特意开设此专栏,在我学习的同时也…

买车是个计算题,看上了比亚迪的宋DMI,选择困难了,选择55km的还是,110km的,理科生一起计算下。

1,背景 赶时髦,啥新鲜就购买啥,最火的车子当然是比亚迪宋dmi。 大家都买说明还不错,买车还要排队。等上一阵子了。 而且可以省下购置税。 就按照最热销的110 km 的版本 17/1.13*0.1 1.50 w 按照发票上“价税总计”金额计算的话…

计算两个字符串的相似度difflib.SequenceMatcher

【小白从小学Python、C、Java】 【计算机等级考试500强双证书】 【Python-数据分析】 计算两个字符串的相似度 difflib.SequenceMatcher 选择题 对于以下python代码表述错误的是? from difflib import SequenceMatcher myText1"我想学习Python做人工智能项目" myTex…

SpringCloud-Netflix学习笔记01——SpringCloud入门

一、SpringCloud是什么 Spring官网:https://spring.io/ SpringCloud, 基于SpringBoot提供了一套微服务解决方案,包括服务注册与发现,配置中心,全链路监控,服务网关,负载均衡,熔断器等组件&#…

mybatis plus基本使用初体验02

1.常用注解 1.1 TableName注解 MyBatis-Plus在确定操作的表时,由BaseMapper的泛型决定,即实体类型决定,且默认操作的表名和实体类型的类名一致。若实体类类型的类名和要操作的表的表名不一致,会出现什么问题? 将数据…

力扣sql基础篇(八)

力扣sql基础篇(八) 1 大满贯数量 1.1 题目内容 1.1.1 基本题目信息 1.1.2 示例输入输出 1.2 示例sql语句 # Championship的数字代表的就是赢得比赛的球员的id,可以使用行转列(UNION all) #如果涉及到分组函数,建议还是不要写除了分组字段外的其他字段,因为不太符合标准sql …

正则化:五重境界理解减少过拟合的神器

本文来自公众号“AI大道理” 正则化作为减少过拟合的手段被大量的使用,那么为什么会出现过拟合呢?正则化又是什么?是怎么样发挥作用的呢? 1、过拟合是什么? 过拟合是指模型在训练集上取得很高的识别性能&#xff0c…

Ubuntu 22.04配置静态IP地址

1、查看ip地址网卡名称:ifconfig 2、编辑网卡配置文件:sudo vim /etc/netplan/01-network-manager-all.yaml 默认样式: network: version: 2 renderer: NetworkManager 3、修改为: network: ethernets: enp7s0: dhcp4: no dhcp6: …

【Kotlin】集合操作 ① ( List 创建与元素获取 | 安全获取集合元素 | getOrElse | getOrNull )

文章目录一、List 创建与元素获取二、安全获取集合元素1、getOrElse 函数2、getOrNull函数三、List 创建与元素获取代码示例一、List 创建与元素获取 Kotlin 中的集合分为两类 , 只读集合 和 可变集合 ; 调用 listOf 函数 , 可以 直接创建 List 集合 ; 通过 [] 下标可以 直接获…

Spring系列 容器

创建容器 方式一:类路径加载配置文件: ApplicationContext ctx new ClassPathXmlApplicationContext("applicationContext.xml"); 方式二:文件路径加载配置文件(用绝对路径): ApplicationConte…

闲话统信UOS

这周统信UOS正式在官网发布了22.0镜像统信UOS家庭版官网-正版国产操作系统--统信软件 (uniontech.com) 支持双系统:不影响原有系统使用,更换系统不担心电脑资料丢失; 官方应用商店:无病毒、放心安全下载,工作学习无打…

[C/Linux练习]进度条小程序

前置知识点 \n\r \n 换行,但只是垂直向下,并不水平移动。 \r 回车,返回当前行的头部。 光标返回头部后再打印,会从头开始覆盖之前打印在该行的内容。 printf的\n默认解释成换行回车。 光标是与显示器匹配的,光标在哪…

基于PHP的宠物社会化小程序

摘要随着信息技术和网络技术的飞速发展,人类已进入全新信息化时代,传统管理技术已无法高效,便捷地管理信息。为了迎合时代需求,优化管理效率,各种各样的管理系统应运而生,各行各业相继进入信息管理时代&…

Java集合面试题

集合容器概述 什么是集合 集合框架:用于存储数据的容器。 集合框架是为表示和操作集合而规定的一种统一的标准的体系结构。 任何集合框架都包含三大块内容:对外的接口、接口的实现和对集合运算的算法。 接口:表示集合的抽象数据类型。接口…

AlexNet,VGG,NiN,GoogleNet,批量归一化

学着学着突然发现,数据分析numpy,matplotlib,pandas这一部分内容没学完,还有pytorch的一些代码没有学完,所以在看像AlexNet这一些代码实现的时候,很多都看不懂,也得慢慢的补上来了hhh。这一周花…