如果有帮助的话(可能并没有),以下是同义的,利用了语言的一个小技巧,允许开放类型在类型的立即左侧或右侧出现
const
,但在任何其他限定符之前(如指针或引用)。
const int * p; // does NOT require initialization
int const * q; // same as above
两者都声明指向常量int
数据的指针,并且在语法上可以互换。
然而这段代码:
int * const p = &a; // requires initialization.
声明一个指向
int
数据的常量指针;
不是 指向常量
int
数据的指针。
进一步扩展(实际上是将它们合并),我们得到:
const int * const p = &a;
int const * const p = &a;
这两个词是同义词。它们都声明了一个指向常量整数数据的常量指针。指针和指向的内容都不可修改,并且都需要初始化。
无耻地复制的图表
以下内容是从我自己(好吧,并不那么丢脸)和一个稍微相关的问题中无耻地复制而来。我希望它能更好地解释当您在声明中放置const
和*
时会发生什么不同:
单重间接寻址:
char *p;
const char *p;
char const *p;
char *const p;
char const *const p;
双重间接引用:
char **p; // ptr-to-ptr-to-char
// p, *p, and **p are ALL mutable
const char **p; // ptr-to-ptr-to-const-char
// p and *p are mutable, **p is const
char const **p; // same as above
char *const *p; // ptr-to-const-ptr-to-char
// p is mutable, *p is const, **p is mutable.
char **const p; // const-ptr-to-ptr-to-char
// p is const, *p is mutable, **p is mutable.
// must be initialized.
const char **const p; // const-ptr-to-ptr-to-const-char
// p is const, *p is mutable, **p is const.
// must be initialized.
char const **const p; // same as above
char const *const *p; // ptr-to-const-ptr-to-const-char
// p is mutable, *p is const, **p is const.
const char *const *p; // same as above.
char *const *const p; // const-ptr-to-const-ptr-to-char
// p is const, *p is const, **p is mutable.
// must be initialized.
"而我个人最喜欢的是:"
char const *const *const p; // const-ptr-to-const-ptr-to-const-char
// everything is const.
// must be initialized.
const char *const *const p; // same as above
const
放在正确的位置,即在类型被声明为const
时,将其放在类型的右侧而非左侧,如上述代码中的int const *
和int * const
。然后从右向左阅读。 - David Rodríguez - dribeasint a [2] [3]
。附注:我根本没有受到压力。 - kotlomoy