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로 해석되는 것이다.

참고

⚠️ **GitHub.com Fallback** ⚠️