C語言中的大小端字節序

C語言中數據是存儲在內存中的,而內存空間又被劃分爲以字節爲單位的連續地址空間,那麼,我們定義的變量是在內存中如何存儲的呢。我們把變量在內存中的存儲分爲兩種,大端字節序存儲與小端字節序存儲。

網絡字節序都是大端字節序
主機字節序看本身電腦的情況,有可能是大端有可能是小端

1.大小端的概念

大小端字節序的概念其實非常簡單,小端字節序無非就是高地址高內存,低地址低內存。大端字節序就是反過來,高地址低內存,低地址高內存。數據的低字節存儲在低地址處,高字節存儲在高地址處。數據的低字節存儲在高地址處,高字節存儲在低地址處。

2.爲什麼有大小端之分

在計算機系統中,我們是以字節爲單位的,每個地址單元都對應着⼀個字節,⼀個字節爲8bit。然而在C語言中了8bit的char之外,還有 16bit(2字節)的short型, 32bit(4字節)的long型、int型(要看具體的編譯器)。另外,對於位數⼤於8位的處理 器,例如16位或者32位的處理器,由於寄存器寬度⼤於⼀個字節,那麼必然存在着⼀個如何將多個字節安排的問題。由此大端和小端就出現了。

比如:⼀個16bit的 short型w,它的值爲0x1122,那麼它的高字節爲0x11,低字節爲0x22。它在內存中的地址爲0x0010。
如果爲大端字節序:高字節0x11就存放在低地址0x0010中,低字節0x22就要存放在比0x0010高的地址0x0011中。小端則相反。

3.相關函數

htonl ntohl htons ntohs
h代表host,主機字節序 n代表net,網絡字節序

這幾個函數用到的頭文件

#include <arpa/inet.h>

3.1htonl()函數

函數原型:uint32_t htonl(uint32_t hostlong)

  • hostlong是主機字節順序表達的32位數,htonl中的h–host主機地址,to–to,n–net網絡,l–unsigned long無符號的長整型(32位的系統是4字節);
  • 函數返回值是一個32位的網絡字節順序;
  • 函數的作用是將一個32位數從主機字節順序轉換成網絡字節順序。

3.2htons()函數

函數原型:uint16_t htons(uint16_t hostlong)

  • hostlong是主機字節順序表達的16位數,htons中的h–host主機地址,to–to,n–net網絡,s–signed long無符號的短整型(32位的系統是2字節);
  • 函數返回值是一個16位的網絡字節順序;
  • 函數的作用是將一個16位數從主機字節順序轉換成網絡字節順序,簡單的說就是把一個16位數高低位互換。

3.3ntohs()函數

函數原型:uint16_t ntohs(uint16_t hostlong)

  • hostlong是網絡字節順序表達的16位數,ntohs中的,n–net網絡,to–toh–host主機地址,s–signed long有符號的短整型(32位的系統是2字節);
  • 函數返回值是一個16位的主機字節順序;
  • 函數的作用是將一個16位數由網絡字節順序轉換爲主機字節順序,簡單的說就是把一個16位數高低位互換。

3.4ntohl()函數

函數原型:uint32_t ntohs(uint32_t hostlong)

  • hostlong是網絡字節順序表達的32位數,ntohs中的,n–net網絡,to–toh–host主機地址,s–unsigned long無符號的短整型(32位的系統是4字節);
  • 函數返回值是一個32位的主機字節順序;
  • 函數的作用是將一個32位數由網絡字節順序轉換爲主機字節順序。

4.判斷大小端存儲方式

我們來設計一個程序看看自己電腦的主機字節序是大端還是小端

#include<stdio.h>
#include <arpa/inet.h>

int check_sys();
int check_sys1();

int main(int argc, char **argv)
{
      int          a = 1;
      int          rv;

      //這裏可以選用兩種方法來判斷
      rv = check_sys();
      //rv = check_sys1();   

      if(rv == 1)
      {
            printf("samll\n");
      }
      else if(rv == 0)
      {
            printf("big\n");
      }

      return 0;
}

int check_sys()
{
     int     a = 1;
     return *(char *)&a;
}

int check_sys1()
{
     union un
     {
          char  c;
          int   i;
     }u;

     u.i = 1;
     return u.c;
}

運行結果:
在這裏插入圖片描述
我的電腦是small!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章