【问题标题】:how to cast an int array to a byte array in C如何在C中将int数组转换为字节数组
【发布时间】:2026-01-27 09:55:02
【问题描述】:

嘿,我想知道如何将 C 中的 Int 数组转换为字节数组,以及声明方法是什么。如果它更简单并且不使用指针,我将不胜感激。感谢cmets

例如:int addr[500] 到 byte[]

另外,我还希望结束字节数组具有相同的数组名称。

【问题讨论】:

  • 整数是 32 位,而一个字节是 8 位。您是否希望字节数组的大小是整数数组的 4 倍,并将每个整数存储在 4 个字节上?
  • 你想访问每个 int 的所有字节,还是只访问每个 int 的低字节?
  • Int 是 4 或 8 字节长(根据定义至少 2 我认为)...你希望它如何转换为 1B 类型?到char[2000] 还是什么?你知道小端和大端的区别吗?
  • 你所说的“演员”是什么意思?你想要一个在每个位置包含相同值的数组吗?还是您想要一个包含相同数据但解释不同的数组?
  • 如上所述@joshhendo,我想将每个整数存储在 4 个字节中。所以我想知道该怎么做。谢谢

标签: c arrays byte


【解决方案1】:

如果您尝试将 int 数组后面的内存重新解释为字节数组,然后:

int ints[500];
char *bytes = (char *) ints;

不能在不使用指针转换的情况下执行此操作,因为声明 [] 数组意味着在堆栈上分配,并且不能用于重新解释现有内存。

显然,您需要知道自己在做什么。对于每个int,将有(通常取决于平台等)4 个chars,因此您的新数组将具有500*4 元素。查看输出的内容:

printf("char size: %d, int size: %d", sizeof(char), sizeof(int));

告诉你要确保。

如果您尝试将每个int 解释为char,即获得与ints 相同数量的chars,那么您不能在没有循环和手动转换的情况下执行此操作(通常是到新的内存位置)。

【讨论】:

  • 不过应该​​说得很清楚,这不会以任何方式将您的整数转换为字符,它只会欺骗编译器将您分配给整数的内存用于字节。
  • 值得注意的是,这是为数不多的 C 标准保证安全的指针转换之一。
  • @DietrichEpp “安全”到底是什么意思?
  • @Vyktor 我认为这是安全的,因为char 的对齐要求没有int 严格
  • @Vyktor:C 标准保证如果你有一些T *ptr,那么你可以转换为(unsigned char *) ptr 并逐字节读取值。 C 标准规定,除了unsigned char 之外,所有其他类型 的行为都是未定义的。例如,没有严格符合的程序可以执行*(unsigned short *) ptr,但严格符合的程序可以执行*(unsigned char *) ptr。还可以保证,例如,您可以将对象复制到 unsigned char 数组并使用 memcpy 返回而不会损坏它。见 n1256 6.2.6.1。
【解决方案2】:

您可以使用联合。

union {
  int ints[500];
  char bytes[0];
} addr;

【讨论】:

  • 这是一个很好的答案——它实际上是唯一满足 OP 要求的“无指针”的答案。当然,如果他们因为不理解指针而试图绕过指针,那么联合可能不会更好......
【解决方案3】:

如果你愿意

  1. int数组后面的内存重新解释为字节,
  2. 想要在句法上避免指针 --无论出于何种原因--,并且
  3. 可以复制int 数组,

然后您可以创建一个新的char 数组并使用memcpy 复制int 数组:

int ints[500];
char bytes[500 * 4];
memcpy(bytes, ints, 500 * 4);

这与我原始答案中的第一个 sn-p 大致相同,不同之处在于bytes 包含ints副本(即修改一个不会影响另一个)。关于int 大小和避免魔术常量/重构代码的常见警告适用。

【讨论】:

    【解决方案4】:

    使用指针可能更容易但没有指针,请尝试以下操作:

        #include <stdio.h>
    
        typedef unsigned char byte;
    
        void main() {
                int addr_size = 500;
                int addr[ addr_size ];
                byte bytes[ addr_size * 4 ];
    
                int i;
                for( i = 0; i < addr_size; i++ ) {
                        bytes[ i ] = (byte)( addr[ i ] >> 24);
                        bytes[ i + 1 ] = (byte)( addr[ i ] >> 16);
                        bytes[ i + 2 ] = (byte)( addr[ i ] >> 8);
                        bytes[ i + 3 ] = (byte)addr[ i ];
                }
        }
    

    【讨论】:

    • 我担心这种转变会给 OP 带来比他们可能给出的答案更多的问题......
    • 恐怕我对他的限制没有答案:) 如果没有指针,你会建议什么?
    • "不能做" ;-) 至少在没有编写不必要的复杂代码并提出更多问题的情况下是这样。指针在 C 中存在的一个非常好的理由,没有它们编写 C 就像骑自行车不使用腿,甚至可能是一只手。不过,C++ 是另一回事。
    • 我的代码中什么是不必要的?如果您要制作同一个数组的两个副本,我认为没有比这更好的了。您在下面提到的只是指向相同的内存。并且移位仍在使用指针:D
    • 我不是在批评你的代码——此外,假设没有指针约束,它可能是 the 解决方案。我指的是现实世界中更普遍的情况,这种约束会导致不必要的代码。我批评这种约束。没有理智的审阅者会喜欢你的代码而不是我的代码,因为没有理智的人会设置 that 约束。 (同样,我在这里并没有真正比较“你的代码”和“我的代码”,这不是重点:-))