找回密码
 立即注册
查看: 359|回复: 13

求教关于关于数的转化问题,一个数如何转换4个8位16进制数组

[复制链接]

48

主题

87

回帖

907

积分

高级会员

积分
907
发表于 2026-6-30 20:02:33 | 显示全部楼层 |阅读模式
求教关于关于数的转化问题,
c语音如何将一个数转换4个8位16进制数组,
比如:12345,就是0x00003039,怎么把他放到AB[]数组里,
AB[0]=00;AB[1]=00;AB[0]=30;AB[0]=39;,
可以通过取余或取模完成吗,求教求教

回复

使用道具 举报 送花

24

主题

546

回帖

2621

积分

荣誉版主

积分
2621
发表于 2026-6-30 20:22:27 | 显示全部楼层
定义一个共同体,即可实现。
回复

使用道具 举报 送花

24

主题

546

回帖

2621

积分

荣誉版主

积分
2621
发表于 2026-6-30 20:34:40 | 显示全部楼层
union
{
    u32 a;
    u8 ab[4];
} UN;

UN.a = 1234;

然后通过 UN.ab[0] --- UN.ab[3] 直接提取。
回复

使用道具 举报 送花

48

主题

87

回帖

907

积分

高级会员

积分
907
 楼主| 发表于 2026-6-30 20:57:43 | 显示全部楼层
非常感谢,受教了
回复

使用道具 举报 送花

83

主题

8317

回帖

1万

积分

超级版主

积分
17932
发表于 2026-6-30 21:04:50 | 显示全部楼层
强制转换即可:
unsigned long i;
unsigned char ab[4];
i = 12345;
((unsigned long *)&ab)[0] = i;
回复

使用道具 举报 送花

已绑定手机

872

主题

1万

回帖

2万

积分

管理员

积分
25428
发表于 2026-6-30 21:10:13 | 显示全部楼层
截图202606302110089216.jpg
回复

使用道具 举报 送花

5

主题

73

回帖

1987

积分

金牌会员

积分
1987
发表于 2026-6-30 21:10:17 | 显示全部楼层

这个方法好,省略了拆分计算
回复

使用道具 举报 送花

已绑定手机

872

主题

1万

回帖

2万

积分

管理员

积分
25428
发表于 2026-6-30 21:10:37 | 显示全部楼层

您提供的这个论坛帖子讨论的是 C语言中将一个32位数值拆分成4个8位字节(存入数组) 的方法。以下是该帖中几种主流实现方案的详细说明及在 STC单片机 上使用的注意事项。


问题回顾

比如数值 12345 = 十六进制 0x00003039,希望存入数组:

AB[0] = 0x00
AB[1] = 0x00
AB[2] = 0x30
AB[3] = 0x39

方案一:共用体(Union)—— 推荐

这是帖子中回复 #2 的方案,也是 STC 单片机开发中最常用、最直观的方法:

union {
    unsigned long a;       // 32位数值
    unsigned char ab[4];   // 4个8位字节
} UN;

UN.a = 12345;

// 然后直接通过数组索引提取:
// UN.ab[0] = 0x39  (LSB,最低字节)
// UN.ab[1] = 0x30
// UN.ab[2] = 0x00
// UN.ab[3] = 0x00  (MSB,最高字节)

**⚠️ 注意字节序(大小端):**​在 STC 单片机(51内核 / 251内核)中,默认是 小端模式(Little-Endian),即:

  • ab[0] 存放的是 最低字节(0x39)
  • ab[3] 存放的是 最高字节(0x00)

如果希望 ab[0] = 0x00, ab[1] = 0x00, ab[2] = 0x30, ab[3] = 0x39(大端顺序),可以调整索引访问方式,或者在共用体中倒序定义:

union {
    unsigned long a;
    unsigned char ab[4];   // 小端:ab[0]=LSB
} UN;

// 按大端读取
unsigned char buf[4];
buf[0] = UN.ab[3];   // 0x00
buf[1] = UN.ab[2];   // 0x00
buf[2] = UN.ab[1];   // 0x30
buf[3] = UN.ab[0];   // 0x39

方案二:强制转换指针 —— 简洁,需注意对齐

帖子回复 #4 的方案:

unsigned long i = 12345;
unsigned char ab[4];

((unsigned long *)&ab)[0] = i;

// 读取时同样是小端顺序:
// ab[0] = 0x39, ab[1] = 0x30, ab[2] = 0x00, ab[3] = 0x00

在 STC 上的注意事项:

  • STC 的 51/251 内核支持对字节数组做 unsigned long 指针强制转换,一般没问题。
  • 但某些编译器优化等级下,如果 ab 地址未对齐(奇数地址),可能效率降低,建议用 __at() 或 xdata 确保对齐。

方案三:用移位运算手动拆分(兼容性最好,不依赖大小端)

unsigned long i = 12345;
unsigned char ab[4];

ab[0] = (unsigned char)(i >> 24);   // 0x00  最高字节
ab[1] = (unsigned char)(i >> 16);   // 0x00
ab[2] = (unsigned char)(i >> 8);    // 0x30
ab[3] = (unsigned char)(i);         // 0x39  最低字节

优点:

  • 结果固定为大端顺序,代码可移植性好
  • 不依赖平台的大小端特性
  • Keil C51 / C251 编译后效率也很高(移位指令优化)

缺点:

  • 写法稍长

在 STC 上的实际建议

需求 推荐方案
追求代码简洁、读写寄存器 共用体(union)
跨平台移植、不在乎大小端 移位运算
从串口/SPI等按大端协议收发数据 移位运算(大端顺序最直观)
需要频繁转换32位与字节数组 共用体 + 宏定义

例如在 STC8H/STC32G 的 USB、DMA 或 EEPROM 操作中,经常需要将 32 位地址或数据拆分成字节数组,共用体 和 移位法 都是工程中广泛使用的做法。


如果您有具体的应用场景(比如串口发送32位数据、写入EEPROM等),我可以进一步给出针对性的代码示例!


🔍 搜索 "https://www.stcaimcu.com/thread-24635-1-1.html"

回复

使用道具 举报 送花

已绑定手机

74

主题

1019

回帖

3775

积分

论坛元老

初出茅庐&无甚本事

积分
3775
发表于 2026-6-30 22:13:32 | 显示全部楼层
移位运算拆分
通用好移植
偶尔看看玩玩
回复

使用道具 举报 送花

48

主题

87

回帖

907

积分

高级会员

积分
907
 楼主| 发表于 2026-7-1 07:38:53 | 显示全部楼层
梁*** 发表于 2026-6-30 21:04
强制转换即可:
unsigned long i;
unsigned char ab[4];

非常感谢,第一次见这种方法,非常简洁,

点评

我平时大量使用各种强制转换的方式,通常3个原因: 1、数学计算时,实现位数对齐。 2、将各种数据保存于EEPROM或FLASH时,写入函数是char型的数组指针,所以非char型数据要强制转换为char型再保存,读出函数也是char  详情 回复 发表于 2026-7-1 10:20
回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2026-11-7 13:38 , Processed in 0.077214 second(s), 96 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表