大家好:
衷心希望各位点赞。
您的问题请留在评论区,我会及时回答。
将 const 用于指针有一些很微妙的地方,我们来详细探讨一下:可以用两种完全不同的方式将 const 关键字用于指针,第一种方式是让指针指向一个常量对象,这样可以防止使用该指针来修改所指向的值;第二种方式是将指针本身声明成为常量,这样可以防止改变指针指向的位置,下面来看细节:
首先,先声明一个指向常量的指针 pt:
int age = 39;
const int* pt = &age;
该声明指出,pt 指向一个 const int (这里为39),因此不能使用 pt 来修改这个值。换句话来说,*pt的值为 const,不能被修改:
*pt += 1; // INVALID because pt points to a const int
cin >> *pt; // INVALID for the same reason
现在来看一个微妙的问题,pt 的声明并不意味着它指向的值实际上就是一个常量,而只是意味着对 pt 而言,这个值是常量。例如,pt 指向 age,然而 age 不是 const ,可以直接通过 age 变量名来修改 age 的值,但不能使用 pt 指针来修改它:
*pt =20; // INVALID beacuse pt points to a const int
age = 20; // VALID beacuse age is not declared to be const
以前我们将常规变量的地址赋值给常规指针,然而这里将常规变量的地址赋值给指向 const 的指针。因此还有两种可能:将 const 变量的地址赋给指向 const 的指针、将 const 的地址赋给常规指针。这两种操作都可行吗?第一种可行,但是第二种不行:
const float g_earth = 9.80;
const float* pe = &g_earth; // VALID
const float g_moon = 1.63;
float* pm = &g_moon; // INVALID
对于第一种情况来说,即不能使用 g_earth 来修改 9.80 ,也不能使用 pe 来修改。C++禁止第二种情况的原因很简单——如果将 g_moon 的地址赋给 pm ,则可以使用 pm 来修改 g_moon 的值,这使得 g_moon 的 const 状态很荒谬,因此 C++ 禁止将 const 的地址赋给非 const 指针。
如果将指针指向指针,则情况将更复杂。假如涉及的是一级间接关系,则将非 const 指针赋给 const 指针是可以的:
int age = 39; // age++ is a valid operation
int* pd = &age; // *pd = 41 is a valid operation
const int* pt = pd; // *pt = 42 is an invalid operation
然而进入两级间接关系时,与一级间接关系一样将 const 和非 const 混合的指针赋值方式将不再安全。如果允许这样做,则可以编写这样的代码:
const int** pp2;
int* p1;
const int n = 13;
pp2 = &p1; // not allowed, but suppose it were
*pp2 = &n; //valid, both const, but sets p1 to point at n
*p1 = 10; // valid, but changes const n
上述代码将非 const 地址(&p1)赋给了 const 指针(pp2),因此可以使用 p1 来修改 const 数据。因此,仅当只有一层间接关系(如指针指向基本数据类型)时,才可以将非 const 地址或指针赋给 const 指针。
注意:如果数据类型本身并不是指针,则可以将 const 数据或非 const 数据的地址赋给指向 const 的指针,但只能将非 const 数据的地址赋给非 const 指针。