2016. 7. 28. 10:11

const ( 상수 )


많이 들어봤으나, 사용하는 사람은 자주 사용하고, 사용하지 않는 사람들은 자주 사용하지 않을것입니다.


상수 (constant)는 값을 '절대로' 바꿀 수 없다. 라는 특징을 가지고 있습니다.

또한 정의시 무조껀 값을 지정해주어야 합니다.


const ( 자료 타입 ) ( 상수 명 ) = ( 상수 값 );


1
2
3
4
5
6
#include <iostream>
 
int main()
{
    const int c = 10
}
cs


이런식으로 말이죠.


하지만 const의 위치는 여러군데에 붙을 수 있답니다.


1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
 
int main()
{
    int a = 10;
    
    const int * c1 = &a;     
    int * const c2 = &a; 
 
 
}
cs


위와 같은 코드를 보시면, c1과 c2의 차이점을 아시겠나요?


간단하게 생각하면 어떤게 상수화가 되는지를 생각하면 됩니다.


c1의 경우 정수형 포인터가 됩니다. 즉 c1의 메모리 주소를 변경이 가능하지만, 메모리에 있는 값을 변경하지 못하게 합니다.


하지만 c2는 상수형 포인터가 됩니다. c2의 메모리주소는 상수화 되어서 변경이 불가능하지만, 메모리에 있는 값은 변경이 가능하게 됩니다.


즉 이런 대입이 가능합니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
 
int main()
{
    int a = 10;
    
    const int * c1 = &a;     
    int * const c2 = &a; 
    
    int b = 20;
    
    c1 = &b;
    c2 = 100;
 
}
cs


이 의외에 대입을 하면 에러가 나니, 직접 해보시기 바랍니다.



Complite const 와 Runtime const


C++에서 const에는 2가지의 종류가 있습니다.


바로 컴파일 상수와 런타임 상수 입니다.


어떤 차이 냐면 아래 소스를 보시면 됩니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
 
int main()
{
    int m_1 = 10;
    int array01[m_1];  // error.
 
    const int m_2 = 10;
    int array02[m_2];  // ok..
 
    const int m_3 = s1;
    int array03[m_3];   // error.
}
cs


위 소스 에서 가운데 있는 array02를 제외하곤 전부 에러가 발생합니다.


이유가 뭘까요?


먼저 array01은 배열의 크기가 변수이기때문에 에러가납니다.


반대로 array02는 상수이기때문에 가능하지요. 하지만,


array03은 상수를 넣었는데 왜 에러가 날까요?


이는 array02에 쓰이는 m_2는 컴파일 상수이며, array03에 쓰이는 m_3는 런타임 상수이기 때문입니다.


실제로 코드를 보시면 m_3는 프로그램이 실행되어 배열 생성까지 도달할때 m_3에 대입되는 s1의 값을 모릅니다.


위 코드는 간단해서 생각만으로도 값을 알아낼 수 있지만, 좀더 복잡한 코드가 된다면 눈으로도 알아낼 수 없을것입니다.


이런 컴파일 상수와 런타임 상수과 확실하게 나눠진다면 정말 편할텐데 말이죠.


(PS. C++11에서는 이를 해결 할 수 있는 constexpr 이 있습니다. 참고하세요.)



const 위치에 따른 쓰임 변화


const는 정말 여러 위치에 놓일 수 있습니다.


변수 선언 시 : [const] 자료형타입 [ const ] 포인터 [const] 변수명

함수 선언 시 : [const] 자료형타입 [ const ] 포인터 [const] 함수명(매개변수...) [const { }


함수 변수를 생각하면 총 7군데나 되네요.. 많아라..


겹치는곳을 생각하면 총 4가지입니다. 걱정마시죠!


그럼 먼저 다시 짚고 가야할 부분이 있습니다.


const(상수화)가 되면 값 변경이 불가능하다.


그럼 이제 찾아야 할 점을 '어디서' 또는 '어떤게' 값 변경이 안되는가 입니다.



그럼 몸풀기로 생각을 해봅시다.


const int * * a;

int *const * a;

int * * const a;


이렇게 3개의 변수가 각각 다른 위치에 const를 달고 있습니다. 이 3개를 구분지어 볼까요?


먼저 '어디서', '어떤게' 영향을 받았나가 중요합니다.


그럼 제일 크게 const를 기반으로 자료형과 변수명을 나눌수있습니다.


(const int) * * a;

(int *const) * a;

(int **) const a;


위 처럼 나눠서 보면 더 쉬울까요?


첫번째 (const int) * * a; 은 상수화된 int의 이중포인터 라는 것입니다.

즉 해석하면 가능과같습니다.

const int x =10;

const int * y = &x;

이때 &x 가 const int ** 라고 형입니다.

즉, (const int) * * a; 에선 알맹이 값인 a가 상수처리 되는것이죠.


다시 말하면

a (값변경가능 = 주솟값)

*a (값 변경가능 = 주솟값)

**a (값 병경 불가능 , 상수)

입니다.


2번쨰 (int *const) * a; 은 int*이 가지고 있는 주솟값 즉 *를 상수화 시킨겁니다.


가리키는 방향을 상수화 한거죠.


간단하죠?


3번쨰는 (int **) const a;

int **형 자체가 상수화가 된겁니다.


즉 처음으로 가리키는 주솟값이 상수화가 된것이지요.


함수도 비슷합니다. 하지만 마지막으로 함수 맨뒤에 붙는 const는 함수 내부 내용을 상수화 하겠다는 뜻입니다. 즉, 함수 내부에서는 값을 변화시키는 행위를 일절 하지 못하게 막는다는 소리입니다.


감사합니다



Posted by 시리시안