[CS50] 메모리

업데이트:





메모리 주소

16진수

  • 컴퓨터과학에서는 숫자를 10진수나 2진수 대신 16진수(Hexadecimal)로 표현하는 경우가 많다.
  • 16진수의 장점
    • 16진수를 사용하면 10진수보다 2진수를 간단하게 나타낼 수 있다.



10진수를 16진수로 바꾸어보기

  • JPG 이미지 파일은 255 216 255로 시작되고 이것은 10진수이다. 하지만 컴퓨터는 0과 1만을 이해할 수 있기 때문에 실제 컴퓨터 내에서는 10진수를 사용하지 않는다.

그림1


  • 2진수로 모든 데이터를 표현하기에는 너무 길어, 16진수로 바꾸어보자.
  • 24 이 16이기 때문에 4bits씩 두 덩어리로 나누어 보면 0000부터 1111까지는 16진수로 표현할 수 있다.
  • 16진수에서 10부터 15까지를 표기하려면 10은 a, 11은 b, …, 15는 f를 대입하여 사용한다. 4bits씩 16진수로 변환 후 0x를 붙여 뒤에 오는 문자들이 16진수임을 알린다.



16진수의 유용성

  • 10진수를 2진수로 표현하면 길이가 너무 길다.
  • 16진수로 표현하면 2진수로 표현했을 때보다 훨씬 간단해진다. 또한 컴퓨터는 8개의 비트가 모인 바이트 단위로 정보를 표현한다. 2개의 16진수는 1byte의 2진수로 변환되기 때문에 정보를 표현하기 매우 유용하다.

그림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이 출력된다.




포인터

  • * 이 연산자를 이용해서 포인터 역할을 하는 변수를 선언할 수도 있다.
#include <stdio.h>

int main(void)
{
   int n = 50;
   int *p = &n;
   printf("%p\n", p);
   printf("%i\n", *p);
}
  • 정수형 변수 n에는 50이라는 값이 저장되어 있다.
  • *p 포인터 변수에 &n이라는 값, 즉 변수 n의 주소를 저장한다.
  • int *p에서 *는 이 변수가 포인터라는 의미이고, int는 이 포인터가 int 타입의 변수를 가리킨다는 의미이다.
  • 따라서 첫 번째 print문과 같이 포인터 p의 값, 즉 변수 n의 주소를 출력하거나, 두 번째 printf문과 같이 포인터 p가 가리키는 값, 즉 변수 n의 값을 출력할 수도 있다.

포인터


  • 실제 컴퓨터 메모리에서 변수 p는 위와 같이 저장될 수 있다.

포인터2


  • 하지만 위의 그림과 같이 실제로 p의 값, 즉 n의 주소를 생각하지 않고, 추상적으로 단지 p가 n을 가리키고 있다는 것만 생각해도 된다.
  • 이런 포인터를 기반으로 해서 앞서 배울 다양한 데이터 구조를 정의하고 사용할 수 있다.

태그:

카테고리:

업데이트:

댓글남기기