Computer >> 컴퓨터 >  >> 프로그래밍 >> C 프로그래밍

C언어에서 변수의 메모리 표현을 출력하는 방법

이번 글에서는 C언어에서 변수가 메모리에 어떤 형태로 저장되어 있는지, 즉 메모리 표현을 직접 출력해 보는 방법을 알아보겠습니다. 정수(int), 실수(float), 그리고 포인터(pointer) 세 가지 자료형을 예로 들어 설명합니다.

구현 원리

변수의 메모리 내용을 바이트 단위로 확인하려면 다음과 같은 순서로 진행합니다.

  • 출력할 변수의 주소크기(sizeof)를 구합니다.
  • 해당 주소를 unsigned char* 타입으로 캐스팅하여 바이트 단위로 접근할 수 있게 만듭니다.
  • 변수의 크기만큼 반복문을 돌면서 캐스팅된 포인터가 가리키는 각 바이트의 값을 16진수로 출력합니다.

char 포인터를 사용하는 이유는 char가 정확히 1바이트 크기를 가지기 때문입니다. 어떤 자료형의 주소라도 char 포인터로 변환하면 메모리를 바이트 단위로 하나씩 읽어낼 수 있습니다.

예제 코드

#include <stdio.h>
typedef unsigned char *byte_pointer; // char*를 이용해 바이트 포인터 생성

void disp_bytes(byte_pointer ptr, int len) {
// 바이트 포인터를 받아 메모리 내용을 출력
int i;
for (i = 0; i < len; i++)
printf(" %.2x", ptr[i]);
printf("\n");
}

void disp_int(int x) {
disp_bytes((byte_pointer) &x, sizeof(int));
}

void disp_float(float x) {
disp_bytes((byte_pointer) &x, sizeof(float));
}

void disp_pointer(void *x) {
disp_bytes((byte_pointer) &x, sizeof(void *));
}

main() {
int i = 5;
float f = 2.0;
int *p = &i;
disp_int(i);
disp_float(f);
disp_pointer(p);
disp_int(i);
}

실행 결과

05 00 00 00
00 00 00 40
3c fe 22 00 00 00 00 00
05 00 00 00

결과 해석

정수 5의 경우: 05 00 00 00으로 출력됩니다. 이는 리틀 엔디안(Little Endian) 방식으로, 최하위 바이트(05)가 낮은 주소에 먼저 저장되기 때문입니다.

실수 2.0의 경우: 00 00 00 40으로 출력됩니다. IEEE 754 부동소수점 표준에 따라 2.0은 지수부와 가수부로 인코딩되며, 역시 리틀 엔디안 순서로 저장됩니다.

포인터의 경우: 실행 환경마다 할당되는 주소가 다르므로 출력 값은 시스템과 실행 시점에 따라 달라질 수 있습니다. 위 예제에서는 8바이트 크기의 포인터가 출력되었는데, 이는 64비트 시스템임을 의미합니다.

마지막 줄의 disp_int(i)는 동일한 변수를 다시 출력한 것으로, 같은 결과 05 00 00 00이 나오는 것을 확인할 수 있습니다.