2012-01-05 35 views
3

我使用了一段代碼(在本站點發現其他地方),它在運行時檢查字節序。理解字節順序 - 變量值

static bool isLittleEndian() 
{ 
    short int number = 0x1; 
    char *numPtr = (char*)&number; 

    std::cout << numPtr << std::endl; 
    std::cout << *numPtr << std::endl; 

    return (numPtr[0] == 1); 
} 

在調試模式下,該值numPtr看起來像這樣:0x7fffffffe6ee "\001"

我認爲第一個十六進制部分是指針的內存地址,而第二部分是其持有的價值。我知道\ 0在舊式C++中是空終止的,但爲什麼它在前面?這是否與排序有關?
在小端機器上:01第一個字節,因此最不重要(字節位置0),和\ 0第二個字節/最終字節(字節位置1)?

此外,cout語句不打印指針地址或它的值。這是因爲什麼?

+0

您在使用它之後定義了'numPtr',那將如何編譯? – 2012-01-05 13:22:45

+0

現在已經改變了。代表我複製粘貼錯誤。 – nf313743 2012-01-05 13:28:36

+0

爲什麼你需要在運行時檢查字節順序。是不是每個端口的make文件的一部分? – 2012-01-05 14:28:16

回答

1

檢查大小端的最簡單的方法是讓系統爲你做它:

if (htonl(0xFFFF0000)==0xFFFF0000) printf("Big endian"); 
else printf("Little endian"); 
0

"\001"你所看到的僅僅是一個字節。這可能是八進制表示法,它需要三位數來正確表示(十進制)的值0到255.

1

這不是\0後跟「01」,它是單個字符\001,它表示八進制數1。這是你的字符串中唯一的字節。在零值之後還有另一個字節,但你沒有看到,因爲它被視爲字符串終結符。

0

\ 0不是NUL,調試器將numPtr顯示爲一個字符串,其中的第一個字符是\ 001或ASCII中的control-A。第二個字符是\ 000,因爲在顯示字符串時不顯示NUL,所以不顯示。兩個字符串版本的'number'在大端機器上顯示爲「\ 000 \ 001」,而不是在小端機器上出現的「\ 001 \ 000」。

2

其他人給你一個明確的答案是什麼"\000"手段,所以這是一個回答你的問題:

在一個小端機:01的第一個字節,因此至少顯著(字節的地方0)和\ 0第二個字節/最終字節(字節位置1)?

是的,這是正確的。你看看像0x1234這樣的值,它由兩個字節組成,高位部分爲0x12,低位部分爲0x34。術語「小尾」是指低部分首先存儲在存儲器中:

addr: 0x34 
addr+1: 0x12 

你知道的術語「端」早於計算機行業?它最初是由喬納森斯威夫特在其着作Gulliver's Travels中使用的,其中描述了人們是從尖端還是圓端吃雞蛋。

0

此外,cout語句不打印指針地址或 它的值。這是因爲什麼?

因爲在打印時,字符和字符指針的處理方式與整數不同。

當您打印一個字符時,它會打印任何字符集正在使用的字符。通常,這是ASCII或ASCII的超集。 ASCII中的值0x1不是打印。

當您打印一個字符指針時,它不會打印該地址,它會將其打印爲以空字符結尾的字符串。

爲了得到你想要的結果,把你的char指針轉換成一個void指針,然後將你的char轉換爲int。

std::cout << (void*)numPtr << std::endl; 
std::cout << (int)*numPtr << std::endl; 
1

對於初學者:這種類型的功能是完全毫無價值:機器 其中sizeof(int)是4上,有24種可能的字節順序。當然,大多數人都沒有意義,但我至少見過三次。而字節碼 不是唯一影響整數表示的東西。如果您有 和int,並且您希望獲得低位8位,請在接下來的8位(intValue >> 8) & 0xFF處使用intValue & 0xFF

關於您的確切問題:我假定您所描述的 爲「看起來像這樣」是您在調試器中看到的,當您在 處得到回報時。在這種情況下,numPtrchar*unsigned char const*會更有意義),因此調試器會採用C風格 字符串。 0x7fffffffe6ee是地址;接下來是 編譯器將其視爲C風格的字符串,它顯示爲一個字符串,即 "..."。據推測,你的平臺是傳統的小端 (英特爾);指向C風格字符串的指針會看到1, 0的序列(數值爲 值)。 0當然相當於'\0',所以它 認爲這是一個字符的字符串,與該一個字符 的編碼爲1.沒有可編碼的 之一的可打印字符,它不符合任何正常轉義序列 (例如'\n','\t'等)。所以調試器輸出它使用八進制轉義序列 ,'\'後跟1到3個八進制數字。 (傳統'\0'是這只是一個特例;一個'\'由一個八進制數字,然後 ),並將其輸出3個數字,因爲(可能) 它不希望向前看,以確保下一個字符ISN '是一個 八進制數字。 (如果序列是通常編碼中的兩個字節1, 49,例如 49是'1',並且如果它僅輸出用於八進制編碼1的單個字節 ,則結果將是「\ 11」,其是對應於通常的編碼以 '\t'。 單個字符串—)所以,你得到"這是一個字符串,\001與第一字符具有1的編碼(沒有顯示錶示) ,和" 那是字符串的末尾。

+0

這是你見過的第三個內疚,大,小,......? – 2012-01-05 14:00:48

+0

嘗試中端。 :-) http://en.wikipedia。org/wiki/Endianness#Middle-endian – 2012-01-05 14:22:30

+0

@ edA-qamort-ora-y 1234,4321和3412.最後一個與Microsoft C在MS-DOS下的Intel 8086上。不完全是一個奇特的。當然,今天還有機器被銷售(由Unisys提供),sizeof(int)是6,表示符號大小,int中有8個保留位,它必須是0。 – 2012-01-05 14:37:29