我是靠谱客的博主 健壮奇迹,这篇文章主要介绍C语言开发之UNION,现在分享给大家,希望可以做个参考。

union简介

union常见于C语言嵌入式开发中,union中的数据分享同一段内存,大小与最大的数据类型一致。

union应用

查看浮点数的16进制表示:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include<stdio.h> #include <stdint.h> uint32_t float2int(float a){ union{ float a; uint32_t b; }u; u.a = a; return u.b; } int main(){ float num = 1.5; printf("%xn", num); printf("%xn",float2int(num)); return 0; }

输出:

复制代码
1
2
3
4
5
//这里的输出是乱的,运行不同次输出结果不一样 d6009ab8 //这里的输出是符合IEEE754标准的 3fc00000

3fc00000
转换为二进制
0011 1111 1100 0000 0000 0000 0000 0000
0,01111111,100 0000 0000 0000 0000 0000
指数位 -127为0
尾数位个位补1变为1.1,转为10进制1.5。
最终结果1.5*2^0 = 1.5

为啥是乱的?个人解释如下,如有专业人员还望指正:
查看汇编代码

复制代码
1
2
3
4
gcc union.c -S ls cat union.s
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
main: stp x29, x30, [sp, -32]! add x29, sp, 0 fmov s0, 1.5e+0 str s0, [x29, 28] ldr s0, [x29, 28] fcvt d0, s0 adrp x0, .LC0 add x0, x0, :lo12:.LC0 bl printf ldr s0, [x29, 28] bl float2int mov w1, w0 adrp x0, .LC0 add x0, x0, :lo12:.LC0 bl printf mov w0, 0 ldp x29, x30, [sp], 32 ret

先看下面一段,将数据读入s0,(str后ldr,转入外存再转入内存,可能与内外存数据一致有关)然后利用fcvt指令转换位double型存入d0。

复制代码
1
2
3
4
5
6
fmov s0, 1.5e+0 str s0, [x29, 28] ldr s0, [x29, 28] fcvt d0, s0 adrp x0, .LC0

而我们的printf,输出类型位"%x",为整数,所以printf函数找不到d0寄存器(存储浮点数的寄存器),找错寄存器位置导致的。
2.大小端转换

复制代码
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> #include <stdint.h> uint32_t big2low(uint32_t num){ union{ uint32_t num; uint8_t base[4]; }u; u.num = num; uint32_t res = 0x00000000; for(int i = 0; i < 3; i++){ res = (res | u.base[i]) << 8; } res = (res | u.base[3]); return res; } int main(){ uint32_t num = 0x12345678; printf("%xn", num); printf("%xn",big2low(num)); return 0; }

编译运行

复制代码
1
2
3
12345678 78563412

最后

以上就是健壮奇迹最近收集整理的关于C语言开发之UNION的全部内容,更多相关C语言开发之UNION内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(83)

评论列表共有 0 条评论

立即
投稿
返回
顶部