大端小端(char)&x 和 char&x 的區別

Endianness 的問題實質就是關於計算機如何存儲大的數值的問題。

我們知道一個基本存儲單元可以保存一個字節,每個存儲單元對應一個地址。

對於大於十進制255(16進制0xff)的整數,需要多個存儲單元。

例如,4660對應於0x1234,需要兩個字節。不同的計算機系統使用不同的方法保存這兩個字節。

在我們常用的PC機中,低位的字節0x34保存在低地址的存儲單元,高位的字節0x12保存在高地址的存儲單元;

而在Sun工作站中,情況恰恰相反,0x34位於高地址的存儲單元,0x12位於低地址的存儲單元。前一種就被稱爲Little Endian,後一種就是Big Endian。


如何記住這兩種存儲模式?其實很簡單。首先記住我們所說的存儲單元的地址總是由低到高排列。

對於多字節的數值,如果先見到的是低位的字節,則系統就是Little Endian的,Little 就是"小,少"的意思,也就對應"低"。

相反就是Big Endian,這裏 Big "大"對應"高"。

爲了加深對Endianness的理解,讓我們來看下面的C程序例子:
 char a = 1;  
 char b = 2;        地址偏移量 內存映像
 short c = 255; /* 0x00ff */         0x0000: 01 02 FF 00
 long d = 0x44332211;         0x0004: 11 22 33 44

在右側我們可以見到在基於Intel 80x86的系統上的內存映像,顯然我們可以馬上判定這一系統是Little Endian的。

對於16位的整形數(short)c,我們先見到其低位的0xff,下一個纔是0x00。

同樣對於32位長整形數(long)d,在最低的地址0x0004存的是最低位字節0x11。

如果是在Big Endian的計算機中,則地址偏移量從0x0000到0x0007的整個內存映像將爲:01 02 00 FF 44 33 22 11。

     用文字說明可能比較抽象,下面用圖像加以說明。比如數字0x12345678在兩種不同字節序CPU中的存儲順序如下所示: 
Big Endian 

   低地址                                            高地址 
   -----------------------------------------> 
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
   |     12     |      34    |     56      |     78    | 
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 

Little Endian 


   低地址                                            高地址 
   -----------------------------------------> 
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
   |     78     |      56    |     34      |     12    | 
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

所有計算機處理器都必須在這兩種Endian間作出選擇。但某些處理器(如MIPS和IA-64)支持兩種模式,可由編程者通過軟件或硬件設置一種

Endian。以下是一個處理器類型與對應的Endian的簡表:
?  純Big Endian: Sun SPARC, Motorola 68000,Java Virtual Machine 
?  Bi-Endian, 運行Big Endian模式: MIPS運行IRIX, PA-RISC,大多數Power和PowerPC系統 
?  Bi-Endian, 運行Little Endian模式: MIPS  運行Ultrix,大多數DEC Alpha, IA-64運行Linux 
?  Little Endian: Intel x86,AMD64,DEC VAX 

******************************************************
#include <stdio.h>
//測試系統是大端模式還是小端模式,如果返回值是1:小端模式;0:大端模式
int testendian()
{
int x = 1;
return *((char*)&x);
}
int main()
{
int flag = 0;
flag = testendian();

printf("flag=%d ",flag);
if(flag == 0)
{
printf("the system is big endian\n");
}
else if(flag == 1)
{
printf("the system is little endian\n");
}
}
******************************************************

/* (char*)&x 和 char*&x 的區別

(char*)&x  :是取x的地址,強制轉換爲char型指針

例:
    int x;
    char *pc;
若要讓pc指向x;則可用  pc=(char*)&x;
或者
{
   int x,*p1;
   char *pc;
   p1=&x;
   pc=(char*)p1;
}
char*&x  :表示一個字符指針的引用。也就是說,這個 x 是一個指針,但它是一個鏡像(引用),改變這個指針的值(注意不是他指向的值),就會引起它的原像的改變。
舉個例子:
char* p = "abcdef";
char* q = "ghijkl";
// 這個時候 x 是 p 的鏡像(引用);
char* &x = p;
// 改變這個鏡像的值(注意是指針的值,而不是它指向的值)
x = q;
// 再看看 x 的值和它原像的值:
cout << x << endl;
cout << p << endl;
// 輸出兩行都應該是 ghijkl
// 由此看到 p 已經通過對其鏡像 x 的賦值被改變了。 
*/

轉自:http://wenku.baidu.com/link?url=qJ_TKF6_B7yq8hGO8Oo93UYbdDPMshnQ9h-Ql5OjVYYmNoIlUZ_-rBU5RjDrn-4d4CCB9Ob3ZSGrOYcGeITyHUDwfn7CNNhjraLLi2I4zVq

發佈了2 篇原創文章 · 獲贊 6 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章