포인터 변수는 가리키고자 하는 변수의 자료형에 따라서 선언하는 방법이 달라진다.
type* ptr; //type형 변수의 주소 값을 저장하는 포인터 변수 ptr의 선언
포인터 변수의 선언 및 구분에 사용되는 int* 등을 가리켜 '포인터 형'이라 한다. 포인터의 형은 메모리 공간을 참조하는 기준이 된다.
정수 7이 저장된 int형 변수 num을 선언하고(1) 이 변수의 주소 값 저장을 위한 포인터 변수 pnum을 선언하자.(2) 그리고 나서 pnum에 변수 num의 주소 값을 저장하자.(3)
int main(void) {
int num = 7; //(1)
int* pnum; //(2)
pnum = # //(3)
...
}
변수 num의 주소 값이 0x12ff76 ~ 0x1279 라고 한다면, 포인터 변수 pnum에는 변수 num의 시작번지 주소 값인 0x12ff76이 저장된다. 즉, num에는 7이 저장되어있고, pnum에는 0x12ff76이 저장되어있다.
(포인터 변수의 크기는 주소 값의 크기와 동일하다.)
피연산자의 주소 값을 반환한다. 이때 피연산자는 상수가 아닌 변수이어야 하고, 변수의 자료형과 포인터형이 일치해야 한다.
포인터가 가리키는 메모리 공간에 접근할 때 사용하는 연산자이다.
int main(void)
{
int num = 10;
int* pnum = # // 포인터 변수 pnum이 변수 num을 가리키게 함
*pnum = 20; // pnum이 가리키는 변수에 20을 저장
printf("%d", *pnum); // pnum이 가리키는 변수를 부호 있는 정수로 출력
...
}
여기서 *pnum은 포인터 변수 pnum이 가리키는 변수 num을 의미한다.
#include <stdio.h>
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; 과 동일
printf("num1:%d, num2:%d \n", num1, num2);
return 0;
}
실행 결과
num1:130, num2:70
일반 변수와 포인터 변수를 하나의 문장 안에서 동시에 선언하는 것도 가능하다.
int num, *pnum;
그러나 선언하고자 하는 변수의 형이 다르면 문장을 달리해서 선언하는 것이 좋다.
// 더 좋은 코드
int num;
int * pnum;
포인터 변수를 선언만 하고 초기화하지 않으면, 포인터 변수는 쓰레기 값으로 초기화된다.
int main(void)
{
int* ptr = 125;
*ptr = 10;
}
위와 같이 포인터 변수를 일반 상수로 초기화하는 것은 쓰레기 값으로 초기화한 것과 다르지 않다.
포인터 변수를 우선 선언만 해놓고, 이후에 유효한 주소 값을 채워 넣을 것이라면 다음과 같이 초기화하는 것이 좋다.
int main(void)
{
int* ptr1 = 0;
int* ptr2 = NULL; //NULL은 사실상 0을 의미함
}
이때 ptr1을 초기화하는 값 0은 '널 포인터'라고 한다. 이는 "아무데도 가리키지 않는다"는 의미이다.
int main(void)
{
int num = 10;
int* ptr1 = #
int* ptr2 = ptr1;
(*ptr1)++;
(*ptr2)++;
printf("%d \n", num);
return 0;
}
변수와 포인터 변수의 관계
출력의 결과: 12
#include <stdio.h>
int main(void)
{
int num1 = 10, num2 = 20;
int* ptr1 = &num1;
int* ptr2 = &num2;
(*ptr1) += 10;
(*ptr2) -= 10;
ptr1 = &num2;
ptr2 = &num1;
printf("%d, %d \n", (*ptr1), (*ptr2));
}
ptr1과 ptr2가 가리키는 대상을 바꿀 때, 포인터 변수에 *를 붙이지 않도록 주의하자.
만약 아래와 같이 코드를 작성한다면, 실행 결과는 (num2의 주소 값), (num1의 주소 값)이 될 것이다.
*ptr1 = &num2; //num1 = &num2과 동일
*ptr2 = &num1; //num2 = &num1과 동일