我总是搞砸如何正确使用const int*、const int*const和int const*。有没有一套规则来定义你能做什么和不能做什么?

我想知道在赋值、传递给函数等方面的所有注意事项。


当前回答

在我读到C++大师斯科特·梅耶斯(Scott Meyers)的这本书之前,我和你一样心存疑虑。请参阅本书中的第三项,其中他详细介绍了如何使用const。

只需遵循以下建议

如果单词const出现在星号的左侧,则所指向的是常量如果单词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对象。

反向阅读(由顺时针/螺旋法则驱动):

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

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

常量int*==int常量*const int*const==int const*const

如果你想变得疯狂,你可以这样做:

int**-指向int指针的指针int**const-指向int指针的const指针int*const*-指向int的const指针int const**-指向常量int的指针int*const*const-指向int的常量指针的常量指针...

为了确保我们清楚const的含义:

int a = 5, b = 10, c = 15;

const int* foo;     // pointer to constant int.
foo = &a;           // assignment to where foo points to.

/* dummy statement*/
*foo = 6;           // the value of a can´t get changed through the pointer.

foo = &b;           // the pointer foo can be changed.



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

*bar = 16;            // the value of c can be changed through the pointer.    

/* dummy statement*/
bar = &a;             // not possible because bar is a constant pointer.           

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

bar是指向可更改值的常量或固定指针。这就像没有额外语法糖的引用。由于这一事实,通常您会在使用T*常量指针的地方使用引用,除非您需要允许NULL指针。

这个问题确切地说明了为什么我喜欢用我在问题中提到的在类型id可接受之后是常量的方式做事?

简而言之,我发现记住这个规则最简单的方法是“const”跟在它应用的对象后面。所以在你的问题中,“int const*”表示int是常量,而“int*const”表示指针是常量。

如果有人决定把它放在最前面(例如:“constint*”),作为这种情况下的一个特殊例外,它适用于后面的东西。

许多人喜欢使用这个特殊的例外,因为他们认为它看起来更好。我不喜欢它,因为它是一个例外,从而混淆了事情。

为了C遵循其他解释的完整性,对C++不确定。

pp-指针到指针p-指针数据-在示例x中指出的内容粗体-只读变量

指针

p数据-int*p;p数据-int常量*p;p数据-int*const p;p数据-int const*const p;

指向指针的指针

pp p数据-int**pp;pp p数据-int**const pp;pp p数据-int*const*pp;pp p数据-int常量**pp;pp p数据-int*const*const pp;pp p数据-int const**const pp;pp p数据-int const*const*pp;pp p数据-int常量*常量*常量pp;

// Example 1
int x;
x = 10;
int *p = NULL;
p = &x;
int **pp = NULL;
pp = &p;
printf("%d\n", **pp);

// Example 2
int x;
x = 10;
int *p = NULL;
p = &x;
int ** const pp = &p; // Definition must happen during declaration
printf("%d\n", **pp);

// Example 3
int x;
x = 10;
int * const p = &x; // Definition must happen during declaration
int * const *pp = NULL;
pp = &p;
printf("%d\n", **pp);

// Example 4
int const x = 10; // Definition must happen during declaration
int const * p = NULL;
p = &x;
int const **pp = NULL;
pp = &p;
printf("%d\n", **pp);

// Example 5
int x;
x = 10;
int * const p = &x; // Definition must happen during declaration
int * const * const pp = &p; // Definition must happen during declaration
printf("%d\n", **pp);

// Example 6
int const x = 10; // Definition must happen during declaration
int const *p = NULL;
p = &x;
int const ** const pp = &p; // Definition must happen during declaration
printf("%d\n", **pp);

// Example 7
int const x = 10; // Definition must happen during declaration
int const * const p = &x; // Definition must happen during declaration
int const * const *pp = NULL;
pp = &p;
printf("%d\n", **pp);

// Example 8
int const x = 10; // Definition must happen during declaration
int const * const p = &x; // Definition must happen during declaration
int const * const * const pp = &p; // Definition must happen during declaration
printf("%d\n", **pp);

N级取消引用

继续前进,但愿人类将你逐出教会。

int x = 10;
int *p = &x;
int **pp = &p;
int ***ppp = &pp;
int ****pppp = &ppp;

printf("%d \n", ****pppp);

这很简单,但很棘手。请注意,我们可以将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是只读的,所以声明和定义应该在同一位置。