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

【C++】详解形参和实参:别再傻傻分不清

🔥个人主页:@草莓熊Lotso

🎬作者简介:C++研发方向学习者

📖个人专栏: 《C语言》 《数据结构与算法》《C语言刷题集》《Leetcode刷题指南》

⭐️人生格言:生活是默默的坚持,毅力是永久的享受。

前言:在 C/C++ 函数调用中,形参和实参是两个核心概念,也是初学者容易混淆的知识点。本文将从定义、特性、传递方式等多个维度深入解析,帮你彻底掌握这对重要概念。


目录

一、基本定义与本质区别

二、参数传递的三种方式

1. 值传递(默认方式)

2. 地址传递(指针传递)

3. 引用传递(C++ 特有)

三、常见误区与注意事项

数组作为参数的特殊性

指针参数的 const 修饰

引用参数的初始化

四、形参与实参的匹配规则


一、基本定义与本质区别

形参(形式参数) 是函数定义时声明的参数,位于函数名后的括号中,用于接收调用时传递的数据。例如:

// x和y就是形参
int max(int x, int y) {return x > y ? x : y;
}

形参只在函数内部有效,相当于函数内的局部变量,只有当函数被调用时才会分配内存,函数执行结束后立即释放。

实参(实际参数) 是函数调用时传递给函数的具体数据,可以是常量、变量、表达式或函数返回值。例如:

int a = 10, b = 20;
// 以下几种都是实参的合法形式
max(5, 8);           // 常量作为实参
max(a, b);           // 变量作为实参
max(a + 3, min(b, 25));  // 表达式和函数返回值作为实参

实参必须具有确定的值,在函数调用时会将这些值传递给形参。


二、参数传递的三种方式

C/C++ 中参数传递主要有三种方式,每种方式对实参的影响各不相同:

1. 值传递(默认方式)

值传递时,编译器会为形参分配内存,并将实参的值复制一份给形参。这意味着形参和实参是完全独立的两个变量,修改形参不会影响实参。

void increment(int num) {num++;  // 仅修改形参cout << "函数内:" << num << endl;  // 输出11
}int main() {int a = 10;increment(a);cout << "函数外:" << a << endl;  // 仍然输出10return 0;
}

值传递的优点是安全,避免函数意外修改外部变量;缺点是对于大型数据结构,复制操作会影响性能。

2. 地址传递(指针传递)

当形参是指针类型时,传递的是实参的地址。这时通过指针间接访问可以修改实参的值:

void increment(int* num) {(*num)++;  // 通过指针修改实参cout << "函数内:" << *num << endl;  // 输出11
}int main() {int a = 10;increment(&a);  // 传递a的地址cout << "函数外:" << a << endl;  // 输出11return 0;
}

指针传递本质上还是值传递,只是传递的是地址值。这种方式常用于需要修改实参或传递大型数据结构(避免复制开销)的场景。

3. 引用传递(C++ 特有)

引用是变量的别名,声明时必须初始化且不能更改指向。引用传递时,形参相当于实参的别名,操作形参就是直接操作实参:

void increment(int& num) {  // &表示引用num++;  // 直接修改实参cout << "函数内:" << num << endl;  // 输出11
}int main() {int a = 10;increment(a);  // 直接传递变量cout << "函数外:" << a << endl;  // 输出11return 0;
}

引用传递在语法上比指针更简洁,同时保留了指针传递的效率,是 C++ 中推荐的方式。


三、常见误区与注意事项

数组作为参数的特殊性

数组作为参数时,会自动退化为指针,传递的是数组首元素的地址:

void printArray(int arr[], int size) {  // arr实际是指针for(int i = 0; i < size; i++) {cout << arr[i] << " ";}
}

指针参数的 const 修饰

如果不希望函数修改指针指向的数据,可以用const修饰:

// 确保不会修改str指向的内容
void printString(const char* str) {// *str = 'A';  // 编译错误,不允许修改cout << str << endl;
}

引用参数的初始化

引用必须初始化,因此函数调用时必须提供有确定值的实参:

void func(int& x) {}int main() {// func(10);  // 错误,不能绑定到临时值int a = 10;func(a);  // 正确return 0;
}

四、形参与实参的匹配规则

函数调用时,实参与形参需要满足:

  • 数量必须相同
  • 类型必须兼容(可以自动转换或显式转换)
  • 顺序必须一一对应

例如:

