“return”在C语言中的基本作用是什么?

fnx2tebb  于 2023-01-04  发布在  其他
关注(0)|答案(2)|浏览(131)

直到今天,我对函数返回语句的理解是这样的:
当控制到达函数末尾时,控制返回给调用方(函数),无论函数是否有return语句。

退出时使用ISO C()

在阅读有关终止C程序的内容时,我看到ISO C(7.22.4.4.6)中的一条声明-
exit函数无法返回到其调用方。
这个说法与我以前的理解相矛盾。

ISO C on return语句

因此,我检查了ISO C对return语句的注解(6.8.6.4),发现如下内容:
1.带表达式的return语句不应出现在返回类型为void的函数中。不带表达式的return语句只能出现在返回类型为void的函数中。

  1. return语句终止当前函数的执行并将控制权返回给调用者。一个函数可以有任意数量的return语句。
    我的新结论
    1.“return”语句使宿主环境强制将控制返回给调用者(函数)。
    1.在具有void返回类型的函数的情况下,如果它包含return语句,则主机环境必须将控制返回给调用者(函数)。否则(即,如果return语句不存在),则主机环境可以将控制返回给调用者。
    1.默认情况下,许多实现选择将控制权返回给调用方函数,即使被调用方函数没有return语句,但exit()除外(此异常也可能扩展到其他一些函数)。

我的结论正确吗

km0tfn4u

km0tfn4u1#

你的函数在你的程序内部,它们不是宿主环境的一部分。宿主环境在你的程序外部。在一个普通的通用多用户系统中,宿主环境是操作系统(包括像用于执行程序的命令行shell这样的东西)。
return语句返回到程序内的调用函数。流向函数的结束}的程序控制将控制返回到调用函数。调用exit不会返回到程序内的函数;它会向操作系统发出终止程序的请求(但是,在发出最后一个请求之前,exit可能会执行各种清理工作并调用退出处理程序,因此在程序终止之前,程序中的某些函数可能仍在执行)。

jhdbpxl9

jhdbpxl92#

当然,你从标准中引用的所有内容都是正确的,没有矛盾。

退出()

但是exit()函数的描述与return语句的作用无关,主要是因为它不包含return语句,或者说从来没有到达return语句,也从来没有到达return语句的末尾,而是指示Linux或Windows等操作系统完全停止执行该程序。而程序仍在执行exit函数。这就是exit()从不返回的原因:它只是简单地停止并从内存中删除,与程序的其余部分一起。它不仅不返回;就没有什么可以回去了。

从函数调用和返回

函数调用本质上是跳转到不同的机器码指令,再加上一些细节。例如,我们要跳转的地址被存储起来,这样我们就知道函数结束时要继续到哪里,参数被存储在某个地方,这样被调用的函数就可以访问它们。从函数返回也是跳转到存储的返回地址。再加上一些细节,比如把返回值(如果有的话)放在调用者可以访问它的地方。到达函数的末尾完全等同于命中一个return语句,没有功能上的区别。
“调用”函数的代码以及从函数返回的代码完全由编译器生成,与操作系统无关,这些代码是编译器生成的二进制代码的一部分。

使用操作系统工具

  • 相反,终止程序*是每个操作系统提供给程序的基本服务之一。执行此操作的代码不是程序的一部分,而是Linux或Windows等操作系统的一部分。要使用此类操作系统服务的程序必须使用system calls 2。Windows下的一个此类调用可能是ExitProcess(),这可能是Windows的C标准库的exit()实现在某个时候调用的。因为这将导致Windows停止当前进程,所以exit()中的该代码之后的代码永远不会执行,包括将控制返回给调用函数的任何代码,例如main()

C程序可以在不同操作系统之间移植的原因之一是有一个 Package 器,它可以保护C程序不受任何给定操作系统特性的影响1:标准C库。
如果没有标准库,Windows的C程序将调用ReadFile()ExitProcess(),而Posix程序将调用read()_exit()。将程序从一个操作系统移植到另一个操作系统将需要更改源代码。相反,仅使用标准库的C程序调用fread()exit()(该页面包含Posix平台特定_exit()函数以及标准C库函数exit()的文档)将在具有标准库的C编译器的任何平台上重新编译:适应新的操作系统只需要一次,然后所有程序都可以使用。

你的问题

现在我们能够回答您的问题。
1.不,return语句不会引起与操作系统的任何交互,所有内容都停留在正在运行的进程中,不会使用或释放任何系统资源。3
1.由于return语句或由于到达函数末尾而返回是完全等效的。生成的代码是exactly equivalent。在这两种情况下,都必须将控制流返回到调用函数。(exit()函数不返回的原因是它在到达其end或return语句之前终止了进程。如果它确实到达了其中之一,它将返回并且调用者将继续执行)。
1.这一点已在上一段作了回答;只是澄清一下:当到达函数末尾时,一致性实现不能自由地选择返回或不返回调用者;它总是必须这样做。exit()函数永远不会到达它的结尾。
1值得注意的是,操作系统本身已经提供了标准化层:每个使用Windows API的程序都可以使用ReadFile(),而与特定计算机上使用的特定文件系统和I/O芯片组无关。C标准库是这些抽象层之上的一个抽象/标准化层。
2我在这里使用“系统调用”作为“本机OS API中的函数”时有点松散。
3除非函数在单独的任务中执行,这完全是另一回事。

相关问题