<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          為什么要有字節(jié)序?用 Go 解釋下

          共 3735字,需瀏覽 8分鐘

           ·

          2021-02-28 20:37

          什么是字節(jié)序

          字節(jié)序,又稱端序尾序(英語中用單詞:Endianness 表示),在計算機領域中,指電腦內存中或在數字通信鏈路中,占用多個字節(jié)的數據的字節(jié)排列順序。

          在幾乎所有的平臺上,多字節(jié)對象都被存儲為連續(xù)的字節(jié)序列。例如在 Go 語言中,一個類型為int的變量x地址為0x100,那么其指針&x的值為0x100。且x的四個字節(jié)將被存儲在內存的0x100, 0x101, 0x102, 0x103位置。

          字節(jié)的排列方式有兩個通用規(guī)則:

          • 大端序(Big-Endian)將數據的低位字節(jié)存放在內存的高位地址,高位字節(jié)存放在低位地址。這種排列方式與數據用字節(jié)表示時的書寫順序一致,符合人類的閱讀習慣。
          • 小端序(Little-Endian),將一個多位數的低位放在較小的地址處,高位放在較大的地址處,則稱小端序。小端序與人類的閱讀習慣相反,但更符合計算機讀取內存的方式,因為CPU讀取內存中的數據時,是從低地址向高地址方向進行讀取的。

          上面的文字描述有點抽象,我們拿一個例子來解釋一下字節(jié)排列時的大端序和小端序。

          在內存中存放整型數值168496141 需要4個字節(jié),這個數值的對應的16進制表示是0X0A0B0C0D,這個數值在用大端序和小端序排列時的在內存中的示意圖如下:

          大端序和小端序

          為何要有字節(jié)序

          很多人會問,為什么會有字節(jié)序,統(tǒng)一用大端序不行嗎?答案是,計算機電路先處理低位字節(jié),效率比較高,因為計算都是從低位開始的。所以,計算機的內部處理都是小端字節(jié)序。在計算機內部,小端序被廣泛應用于現(xiàn)代 CPU 內部存儲數據;而在其他場景,比如網絡傳輸和文件存儲則使用大端序。

          Go語言對字節(jié)序的處理

          Go 語言存儲數據時的字節(jié)序依賴所在平臺的 CPU,處理大小端序的代碼位于 encoding/binary ,包中的全局變量BigEndian用于操作大端序數據,LittleEndian用于操作小端序數據,這兩個變量所對應的數據類型都實現(xiàn)了ByteOrder接口。

          package main

          import (
           "encoding/binary"
           "fmt"
           "unsafe"
          )

          const INT_SIZE = int(unsafe.Sizeof(0)) //64位操作系統(tǒng),8 bytes

          //判斷我們系統(tǒng)中的字節(jié)序類型
          func systemEdian() {

           var i = 0x01020304
           fmt.Println("&i:",&i)
           bs := (*[INT_SIZE]byte)(unsafe.Pointer(&i))

           if bs[0] == 0x04 {
            fmt.Println("system edian is little endian")
           } else {
            fmt.Println("system edian is big endian")
           }
           fmt.Printf("temp: 0x%x,%v\n",bs[0],&bs[0])
           fmt.Printf("temp: 0x%x,%v\n",bs[1],&bs[1])
           fmt.Printf("temp: 0x%x,%v\n",bs[2],&bs[2])
           fmt.Printf("temp: 0x%x,%v\n",bs[3],&bs[3])

          }


          func testBigEndian() {

           var testInt int32 = 0x01020304
           fmt.Printf("%d use big endian: \n", testInt)
           testBytes := make([]byte4)
           binary.BigEndian.PutUint32(testBytes, uint32(testInt))
           fmt.Println("int32 to bytes:", testBytes)
           fmt.Printf("int32 to bytes: %x \n", testBytes)

           convInt := binary.BigEndian.Uint32(testBytes)
           fmt.Printf("bytes to int32: %d\n\n", convInt)
          }

          func testLittleEndian() {

           var testInt int32 = 0x01020304
           fmt.Printf("%x use little endian: \n", testInt)
            testBytes := make([]byte4)
           binary.LittleEndian.PutUint32(testBytes, uint32(testInt))
           fmt.Printf("int32 to bytes: %x \n", testBytes)

           convInt := binary.LittleEndian.Uint32(testBytes)
           fmt.Printf("bytes to int32: %d\n\n", convInt)
          }

          func main() {
           systemEdian()
           fmt.Println("")
           testBigEndian()
           testLittleEndian()
          }

          運行上面的程序會在終端里輸出

          &i: 0xc000084000
          system edian is little endian
          temp: 0x4,0xc000084000
          temp: 0x3,0xc000084001
          temp: 0x2,0xc000084002
          temp: 0x1,0xc000084003

          16909060 use big endian: 
          int32 to bytes: [1 2 3 4]
          int32 to bytes: 01020304 
          bytes to int32: 16909060

          1020304 use little endian: 
          int32 to bytes: 04030201 
          bytes to int32: 16909060

          總結

          計算機電路先處理低位字節(jié),效率比較高,因為計算都是從低位開始的。所以,計算機的內部處理都是小端字節(jié)序。但是,人類還是習慣讀寫大端字節(jié)序。所以,除了計算機的內部處理,其他的場合比如網絡傳輸和文件儲存,幾乎都是用的大端字節(jié)序。正是因為這些原因才有了字節(jié)序。

          計算機處理字節(jié)序的時候,如果是大端字節(jié)序,先讀到的就是高位字節(jié),后讀到的就是低位字節(jié)。小端字節(jié)序則正好相反。



          推薦閱讀


          福利

          我為大家整理了一份從入門到進階的Go學習資料禮包,包含學習建議:入門看什么,進階看什么。關注公眾號 「polarisxu」,回復 ebook 獲??;還可以回復「進群」,和數萬 Gopher 交流學習。

          瀏覽 90
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美A∨在线观看 | 日本A V在线视频 | 国产午夜免费 | 欧美亚洲性爱在线 | 国产精品男人操女人 |