본문 바로가기
기술자료/C C++

const 에 대해서 알아봅시다..

by 알 수 없는 사용자 2009. 8. 7.
728x90
반응형

c/c++ 언어 에서는 const 라는 제한자가 존재하는데 이의 쓰임에 대해서 잠깐 정리해 보겠습니다.

 

1.  형식

먼저, const 를 사용하는 형식은  다음과 같습니다.

1) const 자료형 변수명 = 초기값

    ex)

          const float PI = 3.1415;

 

2) 자료형 const 변수명 = 초기값

    ex)

          float const PI = 3.1415;

 

 

const는 이처럼 변수선언시 변수 앞부분에 사용하여 해당 변수가 상수임을 정의합니다. 위의 예처럼, const는 자료형 앞이나 변수명 앞에 사용할수있으며,  둘다 반드시 초기값을 가져야 한다는 속성을 가집니다.

하지만, 관습적으로  1)과 같이 변수의 자료형 앞에 주로 사용하여 상수임을 나타내게 됩니다.

 

2. 특징

const는 변수에 사용하여 해당 변수를 상수로 만드는 키워드 입니다. 따라서,  const로 지정된 변수는 선언시 지정한 값이외에  새로운 값을 대입할수 없으며, 만일 대입시는 컴파일 에러가 발생하게 됩니다. 

 

float area(int r) {

   const float PI = 3.1415;

   float value = PI*(r*r);

   PI = 4.2; //컴파일시 에러 발생 

   return value;

}

위의 예처럼 PI에 새로운 값을 대입하면 바로 컴파일러는 에러를 발생시킵니다.

 

3. 배열선언시 배열 크기로 사용

const로 지정된 상수는 배열선언시 배열의 크기값으로 사용할수 있습니다.

const int SIZE = 10;

int num[SIZE];

 

만일, 아래와 같이 일반변수를 배열의 크기로 사용한다면 컴파일에러가 발생합니다.

int size = 10;

int num[size];

 

4. #define과 차이점

c/c++언어에서는 #define 라는 매크로를 선언문을 지원하는데, const 와 같이 상수를 정의할수 있다는 점에서 공통점을 가집니다.

 

1) #define 매크로 상수는 지정된 타입이 명확하지 않다

const는 선언시 자료형을 사용하므로 해당 상수의 타입을 분명하게 명시할수 있지만, #define은 타입지정을 요구하지 않습니다.

 

2) #define으로 지정된 매크로 상수는 선언후, 일반적으로 어느곳에서나 사용할수 있지만, const는 일반변수와 마찬가지로 해당 상수가 선언된 영역내에서만 사용가능 합니다.

 

3) #define 매크로 구문은 컴파일러가 아닌 전처리기에 의해서 해당 문장이 처리(치환) 되다 보니 디버깅시 매크로 상수의 값을 확인하기 어렵다는 단점을 가집니다.

 

5. 포인터와 사용

 

포인터와 const를 사용하는 경우, 일반적인 변수에 사용시와는 약간 다른점이 있습니다.

 

1)

int n = 10;

const int *p = &n;

2)

int n = 10;

int* const p = &n;

3)

int n = 10;

const int* const p = &n;

 

위의 3개의 각각에 대해서 설명드리면 다음과 같습니다.

앞서 const는 변수에 사용하여 상수를 나타낸다고 했습니다. 그럼, 포인터에 const 선언시 어느 부분이 상수로 되는지 알아야 합니다.

 

1)

const int  *p = &n : 문장을 해석하면 p는 포인터 입니다. 어떤 자료형에 대한 포인터 이냐면? const int (상수형 int)에 대한 포인터라고 말할수 있습니다.

 

int n1 = 10; int n2 = 20;

const int *p = &n1;

*p = 15;   (에러)

p = &n2;   (정상)

 

정리하면, 포인터는 상수형 int 변수를 가리키는 포인터변수 이므로, 값을 변경할수는 없지만, 가리키는 대상은 변경할수 있습니다. 즉, 포인터가 상수가 아니라 포인터가 가리키는 대상이 상수라는 의미입니다.

 

2)

int* const p = &n : 문장을 풀이하면 p는 상수입니다. 그리고 p는 정수형 포인터 입니다. 즉, p는 상수로써 포인터 라는 의미입니다. 

 

int n1 = 10; int n2 = 20;

int* const p = &n1;

*p = 15;   (정상)

p = &n2;   (에러)

 

정리하면, 포인터는 상수로 가리키는 대상을 변경할수는 없지만, 가리키는 대상의 값을 변경할수 있습니다. 즉, 포인터는 변수의 주소값을 가지는데 포인터가 상수이므로, 한번 지정된 변수의 주소값 이외에는 다른값을 대입할수 없다는 뜻입니다.

 

3)

const int* const p = &n: 이문장은 앞의 1), 2)를 합쳐논 것으로 포인터가 상수이고, 포인터가 가리키는 변수 역시 상수라는 의미입니다.

int n1 = 10; int n2 = 20;

const int* const p = &n1;

*p = 15;   (에러)

p = &n2;   (에러)

 

결론:

정리하면, const는 일반변수에 상수를 지정하는 키워드로 반드시 자료형이나 변수명앞에 사용되며, 선언시 반드시 초기값을 지정해줘야 합니다.     따라서, const를 "*" 앞에 사용할수는 없습니다.

 

ex)

int const* p = &n; (에러)

int* const p = &n; (에러없음)

const int* p = &n; (에러없음)

 
728x90