为什么写常量指针有两种方式,而写常量指针只有一种方式?

Why is there 2 ways to write a Pointer to Constant, but only one way to write Constant Pointers?

指向常量的指针可以用以下两种方式编写:

int a = 5;

const int* b = &a;
/* or */
int const* c = &a;

但是一个常量指针只能这样写:

int a = 5;

int* const b = &a;

// const* int c = &a; This will not compile.

第二行会产生这个错误:

expected identifier or '(' before 'int'

为什么不允许这样做?

在C声明中定义如下

declaration:
    declaration-specifiers init-declarator-list

例如在这个声明中

const int* b = &a;

const int 是类型说明符,( *b ) = &a 是初始化声明符列表。

你可以像这样重写上面的声明

const int ( *b ) = &a;

如果你想让声明符成为常量对象,你应该这样写

const int ( * const b ) = &a;

您不能使用类型说明符分隔声明符(使用限定符除外),例如

const* int c = &a;

即在此记录中,类型说明符 int 拆分声明符 *c

另一方面,您可以通过以下方式引入类型说明符

typedef const int *Ptr;

在这种情况下,您可以使声明符常量写作

const Ptr b = &a;

在这种情况下,您将获得与

相同的声明
const int * const b = &a;

声明说明符可以以任何顺序出现。作为风格问题,我们倾向于将存储 class 说明符放在第一位,然后是类型限定符,然后是类型说明符,如

static const volatile unsigned long int *p;

但编译器不关心 - 我们可以将其写为

unsigned long int volatile static const *p;

编译器会对此感到满意(任何阅读和维护您的代码的人可能不会)。

* 声明符 的一部分,而不是声明说明符 - 无论声明说明符如何排序,它都绑定到 p。如果我们想将 p 声明为 const 指针,那么我们必须将 const 关键字用作声明符的一部分。为了防止与声明指向 const 的指针混淆,规则是如果我们正在制作 指针 const,那么 const 关键字将在 * 运算符的 右边

const T *p;  // p is a pointer to const T
T const *p;  // same as above

T * const p; // p is a const pointer to T.