char * const와 const char *의 차이점은 무엇입니까?


279

차이점은 무엇입니까?

char * const 

const char *


8
"const"의 왼쪽에있는 첫 번째 것은 상수입니다. "const"가 왼쪽에서 가장 먼 것이라면, 그것의 오른쪽에있는 첫 번째 것은 상수입니다.
컵케익

4
친근한 팁으로 cdecl중요한 것임을 잊지 마십시오 .
Braden Best

예외의 반환 유형 인 또 다른 char const *가 있습니다 :: what ()
Zhang

답변:


363

차이점은에 const char *대한 포인터 const char이고, char * const에 대한 상수 포인터 char입니다.

첫 번째로 가리키는 값은 변경할 수 없지만 포인터는 변경할 수 있습니다. 두 번째, 가리키는 값은 변경 될 수 있지만 포인터는 참조와 유사하지 않습니다.

또 한있다

const char * const

상수 char에 대한 상수 포인터입니다 (따라서 변경할 수는 없습니다).

노트 :

다음 두 가지 형태가 동일합니다.

const char *

char const *

정확한 이유는 C ++ 표준에 설명되어 있지만 혼동을 피하고 피하는 것이 중요합니다. 선호하는 몇 가지 코딩 표준을 알고 있습니다.

char const

위에

const char

(포인터가 있거나없는) const요소 의 배치 는 pointer와 동일 const합니다.


6
동일한 선언에 여러 변수가 지정되면 어떻게되는지 알아볼 가치가 있습니까? 저는 믿습니다 const int *foo,*bar;모두를 선언 할 foobarint const *있지만 int const *foo, *bar선언 할 foo가 될 int const *barint *. typedef int * intptr; const intptr foo,bar;두 변수를 모두 선언 한다고 생각 합니다 int * const. typedef없이 결합 된 선언을 사용하여 해당 유형의 두 변수를 만드는 방법을 모르겠습니다.
supercat

1
@supercat I believe const int *foo,*bar; would declare both foo and bar to be int const *: 예. but int const *foo, *bar would declare foo to be a int const * and bar to be int *: 안돼! 이전 사례와 정확히 동일합니다. ( foo와 bar에서 동일한 오류가 발생하는 ideone.com/RsaB7n을 참조하십시오 ). I think typedef int * intptr; const intptr foo,bar; would declare both variables to be int * const: 예. I don't know any way to use a combined declaration to create two variables of that type without a typedef: 글쎄 int *const foo, *const bar;. C 선언자 구문 ...
gx_

