众所周知,指针作为c语言中极其重要的一部分,不知道小伙伴们是否熟练掌握了这一部分知识呢
下面我们通过八道企业面试题目来测试一下自己,看自己能对几个
笔试题1:
此题正确答案为:2,5
解析:
数组a如图所示, 第二行代码中 &a+1 则是解决本题的重要细节 &a是取出整个数组的地址,而不是数组a的首地址,&a+1 即 ptr地址如下图所示
printf(“%d,%d”,*(a+1),*(ptr-1));
其中*(a+1)则是取出数组a首地址再加一,即为数组中第二个元素 2;
*(ptr-1)也很容易的看出来指向 5;
因此本题的答案就是2和5.
笔试题2:
此题正确答案为: 0x100014 0x100001 0x100004
解析:
首先 p+0x1 ->p+1 而p大小为0x100000 且题目告诉了结构体Test类型的变量大小是20个字节
0x100000+20 =0x100020 又因为寻址是以16进制存储的 20的16进制为14
则 0x100000+20 的结果为0x100014
将p强制转化为 unsigned int类型
1048576+1=1048577 再转化过来就是0x100001
最后一个将p强制转化为unsigned int类型的指针 +1就是跳过4个字节
即0x100000+4 =0x100004
笔试题3:
此题正确答案为: 4,2000000
解析:
ptr1 与笔试题1所述同理 &a+1就是ptr1指向的地址
(int)a, 我们知道a是表示数组首元素地址,将a强制转化为int类型再加1,会是什么样的结果
将a强制转化为int类型 再加1 就意味着a只会向后移动一个字节 指向 “00” 即为ptr2指向的地址
ptr[-1] 可以写为 *(ptr-1) 那么很容易知道ptr[-1]指向 4 了
ptr2为(int*)类型 包含4个字节 即为 00 00 00 02 由于是小端存储方式,打印出来即为00000002
笔试题4:
此题答案为:1
解析:此题值得注意的是在二维数组a中的定义,里面的并不是分割一维数组的大括号,而是小括号,从而导致里面成为逗号表达式。
(0,1),(2,3),(4,5) 可得二维数组前三个元素为 1,3,5 剩下的未完全初始化,全部为0
a[0]为a第一行数组名 又因为这里并不是单独放在sizeof和取地址的情况下,则表示为首元素地址
p[0]——>*(p+0) 由图可知显而易见就是 1
笔试题5:
此题答案为: FFFFFFFC,-4
解析:int (*p)[4] 是一次指向4个元素的数组指针
找到&a[4][2]的地址和&p[4][2]的地址 而&p[4][2]可以转化为 *(*(p+4)+2) 而p每次跳过4个元素
指针的运算,指针减去指针是中间相差几个元素 由图可知 为4个 答案为-4
-4 用%p打印 以-4的补码存储 -4的补码为11111111111111111111111111111100
再换成16进制 ff ff ff fc 即是答案
笔试题6:
此题答案为:10,5
这题相对简单 与第一题思路类型,不做过多的讲解
笔试题7:
此题答案为:at
解析:
char** pa=a; pa指向a的首地址
由图可知 pa++ 指向了“at” ,解引用内容就是at 接着打印出来就是答案
笔试题8:
此题答案为: ENTER ER ST EW
解析:
本题难度较大,需要层层剖析,画图理解,仔细思考
首先将cp中的 c+3,c+2,c+1,c 分析出来 c表示指针数组c的首地址
**++cpp ++cpp指向c+2 接着再次解引用指向POINT 即为第一个答案
*--*++cpp+3 ,由第一步影响,cpp指向的地址已经发生变化 指向 c+1 解引用得出 c+1
c+1 再进行--操作符变成c 解引用指向 ENTER 再+3 指向E 接着将后面的ER打印出来则为答案
cpp[-2] -->*(cpp-2) 指向FIRST 再+3 与上面+3同理 指向了S ,打印出ST为答案
cpp[-1][-1]----> *(*(cpp-1)-1) 同理可知 *(cpp-1) 解引用指向了POINT 再+1 则指向了NEW
最后再次+1 从指向N到了指向E,最后将EW打印出来即为答案