programing tip

const char * const 대 const char *?

itbloger 2020. 8. 17. 08:15
반응형

const char * const 대 const char *?


C ++에 익숙해지기 위해 몇 가지 예제 프로그램을 실행 중이며 다음 질문에 직면했습니다. 먼저 다음은 예제 코드입니다.

void print_string(const char * the_string)
{
    cout << the_string << endl;
}

int main () {
    print_string("What's up?");
}

위 코드에서 print_string에 대한 매개 변수는 대신 const char * const the_string. 이것에 대해 어느 것이 더 정확할까요?

차이점은 하나는 상수 문자에 대한 포인터이고 다른 하나는 상수 문자에 대한 상수 포인터라는 것입니다. 하지만이 두 가지가 모두 작동하는 이유는 무엇입니까? 언제 관련이 있습니까?


후자는 the_string내부 수정을 방지합니다 print_string. 실제로 여기에서는 적절할 것이지만 아마도 장황함은 개발자를 미루 었습니다.

char* the_string: 포인트 char변경할 수 있고 the_string포인트를 수정할 수 있습니다 char.

const char* the_string: 나는 변경할 수 있습니다 charthe_string포인트를,하지만 난 수정할 수 없습니다 char그것을 지적하는.

char* const the_string: 나는 변경할 수 없습니다 charthe_string포인트를,하지만 난 수정할 수 있습니다 char그것을 지적하는.

const char* const the_string: char어느 the_string지점 가리키는 지 변경할 수 없으며 , 가리키는 지점을 수정할 수도 없습니다 char.


  1. 변경 가능한 문자에 대한 변경 가능한 포인터

    char *p;
    
  2. 상수 문자에 대한 가변 포인터

    const char *p;
    
  3. 가변 문자에 대한 상수 포인터

    char * const p; 
    
  4. 상수 문자에 대한 상수 포인터

    const char * const p;
    

const char * const포인터와 포인터가 가리키는 데이터는 모두 const입니다!

const char *포인터가 가리키는 데이터 const 임을 의미 합니다 . 그러나 포인터 자체는 const가 아닙니다.

예.

const char *p = "Nawaz";
p[2] = 'S'; //error, changing the const data!
p="Sarfaraz"; //okay, changing the non-const pointer. 

const char * const p = "Nawaz";
p[2] = 'S'; //error, changing the const data!
p="Sarfaraz"; //error, changing the const pointer. 

(이것이 오래되었다는 것을 알고 있지만 어쨌든 공유하고 싶었습니다.)

Thomas Matthews의 대답에 대해 자세히 설명하고 싶었습니다. C 타입 선언의 오른쪽-왼쪽 규칙은 거의 말합니다 : C 타입 선언을 읽을 때 식별자에서 시작하고 할 수있을 때 오른쪽으로 가고 할 수 없을 때 왼쪽으로 가십시오.

이것은 몇 가지 예를 통해 가장 잘 설명됩니다.

예 1

  • 식별자에서 시작해 오른쪽으로 갈 수 없어 왼쪽으로

    const char* const foo
                ^^^^^
    

    foo는 상수입니다 ...

  • 계속 왼쪽

    const char* const foo
              ^
    

    foo는 ...에 대한 상수 포인터입니다 .

  • 계속 왼쪽

    const char* const foo
          ^^^^
    

    foo는 char에 대한 상수 포인터입니다 .

  • 계속 왼쪽

    const char* const foo
    ^^^^^
    

    foo는 char 상수에 대한 상수 포인터입니다 (Complete!)

예 2

  • 식별자에서 시작해 오른쪽으로 갈 수 없어 왼쪽으로

    char* const foo
          ^^^^^
    

    foo는 상수입니다 ...

  • 계속 왼쪽

    char* const foo
        ^
    

    foo는 ...에 대한 상수 포인터입니다 .

  • 계속 왼쪽

    char* const foo
    ^^^^
    

    foo는 char에 대한 상수 포인터입니다 (Complete!)

