C 포인터 연산 배열을구조체로 - sonkoni/Koni-Wiki GitHub Wiki
연속된 메모리 공간에서 배열과 구조체의 자료 저장 매커니즘은 동일하다.
#include <stdio.h>
#include <stdint.h>
struct Test {
int8_t a; // char 와 동일
int8_t b;
int8_t c;
int8_t d;
};
int main(int argc, char *argv[]) {
int8_t arr[] = {11, 12, 13, 14, 21, 22, 23, 24, 31, 32, 33, 34, 41, 42, 43, 44};
struct Test *buffer;
for (int i = 0; i < 4; i++) {
buffer = (struct Test *)(arr + sizeof(struct Test) * i);
printf("%d %d %d %d\n", buffer->a, buffer->b, buffer->c, buffer->d);
}
return 0;
}
// 11 12 13 14
// 21 22 23 24
// 31 32 33 34
// 41 42 43 44#include <stdio.h>
#include <stdint.h>
struct Test {
char a;
int32_t b; // int 형과 동일. 4바이트(32비트).
} __attribute__((aligned(1), packed)); // 멤버정렬 해제
int main(int argc, char *argv[]) {
char arr[] = {11, 1, 2, 3, 4, 22, 4, 3, 2, 1, 33, 7, 6, 5, 4};
struct Test *buffer;
printf("struct size: %zu\n", sizeof(struct Test));
for (int i = 0; i < 3; i++) {
buffer = (struct Test *)(arr + sizeof(struct Test) * i);
printf("%d %d(%08x)\n", buffer->a, buffer->b, buffer->b);
}
return 0;
}
// struct size: 5
// 11 67305985(04030201) // 10진수 67305985 == 16진수 04030201
// 22 16909060(01020304) // 10진수 16909060 == 16진수 01020304
// 33 67438087(04050607) // 10진수 67438087 == 16진수 04050607먼저, 구조체 내부에 여러 자료형을 사용하고 있기 때문에 멤버정렬을 해제한다. 그렇게 하지 않으면 char 영역에 자동정렬이 발생하여 구조체 총 크기는 8비트가 되어버린다. 이러면 우리가 원하는 결과를 만들 수 없다.
그 다음 앞 예제와 동일하게 구조체 단위로 값을 읽어온다. 어떤 일이 벌어지는가?
struct Test {
┌─────────────────────▶ char a;
char arr [11][1][2][3][4] int32_t b; ◀─┐
============ } │ 0x04030201 == 67305985
Little Endian int |04||03||02||01| ──▶ [04030201] ─────┘
char 1바이트 + int 4바이트를 읽어온다. int 의 경우 리틀엔디언으로 해석되므로, 이를 합쳐서 통으로 [04030201] 로 해석된다. 즉 10진수 67305985 가 b로 해석되는 것이다.