Programming Tools/C++

[C++] Const 총 정리 - 1

LiDARian 2021. 6. 12. 18:10
반응형

Pointer와 Const variable

const(상수)값은 그 값을 변경할 수 없다.
변경할 수 있는 값은 non-const(비상수)라고 할 수 있겠다.

#include <stdio.h>

void main(){
    int value = 5;
    int* ptr = &value;
    *ptr = 6;

    printf("%d\n", *ptr);
}

출력 : 6

 

하지만 value의 값이 상수인 경우에는 어떻게 될까?

#include <stdio.h>

void main(){
    const int value = 5;
    int* ptr = &value;
    *ptr = 6;

    printf("%d\n", *ptr);
}

출력 : 컴파일 에러

 

위 코드는 컴파일되지 않는다. 상수 변수는 값을 변경할 수 없다.
만약 상수가 아닌 포인터가 상수 변수를 가리킨 다음에 역참조하여 값을 바꿀 수 있다면, const의 의도를 위반하게 되므로 상수가 아닌 포인터는 상수 변수를 가리킬 수 없다.

 

물론, 종종 컴파일러에서 최적화 기능을 통해 const 한정자를 제거하고 컴파일 하는 경우도 있다. 하지만 기본적으로는 컴파일되지 않는다.


Pointer to Const 포인터 상수

const int * ptr 

형식에 대한 설명이다.

 

이 때의 pointer는 const가 아니고, pointer가 가리키는 곳이 const이다.
const int* ptr이라는 선언은 const int를 가르키는 pointer(*)라는 의미이다.

#include <stdio.h>

void main(){
    const int value = 5;
    const int* ptr = &value; 
    *ptr = 6;

    printf("%d\n", *ptr);
}

출력 : 컴파일 에러 error: assignment of read-only location

‘*ptr’ : 6 | *ptr = 6;

 

이번에도 마찬가지로 pointer는 const가 아니고, pointer가 가리키는 곳이 const이다.

#include <stdio.h>

void main(){
    int value = 5;
    const int* ptr = &value;
    *ptr = 6;

    printf("%d\n", *ptr);
}

출력 : 컴파일 에러 error: assignment of read-only location

‘*ptr’ : 6 | *ptr = 6;

 

상수 변수에 대한 포인터는 상수가 아닌 변수를 가리킬 수 있다.
상수 변수에 대한 포인터는 변수가 초기에 const로 정의되었는지에 관계 없이 포인터를 통해 접근할 때 변수를 상수로 취급한다.

 

따라서 포인터가 아니라 변수 그자체에서 접근은 가능하다.

#include <stdio.h>

void main(){
    int value = 5;
    const int* ptr = &value;
    value = 6; // 포인터가 아니라 변수 그자체에서 접근은 가능하다.

    printf("%d\n", *ptr);
}

출력 : 6

 

하지만 포인터를 통한 변수 접근은 안된다는 것이다.

#include <stdio.h>

void main(){
    int value = 5;
    const int* ptr = &value;
    *ptr = 6; // 포인터에서의 변경은 불가능하다.

    printf("%d\n", *ptr);
}

출력 : 컴파일 에러


상수를 가리키는 포인터는 상수를 가리킬 뿐, 상수 자체가 아니므로 다른 값을 가리킬 수 있다.

#include <stdio.h>

void main(){
    int value1 = 5;
    const int* ptr = &value1; // ptr points to a const int

    int value2 = 6;
    ptr = &value2; // okay, ptr now points at some other const int

    printf("%d\n", *ptr);
}

출력 : 6


Const pointer 상수 포인터

int * const ptr 

형식에 관한 설명이다.

 

포인터 자체를 상수로 만들 수 있다. 상수 포인터는 초기화 후에 가리키는 주소를 변경할 수 없는 포인터다.

상수 포인터(Const pointer) int* const (변수명)형태로 작성한다. 즉 (변수명)이 상수라는 의미의 작성방식이다.

#include <stdio.h>

void main(){
    int value = 5;
    int* const ptr = &value;

    printf("%d\n", *ptr);
}

일반 상수 변수와 마찬가지로 상수 포인터는 선언 시 초기화해야 한다.
즉, 상수 포인터는 항상 같은 주소를 가리킨다.
따라서 아래와 같이 코드를 작성하면 컴파일 에러가 뜬다.

#include <stdio.h>

void main(){
    int value1 = 5;
    int value2 = 6;

    int* const ptr = &value1; // 초기화를 선언과 동시에 해야한다.
    ptr = &value2; // int* const로 선언하면 주소를 변경할 수 없다.

    printf("%d\n", *ptr);
}

포인터가 상수일 뿐, 가리키는 변수는 상수가 아니므로 포인터를 역참조하여 값을 변경하는 것은 가능하다.

#include <stdio.h>

void main(){
    int value = 5;
    int* const ptr = &value;
    *ptr = 6; // 가능하다

    printf("%d\n", *ptr);
}

Const pointer to a const value

포인터가 주소도 못 바꾸고 역참조 값도 못 바꾸게 하려면 const를 두번 써주면 된다.

#include <stdio.h>

void main(){
    int value = 5;
    const int *const ptr = &value;

    printf("%d\n", *ptr);
}

상수를 가리키는 상수 포인터는 다른 주소를 가리키도록 수정할 수 없으며, 역참조를 통해 값을 수정할 수도 없다.

반응형