在一些串行通信中,一次只能发送一个字节。发送一个int类型有4个字节,是按照
byte0 byte1 byte2 byte3 还是byte3 byte2 byte1 byte0的顺序发送呢。
这是通信中的大小端,
现在我们讲的大小端,更多的是指计算机存储系统中的大小端。数据按照字节为单位存放,于是分为两种分布方式:
高字节对应低地址(大端模式)
高字节对应高地址(小端模式)
大小端没有对错优劣,但是要求存储时和读取时必须按照同样的大小端模式来进行,否则会出错哦。c51单片机是用大端,Arm大部分是用小端。
看一到经典的笔试题。
用c语言写一个函数来测试当前机器的大小端模式
方法1.用联合体
先说说联合体的特点
- 共用体union和结构体struct在类型声明、变量定义和使用方法上很相似。
- 共用体和结构体的不同:结构体类似于一个包裹,其中的成员彼此是独立存在的,分布在
- 内存的不同单元中,它们只是被打包成一一个整体叫做结构体而已;共用体中的各个成员其实
- 是一体的,彼此不独立,它们使用同一个内存单元。可以理解为:有时候是这个元素,有时候是那个元素。更准确的说法是,同-一个内存空间有多种解释方式。
- 在有些书中把union翻译成联合(联合体),这个名字不好。现在翻译成共用体比较合适。
- union的sizeof测到的大小实际是union中各个元素里面占用内存最大的那个元素的大小。
- union中的元素不存在内存对齐的问题,因为union中实际只有一个内存空间,都是从同
- 一个地址开始的,开始地址就是整个union占有的内存空间的首地址,所以不涉及内存对齐。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | #include <stdio.h> union myunion { int a; char b; /* data */ }; int is_litte_endian( void ) { union myunion ul; ul.a=1; return ul.b; } int main( void ) { int i=is_litte_endian(); if (i==1) { printf ( "小端模式" ); } else { printf ( "大端模式" ); } return 0; } |
方法2.利用指针。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #include <stdio.h> int is_little_endian2( void ) { int a=1; char b = *(( char *) (&a)) ; //指针方式其实就是共用体的本质,取a的地址强制类型转换为char,再看看char的地址指向的是1还是0 return b; } int main ( void ){ int i = is_little_endian2() ; if (1== i) printf ( "小端模式\n" ); else printf ( "大端模式\n" ); return 0; } |
最后再说说在通信协议中的大小端,先发低字节叫小端,先发高字节是大端。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步