const int *,const int * const 和 int const * 有什么区别?

我总是搞砸了如何正确使用const int*const int * constint const * 。是否有一组规则定义您可以做什么和不能做什么?

我想知道在分配,传递给函数等方面所有需要做的事情。

答案

向后读取(受 “ 顺时针 / 螺旋规则”驱动):

  • int* - 指向 int 的指针
  • int const * - 指向 const int 的指针
  • int * const指向 int 的 const 指针
  • int const * const指向 const int 的 const 指针

现在,第一个const可以位于类型的任一侧,因此:

  • const int * == int const *
  • const int * const == int const * const

如果您想发疯,可以执行以下操作:

  • int ** - 指向 int 的指针
  • int ** const指向 int 的指针的 const 指针
  • int * const * - 指向 int 的 const 指针
  • int const ** - 指向 const int 的指针
  • int * const * const指向int * const * const的 const 指针的 const 指针
  • ...

并确保我们清楚 const 的含义

const int* foo;
int *const bar; //note, you actually need to set the pointer 
                //here because you can't change it later ;)

foo是指向常量整数的变量指针。这使您可以更改指向的内容,但不能更改指向的值。最常见的情况是使用 C 样式的字符串,其中有指向const char的指针。您可以更改指向的字符串,但是不能更改这些字符串的内容。当字符串本身位于程序的数据段中并且不应更改时,这一点很重要。

bar是指向可以更改的值的常量或固定指针。这就像没有多余语法糖的参考。由于这个事实,除非需要允许使用NULL指针,否则通常会在使用T* const指针的地方使用引用。

对于那些不了解顺时针 / 螺旋规则的人:从变量名开始,顺时针移动(在这种情况下,向后移动)到下一个指针键入 。重复直到表达式结束。

这是一个演示:

指向int的指针

const指向int const的指针

指向int const的指针

指向const int的指针

指向int的const指针

我认为这里已经回答了所有问题,但是我想补充一下,您应该提防typedef !它们不只是文本替换。

例如:

typedef char *ASTRING;
const ASTRING astring;

astring的类型是char * const ,而不是const char * 。这就是为什么我总是倾向于将const放在类型的右边,而不是从一开始就这样做。

几乎每个人都指出:

const X* pX* const pconst X* const p什么区别?

您必须从右到左读取指针声明。

  • const X* p表示 “p 指向 X 是 const”:不能通过 p 更改 X 对象。

  • X* const p意思是 “p 是指向非 const X 的 const 指针”:您不能更改指针 p 本身,但是可以通过 p 更改 X 对象。

  • const X* const p意思是 “p 是指向 X 的 const 指针,它是 const”:您不能更改指针 p 本身,也不能通过 p 更改 X 对象。

  1. 常数参考:

    对常量的变量(此处为 int)的引用。我们主要将变量作为引用传递,因为引用的大小小于实际值,但是有副作用,这是因为它就像是实际变量的别名。通过完全访问别名,我们可能会意外更改主变量,因此我们将其设为常量以防止这种副作用。

    int var0 = 0;
    const int &ptr1 = var0;
    ptr1 = 8; // Error
    var0 = 6; // OK
  2. 常量指针

    一旦常量指针指向变量,则它不能指向任何其他变量。

    int var1 = 1;
    int var2 = 0;
    
    int *const ptr2 = &var1;
    ptr2 = &var2; // Error
  3. 指向常量的指针

    不能更改其指向的变量的值的指针称为常量指针。

    int const * ptr3 = &var2;
    *ptr3 = 4; // Error
  4. 指向常量的常量指针

    指向常量的常量指针既不能更改其指向的地址,也不能更改保留在该地址的值的指针。

    int var3 = 0;
    int var4 = 0;
    const int * const ptr4 = &var3;
    *ptr4 = 1;     // Error
     ptr4 = &var4; // Error

一般规则是const关键字适用于紧随其后的内容。例外,起始const适用于以下内容。

  • const int*int const*相同,表示“指向常量 int 的指针”
  • const int* constint const* const相同,表示“指向常量 int 的常量指针”

编辑:对于该做什么和不该做什么,如果这个答案还不够,您能否更精确地知道自己想要什么?

这个问题正好说明了为什么我喜欢以我在问题中提到的方式在类型 ID 可接受之后以 const的方式进行操作

简而言之,我发现记住规则的最简单方法是,将 “const” 放在要应用的内容之后 。因此,在您的问题中,“int const *” 表示 int 是常量,而 “int * const” 将表示指针是常量。

如果有人决定将其放在最前面(例如:“const int *”),则在这种情况下,它是一个特殊的例外,适用于其后的事物。

许多人喜欢使用该特殊异常,因为他们认为它看起来更好。我不喜欢它,因为这是一个例外,因此使事情变得混乱。

简单使用const

最简单的用法是声明一个命名常量。为此,将一个常量声明为变量,但在其前面加上const 。一个人必须在构造函数中立即对其进行初始化,因为,当然,一个人以后不能设置该值,因为那会改变它。例如:

const int Constant1=96;

将创建一个整数常量,其值难以想象地称为Constant1 ,值为 96。

此类常数对于程序中使用的参数很有用,但在编译程序后无需更改。与 C 预处理程序#define命令相比,它对程序员具有优势,因为它可以被编译器本身理解和使用,而不是在到达主编译器之前被预处理器替换为程序文本,因此错误消息会更有帮助。

它也适用于指针,但必须注意const以确定指针或其指向的对象是常量还是两者。例如:

const int * Constant2

声明Constant2是指向常量整数的变量指针,并且:

int const * Constant2

是一种替代语法,具有相同的功能,而

int * const Constant3

声明Constant3是指向变量整数的常量指针,并且

int const * const Constant4

声明Constant4是指向常量整数的常量指针。基本上,“const” 适用于其紧靠左边的任何东西(除非没有什么东西,在这种情况下它适用于其紧靠右边的任何东西)。

参考: http : //duramecho.com/ComputerInformation/WhyHowCppConst.html

在您遇到 C ++ 专家 Scott Meyers 的这本书之前,我一直和您有同样的疑问。请参考本书的第三项,他在其中详细介绍了有关使用const

只要遵循这个建议

  1. 如果const单词出现在星号的左侧,则指向的是常量
  2. 如果单词const出现在星号的右边,则指针本身是常量
  3. 如果const出现在两边,则两者都是常数

简单但棘手。请注意,我们可以用任何数据类型( intcharfloat等)交换const限定符。

让我们看下面的例子。


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 p1 ==> *pp是只读的 [ p是指向常量整数的常量指针]。由于此处的指针p是只读的,因此声明和定义应位于同一位置。


int const *p const ==> 错误的语句。编译器将引发语法错误。

int const int *p ==> 错误的语句。编译器将引发语法错误。

int const const *p ==> *p是只读的,等效于int const *p

int const *const p ==> *pp是只读的 [ p是指向常量整数的常量指针]。由于此处的指针p是只读的,因此声明和定义应位于同一位置。