關於大小端、位域的一些概念詳解
大小端:
對於像C++中的char這樣的資料型別,它本身就是佔用一個位元組的大小,不會產生什麼問題。但是當數制型別為int,在32bit的系統中,它需要佔用4個位元組(32bit),這個時候就會產生這4個位元組在暫存器中的存放順序的問題。比如int maxHeight = 0x12345678,&maxHeight = 0x0042ffc4。具體的該怎麼存放呢?這個時候就需要理解計算機的大小端的原理了。
大端:(Big-Endian)就是把數值的高位位元組放在記憶體的低位地址上,把數值的地位位元組放在記憶體的高位地址上。
小端:(Little-Endian)就是把數字的高位位元組放在高位的地址上,低位位元組放在低位地址上。
我們常用的x86結構都是小端模式,而大部分DSP,ARM也是小端模式,不過有些ARM是可以選擇大小端模式。所以對於上面的maxHeight是應該以小端模式來存放,具體情況請看下面兩表。
地址 | 0x0042ffc4 | 0x0042ffc5 | 0x0042ffc6 | 0x0042ffc7 |
數值 |
0x78 |
0x56 |
0x34 |
0x12 |
圖(1)為小端模式
地址 | 0x0042ffc4 | 0x0042ffc5 | 0x0042ffc6 | 0x0042ffc7 |
數值 |
0x12 |
0x34 |
0x56 |
0x78 |
圖(2)為大端模式
通過上面的表格,可以看出來大小端的不同,在這裡無法討論那種方式更好,個人覺得似乎大端模式更符合我的習慣。(注:在這裡我還要說一句,其實在計算機記憶體中並不存在所謂的資料型別,比如char,int等的。這個型別在程式碼中的作用就是讓編譯器知道每次應該從那個地址起始讀取多少位的資料,賦值給相應的變數。)
位域:
在計算機中是採用二進位制0和1來表示資料的,每一個0或者1佔用1位(bit)儲存空間,8位組成一個位元組(byte),為計算機中資料型別的最小單位,如char在32bit系統中佔用一個位元組。但是正如我們知道的,有時候程式中的資料可能並不需要這麼的位元組,比如一個開關的狀態,只有開和關,用1和0分別替代就可以表示。此時開關的狀態只需要一位儲存空間就可以滿足要求。如果用一個位元組來儲存,顯然浪費了另外的7位儲存空間。所以在C語言中就有了位段(有的也叫位域,其實是一個東西)這個概念。具體的語法就是在變數名字後面,加上冒號(:)和指定的儲存空間的位數。具體的定義語法如下:
struct 位段名稱
{
位段資料型別 位段變數名稱 : 位段長度;
.......
}
//例項
struct Node
{
char a:2;
double i;
int c:4;
}node;
其實定義很簡單,上面示例的意義是,定義一個char變數a,佔用2位儲存空間,一個double變數i,以及一個佔用4位儲存的int變數c。請注意這裡改變了變數本來佔用位元組的大小,並不是我們常規定義的一個int變數佔用4個位元組,一個char變數佔用1一個位元組。在實際的執行環境中執行,由於記憶體位元組對齊,得到sizeof(node) = 24。