当前位置: 首页 > news >正文

从混淆到精通:C/C++常量指针与指针常量的本质差异与实战应用

一、定义与声明

  1. 常量指针(Pointer to Constant)

    • 定义:指针指向的内容为常量,不可通过该指针修改,但指针本身可改变指向。
    • 声明方式:const int* pint const* p
      const int a = 10;
      const int* p = &a;  // p是常量指针 
      // *p = 20;         // 错误!内容不可修改 
      p = &b;             // 正确,指针指向可修改 
      
  2. 指针常量(Constant Pointer)

    • 定义:指针本身是常量,不可修改指向的地址,但可通过指针修改指向的内容。
    • 声明方式:int* const p
      int b = 20;
      int* const p = &b;  // p是指针常量 
      *p = 30;            // 正确,内容可修改 
      // p = &a;          // 错误!指针指向不可修改 
      
  3. 常指针常量(Constant Pointer to Constant)

    • 定义:指针本身和指向的内容均为常量。
    • 声明方式:const int* const p
      const int c = 30;
      const int* const p = &c;  // 两者均不可修改 
      // *p = 40;               // 错误!
      // p = &a;                // 错误!
      

二、核心区别对比

特性常量指针指针常量常指针常量
指针指向可变性可修改指向(p = &b不可修改指向不可修改指向
内容可变性不可通过指针修改内容可通过指针修改内容不可通过指针修改内容
初始化要求无强制初始化必须初始化必须初始化
典型应用场景函数参数保护数据固定地址操作硬件/资源完全不可变的全局配置

三、使用场景与注意事项

  1. 常量指针的典型应用

    • 函数参数保护:避免函数内部修改外部数据,如strlen(const char* s)
    • 指向字面量:如const char* str = "Hello";,防止修改字符串常量。
  2. 指针常量的典型应用

    • 硬件寄存器操作:固定地址的硬件寄存器访问,如volatile int* const reg = 0x8000;
    • 资源句柄管理:如文件指针需固定指向某个资源句柄。
  3. 常见错误

    • 混淆声明顺序:int const* pconst int* p等价,但int* const p完全不同。
    • 未初始化指针常量:int* const p;会导致编译错误。
    • 通过常量指针修改数据:需确保原始变量本身不是常量(如const int a不可修改,但int a可通过其他方式修改)。

四、示例代码解析

#include <iostream>
using namespace std;
 
int main() {
    int x = 10, y = 20;
    
    // 常量指针 
    const int* p1 = &x;
    // *p1 = 15;    // 编译错误 
    p1 = &y;        // 合法 
 
    // 指针常量 
    int* const p2 = &x;
    *p2 = 15;       // 合法 
    // p2 = &y;     // 编译错误 
 
    // 常指针常量 
    const int* const p3 = &x;
    // *p3 = 20;    // 错误 
    // p3 = &y;     // 错误 
    return 0;
}

五、记忆技巧

  1. 从右向左读声明:
    • const int* p → “p是指针,指向int常量”。
    • int* const p → “p是常量,指向int”。
  2. 口诀:
    • 常量指针:内容不变,指向可变(如看门狗,只读不写)。
    • 指针常量:指向不变,内容可变(如固定管家,可改内容)。

相关文章:

  • Cookie与Session:Web开发中的状态管理机制
  • Docker数据卷容器实战
  • Redis缓存一致性难题:如何让数据库和缓存不“打架”?
  • let、const【ES6】
  • 前端性能测试面试题及参考答案
  • MySQL中的DATETIME与TIMESTAMP选择指南
  • FreeRTOS-在队列发送读取数据小实验
  • C++初阶—list类
  • RISC-V架构的平台级中断控制器(PLIC:platform-level interrupt controller)详解
  • visual studio 2022安装教程及下载(附安装包)visual studio 2022下载安装教程图文详情
  • 解决 Ubuntu 24.04 虚拟机内无法ping 通 Hostname 的问题
  • 【论文笔记-TPAMI 2024】FreqFusion:用于密集图像预测的频率感知特征融合
  • LLM中的Benchmark是什么
  • 阿里开源正式开园文生视频、图生视频模型-通义万相 WanX2.1
  • 浔川 AI 翻译 v6.1.1 将于 3 月 2 日上线:功能升级,体验更优
  • 【文献阅读】A Survey on Model Compression for Large Language Models
  • km98. 所有可达路径(邻接矩阵+邻接表)
  • 【02】Cocos游戏开发引擎从0开发一款游戏-cocos项目目录结构熟悉-调试运行项目-最重要的assets资源文件认识-场景sense了解-优雅草卓伊凡
  • 953 验证外星语词典
  • Qt关于平滑滚动的使用QScroller及QScrollerProperties类说明
  • “家国万里时光故事会” 举行,多家庭共话家风与家国情怀
  • 新闻1+1丨城市,如何对青年更友好?
  • 订婚不等于性同意!山西订婚强奸案入选最高法案例
  • 陈吉宁龚正黄莉新胡文容等在警示教育基地参观学习,出席深入贯彻中央八项规定精神学习教育交流会
  • 英媒:英国首相住所起火,目前无人伤亡
  • 茅台1935今年动销达到预期,暂无赴港上市计划!茅台业绩会回应多个热点