小端大端、判斷方法和筆試題
小端模式(Little-Endian):低位元組儲存在低地址(先存)
大端模式(Big-Endian):高位元組儲存在低地址(先存)
使用union聯合體判斷
union A
{
int i;
char c;
}a;
a.i=1;
printf("%d",a.c);
小端儲存:
i 0x01 00 00 00
大端儲存:
i 0x00 00 00 01
聯合體union會給其中的成員分配同一個地址,長度為最大成員的長度,所以小端下c = 1,大端下c = 0。
寫一個檢測大小端的函式
// 大端返回1,小端返回0 int CheckDX() { union A { int i = 1; char c; }a; a.i = 1; return if(i==c); }
大小端很容易記憶混亂,我自己想了一個理解的方法:常用的X86如Windows、GCC中都是小端模式,小端也比較好理解,例如上面int型別i的儲存,四個位元組,從左往右地址依次增高,位元組也依次增高(從低位元組0x01到高位元組0x00),就是寫出來視覺上
看著是反的。一句話,小端模式是先存低位元組。
KEIL C51為大端模式。很多的ARM,DSP都為小端模式。有些ARM處理器還可以由硬體來選擇是大端模式還是小端模式。大端模式等下次用的時候測試一下。
採用大端方式進行資料存放符合人類的正常思維,而採用小端方式進行資料存放利於計算機處理。
筆試題
#include <stdio.h> void main() { char str[20] = "Hello world!"; int *p = (int *)str; p[0] = 0x61626364; p[1] = 0x41424344; p[2] = 0x31323334; printf("%s", str); }
結果:
dcbaDCBA4321
#include <stdio.h>
void main()
{
union Test
{
char a[4];
short b;
};
union Test test;
test.a[0]=256;
test.a[1]=255;
test.a[2]=254;
test.a[3]=253;
printf("%d\n",test.b);
}
結果:
-256
char a[0]=256;
val=-128+(256-128)%256=0 ====>a[0]:00000000
char a[1]=255;
val=-128+(255-128)%256=-1 ====>a[1]:11111111
10000001(-1原始碼)
11111110(-1反碼)
11111111(-1補碼)
80X86-->小端模式 資料低位--->記憶體低地址
test共4位元組
test XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX
低地址 a[0] 00000000
a[1] 11111111
a[2] ........
a[3] ........
====>short 11111111 00000000(補碼)
10000000 11111111(反碼)
10000001 00000000(原始碼-256)
參考資料:
1. https://blog.csdn.net/vevenlcf/article/details/46924267
2. https://blog.csdn.net/qq_18815817/article/details/70196100