我总是搞砸如何正确使用const int*、const int*const和int const*。有没有一套规则来定义你能做什么和不能做什么?
我想知道在赋值、传递给函数等方面的所有注意事项。
我总是搞砸如何正确使用const int*、const int*const和int const*。有没有一套规则来定义你能做什么和不能做什么?
我想知道在赋值、传递给函数等方面的所有注意事项。
当前回答
就像每个人都指出的那样:
常量X*p、X*constp和常量X*const p之间有什么区别?
必须读取指针声明从右到左。const X*p表示“p指向常量的X”:X对象不能通过p更改。X*const p表示“p是指向非常量X的常量指针”:不能更改指针p本身,但可以通过p更改X对象。const X*const p表示“p是指向常量X的常量指针”:不能更改指针p本身,也不能通过p更改X对象。
其他回答
C++中围绕常量正确性还有许多其他微妙之处。我想这里的问题只是关于C,但我会给出一些相关的例子,因为标记是C++:
通常将字符串等大参数作为TYPE const&传递,这会防止对象被修改或复制。例子:TYPE&TYPE::operator=(const TYPE&rhs){…return*this;}但是TYPE&const是没有意义的,因为引用总是常量。您应该始终将不修改类的类方法标记为const,否则不能从TYPE const引用调用该方法。例子:bool TYPE::运算符==(const TYPE&rhs)const{…}在一些常见情况下,返回值和方法都应该是常量。例子:const TYPE TYPE::运算符+(const TYPE&rhs)const{…}事实上,const方法不能返回内部类数据作为对非常量的引用。因此,必须经常使用常量重载创建常量和非常量方法。例如,如果定义T const&operator[](unsigned i)const;,那么您可能还需要以下给出的非常量版本:内联T运算符[](无符号i)(&O){返回const_cast<char&>(static_cast<const TYPE&>(*this)[](i));}
事实上,C中没有常量函数,非成员函数本身在C++中不能是常量,常量方法可能有副作用,编译器不能使用常量函数来避免重复的函数调用。事实上,即使是一个简单的int const&reference,它引用的值也可能在其他地方更改。
我想这里已经回答了所有问题,但我只想补充一点,你应该小心typedefs!它们不仅仅是文本替换。
例如:
typedef char *ASTRING;
const ASTRING astring;
跨接的类型是char*const,而不是const char*。这是我总是倾向于将常量放在类型的右边,而从不放在开头的原因之一。
对于那些不了解顺时针/螺旋规律的人:从变量的名称开始,顺时针移动(在这种情况下,向后移动)到下一个指针或类型。重复此操作,直到表达式结束。
下面是一个演示:
这个问题确切地说明了为什么我喜欢用我在问题中提到的在类型id可接受之后是常量的方式做事?
简而言之,我发现记住这个规则最简单的方法是“const”跟在它应用的对象后面。所以在你的问题中,“int const*”表示int是常量,而“int*const”表示指针是常量。
如果有人决定把它放在最前面(例如:“constint*”),作为这种情况下的一个特殊例外,它适用于后面的东西。
许多人喜欢使用这个特殊的例外,因为他们认为它看起来更好。我不喜欢它,因为它是一个例外,从而混淆了事情。
这很简单,但很棘手。请注意,我们可以将const限定符应用于任何数据类型(int、char、float等)。
让我们看看下面的例子。
const int*p==>*p是只读的[p是指向常量整数的指针]
int const*p==>*p是只读的[p是指向常量整数的指针]
int*p const==>错误语句。编译器抛出语法错误。
int*const p==>p是只读的[p是指向整数的常量指针]。因为这里的指针p是只读的,所以声明和定义应该在同一位置。
const int*p const==>错误语句。编译器抛出语法错误。
const int const*p==>*p为只读
const int*const p==>*p和p是只读的[p是指向常量整数的常量指针]。因为这里的指针p是只读的,所以声明和定义应该在同一位置。
int const*p const==>错误语句。编译器抛出语法错误。
int const int*p==>错误语句。编译器抛出语法错误。
int const const*p==>*p是只读的,与int const*p等效
int const*const p==>*p和p是只读的[p是指向常量整数的常量指针]。因为这里的指针p是只读的,所以声明和定义应该在同一位置。