C++ 指针参数怎么传递 C++ 传值与传地址的区别演示【函数】

发布时间 - 2026-02-03 00:00:00    点击率:
C++默认按值传递参数,包括指针本身;要修改指针变量的指向,须传二级指针(int*)或指针引用(int&),后者更安全自然。

函数里改不了原始变量?那大概率传的是值

当函数内部修改了参数,但调用方的变量没变,说明你传的是副本——也就是按值传递。C++ 默认所有参数都是传值,包括指针变量本身。比如 void foo(int* p),传进来的 p 是原指针的拷贝,你能通过它改它指向的内存(如 *p = 42),但没法让调用方的指针变量指向别处(比如在函数里写 p = new int(99),外面的指针不受影响)。

常见错误现象:
- 想在函数里分配内存并让调用方拿到新地址,结果调用方指针仍是 nullptr 或旧地址;
- 函数里对指针做了 ++p,返回后原指针没动。

  • 传值:函数得到的是指针变量的副本,地址值相同,但变量本身独立
  • 想让函数能“重绑定”指针(即改变指针变量本身的值),必须传指针的地址(即 int**)或引用(int*&
  • 性能上,传指针比传大对象(如 std::vector)便宜,但传指针本身开销仍是复制一个地址(通常 8 字节)

想让函数修改指针本身?用指针的指针或引用

如果目标是让函数内部分配内存、并让调用方的指针变量真正指向新地址,就得把指针的地址交给函数——也就是二级指针。或者更现代、更安全的做法:用指针引用。

示例对比:

void alloc_bad(int* p) { p = new int(100); } // 外面看不到 new 出来的地址
void alloc_good(int** p) { *p = new int(100); }
void alloc_clean(int*& p) { p = new int(100); }

调用方式:

立即学习“C++免费学习笔记(深入)”;

int* ptr = nullptr;
alloc_good(&ptr);   // 必须取地址
alloc_clean(ptr);   // 语法更自然,语义更清晰
  • int** 易错:容易漏掉 &,也容易误写成 **p = ...(那是改内容,不是改指针)
  • int*& 更符合直觉,且编译器会阻止你传临时量(如

    alloc_clean(&x) 这种错误写法直接报错)
  • 两者都避免了拷贝整个对象,但引用形式可读性和安全性更高

传值 vs 传指针 vs 传引用:别只看“能不能改内容”

关键区别不在“能不能改数据”,而在于“谁的数据”和“谁的变量”。同一个 int x = 5;,三种传法行为完全不同:

  • func(x):函数收到 x 的副本,改它不影响 x
  • func(&x):函数收到 &x 的副本(即一个 int*),能通过它改 x 的值,但不能让 &x 变成别的地址(因为地址字面量不可变)
  • func(x) 配合 void func(int& r):函数直接操作 x 本体,改 r 就是改 x;且无法传字面量(如 func(5) 报错),除非加 const

注意:int*int& 都能实现“修改原始值”,但语义不同:前者强调“我操作的是某块内存”,后者强调“我操作的就是这个变量”。实际选型时,优先用引用(&)代替裸指针(*)做输入/输出参数,除非需要空值(nullptr)语义。

const 修饰位置决定你能干什么

const 放在指针声明的不同位置,约束的对象完全不同,直接影响函数能否修改数据或指针本身:

void f1(const int* p);  // *p 不可改(数据只读),p 可改(指针可移动)
void f2(int* const p);  // p 不可改(指针固定),*p 可改(数据可写)
void f3(const int* const p); // 两者都不可改

最常见的是 f1 形式,用于只读访问外部数据(如字符串字面量、只读缓冲区)。如果你发现函数里被禁止写 *p = ...,检查是不是加了前面的 const;如果被禁止写 p++p = ...,那就是后面的 const 在起作用。

  • 传参时加 const 不仅是自我约束,更是接口契约:告诉调用方“我不会改你的数据”
  • 编译器可能据此做优化(如缓存值、省去重读)
  • 但要注意:const int* p 允许你把一个非 const 变量的地址传进去,只是函数内部不能改它

真正容易被忽略的是:指针本身的可变性常被当成理所当然,直到你在函数里试图重新赋值指针却失败,才回头翻声明——这时候看 const 在哪,比猜逻辑快得多。


# go  # 字节  # c++  # 区别  # const  # 字符串  # int  # void  # 指针  # 接口  # 输出参数  # 值传递  # 对象  # 的是  # 你能  # 仍是  # 谁的  # 想让  # 报错  # 并让  # 都是  # 或引用  # 如果你 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 手机网站制作平台,手机靓号代理商怎么制作属于自己的手机靓号网站?  Laravel如何使用Blade组件和插槽?(Component代码示例)  *服务器网站为何频现安全漏洞?  米侠浏览器网页图片不显示怎么办 米侠图片加载修复  如何用免费手机建站系统零基础打造专业网站?  如何在阿里云高效完成企业建站全流程?  Laravel Sail是什么_基于Docker的Laravel本地开发环境Sail入门  jQuery中的100个技巧汇总  EditPlus中的正则表达式 实战(2)  Laravel如何实现模型的全局作用域?(Global Scope示例)  企业在线网站设计制作流程,想建设一个属于自己的企业网站,该如何去做?  深圳网站制作平台,深圳市做网站好的公司有哪些?  网站建设保证美观性,需要考虑的几点问题!  香港代理服务器配置指南:高匿IP选择、跨境加速与SEO优化技巧  JavaScript数据类型有哪些_如何准确判断一个变量的类型  大连企业网站制作公司,大连2025企业社保缴费网上缴费流程?  Laravel数据库迁移怎么用_Laravel Migration管理数据库结构的正确姿势  香港服务器网站测试全流程:性能评估、SEO加载与移动适配优化  ChatGPT回答中断怎么办 引导AI继续输出完整内容的方法  如何用虚拟主机快速搭建网站?详细步骤解析  如何选择可靠的免备案建站服务器?  谷歌Google入口永久地址_Google搜索引擎官网首页永久入口  Laravel怎么发送邮件_Laravel Mail类SMTP配置教程  Python文本处理实践_日志清洗解析【指导】  常州企业网站制作公司,全国继续教育网怎么登录?  如何生成腾讯云建站专用兑换码?  javascript如何操作浏览器历史记录_怎样实现无刷新导航  网站制作企业,网站的banner和导航栏是指什么?  PHP 500报错的快速解决方法  公司门户网站制作流程,华为官网怎么做?  浅谈redis在项目中的应用  如何用5美元大硬盘VPS安全高效搭建个人网站?  新三国志曹操传主线渭水交兵攻略  Win11搜索栏无法输入_解决Win11开始菜单搜索没反应问题【技巧】  标题:Vue + Vuex + JWT 身份认证的正确实践与常见误区解析  Laravel如何与Pusher实现实时通信?(WebSocket示例)  EditPlus中的正则表达式 实战(4)  Win11怎么更改系统语言为中文_Windows11安装语言包并设为显示语言  香港服务器网站推广:SEO优化与外贸独立站搭建策略  使用豆包 AI 辅助进行简单网页 HTML 结构设计  C#如何调用原生C++ COM对象详解  原生JS获取元素集合的子元素宽度实例  详解Android——蓝牙技术 带你实现终端间数据传输  如何基于云服务器快速搭建网站及云盘系统?  油猴 教程,油猴搜脚本为什么会网页无法显示?  深圳防火门网站制作公司,深圳中天明防火门怎么编码?  三星网站视频制作教程下载,三星w23网页如何全屏?  Laravel API资源(Resource)怎么用_格式化Laravel API响应的最佳实践  Javascript中的事件循环是如何工作的_如何利用Javascript事件循环优化异步代码?  laravel服务容器和依赖注入怎么理解_laravel服务容器与依赖注入解析