是之前继续还是之后继续?

首先,您可能知道 const可以用来使对象的数据或指针不可修改,或者两者兼而有之。

const Object* obj; // can't change data
Object* const obj; // can't change pointer
const Object* const obj; // can't change data or pointer

不过,你也可以使用这样的语法:

Object const *obj; // same as const Object* obj;

唯一重要的是你把 const关键字放在星号的哪一边。就我个人而言,我更喜欢把 const放在类型的左边,以指定它的数据是不可修改的,因为我发现它在我从左到右的思维模式下读起来更好,但哪种语法是第一个出现的?

更重要的是,为什么有两种指定 const数据的正确方法? 在什么情况下,如果有的话,您更喜欢或需要一种方法?

编辑:

因此,这听起来像是一个武断的决定,而编译器应该如何解释事物的标准早在我出生之前就已经起草了。因为 const应用于关键字左边的内容(默认情况下?)我猜想他们认为添加 “捷径”以其他方式应用关键字和类型限定符没有坏处,至少在声明通过解析 a * 或 & 发生变化之前没有坏处。

我猜 C 区也是这样?

87305 次浏览

规则是:

常量应用于它的左边。如果左边什么都没有,那么它适用于它右边的东西。

我更喜欢在事物的右边使用 const 作为 const,因为它是 const 定义的“原始”方式。

但我认为这是一个非常主观的观点。

为什么有两种指定 const数据的正确方法? 在什么情况下,如果有的话,您更喜欢或需要一种方法?

本质上,const在星号之前的说明符中的位置并不重要的原因是 C 语法是由 Kernighan 和 Ritchie 定义的。

他们以这种方式定义语法的原因可能是他们的 C 编译器从左到右解析输入,并在使用每个标记时完成处理。使用 *令牌将当前声明的状态更改为指针类型。在 *之后遇到 const意味着 const限定符应用于指针声明; 在 *之前遇到它意味着该限定符应用于指向的数据。

因为如果 const限定符出现在类型说明符之前或之后,语义含义不会改变,所以无论哪种方式都可以接受。

在声明函数指针时,也会出现类似的情况,其中:

  • void * function1(void)声明一个返回 void *的函数,

  • void (* function2)(void)向返回 void的函数声明一个 函数指针

同样需要注意的是,语言语法支持从左到右的解析器。

第一条规则是使用任何格式的本地编码标准 之后: 把 const放在前面会导致无穷无尽的 当涉及 typedef 时会产生混淆,例如:

typedef int* IntPtr;
const IntPtr p1;   // same as int* const p1;

如果您的编码标准允许 typedef 的指针,那么它真的 应该坚持把常数放在类型之后。在每种情况下,但 当应用于类型时,const 必须遵循它所应用的内容,因此 连贯性也支持后连续性。但局部编码 指导方针胜过所有这些; 区别通常并不重要 足以返回并更改所有现有代码。

我更喜欢第二种语法。通过从右到左阅读类型声明,它帮助我跟踪“ what”是常量:

Object * const obj;        // read right-to-left:  const pointer to Object
Object const * obj;        // read right-to-left:  pointer to const Object
Object const * const obj;  // read right-to-left:  const pointer to const Object

声明中关键字的顺序并不是完全固定的。除了“唯一真正的秩序”,还有许多其他选择。像这样

int long const long unsigned volatile i = 0;

或者应该是

volatile unsigned long long int const i = 0;

??

有历史原因表明,无论是左派还是右派都是可以接受的。但直到 C89/C90才到达 C 区。

在 C + + 中,有一个很好的理由总是在右边使用 const。在任何地方都是一致的,因为 const 成员函数 必须的是这样声明的:

int getInt() const;

C 语言使用从右到左的语法:

int var = 0;


// one is a pointer to a const int
int const * one = &var;
// two is a pointer to an int const (same as "const int")
const int * two = &var;


// three is a constant pointer to an int
int * const three = &var;

留给“ const”的第一件事就是受到它的影响。

要获得更多乐趣,请阅读以下指南: Http://cseweb.ucsd.edu/~ricko/rt_lt.rule.html

using P_Int = int *;


P_Int const a = nullptr;
int * const b = nullptr;


const P_Int c = nullptr;
const int * d = nullptr;

变量 ab的类型是相同的,但是有点混乱的是,变量 cd的类型并不相同。我倾向于第一种场景,不要混淆: 在类型的右边放置 const。注意,指针 constabc,而 intconstd

当我使用现有的代码时,我会遵循大多数情况下已经使用的方法,例如左边的 const,但是如果我有机会从头开始工作,我会选择“正确的方法”,意思是右边的 const,例如 int const a = 10;,这是一种更通用的方法,也更容易阅读。

如前所述,规则是

常量应用于它的左边。如果左边什么都没有,那么它适用于它右边的东西。

下面是基本用例的示例代码。

int main() {
int const a = 10; // Constant integer
const int b = 20; // Constant integer (same as above)


int c = 30; // Integer (changeable)
int * const d = &c; // Constant pointer to changeable integer


int const * e = &a; // Changeable pointer to constant integer


int const * const f = &a; // Constant pointer to constant integer


return 0;
}

最后,如果没有指导方针可以遵循,那么这是主观的,使用任何一种方法都是无害的。