数组和指针经典笔试题讲解下

目录

创作不易,如对您帮助,还望一键三连,谢谢!!!

题目一:

题目二:

题目三:

题目四:

题目五:

题目六:

题目七:


创作不易,如对您帮助,还望一键三连,谢谢!!!

上次我们讲解了数组笔试题目,今天我们接着讲解指针经典的笔试题目。

话不多说,我们直接来看题目:

题目一:

这段代码运行结果是什么呢?

&a是&数组名,取出的是整个数组的地址,类型是int(*)[5],&a+1跳过整个数组,指向数组后面的内存地址,紧接着又进行了强制类型转换,转换成了int*类型的指针。

*(a+1),此时a表示数组首元素的地址,a+1表示第二个元素的地址,对其解引用得到第二个元素2,所以第一个打印结果为2。

*(ptr-1):ptr指向数组后面的内存地址,ptr-1指向了数组的最后一个元素5,解引用得到数组最后一个元素的值5,所以打印结果为5

示意图如下所示:

题目二:

这个结果又是多少呢?

我们首先创建了一个二维数组,创建了一个int*类型的p指针,并进行了p=a[0]的操作,那么此时a[0]表示什么呢?它既没有单独放在sizeof内部,也没有对其单独进行&操作,所以此时a[0]表示二维数组首元素的地址,那么p[0]其实就是*(p+0),也就是得到数组第一个元素。

那么问题来了,数组第一个元素是什么,是0吗?

有一部分粗心的小伙伴肯定立马写出0,但我们认真看二维数组a的初始化,就能从中发现端倪:二维数组初始化它使用了诸如(x,y)这种形式的初始化方式,这是什么?这是逗号表达式!所以该初始化只初始化了数组前三个元素,赋值为:1,3,5,其余全为0

所以本题的结果为1.

题目三:

这段代码在给定条件下结果为多少?

首先,我们来看题目:p是一个结构体指针,后面全是对p进行加减整数,这不就是考察指针加减整数吗?

p是一个结构体指针,p+1就跳过整个结构体。

p+0x1:就是p+1,跳过一个结构体,就是20个字节,所以就是0x00100000+20,注意进制不同!一个是16进制,一个是10进制,结果为0x00100014

(unsigned long)p+0x1:这里把p强制类型转换为unsigned long类型,是个长整型,整形加一不就是加一吗?所以结果为0x0010001.

(unsigned int*)p+1:这里把p强制类型转换为unsigned int*类型,是个指针,此时p+1跳过一个unsigned int大小的元素,也就是跳过4个字节,所以就是0x00100000+4,结果为0x00100004。

我们运行代码,发现结果正确:

题目四:

我们先看题目,创建了一个数组指针p,指向一行为4个元素的数组

接着又p=a,此时a表示数组首元素的地址,也就是二维数组第一行的地址,那二维数组每行不应该是5个元素吗?没错,这两个类型不一样:一个是int(*)4,一个是int(*)5,这一点我们要能看出来。

接着就是要找到a[4][2]和p[4][2]了。

我们先来回忆一下一个重要的知识:二维数组每行在内存中是连续存放的,可以看成一个个连续的一维数组。

p[4][2]==*(*(p+4)+2),知道这个,我们就能找到&p[4][2]的位置了,最后要计算&p[4][2]-&a[4][2]就是指针减去指针,得到的是二者之间的元素个数,为4,注意这里是-4.

-4在内存中存放的是其补码,为:11111111 11111111 11111111 11111100

我们再来看一个按%p打印,一个按照%d打印。

%p是按地址打印,而地址有负数吗?没有,所以会自动把数据当成正数,正数原反补码相同,故结果为0XFFFFFFFC。

%d是按十进制整数打印,所以结果就是-4。

题目五:

这道题目考察的是二维数组数组名的理解,昨天我们系统的讲过了,这题就十分简单了:

ptr1:&aa取出的是整个二维数组的地址,类型为int(*)[2][5],加一跳过整个数组,指向数组后面的内存地址,接着又强制类型转换为int*类型,故ptr1-1指向二维数组最后一个元素,解引用得到二维数组最后一个元素10,故打印结果为10。

ptr2:aa表示数组首元素的地址,即为二维数组第一行的地址,aa+1跳过一行,指向二维数组的第二行,*(aa+1)访问得到二维数组的第二行,强转为int*类型,所以ptr2-1指向5,解引用得到5,最后打印结果为5

题目六:

这题目一看,秒了:阿里巴巴的笔试题。哈哈~。

我们来看题目:定义了一个指针数组a,数组中存放着“work” ,“at”,“alibaba”的首元素的地址。

pa是一个二级指针,存放着a的地址,pa++,此时指针加一,跳过一个元素,也就是跳过一个char*类型的元素:

对pa进行解引用得到字符串“at”的首元素的地址,故打印结果为at。

题目七:

作为压轴题,这道题还是有一定的难度的,接下来我们来一步步讲解:

这是上诉代码大致示意图,定义了一个指针数组c,指向内容如图所示,又定义了一个指针数组cp指向内容如图所示,又定义了一个指针,指向cp。

先看这段代码,++cpp,cpp跳过一个元素,指向cp第二个元素,对其解引用得到cp的第二个元素,在解引用得到c数组的第三个元素,也就是“POINT”的首元素地址,对其进行打印,故结果为POINT.

注意,因为进行了++cpp操作,此时cpp的指向已经改变,指向cp的第二个元素,如下图所示:

接下来来看下一个:

++cpp改变了cpp的指向,此时cpp指向cp的第三个元素,解引用访问得到cp的第三个元素,

而cp的第三个元素指向c的第二个元素“NEW”的首元素地址,--*++cpp对其进行自减运算,此时cp数组的第三个元素的指向被改变,指向了c数组的第一个元素。

最后进行+3操作,指向了ENTER的第四个字符的地址,故打印结果为ER。

示意图如下:

再看下一个:

cpp[-2]==*(cpp-2),故cpp[-2]访问得到cp首元素,再次解引用访问到c数组第四个元素,也就是FIRST首元素的地址,+3操作,得到S的地址,故打印结果为ST.

这里没有对指针进行自增自减操作,故指针指向不变,仍然为:

最后一个:

cpp[-1][-1]==*(*(cpp-1)-1)。

*(cpp-1)得到cp数组的第二个元素。

*(*(cpp-1)-1)就相当于*((*(cp+2))-1),使得cp第二哥元素指向了c的第二个元素,也就是NEW收元素的地址,+1跳过一个元素,指向了NEW第二个元素的地址,故打印结果为EW。

至此,我们把数组和指针的一些经典笔试题讲解完毕。希望大家能有所收获。

评论 36
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值