Подтвердить что ты не робот

Сохранить int в массиве char?

Я хочу сохранить 4-байтовый int в массиве char... так что первые 4 местоположения массива char являются 4 байтами int.

Затем я хочу вывести int из массива...

Кроме того, бонусные баллы, если кто-то может дать мне код для этого в цикле... IE пишет, как 8 ints в 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

Спасибо, ребята!

EDIT: Предположим, что int - 4 байта...

EDIT2: Пожалуйста, не заботясь о контенте... Я буду беспокоиться о контенте. Я просто хочу, чтобы различные способы добиться вышеуказанного в C/С++. Благодаря

EDIT3: Если вы не можете сказать, я пытаюсь написать класс сериализации на низком уровне... поэтому я ищу различные стратегии для сериализации некоторых распространенных типов данных.

4b9b3361

Ответ 1

Не самый оптимальный способ, но безопасен для всех.


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

Если вы не заботитесь о порядке байтов и т.д., memcpy выполнит трюк:

memcpy(a, &har, sizeof(har));
...
memcpy(&har2, a, sizeof(har2));

Конечно, нет никакой гарантии, что sizeof(int)==4 для какой-либо конкретной реализации (и существуют реализационные реализации, для которых это фактически ложно).

Написание петли должно быть тривиально отсюда.

Ответ 3

#include <stdio.h>

int main(void) {
    char a[sizeof(int)];
    *((int *) a) = 0x01010101;
    printf("%d\n", *((int *) a));
    return 0;
}

Имейте в виду:

Указатель на объект или неполный тип может быть преобразован в указатель на другой объект или неполный тип. Если результирующий указатель неправильно выровнен для поведенческий тип, поведение undefined.

Ответ 4

Примечание. Доступ к соединению через элемент, который не был последним, назначен undefined. (предполагая платформу, где символы - 8 бит и int - 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].

edit: Просто чтобы вы поняли трюк и немного мудры и "where" и "amp; & является логическим" и". Благодаря комментариям о забытом сдвиге.

Ответ 5

Не используйте союзы, Павел разъясняет:

Это U.B., потому что С++ запрещает доступ к любому члену профсоюза, кроме последний, который был написан. В в частности, компилятор свободен для оптимизируйте присвоение intполностью выйти из кода выше, поскольку его значение не впоследствии используется (он видит только последующее чтение для char[4]член, и не несет никаких обязательств по предоставить там какую-либо значимую ценность). На практике g++, в частности, известный для вытягивания таких трюков, так что это это не просто теория. С другой стороны, используя static_cast<void*>, за которым следует static_cast<char*> гарантируется работа.

- Павел Минаев

Ответ 6

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, а [3] содержит MSB, на маленькой конечной машине.

Ответ 7

Вы также можете использовать новое размещение для этого:

void foo (int i) {
  char * c = new (&i) char[sizeof(i)];
}

Ответ 8

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

    }

Ответ 9

char a[10];
int i=9;

a=boost::lexical_cast<char>(i)

нашел, что это лучший способ конвертировать char в int и наоборот.

альтернатива boost:: lexical_cast is 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

Ответ 10

union value {
   int i;
   char bytes[sizof(int)];
};

value v;
v.i = 2;

char* bytes = v.bytes;