예제 1337

  • 식별자에서 시작하지만 이제 바로 갈 수 있습니다!

    const char* const* (*foo[8])()
                            ^^^
    

    foo는 8 ...

  • Hit parenthesis so can't go right anymore, go left

    const char* const* (*foo[8])()
                        ^
    

    foo is an array of 8 pointer to...

  • Finished inside parenthesis, can now go right

    const char* const* (*foo[8])()
                                ^^
    

    foo is an array of 8 pointer to function that returns...

  • Nothing more to the right, go left

    const char* const* (*foo[8])()
                     ^
    

    foo is an array of 8 pointer to function that returns a pointer to a...

  • Continue left

    const char* const* (*foo[8])()
                ^^^^^
    

    foo is an array of 8 pointer to functions that returns a pointer to a constant...

  • Continue left

    const char* const* (*foo[8])()
              ^
    

    foo is an array of 8 pointer to functions that returns a pointer to a constant pointer to a...

  • Continue left

    const char* const* (*foo[8])()
          ^^^^
    

    foo is an array of 8 pointer to functions that returns a pointer to a constant pointer to a char...

  • Continue left

    const char* const* (*foo[8])()
    ^^^^^
    

    foo is an array of 8 pointer to functions that returns a pointer to a constant pointer to a char constant (Complete!)

Further explanation: http://www.unixwiz.net/techtips/reading-cdecl.html


Many people suggest reading the type specifier from right to left.

const char * // Pointer to a `char` that is constant, it can't be changed.
const char * const // A const pointer to const data.

In both forms, the pointer is pointing to constant or read-only data.

In the second form, the pointer cannot be changed; the pointer will always point to the same place.


The difference is that without the extra const the programmer could change, inside the method, where the pointer points to; for example:

 void print_string(const char * the_string)
 {
    cout << the_string << endl;
    //....
    the_string = another_string();
    //....

 }

That would be instead illegal if the signature were void print_string(const char * const the_string)

Many programmers feel too verbose (in most scenarios) the extra const keyword and omit it, even though it would be semantically correct.


In the latter you are guaranteeing not to modify both pointer and character in the first you only guarantee that the contents will not change but you may move the pointer around


There's no reason why either one wouldn't work. All print_string() does is print the value. It doesn't try to modify it.

It's a good idea to make function that don't modify mark arguments as const. The advantage is that variables that can't change (or you don't want to change) can be passed to these functions without error.

As far as the exact syntax, you want to indicate which type of arguments are "safe" to be passed to the function.


I think it's vary rarely relevant, because your function isn't getting called with arguments like &*the_string or **the_string. The pointer itself is a value-type argument, so even if you modify it you're not going to change the copy that was used to call your function. The version you're showing ensures that the string will not change, and I think that's sufficient in this case.


const char * means that you can't use the pointer to change what is pointed to. You can change the pointer to point to something else, though.

Consider:

const char * promptTextWithDefault(const char * text)
{
    if ((text == NULL) || (*text == '\0'))
        text = "C>";
    return text;
}

The parameter is a non-const pointer to const char, so it can be change to another const char * value (like a constant string). If, however, we mistakenly wrote *text = '\0' then we'd get a compilation error.

Arguably, if you don't intend to change what the parameter is pointing to, you could make the parameter const char * const text, but it's not common to do so. We usually allow functions to change the values passed to parameters (because we pass parameters by value, any change does not affect the caller).

BTW: it is good practice to avoid char const * because it's often misread - it means the same as const char *, but too many people read it as meaning char * const.


Nearly all of the other answers are correct, but they miss one aspect of this: When you use the extra const on a parameter in a function declaration, the compiler will essentially ignore it. For a moment, let's ignore the complexity of your example being a pointer and just use an int.

void foo(const int x);

declares the same function as

void foo(int x);

Only in the definition of the function is the extra const meaningful:

void foo(const int x) {
    // do something with x here, but you cannot change it
}

This definition is compatible with either of the declarations above. The caller doesn't care that x is const--that's an implementation detail that's not relevant at the call site.

If you have a const pointer to const data, the same rules apply:

// these declarations are equivalent
void print_string(const char * const the_string);
void print_string(const char * the_string);

// In this definition, you cannot change the value of the pointer within the
// body of the function.  It's essentially a const local variable.
void print_string(const char * const the_string) {
    cout << the_string << endl;
    the_string = nullptr;  // COMPILER ERROR HERE
}

// In this definition, you can change the value of the pointer (but you 
// still can't change the data it's pointed to).  And even if you change
// the_string, that has no effect outside this function.
void print_string(const char * the_string) {
    cout << the_string << endl;
    the_string = nullptr;  // OK, but not observable outside this func
}

Few C++ programmers bother to make parameters const, even when they could be, regardless of whether those parameters are pointers.


The difference between the two is that char* can point to any arbitrary pointer. Const char* by contrast, points to constants defined in the DATA section of the executable. And, as such, you cannot modify the character values of a const char* string.

참고URL : https://stackoverflow.com/questions/4949254/const-char-const-versus-const-char

반응형