와드의 블로그

13. 포인터 본문

프로그래밍 언어/C

13. 포인터

Ward 2021. 9. 16. 03:03

(1) 운영체제의 메모리 관리 방식

 

* 운영체제와 프로그래밍

지금까지 변수를 사용하여 메모리에 데이터를 저장하거나 읽었다. 변수들은 컴파일 작업 후 모두 메모리 주소로 바꾸어 적용되고 운영체제가 이 메모리를 관리한다.

 

* 메모리 주소 지정 방식

운영체제는 메모리 주소를 1바이트 단위로 관리한다.

직접 주소 지정 방식: 메모리를 사용할 때 프로그래머가 사용할 메모리 주소를 직접 적는 방식으로 변수에 값을 대입하는 것과 같다.

간접 주소 지정 방식: 메모리에 데이터가 담긴 주소를 저장하고 이 주소를 통해 데이터에 접근한다. 데이터의 위치가 바뀌면 주소만 수정하면 되기 때문에 명령어를 바꿀 필요가 없다.

 

(2) 포인터

 

* 포인터란?

포인터 변수는 메모리 주소를 저장하기 위한 변수이다.

포인터 변수는 일반 변수와 달리 * 기호를 추가로 사용하여 선언한다.

 

* 변수가 저장된 메모리 공간의 주소 얻기

프로그램은 실행될 때마다 사용할 메모리 공간의 주소가 달라진다. 따라서 프로그램에 선언된 변수의 주소는 프로그램이 실행될 때마다 다른 주소에 할당된다.

변수가 위치한 메모리 주소 출력

#include <stdio.h>

int main()
{
	int birthday;
	int* ptr;
	ptr = &birthday;

	printf("birthday 변수의 주소는 %p입니다.\n", ptr);
}

 

* '*' 키워드의 두 가지 사용

int* ptr // int형 포인터 변수의 선언
*ptr = 1000// ptr에 저장된 주소가 가리키는 곳에 1000을 저장 (주소 지정 연산자)

* 다른 함수에 선언된 지역 변수 사용하기

#include <stdio.h>

void WrongSwap(int a, int b) {
	int tmp = a;
	a = b;
	b = tmp;
}

void CorrectSwap(int* a, int* b) {
	int tmp = *a;
	*a = *b;
	*b = tmp;
}

int main()
{
	int a = 1, b = 2, c = 1, d = 2;

	WrongSwap(a, b); // a, b는 main함수에 선언된 지역 변수이기 때문에 WrongSwap에서 접근할 수 없다.
	CorrectSwap(&a, &b); // 포인터를 사용하면 가능하다.

	printf("%d %d %d %d", a, b, c, d); 

	return 0;
}

 

(3) 포인터와 const 키워드

 

* 포인터 변수에 const 키워드를 사용하는 여러 가지 방법

int data = 5, tmp = 0;
int* const p = &data; // 포인터 변수를 선언할 때만 p에 주소 값을 대입할 수 있다.
*p = 3;
p = &tmp; // 오류 발생, 주소값 수정 불가능
----------------------------------------------------------------------------------        
int data = 5;
int const* p = &data; // p가 가리키는 대상에 const 적용 
*p = 3; // 오류 발생, p가 가리키는 값 수정 불가능
----------------------------------------------------------------------------------
int data = 5, tmp = 0;
int* const* p = &data; // 포인터 변수를 선언할 때만 p에 주소 값을 대입할 수 있다.
*p = 3; // 둘 다 오류가 발생한다.
p = &tmp;

 

(4) 포인터 변수의 주소 연산

 

* 사용할 메모리의 범위를 기억하는 방법

시작 주소와 끝 주소로 메모리 범위 기억하기: 4 + 4 = 8바이트가 필요하다.

시작 주소와 사용할 크기로 메모리 범위 기억하기: 메모리를 사용할 때 자료형으로 항상 그 메모리의 크기를 먼저 정하므로 메모리의 시작 주소만 기억하면 된다. 따라서 4바이트가 필요하다.

 

* 포인터 변수의 주소 연산

포인터 변수가 연산을 할 때 포인트 변수에 +1을 하면 자신이 가리키는 대상의 크기만큼 증가한다.

 

(5) void*형 포인터

 

* 대상의 크기가 정해져 있지 않은 void* 형 포인터

void*형 포인터는 자신이 사용할 대상의 크기 지정을 잠시 미룰 수 있다. void* 포인터의 주소가 가리키는 값에 데이터를 저장할 대는 향상 사용할 크기를 표기해 줘야 한다.

 

 참조문헌: C언어 입문

'프로그래밍 언어 > C' 카테고리의 다른 글

15. 배열과 포인터  (0) 2021.09.17
14. 표준 입력 함수  (0) 2021.09.16
12. 배열과 문자열  (0) 2021.09.14
11. 지역 변수와 전역 변수  (0) 2021.09.12
10. 시프트 연산자와 비트 연산자  (0) 2021.09.12