C++函数返回值

在返回值的函数内部,我们使用return 语句来指示返回给调用者的特定值。函数返回的具体值称为返回值。当执行return语句时,函数立即退出,并且返回值从函数复制回调用者。这个过程称为按值返回。

在C++中,函数可以返回一个值,这个值被称为函数的返回值。函数的返回值可以是任何合法的数据类型,包括基本数据类型(如整数、浮点数、字符等)和用户自定义的数据类型(如结构体、类对象等)。

考虑以下程序:

#include <iostream>

int main()
{
	// get a value from the user
	std::cout << "Enter an integer: ";
	int num{};
	std::cin >> num;

	// print the value doubled
	std::cout << num << " doubled is: " << num * 2 << '\n';

	return 0;
}

这个程序由两个概念部分组成:首先,我们从用户那里获取一个值。然后告诉用户这个值的两倍是多少。

虽然这个程序很简单,我们不需要将它分成多个函数,但如果我们想要呢?从用户那里获取一个整数值是一个明确定义的任务,我们希望我们的程序执行这个任务,因此可以编写一个函数来实现。

那么让我们编写一个程序来执行此操作:

// This program doesn't work
#include <iostream>

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

int main()
{
	getValueFromUser(); // Ask user for input

	int num{}; // How do we get the value from getValueFromUser() and use it to initialize this variable?

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

	return 0;
}

这个程序是一个不错的尝试,但还不够完善。

当调用 getValueFromUser 函数时,用户会如预期地被要求输入一个整数。但是当 getValueFromUser 结束并控制返回到 main 时,用户输入的值丢失了。变量 num 永远不会被初始化为用户输入的值,因此程序总是打印出答案 0。

我们需要的是一种方式,让 getValueFromUser 将用户输入的值返回给 main,以便 main 可以使用该数据。

返回值

当您编写用户定义的函数时,您需要确定您的函数是否会将值返回给调用者。要将值返回给调用者,需要做两件事。

首先,您的函数必须指示将返回什么类型的值。这是通过设置函数的返回类型来完成的,返回类型是在函数名称之前定义的类型。在上面的示例中,函数getValueFromUser的返回类型为void(意味着不会向调用者返回任何值),而函数main的返回类型为(意味着将向调用者返回int类型的值)。int请注意,这并不能确定返回什么具体值——它只确定将返回什么类型的值。

其次,在返回值的函数内部,我们使用return 语句来指示返回给调用者的特定值。函数返回的具体值称为返回值。当执行return语句时,函数立即退出,并且返回值从函数复制回调用者。这个过程称为按值返回

让我们看一个返回整数值的简单函数,以及调用它的示例程序:

#include <iostream>

// int is the return type
// A return type of int means the function will return some integer value to the caller (the specific value is not specified here)
int returnFive()
{
    // the return statement indicates the specific value that will be returned
    return 5; // return the specific value 5 back to the caller
}

int main()
{
    std::cout << returnFive() << '\n'; // prints 5
    std::cout << returnFive() + 2 << '\n'; // prints 7

    returnFive(); // okay: the value 5 is returned, but is ignored since main() doesn't do anything with it

    return 0;
}

输出:

5
7

执行从 的顶部开始main。在第一个语句中,对函数调用returnFive进行求值,从而导致函数returnFive被调用。函数将 backreturnFive的具体值返回5给调用者,然后通过 打印到控制台std::cout

在第二次函数调用中,对函数调用returnFive进行求值,这导致函数returnFive被再次调用。函数returnFive将返回值返回5给调用者。计算表达式5 + 2以产生结果7,然后通过 打印到控制台std::cout

returnFive在第三个语句中,再次调用函数,导致值5返回给调用者。但是,函数main对返回值不执行任何操作,因此不会发生进一步的情况(返回值被忽略)。

注意:除非调用者通过将返回值发送到控制台,否则不会打印返回值std::cout。在上面的最后一种情况下,返回值没有发送到std::cout,因此没有打印任何内容。

修复本课开头介绍的程序

#include <iostream>

int getValueFromUser() // this function now returns an integer value
{
 	std::cout << "Enter an integer: ";
	int input{};
	std::cin >> input;

	return input; // return the value the user entered back to the caller
}

