转载 关于指针常量与常量指针

📎 原文链接:https://blog.030215.xyz/guan-yu-zhi-zhen-chang-liang-yu-chang-liang-zhi-zhen

指针常量#

1
int *const ptr = nullptr;

const 修饰的是指针 ptr 的值,ptr 本身不能被修改,所以指针常量必须初始化,同时我们无法对 ptr 的值进行修改。

1
2
3
int a = 10;
int *const ptr = &a;
ptr = nullptr; // error

指针常量的应用场景#
例如:需要编写一个函数,实现使用传参指针的形式交换两个整形的值。

下面是实现代码:

1
2
3
4
5
void swap(int *a, int *b) {
int tmp = *a;
*a = *b;
*b = tmp;
}

上述代码可以实现功能,但是存在一定的问题,因为我们可以在函数体内可以修改指针的所指向的值,同时也可以修改指针的值(这并不是我们所希望的),为了使代码更为健壮,我们可以使用指针常量,使得传入指针的值不会被无意修改。

下面是修改后的代码:

1
2
3
4
5
6
7
8
9
10
void swap(int *const a, int *const b) { ... }
常量指针#
const int *ptr;
// 或
int const *ptr;
const 修饰的 *ptr 的值,也就是指针所指向的值,ptr 指向的值是不可修改的。同时在不进行常量类型转换的情况下我们无法对 *ptr 进行修改。

int a = 10;
int const *ptr = &a;
*ptr = 20; // error

常量指针的应用场景#
例如:需要编写一个函数,实现打印一个数组。

下面是实现代码:

1
2
3
4
5
void printArray(int const* arr, size_t len) {
for (size_t i = 0; i < len; ++i) {
std::cout << arr[i] << " ";
}
}

这里你可能会认为使用 const 修饰数组退化而来的指针所指向的值就可以了,但是这仍存在的问题,因为我们仍可以在函数体内修改指针的值,这并不是我们希望的,因此在此基础上还需要 const 修饰指针的值。

下面是修改后的代码:

1
void printArray(int const *const arr, size_t len) { ... }

指针常量与常量指针的关系#
我们会发现常量指针有两种写法:int const * 和 const int * 。

对于第一种形式的理解:const 是向左修饰的,例如:int const *ptr; 中 const 修饰的是 int 值类型,所以指针指向的值不可以修改;int *const ptr = nullptr; 中 const 修饰 int * 指针类型,所以指针指向不能修改。这种理解需要遵守的代码规范,因为如果将常量指针写成 const int * 就需要我们进行转换了。(也可以理解为如果左侧没有对象,则转为修饰右侧对象。)

常量指针和指针常量的命名则是与 const int * 和 int *const 的代码规范相对应。

观察以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>

struct A {
void foo() { std::cout << "non const" << std::endl; }
void foo() const { std::cout << "const" << std::endl; }
};

int main() {
A a;
A *const ptr1 = &a;
ptr1->foo();
A const *ptr2 = &a;
ptr2->foo();
}
int *const ptr1 = &a 中 const 修饰的是 ptr1 指针的值,没有修饰指针所指向的对象,所以 ptr1->foo() 调用非 const 版本。

int const *ptr2 = &a 中 const 修饰的是 ptr2 指针指向的值 a,意思是指向的值不可修改,所以 ptr2->foo() 调用 const 版本。

如有纰漏,欢迎指正。

作者

Jhuoer Yen

发布于

2024-06-28

更新于

2024-06-28

许可协议

评论

Your browser is out-of-date!

Update your browser to view this website correctly.&npsb;Update my browser now

×