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

C++的指针 、 、* 、值传递、地址传递、引用传递

欢迎来到 C++ 的世界!别担心,你现在的“似懂非懂”其实是每个 C++ 学习者的必经之路。指针和引用就像是 C++ 的“入场券”,一旦理顺了,后面的路就好走多了。

我们可以把内存想象成一排带编号的储物柜


1. 核心概念:*& 的多重身份

这两个符号最让人头疼的地方在于,它们在声明变量实际执行时的含义是不一样的。

* (星号)

  • 在类型后(声明时): 表示“这是一个指针”。例如 int* p; 意思是一个存放 int 类型地址的柜子钥匙。
  • 在变量前(执行时): 表示“解引用”,即“顺着地址去找值”。例如 *p = 10; 意思是把 10 放到钥匙指向的那个柜子里。

& (取地址/引用)

  • 在变量前(执行时): 表示“取地址”。例如 &a 意思是拿走变量 a 所在柜子的编号。
  • 在类型后(声明时): 表示“引用”。这相当于给原有的柜子起了一个别名(绰号)。

2. 三种传递方式的直观对比

假设我们要写一个函数,让一个变量的值增加 10。

A. 值传递 (Pass by Value)

这是最简单的,相当于复印件

void add(int a) { a += 10; }
  • 原理: 函数创建了一个全新的副本。你在函数里怎么折腾副本,原本的变量都不会变。
  • 缺点: 如果数据很大(比如一张巨大的图片),复印会非常慢。

B. 指址传递 (Pass by Pointer)

这相当于把柜子的钥匙交给函数。

void add(int* p) { *p += 10; }
  • 原理: 你把变量的地址传进去,函数通过 *p 找到原件并修改。
  • 注意: 传入时需要用 add(&x)

C. 引用传递 (Pass by Reference)

这相当于给柜子起个别名

void add(int& r) { r += 10; }
  • 原理: r 就是原变量本身,只是换了个名字。在函数里改 r,外面也跟着变。
  • 优势: 语法最简洁(像值传递一样写代码),效率最高(不用复制,也不用处理指针的繁琐)。

3. 总结对照表

方式 语法示例 效果 就像是...
值传递 void func(int x) 修改 x 不影响实参 寄了一份文档副本给对方
指针传递 void func(int* p) 修改 *p 会影响实参 给了对方一张储物柜钥匙
引用传递 void func(int& r) 修改 r 会影响实参 给原件起了个绰号

学习建议:

如果你觉得指针太绕,可以先记住这个黄金法则

  1. 如果只是想读数据,用 const 引用(效率高且安全)。
  2. 如果想修改函数外的变量,优先用 引用
  3. 除非你需要处理 NULL(空地址)或者进行复杂的内存操作,否则尽量少用原始指针。

你想试着写一个小程序,观察一下这三种方式下变量地址的变化吗?我可以带你写一个实验代码。


太棒了,实践是消除“似懂非懂”的最好药方。

我们可以编写一个简单的“地址侦探”程序。通过打印变量在不同传递方式下的内存地址,你能亲眼看到谁是在“复印”,谁是在“操作本体”。


实验代码:地址侦探

你可以直接把这段代码复制到你的 IDE(如 Dev-C++、VS Code 或 Visual Studio)中运行:

#include <iostream>
using namespace std;// 1. 值传递:传入的是副本
void byValue(int x) {cout << "【值传递】  函数内变量地址: " << &x << ",值: " << x << endl;
}// 2. 指针传递:传入的是地址(钥匙)
void byPointer(int* p) {cout << "【指针传递】函数内指针指向的地址: " << p << ",值: " << *p << endl;
}// 3. 引用传递:传入的是别名(本体)
void byReference(int& r) {cout << "【引用传递】函数内引用关联的地址: " << &r << ",值: " << r << endl;
}int main() {int a = 100;cout << "--- 原始变量 a 的地址: " << &a << " ---" << endl << endl;byValue(a);      // 传入 a 的值byPointer(&a);   // 传入 a 的地址byReference(a);  // 传入 a 本身(引用)return 0;
}

运行结果深度解析

