1. 为什么我们需要区分形参和实参
记得刚学C++那会儿,我经常在函数调用时搞混这两个概念。直到有次调试一个排序算法,花了整整三小时才发现是传参方式搞错了——本该修改原数组的地方,因为参数传递理解错误,导致排序结果根本没保存。这个惨痛教训让我深刻认识到:理解形参和实参的区别,是写出正确C++代码的基本功。
形参(formal parameter)是函数定义时声明的变量,它们就像是函数门口的接待员,负责接收外界传递的信息。而实参(actual argument)则是调用函数时真正传入的具体值或变量,相当于来访的客人。举个例子:
cpp复制void greet(string name) { // name是形参
cout << "Hello, " << name << "!";
}
int main() {
greet("Alice"); // "Alice"是实参
return 0;
}
这里最容易混淆的是:形参只在函数内部有效,是函数的局部变量;而实参则是函数调用时存在的具体数据。它们之间的关系就像快递单和实际包裹——形参是快递单上的收件人信息栏,实参是你实际要寄的那个包裹。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 形参与实参的核心区别解析
2.1 内存分配时机与生命周期
形参的内存分配发生在函数被调用时,函数执行结束后立即释放。这就像会议室预订——会议开始前才安排座位,结束后立即收回。而实参的生命周期取决于它原本的作用域。
cpp复制void process(int x) { // x的内存在此分配
// 使用x...
} // x的内存在此释放
int main() {
int value = 42; // value的生命周期持续到main结束
process(value); // value作为实参传入
return 0;
}
2.2 传递方式的本质差异
C++中默认使用值传递(pass by value),这意味着形参得到的是实参的副本。修改形参不会影响原始实参:
cpp复制void tryChange(int num) {
num = 100; // 只修改了副本
}
int main() {
int original = 5;
tryChange(original);
cout << original; // 仍然输出5
}
但如果是引用传递(使用&符号),形参就成为实参的别名,修改形参直接影响实参:
cpp复制void reallyChange(int &num) {
num = 100; // 修改了原始变量
}
int main() {
int original = 5;
reallyChange(original);
cout << original; // 输出100
}
2.3 类型匹配的严格要求
C++对形参和实参的类型匹配要求严格。即使可以隐式转换的类型,有时也需要显式转换:
cpp复制void print(double d) {
cout << d;
}
int main() {
int
