求p[0]–p[5]的值
#include <stdio.h>
int main(void)
{
char* data = "12345678";
short* tmp = NULL;
char p[6] = {0};
tmp = (short *)&p[2];
*tmp = atoi(&data[4]);
p[0] = ?, p[1] = ?, p[2] = ?,
p[3] = ?, p[4] = ?, p[5] = ?。
return 0;
}
从题中可知,数组p[6]中有6个元素,同时,全部初始化为0。而tmp是从p[2]开始存储数据的,同时占据的空间是四个元素,
从中可以知道,p[0],p[1],p[4],p[5]全部都等于0.接下来只需要探讨p[2]与p[3]的取值就可以了。
*tmp = atoi(&data[4]) atoi()函数是将字符类型转换成int类型的函数,在这里就是说把字符串“5678”转换成数值5678。
那么5678存储在p[2]与p[3]之中,是怎么存储的呢?
我们知道,计算机存储的数据都是以二进制的格式进行存储与输出的,而我们所见到内容是计算机内部编译后生成的。
从题中可知,p的类型是char类型,char类型占空间1字节(8个bite位),而数值5678是整数类型的数据。tmp的类型是short类型,在空间中占2字节(16个bite位)。由此可知tmp中一个元素中存储char类型的两个元素。
如果在这里写p[2] = 56 ,p[3] = 78;那么答案是错误的,为什么呢?数值5678是整数类型,而p[2],p[3]的类型是char类型。
类型不同,怎么能直接赋值呢!这里我们还需要进行类型的转换。
数值5678转换成16进制的数值是,这里可以借助计算器进行计算,结果是 0x162E。计算机的数据的存储一般(小端系统)是从低位向高位进行存储的。所以p[2] 存储的是低位的0x2E ,p[3]存储的是高位的0x16。所以结果是:
p[2] = 0x2e(大写E也正确) p[3] = 0x16;
转换成十进制是p[2] = 46 ,p[3] = 22。
前文提到计算机的存储一般是低位向高位进行存储,那么就有特别的,部分电脑可能是大端系统,存储的方式相反,低位存储高位的数值,高位存储低位的值。那么p[2]与p[3]的值正好调换。所以,这道题在未规定在什么端的系统下时,保险起见,可以把两种情况全部写上。结果为:
(小端系统下)p[2] = 0x2e (大写E也正确) p[3] = 0x16; (十进制写法)p[2] = 46,p[3] = 22
(大端系统下)p[2] = 0x16, p[3] = 0x2e(大写E也正确); (十进制写法)p[2] = 22 , p[3] = 46
部分详细情况如下图。
拓展:大小端问题
判断自己的电脑是大端还是小端的代码如下:
#include <stdio.h>
int main(int argc, const char *argv[])
{
unsigned int a = 0x12345678;
unsigned char *p = (unsigned char *)&a;
if(*p == 0x78){
printf("小端系统\n");
}else if(*p == 0x12){
printf("大端系统\n");
}
return 0;
}