1. 程式人生 > >小端大端、判斷方法和筆試題

小端大端、判斷方法和筆試題

小端模式(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