포인터 대상의 const 선언
포인터 변수가 참조하는 대상의 변경을 허용하지 않는 const 선언
아래의 코드에서 보이는 바와 같이 포인터 변수 mafa를 대상으로도 const 선언을 할수가 있다.
int main(void)
{
int num = 20;
const int * mafa = #
* mafa =30 ; // 컴파일 에러!!!!!
num = 40; // 컴파일 성공!
}
위의 예제에서 주의 깊게 볼 곳은 const 의 선언 위치이다.
이 예제에서 선언된 const의 뜻은 "포인터 변수 mafa를 이용해서 mafa가 가리키는 변수에 저장된 값을 변경하는 것을 허용하지 않겠다! " 라는 의미이다.
그렇다고 해서 포인터 변수 mafa가 가리키는 변수 num이 상수화가 되는 것은 아니다.
다음 예제를 보자
int main(void)
{
int num1 = 20;
int num2 = 30;
int * const mafa = &num1;
mafa = &num2; // 컴파일 에러!!!!
*ptr = 40; // 컴파일 성공!
}
위의 예제의 의미는 포인터 변수 mafa는 상수가 된다. 포인터 변수 mafa가 상수라는 뜻은 한번 주소 값이 저장되면 그 값이 변경이 불가능하다는 뜻이며 , 이는 한번 가리키기 시작한 변수를 끝까지 가리켜야 한다는 뜻으로 이해 할 수 있다.
이예제를 보면 상수화된 포인터 변수 mafa가 num1를 가리키고 있다. 그런데 그 다음 행에서 가리키는 대상을 num2로 바꾸기 위한 연산을 진행하고 있다. 하지만 mafa는 상수이기 때문에 이 부분에서 컴파일 에러가 발생한다. 물론 mafa가 상수일 뿐이니 다음과 같이 mafa가 가리키는 대상에 저장된 값을 변경하는 연산은 문제가 되지 않는다.
지금까지 포인터 변수를 대상으로 하는 두 가지 형태의 const 선언에 대해서 설명하였는데 , 다음과 같이 하나의 포인터 변수를 대상으로 이 두 가지 형태의 const 선언을 동시에 할 수도 있다.
const int * const mafa = #
이렇게 선언이 되면 맨 앞으 const 선언으로 인해 다음의 연산이 불가능해지고,
*mafa = 20; // 컴파일 에러!!!!!
포인터 변수 mafa 앞의 const 선언으로 인해서 다음의 연산도 동시에 불가능해진다.
mafa = &age; // 컴파일 에러!!!!!
const 선언이 갖는 의미?
const는 처음엔 C++에만 존재하던 키워드 였는데 , C언어의 표준을 재정립하는 과정에서 C언어의 일부가 되었다. 그만큼 cosnt 선언은 중요하고 유용하다는 뜻이다. const 선언을 많이 하면 그만큼 프로그램 코드의 안정성은 높아진다.
int main(void)
{
double PI = 3.1415 ;
double rad ;
PI = 3.112 // 실수로 잘못 삽입된 문장이다. 컴파일 시에도 발견이 안된다.
scanf("%lf",&rad);
printf("circle area %f \n", rad*rad*PI);
return 0;
}
이는 원의 넓이를 계산하여 출력하려고 하였다가 원주율에 해당되는 값이 저장된 변수의 값을 변경하는 실수를 한 상황이다. 물론 프로그래머도 PI의 값을 변경하면 안되는 것을 알고 있지만 실수를 한 것이다.
여기서 가장큰 문제는 컴파일러가 이러한 문제점을 발견하지 못하는 데에 있다.
이러한 짧은 소스에서야 금방 디버깅을 할 수 있겟지만 나중에 몇천라인 정도되는 프로그램을 작성하고 컴파일까지 완료한 상태에서 실행 한 후 결과가 조금 이상하다면 거의 찾기가 불가능 할 것이다. 그래서 현명한 프로그래머는 값이 변경되서는 안되는 변수앞에 const를 써주어 안정성을 높이는 것이다.