Bjarne gave a mnemonic method in his The C++ Programming Language:Read a declaration from right to left.。

char * const cp; ( * 读成 pointer to ) 
cp is a const pointer to char 

const char * p; 
p is a pointer to const char; 

char const * p; 

Same as above. Because there is no const* operator in C++, const can only belong to the preceding type.

The C++ standard stipulates that placing the const keyword before the type or before the variable name is equivalent.

const int n=5;    //same as below
int const m=10;

const int *p;    //same as below  const (int) * p
int const *q;    // (int) const *p


char ** p1; 
//    pointer to    pointer to    char 
const char **p2;
//    pointer to    pointer to const char 
char * const * p3;
//    pointer to const pointer to    char 
const char * const * p4;
//    pointer to const pointer to const char 
char ** const p5;
// const pointer to    pointer to    char 
const char ** const p6;
// const pointer to    pointer to const char 
char * const * const p7;
// const pointer to const pointer to    char 
const char * const * const p8;
// const pointer to const pointer to const char

Speaking of which, we can look at a previous Google written test question:

const char *p="hello";       
foo(&p);  // 函数foo(const char **pp)下面说法正确的是[]
  • A. The function foo() cannot change the content of the string pointed to by p.
  • B. The function foo() cannot make the pointer p point to the address generated by malloc.
  • C. The function foo() can make p point to a new string constant.
  • D. The function foo() can assign NULL to p.

As for the answer to this question, opinions vary. Regarding the above question, we can use the following program to test:

#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
void foo(const char **pp)
{
//    *pp=NULL;
//    *pp="Hello world!";
        *pp = (char *) malloc(10);
        snprintf(*pp, 10, "hi google!");
//       (*pp)[1] = 'x';
}
int
main()
{
    const char *p="hello";
    printf("before foo %s/n",p);
    foo(&p);
    printf("after foo %s/n",p);
    p[1] = 'x';
    return;
}

The conclusions are as follows:

 
  1. In the foo function, p in the main function can be made to point to a new string constant.
  2. In the foo function, p in the main function can be made to point to NULL.
  3. In the foo function, p in the main function can be made to point to a memory block generated by malloc, and it can be freed with free in main, but there will be a warning. However, note that even if p is made to point to a memory block generated by malloc in foo, you still cannot use a statement like p
  4. In foo, you cannot use a statement like (*pp)

Therefore, it seems that gcc only restricts it based on the literal meaning of const. That is, for a pointer like const char*p, no matter whether p later actually points to memory from malloc or constant memory, you cannot use a statement like p