程式執行在記憶體中,計算機中的最小儲存單位是bit
,即1
和0
的二進位制,它可以識別的機器碼就是以二進位制形式儲存的;
記憶體由多個儲存單元組成,每個儲存單元都有乙個唯一的數字位址位元組可定址記憶體。每個儲存位置可以包含固定數量的二進位制數字。
在大多數的現代計算機上,位址的最小資料的長度為8
位,稱為位元組(1 byte = 8 bit
);
一般計算機中使用者程式直接訪問的位址是虛擬記憶體的位址,作業系統核心會根據使用者程式訪問的虛擬位址,找出頁表中對於的實體地址,最終定址到所需要的資料;具體如下圖所示;
然而,在mcu等裸機開發的環境中,沒有mmu
,則程式直接訪問的是物理記憶體,所以無論是計算機還是mcu在程式執行中都需要記憶體作為載體,儲存資料和執行程式。那麼,下面再來看是程式以及資料在記憶體中是以何種形式儲存的?
前面提到過,在大多數的現代計算機上,位址的最小資料的長度為8
位,稱為位元組(1 byte = 8 bit
);至於為什麼是8位?看起來似乎有點玄學,並且很吉利的乙個數字,但是老外好像沒有數字迷信,這裡的原因大概是因為這幾點;
在說大小端之前,要先提一下位元組順序(endianness
),它是描述資料以位元組為一組在計算機記憶體中儲存順序的術語。
位元組順序可以是大端順序(big-endian
)或者小端順序(little-endian
);在對多位元組資料進行儲存時,一般遵循以下規則;
資料0x01020304
分別在大端機器和小端機器中的儲存形式,具體如下圖所示;
在大多數情況下,編譯器會處理位元組順序,從而避免出現大小端不一致的問題,但是在以下情況下位元組順序就會成為乙個問題。
在通訊中,例如網路程式設計:假設在小端機器上向檔案寫入整數,然後將此檔案傳輸到大端機器上。如果沒有做大小端轉換,那麼大端機器就會以相反的順序讀取檔案。
tcp/ip
協議中,預設使用的是大端順序,它與具體的cpu型別、作業系統等無關;
那麼如何在程式中快速的區分大小端呢?
下面介紹幾種通過c語言實現大小端判斷的方法;
第一種通過指標的記憶體對齊來實現;
函式的形式;
unsigned
char
check_endian
(void
)
巨集定義的形式;
static uint32_t endianness =
0xdeadbeef
;enum endianness
;#define endianness ( *(const char *)&endianness == 0xef ? little \
: *(const char *)&endianness == 0xde ? big \
: assert(0))
更加簡潔;
#define is_big_endian (!*(unsigned char *)&(uint16_t))
第二種通過結構體和聯合體的記憶體對齊來實現;
#ifndef order32_h
#define order32_h
#include
#include
#if char_bit != 8
#error "unsupported char size"
#endif
enum
;static
const
union
o32_host_order =};
#define o32_host_order (o32_host_order.value)
#endif
當然具體的方法還有很多,本文就先講到這裡。 那些移動端web踩過的坑
扔了n久,還是撿回來了。好好弄一下吧。剛工作的時候挺忙的,後來不那麼忙了,但是變懶了。這一年大多數時間都在在做移動端的東東,做了之後才發現,同樣是web前端,移動端的坑真的是深不可測,各種各樣的,只有想不到,沒有遇不到。在這裡把最近踩過的坑整理一下。首先,要解決的關鍵問題是如何為裝置選擇可視視口尺寸...
踩坑 Integer型別的整數比較大小
先劃重點 integer型別的整數比較數值大小用equals.和intvalue 盡量別用 去比較是否相等 之前沒注意過integer型別比較數值大小,一直在用 某天,寫的一段程式沒跑通,才注意到這個問題 public static void main string args 結果 true tru...
踩了apache配置虛擬主機的坑
一直使用xampp做apache伺服器,可是新版的xampp新增了虛擬主機就訪問127.0.0.1也跳轉到了虛擬主機去了,比如 我新增了www.demo.com,路徑是e www demo,而我的新增完之後,訪問127.0.0.1竟然也是跑到了www.demo.com下面去。上網找了好多數據說是新增...