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

发布于 2024-09-19 03:35:50 字数 367 浏览 11 评论 0原文

我编写了一个打印表格的程序。我没有在主函数中包含返回语法,但每当我输入 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

抱猫软卧 2024-09-26 03:35:50

正如 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.

墟烟 2024-09-26 03:35:50

回答是因为所有现有的答案都说这是未定义的行为,这不是真的,所以我没有什么可以投票的。

在 C89 中(感谢 pmg 参考标准草案),5.1 .2.2.3:

从初始调用返回
主要功能是
相当于用该值调用退出函数
由 main 函数作为其参数返回。如果}
到达终止主函数的位置,
返回到主机环境的终止状态是
未指定。

在 C99 中,引用 n1256, 5.1.2.2.3:

如果main的返回类型
函数是兼容的类型
int,从初始调用返回
主要功能相当于
调用退出函数
主函数返回的值如下
它的论点;达到 } 那个
终止主函数返回一个
值为 0。如果返回类型不是
与 int 兼容,终止符
状态返回给主机
环境未指定。

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

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

如果终止函数的 } 是
达到,以及函数的值
call 由调用者使用,
行为未定义。

我不确定对 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:

A return from the initial call to the
main function is
equivalent to calling the exit function with the value
returned by the main function as its argument. If the }
that terminates the main function is reached, the
termination status returned to the host environment is
unspecified.

In C99, quoting from n1256, 5.1.2.2.3:

If the return type of the main
function is a type compatible with
int, a return from the initial call to
the main function is equivalent to
calling the exit function with the
value returned by the main function as
its argument; reaching the } that
terminates the main function returns a
value of 0. If the return type is not
compatible with int, the termination
status returned to the host
environment is unspecified.

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):

If the } that terminates a function is
reached, and the value of the function
call is used by the caller, the
behavior is undefined.

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.

我不吻晚风 2024-09-26 03:35:50

如果您非常熟悉汇编语言,您可能还记得函数的“返回值”是通过 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.

陌路终见情 2024-09-26 03:35:50

您的程序在应该返回任何内容时不返回任何内容,从而导致未定义的行为,因此调用者通常会获取程序返回时 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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文