你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

如何用C语言验证大小端?

[复制链接]
gaosmile 发布时间:2020-5-7 19:13
大小端的问题在很多面试笔试中都会遇到,最直接的考察是,笔试的时候,让你写一个代码,如何确定当前系统是大端还是小端的。
什么是大端和小端呢?
大端: 高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。(CPU对操作数的存放方式是从高字节到低字节)
小端: 低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。(CPU对操作数的存放方式是从低字节到高字节)
假设我们的内存是这样的
微信图片_20200507190908.png
我们要存一个数据 0x44332211到这块内存里面去 如果系统是小端模式的话,存储方式如下图
微信图片_20200507190912.png
如果系统是大端模式的话,存储方式如下图
微信图片_20200507190915.png
好了,我们既然知道了大端和小端的存储方式不同,那就可以写代码来判断当前系统的存储模式了。
方法一#include <cstdio>
# L& ?+ `# ~3 n8 P* W& J. w7 y, J2 A% q0 t5 S
int main()  a* b" Y3 d; L1 W
{' q. j" s" B  u( {1 Z7 S$ r" U; U
        int i = 1;
: F6 X* I- |. d5 e    (*(char *)&i == 1) ? printf("Little-endian\n") : printf("Big-endian\n");$ C# [3 m0 F) f2 s7 f( Z
    return 0;
1 v, m% _1 _2 }7 S" W/ O}
; ^1 l7 h/ S% n5 K# Q" P
微信图片_20200507190918.png
指针类型转换,最后取 char * 指针的值,也就是判断 int 低地址的数据是否为1。
方法二#include <cstdio>8 L; a0 b6 a) x/ m0 x
7 n! v/ J: ~0 C8 s  C
union System+ S# w3 c' o/ e; x- u
{# C3 F1 i" u6 K' v" A# r$ t
        char a;
! r- H0 U6 y4 T5 j  [        int b;$ w0 C% h5 w4 _
};8 g) z. V0 w$ d  r& W7 U/ {7 T
, `9 o  h& `. [6 g# F/ Y5 x, K
int main()- Z2 J( B" ]" e. M7 `) @# L6 j
{# v, f) y: H  e
    union System s;
: ^6 G3 n; D7 B/ j9 o/ B+ n        s.b = 1;
) ]8 q) n. e5 @6 H2 z2 o6 ^       
# ^* _, ]0 B* y6 Q/ Y8 V4 `        printf("0x%x\n",&s.a);. A! {$ _# W* T& [* w# \# s
        printf("0x%x\n",&s.b);6 K. t+ Y/ v( f" T
        ' L% g* c7 @; B- }3 L. n1 j/ E4 b( z
        if(s.a == 1)
) X( g0 j  v3 T8 x' {( g0 x        {. e4 q+ y5 X  C( }( V! y
                printf("Little-endian\n");+ P- J2 T2 j$ e# h5 U9 d
        }
5 p* b4 \$ r3 ]& I/ G; d        else/ \0 ?  M8 v. A7 z9 \( Y
        {- j! H( H" h2 F# |
                printf("Big-endian\n");5 p5 |; A0 H, f3 h7 \
        }7 z, ^, f9 {6 j- j" }" ]
          
8 {2 b3 _* w- o* m  Z' d: c4 z    return 0;5 ~' L3 C3 \2 V; E1 B- U0 n
}
# x2 H' C- {" B" f' s
微信图片_20200507190922.png
共用体的特点是,使用类型最大的那个类型作为共用体的大小,所以,char a 使用的是 int b的空间大小,判断 a的值,也就是判断低地址的数据值。
方法三#include<stdio.h>
; ~. b. o0 c: P2 Astatic union
7 b$ R& M' d; t: Z" ^+ ~{
: w2 X) z* G! i+ B) }6 g    char a[4];) N: Y/ h! Z9 ~/ I1 v0 r! c" R* C
    int ul;
* @. ^6 Z* {/ [* i9 P% Q' o2 q, Y}endian = {{'L', '?', '?', 'B'}};
+ Y6 t& _; A" g5 ?, ~8 C, P#define ENDIAN ((char)endian.ul)
/ q/ d7 c+ h9 N8 H' F7 r" z  
/ T% A9 D. {2 t9 j; ~$ `4 Cint main()
' T/ A  o' A9 m{# h( y% D( L$ p/ }; r/ ~* n
    printf("%cENDIAN\n", ENDIAN);6 s  P  z% I4 i7 m
    return 0;
( O! y0 T% a* u3 ]}
5 W# w( x+ U8 Y! }  j
微信图片_20200507190926.png
宏和字符数组
方法四#include<stdio.h>  N9 }- p. _) u

& E+ [& e. f  |6 \% d/ y& m& }int main()
$ W* E' s: k$ U: v/ C" V{3 V9 g4 ?- @3 p/ l% a! w" U
        int a = 0x44332211;
. G7 X  @( Q2 Y        char *b = (char *)&a;
8 L  X" J) a% N        " G. f2 T# O2 S6 J6 m& w
        (*b == 0x11)?printf("Little-endian\n") : printf("Big-endian\n");
- o' l  k5 `* {: \+ G5 S        & H. s+ K& Y% m  T
    return 0;
( l& d* r( w, f  b( |6 Z( b/ p* m$ o$ ~}

* o- G$ U" y8 `/ i  { 微信图片_20200507190930.png
直接指针操作,原理也是取 int 低地址判断里面的数据。
总结
所有的判断依据都是按照上面的理论来验证的,读者们如果对代码有什么疑惑或者问题的请给我留言,我也不敢保证自己写的代码一定是正确的,几个方法也是参考网上的写法,我最喜欢还是用union来实现。如果在面试中突然不知道怎么写,我建议还是画个图出来先理解一下,这样更有利于写代码。
我原来也是上来就想把代码写出来,经过这些年的锤炼,我明白了,原理远比代码来的重要,我们学习也不要局限在某种语言上面,语言是为了实现某种需求的,C,C++,python,等等,都只是一种语言而已,说白了,就是一把刀,磨得再锋利的刀,没有猪肉来砍也只是用来观赏而已。

- g; k: d( {  m2 S
赞 收藏 评论1 发布时间:2020-5-7 19:13

举报

1个回答
李康1202 回答时间:2020-5-8 08:41:06
谢谢分享
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版