我总是搞砸如何正确使用const int*、const int*const和int 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);

其他回答

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

下面是一个演示:

常量参考:对变量(此处为int)的引用,该变量是常量。我们主要将变量作为引用传递,因为引用的大小比实际值小,但有一个副作用,这是因为它像实际变量的别名。通过对别名的完全访问,我们可能会意外地更改主变量,因此我们将其设置为常量以防止这种副作用。int var0=0;常量int&ptr1=var0;ptr1=8;//错误var0=6;//好啊常量指针一旦常量指针指向一个变量,那么它就不能指向任何其他变量。int var1=1;int var2=0;int*const ptr2=&var1;ptr2=&var2;//错误指向常量的指针不能改变所指向变量值的指针称为常量指针。int const*ptr3=&var2;*ptr3=4;//错误指向常量的常量指针指向常量的常量指针是一个既不能改变它所指向的地址,也不能改变保存在该地址的值的指针。int var3=0;int var4=0;const int*const ptr4=&var3;*ptr4=1;//错误ptr4=&var4;//错误

要简单地记住:

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

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

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

e.g.

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

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,它引用的值也可能在其他地方更改。

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

只需遵循以下建议

如果单词const出现在星号的左侧,则所指向的是常量如果单词const出现在星号的右侧,则指针本身是常量如果常量出现在两侧,则两者都是常量