首页|资源下载
登录|注册

您现在的位置是:首页 > 技术阅读 >  深入剖析一道有意思的面试题

深入剖析一道有意思的面试题

时间:2022-09-29

来源:公众号【鱼鹰谈单片机】

作者:鱼鹰Osprey

ID   :emOsprey


鱼鹰在技术交流群看到这样一道面试题:

请问这道题的result值是什么(32 位机器)?

变换一下,结果又是什么?

在看鱼鹰剖析之前,建议认真思考之后再看下面的答案。

1、答案是4

2、答案不确定,结果可能是随机的(为什么用可能)。

首先分析上面这道题,从里到外一步步分析:

&arr

数组的首地址,并且得到的对象还是数组,可理解为对象 int(*p)[5];

&arr + 1

因为目前的操作对象还是数组形式,所以 + 1 时,实际上操作单位大小是数组,也就是 4* 5,也就是说此时地址指向了数组的末尾。


因为只申请了 5 个 int空间,所以这个空间之外的值是不知道的,但幸好这里又使用了强制转化,将数组对象转化了成了 int* 指针。

这样一来,操作对象就不再是数组,而是 int*指针。

这样我们就可以按照 int的大小移动指针,这里是 2 ,所以按照 int大小移动,就在 4 的位置。

最后取这个地址的值,这就是为什么这道题的答案是 4


其实如果要增加难度,可以这样:

强制转化为 char *, 并且修改移动大小 8,此时答案还是 4

如果不修改移动大小,还是 2 ,那么值就是 0 。但是对于数组的初始值大于两个字节的情况(目前的初始值很小),此时你必须提供机器的大小端情况,否则你将受到面试者的鄙视(出题不严谨)。


所以这道题不是闲着慌,很考验面试者对指针的理解。并且综合考察了以下几个方面:

1、各种优先级

2、强制转化

3、地址的操作对象问题。

4、数组的分布问题。


对象这个词可能更多体现在面向对象语言的书籍中,事实上,C 语言中也处处蕴含该思想,只是它更多的是内存对象,比如下面这种:

虽然都是自加操作,但因为内存对象不同,自加的值也不同。同理,自减也一样。


言归正传,下面这个又该如何分析呢?

实际上,理解了上面的分析过程,这道题也能分析,只不过麻烦的是这道题的指向不在数组内,而在数组之外(arr- 20),导致取得值并不确定。

其实鱼鹰在测试该问题时,发现优化级别3优化级别0 的结果是完全不同的,可能编译器在优化时发现了代码的傻逼,直接给了一个比较固定的值,即数组的末尾地址(注意结果就是给了一个地址,而不是取它的值,感兴趣的可以自己使用 MDK 测试一下)。
不管你是修改上面的 1 还是 2,都是固定不变的。
但优化级别0就是你理解的结果。
从中也可以明白级别优化的影响了,所以如果结果和自己想不一样,不如先把优化级别设置为最低再测试。


关于指针,也可以看这篇文章《指针,很难吗?| 解析指针的过程与意义(一)


希望本篇剖析对你有帮助,下期再见咯!