int main()
{
	int num { getValueFromUser() }; // initialize num with the return value of getValueFromUser()

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

	return 0;
}

当该程序执行时,中的第一条语句main将创建一个int名为 的变量num。当程序进入初始化时num,它会看到有一个函数调用getValueFromUser(),因此它将执行该函数。函数getValueFromUser,要求用户输入一个值,然后将该值返回给调用者 ( main)。该返回值用作变量 的初始化值num

回顾 main()

现在,您具备了理解主函数(main)实际工作原理的概念工具。当程序被执行时,操作系统会调用 main 函数。然后,执行会跳转到 main 的顶部。main 中的语句按顺序执行。最后,main 返回一个整数值(通常是0),您的程序终止。main 返回的值有时称为状态码(有时也称为退出码,或极少数情况下称为返回码),因为它用于指示程序是否成功运行。

根据定义,状态码为0意味着程序成功执行。

没有返回值的返回值函数将产生未定义的行为

有返回值的函数称为返回值函数。如果返回类型不是 ,则函数是有返回值的void

返回值函数必须返回该类型的值(使用 return 语句),否则将导致未定义的行为。

下面是一个产生未定义行为的函数示例:

#include <iostream>

int getValueFromUserUB() // this function returns an integer value
{
 	std::cout << "Enter an integer: ";
	int input{};
	std::cin >> input;

	// note: no return statement
}

int main()
{
	int num { getValueFromUserUB() }; // initialize num with the return value of getValueFromUserUB()

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

	return 0;
}

编译器生成警告,因为getValueFromUserUB被定义为返回int但未提供 return 语句。运行这样的程序会产生未定义的行为,因为getValueFromUserUB()是一个不返回值的返回值函数。

在大多数情况下,编译器会检测您是否忘记返回值。但是,在某些复杂的情况下,编译器可能无法正确确定您的函数是否在所有情况下都返回值,因此您不应依赖于此。

如果没有提供 return 语句,函数 main 将隐式返回 0

返回值函数必须通过 return 语句返回值的规则的唯一例外是main()函数。如果没有提供 return 语句,该函数main()将隐式返回0。也就是说,最好的做法是从 main 显式返回一个值,既可以显示您的意图,也可以与其他函数保持一致(如果未指定返回值,它将表现出未定义的行为)。

函数只能返回单个值

返回值函数每次调用时只能将单个值返回给调用者。

请注意,return 语句中提供的值不必是文字 – 它可以是任何有效表达式的结果,包括变量,甚至是对另一个返回值的函数的调用。在getValueFromUser()上面的示例中,我们返回一个变量input,其中保存用户输入的数字。

有多种方法可以解决函数只能返回单个值的限制,我们将在以后的课程中介绍这一点。

函数重用

现在我们可以举例说明函数重用的一个很好的例子。考虑以下程序:

#include <iostream>

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

	int y{};
	std::cout << "Enter an integer: ";
	std::cin >> y;

	std::cout << x << " + " << y << " = " << x + y << '\n';

	return 0;
}

虽然这个程序可以工作,但它有点多余。事实上,这个程序违反了良好编程的核心原则之一:不要重复自己(通常缩写为DRY)。

为什么重复的代码不好?如果我们想将文本“Enter an integer:”更改为其他内容,我们必须在两个位置更新它。如果我们想初始化 10 个变量而不是 2 个怎么办?这将是大量冗余代码(使我们的程序变得更长且更难理解),并且有很大的空间出现拼写错误。

让我们更新这个程序以使用我们getValueFromUser上面开发的函数:

#include <iostream>

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

	return input;
}

int main()
{
    int x{ getValueFromUser() }; // first call to getValueFromUser
    int y{ getValueFromUser() }; // second call to getValueFromUser

    std::cout << x << " + " << y << " = " << x + y << '\n';

    return 0;
}

输出:

Enter an integer: 5
Enter an integer: 7
5 + 7 = 12

在这个程序中,我们调用了getValueFromUser两次,一次初始化变量x,一次初始化变量y。这使我们不必重复代码来获取用户输入,并减少出错的可能性。

这是模块化编程的本质:能够编写一个函数,测试它,确保它工作,然后知道我们可以根据需要多次重用它。

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

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

相关推荐

发表回复

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