Не наиболее оптимальный способ, но он безопасен с порядком байтов.
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;
}
Помните:
Указатель на объект или неполный тип может быть преобразован в указатель на другой объект или неполный тип. Если полученный указатель неправильно выровнен для указывает на тип, поведение не определено.
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 бит, а целые 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] - наименьший.
править: Просто чтобы вы поняли, что трюк & побитовый 'и' где как && логично 'и'. Спасибо за комментарии о забытой смене.
Не используйте объединения, Павел поясняет:
Это UB, потому что C ++ запрещает доступ к любому члену союза кроме последний, на который было написано. В в частности, компилятор может оптимизировать присвоение
int
полностью отказаться от кода выше, так как его значение не впоследствии используется (он видит только последующее чтениеchar [4]
член и не обязан укажите там какую-либо значимую ценность). На практике, в частности, g ++ известен своими трюками, так что этот это не просто теория. С другой стороны, используяstatic_cast
, за которым следуетstatic_cast
гарантированно работа.
- Павел Минаев
Для этого также можно использовать новое размещение:
void foo (int i) {
char * c = new (&i) char[sizeof(i)];
}