一、概述
前段时间碰到这么一个有趣的题目:
int a = 0x1234abcd;
char* b = (char*)(&a);
printf("%d\n", *b);
请问输出的内容是什么?
二、分析
题目大概的意思是,int类型的指针转换为char类型的指针后,会读取原来哪些内容。int类型是4个字节,char类型是1个字节,肯定只能读取一部分内容,所以只要找到这读取的部分内容,输出的值自然就明白了。
首先,为了简化难度,我们用一个简单的方便表示成二进制的数字:int a = 0x80808081;对应的二进制就是:10000000 10000000 10000000 10000001。把a转换成char类型指针后,读取指针内容,很明显只能读取一个字节。指针肯定是从int首地址开始读取的,那么读取的是哪个字节呢?10000000还是10000001呢?做个试验就知道了。代码如下:
#include "stdafx.h"
int _tmain(int argc, _TCHAR* argv[])
{
unsigned int a = 0x80808081;
char* b = (char*)(&a);
printf("%d\n", *b);
return 0;
}
输出的结果是:
-127的补码是:10000001(只取8位),所以char指针读取的是a的低位数值。同时我们也知道了,在vs 2013的环境下(我是在vs 2013中做的实验),高位存储在高地址,低位存储在低地址中。
好,同样的道理,我们来看看当a=0x1234abcd时,输出是多少。
首先将其表示为二进制得:10010001101001010101111001101
然后我们取低8位得:11001101
最后将补码转换为十进制得:-51
看看程序运行结果是多少,代码如下:
#include "stdafx.h"
int _tmain(int argc, _TCHAR* argv[])
{
unsigned int a = 0x1234abcd;
char* b = (char*)(&a);
printf("%d\n", *b);
return 0;
}
输出的结果是:
与我们的分析的结果刚好一致。
这里我们是将int*转换成了char*类型,读取的内容是截取了的。那么如果将char*类型转换为int*类型呢?因为Int*会读取4个字节,所以应该是随机的值。实验代码和结果分别如下:
#include "stdafx.h"
int _tmain(int argc, _TCHAR* argv[])
{
unsigned char a = 0xa;
int* b = (int*)(&a);
printf("%d\n", *b);
return 0;
}
运行结果:
运行结果应该是因人而异就对了。
希望这个有趣的试验可以帮助你更好的理解指针。^_^