I want to store a 4-byte int in a char array... such that the first 4 locations of the char array are the 4 bytes of the int.
Then, I want to pull the int back out o
Unless you care about byte order and such, memcpy
will do the trick:
memcpy(a, &har, sizeof(har));
...
memcpy(&har2, a, sizeof(har2));
Of course, there's no guarantee that sizeof(int)==4
on any particular implementation (and there are real-world implementations for which this is in fact false).
Writing a loop should be trivial from here.
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;
}
Bear in mind that the a[0] holds the LSB and a[3] holds the MSB, on a little endian machine.
#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; }
Note: Accessing a union through an element that wasn't the last one assigned to is undefined behavior. (assuming a platform where characters are 8bits and ints are 4 bytes) A bit mask of 0xFF will mask off one character so
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;
would make arr[0] hold the most significant byte and arr[3] hold the least.
edit:Just so you understand the trick & is bit wise 'and' where as && is logical 'and'. Thanks to the comments about the forgotten shift.