"속세에서 사람이 오는 것은 귀찮노라. 라곤 해도 그건 네가 아니다." – 大田 南畝(오오타 난포) / 狂歌(광가)

2014/12/27

pointer와 const

포인터를 보면 상수 포인터도 있고 상수를 가리키는 포인터도 있지요. 근데 제가 바보라 그런 건지 cpp를 자꾸 안 써서 그런 건지 어쩐 건지 계속 잊어먹고 헷갈리고 그러네요. 다시 상기시킬 겸 적어둡니다. ;ㅁ;

int main()
{
    int i = 1;
    int j = 2;

    int * p = &i;
    int * q = &j;

    int ** pp = &p;
    int ** qq = &q;

    //

    int *const pc = p;

    pc = q; // error C3892: 'pc' : you cannot assign to a variable that is const
    *pc = j;

    //

    const int * cp = p;

    cp = q;
    *cp = j; // error C3892: 'cp' : you cannot assign to a variable that is const

    //
    //

    int **const ppc = pp;

    ppc = qq; // error C3892: 'ppc' : you cannot assign to a variable that is const
    *ppc = q;
    **ppc = j;

    //

    int *const * pcp = pp;

    pcp = qq;
    *pcp = q; // error C3892: 'pcp' : you cannot assign to a variable that is const
    **pcp = j;

    //

    const int ** cpp = pp; // error C2440: 'initializing' : cannot convert from 'int **' to 'const int **'

    cpp = qq; // error C2440: '=' : cannot convert from 'int **' to 'const int **'
    *cpp = q;
    **cpp = j; // error C3892: 'cpp' : you cannot assign to a variable that is const

    //
    //

    int *const *const pcpc = pp;

    pcpc = qq; // error C3892: 'pcpc' : you cannot assign to a variable that is const
    *pcpc = q; // error C3892: 'pcpc' : you cannot assign to a variable that is const
    **pcpc = j;

    //

    const int **const cppc = pp; // error C2440: 'initializing' : cannot convert from 'int **' to 'const int **const '

    cppc = qq; // error C2440: '=' : cannot convert from 'int **' to 'const int **const '
    *cppc = q;
    **cppc = j; // error C3892: 'cppc' : you cannot assign to a variable that is const

    //

    const int *const * cpcp = pp;

    cpcp = qq;
    *cpcp = q; // error C3892: 'cpcp' : you cannot assign to a variable that is const
    **cpcp = j; // error C3892: 'cpcp' : you cannot assign to a variable that is const

    //
    //

    const int *const *const cpcpc = pp;

    cpcpc = qq; // error C3892: 'cpcpc' : you cannot assign to a variable that is const
    *cpcpc = q; // error C3892: 'cpcpc' : you cannot assign to a variable that is const
    **cpcpc = j; // error C3892: 'cpcpc' : you cannot assign to a variable that is const

    return 0;
}

(삼중 포인터까지 하려다가 쓸데없어서 그만 적음.)

포인터만 알면 너무 기초적이고 이중부터는 저렇게 잘 쓰지도 않을 테니(쓰려나?) 따로 설명은 안 적어도 될 것 같네요. vs2013에서 컴파일했고 .c로 컴파일하면 45, 47, 62줄 오류는 사라지고 나머지는 c2166(좌변값 상수 개체로 지정됨)으로 나옵니다.

딴 얘기를 좀 하자면 45줄과 47줄은 오류 번호는 같으나 내용을 보면 45줄은 초기화를 실패한 것이고 47줄은 대입을 실패한 것입니다. 다시 말해서 45줄의 =은 변수 선언문과 초깃값을 구분하는 구두점이고 47줄의 =은 변수에 값을 대입하는 연산자입니다. 모양은 같으나 동작은 완전히 다릅니다. 같다고 착각하면

int ar[ 5 ];
ar = { 1, 2, 3, 4, 5 };

이와 같이 실수할 수 있습니다. 이 문장은 컴파일러가 오류를 잡아주기 때문에 못 보고 지나 치진 않겠지만, 오류가 왜 나는지 알고 있는 것도 나쁘진 않겠지요. 덧붙여서 위의 문장을 .c로 컴파일하면 둘째 줄에 c2059(구문 오류) 오류가 나고 .cpp로 컴파일하면 c3079(초기화 목록은 대입 연산자 우변값으로 사용 못 함) 오류가 납니다.


참조

혼자 연구하는 C/C++ 1권
http://stackoverflow.com/questions/1143262/what-is-the-difference-between-const-int-const-int-const-int-const
https://kldp.org/node/68231
http://stackoverflow.com/questions/13267277/where-can-we-use-list-initialization

댓글 남기기 | cat > 타닥타닥 | tag >

댓글 남기기

* 표시된 곳은 반드시 입력해주세요