我目前正在阅读 c++ 中的功能。它说它们是“使您能够将应用程序的内容划分为可以按您选择的顺序调用的功能单元的工件。函数在被调用时通常会向调用函数返回一个值。”
然后它继续说 main() 被编译器识别为您的 c++ 应用程序的起点,并且必须返回一个 int(整数)。
我不知道“必须返回一个整数”是什么意思。根据我的(极其有限的经验) int main() 是您的应用程序的开始。但是'必须返回一个int'是什么意思?这也与我不理解“通常向调用函数返回值”交织在一起
就像在数学中一样,在 C++ 函数中返回值。C++ 中的所有函数都必须准确指定它们返回的值类型,并且每个函数必须只返回一种类型的东西。在某些情况下,“一种事物”可能是nothing,这在 C++ 中用关键字 表示void
。
每个函数都必须声明它返回的内容。这是通过函数声明完成的。这里有几个例子:
int foo();
void bar();
string baz();
int main();
4个函数声明。 foo
返回 an int
,bar
不返回任何内容,baz
返回 a string
(在 C++ 标准库中声明),并main
返回一个 int。
每个函数不仅必须声明它返回的内容,还必须返回那种类型的东西。如果您的函数返回void
,那么您可以编写:
void bar()
{
return;
}
...或者什么也不做:
void bar()
{
}
如果您的函数返回除 之外的任何内容void
,那么您必须有一个return
返回该类型事物的语句:
int foo()
{
return 42;
}
如果您声明一个函数以返回一种类型的东西,然后尝试返回另一种类型的东西,那么必须有一种方法可以隐式地从您尝试转换的任何内容转换为函数声明返回的内容。如果没有可能的隐式转换,您的程序将无法编译。考虑:
int foo()
{
return "foobar rulez!";
}
在这里,foo
声明返回一个int
,但我试图返回一个字符串(不是string
来自标准库的 a,而是一个旧的 C 风格的const char*
字符串。`"foobar rulez!" 这里称为字符串文字。)
可以编写代码来提供我前面提到的隐式转换,但除非您确切知道为什么要这样做,否则最好不要立即混淆所有这些。
您如何处理从函数返回的值?同样,就像数学一样,您可以在程序的其他地方使用这些值。
#include <cstdlib>
#include <iostream>
int foo()
{
return 42;
}
int main()
{
int answer = foo();
std::cout << "The answer to Life, the Universe and Everything is...\n"
<< answer << "!\n";
return 0;
}
显然,您不能对从返回的函数返回的值做任何事情void
,因为返回的函数void
根本不会真正返回任何东西。但是这些类型的功能对于做一些侧面的事情很有用。
#include <cstdlib>
#include <iostream>
int theAnswer = 0;
void DeepThought()
{
theAnswer = 42;
}
int foo()
{
return theAnswer;
}
int main()
{
DeepThought();
int answer = foo();
std::cout << "The answer to Life, the Universe and Everything is...\n"
<< answer << "!\n";
return 0;
}
好的,回到与main
.
main
是 C++ 中的一个函数。与 C++ 中的其他函数相比,它有一些main
特别之处,其中两点是:
main()
(在全局范围内)。int
还有一件事main
有点特别,可能令人困惑。您实际上不必return
在 * 中编写语句main
,即使它被声明为返回一个int
. 考虑:
int main()
{
}
请注意,这里没有 return 语句。这在 C++ for 中是合法有效的main
,但main
它是唯一允许这样做的函数。return
如果所有其他函数不返回,则它们必须具有显式声明void
。
那么 from 的返回值main()
呢?当您在 Windows 或 Linux 计算机上运行程序时,程序会向操作系统返回一个值。该值的含义取决于程序,但一般来说,值0
意味着程序可以正常运行。一个非0
经常的值意味着程序没有工作,而确切的值实际上是出错的代码。
脚本和其他程序可以使用这些返回值来决定下一步要做什么。例如,如果您编写了一个程序来根据艺术家和曲目编号重命名 MP3 文件,那么您的程序可能会返回0
,如果它工作,1
如果它无法确定艺术家,2
如果它无法确定曲目数字。您可以在重命名然后移动文件的脚本中调用此函数。如果您希望脚本在重命名文件时出现错误而退出,那么它可以检查这些返回值以查看它是否有效。
main
main
:在没有显式的情况下,return
定义为返回值0
。尽管在使用 C 或 C++ 编程时可能会出现这种情况,main
但实际上并不是发生的“第一件事”。通常,在 C 或 C++ 运行时库的内部某处是对 的调用main
,它会启动您的程序。当你的程序完成并从 中返回时main
,它会返回一个值(在 C++ 中,如果你不指定某些东西,编译器会自动添加return 0
),这个返回值用于表示程序“成功”。
在 Unix/Linux 等中,它用作$?
,因此您可以echo $?
在运行程序后查看“结果”是什么 - 0 表示“顺利”,其他值用于“失败”。在windows中,批处理脚本等中有一个ERRORLEVEL
变量,可以用来查看最后一个命令的结果。
编辑:如果您的代码调用另一个程序,例如通过 Windows 中的 CreatProcess 或fork()/exec()
Unix 风格的操作系统(或spawn
几乎任何操作系统中的 C 运行时函数和同级),则返回值main
是新进程完成,并可供拥有过程。结束编辑。
因为,即使在 C++ 中,main
它也是一个“C”风格的函数,如果你改变返回类型,它仍然有相同的名字,所以链接器/编译器不能“检测”它有错误的返回类型,而且有些奇怪如果您声明void main()
,std::string main()
或者float main()
其他事情会发生int main()
- 它仍然会编译,但代码调用中发生的事情main
将是未定义的行为 - 这意味着“几乎任何事情都可能发生”。
是的,main
应该总是返回一个int
,这可以用来显示程序是否运行成功,通常0
代表成功,非零值代表某种失败。
例如,在 Linux 中,您可以在 bash 脚本中调用您的程序,并在此脚本中针对程序的返回状态运行不同的命令。
这意味着,在main()
返回类型的签名中是int
:
int main();
int main(int argc, char const *argv[]);
现在,您将从中返回什么值main()
,这是个问题。好吧,返回值实际上是退出状态,它向运行时指示main()
执行成功还是失败。
在 Linux 中,我通常返回EXIT_SUCCESS
或EXIT_FAILURE
视情况而定。这些是由 定义的宏<cstdlib>
。
int main()
{
//code
if ( some failure condition )
return EXIT_FAILURE;
//code
return EXIT_SUCCESS;
}
根据文档:
#define EXIT_SUCCESS /*implementation defined*/
#define EXIT_FAILURE /*implementation defined*/
EXIT_SUCCESS 和 EXIT_FAILURE 宏扩展为一个完整的表达式并指示程序执行状态。
Constant Explanation EXIT_SUCCESS successful execution of a program EXIT_FAILURE unsuccessful execution of a program
这是您向操作系统报告程序退出状态的方式,无论它是否成功运行。例如在 Linux 中,您可以使用以下命令:
echo $?
获取之前运行的程序的退出状态。