指针与 const

回顾:普通(非常量)指针

对于普通(non-const)指针,我们既能改变它指向的地址(通过给指针赋新地址),也能改变所指地址上的值(通过对解引用后的指针赋值):

int main() {
    int x{ 5 };
    int* ptr{ &x }; // ptr 为普通指针

    int y{ 6 };
    ptr = &y;   // 改变指向
    *ptr = 7;   // 改变值
}

指向 const 对象

若目标对象被声明为 const,则不能让普通指针指向它:

int main() {
    const int x{ 5 };
    int* ptr{ &x }; // 编译错误:无法将 const int* 转换为 int*
}

道理显而易见:普通指针解引用后可修改值,这会破坏对象的常量性。

“指向 const 的指针”(pointer to const)
在类型前加 const,声明一个指向 const 值的指针

int main() {
    const int x{ 5 };
    const int* ptr{ &x }; // OK:指向 const int
    *ptr = 6;             // 错误:不能通过 ptr 修改 const 值
}

注意:指针本身不是常量,因此仍可改变它指向的地址:

const int x{ 5 }, y{ 6 };
const int* ptr{ &x };
ptr = &y; // OK:指向新的 const int

指向 const 的指针同样可指向非 const 变量,只是通过该指针访问时把对象视为 const:

int x{ 5 };
const int* ptr{ &x }; // OK
*ptr = 6;    // 错误:不能通过 ptr 修改
x = 6;       // OK:直接修改原变量

const 指针

若希望指针本身在初始化后不可再指向别处,应在 * 后加 const

int main() {
    int x{ 5 }, y{ 6 };
    int* const ptr{ &x }; // const 指针,指向 int
    ptr = &y; // 错误:地址不可再改
    *ptr = 7; // OK:可修改所指对象
}

“指向 const 的 const 指针”

在类型前和 * 后都加 const 即可得到既不能改指向、也不能改值的指针

int value{ 5 };
const int* const ptr{ &value }; // 指向 const int 的 const 指针

四种组合速记

只需记住 4 条规则,逻辑清晰:

  1. 普通指针 int* ptr

    • 可改指向
    • 可改值
    • 不能指向 const 值
  2. 指向 const 的指针 const int* ptr

    • 可改指向
    • 不能改值
    • 可指向 const 或非 const 对象
  3. const 指针 int* const ptr

    • 不能改指向
    • 可改值
  4. 指向 const 的 const 指针 const int* const ptr

    • 不能改指向
    • 不能改值

声明速记

  • const* 左侧:修饰所指值
  • const* 右侧:修饰指针本身

示例:

int v{ 5 };
int* ptr0{ &v };               // 普通指针
const int* ptr1{ &v };         // 指向 const int
int* const ptr2{ &v };         // const 指针
const int* const ptr3{ &v };   // 指向 const int 的 const 指针

下一课

12.10《通过地址传参》 返回目录 上一课 12.8《空指针》

关注公众号,回复"cpp-tutorial"

可领取价值199元的C++学习资料

公众号二维码

扫描上方二维码或搜索"cpp-tutorial"