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)——测试大小端模式的“坑”


分享到:


相關文章: