首頁 > 軟體

C/C++位元組序的深入理解

2022-02-20 13:00:08

位元組序

        最近在看 redis 的記憶體編碼,裡面涉及到位元組序相關的內容。這裡就當複習一下,做個簡單的回顧。

        資料儲存在記憶體中,是以位元組為單位的,如果是單位元組資料(如char、unsigned char、int8)就不會有位元組序的問題。但是多位元組資料(如 int、float、double)就要考慮位元組序的問題了。位元組序共分為兩種:大端序 和 小端序。

大端序

        資料的高位位元組儲存在地址的低端;低位位元組儲存在地址的高階。如圖所示,值為 0x12345678 的四位元組整數在大端序的主機上的記憶體排布。

小端序

        資料的高位位元組儲存在地址的高階;低位位元組儲存在地址的低端。如圖所示,值為 0x12345678 的四位元組整數在小端序的主機上的記憶體排布。

主機位元組序和網路位元組序

         除了主機位元組序,還有網路位元組序。主機位元組序由CPU決定,Intel Core 經測試都是小端位元組序。而網路位元組序採用的是大端序。測試位元組序可以通過一段 C 的原始碼搞定。

#include <stdio.h>
 
int main(int argc, char *argv[]) {
    int i;
    int x = 0x12345678;
    for (i = 0; i < sizeof(int); ++i) {
        unsigned char *p = ((unsigned char *)(&x)) + i;
        unsigned char v = *p;
        printf("%p 0x%d%dn", p, v>>4, v & 0xf );
    }
    return 0;
}

         取得整數 x 的首地址轉換成 unsigned char* 指標後再向前偏移 i 個單位,分別得到這 sizeof(int) 個位元組的地址,然後用 * 取得每個地址上的值,通過位運算轉換成 16進位制 輸出。
         Linux 系統可以通過指令獲取 CPU 的型別:

cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c
4  Intel(R) Core(TM) i3-2120 CPU @ 3.30GHz

大端序和小端序的互轉

        大端序和小端序的互相轉換,其實就是記憶體翻轉,在知道一個整數或者一個指標的位元組數的時候,就是做一個映象的交換。這裡以 64位元 整型為例:

void memrev64(void *p) {
    unsigned char *x = p, t;
 
    t = x[0];
    x[0] = x[7];
    x[7] = t;
    t = x[1];
    x[1] = x[6];
    x[6] = t;
    t = x[2];
    x[2] = x[5];
    x[5] = t;
    t = x[3];
    x[3] = x[4];
    x[4] = t;
}
 
uint64_t intrev64(uint64_t v) {
    memrev64(&v);
    return v;
}

        64位元整數的位元組數為8,所以在位元組序進行轉換的時候:
        第0個位元組和第7個位元組交換;
        第1個位元組和第6個位元組交換;
        第2個位元組和第5個位元組交換;
        第3個位元組和第4個位元組交換;
        對於 32位元整數、16位元整數的情況,就更加簡單了,不再累述。

到此這篇關於C/C++位元組序的深入理解的文章就介紹到這了,更多相關C語言 位元組序內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com