将一个int存储在char数组中?
我想在一个char数组中存储一个4字节的int …这样char数组的前4个位置就是int的4个字节。
然后,我想把int从数组中拉出来…
此外,如果有人可以给我这样的代码在一个循环中,奖励积分… IE写入像8个字节到一个32字节的数组。
int har = 0x01010101; char a[4]; int har2; // write har into char such that: // a[0] == 0x01, a[1] == 0x01, a[2] == 0x01, a[3] == 0x01 etc..... // then, pull the bytes out of the array such that: // har2 == har
多谢你们!
编辑:假设int
是4个字节…
编辑2:请不要在意endianness …我会担心endianness。 我只是想用不同的方法在C / C ++中达到上述目的。 谢谢
编辑3:如果你不能告诉,我试图编写一个序列化类在低级别…所以我正在寻找不同的策略来序列化一些常见的数据types。
不是最优化的方式,而是endian安全的。
int har = 0x01010101; char a[4]; a[0] = har & 0xff; a[1] = (har>>8) & 0xff; a[2] = (har>>16) & 0xff; a[3] = (har>>24) & 0xff;
除非你关心字节顺序等, memcpy
将做的伎俩:
memcpy(a, &har, sizeof(har)); ... memcpy(&har2, a, sizeof(har2));
当然,在任何特定的实现上都不能保证sizeof(int)==4
(并且实际上这些实际的实现其实是错误的)。
写一个循环应该从这里微不足道。
#include <stdio.h> int main(void) { char a[sizeof(int)]; *((int *) a) = 0x01010101; printf("%d\n", *((int *) a)); return 0; }
记住:
指向对象或不完整types的指针可能会转换为指向不同对象或不完整types的指针。 如果生成的指针未针对指向types正确alignment,则行为是不确定的。
注意:通过不是最后一个分配的元素访问联合是未定义的行为。 (假设字符为8位,整数为4字节的平台)0xFF的位掩码将屏蔽掉一个字符
char arr[4]; int a = 5; arr[3] = a & 0xff; arr[2] = (a & 0xff00) >>8; arr[1] = (a & 0xff0000) >>16; arr[0] = (a & 0xff000000)>>24;
会使arr [0]保持最重要的字节,arr [3]保持最小值。
编辑:只要你理解这个技巧&是明智的'和'在哪里&&是逻辑'和'。 感谢关于被遗忘的转变的评论。
int main() { typedef union foo { int x; char a[4]; } foo; foo p; px = 0x01010101; printf("%x ", pa[0]); printf("%x ", pa[1]); printf("%x ", pa[2]); printf("%x ", pa[3]); return 0; }
请记住,a [0]包含LSB,a [3]包含MSB,位于小端机器上。
不要使用工会,帕维尔澄清:
这是UB,因为C ++禁止访问除写入的最后一个以外的任何联合成员。 特别是,编译器可以自由地优化掉
int
成员的赋值,完全用上面的代码,因为它的值没有被随后使用(它只看到char[4]
成员的后续读取,并且没有义务提供任何有意义的价值)。 在实践中,g ++特别以拉动这种技巧而闻名,所以这不仅仅是理论。 另一方面,使用static_cast<void*>
后跟static_cast<char*>
是有保证的。
– 帕维尔Minaev
您也可以使用此新的展示位置:
void foo (int i) { char * c = new (&i) char[sizeof(i)]; }
#include <stdint.h> int main(int argc,char * argv []){ / * 8个循环中的整数* / int i; int * intPtr int intArr [8] = {1,2,3,4,5,6,7,8}; char * charArr = malloc(32); for(i = 0; i <8; i ++){ intPtr =(int *)&(charArr [i * 4]); / * ^ ^ ^ ^ * / / *指向| | | * / / *强制转换为int * | | * / / *地址| * / / * char数组中的位置* / * intPtr = intArr [i]; / *在指向* /的位置写入int } / *读取出来* / for(i = 0; i <8; i ++){ intPtr =(int *)&(charArr [i * 4]); intArr [i] = * intPtr; } char * myArr = malloc(13); int myInt; uint8_t * p8; / *无符号的8位整数* / uint16_t * p16; / *无符号的16位整数* / uint32_t * p32; / *无符号的32位整数* / / *使用除4字节整数以外的大小,* / / *将myArr中的所有位设置为1 * / p8 =(uint8_t *)&(myArr [0]); p16 =(uint16_t *)&(myArr [1]); p32 =(uint32_t *)&(myArr [5]); * p8 = 255; * p16 = 65535; * p32 = 4294967295; / *取回数值* / p16 =(uint16_t *)&(myArr [1]); uint16_t my16 = * p16; / *将16位int放入一个普通的int * / myInt =(int)my16; }
char a[10]; int i=9; a=boost::lexical_cast<char>(i)
发现这是将char转换为int的最好方法,反之亦然。
替代boost :: lexical_cast是sprintf。
char temp[5]; temp[0]="h" temp[1]="e" temp[2]="l" temp[3]="l" temp[5]='\0' sprintf(temp+4,%d",9) cout<<temp;
输出将是:hell9
联盟价值{ int i; 字节字节[sizof(int)]; }; 价值v; vi = 2; char * bytes = v.bytes;