昨天群里有个同学发了这样一个题目过来,这个题目应该是嵌入式笔试经典题目了,如果是校招的话,笔试不考这个题目,都觉得有点说不过去。

#include <stdio.h>

int main()
{
	int a[5] = {1,2,3,4,5};
	int *ptr1 = (int *)(&a +1);
	int *ptr2 = (int *)(a +1);
	
	printf("%x,%x \n",ptr1[-1],*ptr2);
	
	return (0);
}

这个输出我相信很多人都能看出来是什么了吧,之前我记得在文章里面也有分析过这个题目。实力剖析一个经典笔试题_其他

好了,我稍微修改下这个题目,改成下面这样的

#include <stdio.h>

int main()
{
	int a[5] = {1,2,3,4,5};
	int *ptr1 = (int *)(&a +1);
	int *ptr2 = (int *)((int)a +1);
	
	printf("%x,%x \n",ptr1[-1],*ptr2);
	
	return (0);
}

大家好好看题目哈 我把

(int *)(a+1);

改成了

(int *)((int)a +1);

我们知道,a 代表的是数组的首元素的地址,它如果加1 的话,那么应该是

&a[0] + sizeof(int)

这里偏移的应该是一个 a[0] 的长度,因为 a 是代表的 数组元素,这个数组元素是 int

但是

(int *)((int)a +1);

这个加1的话,就不一样了,a 被强制转换成了 int,这个时候加1,就是简单的数学运算增加1。所以这个值应该是

&a[0] +1

 

我们看看两个截图

实力剖析一个经典笔试题_其他_02

看到没有,跟我们上面的预测一样

再看看下面的这个,就真的只是增加1而已。

&a[0] + sizeof(int)

实力剖析一个经典笔试题_其他_03实力剖析一个经典笔试题_其他_04所以,我们上面说的这段代码

#include <stdio.h>

int main()
{
	int a[5] = {1,2,3,4,5};
	int *ptr1 = (int *)(&a +1);
	int *ptr2 = (int *)((int)a +1);
	
	printf("%x,%x \n",ptr1[-1],*ptr2);
	
	return (0);
}

最终输出什么呢?这个就涉及我们之前讨论的一个问题,大小端了,先贴出输出结果实力剖析一个经典笔试题_其他_05

我写了个小程序来说明为什么是这个结果,我先说下,我们PC默认的是小端模式实力剖析一个经典笔试题_其他_06

b的值就是我们ptr2 指向的数据,他们的内存组合是一样的,因为Dev C++ 对内存显示还不是非常完美,不能直接看到内存,如果用VC

来调试就更加清晰了。

实力剖析一个经典笔试题_其他_07

看了这个图,我是不是应该什么都不需要说了,可能有人想问我,怎么找到VC6.0的安装包,我就是不告诉你们,等你们来找我。


实力剖析一个经典笔试题_其他_08