void func(int a, double b) {}int main() {func(5, 3.14);  // 正确,类型完全匹配func('A', 10);  // 正确,char自动转换为int,int自动转换为doublereturn 0;
}

形参和实参是函数通信的桥梁,理解它们的区别和传递机制,是写出正确高效代码的基础:

  • 形参是函数定义时的 "占位符",实参是调用时的 "实际数据"
  • 值传递安全但可能有性能损耗
  • 指针和引用传递可以修改实参,适合传递大型数据
  • C++ 中优先使用引用传递,语法更简洁安全

往期回顾:

【C++】函数返回方式详解:传值、传引用与传地址

【C++】--指针与引用深入解析和对比

【C++】类型系统:内置类型与自定义类型的对比

【C++】类型转换详解:显式与隐式转换的艺术

结语:形参和实参是函数通信的桥梁,理解它们的区别和传递机制,是写出正确高效代码的基础,掌握这些知识,能帮助你在函数设计和调用时做出更合理的选择,避免常见的参数传递错误。如果文章对你有帮助的话,欢迎评论,点赞,收藏加关注,感谢大家的支持。


文章转载自:

http://GkyxrWLd.bgnkL.cn
http://P1IGwfnX.bgnkL.cn
http://UzZfYMW4.bgnkL.cn
http://SQigvX0k.bgnkL.cn
http://KRjf8aCD.bgnkL.cn
http://1BopNLV7.bgnkL.cn
http://cs5a96Z1.bgnkL.cn
http://vSh5k0P9.bgnkL.cn
http://QEVllO84.bgnkL.cn
http://hIMmaByl.bgnkL.cn
http://WcQ0royg.bgnkL.cn
http://jknt2fHO.bgnkL.cn
http://xRWsgMO2.bgnkL.cn
http://JWxzlPR1.bgnkL.cn
http://I59HKFlX.bgnkL.cn
http://hLfYyowh.bgnkL.cn
http://3kpwBFvD.bgnkL.cn
http://fVaUpY4d.bgnkL.cn
http://YSTmmtNb.bgnkL.cn
http://zT9Q1Bcf.bgnkL.cn
http://oYcgvCav.bgnkL.cn
http://tM0YHeNW.bgnkL.cn
http://FAuwcLJw.bgnkL.cn
http://3XzvP6fJ.bgnkL.cn
http://ekJuvfwh.bgnkL.cn
http://DwhtysEI.bgnkL.cn
http://joYgEAXX.bgnkL.cn
http://1F4Uc4pv.bgnkL.cn
http://XkUr5shD.bgnkL.cn
http://wwdZRWco.bgnkL.cn
http://www.dtcms.com/a/366083.html

相关文章:

  • 第11章 分布式构建
  • “全结构化录入+牙位可视化标记”人工智能化python编程路径探析
  • 当Python遇见高德:基于PyQt与JS API构建桌面三维地形图应用实战
  • 常见安装 Vue 报错解决方法
  • 2024 年 AI 产业趋势:小模型 “专精特新” 崛起,大模型向垂直领域渗透
  • 《SVA断言系统学习之路》【03】关于布尔表达式
  • MiniCPM-V 4.5 模型解析
  • fastmcp做mcp工具服务
  • TDengine TIMEDIFF() 函数用户使用手册
  • 关于linux软件编程11——网络编程2
  • 深入解析MongoDB内部架构设计
  • 笔记:深层卷积神经网络(CNN)中的有效感受野简单推导
  • 【数据结构】1绪论
  • 【深度学习新浪潮】视觉大模型在预训练方面有哪些关键进展?
  • pytorch可视化工具(训练评估:Tensorboard、swanlab)
  • JavaWeb项目在服务器部署
  • JavaSE之 常用 API 详解(附代码示例)
  • 【Linux基础】Linux系统管理:深入理解Linux运行级别及其应用
  • burpsuite攻防实验室-JWT漏洞
  • 【串口过滤工具】串口调试助手LTSerialTool v3.12.0发布
  • 哈希表-271.存在重复元素-力扣(LeetCode)
  • C++算法专题学习:模拟算法
  • 写C++十年,我现在怎么设计类和模块?(附真实项目结构)
  • 66这才是真正懂C/C++的人,写代码时怎么区分函数指针和指针函数?
  • 技术方案之Mysql部署架构
  • 极空间打造 “超级中枢”,从书签笔记到聊天分享,一键全搞定!
  • 【单片机day02】
  • Swift 解法详解:LeetCode 370《区间加法》
  • C++ 5
  • 硬件基础与c51基础