形参与实参
中等5形参和实参:函数中的“填空格”与“真答案”
当你填快递单时,会在收件人一栏写上“张三”。快递员送包裹时,真正收包裹的人是张三本人。这里的“收件人名字”就像形参,它只是一个占位符,告诉你这里需要填一个名字;而“张三本人”就是实参,是真正实际的值。
在C++函数中,形参和实参就是这种关系。理解它们,你就能看懂函数的“输入口”是怎么回事。
什么是形参?
形参(形式参数)是在定义函数时写在括号里的变量。它没有具体的值,只是告诉编译器:“这个函数将来需要接收几个数,每个数是什么类型”。形参就像一张表格里预留的空格,等你往里填内容。
// 函数定义:形参 width 和 height 都是 double 类型,目前没有具体数值
double rectangleArea(double width, double height) {
return width * height;
}
width和height是形参,它们存在于函数定义的那一行的括号里。- 在函数内部,你可以使用形参的名字进行计算,就像使用普通变量一样。
- 形参只在函数内部有效,函数执行完毕就会消失。
生活类比:就像数学公式 面积 = 长 × 宽 中的“长”和“宽”,它们代表未知数,等着你代入具体的数字。
什么是实参?
实参(实际参数)是在调用函数时真正传给函数的数值或变量。实参就是快递单上“张三本人”那个具体的收货人。例如:
double length = 5.0, width = 3.0;
// 调用函数:传入两个实参 length 和 width(它们的值是 5.0 和 3.0)
double area = rectangleArea(length, width);
cout << area << endl; // 输出 15
// 也可以直接传数字(字面量)
cout << rectangleArea(7.2, 4.5) << endl; // 输出 32.4
length和width是变量,调用时它们的值复制给形参。7.2和4.5是字面量,也是实参。- 实参可以有任意多个,只要类型和数量与形参一一对应。
形参和实参的“复制”关系
当函数被调用时,实参的值会复制一份给对应的形参。就像你把快递单上的名字写下来,快递员拿着单子去找那个人,而不是把单子本身给那个人。所以:
- 形参得到了实参的副本。
- 在函数内部修改形参,不会影响函数外部的实参(除非用引用,那是后话)。
看这个例子:
#include <iostream>
using namespace std;
void changeValue(int x) { // 形参 x
x = 100; // 修改形参
cout << "函数内部 x = " << x << endl;
}
int main() {
int num = 5; // 实参 num = 5
cout << "调用前 num = " << num << endl; // 输出 5
changeValue(num); // 把 num 的值(5)复制给 x
cout << "调用后 num = " << num << endl; // 输出 5(没变!)
return 0;
}
输出:
调用前 num = 5
函数内部 x = 100
调用后 num = 5
你看,num 的值并没有变成 100,因为函数修改的是形参 x 的副本,实参 num 自己还是原来的 5。这就像你叫“张三”去帮你拿快递,但快递员把包裹给了另一个也叫“张三”的人,真正的你还是没拿到。
生活中的更多例子
例子1:计算零花钱中的“折扣价”
假设你每天有零花钱 allowance 元,妈妈对你买零食的总价打九折(乘以0.9)。写一个函数:
double discountPrice(double original) { // 形参 original
return original * 0.9; // 九折
}
int main() {
double myMoney = 20.0; // 我有20元零花钱,实参
double afterDiscount = discountPrice(myMoney); // 20 复制给 original
cout << "打折后价格:" << afterDiscount << "元" << endl; // 输出18
return 0;
}
例子2:考试平均分
老师让你写一个函数,计算两门课成绩的平均分。形参是 score1 和 score2,调用时传入你的数学和语文分数。
double average(double a, double b) { // 形参 a, b
return (a + b) / 2.0;
}
int main() {
double math = 95.5, chinese = 88.0; // 实参
double avg = average(math, chinese);
cout << "平均分 = " << avg << endl; // 输出 91.75
return 0;
}
新手常见的错误
❌ 错误1:形参和实参名字混用
新手容易在函数内部使用实参的变量名,以为可以自动访问外部的变量。
void add(int a, int b) {
// 错误:函数内部不能直接使用 main() 里的变量 x 和 y,除非它们是全局变量
// int sum = x + y; // ❌ x 和 y 未定义
int sum = a + b; // ✅ 应该用形参
}
正确做法:只使用形参名字,不要幻想外部的变量名会自动传进来。
❌ 错误2:实参个数或类型不匹配
形参有3个,调用时只传2个——编译报错。或者传入一个 double 给 int 形参,可能会导致精度丢失,但一般能自动转换(不过最好类型一致)。
int add(int a, int b) { return a + b; }
int main() {
cout << add(3); // ❌ 编译错误:缺少一个实参
cout << add(3.5, 2.1); // ✅ 但自动转换:3.5变成3,2.1变成2,结果5(丢失小数)
return 0;
}
❌ 错误3:以为修改形参能改变实参
就像我们前面展示的,新手可能写了这样的代码,期待 x 被修改:
void doubleValue(int n) {
n = n * 2; // 形参 n 被改了,但调用者的变量不变
}
int main() {
int score = 80;
doubleValue(score);
cout << score; // 仍然是 80,不是 160
return 0;
}
如果不理解“值传递”,就会困惑。记住:形参是实参的复印件,不是原件。
❌ 错误4:函数定义时忘记写形参类型
void print(double x, y) { // ❌ y 没有类型,编译错误
cout << x << " " << y;
}
每个形参都必须单独声明类型,即使类型相同也不能省略。
完整可运行的示例:计算长方体的体积
下面是一个完整的程序,包含函数定义、多次调用,演示形参和实参的关系。
#include <iostream>
using namespace std;
// 计算长方体体积,形参:长、宽、高
double boxVolume(double length, double width, double height) {
// 在函数内部,length/width/height 是形参,可以自由使用
double volume = length * width * height;
return volume;
}
int main() {
// 定义三个实参(变量)
double box1_len = 2.0; // 长
double box1_wid = 3.0; // 宽
double box1_hei = 4.0; // 高
// 调用函数,实参是三个变量
double v1 = boxVolume(box1_len, box1_wid, box1_hei);
cout << "第一个盒子体积 = " << v1 << endl; // 输出 24
// 直接用数字做实参
double v2 = boxVolume(5.0, 6.0, 7.0);
cout << "第二个盒子体积 = " << v2 << endl; // 输出 210
// 混合使用(变量+字面量)
double v3 = boxVolume(box1_len, 10.0, 2.5);
cout << "第三个盒子体积 = " << v3 << endl; // 输出 2*10*2.5 = 50
// 验证:形参修改不影响实参(如果我们在函数内部修改形参,不会影响外面的变量)
// 但这里没有修改,所以没问题
return 0;
}
运行结果:
第一个盒子体积 = 24
第二个盒子体积 = 210
第三个盒子体积 = 50
你可以看到,每次调用传进来的实参值不同,函数就用这些值做不同的计算。
相关知识点指引
- 函数的定义和声明:形参只在函数定义中起作用。
- 返回值:函数通过
return把计算结果传回给调用处。 - 变量作用域:形参是局部变量,仅在函数内部有效。
- 引用参数:C++ 还有一种
&引用,可以让形参直接绑定实参(不复制),此时修改形参就会修改实参——那是更高级的技巧。 - 默认参数:可以在函数定义中给形参默认值,调用时可以不传对应实参。
明白了形参和实参,你就能写出更灵活的函数,把重复的代码“打包”起来,随时调用。动手试试吧!
例题精讲
下列关于形参与实参的说法,正确的是( )。
在C++中,函数的值传递方式下,形参和实参占用不同的内存单元。
以下程序执行后输出的结果是5。请在空白处填入一条语句,使输出结果不受影响(即仍为5)。
#include <iostream>
using namespace std;
void modify(int x) {
___;
}
int main() {
int a = 5;
modify(a);
cout << a;
return 0;
}设有函数定义:void f(int n) { n += 5; } 执行如下代码后,变量x的值是( )。 int x = 10; f(x); cout << x;
在C++函数调用中,实参和形参的名称可以相同。