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

【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; // 仍然输出10 return 0; }

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

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

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

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

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

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

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

void increment(int& num) { // &表示引用 num++; // 直接修改实参 cout << "函数内:" << num << endl; // 输出11 } int main() { int a = 10; increment(a); // 直接传递变量 cout << "函数外:" << a << endl; // 输出11 return 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自动转换为double return 0; }

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

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

往期回顾:

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

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

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

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

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

Read more

《C++ 动态规划》第001-002题:第N个泰波拉契数,三步问题

《C++ 动态规划》第001-002题:第N个泰波拉契数,三步问题

🔥个人主页:Cx330🌸 ❄️个人专栏:《C语言》《LeetCode刷题集》《数据结构-初阶》《C++知识分享》 《优选算法指南-必刷经典100题》《Linux操作系统》:从入门到入魔 《Git深度解析》:版本管理实战全解 🌟心向往之行必能至 🎥Cx330🌸的简介: 目录 前言: 01.第N个泰波拉契数 算法原理(动态规划): 思路: 解法代码(C++): 博主手记(字体还请见谅哈): 02.三步问题 算法原理(动态规划): 思路: 解法代码(C++): 博主手记(字体还请见谅哈): 结尾: 前言: 聚焦算法题实战,系统讲解三大核心板块:“精准定位最优解”——优选算法,“简化逻辑表达,系统性探索与剪枝优化”——递归与回溯,“以局部最优换全局高效”——贪心算法,讲解思路与代码实现,帮助大家快速提升代码能力 01.

By Ne0inhk
【C++】AVL树的底层以及实现

【C++】AVL树的底层以及实现

个人主页 文章目录 * ⭐一、AVL树的概念 * 🎉二、AVL树的性质 * 🏝️三、AVL树的实现 * 1. 树的基本结构 * 2. 树的插入 * 3. 树的旋转 * • 左单旋 * • 右单旋 * • 左右双旋 * • 右左双旋 * 🎡四、AVL树的其它功能 * 1. 树的查找 * 2. 树的遍历 * 3. 树的高度 * 4. 树的大小 * 🚀五、总结 * 1. AVL树的优缺点 * 2. 完整代码 ⭐一、AVL树的概念 AVL树是一种高度平衡的平衡二叉树,相比于搜索二叉树,它的特点在于左右子树都为AVL树且树的高度差的绝对值不超过1。 这里我们会引入一个新的概念叫做平衡因子。平衡因子也就是左右子树的高度差,我们可以通过平衡因子方便我们后续去观察和控制树是否平衡。 🎉二、AVL树的性质 AVL树主要有三大性质: 1.每棵树的左右子树都是AVL树。 2.左子树和右子树的高度之差的绝对值不超过1。 3.

By Ne0inhk
Java选择结构全解析:if与switch实战

Java选择结构全解析:if与switch实战

1.选择结构:根据条件,选择执行某一部分代码 (1).单分支if选择结构 执行规则:判断条件,如果条件为true,执行{}中的代码块m,执行完代码块结束if结构,继续往下执行if结构后面的代码,如果条件为false,直接跳过if结构,执行if结构后面的代码。注意事项:条件不管是多么简单还是多么复杂,结果都只能是一个布尔值,要么为true,要么为false。 import java.util.Scanner; public class Demo12 { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.println("请输入一个整数"); int num = scanner.nextInt(

By Ne0inhk
拒绝重复造轮子:利用自定义注解封装POI,实现Java通用Excel解析

拒绝重复造轮子:利用自定义注解封装POI,实现Java通用Excel解析

基于 SSM + Vue 的 POI Excel 导入导出全流程实现 本文详细讲解基于 SSM(Spring + SpringMVC + MyBatis)后端与 Vue + Element UI 前端的 Excel 导入导出功能实现。通过自定义注解的方式,实现通用的 POI 操作流程。 1. 环境准备与依赖引入 首先需要在项目的 pom.xml 中引入 Apache POI 及相关工具类的依赖。 <!-- POI 核心依赖(支持 .xls 格式 - Office 2003) --><dependency><groupId>

By Ne0inhk