1、大小端的区别
大小端的区别和关系可以从上图中得知,对于0x12345678数据来说0x12就是最高位,0x78则是数据的最低位,地址从上往下表示:0x40000000 ~ 0x40000003,每个地址下是8bit 也就是1byte的数据长度。小端会把数据低位数据放到地址低处,所以会把0x78放到0x40000000的地方,0x12是最高位,所以会放到最高地址处。大端则是相反,大端的时候,会把数据高位0x12放到地址低处,0x78放到地址最高处。
2、变量
了解了大小端之后就能来看看我们在程序里申请的变量是怎么存放在内存中的了,关于怎么判断当前系统或软件是大端小端,读者们也可以在csdn上找一下相关资料,这里主要讲解变量是怎么在内存中存储的,一般都是小端存储的。
通过上面两张图片可以看出当前定义了一个 int32_t 的变量show,通过char *强转获得show的首地址,并且能以char的形式来解析 show,可以看到在地址低处是0x78,而最高位则是0x12,从此处也可以看出当前变量是以小端模式来存储的,即地址地位存放数据的低位,这里0x12在数据最左边,因此是数据的最高位,这个不能搞错了。所以该变量在内存中存储的方式便是开篇第一幅图右边的存储方式,只是地址改了一下而已。
3、数组
明白了变量的存储方式,我们接下来看看数组的存储方式
从数据可以看出数组在内存中的存储方式是从左往右,数组低位数据就是在地址低处的,即存储方式如下图
那么数组和大小端又有什么关系呢,这里是char类型看不出来,定义一个short类型就能看出来了
可以看到数组按照地址顺序存放,并且数组里每组数据大于一字节的时候,又遵循小端模式
4、数组强转
了解了变量和数组的存放,接下来就是数组的类型强转了,为什么有的时候数组类型强转后数据正确,有的时候强转之后数据又会变化了呢
从上图可以看出因为数组是顺序存放,而解析 int16_t 数据的时候是从高位地址解析,所以解析出来的数据是0x3412,第二个数据同理,所以解析出来是0x7856。
上面的操作我们是直接对数组赋值,所以内存存储的也就按照我们数组的数据存放,所以解析出来的数据便会反着来,那为什么有的时候数组转化出来的数据就是正确的呢,可以看下图
通过这个就能看出,因为一般我们是先对对应数据比如 int16_t , int32_t 的数据进行赋值,再将其数据通过memcpy或者其他赋值操作给到数组,当一个变量 int16_t data = 0x1234给到数组的时候,其实此时数组里的数据已经是 0x3412也就是 0x34 , 0x12了,所以之后从数组里拿出数据再重新转换回来的时候才能是正确的数据,假如我们直接给数组赋值 0x1234,也即0x12,0x34,那解析出来就不对了,所以这就是为什么有的时候数据是能正确解析,有的时候就会相反,其实说到底就是内存里存储的数据放在高位和低位不一样,这样解析出来的数据就会不一样而已。
最后附上这些演示的代码
printf("/\r\n");
int32_t show = 0x12345678;
char* p = (char*)&show;
printf("show = %x\r\n",show);
printf("the Address of p is:%p\r\n",p);
printf("the Address of (p + 1) is:%p\r\n",(p + 1));
printf("the Address of (p + 2)is:%p\r\n",(p + 2));
printf("the Address of (p + 3) is:%p\r\n",(p + 3));
printf("the Value of p is:%x\r\n",*p);
printf("the Value of (p + 1) is:%x\r\n",*(p + 1));
printf("the Value of (p + 2) is:%x\r\n",*(p + 2));
printf("the Value of (p + 3) is:%x\r\n",*(p + 3));
printf("**********************************************\r\n");
char array[4] ={0x12,0x34,0x56,0x78};
char* array_p = &(array[0]);
printf("the Address of array_p is:%p\r\n",array_p);
printf("the Address of (array_p + 1) is:%p\r\n",(array_p + 1));
printf("the Address of (array_p + 2)is:%p\r\n",(array_p + 2));
printf("the Address of (array_p + 3) is:%p\r\n",(array_p + 3));
printf("the Value of array_p is:%x\r\n",*array_p);
printf("the Value of (array_p + 1) is:%x\r\n",*(array_p + 1));
printf("the Value of (array_p + 2) is:%x\r\n",*(array_p + 2));
printf("the Value of (array_p + 3) is:%x\r\n",*(array_p + 3));
printf("...............................................\r\n");
short s_array[3] ={0x1234,0x5678,0xabcd};
char* s_array_p = (char*)&(s_array[0]);
printf("the Address of s_array_p is:%p\r\n",s_array_p);
printf("the Address of (s_array_p + 1) is:%p\r\n",(s_array_p + 1));
printf("the Address of (s_array_p + 2) is:%p\r\n",(s_array_p + 2));
printf("the Address of (s_array_p + 3) is:%p\r\n",(s_array_p + 3));
printf("the Address of (s_array_p + 4) is:%p\r\n",(s_array_p + 4));
printf("the Address of (s_array_p + 5) is:%p\r\n",(s_array_p + 5));
printf("the Value of s_array_p is:%x\r\n",*s_array_p);
printf("the Value of (s_array_p + 1) is:%x\r\n",*(s_array_p + 1));
printf("the Value of (s_array_p + 2) is:%x\r\n",*(s_array_p + 2));
printf("the Value of (s_array_p + 3) is:%x\r\n",*(s_array_p + 3));
printf("the Value of (s_array_p + 4) is:%x\r\n",*(s_array_p + 4));
printf("the Value of (s_array_p + 5) is:%x\r\n",*(s_array_p + 5));
printf("|||||||||||||||||||||||||||||||||||||||||||||||||\r\n");
char change_array[4] ={0x12,0x34,0x56,0x78};
int16_t * int16_change_p_first = (int16_t*)&(change_array[0]);
int16_t * int16_change_p_second = (int16_t*)&(change_array[2]);
printf("the Address of change_array[0] is: %p\r\n",&change_array[0]);
printf("the Address of change_array[1] is: %p\r\n",&change_array[1]);
printf("the Address of change_array[2] is: %p\r\n",&change_array[2]);
printf("the Address of change_array[3] is: %p\r\n",&change_array[3]);
printf("the Value of change_array[0] is: %x\r\n",change_array[0]);
printf("the Value of change_array[1] is: %x\r\n",change_array[1]);
printf("the Value of change_array[2] is: %x\r\n",change_array[2]);
printf("the Value of change_array[3] is: %x\r\n",change_array[3]);
printf("the Address of int16_change_p_first is: %p\r\n",int16_change_p_first);
printf("the Value of int16_change_p_first is: %x\r\n",*int16_change_p_first);
printf("the Address of int16_change_p_second is: %p\r\n",int16_change_p_second);
printf("the Value of int16_change_p_second is: %x\r\n",*int16_change_p_second);
printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\r\n");
int16_t int16_data = 0x1234;
char *int16_data_p = (char*)&int16_data;
char save16_data_array[4] = {0};
for(int i = 0; i < 2; i++)
{
save16_data_array[i] = int16_data_p[i];
}
int16_t *arrayToInt16 = (int16_t* )&save16_data_array[0];
printf("the Address of int16_data_p is: %p\r\n",int16_data_p);
printf("the Address of (int16_data_p + 1) is: %p\r\n",(int16_data_p + 1));
printf("the Value of int16_data_p is: %x\r\n",*int16_data_p);
printf("the Value of (int16_data_p + 1) is: %x\r\n",*(int16_data_p + 1));
printf("the Address of save16_data_array[0] is: %p\r\n",&save16_data_array[0]);
printf("the Address of save16_data_array[1] is: %p\r\n",&save16_data_array[1]);
printf("the Value of save16_data_array[0] is: %x\r\n",save16_data_array[0]);
printf("the Value of save16_data_array[1] is: %x\r\n",save16_data_array[1]);
printf("the Address of arrayToInt16 is: %p\r\n",arrayToInt16);
printf("the Value of arrayToInt16 is: %x\r\n",*arrayToInt16);