为什么`main`不能返回double或String而不是int或void?


38

在许多语言(例如C,C ++和Java)中,main方法/函数的返回类型为voidint,但不具有doubleString。背后的原因可能是什么?

我知道一点我们不能做到这一点,因为它main是由运行时库调用的,它需要某种语法int main()int main(int,char**)所以我们必须坚持下去。

所以我的问题是:为什么要main具有它所拥有的类型签名,而又没有其他类型签名?


15
双返回值意味着什么?字符串返回值什么意思

1
ki知道这没有任何意义。但是还有其他原因和约定吗?
JAVA 2013年

1
我认为这没有任何意义,这是因为普遍选择将0表示正常退出,将0表示为非正常退出。选择int作为具有广泛跨语言兼容性的最简单数据类型。@ delnan
JAVA

@sunny从我在使用类似Unix的操作系统的经验中可以得出的结论,将0用作“正常出口”(0错误),因为与其他整数值相比,它是明确的。由于大多数(并非全部)现代语言都设计为类似于C(如果不是在C的背面设计),并且由于C是用于编写Unix的,所以我说这是KnR的历史决定。
杰米·泰勒

3
@sunny“广泛的跨语言兼容性”不是问题。C和UNIX是串联编写的。许多其他语言返回int的原因是因为它们被设计为在UNIX或类似UNIX的环境中工作。

Answers:


83

的返回值将以一种一致的方式main传递给操作系统(任何操作系统)。操作系统需要知道的信息是“程序是否成功终止,或者出现错误?”

如果这是字符串,则使用不同的语言响应变得困难。Pascal字符串(第一个字节为长度)和FORTRAN字符串(固定,填充为某个值)和C字符串(空终止)的内部结构均不同。这将使向操作系统返回一致的值具有挑战性。假设此问题已解决,您将如何回答操作系统对该程序的疑问?字符串比较充满了错误(“成功”与“成功”),尽管错误对于人类可能更有用,但操作系统或其他程序(shell)则更难处理。即使是字符串本身也存在显着差异-EBCDIC(及其所有代码页)与ASCII。

浮点数和双精度数在整数上没有提供任何附加值,用于将数据传回OS(和Shell)。在大多数情况下,计算机的这些部分都不处理浮点数。双精度数也不是难以计数的,因此很难进行比较。由于无法枚举,他们会报告错误的原因(假设您选择了成功的特定值)。再次,浮点数不一致-8位计算机上的浮点数与16位和32位计算机上的浮点数不同(而且这只是“正常”的-即使在IBM内部,浮点数也未标准化直到1980年代为止,同一制造商的机器之间)。然后,您有了十进制与二进制计算机。浮点值不一致,也无法提供有意义的数据。

实际上,我们只剩下字节和整数作为选项。建立的约定是“ 0”表示成功,而其他任何事情都是错误。整数提供了比字节更多的空间来报告错误。可以枚举(返回1表示XYZ,返回2表示ABC,返回3表示DEF,等等。)或用作标志(0x0001表示失败,0x0002表示失败,0x0003表示此和该失败)。将其限制为一个字节很容易用完标志(只有8个),因此决定使用整数。


2
我认为main由c / c ++运行时库调用,然后os调用它,这也是与我们的代码一起加载并由os @ MichaelT调用的一段代码
JAVA

5
main()在不同的操作系统上以不同的方式被调用。 在C语言中,如何首先调用main()方法?进入这个。

22
我认为,要理解的关键点是main-与任何程序中的其他功能不同-它不是程序员定义的协议的一部分,而是用于与主机(OS)交互的协议。您不会选择它,因为它从来都不是您选择的。在更实际的级别上,UNIX期望一个进程返回一个int,因此C-to-UNIX协议正是这样做的。可以为传递参数提供类似的参数:如果为仅传递数字作为参数(例如,没有命令行)的OS /主机发明了C,则参数将是ints而不是字符串。
2013年

2
IBM将代码页的概念从EBCDIC引入了他们的PC。他们仍然困扰着我们,距IBM 5150推出已有35年了。7位ASCII无需代码页,但是即使在单台计算机上,根据设置,8位字符代码也可以用许多不同的方式解释- -更不用说编码多字节编码的代码页了。因此,它实际上甚至比您在第二段的最后一句中提到的还要糟糕
CVn

@EuroMicelli这实际上是一个非常好的信息,谢谢:)
JAVA

27

好吧,可以

例如,在Plan 9操作系统中使用的C语言方言main通常被声明为一个void函数,但是退出状态通过将字符串指针传递给该exits()函数而返回到调用环境。空字符串表示成功,任何非空字符串表示某种失败。这可以通过main返回char*结果来实现。

并且肯定有可能实现具有floatdouble退出状态的系统。

那为什么int呢?这只是一个惯例问题- 让运行在它们下的操作系统和程序遵守一个共同的惯例具有巨大的价值。

Unix约定使用整数状态码,其中0表示成功,非0表示失败(因为通常只有一种成功方法,但是有多种失败方法)。我不知道该约定是否起源于Unix。我怀疑它来自早期的操作系统。

由于(a)浮点支持并不通用,(b)定义浮点值和错误条件之间的映射更加困难,(c)不同的系统使用不同的浮点,点表示,而(d)只是想象在程序的退出状态中追踪舍入错误的乐趣。另一方面,整数非常适合枚举错误代码。

正如我所提到的,计划9使用字符串,但是这给内存管理,字符编码等带来了一定的复杂性。据我所知,当计划9实现时,这是一个新主意,它并不能替代现有的主意。广泛的惯例。

(顺便说一句,在C ++ main只能返回int,并且void main只有在编译器特别支持的情况下才允许在C 中使用。许多编译器在编写时并不会大声抱怨void main,但这只是一点点夸张地说这是错误的。)


9

main方法返回的值是“退出代码”。调用者应用程序(通常是bash)使用它来测试程序是否按预期结束。返回整数是在操作系统级别执行此操作的最简单方法。Double对于错误代码没有意义,并且在操作系统级别很难维护字符串(没有GC)。


3
为什么字符串需要被垃圾回收而整数不需要?
2013年

4
@Brad,字符串的长度可变,本质上与传回一个可以是一个字符或成千上万个数组的数组相同。动态内存将是一个痛苦,而int是一个相当固定的大小,并不是很难处理。
JB金
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.