我想在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个字节......
EDIT2:请不要关心字节序...我会担心字节序。我只是想用不同的方法来实现C / C ++中的上述功能。感谢
EDIT3:如果你不能说,我正在尝试在低级写一个序列化类...所以我正在寻找不同的策略来序列化一些常见的数据类型。
答案 0 :(得分:39)
除非你关心字节顺序等,否则memcpy
会起作用:
memcpy(a, &har, sizeof(har));
...
memcpy(&har2, a, sizeof(har2));
当然,不能保证sizeof(int)==4
对任何特定的实现(并且有实际的实现,这实际上是假的)。
从这里写一个循环应该是微不足道的。
答案 1 :(得分:22)
不是最佳方式,但是是安全的。
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;
答案 2 :(得分:8)
int main() {
typedef union foo {
int x;
char a[4];
} foo;
foo p;
p.x = 0x01010101;
printf("%x ", p.a[0]);
printf("%x ", p.a[1]);
printf("%x ", p.a[2]);
printf("%x ", p.a[3]);
return 0;
}
请记住,a [0]在一个小端机器上保存LSB而a [3]保存MSB。
答案 3 :(得分:8)
#include <stdio.h>
int main(void) {
char a[sizeof(int)];
*((int *) a) = 0x01010101;
printf("%d\n", *((int *) a));
return 0;
}
请记住:
指向对象或不完整类型的指针可能会转换为指向其他对象的指针 对象或不完整的类型。如果生成的指针未正确对齐 指向类型,行为未定义。
答案 4 :(得分:8)
注意:通过不是最后一个元素的元素访问联合是未定义的行为。 (假设字符为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]保持最少。
编辑:只是让你理解这个技巧&amp;是有点'和'在哪里&amp;&amp;是合乎逻辑的'和'。 感谢关于遗忘转变的评论。
答案 5 :(得分:7)
请勿使用工会,Pavel澄清道:
这是U.B.,因为C ++禁止 访问除以外的任何工会会员 写的最后一个。在 特别是,编译器是免费的 优化远离
int
的作业 成员完全使用代码 以上,因为它的价值不是 随后使用(它只看到了 随后阅读char[4]
会员,并没有义务 提供任何有意义的价值)。 在实践中,特别是g ++ 以拉这样的技巧而闻名,所以这个 不只是理论。另一方面, 使用static_cast<void*>
后跟 保证static_cast<char*>
工作
- Pavel Minaev
答案 6 :(得分:4)
您还可以使用新的展示位置:
void foo (int i) {
char * c = new (&i) char[sizeof(i)];
}
答案 7 :(得分:2)
#include <stdint.h> int main(int argc, char* argv[]) { /* 8 ints in a loop */ 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]); /* ^ ^ ^ ^ */ /* point at | | | */ /* cast as int* | | */ /* Address of | */ /* Location in char array */ *intPtr = intArr[i]; /* write int at location pointed to */ } /* Read ints out */ for (i = 0; i < 8; i++) { intPtr = (int*) &(charArr[i * 4]); intArr[i] = *intPtr; } char* myArr = malloc(13); int myInt; uint8_t* p8; /* unsigned 8-bit integer */ uint16_t* p16; /* unsigned 16-bit integer */ uint32_t* p32; /* unsigned 32-bit integer */ /* Using sizes other than 4-byte ints, */ /* set all bits in myArr to 1 */ p8 = (uint8_t*) &(myArr[0]); p16 = (uint16_t*) &(myArr[1]); p32 = (uint32_t*) &(myArr[5]); *p8 = 255; *p16 = 65535; *p32 = 4294967295; /* Get the values back out */ p16 = (uint16_t*) &(myArr[1]); uint16_t my16 = *p16; /* Put the 16 bit int into a regular int */ myInt = (int) my16; }
答案 8 :(得分:1)
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
答案 9 :(得分:0)
union value { int i; char bytes[sizof(int)]; }; value v; v.i = 2; char* bytes = v.bytes;