들어가기 전에
우리가 C로 작성한 변수들은 실제로 컴퓨터 메모리에 어떻게 저장될까요? 메모리 주소를 나타내는 방법과 그 주소를 알아내는 방법, 그 주소에 찾아가는 방법을 배워봅시다.
학습 목표
16진법을 읽고 쓸 수 있습니다.
메모리 주소에 접근하고 값을 받아오는 코드를 C로 작성할 수 있습니다.
핵심 단어
- 16진법
- 메모리 주소
강의 듣기
들어가기 전에
우리가 C로 작성한 변수들은 실제로 컴퓨터 메모리에 어떻게 저장될까요? 메모리 주소를 나타내는 방법과 그 주소를 알아내는 방법, 그 주소에 찾아가는 방법을 배워봅시다.
학습 목표
16진법을 읽고 쓸 수 있습니다.
메모리 주소에 접근하고 값을 받아오는 코드를 C로 작성할 수 있습니다.
핵심 단어
강의 듣기
16진수
컴퓨터과학에서는 숫자를 10진수나 2진수 대신 16진수(Hexadecimal)로 표현하는 경우가 많습니다. 컴퓨터에서 데이터를 처리하기 위해 16진수를 사용할 때 장점이 있기 때문입니다. 16진수와 일상생활에서 우리가 사용하는 10진수와 비교하면 그 차이를 알 수 있습니다. 16진수를 사용하면 10진수보다 2진수를 간단하게 나타낼 수 있습니다. 16진수로 값을 표현하는 방법을 이해하고 나면 16진수, 2진수, 10진수를 변환하는 프로그램을 만들어볼 수 있습니다.
10진수를 16진수로 바꾸어보기
JPG 이미지 파일은 항상 255 216 255 로 시작되고 이것은 10진수입니다. 하지만 실제 컴퓨터 내에서는 10진수를 사용하지 않습니다. 컴퓨터는 0과 1만을 이해할 수 있기 때문입니다.
먼저 255 216 255를 2진수로 나타내보면 <그림 1>과 같습니다. 2진수로 모든 데이터를 표현하기에는 너무 길어지기 때문에 16진수로 바꾸어 보겠습니다. 2^424
이 16이기 때문에 4bits씩 두 덩어리로 나누어 보면 0000 부터 1111까지는 16진수로 표현할 수 있다는 것을 알 수 있습니다.
그렇다면 16진수에서 10부터 15까지는 어떻게 표기할까요? 10은 a, 11은 b, …, 15는 f를 대입하여 사용합니다. 4bits씩 16진수로 변환 후 0x를 붙혀 뒤에 오는 문자들이 16진수임을 알려줍니다.
16진수의 유용성
ASCII 코드에 의해 “A, B, C”는 10진수로 65, 66, 67에 해당합니다. 컴퓨터는 10진수를 이해할 수 없으므로 2진수로 표현해보면 "01000001 01000010 01000011"이 됩니다. 컴퓨터가 처리할 수 있어야 하기 때문에 어쩔 수 없지만 그 길이가 너무 긴 것을 알 수 있습니다.
하지만 16진수로 표현하면 2진수로 표현했을 때 보다 훨씬 간단해집니다. 또한 컴퓨터는 8개의 비트가 모인 바이트 단위로 정보를 표현합니다. 2개의 16진수는 1byte의 2진수로 변환되기 때문에 정보를 표현하기 매우 유용합니다.
메모리 주소
정수형 변수 n에 50이라는 값을 저장하고 출력한다고 생각해 봅시다.
이 n 이라는 값은 int 타입이므로, 아래 그림과 같이 우리 컴퓨터의 메모리 어딘가에 4바이트 만큼의 자리를 차지하며 저장되어 있을 것입니다.
C에서는 변수의 메모리상 주소를 받기 위해 ‘&’이라는 연산자를 사용할 수 있습니다.
#include <stdio.h>
int main(void)
{
int n = 50;
printf("%p\n", &n);
}
예를 들어, 위와 같은 코드를 실행하면 ‘0x7ffe00b3adbc’와 같은 값을 얻을 수 있고, 이는 변수 n의 16진법으로 표현된 메모리의 주소입니다.
반대로 ‘*’를 사용하면 그 메모리 주소에 있는 실제 값을 얻을 수 있습니다.
#include <stdio.h>
int main(void)
{
int n = 50;
printf("%i\n", *&n);
}
위 코드는 먼저 n의 주소를 얻고, 또 다시 그 주소에 해당하는 값을 얻어와 출력한 것이므로 결국 ‘50’이라는 값이 출력되겠죠.
생각해보기
'CS50'을 16진수로 표현해볼까요?
참고자료
comment
C -> 0x43
S -> 0x53
5 -> 0x35
0 -> 0x30
->> 0x43533530
0x43 0x53 0x35 0x30
C : 0x43
S : 0x53
5 : 0x35
0 : 0x30
C의 ASCII 값: 67 -> 16진수: 0x43
S의 ASCII 값: 83-> 16진수: 0x53
5의 ASCII 값: 53-> 16진수: 0x35
0의 ASCII 값: 48-> 16진수: 0x30
c의 아스키 값은 67->0x43/ s의 아스키는 83 -> 0x53/ 5의 아스키는 53->0x35/0의 아스키는 48->0x30
0x43 0x53 0x35 0x30
C의 ASCII 값은 67, 16진수로 43
S의 ASCII 값은 83, 16진수로 53
5의 ASCII 값은 53, 16진수로 35
0의 ASCII 값은 48, 16진수로 30
그래서 CS50을 16진수로 표현하면 43 53 35 30이 돼! >ㅇ<
char | decimal | | hexadecimal
C 67 0x43
S 83 0x53
5 53 0x35
0 48 0x30
C: 0x43
S: 0x53
5: 0x35
0: 0x30
CS50을 ASCII코드를 통해 16진수로 표현하면 0x43 0x53 0x35 0x30 가 나온다.
C: 0x43
S: 0x53
5: 0x35
0: 0x30
아스키 코드로 String "CS50"의 각 Char 값을 찾아보고 이를 16진법으로 전환한 결과
C : 67 -> 01000011 -> 0x43
S : 83 -> 01010011 -> 0x53
5 : 53 -> 00110101 -> 0x35
0 : 48 -> 00110000 -> 0x30
0x43, 0x53, 0x32
0x43 0x53 0x35 0x30
0x43533035
0 1 0 0 / 0 0 1 1 - 67 C
0 0 1 1 / 0 1 0 1 - 53 S
0x43 0x53 0x35 0x30 5 + 0
c s 50
0x43 0x53 0x32
C S 50
C : 67 -> 1000011 -> 00x43
S : 83 -> 1010011 -> 00x53
50 : 110010 -> 00x32
0x43 0x53 0x35 0x30
0x43 0x53 0x35 0x30