C++形式参数和实参简介

C++中的函数参数(形式参数)是在函数定义中声明的变量或标识符。它们用于接受函数被调用时传递的值,这些值称为实际参数。实际参数的值将赋给函数定义中对应的形式参数。

在上一课中,我们了解到可以让函数将值返回给函数的调用者。 我们用它来创建一个在此程序中使用的模块化 getValueFromUser 函数:

#include <iostream>

int getValueFromUser()
{
 	std::cout << "Enter an integer: ";
	int input{};
	std::cin >> input;

	return input;
}

int main()
{
	int num { getValueFromUser() };

	std::cout << num << " doubled is: " << num * 2 << '\n';

	return 0;
}

但是,如果我们也想将输出行放入其自己的函数中怎么办?你可以尝试这样做:

#include <iostream>

int getValueFromUser()
{
 	std::cout << "Enter an integer: ";
	int input{};
	std::cin >> input;

	return input;
}

// This function won't compile
void printDouble()
{
	std::cout << num << " doubled is: " << num * 2 << '\n';
}

int main()
{
	int num { getValueFromUser() };

	printDouble();

	return 0;
}

这不会编译,因为函数printDouble不知道标识符num是什么。您可以尝试将 num 定义为函数 printDouble() 内的变量:

void printDouble()
{
	int num{}; // we added this line
	std::cout << num << " doubled is: " << num * 2 << '\n';
}

虽然这解决了编译器错误并使程序可以编译,但程序仍然无法正常工作(它总是打印“0 doubled is: 0”)。这里问题的核心是函数printDouble无法访问用户输入的值。

我们需要某种方法将变量num的值传递给函数printDouble,以便printDouble可以在函数体中使用该值。

形式参数和实际参数

在许多情况下,能够将信息传递正在调用的函数,以便该函数可以使用数据是很有用的。例如,如果我们想编写一个函数来添加两个数字,我们需要某种方法来告诉函数在调用它时要添加哪两个数字。否则,函数怎么知道要添加什么?我们通过函数参数和参数来做到这一点。

函数参数(形式参数)是在函数定义中声明的变量或标识符。函数参数的工作方式与函数内部定义的变量几乎相同,但有一个区别:它们使用函数调用者提供的值进行初始化。

函数参数在函数头中定义,将其放置在函数名称后面的括号之间,多个参数之间用逗号分隔。

以下是具有不同数量参数的函数的一些示例:

// 此函数不接受任何参数
// 它不依赖调用者提供任何信息
void doPrint()
{
    std::cout << "In doPrint()\n";
}

// 此函数接受一个整数参数,命名为x
// 调用者将提供x的值
void printValue(int x)
{
    std::cout << x  << '\n';
}

// 此函数有两个整数参数,一个命名为x,另一个命名为y
// 调用者将提供x和y的值
int add(int x, int y)
{
    return x + y;
}

参数是在进行函数调用时调用者传递函数的值:

doPrint(); // 这个调用没有参数
printValue(6); // 6 是传递给函数 printValue() 的参数
add(2, 3); //2 和 3 是传递给函数 add() 的参数

请注意,多个参数也用逗号分隔。

参数和实参如何协同工作

当调用函数时,函数的所有参数都被创建为变量,并且每个参数的值都被复制到匹配的参数中。这个过程称为按值传递

例如:

#include <iostream>

// 此函数有两个整数参数,一个命名为x,另一个命名为y
// x和y的值由调用者传递
void printValues(int x, int y)
{
    std::cout << x << '\n';
    std::cout << y << '\n';
}

int main()
{
    printValues(6, 7); // 此函数调用有两个参数,分别是6和7

    return 0;
}

当使用参数67调用函数printValues时,将创建printValues的参数x并使用值6进行初始化,并创建printValues的参数y并使用值7进行初始化。

这导致输出:

6
7

请注意,参数的数量通常必须与函数参数的数量匹配,否则编译器将抛出错误。传递给函数的参数可以是任何有效的表达式(因为参数本质上只是参数的初始值设定项,并且初始值设定项可以是任何有效的表达式)。

优化开头的程序

#include <iostream>

int getValueFromUser()
{
 	std::cout << "Enter an integer: ";
	int input{};
	std::cin >> input;

	return input;
}

void printDouble(int value) // This function now has an integer parameter
{
	std::cout << value << " doubled is: " << value * 2 << '\n';
}

int main()
{
	int num { getValueFromUser() };

	printDouble(num);

	return 0;
}

在此程序中,变量num首先使用用户输入的值进行初始化。然后,调用函数printDouble ,并将参数num的值复制到函数printDouble的value参数中。然后函数printDouble使用参数value的值。

使用返回值作为参数

在上面的问题中,我们可以看到变量num仅使用一次,用于将函数getValueFromUser的返回值传输到调用函数printDouble的参数。

我们可以将上面的例子稍微简化如下:

