You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C语言中实现类似Python struct模块的整数与字节数组互转?

在C语言中实现类似Python struct的打包/解包功能

Python的struct模块核心是完成整数与固定长度大端字节序列的双向转换,在C语言中可以通过手动位运算或标准库函数实现完全一致的功能,以下是针对你示例中>I(大端无符号32位整数)和>Q(大端无符号64位整数)场景的具体实现:

1. 打包(整数转大端字节串)

方法一:手动位运算(跨平台通用)

直接提取整数的每个字节,按大端高位在前的顺序存入数组:

#include <stdint.h>
#include <string.h>

// 对应Python struct.pack('>I', num)
void pack_uint32_be(uint32_t num, uint8_t *out_bytes) {
    out_bytes[0] = (num >> 24) & 0xFF;
    out_bytes[1] = (num >> 16) & 0xFF;
    out_bytes[2] = (num >> 8) & 0xFF;
    out_bytes[3] = num & 0xFF;
}

// 对应Python struct.pack('>Q', num)
void pack_uint64_be(uint64_t num, uint8_t *out_bytes) {
    out_bytes[0] = (num >> 56) & 0xFF;
    out_bytes[1] = (num >> 48) & 0xFF;
    out_bytes[2] = (num >> 40) & 0xFF;
    out_bytes[3] = (num >> 32) & 0xFF;
    out_bytes[4] = (num >> 24) & 0xFF;
    out_bytes[5] = (num >> 16) & 0xFF;
    out_bytes[6] = (num >> 8) & 0xFF;
    out_bytes[7] = num & 0xFF;
}

方法二:利用标准库字节序转换函数

多数系统提供htonl()(32位主机序转网络大端序)、htonll()(64位主机序转网络大端序)函数,转换后直接复制字节即可:

#include <stdint.h>
#include <arpa/inet.h> // Linux/macOS用,Windows需替换为winsock2.h
#include <string.h>

void pack_uint32_be_std(uint32_t num, uint8_t *out_bytes) {
    uint32_t network_num = htonl(num);
    memcpy(out_bytes, &network_num, sizeof(uint32_t));
}

void pack_uint64_be_std(uint64_t num, uint8_t *out_bytes) {
    uint64_t network_num = htonll(num);
    memcpy(out_bytes, &network_num, sizeof(uint64_t));
}

2. 解包(大端字节串转整数)

方法一:手动位运算(跨平台通用)

按大端顺序读取字节数组的每个字节,组合成目标整数:

#include <stdint.h>

// 对应Python struct.unpack('>I', bytes)
uint32_t unpack_uint32_be(const uint8_t *in_bytes) {
    return ((uint32_t)in_bytes[0] << 24) |
           ((uint32_t)in_bytes[1] << 16) |
           ((uint32_t)in_bytes[2] << 8) |
           in_bytes[3];
}

// 对应Python struct.unpack('>Q', bytes)
uint64_t unpack_uint64_be(const uint8_t *in_bytes) {
    return ((uint64_t)in_bytes[0] << 56) |
           ((uint64_t)in_bytes[1] << 48) |
           ((uint64_t)in_bytes[2] << 40) |
           ((uint64_t)in_bytes[3] << 32) |
           ((uint64_t)in_bytes[4] << 24) |
           ((uint64_t)in_bytes[5] << 16) |
           ((uint64_t)in_bytes[6] << 8) |
           in_bytes[7];
}

方法二:利用标准库字节序转换函数

先将字节数组复制到整数变量,再用ntohl()/ntohll()转为主机序:

#include <stdint.h>
#include <arpa/inet.h>
#include <string.h>

uint32_t unpack_uint32_be_std(const uint8_t *in_bytes) {
    uint32_t network_num;
    memcpy(&network_num, in_bytes, sizeof(uint32_t));
    return ntohl(network_num);
}

uint64_t unpack_uint64_be_std(const uint8_t *in_bytes) {
    uint64_t network_num;
    memcpy(&network_num, in_bytes, sizeof(uint64_t));
    return ntohll(network_num);
}

测试示例

以下代码完全对应你给出的Python示例,可直接验证功能一致性:

#include <stdio.h>

int main() {
    // 测试32位整数打包/解包
    uint32_t num32 = 13934;
    uint8_t pack32[4];
    pack_uint32_be(num32, pack32);
    printf("Packed uint32: 0x%02X 0x%02X 0x%02X 0x%02X\n", pack32[0], pack32[1], pack32[2], pack32[3]);

    uint8_t unpack32_data[] = {0x00, 0x00, 0x36, 0x6E};
    uint32_t unpacked32 = unpack_uint32_be(unpack32_data);
    printf("Unpacked uint32: %u\n", unpacked32);

    // 测试64位整数打包/解包
    uint64_t num64 = 12345678901234567890ULL;
    uint8_t pack64[8];
    pack_uint64_be(num64, pack64);
    printf("Packed uint64: 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n",
           pack64[0], pack64[1], pack64[2], pack64[3], pack64[4], pack64[5], pack64[6], pack64[7]);

    uint8_t unpack64_data[] = {0xAB, 0x54, 0xA9, 0x8C, 0xEB, 0x1F, 0x0A, 0xD2};
    uint64_t unpacked64 = unpack_uint64_be(unpack64_data);
    printf("Unpacked uint64: %llu\n", unpacked64);

    return 0;
}

注意事项

  • Windows平台使用标准库函数时,需包含winsock2.h并链接ws2_32.lib。
  • 手动位运算的方法完全不受系统字节序影响,适合需要严格控制字节顺序的场景。

内容的提问来源于stack exchange,提问作者S-N

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 07:53:20