将int存储在char数组中?

时间:2009-10-05 23:57:27

标签: c++ c arrays pointers

我想在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:如果你不能说,我正在尝试在低级写一个序列化类...所以我正在寻找不同的策略来序列化一些常见的数据类型。

10 个答案:

答案 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;