当你运行这段程序时,你会看到类似下面的输出(具体的十六进制地址每次运行都会变):

  1. 值传递 (byValue)
  • 你会发现它的地址和 main 函数里 a 的地址完全不同
  • 结论:系统在内存里新开了一个房间,把 100 拷了进去。你在函数里改这个 x,原来的 a 稳如泰山。
  1. 指针传递 (byPointer)
  • 打印出来的地址和 a 的地址一模一样
  • 结论:函数拿到了 a 房间的钥匙(地址),它可以直接开门进去改掉 a
  1. 引用传递 (byReference)
  • 打印出来的地址也和 a 一模一样
  • 结论r 仅仅是 a 的另一个名字。就像你叫“张三”,外号叫“小张”,地址还是那一个。

💡 一个帮你避坑的小技巧

很多初学者分不清 & 到底是在取地址还是在声明引用。看这个:

  • 如果左边有类型(如 int& r = a;),它是引用(起外号)。
  • 如果左边没类型(如 p = &a;),它是取地址(拿钥匙)。

同样:

  • 如果左边有类型(如 int* p;),它是指针声明(造钥匙盒)。
  • 如果左边没类型(如 *p = 20;),它是解引用(用钥匙开门)。
http://www.jsqmd.com/news/407464/

相关文章:

  • 零基础入门:手把手教你用Asian Beauty生成东方风格人像
  • 2026CRM系统解析:超兔、Dynamics 365 等 4 大平台全链路管理能力评测 - 毛毛鱼的夏天
  • 跨团队协作:敏捷面试场景应对——软件测试人才评估新范式
  • 测试工程师如何用AI拆需求?从“看不懂”到“可测试”
  • 2026年佛山GEO优化/AI搜索排名厂家推荐意合云,智能全域优化技术领先 - 品牌企业推荐师(官方)
  • AI绘画新选择:Z-Image Turbo极速体验报告
  • Ubuntu20.04部署实时口罩检测模型:完整环境配置指南
  • Qwen3-ForcedAligner-0.6B在QT跨平台应用中的集成方案
  • 聊聊永亚智能有机肥设备的品牌影响力,选购靠谱设备看这里 - myqiye
  • Qwen3-ASR-0.6B低成本GPU方案:GTX1660 Super实测可用的轻量部署指南
  • RetinaFace人脸检测模型在安防领域的落地实践
  • 5分钟搞定!用Fish Speech 1.5制作个性化语音助手
  • Gemini 3.1 Pro 发布:一次真正意义上的推理能力跃迁
  • 【GitHub项目推荐--Claude-Mem:Claude Code的持久内存压缩系统】
  • 基于YOLOv8和Qwen3-TTS的智能监控语音报警系统
  • Qwen3-Reranker-4B与LangChain集成:构建智能检索增强生成系统
  • 镁球粘合剂优选:2026年口碑厂家大比拼,超级生粉/粘合剂/宠物饲料淀粉/食用面碱/造纸淀粉,粘合剂实力厂家排行榜 - 品牌推荐师
  • AnimateDiff问题解决:常见报错与显存优化技巧汇总
  • UI-TARS-desktop保姆级教程:从安装到实战全流程
  • FLUX.小红书极致真实V2惊艳生成:弱光环境、逆光人像、雨天玻璃窗反射等复杂场景
  • 2026评测:中低压管件新趋势,高压管件优质厂家推荐,高压管件/异径管件/三通管件/保温管道/合金管道,高压管件品牌推荐 - 品牌推荐师
  • RexUniNLU惊艳案例:仅用Schema定义,精准抽取疫情通报实体链
  • AI 技能树怎么搭?90%的人第一步就走错了
  • BGE-Large-Zh开箱体验:中文文本处理如此简单
  • 2026变压器厂家推荐山东德润,干式/油浸式/光伏/充电桩变压器节能先锋 - 品牌企业推荐师(官方)
  • 编译器错误 CS0246
  • 零基础玩转Qwen2.5-7B-Instruct:保姆级教程带你体验旗舰级AI对话
  • Swin2SR对比评测:传统插值与AI超分的画质差异
  • 2026年重庆杀菌剂厂家权威榜单 实力甄选 适配多场景农业绿色防控需求 筑牢农业防护屏障 - 深度智识库
  • Qwen3智能字幕对齐系统的运维部署最佳实践