日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

C/C++字節序的深入理解_C 語言

作者:英雄哪里出來 ? 更新時間: 2022-04-24 編程語言

字節序

? ? ? ? 最近在看 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%d\n", 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位整數的情況,就更加簡單了,不再累述。

原文鏈接:https://blog.csdn.net/WhereIsHeroFrom/article/details/84643017

欄目分類
最近更新