首先,你可能知道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
应用于关键字左侧的内容(默认情况下?),我猜他们认为添加“快捷方式”来应用关键字并在其他方面输入限定符没有任何害处通过解析*或&至少等到声明改变的时间。 ...
这就是C中的情况,然后我假设?
答案 0 :(得分:73)
为什么有两种正确的方法来指定
const
数据?如果有的话,您希望在哪种情况下或者需要哪种数据?
基本上,const
在星号之前的说明符中的位置无关紧要的原因是C语法是由Kernighan和Ritchie定义的。
他们以这种方式定义语法的原因很可能是他们的C编译器从左到右解析输入并在消耗它时完成处理每个令牌。使用*
标记会将当前声明的状态更改为指针类型。在const
之后遇到*
意味着const
限定符应用于指针声明;在*
之前遇到它意味着限定符应用于指向的数据。
因为如果const
限定符出现在类型说明符之前或之后,语义意义不会改变,那么它就会被接受。
在声明函数指针时会出现类似的情况,其中:
void * function1(void)
声明一个返回void *
的函数,
void (* function2)(void)
向返回void
的函数声明一个函数指针。
需要注意的是语言语法支持从左到右的解析器。
答案 1 :(得分:57)
规则是:
const适用于它剩下的东西。如果左边没有任何内容,那么它适用于它的权利。
我更喜欢在const的右边使用const只是因为它是定义const的“原始”方式。
但我认为这是一个非常主观的观点。
答案 2 :(得分:41)
我更喜欢第二种语法。它通过从右到左阅读类型声明来帮助我跟踪'什么'是不变的:
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
答案 3 :(得分:31)
声明中关键字的顺序并非全部修复。 “一个真正的秩序”有很多替代品。喜欢这个
int long const long unsigned volatile i = 0;
或应该是
volatile unsigned long long int const i = 0;
...
答案 4 :(得分:6)
第一条规则是使用您当地编码标准的格式
需要。在那之后:将const
放在前面导致无穷尽
涉及typedef时的混淆,例如:
typedef int* IntPtr;
const IntPtr p1; // same as int* const p1;
如果您的编码标准允许使用typedef指针,那么它确实如此 应该坚持把const放在类型之后。在每种情况下,但 当应用于类型时,const必须遵循它适用的内容,所以 一致性也支持const之后。但是本地编码 准则胜过所有这些;差异通常不重要 足以返回并更改所有现有代码。
答案 5 :(得分:5)
有历史原因左或右是可以接受的。 Stroustrup had added const to C++ by 1983,但在C89 / C90之前它没有达到C。
在C ++中,总是在右边使用const是一个很好的理由。你在任何地方都是一致的,因为const成员函数必须以这种方式声明:
int getInt() const;
答案 6 :(得分:0)
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