为什么没有返回语句的主函数返回值12?

我写了一个打印表格的程序。 我没有在主函数中包含返回语法,但仍然每当我inputecho $? 它显示12。

我的源代码:

#include <stdio.h> int main(void) { int ans,i,n; printf("enter the no. : "); scanf("%d",&n); for(i=1;i<=10;i++) { ans = n*i; printf("%d * %d = %d\n",n,i,ans); } } 

我没有写回12,但是每次执行程序时都返回12。

谢谢。

Solutions Collecting From Web of "为什么没有返回语句的主函数返回值12?"

正如swegi所说,这是不确定的行为。 正如Steve Jessop等人所说的那样,在C99之前是未指定的行为,并且在C99中指定(观察到的行为与C99不一致)

实际上在大多数环境中发生的情况是,最后一个printf的返回值保留在用于返回值的寄存器中。

所以n == 0将是11,如果n是一个数字,则是12,两个数字n是14,三个数字n是16。

回答是因为所有现有的答案都说这是不确定的行为,这是不正确的,所以我没有什么可以upvote。

在C89中(感谢参考标准草案的 pmg),5.1.2.2.3:

从初始调用返回到主函数相当于以主函数返回的值作为参数调用exit函数。 如果达到了终止主函数的},那么返回到主机环境的终止状态是未指定的。

在C99中,从n1256引用,5.1.2.2.3:

如果main函数的返回类型是与int兼容的类型,则从初始调用返回到main函数的返回值相当于以main函数返回的值为参数调用exit函数。 到达终止main函数的}返回值为0.如果返回类型与int不兼容,则返回到主机环境的终止状态是未指定的。

所以,它不是“未定义的行为”:它的行为就像main函数返回一样,但在C89中,返回的值不是由标准指定的。 对于您的示例程序,在您的实现中,返回的值似乎始终为12,这可能是Ben Voigt说的原因。 因为你在linux上,所以把你的代码编译成C99可能不是一个大的改变(或者,用gcc几乎兼容的C99模式编译它)。

对于任何返回一个非main函数的函数,这未定义的行为, 除非调用者不使用返回值(n1256,6.9.1 / 12):

如果到达终止函数的},并且调用者使用该函数调用的值,则行为是不确定的。

我不确定是否应该提到最初的main呼叫被排除在这个一般规则之外。 它不需要是:从标准的POV,该调用没有调用者,所以我认为函数调用的值不被调用者使用,即使它变成终止状态为节目。

未定义的行为

如果您完全熟悉汇编语言,您可能会记得函数的“返回值”是通过EAX寄存器传递的。

在这种情况下,返回值是从EAX读取的。 在这种情况下,恰好是12。

然而,你没有明确地设置这个值,它只是一个来自其他代码的工件(或者只是偶然的)。

如前所述,这绝对是undefined behavior 。 如果你只是好奇为什么这个结果,请考虑这个解释。

但是,在任何情况下,都不要试图故意使用这个值作为任何有意义的东西。

你的程序通过不返回任何东西而导致不确定的行为,因此调用者通常会抓取eax寄存器的值(在x86上是rax,在x64上),在返回的时候通常是垃圾的eax的最后一个用法(通过函数返回值或只是基于寄存器的变量),在这种情况下,它可能是printf写入stdout缓冲区的char数量