C 语言

关注公众号 jb51net

关闭
首页 > 软件编程 > C 语言 > C++形参和实参

C++中的形参和实参区别解析

作者:草莓熊Lotso

这篇文章主要介绍了C++中的形参和实参区别解析,本文将从定义、特性、传递方式等多个维度深入解析,帮你彻底掌握这对重要概念,需要的朋友可以参考下

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

形参和实参

实参是形参的初始值。第一个实参初始化第一个形参,第二个实参初始化第二个形参以此类推。尽管实参与形参存在对应关系,但是并没有规定实参的求值顺序。编译器能以任意可行的顺序对实参求值。实参的类型必须与对应的形参类型匹配,我们知道初始化过程中初始值的类型也必须与初始化对象的类型匹配。函数有几个形参,我们就须提供相同数量的实参。想要调用成功我们必须提供可以转换成对应类型的实参。

一、基本定义与本质区别

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

// 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++形参和实参内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文