返回文章列表

文章

关于C/C++中 *const指针的一些问题

在 C/C++ 中,*const 是用于指针的常量限定符,它表示 指针本身是常量(不可修改指向的地址),但指向的数据可以修改。这一特性在需要固定指针地址但允许修改数据的场景中非常有用

目录
  1. 一、语法与含义
  2. 1. 基本形式
  3. 2. 对比其他指针类型
  4. 二、使用场景
  5. 1. 硬件寄存器操作
  6. 2. 固定缓冲区地址
  7. 3. 防止指针被篡改
  8. 三、与 const int* 的区别
  9. **四、多级指针中的 **const
  10. 五、常见误区
  11. int* const ptr; // 错误!必须初始化 int* const ptr = &var; // 正确 ``` 3. 与引用的区别: - C++ 中引用 (int&) 类似 const 指针(隐式解引用且不可重置),但更安全。
  12. 六、总结
  13. 📎 参考文章

在 C/C++ 中,*const 是用于指针的常量限定符,它表示 指针本身是常量(不可修改指向的地址),但指向的数据可以修改。这一特性在需要固定指针地址但允许修改数据的场景中非常有用。以下是详细解析:

一、语法与含义#

1. 基本形式#

type* const ptr = &var;  // ptr 是常量指针,指向的地址不可变
  • ptr 必须初始化(因地址不可更改)。
  • 可以修改 ptr(指向的数据),但不能修改 ptr(即不能指向其他地址)。

2. 对比其他指针类型#

**声明方式****指针本身是否可变****指向的数据是否可变****典型用途**
**`int* ptr`**普通指针
**`int* const ptr`****否**固定指针地址但需修改数据
**`const int* ptr`****否**保护数据不被修改
**`const int* const ptr`****否****否**完全固定的指针(硬件寄存器)

二、使用场景#

1. 硬件寄存器操作#

在嵌入式开发中,寄存器地址固定但内容可变:

volatile uint32_t* const UART_TX_REG = (uint32_t*)0x4000C000;
*UART_TX_REG = 'A';  // 允许写入数据
// UART_TX_REG = (uint32_t*)0x4000D000;  // 错误!指针地址不可修改

2. 固定缓冲区地址#

确保函数内操作的指针不意外指向其他地址:

void process_buffer(char* const buffer, int size) {
    for (int i = 0; i < size; i++) {
        buffer[i] = toupper(buffer[i]);  // 允许修改数据
        // buffer = another_buffer;      // 错误!禁止修改指针
    }
}

3. 防止指针被篡改#

提升代码安全性,避免指针被重新赋值:

int data = 42;
int* const p_data = &data;
*p_data = 100;  // 合法:修改数据
// p_data = nullptr;  // 编译错误:指针不可变

三、与 const int* 的区别#

  • int* const(常量指针):
    • 指针地址固定,数据可变。
    • 适用于“固定地址,修改内容”的场景。
  • const int*(指向常量的指针):
    • 指针地址可变,数据不可变。
    • 适用于“只读访问”场景。
int a = 10, b = 20;
const int* ptr1 = &a;  // 数据不可变
ptr1 = &b;             // 合法:指针可变
// *ptr1 = 30;         // 错误!数据不可变

int* const ptr2 = &a;  // 指针不可变
*ptr2 = 30;            // 合法:数据可变
// ptr2 = &b;          // 错误!指针不可变

**四、多级指针中的 **const#

在嵌套指针中,*const 限定的是当前层级的指针:

int x = 10;
int* p = &x;
int* const* pp = &p;  // pp 是指向(常量指针)的指针

// **pp = 20;        // 合法:修改 x
// *pp = nullptr;    // 错误!*pp 是 const
// pp = &another_p;  // 合法:pp 自身可变

五、常见误区#

  1. 混淆 const 和 ****const*
    • int* const:指针常量(地址固定)。
    • const int*:指向常量的指针(数据只读)。
  2. 未初始化常量指针

int* const ptr; // 错误!必须初始化 int* const ptr = &var; // 正确 ``` 3. 与引用的区别: - C++ 中引用 (int&) 类似 const 指针(隐式解引用且不可重置),但更安全。#

六、总结#

  • 用途const 用于固定指针地址,同时允许修改指向的数据。
  • 典型场景
    • 硬件寄存器访问。
    • 确保函数内指针不意外偏移。
    • 提升代码可读性(明确指针不应被重新赋值)。
  • 关键点
    • 必须初始化。
    • 与 const int* 有本质区别(前者锁指针,后者锁数据)。 一个指针牵扯到两个对象:指针本身以及指针所指的对象。在指针的声明语句中“前置”const关键字将令所指的对象而非指针本身成为常量。要想令指针本身成为常量,应该用const代替普通的

📎 参考文章#