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

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


当前回答

最初的设计者多次将C和C++声明语法描述为失败的实验。

相反,让我们将类型命名为“pointer to type”;我叫它Ptr_:

template< class Type >
using Ptr_ = Type*;

现在Ptr_<char>是一个指向char的指针。

Ptr_<const char>是指向const char的指针。

const Ptr_<const char>是指向const char的const指针。

其他回答

为了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);

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

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

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

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

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

下面是一个演示:

要简单地记住:

若const在*之前,则值为常量。

如果const在*之后,则地址为常量。

如果const在*之前和之后都可用,则值和地址都是常量。

e.g.

int*常量变量//这里地址是恒定的。int常量*var//这里的值是恒定的。int常量*常量变量;//值和地址都是常量。

我想这里已经回答了所有问题,但我只想补充一点,你应该小心typedefs!它们不仅仅是文本替换。

例如:

typedef char *ASTRING;
const ASTRING astring;

跨接的类型是char*const,而不是const char*。这是我总是倾向于将常量放在类型的右边,而从不放在开头的原因之一。