C++ 常量引用与指向常量的指针

C++ 常量引用与指向常量的指针,c++,C++,为什么使用指针指向常量我可以更改指针指向的变量的值,而使用常量引用我不能 int a = 10; int * const ptr = &a; (*ptr)++; // OK const int & ref = a; ref++; // error 在第一个示例中,您有一个指向非常量int的常量指针。这是因为const适用于它左边的东西,除了左边没有东西,它也适用于右边的东西。因此,可以增加值,但禁止增加指针(不取消引用的情况下增加)。在第二个示例中,您尝试递增一个常量引用,这是

为什么使用指针指向常量我可以更改指针指向的变量的值,而使用常量引用我不能

int a = 10;
int * const ptr = &a;
(*ptr)++; // OK
const int & ref = a;
ref++; // error

在第一个示例中,您有一个指向非常量
int
的常量指针。这是因为
const
适用于它左边的东西,除了左边没有东西,它也适用于右边的东西。因此,可以增加值,但禁止增加指针(不取消引用的情况下增加)。在第二个示例中,您尝试递增一个常量引用,这是不允许的。

“const int*ptr”表示指针指向的数据是常量,当指针本身可以更改时,无法更改

“int*const ptr”表示指针不能指向其他地方,而指向的数据可以更改


因此,第一个增量有效,而第二个增量给出一个错误

常量指针和指向常量变量的指针之间存在差异,具体取决于
常量
限定符的放置位置:

intmain()
{
INTA=10;
int*const ptr1=&a;
(*ptr1)++;//好-这是指向非常量int的常量指针
常数int*ptr2=&a;
(*ptr2)++;//错误-但这是指向常量int的指针
返回0;
}

要完全理解,请阅读以下内容:

const int value = 5; // value is const
int *ptr = &value; // compile error: cannot convert const int* to int*
*ptr = 6; // change value to 6

上面的代码段无法编译——我们无法设置指向常量变量的非常量指针。这是有道理的:常量变量的值是不能更改的。假设,如果我们可以将一个非常量指针设置为常量值,那么我们就可以取消对该非常量指针的引用并更改该值。那将违反康斯特的意图

指向常量值的2指针

指向常量值的指针是指向常量值的(非常量)指针

要声明指向常量值的指针,请在数据类型之前使用const关键字:

const int value = 5;
const int *ptr = &value; // this is okay, ptr is a non-const pointer that is pointing to a "const int"
*ptr = 6; // not allowed, we can't change a const value
在上面的示例中,ptr指向const int

到目前为止还不错,对吧?现在考虑下面的例子:

一, 二,

int值=5;//这个值不是常数 常量int*ptr=&value;//这还可以

指向常量变量的指针可以指向非常量变量(如上例中的变量值)。可以这样想:当通过指针访问某个常量变量时,指向该变量的指针将该变量视为常量,而不管该变量最初是否定义为const

因此,以下是可以的:

int value = 5;
const int *ptr = &value; // ptr points to a "const int"
value = 6; // the value is non-const when accessed through a non-const identifier
但以下情况并非如此:

int value = 5;
const int *ptr = &value; // ptr points to a "const int"
*ptr = 6; // ptr treats its value as const, so changing the value through ptr is not legal
由于指向常量值的指针不是常量本身(它只是指向常量值),因此指针可以重定向到指向其他值:

int value1 = 5;
const int *ptr = &value1; // ptr points to a const int

int value2 = 6;
ptr = &value2; // okay, ptr now points at some other const int
3常数指针

我们还可以使指针本身保持常量。常量指针是其值在初始化后无法更改的指针

要声明常量指针,请在星号和指针名称之间使用const关键字:

int value = 5;
int *const ptr = &value;
与普通常量变量一样,常量指针必须在声明时初始化为值。这意味着常量指针将始终指向同一地址。在上述情况下,ptr将始终指向值的地址(直到ptr超出范围并被销毁)

但是,由于指向的值仍然是非常量,因此可以通过取消引用常量指针来更改指向的值:

int value = 5;
int *const ptr = &value; // ptr will always point to value
*ptr = 6; // allowed, since ptr points to a non-const int
指向常量值的4-Const指针

最后,可以在类型和变量名之前使用const关键字声明指向const值的const指针:

int value = 5;
const int *const ptr = &value;
指向常量值的常量指针不能设置为指向另一个地址,也不能通过指针更改它指向的值

重述

总而言之,您只需要记住4条规则,它们非常符合逻辑:

A non-const pointer can be redirected to point to other addresses.
A const pointer always points to the same address, and this address can not be changed. 

A pointer to a non-const value can change the value it is pointing to. These can not point to a const value.
A pointer to a const value treats the value as const (even if it is not), and thus can not change the value it is pointing to. 
保持声明语法的直截了当可能是一项挑战。只要记住

int value = 5;
const int *ptr1 = &value; // ptr1 points to a "const int", so this is a pointer to a const value.
int *const ptr2 = &value; // ptr2 points to an "int", so this is a const pointer to a non-const value.
const int *const ptr3 = &value; // ptr3 points to a "const int", so this is a const pointer to a const value.
结论

指向常量值的指针主要用于函数参数中(例如,将数组传递给函数时),以帮助确保函数不会无意中更改传入的参数。我们将在函数部分进一步讨论这一点


资源::

该代码中没有常量引用。您忘记了第二个示例中的地址运算符。
int*const ptr
不是指向常量的指针。它是指向非常量int的常量指针。我们无法将非常量指针设置为指向常量变量错误(已更正)。要获取指向常量int的指针,您需要:
int-const*ptr=&a
(或
const int*ptr=&a;
,意思完全相同。)
int value = 5;
const int *ptr1 = &value; // ptr1 points to a "const int", so this is a pointer to a const value.
int *const ptr2 = &value; // ptr2 points to an "int", so this is a const pointer to a non-const value.
const int *const ptr3 = &value; // ptr3 points to a "const int", so this is a const pointer to a const value.