首页 > 编程笔记

C++函数的形参和实参(入门必读)

如果把函数比喻成一台机器,那么参数就是原材料,返回值就是最终产品。从一定程度上讲,函数的作用就是根据不同的参数产生不同的返回值。

在 C++ 中,函数的参数会出现在三个地方,分别是函数声明处、函数定义处和函数调用处。

函数声明和定义时出现的参数,可以看做是一个占位符,它们没有数据,只能等到函数被调用时接收传递进来的数据,所以称为形式参数,简称形参。

函数调用处传入的参数,包含了实实在在的数据,会被函数内部的代码使用,所以称为实际参数,简称实参。

举个简单的例子:
#include <iostream>
// 函数声明处
int addNum(int a, int b);
int main()
{
    // 函数调用处
    int sum = addNum(3, 5);
    std::cout << sum << std::endl;
    return 0;
}

// 函数定义处
int addNum(int a, int b)
{
    int c = a + b;
    return c;
}
addNum() 声明和定义处的 a 和 b,它们都是形参;addNum() 调用处的 3 和 5,它们都是实参。

形参和实参是相对的概念,有时会相互转化。再看一个例子:
int addNum(int a, int b)
{
    int c = a + b;
    return c;
}

void outputSum(int a, int b) {
    int num = addNum(a, b);
    std::cout << num << std::endl;
}
outputSum() 函数的参数 a 和 b 都是形参,该函数内调用了 addNum() 函数,并将 a 和 b 传递给了 addNum() 函数。对于 addNum() 函数而言,传递给它的 a 和 b 都是实参。

总结一下,函数的参数分为形参和实参,函数声明和定义处的参数是形参,函数调用处的参数是实参。

值传递

形参和实参的功能是传递数据,发生函数调用时,实参的值会传递给形参。

注意,实参的值传递给形参,本质是将实参的值拷贝一份给形参。也就是说,实参和形参是相互独立的两份数据,这种传递数据的方式称为值传递。

例如:
#include <iostream>

void swap(int a, int b) {
    int temp = a;
    a = b;
    b = temp;
    std::cout << "swap: " << "a=" << a << " b=" << b << std::endl;
}

int main()
{
    int a=3, b=5;
    swap(a, b);
    std::cout << "main: " << "a=" << a << " b=" << b << std::endl;
    return 0; 
}
运行结果为:

swap: a=5 b=3
main: a=3 b=5

在 main() 函数中,将 a 和 b 的值作为实参传递给 swap() 函数。从运行结果可以看出,swap() 函数的内部交换了形参 a 和 b 的值,但 main() 函数中 a 和 b 的值并没有交换。

也就是说,swap() 函数只是交换了两个形参的值,实参的值不受影响,即实参和形参是相互独立的。

参数类型检查

调用函数时,编译器会检查实参与形参的类型是否匹配。如果不匹配,则检查是否存在实参类型到形参类型的隐式类型转换。如果存在,则按照隐式类型转换规则进行转换;否则,编译器就会报告一个编译错误。

例如:
#include <iostream>

void outPut(int a, int b) {
    std::cout << a << " " << b << std::endl;
}

int main()
{
    outPut(1, 1); // 类型匹配
    outPut('a', 'a'); // 将 char 类型转换为 int 类型
    outPut(3.2, 3.8); // 将 double 类型转换为 int 类型
    return 0;
}
运行结果为:

1 1
97 97
3 3

推荐阅读