@gx_ : 틀렸어요. 불확실성 때문에 규칙이 무엇인지 말하는 것이 도움이 될 것입니다. 어떻게 int const *foo, *volatile bar해야 bar합니까? 둘 다 const만들고 volatile? 나는 선언 된 변수 이름과 그 유형의 Pascal의 깔끔한 분리를 그리워합니다 (정수에 대한 포인터 배열에 대한 포인터는 var foo: ^Array[3..4] of ^Integer;`일 것입니다.). C에서 중첩 된 괄호로 묶인 것입니다.
supercat

3
@supercat (오, C 전용, C ++ 코드 링크는 죄송합니다. C ++ 질문에서 왔어요) C 선언 구문 은 ( "순수한") 형식 부분과 선언자가 있습니다. " int const *foo, *volatile bar"에서 형식 부분은 int const(앞에 멈춤 *)이고 선언자는 *foo(표현식 *foo은을 나타냄 int const) 및 *volatile bar; 읽기 오른쪽에서 왼쪽으로 (좋은 규칙 CV-한정자 ), fooA와 포인터입니다 CONST의 INT, 그리고 barA는 휘발성 A와 포인터 CONST의 INT (그 자체가 휘발성 포인터, 뾰족한 INT는 const를 [로 액세스]입니다).
gx_

@supercat 그리고 "정수에 대한 포인터 배열에 대한 포인터"에 관해서는 (파스칼을 모른다. [3..4]구문 에 대해 확실하지 않으므로 10 요소의 배열을 보자) : int *(*foo)[10];. 그것은 (미래의) 사용을 표현으로 반영합니다 : *(*foo)[i]( 즉 i, 범위의 정수로 )는 먼저 배열을 가져 오기 위해 역 참조 한 다음 색인에서 요소에 액세스합니다 (postfix 가 prefix보다 꽉 묶기 때문에 ). 수율 ( ideone.com/jgjIjR 참조 ). 그러나 더 쉽게 만듭니다 ( ideone.com/O3wb7d 참조 ). [0, 10)[0, 9]fooi[]*inttypedef
gx_

102

혼동을 피하려면 항상 const 한정자를 추가 하십시오.

int       *      mutable_pointer_to_mutable_int;
int const *      mutable_pointer_to_constant_int;
int       *const constant_pointer_to_mutable_int;
int const *const constant_pointer_to_constant_int;

10
왜? "혼란을 피하기 위해"혼란이 무엇인지 설명하지 않습니다.
앤드류 위어

14
@Andrew : 일관성과 가독성을 암시하고있었습니다. 모든 유형 한정자를 작성하여 항상 왼쪽에있는 내용을 수정하는 것이 내가 사용하는 것입니다.
diapir

1
실제로 그것은 내가 찾은 주제에 대한 최상의 답변입니다
Trap

8
코드 표준 으로이 스타일은 거의 발생하지 않았으므로 채택하지 않을 것입니다. 그러나 학습 도구로서이 답변은 매우 도움이되었습니다! (그래서 나쁘게 생각하는 것이 더 일반적인 스타일은 아닙니다.)
natevw

8
@Alla : p유형과 관련이 없습니다 (const int *const). C와 C ++에서 const 한정자는 더 나은지 나쁜지 (나에게 물어 보면 더 나쁘다) postfix : cf const member function void foo(int a) const;입니다. 선언 가능성 const int은 규칙이 아닌 예외입니다.
diapir

44

const 형식 선언에서 첫 번째 일 때를 제외하고 그 앞 (왼쪽)에 오는 것을 항상 수정하고, 그 뒤에 오는 것을 수정합니다 (오른쪽에).

따라서이 두 가지는 동일합니다.

int const *i1;
const int *i2;

그들은에 대한 포인터를 정의합니다 const int. 위치 i1i2지점을 변경할 수 있지만 해당 지점의 값을 변경할 수는 없습니다.

이:

int *const i3 = (int*) 0x12345678;

const정수에 대한 포인터를 정의하고 메모리 위치 12345678을 가리 키도록 초기화합니다 int. 주소 12345678 의 값을 변경할 수 있지만 i3가리키는 주소는 변경할 수 없습니다 .



18

const char*상수 문자
char* const에 대한 포인터입니다. 문자
const char* const에 대한 상수 포인터입니다. 상수 문자 에 대한 상수 포인터입니다.


9

경험 법칙 : 정의를 오른쪽에서 왼쪽으로 읽으십시오!


const int *foo;

" foo포인트 ( *)는 int변경할 수없는 ( const)"을 의미합니다.
프로그래머에게 이것은 " 이것이 가리키는 것의 가치 를 바꾸지 않을 것"을 의미 foo합니다.

  • *foo = 123;또는 foo[0] = 123;유효하지 않습니다.
  • foo = &bar; 허용됩니다.

int *const foo;

" foo는 ( const) 및 ( *)를 int"로 변경할 수 없음을 의미 합니다.
프로그래머에게 이것은 " 참조 하는 메모리 주소 를 변경하지 않겠다 foo"는 의미입니다.

  • *foo = 123;또는 foo[0] = 123;허용됩니다.
  • foo = &bar; 유효하지 않습니다.

const int *const foo;

수단 "은 foo변경할 수 없습니다 ( const)과 점 ( *)는에 int그 수없는 변화 ( const)".
프로그래머에게 이것은 " 포인팅 한 foo변경하지 않으며 참조 하는 주소 를 변경하지 않을 것 foo" 을 의미합니다.

  • *foo = 123;또는 foo[0] = 123;유효하지 않습니다.
  • foo = &bar; 유효하지 않습니다.

8
  1. const char * x 여기서 X는 기본적으로 상수 값을 가리키는 문자 포인터입니다.

  2. char * const x 는 상수 인 문자 포인터를 나타내지 만, 가리키는 위치는 변경 될 수 있습니다.

  3. const char * const x 는 1과 2의 조합으로 상수 값을 가리키는 상수 문자 포인터임을 의미합니다.

  4. const * char x 는 컴파일러 오류를 일으 킵니다. 선언 할 수 없습니다.

  5. char const * x 는 포인트 1과 같습니다.

일반적으로 const 가 var name 인 경우 포인터는 일정하지만 포인팅 위치는 변경할 수 있습니다 . 그렇지 않으면 포인터는 일정한 위치를 가리키고 포인터는 다른 위치를 가리킬 수 있지만 포인팅 위치 내용은 변경할 수 없습니다 .


1
"char * const x는 상수 인 문자 포인터를 가리 키지 만 가리키는 위치는 변경 될 수 있습니다." 잘못된. 위치 자체의 값이 아닌 위치의 값을 변경할 수 있습니다.
PleaseHelp

3

첫 번째는 구문 오류입니다. 아마 당신은 차이를 의미

const char * mychar

char * const mychar

이 경우 첫 번째는 변경할 수없는 데이터에 대한 포인터이고 두 번째는 항상 동일한 주소를 가리키는 포인터입니다.


3

또 다른 규칙은 const가 어디에 있는지 확인하는 것 입니다 .

  1. * => 저장된 일정 하기 전에
  2. * => 포인터 자체가 일정 한 후

3

많은 답변은 특정 변수 선언의 특정 인스턴스를 이해하기 위해 특정 기술, 경험 규칙 등을 제공합니다. 그러나 선언을 이해하는 일반적인 기술이 있습니다.

시계 방향 / 나선 규칙

ㅏ)

const char *a;

시계 방향 / 나선형 규칙에 따라 a일정한 문자를 가리키는 포인터입니다. 이것은 문자가 일정하지만 포인터가 변경 될 수 있음을 의미합니다. 즉 a = "other string";괜찮지 만a[2] = 'c'; 컴파일에 실패합니다

비)

char * const a;

규칙 a에 따라 문자에 대한 const 포인터입니다. 즉 할 수는 a[2] = 'c';있지만 할 수는 없습니다a = "other string";


1
오른쪽-왼쪽 규칙이라고도합니다 (적어도 내가 배운 방법입니다) : jdurrett.ba.ttu.edu/3345/handouts/RL-rule.html
Tomas Pruzina

(해답의 본질이 링크 뒤에 숨겨지지 않으면, 여기의 텍스트가 일반적인 "규칙에 따라"일반적인 내용을 넘어서서 그 내용을 인용하거나 적어도 언급하지 않는 경우 훨씬 더 나을 것입니다.
Sz.

@Sz. 내가 분명히 할 수있는 구체적인 혼란이 있습니까? 규칙을 알고 나면 그다지 많지 않습니다.
PnotNP

1

나는 당신이 const char * 및 char * const을 의미한다고 가정합니다.

첫 번째 인 const char *는 상수 문자에 대한 포인터입니다. 포인터 자체는 변경 가능합니다.

두 번째 char * const는 문자에 대한 상수 포인터입니다. 포인터는 변경할 수없는 문자를 변경할 수 없습니다.

그리고 포인터와 문자를 변경할 수없는 const char * const가 있습니다.


처음 두 개는 실제로 동일하며 세 번째는 컴파일러 오류입니다. :)
workmad3

1

다음은 코드에 대한 자세한 설명입니다

/*const char * p;
char * const p; 
const char * const p;*/ // these are the three conditions,

// const char *p;const char * const p; pointer value cannot be changed

// char * const p; pointer address cannot be changed

// const char * const p; both cannot be changed.

#include<stdio.h>

/*int main()
{
    const char * p; // value cannot be changed
    char z;
    //*p = 'c'; // this will not work
    p = &z;
    printf(" %c\n",*p);
    return 0;
}*/

/*int main()
{
    char * const p; // address cannot be changed
    char z;
    *p = 'c'; 
    //p = &z;   // this will not work
    printf(" %c\n",*p);
    return 0;
}*/



/*int main()
{
    const char * const p; // both address and value cannot be changed
    char z;
    *p = 'c'; // this will not work
    p = &z; // this will not work
    printf(" %c\n",*p);
    return 0;
}*/

@reese moore 감사합니다.
Megharaj

1
// Some more complex constant variable/pointer declaration.
// Observing cases when we get error and warning would help
// understanding it better.

int main(void)
{
  char ca1[10]= "aaaa"; // char array 1
  char ca2[10]= "bbbb"; // char array 2

  char *pca1= ca1;
  char *pca2= ca2;

  char const *ccs= pca1;
  char * const csc= pca2;
  ccs[1]='m';  // Bad - error: assignment of read-only location ‘*(ccs + 1u)’
  ccs= csc;    // Good

  csc[1]='n';  // Good
  csc= ccs;    // Bad - error: assignment of read-only variable ‘csc’

  char const **ccss= &ccs;     // Good
  char const **ccss1= &csc;    // Bad - warning: initialization from incompatible pointer type

  char * const *cscs= &csc;    // Good
  char * const *cscs1= &ccs;   // Bad - warning: initialization from incompatible pointer type

  char ** const cssc=   &pca1; // Good
  char ** const cssc1=  &ccs;  // Bad - warning: initialization from incompatible pointer type
  char ** const cssc2=  &csc;  // Bad - warning: initialization discards ‘const’
                               //                qualifier from pointer target type

  *ccss[1]= 'x'; // Bad - error: assignment of read-only location ‘**(ccss + 8u)’
  *ccss= ccs;    // Good
  *ccss= csc;    // Good
  ccss= ccss1;   // Good
  ccss= cscs;    // Bad - warning: assignment from incompatible pointer type

  *cscs[1]= 'y'; // Good
  *cscs= ccs;    // Bad - error: assignment of read-only location ‘*cscs’
  *cscs= csc;    // Bad - error: assignment of read-only location ‘*cscs’
  cscs= cscs1;   // Good
  cscs= cssc;    // Good

  *cssc[1]= 'z'; // Good
  *cssc= ccs;    // Bad - warning: assignment discards ‘const’
                 //                qualifier from pointer target type
  *cssc= csc;    // Good
  *cssc= pca2;   // Good
  cssc= ccss;    // Bad - error: assignment of read-only variable ‘cssc’
  cssc= cscs;    // Bad - error: assignment of read-only variable ‘cssc’
  cssc= cssc1;   // Bad - error: assignment of read-only variable ‘cssc’
}

1
  1. 상수 포인터 : 상수 포인터는 전체 프로그램 동안 각 데이터 유형의 단일 변수만을 가리킬 수 있으며 포인터가 가리키는 변수의 값을 변경할 수 있습니다. 선언 자체는 선언하는 동안 초기화해야합니다.

통사론:

datatype *const var;

char *const 이 경우에 온다.

/*program to illustrate the behaviour of constant pointer */

#include<stdio.h>
int main(){
  int a=10;
  int *const ptr=&a;
  *ptr=100;/* we can change the value of object but we cannot point it to another variable.suppose another variable int b=20; and ptr=&b; gives you error*/
  printf("%d",*ptr);
  return 0;
}
  1. const 값에 대한 포인터 : 여기서 포인터는 각 유형의 여러 변수를 가리킬 수 있지만 특정 시간에 포인터가 가리키는 객체의 값을 변경할 수 없습니다.

통사론:

const datatype *var또는 datatype const *var

const char* 이 경우에 온다.

/* program to illustrate the behavior of pointer to a constant*/

   #include<stdio.h>
   int main(){
       int a=10,b=20;
       int const *ptr=&a;
       printf("%d\n",*ptr);
       /*  *ptr=100 is not possible i.e we cannot change the value of the object pointed by the pointer*/
       ptr=&b;
       printf("%d",*ptr);
       /*we can point it to another object*/
       return 0;
    }

1

char * const와 const char *?

  1. 상수 값을 가리키는

const char * p; // 값을 변경할 수 없습니다

  1. 값에 대한 상수 포인터

char * const p; // 주소를 변경할 수 없습니다

  1. 상수 값에 대한 상수 포인터

const char * const p; // 둘 다 변경할 수 없습니다.


1

그만큼 const개질제는 바로 왼쪽 용어에 적용된다. 이것에 대한 유일한 예외는 왼쪽에 아무것도 없을 때 오른쪽에있는 것에 적용됩니다.

다음은 "상수에 대한 상수 포인터"라고 말하는 것과 동등한 방법입니다 char.

  • const char * const
  • const char const *
  • char const * const
  • char const const *

컴파일러에 의존합니까? "const char const *"및 "const const char *"및 "char const const *"에 대해 gcc는 동일한 결과-> 포인터가 다른 위치를 가리킬 수 있습니다.
cosinus0

1

두 가지 규칙

  1. If const is between char and *, it will affect the left one.
  2. If const is not between char and *, it will affect the nearest one.

예 :

  1. char const *. This is a pointer points to a constant char.
  2. char * const. This is a constant pointer points to a char.

1

int const *(또는 const int *) 사용은 const int변수를 가리키는 포인터에 관한 것이 아니라이 변수 라는 것을 지적하고 싶습니다.const 가이 특정 포인터를위한 .

예를 들면 다음과 같습니다.

int var = 10;
int const * _p = &var;

위의 코드는 완벽하게 컴파일됩니다. 상수는 아니지만 변수를 _p가리 킵니다 .constvar


1

나는 체코 책에서 C에 대해 기억합니다. 변수로 시작하고 왼쪽으로 가라는 선언을 읽으십시오. 그래서

char * const a;

다음과 같이 읽을 수 있습니다 : " a는 " 에 대한 상수 포인터 유형의 변수입니다 char.

char const * a;

" a는 char 유형의 상수 변수에 대한 포인터입니다. 이것이 도움이되기를 바랍니다.

보너스:

const char * const a;

achar 유형의 상수 변수에 대한 상수 포인터를 읽습니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.