新闻  |   论坛  |   博客  |   在线研讨会
深入剖析一道有意思的面试题
鱼鹰谈单片机 | 2021-06-03 05:20:59    阅读:351   发布文章

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

1.png

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

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

2.png

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

1、答案是4

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

3.png

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

&arr

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

&arr + 1

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

4.png

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

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

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

5.png

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

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

6.png

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

7.png

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

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

1、各种优先级

2、强制转化

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

4、数组的分布问题。

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

8.png

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

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

9.png

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

10.png

其实鱼鹰在测试该问题时,发现优化级别3和 优化级别0 的结果是完全不同的,可能编译器在优化时发现了代码的傻逼,直接给了一个比较固定的值,即数组的末尾地址(注意结果就是给了一个地址,而不是取它的值,感兴趣的可以自己使用 MDK 测试一下)。

不管你是修改上面的 1 还是 2,都是固定不变的。

但优化级别0就是你理解的结果。

从中也可以明白级别优化的影响了,所以如果结果和自己想不一样,不如先把优化级别设置为最低再测试。

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客