포인터의 주의사항
저번에 포인터의 형이 중요하다고 하였다. 이외에도 주의할 점이 있는데, 선언만 하고 초기화를 하지 않을 때이다.
우리는 C언어에서 변수를 선언만 하고 초기화하지 않는 경우가 있는데, 전역변수나 static변수가 아닌이상 임의의 값으로 초기화 된다. 여기서 문제는 포인터는 메모리상의 주소이고 이 주소값에 잘못 접근하게 되면 중요한 영역에 접근할 수 있어 치명적이기 때문이다. (물론 잘못된 메모리 접근은 컴퓨터가 막아주긴 한다.)
따라서 우리는 널(NULL)포인터를 사용하는데, 이러한 문제를 방지하기 위해 사용한다.
int a;
int *pa = NULL; // 널포인터로 초기화
포인터와 배열
사실 배열은 포인터와 굉장히 긴밀한 관계를 갖고 있다. 아니 긴밀하다 못해 그냥 동치라고 봐도 무방할 것이다.
왜냐하면, 배열의 이름은 곧 첫번째 요소의 주소를 가지는 상수형 포인터이기 때문이다.
다음 예제를 보자
#include <stdio.h>
int main () {
int arr[] = {1,2,3};
printf("배열이름: %p\n", arr);
printf("1: %p\n", &arr[0]);
printf("2: %p\n", &arr[1]);
printf("3: %p\n", &arr[2]);
}
이를 실행시키면 다음과 같이 될 것이다.\
이를 통해 포인터의 이름은 배열의 첫번째값의 주소와 같다는 것을 알 수 있다. 하지만 배열은 상수형 포인터라고 했다. 즉, 배열의 선언을 통해 메모리의 주소값이 주어지지만, 이를 바꿀 수는 없다는 것이다.
다음 예제를 확인해보자.
#include <stdio.h>
int main () {
int arr[] = {1,2,3};
// printf("배열이름: %p\n", arr);
// printf("1: %p\n", &arr[0]);
// printf("2: %p\n", &arr[1]);
// printf("3: %p\n", &arr[2]);
arr = &arr[1];
}
이를 실행시키면, 다음과 같이 컴파일 에러가 난다.
즉, 배열의 포인터는 상수형임을 명심하자.