如何在C语言中将int数组转换为byte数组

4

嘿,我想知道在C语言中如何将整数数组转换为字节数组,声明方法是什么。如果可以更简单,并且不使用指针,我会非常感激。谢谢评论。

示例:int addr [500] 转换为 byte[]

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


一个整数是32位,而一个字节是8位。您是否希望将字节数组的大小增加4倍,并将每个整数存储在4个字节中? - joshhendo
你想访问每个int的所有字节,还是只访问每个int的低字节? - jcomeau_ictx
Int类型的长度为4或8个字节(根据定义至少是2个字节)...您想将其转换为1B类型吗?转换成char[2000]还是其他什么?您知道小端和大端之间的区别吗? - Vyktor
“Cast”是什么意思?你想要一个包含相同值的数组吗?还是你想要一个包含相同数据但有不同解释的数组? - Dietrich Epp
正如@joshhendo所描述的那样,我想将每个整数存储在4个字节中。因此,我想知道如何做到这一点。谢谢。 - Apekshith Ramesha
4个回答

15

如果你想要把 int 数组的内存重新解释为字节数组,那么只需要:

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

如果您想要重新解释现有的内存,那么您必须使用指针强制转换,因为声明一个[]数组意味着在堆栈上分配内存,并且不能用于重新解释现有的内存。

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

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

如果你尝试将每个int解释为char,即获得与int数量相同的char,那么你不能不经过循环和手动转换(通常是到新的内存位置)实现这一点。


1
需要非常清楚地指出的是,这并不以任何方式将您的整数转换为字符,它只是欺骗编译器使用您为整数分配的内存来代替字节。 - Joachim Isaksson
5
值得注意的是,这是C标准保证安全的极少数指针转换之一。 - Dietrich Epp
@JoachimIsaksson 编辑后,希望这一点非常清楚,谢谢。 - Irfy
这里的“bytes”是数组还是数组中的一个元素? - Apekshith Ramesha
2
@Vyktor:C标准保证,如果你有一个T *ptr,那么你可以将其强制转换为(unsigned char *) ptr并逐字节读取值。C标准规定,除了unsigned char之外的每种其他类型的行为都是未定义的。例如,没有严格符合规范的程序可以执行*(unsigned short *) ptr,但是严格符合规范的程序可以执行*(unsigned char *) ptr。还保证您可以使用memcpy将对象复制到unsigned char数组中,然后再复制回来而不会破坏它。请参见n1256 6.2.6.1。 - Dietrich Epp
显示剩余4条评论

4
你可以使用联合体。
union {
  int ints[500];
  char bytes[0];
} addr;

1
这是一个很好的答案 - 实际上,这是唯一符合OP请求“没有指针”的答案。当然,如果他们试图绕过指针,因为他们不理解它们,那么联合可能也不会更好... - setholopolus

1

如果你想要:

  1. int 数组背后的内存重新解释为字节,
  2. 出于任何原因而想要避免指针语法,
  3. 复制 int 数组是可以接受的,

那么你可以创建一个新的 char 数组,并使用 memcpy 复制 int 数组:

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

这与我原始答案中的第一个片段基本相同,不同之处在于 bytes 包含了 ints 的一个 副本(即修改其中一个不会影响另一个)。通常的注意事项包括 int 大小和避免使用魔法常量/重构代码。


0

使用指针可能更容易,但如果不使用指针,请尝试以下方法:

    #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 ];
            }
    }

1
我担心这些变化会给OP带来更多问题,而不是可能给出的答案… - Irfy
2
“不能这样做”;-) 除非编写不必要复杂的代码并引发更多问题,否则无法完成。在C语言中指针有着非常重要的作用,没有它们编写C代码就像是骑自行车而不使用腿部并有可能只使用一只手。但对于C++来说情况又不同了。 - Irfy
我的代码中有什么是不必要的?如果你正在制作两个相同数组的副本,我认为你做不得比这更好了。你下面提到的只是指向同一内存的指针。而且移位仍然使用指针:D - vimdude
1
我并不是在批评你的代码——而且,假设不能使用指针的限制条件,这可能是唯一的解决方案。我所指的是真实世界中更普遍的情况,在这种限制条件下会导致不必要的代码。我批评的是这种限制条件。没有理智的评论者会喜欢你的代码胜过我的,因为没有理智的人会设置那个限制条件。(再次强调,我这里并不是真的在比较“你的代码”和“我的代码”,这不是重点 :-) ) - Irfy
实际上...看看我的新答案 xD - Irfy
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接