juuuding

CH 12 포인터의 이해 본문

C언어/윤성우의 열혈 C

CH 12 포인터의 이해

jiuuu 2023. 3. 15. 01:01

 1. 포인터란 무엇인가

 

1. 주소 값의 저장을 목적으로 선언되는 포인터 변수

int main(void) {

	char ch1 = 'A', ch2 = 'Q';
	int num = 7;

}

 

 

 

 이 코드에서는 총 6바이트(1+1+4)가 메모리 공간에 할당된다.  "int형 변수 num은 0x12ff76번지에 할당되어 있다"와 같이 시작번지만을 가지고 위치를 표현한다. 주소 값 0x12ff76번지 역시 정수인데 이것의 저장을 위해 마련된 변수가 "포인터 변수"이다. 따라서 "포인터 변수란 메모리 주소 값을 저장하기 위한 변수"라고 할 수 있다. 

 

int main(void) {

	int num = 7;
	int* pnum;	//포인터 변수 pnum의 선언
	pnum = #	//num의 주소 값을 포인터 변수 pnum에 저장

}

 여기서 pnum은 int형 변수의 주소 값을 저장할 수 있는 포인터 변수가 된다. 더하여 "& 연산자는 피연산자의 주소 값을 반환하는 연산자"이다. pnum과 num의 관계를 그림으로 나타내면 다음과 같다. 

 

pnum과 num의 관계

 

 위와 같이 포인터 변수 pnum에는 변수 num의 시작번지 주소 값이 저장된다. 따라서 "포인터 변수 pnum이 int형 변수 num을 가리킨다"고 표현할 수 있다.

 

 

2. 포인터 변수 선언하기

 포인터 변수 선언의 기본 공식은 "type * ptr"(type형 변수의 주소 값을 저장하는 포인터 변수 ptr의 선언)이다. 예를 들면 double * pnum2, unsigned int * pnum3와 같다. 이처럼int *, char *, double * 등을 가리켜 포인터 형이라고 하며 이는 자료형의 범주에 포함시키기도 한다. 

 

 

 

 2. 포인터와 관련 있는 연산자: & 연산자와 * 연산자 

 

1. 변수의 주소 값을 반환하는 & 연산자

 & 연산자는 피연산자의 주소 값을 반환하는 연산자이다. & 연산자의 피연산자는 변수여야하며, 상수는 피연산자가 될 수 없다. 

 

 

2. 포인터가 가리키는 메모리를 참조하는 * 연산자

 * 연산자는 포인터가 가리키는 메모리 공간에 접근할 때 사용하는 연산자이다. 때문에 아래의 코드는 다음과 같이 해석된다. 

int main(void) {

	int num = 10;
	int* pnum = #
	*pnum = 20;		//pnum이 가리키는 메모리 공간인 변수 num에 정수 20을 저장해라
	printf("%d", *pnum);	//pnum이 가리키는 메모리 공간인 변수 num에 저장된 값을 출력해라

}

 이렇듯 사실상 *pnum은 포인터 변수 pnum이 가리키는 변수 num을 의미하는 것이다.

 

int main(void) {

	int num1 = 100, num2 = 100;
	int* pnum;
	
	pnum = &num1;	//포인터 pnum이 num1을 가리킴
	(*pnum) += 30;	//num1+=30과 동일

	pnum = &num2;	//포인터 pnum이 num2을 가리킴
	(*pnum) -= 30;	//num2-=30과 동일

}

 

포인터 변수의 참조 관계

 

3. 다양한 '포인터 형'이 존재하는 이유

 "pnum이 int형 포인터 변수이므로 pnum에 저장된 주소를 시작으로 4바이트 읽어 정수로 해석해야한다.",  "pnum이 double형 포인터 변수이므로 pnum에 저장된 주소를 시작으로 8바이트 읽어 정수로 해석해야한다." 이처럼 포인터 형은 메모리 공간을 참조하는 기준이 된다. 즉, 포인터 형의 정의하는 이유는 * 연산자를 통한 메모리 공간의 접근 기준을 마련하기 위함이다.

 

 

4. 포인터에서의 널 포인터

 포인터 변수를 우선 선언만 해두고 이후에 유효한 주소 값을 채워 넣고 싶다면, 다음과 같이 초기화를 해야한다.

int main(void) {

	int* ptr1 = 0;	//0번지를 의미하는 것이 아니라 '널 포인터를 의미함'
	int* ptr2 = NULL;

}

이것이 의미하는 바는 "아무데도 가리키지 않는다"와 같다.