C語言 - 大小端問題



目前使用的機器都是使用字節BYTE來存儲的。

對於跨越多字節的對象,必須搞清楚兩個規則:

  • 這個對象的地址是什么
  • 在存儲器中如何按照這些字節的存放的書序

對於一個整型對象 a=0x12345678,一共有四個字節。
假設存放在地址0x00002000中,於是,在0x2000開始放0x78還是0x12就是一個大小端問題。
但是,對於只是讀寫一個WORD32而言,計算器如何存儲WORD32字節序,其實並不重要。

大小端的存儲示例:
大端法

0x2000    0x2001    0x2002    0x2003
12        34        56        78

小端法

0x2000    0x2001    0x2002    0x2003
78        56        34        12

什么時候會遭遇大小端問題:

  1. 在不同類型的機器之間通過網絡傳送二進制數據時
  2. 當閱讀表示整型數據的字節序列時,這里重點是整型數據,並不是字節數據
  3. 檔使用強制轉換對象類型時候

對於二進制文件流:
文件流與網絡流其實是一樣的傳輸方式。
如果一個整型對象,使用fread的方式按照字節序讀取進來,首先要知道二進制文件的字節流的結構意義。

  • 1)從程序寫入到二進制文件中

假設有整型對象a=0x12345678 b=0x1E2B3D4C
使用fwrite寫入到二進制文件中
a、在小端機器上使用fwrite寫入時,這兩個整型對象在內存中的擺放方式為
0x200 0x201 0x202 0x203 0x204 0x205 0x206 0x207
78 56 34 12 4C 3D 2B 1E

0x200    0x201    0x202    0x203    0x204    0x205    0x206    0x207
78        56        34        12    4C        3D        2B        1E 

寫入到文件中
0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07
78   56   34   12   1E   2B   3D   4C

b、在小端機器上使用fwrite寫入時,這兩個整型對象在內存中的擺放方式為
0x200 0x201 0x202 0x203 0x204 0x205 0x206 0x207
12 34 56 78 1E 2B 3D 4C
寫入到文件中
0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07
12 34 56 78 1E 2B 3D 4C

  • 2)從二進制文件讀取到程序中

譬如文件里有下面的二進制序列:
0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07
12 34 56 78 91 23 45 67
a、在小端機器上使用fread,讀取到0x200地址上,
0x200 0x201 0x202 0x203 0x204 0x205 0x206 0x207
12 34 56 78 91 23 45 67
現在,代碼中從0x200地址讀出一個整型對象,由於該機器是小端,那么讀出來就是0x78563412
b、在大端機器上使用fread,讀取到0x200地址上,結果同上
0x200 0x201 0x202 0x203 0x204 0x205 0x206 0x207
12 34 56 78 91 23 45 67
但是,如果現在代碼從0x200地址中讀出一個整型對象時,讀出來的整型對象將是0x12345678


對於文本文件:(並不區分大小端)
文本文件在文件中的存儲方式是ASCII碼的字節流
如果有char *s = "ABCD1234"
無論是大端還是小端機器,在內存里面的表示都是
0x200 0x201 0x202 0x203 0x204 0x205 0x206 0x207
41 42 43 44 31 32 33 34
所以使用stdio的庫函數,寫入到文件中,都是一樣,從0地址開始按照byte寫,連續寫入8個字節


//對應int32大小的成員 的轉換 范例
unsigned int swapInt32(unsigned int value)
{
return ((value & 0x000000FF) << 24) |
((value & 0x0000FF00) << 8) |
((value & 0x00FF0000) >> 8) |
((value & 0xFF000000) >> 24) ;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM