const char * 및 char const *-동일합니까?


81

내 이해에서 const수식어는 오른쪽에서 왼쪽으로 읽어야합니다. 그것으로부터 나는 그것을 얻습니다.

const char*

char 요소는 수정할 수 없지만 포인터 자체는 수정할 수있는 포인터입니다.

char const*

mutable문자에 대한 상수 포인터 입니다.

하지만 다음 코드에 대해 다음과 같은 오류가 발생합니다.

const char* x = new char[20];
x = new char[30];   //this works, as expected
x[0] = 'a';         //gives an error as expected

char const* y = new char[20];
y = new char[20];   //this works, although the pointer should be const (right?)
y[0] = 'a';         //this doesn't although I expect it to work

그래서 .. 어느 거지? 내 이해 또는 내 컴파일러 (VS 2005)가 잘못 되었습니까?


35
의심스러운 경우 항상 나선형 규칙을 사용하십시오 .
Alok Save

"... 문자 요소는 수정할 수 있지만 포인터 자체는 수정할 수 있습니다. 그리고 ..." — 이러한 "can"중 하나에 대해 "ca n't"라고 말하려했지만 어떻게해야할지 모르겠습니다. 혼란스러워서 수정해야 할 부분을 모르겠습니다 : P
detly

1
이 웹 사이트를보십시오 : www.cdecl.org
yasouser 2011

컴파일러는 결코 잘못되지 않았습니다;)
monolith

답변:


129

실제로 표준에 따라 왼쪽에const 있는 요소를 직접 수정합니다 . 의 사용 선언의 시작 부분에 그냥 편리 정신 바로 가기입니다. 따라서 다음 두 문은 동일합니다.const

char const * pointerToConstantContent1;
const char * pointerToConstantContent2;

포인터 자체가 수정되지 않도록 const하려면 별표 뒤에 와야합니다.

char * const constantPointerToMutableContent;

포인터와 포인터가 가리키는 내용을 모두 보호하려면 두 개의 const를 사용하십시오.

char const * const constantPointerToConstantContent;

포인터가 일정하게 유지하고 싶은 부분이더라도 일관성을 유지하도록 수정하지 않으려는 부분 뒤에 항상 const를 넣는 것을 개인적으로 채택했습니다 .


23
'편리한 속기'는 더 짧지 않고 정상적인 규칙을 따르지 않는 것에 대한 흥미로운 설명입니다.
beetstra 2011

표준은 어떤 순서를 사용하든 상관하지 않습니다. 섹션 7.1.6은 두 장소를 모두 보여주고 한 곳에서만 사용한다고 말합니다.
edA-qa mort-ora-y 2011

1
@beetstra 동의합니다. 좀 더 명확하게하기 위해 "편리한 정신적 지름길"로 변경했습니다.
Greyson

31

둘 다 동일하기 때문에 작동합니다. 이것에 혼란 스러울 수 있습니다.

const char*  // both are same
char const*

char* const  // unmutable pointer to "char"

const char* const  // unmutable pointer to "const char"

[이것을 기억하기 위해 여기 간단한 규칙이 있습니다. '*'는 전체 LHS에 먼저 영향을 미칩니다. ]


알겠습니다. 지금 확인했습니다. 감사합니다.
Luchian Grigore 2011

1
unmutable pointer to char*charnot을 가리키는 변경 불가능한 포인터 char *입니다.
Alok Save

25

규칙이 다음과 같기 때문입니다.

규칙 : const왼쪽에 아무것도 없으면 왼쪽으로 묶고 오른쪽으로 묶습니다. :)

따라서 다음과 같이보십시오.

(const --->> char)*
(char <<--- const)*

둘 다 동일합니다! 아, 그리고 --->><<---운영하지, 그들은 단지 무엇을 보여 const결합합니다.


2
예, 올바른 연산자는 -->>값에 대해서만 작동합니다. 시도 int i = 8; std::cout << (i -->> 1) << std::endl;:
알렉산더 Malakhov에게

11

( 2 간단한 변수 초기화 질문에서 )

다음에 관한 정말 좋은 경험 법칙 const:

오른쪽에서 왼쪽으로 선언문을 읽으십시오.

(Vandevoorde / Josutiss "C ++ Templates : The Complete Guide"참조)

예 :

int const x; // x is a constant int
const int x; // x is an int which is const

// easy. the rule becomes really useful in the following:
int const * const p; // p is const-pointer to const-int
int const &p;        // p is a reference to const-int
int * const * p;     // p is a pointer to const-pointer to int.

이 규칙을 따랐기 때문에 그런 선언을 다시는 잘못 해석하지 않았습니다.

(: sisab retcarahc-rep a no ton, sisab nekot-rep a no tfel-ot-thgir naem I hguohT : tidE


+1 환상적입니다, 감사합니다! 나는 const char* const오랜 세월과 같은 것들에 내 머리를 돌리려고 노력해 왔고 당신 덕분에 이제 그것을 얻습니다.
OMGtechy

5

내가 항상 해석하려고하는 방법은 다음과 같습니다.

char *p

     |_____ start from the asterisk. The above declaration is read as: "content of `p` is a `char`".

char * const p

     |_____ again start from the asterisk. "content of constant (since we have the `const` 
            modifier in the front) `p` is a `char`".

char const *p

           |_____ again start from the asterisk. "content of `p` is a constant `char`".

도움이 되었기를 바랍니다.


0

두 경우 모두 상수 문자를 가리키고 있습니다.

const char * x  //(1) a variable pointer to a constant char
char const * x  //(2) a variable pointer to a constant char
char * const x  //(3) a constant pointer to a variable char
char const * const x //(4) a constant pointer to a constant char
char const * const * x //(5) a variable pointer to a constant pointer to a constant char
char const * const * const x //(6) can you guess this one?

기본적으로 const왼쪽에있는 중간에 적용되지만 (1)에서와 같이 앞에 아무것도 없으면 오른쪽에 즉시 적용 할 수 있습니다.


마지막 하나 : 상수 포인터, 상수 문자에 대한 상수 변수 포인터.
Secko

만약 "constant variable pointer"가 "constant pointer"를 의미한다면, 당신은 그것을 못 박았습니다!
Lino Mediavilla 19.02.03

(5)에서는 식별자 "x"앞의 마지막 별표 오른쪽에 "const"가 없기 때문에 상수 char에 대한 상수 포인터에 대한 변수 포인터입니다. 그러나 상수 포인터가되는 (6)에서 나머지는 동일하게 유지됩니다.
Lino Mediavilla 19.02.05
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.