在C和C++中定义main()函数的正确(最有效)方法是什么?int main()或void main()-为什么?那争论呢?如果int main(),则返回1或0?


这个问题有很多重复之处,包括:

C的main()函数的有效签名是什么?main()函数的返回类型void main()和int main()之间的区别?main()在C中的签名++main()的正确声明是什么?-对于C++,确实有一个非常好的答案。C中main()函数的样式C中main()方法的返回类型C中的int main()与void main()

相关:

C++-int main(int argc,char**argv)C++-int main(int argc,char*argv[])char*envp[]作为main()的第三个参数是否可移植?int main()函数必须在所有编译器中返回值吗?为什么C和C++中main()函数的类型留给用户定义?为什么int main(){}编译?C++14中main()的合法定义?


当前回答

这里有一个关于返回代码用法的小演示。。。

当使用Linux终端提供的各种工具时,可以使用返回代码,例如在过程完成后进行错误处理。假设存在以下文本文件myfile:

这是一些示例,以检查grep的工作原理。

执行grep命令时,将创建一个进程。一旦它通过(并且没有中断),它将返回一些介于0和255之间的代码。例如:

$ grep order myfile

如果你这样做

$ echo $?
$ 0

您将获得0。为什么?因为grep找到了匹配项并返回了退出代码0,这是成功退出的通常值。原因可能在于简单检查是否一切正常的布尔性质。对0(布尔值假)的简单否定返回1(布尔值真),这可以在if-else语句中轻松处理。

让我们再次检查它,但不在文本文件中,因此不会找到匹配项:

$ grep foo myfile
$ echo $?
$ 1

由于grep未能将标记“foo”与文件内容匹配,因此返回代码为1(这是发生故障时的常见情况,但如上所述,您有很多值可供选择)。同样,如果我们将其放在简单的布尔上下文中(一切正常与否),则否定1(布尔值为真)会产生0(布尔值假),这同样可以通过if-else语句轻松处理。当涉及布尔值时,任何不是0的值都被视为等同于1(因此,在用于检查是否发生错误的简单if-else语句中,2、3、4等的工作方式与使用1的情况相同)。您可以使用不同的返回值来增加错误状态的粒度。对于成功执行的状态,使用0以外的任何值都被认为是不好的做法(由于上面给出的原因)。

以下bash脚本(只需在Linux终端中键入它)虽然非常基本,但应该能给出一些错误处理的概念:

$ grep foo myfile
$ CHECK=$?
$ [ $CHECK -eq 0] && echo 'Match found'; [ $CHECK -ne 0] && echo 'No match was found'
$ No match was found

在第二行之后,由于“foo”使grep返回1,所以没有任何内容打印到终端,我们检查grep的返回代码是否等于0。第二个条件语句在最后一行回显其消息,因为由于CHECK==1,它是真的。

正如您所看到的,如果您正在调用这个和那个进程,有时需要查看它返回了什么(通过main()的返回值),例如在运行测试时。

其他回答

这里有一个关于返回代码用法的小演示。。。

当使用Linux终端提供的各种工具时,可以使用返回代码,例如在过程完成后进行错误处理。假设存在以下文本文件myfile:

这是一些示例,以检查grep的工作原理。

执行grep命令时,将创建一个进程。一旦它通过(并且没有中断),它将返回一些介于0和255之间的代码。例如:

$ grep order myfile

如果你这样做

$ echo $?
$ 0

您将获得0。为什么?因为grep找到了匹配项并返回了退出代码0,这是成功退出的通常值。原因可能在于简单检查是否一切正常的布尔性质。对0(布尔值假)的简单否定返回1(布尔值真),这可以在if-else语句中轻松处理。

让我们再次检查它,但不在文本文件中,因此不会找到匹配项:

$ grep foo myfile
$ echo $?
$ 1

由于grep未能将标记“foo”与文件内容匹配,因此返回代码为1(这是发生故障时的常见情况,但如上所述,您有很多值可供选择)。同样,如果我们将其放在简单的布尔上下文中(一切正常与否),则否定1(布尔值为真)会产生0(布尔值假),这同样可以通过if-else语句轻松处理。当涉及布尔值时,任何不是0的值都被视为等同于1(因此,在用于检查是否发生错误的简单if-else语句中,2、3、4等的工作方式与使用1的情况相同)。您可以使用不同的返回值来增加错误状态的粒度。对于成功执行的状态,使用0以外的任何值都被认为是不好的做法(由于上面给出的原因)。

以下bash脚本(只需在Linux终端中键入它)虽然非常基本,但应该能给出一些错误处理的概念:

$ grep foo myfile
$ CHECK=$?
$ [ $CHECK -eq 0] && echo 'Match found'; [ $CHECK -ne 0] && echo 'No match was found'
$ No match was found

在第二行之后,由于“foo”使grep返回1,所以没有任何内容打印到终端,我们检查grep的返回代码是否等于0。第二个条件语句在最后一行回显其消息,因为由于CHECK==1,它是真的。

正如您所看到的,如果您正在调用这个和那个进程,有时需要查看它返回了什么(通过main()的返回值),例如在运行测试时。

操作系统可以使用返回值来检查程序是如何关闭的。

返回值0通常意味着大多数操作系统(我无论如何都能想到的操作系统)正常。

当您自己调用进程时,也可以检查它,看看程序是否退出并正确完成。

这不仅仅是一个编程惯例。

在Windows上,如果程序因访问冲突而崩溃,则退出代码将为STATUS_access_violation(0xC0000005)。类似于x86异常导致的其他类型的崩溃。

因此,除了从main返回或传递到exit之外,还有其他东西可以导致退出代码被看到。

返回什么取决于您要对可执行文件执行什么操作。例如,如果您使用带有命令行shell的程序,则需要返回0表示成功,返回非零表示失败。然后,您就可以根据代码的结果在shell中使用带有条件处理的程序。此外,您还可以根据您的解释分配任何非零值,例如,对于严重错误,不同的程序退出点可以终止具有不同退出值的程序,调用shell可以通过检查返回的值来决定要做什么。如果代码不打算与shell一起使用,并且返回的值不会影响任何人,那么可以省略它。我个人使用签名int main(void){..return 0;..}

main()的返回值显示程序如何退出。如果返回值为零,则表示执行成功,而任何非零值都表示执行中出现了问题。