#include <iostream>

int getValueFromUser()
{
 	std::cout << "Enter an integer: ";
	int input{};
	std::cin >> input;

	return input;
}

void printDouble(int value)
{
	std::cout << value << " doubled is: " << value * 2 << '\n';
}

int main()
{
	printDouble(getValueFromUser());

	return 0;
}

现在,我们直接使用函数getValueFromUser的返回值作为函数printDouble的参数!

参数和返回值如何协同工作

通过使用参数和返回值,我们可以创建将数据作为输入的函数,对其进行一些计算,然后将值返回给调用者。

下面是一个非常简单的函数示例,它将两个数字相加并将结果返回给调用者:

#include <iostream>

// add()函数接受两个整数作为参数,并返回它们的和
// 参数x和y的值由调用add()函数的地方确定
int add(int x, int y)
{
    return x + y;
}

// main函数不接受参数
int main()
{
    std::cout << add(4, 5) << '\n'; // 将参数4和5传递给add()函数,并打印结果
    return 0;
}

从main的顶部开始执行。add(4, 5)求值时,调用函数add,参数x初始化为值4,参数y初始化为值5

函数add中的return语句计算x + y以生成值9,然后将其返回到main。然后这个值9被发送到std::cout以打印在控制台上。

输出:

9

以图片形式:

C++形式参数和实参简介

更多示例

让我们看一下更多的函数调用:

#include <iostream>

// 定义一个函数 add(),接受两个整数参数 x 和 y,并返回它们的和
int add(int x, int y)
{
    return x + y;
}

// 定义一个函数 multiply(),接受两个整数参数 z 和 w,并返回它们的乘积
int multiply(int z, int w)
{
    return z * w;
}

int main()
{
    std::cout << add(4, 5) << '\n'; // 在 add() 函数内部,x=4,y=5,所以 x+y=9
    std::cout << add(1 + 2, 3 * 4) << '\n'; // 在 add() 函数内部,x=3,y=12,所以 x+y=15

    int a{ 5 };
    std::cout << add(a, a) << '\n'; // 计算 (5 + 5)

    std::cout << add(1, multiply(2, 3)) << '\n'; // 计算 1 + (2 * 3)
    std::cout << add(1, add(2, 3)) << '\n'; // 计算 1 + (2 + 3)

    return 0;
}

输出:

9
15
10
7
6

第一个陈述很简单。

在第二个语句中,参数是在传递之前进行计算的表达式。在本例中,1 + 2的计算结果为3,因此3被复制到参数x3 * 4 的计算结果为12,因此12被复制到参数yadd(3, 12)解析为15

接下来的一对语句也相对简单:

int a{ 5 };
std::cout << add(a, a) << '\n'; // evaluates (5 + 5)

在这种情况下,调用add() ,其中a的值被复制到参数xy中。由于a 的值为5,因此add(a, a) = add(5, 5),解析为值10

让我们再看这一句:

std::cout << add(1, multiply(2, 3)) << '\n'; // evaluates 1 + (2 * 3)

当执行函数add时,程序需要确定参数xy的值是什么。x很简单,因为我们刚刚向它传递了整数1要获取参数y的值,需要首先计算multip(2, 3)。程序调用multiply并初始化z = 2w = 3,因此multiply(2, 3)返回整数值6。现在可以使用返回值6来初始化y参数添加功能。add(1, 6)返回整数7,然后将其传递给 std::cout 进行打印。

以下语句看起来很棘手,因为提供给add 的参数之一是对add 的另一次调用。

std::cout << add(1, add(2, 3)) << '\n'; // evaluates 1 + (2 + 3)

但这个案例的工作原理与之前的案例完全相同。add(2, 3) 首先解析,导致返回值5。现在它可以解析 add(1, 5),其计算结果为值6,该值被传递到 std::cout 进行打印。

未引用的参数

在某些情况下,您会遇到函数的参数未在函数体中使用的情况。这些称为未引用参数

当函数参数曾经使用过但不再使用时,可能会发生这种情况。

举一个简单的例子:

void doSomething(int count) // 警告:未使用的参数 count
{
    // 这个函数曾经用 count 做些事情,但现在不再使用它了
}

int main()
{
    doSomething(4);
}

就像未使用的局部变量一样,编译器可能会警告该变量count已定义但未使用。

在函数定义中,函数参数的名称是可选的。因此,当函数参数需要存在但函数体中没有使用时,可以简单地省略名称。没有名称的参数称为未命名参数

void doSomething(int) // ok: unnamed parameter will not generate warning
{
}

建议使用注释来记录未命名参数的内容:

void doSomething(int /*count*/)
{
}

原创文章,作者:jkhxw,如若转载,请注明出处:https://www.jkhxw.com/cpp-function-parameters-and-arguments/

(0)
上一篇 2023年10月3日
下一篇 6天前

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注