书上原文说到:
注意:如果数据本身并不是指针,则可以将const数据或非const数据的地址赋给指向const的指针,但只能将非const数据的地址赋给非const指针
本文对该句进行解析
本句强调的是书上所说的“仅当只有一层间接关系(如指针指向基本数据类型)时”
举个例子:
只有一层间接关系
又或者
相对的,指的的是说上所说的“两层间接关系”
注意第一行的 const int pp2,“两层间接关系”说的就是pp2,**pp2是个指针套指针的存在,其关系可以解析为如下
举个例子
非const数据 即 age;非const数据的地址 即 &age
指向const的指针 即 pt
指针pt即将存储一个地址,但目前未将&age赋给该地址,指针pt存储的地址并未生成;但int修饰pt,可以知道pt的性质是int,并且const修饰int,即*pt是个常量
然后将 非const数据的地址 赋给 指向const的指针,即 &age 赋给 pt
书上对这种情况说到:
pt的声明并不意味着它指向的值实际上就是一个常量,而只是意味着对pt而言,这个值是常量。例如,pt指向age,而age不是const。可以直接通过age变量来修改age的值,但不能使用pt指针来修改它。
——这种情况即
后生成的指针 无法修改(无法修改的原因:是指向const的指针) 之前生成的非const数据。
可以视这种情况视为一种“升级”,非const数据本可以被修改,我现在要求它不可以被修改。
举个例子
const数据 即 g_earth
指向const的指针 即 pe
指针pe即将存储一个地址,但目前未将&g_earth赋给该地址,指针pt存储的地址并未生成;但int修饰pe,可以知道pe的性质是int,并且const修饰int,即*pt是个常量
因此,后生成的指针 无法修改(无法修改的原因:是指向const的指针) 之前生成的const数据
举个反例:将 const数据的地址赋给非const指针
书上对这种情况的解释是:
“如果将g_moon的地址赋给pm,则可以使用pm来修改g_moon的值,这使得g_moon的const状态很荒谬,因此c++禁止将const的地址赋给非const指针”
其实不准这种情况存在,是怕 后生成的指针(pm) 修改(可以修改的原因:是指向非const的指针) 之前生成的const数据(g_moon),
即后面的运算情况 不会改变 先前运算情况的性质
非const数据的地址赋给非const指针 也 举个例子
后生成的指针(pd) 修改(可以修改的原因:是指向非const的指针) 之前生成的非const数据(age)。
然而,进入两层间接关系时,与一级间接关系一样将const和非const混合的指针赋值方式将不再安全。
这种“不安全”体现在:
上述代码将非const地址(&pl)赋值给了const指针(pp2),因此可以使用pl来修改const数据。
即
*p1=10;//valid , but changes const n”
n作为const,不应该被修改,这句却修改了它
如上操作可行的原因:
看下表
只有**pp2是const,*pp2(是内容,可变)、指针pp2存储的地址均可改变
所以有了最后三行的操作