C語言學習篇(25)——測試大小端模式的“坑”

引言

上一篇我們介紹瞭如何使用共用體和指針方式測試機器的大小端模式,並實際測試了本機x86_64是小端模式,C51機器是大端模式。 結論是以上兩種方式是可靠有效的,除了這2種方法,大家開動下自己的小腦袋,思考是否還有其他方法測試呢? 那麼今天我們就來嘗試下其他幾種方法,並分析其是否可靠有效。

第一種:位與

<code> 

int

main

(

void

)

{

int

a =

1

;

char

b = a&

0x01

;

if

(b ==

1

)

printf

(

"b = %d. 我是小端模式.\n"

, b);

else

printf

(

"b = %d. 我是大端模式.\n"

, b);

return

0

; }/<code>

首先我們定義int類型的a = 1, 然後位與0x01賦值給b, 我們預想是當機器為小端模式時,此時b值應當等於1,而如果是大端模式的話,b應當等於0。

C語言學習篇(25)——測試大小端模式的“坑”

我們將以上代碼放到Ubuntu(x86_64)和Keil_C51中編譯運行看看運行結果(前面我們已經知道x86_64是小端模式, C51是大端模式)

Ubuntu中編譯運行:

C語言學習篇(25)——測試大小端模式的“坑”

Keil C51中編譯運行:

C語言學習篇(25)——測試大小端模式的“坑”

可以看到測試結果居然都是小端模式!

結論:位與的方式無法測試機器的大小端模式。那究其原因呢?位與運算是編譯器提供的運算,這個運算是高於內存層次的(或者說&運算在二進制層次具有可移植性,也就是說&的時候一定是高字節&高字節,低字節&低字節,和二進制存儲無關)

第二種:移位

<code> 

int

main

(

void

)

{

int

a =

1

;

int

b = a>>

1

;

if

(b ==

0

)

printf

(

"b = %d. 我是小端模式.\n"

, b);

else

printf

(

"b = %d. 我是大端模式.\n"

, b);

return

0

; }/<code>

還是定義一個int類型變量a = 1;然後右移一位後,賦值給b,我們預想e通過判斷b是否等於0來測試i機器大小端。

C語言學習篇(25)——測試大小端模式的“坑”

同樣我們將以上代碼放在Ubuntu和Keil C51編譯,並看看運行結果。

Ubuntu中編譯運行:

C語言學習篇(25)——測試大小端模式的“坑”

Keil C51中編譯運行:

C語言學習篇(25)——測試大小端模式的“坑”

測試結果同樣都是小端模式! 結論:移位的方式無法測試機器的大小端模式。原因與前一種位與方法一致。

第三種:強制類型轉化

<code> 

int

main

(

void

)

{

int

a =

1

;

int

b = (

char

)a;

if

(b ==

0

)

printf

(

"b = %d. 我是小端模式.\n"

, b);

else

printf

(

"b = %d. 我是大端模式.\n"

, b);

return

0

; }/<code>

還是定義int類型變量a = 1, 並強制類型轉化成char,賦值給b,我們預想通過b的值是否等於0來判斷機器的大小端模式。

C語言學習篇(25)——測試大小端模式的“坑”

同樣放到Ubuntu和Keil C51中編譯運行。

Ubuntu中編譯運行:

C語言學習篇(25)——測試大小端模式的“坑”

Keil C51中編譯運行:

C語言學習篇(25)——測試大小端模式的“坑”

結論:強制類型方式無法測試機器的大小端模式, 原因同上。

總結

以上3種方式: 位與, 移位, 強制類型轉化 都是不能測試機器的大小端模式的,其原因是這3種都是編譯器提供的運算,編譯器已經為我們做了最終的關係轉化。這些都是看似可行,實在不行的幾種方式,大家應在實際開發應用中避開這些"坑",尤其是在面試和筆試中注意。 最後總結來說,共用體或指針方式來測試機器的大小端是推薦使用的兩種方式。

C語言學習篇(25)——測試大小端模式的“坑”


分享到:


相關文章: