1.운영체제의 메모리 관리 방식
C언어 소스 코드에서 사용한 변수들은 컴파일 후 기계어로 변경되면 모두 메모리 주소로 바뀜.

메모리 주소는 운영체제가 관리함.
그래서 운영체제가 메모리를 어떻게 관리하는지 알아야함.
32비트 운영체제 vs 64비트 운영체제
각각 장단점이 있음.
32비트 운영체제는 메모리를 4gb 밖에 사용 못함.
64비트 운영체제에서는 16EB 헥사바이트 까지 사용할 수 있음.
64비트 운영체제는 데이터 기본 처리 단위가 64비트 라는 뜻. (메모리 사용량이 많음)
운영체제나 프로그램이 몇 비트인가에 대해서 이야기 하는 이유는 이 방식에 따라 데이터를 처리하는 기본 단위가 달라지기 때문.
운영체제는 메모리를 1바이트 단위로 관리한다.
32비트 윈도우는 0 ~ 42억번지 까지 바이트 단위로 주소가 매겨져 있다.
직접 주소 지정 방식
102번지에 1042 값을 2바이트 크기로 저장하겠다.

실제로는 1042는 두 개의 바이트에 각각 4와 18로 나뉘어 저장된다.

[*] 1042가 왜 4와 18로 나누어 질까?

1042는 8비트에 저장할 수 없기 때문에 두 개의 8비트에 4와 18라 나누어 저장된다.
메모리에 16진수로 표시해보기
16진수의 한 자릿수는 4비트로 표시할 수 있다.


C언어는 변수라는 개념으로 메모리 주소를 직접 적지 않으면서도 직접 주소 지정 방식을 사용한다.
번역기의 도움을 받아서 내부적으로 변수가 주소로 변환되어 결과적으로 직접 주소 지정 방식을 사용하게 되는것.

c언어에서 직접 주소 지정 방식의 한계
다른 함수에서 선언한 변수가 메모리에 존재해도 문법적으로 접근할 수 없다.

간접주소 지정 방식



이렇게 간접주소 지정 방식을 사용하면 1042 값이 108번지가 아니라 120번지로 변경되더라도 명령을 바꾸지 않아도 된다.
왜냐면 102번지에 저장되어 있는 주소를 108번지에서 120번지로 바꾸면 되기 때문이다.

명령을 바꾼다는 뜻은 기계어를 바꿔야 한다는 뜻이고, 이것은 코드를 다시 번역해서 실행 파일을 만들어야 한다는 뜻이다.
하지만 메모리에 있는 주소를 변경하는 것은 단순한 데이터 조작이기 때문에 코드를 다시 번역할 필요가 없고 프로그램이 실행되는 중에도 변경 할 수 있다.
2.포인터

이렇게 선언한 addr 변수에 주소를 저장할 수 있다.
하지만 일반 변수라서 실제로 해당하는 주소의 메모리에 가서 값을 읽거나 저장할 수 있는 기능이 없다.
이것은 c언어의 일반 변수가 자신이 위치한 메모리에서만 값을 읽거나 쓸 수 있는 직접 주소 지정 방식으로 동작하기 때문이다.
그래서 c언어는 간접 주소 지정 방식으로 동작하는 특별한 변수를 선언하기 위해 포인터 문법을 추가로 제공한다.




변수가 저장된 메모리 공간의 주소 얻기
변수의 주소는 변수 앞에 & 연산자를 사용하여 구할 수 있음.

*키워드의 또 다른 이름, 번지 지정 연산자


위 코드에서 short *ptr; 와 ptr = &birthday; 는 short *ptr = &birthday; 라고 줄여서 적을 수 있다.
주의점은!
Short *ptr = &birthday; 가 값을 대입 하는 형태와 비슷해서
* 키워드를 *ptr = 1042;에서 번지를 지정하기 위해 사용한 * 연산자와 같다고 착각할 수 있다는것이다.
short *ptr = &birthday; 는 포인터 변수를 선언하기 위해 사용한 것.
*ptr = 1042;의 * 연산자는 ptr 포인터가 가리키는 주소의 변수에 가서 1042 값을 대입하겠다는 의미이다.


위 예제에서 birthday 변수는 선언 후 직접 사용된 적이 없지만, ptr 포인터 변수에 의해 간접적으로 0x0412가 대입되었다.
ptr = 과 *ptr = 차이점
ptr = 형태는 포인터 변수에 주소를 저장한다.
포인터 변수의 주소는 ‘포인터가 가리키는 대상 메모리’의 시작 주소를 의미한다.

*ptr = 형태는 포인터가 가리키는 대상에 값을 저장한다.


3.포인터와 const 키워드
4.포인터 변수의 주소 연산
사용할 메모리의 범위를 기억하는 방법
1.시작주소와 끝주소를 기억하는방법

2.시작주소와 사용할 크기를 기억하는 방법

하지만 c언어 문법은 메모리를 사용할 때 항상 그 메모리의 크기를 먼저 결정하도록 되어 있다.
예를 들어 정수 값 5를 저장하고 싶다면 int data; 와 같이 변수를 선언해야 하는데 이때 사용할 메모리의 크기는 Int형으로 선언했기 때문에 4바이트로 결정된다.
결국 사용할 메모리 크기는 명령문에 포함되어 있다. 그래서 자신이 사용할 메모리의 시작 주소만 기억하면 된다.
이런 프로그래밍 언어의 특성 때문에 포인터도 자신이 가리킬 대상에 대해 사용할 범위는 저장하지 않고 사용할 메모리의 시작 주소만 기억하면된다.

포인터 변수의 주소 연산
포인터가 자신이 가리킬 대상 메모리의 시작 주소만 기억하면 되기 때문에 갖게 되는 특성이 있다.

위 예시에서 포인터 변수 p가 가리키는 대상의 크기가 2바이트 인데, 이 포인털 다음 데이터를 가리키려면 주소 값이 1이 아닌 2가 증가되어야 그 다음 데이터를 가리킬 수 있다.
이처럼 포인터 변수에 + 1 을 하면 자신이 가리키는 대상의 크기만큼 증가하는데, 이것을 ‘포인터 변수의 주소 연산’ 이라고 한다.


5.포인터와 대상의 크기
Int *p 라고 포인터 변수를 선언할 때 int 자료형은 포인터 변수의 크기를 의미하는 것이 아님.
포인터 변수가 가리키는 대상의 크기임!
따라서 포인터 변수 p에 일반 변수 data의 주소 값을 저장하고 포인터 변수 p를 사용하여 data 변수의 값을 변경하는 경우에는 두 변수의 자료형을 같게 지정하는 것이 일반적임.

포인터가 가리킬 수 있는 크기와 실제 대상의 크기가 다른경우

이러한 포인터의 특성을 활용하면 4바이트 크기의 변수에 저장된 값을 1바이트 단위로 출력할 수도 있다.

6.void 형 포인터



포인터 변수에 주소 값을 저장할 수 있지만 시작주소만 알고 끝주소는 모를때 사용.
'컴퓨터 기초 > C언어' 카테고리의 다른 글
| [C언어]38일차 - 링크드 리스트 (이것이 C언어 자료구조 알고리즘이다.) (0) | 2025.11.06 |
|---|---|
| [C언어]37일차 - C언어 기초 (이것이 C언어 자료구조 알고리즘이다.) (0) | 2025.11.06 |
| [C언어]36일차 - 빅오 표기법 (0) | 2025.11.04 |
| [C언어]35일차 - 동적계획법 알고리즘 (황금미로) (0) | 2025.10.31 |
| [C언어]35일차 - 동적계획법 알고리즘 (배낭문제) (0) | 2025.10.31 |