目录
创作不易,如对您帮助,还望一键三连,谢谢!!!
上次我们讲解了数组笔试题目,今天我们接着讲解指针经典的笔试题目。
话不多说,我们直接来看题目:
题目一:
这段代码运行结果是什么呢?
&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。
至此,我们把数组和指针的一些经典笔试题讲解完毕。希望大家能有所收获。