計算機的大小端主要體現在兩個點:
1,內存存儲的大小端
2,網絡字節序,確定的是大端。
內存之所以有大小端,原因爲:超過1個字節的存儲,比如short,int等,該如何組織存儲單元?數據的高位放在內存的高地址還是低地址?都需要有明確的定義。
大端指的是數據的高位放在內存的低地址,小端則相反。
具體記憶的時候可以這樣:我們肉眼看的或者寫的就是大端。從左往右權重依次減小,內存地址依次增大。
內存存儲大小端是由什麼關鍵因素決定的?
分析下(純屬個人臆想分析)可能的決定點有:操作系統和CPU。
如果是操作系統,那麼在程序經過編譯之後應該會有顯示的對於彙編指令的特殊調用來適配大小端操作,也就是說不應該是正常的調用匯編指令,所以只需要查看生成的彙編指令文件即可確定,gcc -S a.c,X86-64上面任寫一個文件可以清楚的看到是直接使用匯編指令,並無特殊之處。目測應該不是操作系統來決定。
剩下的就是CPU本身了,CPU更能理解一點,彙編指令經過彙編之後生成的機器碼,統一接口,硬件操作。
當然具體的也百度了下,網上一致說的也都是由CPU決定的,官方文檔沒有查看過。
接下來就是網絡字節序的大小端。
why?爲什麼網絡字節序需要大小端?
用於網絡通信的套接字,端口和ip地址的存儲都是大於一個字節的數據類型,同時這兩個信息也是由用戶來設置的,大小端的服務器都需要進行網絡通信,網絡模塊代碼也不可能說大端一份小端一份,那麼這時候就需要做一個約定規定了,網絡字節序使用大端,所以在寫套接字代碼的時候端口設置要用到htons htonl函數來顯示的賦值大端模式下的值。
那接收端也是同樣的,接收到之後肯定就是大端模式,根據大端模式來解析出端口或者ip地址。
這裏還有一個問題:網絡通信的tcp層用戶數據需要顯示的轉換爲大端嗎?
回答是:可要可不要。
可要的原因是:服務器的客戶端肯定有大端小端之分,且傳輸的數據必然有int等類型,那麼必須需要一個統一的格式,要不然大端的服務器發送到小端的客戶端上面,數據解析就肯定出錯了,那麼就需要採用協議棧標準的網絡字節序了。
可不要的原因是:現在網絡傳輸有各種各樣的流庫,比如json,protobuf等,把數據完全字符串話,也就是說避免了大小端的區分了,都是一個一個獨立的char組成的字符串。
總結下就是:網絡的字節序大端,主要就是協議棧內部使用。
另外一點,也是提供一個標準吧,畢竟網絡是處在中間位置,兩邊可能不一致。
C語言判斷大小端的代碼:
理論上應該還可以通過CPU信息拿到,也有可能拿不到,必然系統沒有提供等等原因,請知道的留言。
#include "stdio.h"
typedef struct {
char a;
char b;
}mystruct;
typedef union {
short value;
mystruct mysvalue;
}union_t;
int main()
{
union_t union_value={.value=0x0102};
if(union_value.mysvalue.a==0x01)
{
printf("big endian\n");
}
else if(union_value.mysvalue.a==0x02)
{
printf("small endian\n");
}
else
{
printf("a is %#x and b is %#x\n",union_value.mysvalue.a,union_value.mysvalue.b);
}
return 0;
}