为什么没有 return 语句的 main 函数返回值 12?
我编写了一个打印表格的程序。我没有在主函数中包含返回语法,但每当我输入 echo $?它显示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);
}
}
我没有写return 12,但每次执行程序时它仍然返回12。
谢谢。
I have written a program that prints a table. I have not included the return syntax in the main function, but still whenever I type echo $? it displays 12.
My source code :
#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);
}
}
I have not written return 12, but still it returns 12 every time I execute the program.
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
正如 swegi 所说,这是未定义的行为。正如 Steve Jessop 等人所说,在 C89 之前它是一个未指定的值,并在 C99 中指定(观察到的行为与 C99 不符)大多数环境中实际发生的情况是最后一个
printf
的返回值留在用于返回值的寄存器中。因此,n == 0 时为 11,如果 n 是一位数,则为 12,两位数 n 为 14,三位数 n 为 16,等等。
As swegi says, it's undefined behavior.As Steve Jessop et al say, it's an unspecified value until C89, and specified in C99 (the observed behavior is non-conformant to C99)What actually happens in most environments is that the return value from the last
printf
is left in the register used for return values.So it'll be 11 for n == 0, 12 if n is one digit, 14 for two digit n, 16 for three digit n, etc.
回答是因为所有现有的答案都说这是未定义的行为,这不是真的,所以我没有什么可以投票的。
在 C89 中(感谢 pmg 参考标准草案),5.1 .2.2.3:
在 C99 中,引用 n1256, 5.1.2.2.3:
因此,这不是“未定义的行为”:它的行为就像
main
函数返回一样,但在 C89 中,返回的值不是由标准指定的。对于您的示例程序,在您的实现中,返回的值似乎始终为 12,大概是出于 Ben Voigt 所说的原因。由于您使用的是 Linux,因此将代码编译为 C99 可能并不是一个大的改变(或者无论如何,使用 gcc 几乎兼容的 C99 模式来编译它)。对于除
main
之外的任何返回值的函数,它是未定义的行为,除非调用者不使用返回值(n1256 ,6.9.1/12):我不确定对
main
的初始调用是否应该被提及为排除在这条一般规则之外。它不需要是:从标准的 POV 来看,该调用没有调用者,所以我认为函数调用的值不是“由调用者使用”,即使它成为终止状态对于该程序。Answering because all the existing answers say that it's undefined behaviour, which is not true, so I have nothing I can upvote.
In C89 (thanks to pmg for the reference to a draft standard), 5.1.2.2.3:
In C99, quoting from n1256, 5.1.2.2.3:
So, it's not "undefined behaviour": it behaves as if the
main
function returns, but in C89 the value returned is not specified by the standard. For your example program, on your implementation, the value returned appears to consistently be 12, presumably for the reason Ben Voigt says. Since you're on linux, it's probably not a big change to compile your code as C99 (or anyway, compile it using gcc's almost-compliant C99 mode).For any function that returns a value, other than
main
, it is undefined behaviour, unless the caller doesn't use the return value (n1256, 6.9.1/12):I'm not sure whether the initial call to
main
should be mentioned as excluded from this general rule. It doesn't need to be: from the POV of the standard, that call doesn't have a caller, so I think that the value of the function call is not "used by the caller", even though it becomes the termination status for the program.如果您非常熟悉汇编语言,您可能还记得函数的“返回值”是通过 EAX 寄存器传递的。
在本例中,返回值是从 EAX 读取的。在本例中,恰好是 12。
但是,您没有显式设置该值,它只是代码其余部分的产物(或者可能只是偶然)。
正如已经说过的,这绝对是
未定义的行为
。如果您只是好奇为什么会出现这种结果,请考虑这个解释。但在任何情况下都不要尝试故意将此值用作任何有意义的值。
If you're at all familiar with assembly language, you may recall that the "return value" of a function is passed through the EAX register.
In this case, the return value is being read from EAX. Which, in this case, happens to be 12.
However, you're not explicitly setting this value, it's simply an artifact from the rest of the code (or perhaps just chance).
As has been said, this is definitely
undefined behavior
. If you are simply curious why this results, please consider this explanation.But do not, under any circumstances, attempt to intentionally use this value as anything meaningful.
您的程序在应该返回任何内容时不返回任何内容,从而导致未定义的行为,因此调用者通常会获取程序返回时 eax 寄存器(在 x86 上,rax 在 x64 上)的值,这通常是垃圾eax 的最后一次使用(通过返回值的函数或仅基于寄存器的变量),在这种情况下,它可能是 printf 写入标准输出缓冲区的字符数量
Your program is causing undefined behavior by not returning anything when it should, thus the caller will generally grab what ever the value of the eax register(on x86, rax on x64) is at the time of the procedure return, which is generally rubbish from the last use of eax(by functions returning values or just register based vars), in this case its probably the amount of char's that printf has written to the stdout buffer