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

20
задан InfantPro'Aravind' 11 January 2013 в 12:36
поделиться

7 ответов

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


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;
22
ответ дан 29 November 2019 в 22:27
поделиться

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

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

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

Написание цикла здесь должно быть тривиальным.

39
ответ дан 29 November 2019 в 22:27
поделиться
#include <stdio.h>

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

Помните:

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

8
ответ дан 29 November 2019 в 22:27
поделиться
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] содержит младший бит, а a [3] - старший бит на машине с прямым порядком байтов.

8
ответ дан 29 November 2019 в 22:27
поделиться

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

править: Просто чтобы вы поняли, что трюк & побитовый 'и' где как && логично 'и'. Спасибо за комментарии о забытой смене.

8
ответ дан 29 November 2019 в 22:27
поделиться

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

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

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

7
ответ дан 29 November 2019 в 22:27
поделиться

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

void foo (int i) {
  char * c = new (&i) char[sizeof(i)];
}
4
ответ дан 29 November 2019 в 22:27
поделиться