一. 入门:概念引入
定义一个 int 类型的普通变量 val ,假设它的值是 10。再定义一个指向该变量的指针 val_ptr ,它保存了 val 的地址。
1 int val = 10; 2 int *val_ptr = &val;
一个 int 类型的变量保存的是 int 类型的值,同理,一个指向 int 类型的指针变量,保存的是一个地址,这个地址所指向的内存空间,存放着一个 int 类型的值。
指针类型与其它类型别无二致,里面都存放着东西,所以指针变量里面的内容是可以被修改的。我们还可以通过指针,修改它所指向的内存空间的东西。
二. 进阶:const 与指针
1. 我们在上面定义了一个普通变量 val,它的值是可以被改变的。要让这个变量成为一个常量,则需要加上 const 关键字,这样变量 val 的值就不能被改变了。
1 const int val = 10;
2. 现在我们用上面的原始 val 变量来说明问题(不带 const 关键字的版本)
1 int val = 10; 2 int *val_ptr = 10;
val 是一个普通变量, val_ptr 也是一个普通指针。val 变量的值可以被改变,val 的值也可以通过 val_ptr 来改变。
如果不想让 val_ptr 对变量作出修改,则需要加上 const 关键字:
1 const int *val_ptr = &val;
这使得 val_ptr 指向了一个 “常量”。但是我们知道, val 并不是一个常量。这条语句只是规定了,不允许通过 val_ptr 这个途径来修改 val 的值,但它并不在意 val 到底是不是一个常量。
3. 假如 val 真的是一个常量,那么 指向它的指针应该是这样:
1 const int val = 10; 2 const int *val_ptr = &val;
以上语句清楚的表明了, val 的值不能被改变,因此指向它的指针的类型,也需要匹配。
4. 不过既然指针也是变量,它里面存放的值应该可以被改变。
1 int val_a = 10; 2 int *val_ptr = &val_a; 3 int val_b = 20; 4 val_ptr = &b;
我们定义了一个普通变量 val_a 和普通指针 val_ptr ,并令 val_ptr 指向 val_a。之后又定义了一个普通变量 val_b,并该变了 val_ptr 的指向,使它指向了 val_b。
这样做并没有任何不妥,因为没有人规定 val_ptr 是 val_a 独有的。(引用不一样,引用与变量的关系一旦建立,就不会改变)
如果我们需要指定指针与变量的对应关系,就需要向下面这样:
1 int val = 10; 2 int *const val_ptr = &val;
注意 const 的位置,这次它在指针名前,说明指针里面的内容不能被改变。
如果我们希望更进一步,不允许通过指针这个途径改变变量值,那么需要向下面这样:
1 int val = 10; 2 const int *const val_ptr = &val;
这里有两个 const ,第一个 const 指出,指针不能改变它指向的对象;第二个 const 指出,指针自身不允许被改变。