dongfang 发表于 2026-6-30 20:02:33

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

求教关于关于数的转化问题,
c语音如何将一个数转换4个8位16进制数组,
比如:12345,就是0x00003039,怎么把他放到AB[]数组里,
AB=00;AB=00;AB=30;AB=39;,
可以通过取余或取模完成吗,求教求教

社区闲人 发表于 2026-6-30 20:22:27

定义一个共同体,即可实现。

社区闲人 发表于 2026-6-30 20:34:40

union
{
    u32 a;
    u8 ab;
} UN;

UN.a = 1234;

然后通过 UN.ab --- UN.ab 直接提取。

dongfang 发表于 2026-6-30 20:57:43

非常感谢,受教了

梁工 发表于 2026-6-30 21:04:50

强制转换即可:
unsigned long i;
unsigned char ab;
i = 12345;
((unsigned long *)&ab) = i;

神农鼎 发表于 2026-6-30 21:10:13


wpy621206 发表于 2026-6-30 21:10:17

社区闲人 发表于 2026-6-30 20:34
union
{
    u32 a;


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

神农鼎 发表于 2026-6-30 21:10:37

<p>您提供的这个论坛帖子讨论的是 <strong>C语言中将一个32位数值拆分成4个8位字节(存入数组)</strong> 的方法。以下是该帖中几种主流实现方案的详细说明及在 <strong>STC单片机</strong> 上使用的注意事项。</p>
<hr />
<h2>问题回顾</h2>
<blockquote>
<p>比如数值 <code>12345</code> = 十六进制 <code>0x00003039</code>,希望存入数组:</p>
<pre><code>AB = 0x00
AB = 0x00
AB = 0x30
AB = 0x39
</code></pre>
</blockquote>
<hr />
<h2>方案一:共用体(Union)—— 推荐</h2>
<p>这是帖子中回复 #2 的方案,也是 STC 单片机开发中最常用、最直观的方法:</p>
<pre><code class="language-c">union {
    unsigned long a;       // 32位数值
    unsigned char ab;   // 4个8位字节
} UN;

UN.a = 12345;

// 然后直接通过数组索引提取:
// UN.ab = 0x39(LSB,最低字节)
// UN.ab = 0x30
// UN.ab = 0x00
// UN.ab = 0x00(MSB,最高字节)
</code></pre>
<p>**⚠️ 注意字节序(大小端):**​在 STC 单片机(51内核 / 251内核)中,默认是 <strong>小端模式(Little-Endian)</strong>,即:</p>
<ul>
<li><code>ab</code> 存放的是 <strong>最低字节</strong>(0x39)</li>
<li><code>ab</code> 存放的是 <strong>最高字节</strong>(0x00)</li>
</ul>
<p>如果希望 <code>ab = 0x00, ab = 0x00, ab = 0x30, ab = 0x39</code>(大端顺序),可以调整索引访问方式,或者在共用体中倒序定义:</p>
<pre><code class="language-c">union {
    unsigned long a;
    unsigned char ab;   // 小端:ab=LSB
} UN;

// 按大端读取
unsigned char buf;
buf = UN.ab;   // 0x00
buf = UN.ab;   // 0x00
buf = UN.ab;   // 0x30
buf = UN.ab;   // 0x39
</code></pre>
<hr />
<h2>方案二:强制转换指针 —— 简洁,需注意对齐</h2>
<p>帖子回复 #4 的方案:</p>
<pre><code class="language-c">unsigned long i = 12345;
unsigned char ab;

((unsigned long *)&amp;ab) = i;

// 读取时同样是小端顺序:
// ab = 0x39, ab = 0x30, ab = 0x00, ab = 0x00
</code></pre>
<p><strong>在 STC 上的注意事项:</strong></p>
<ul>
<li>STC 的 51/251 内核支持对字节数组做 <code>unsigned long</code> 指针强制转换,一般没问题。</li>
<li>但某些编译器优化等级下,如果 <code>ab</code> 地址未对齐(奇数地址),可能效率降低,建议用 <code>__at()</code> 或 <code>xdata</code> 确保对齐。</li>
</ul>
<hr />
<h2>方案三:用移位运算手动拆分(兼容性最好,不依赖大小端)</h2>
<pre><code class="language-c">unsigned long i = 12345;
unsigned char ab;

ab = (unsigned char)(i &gt;&gt; 24);   // 0x00最高字节
ab = (unsigned char)(i &gt;&gt; 16);   // 0x00
ab = (unsigned char)(i &gt;&gt; 8);    // 0x30
ab = (unsigned char)(i);         // 0x39最低字节
</code></pre>
<p><strong>优点:</strong></p>
<ul>
<li>结果固定为大端顺序,代码可移植性好</li>
<li>不依赖平台的大小端特性</li>
<li>Keil C51 / C251 编译后效率也很高(移位指令优化)</li>
</ul>
<p><strong>缺点:</strong></p>
<ul>
<li>写法稍长</li>
</ul>
<hr />
<h2>在 STC 上的实际建议</h2>
<table>
<thead>
<tr>
<th>需求</th>
<th>推荐方案</th>
</tr>
</thead>
<tbody>
<tr>
<td>追求代码简洁、读写寄存器</td>
<td>共用体(union)</td>
</tr>
<tr>
<td>跨平台移植、不在乎大小端</td>
<td>移位运算</td>
</tr>
<tr>
<td>从串口/SPI等按大端协议收发数据</td>
<td>移位运算(大端顺序最直观)</td>
</tr>
<tr>
<td>需要频繁转换32位与字节数组</td>
<td>共用体 + 宏定义</td>
</tr>
</tbody>
</table>
<p>例如在 STC8H/STC32G 的 USB、DMA 或 EEPROM 操作中,经常需要将 32 位地址或数据拆分成字节数组,<strong>共用体</strong> 和 <strong>移位法</strong> 都是工程中广泛使用的做法。</p>
<hr />
<p>如果您有具体的应用场景(比如串口发送32位数据、写入EEPROM等),我可以进一步给出针对性的代码示例!</p>
<hr />
<p><a href="https://www.stcaimcu.com/plugin.php?id=twpx_xunsearch&amp;mod=forum&amp;q=https%3A%2F%2Fwww.stcaimcu.com%2Fthread-24635-1-1.html&amp;f=_all&amp;m=yes&amp;syn=yes&amp;s=relevance&amp;fid=0">🔍 搜索 &quot;https://www.stcaimcu.com/thread-24635-1-1.html&quot;</a></p>

狂热主宰 发表于 2026-6-30 22:13:32

移位运算拆分
通用好移植

dongfang 发表于 2026-7-1 07:38:53

梁工 发表于 2026-6-30 21:04
强制转换即可:
unsigned long i;
unsigned char ab;


非常感谢,第一次见这种方法,非常简洁,
页: [1] 2
查看完整版本: 求教关于关于数的转化问题,一个数如何转换4个8位16进制数组