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
4gcc 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
20main: 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
6fmov 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
312345678 78563412
最后
以上就是健壮奇迹最近收集整理的关于C语言开发之UNION的全部内容,更多相关C语言开发之UNION内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复