我写了一个打印表格的程序。我没有在main函数中包含返回语法,但每当我输入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);
}
}
我没有写回12,但每次执行程序时它都会返回12。
感谢。
答案 0 :(得分:20)
正如swegi所说,它是未定义的行为。正如Steve Jessop等人所说,它是一个未指定的值,直到C89,并在C99中指定(观察到的行为不符合C99)
在大多数环境中实际发生的事情是,上一个printf
的返回值保留在用于返回值的寄存器中。
因此,对于n == 0,它将是11;如果n是一位数,则为12,对于两位数n为14,对于三位数n为16,等等。
答案 1 :(得分:18)
回答是因为所有现有的答案都表明它是未定义的行为,这是不正确的,所以我没有任何东西可以投票。
在C89中(感谢pmg引用draft standard),5.1.2.2.3:
从初始通话返回到 主要功能是 相当于用值调用exit函数 由main函数返回作为其参数。如果} 到达终止主要功能, 终止状态返回给主机环境 未指定的。
在C99中,引用n1256,5.1.2.2.3:
如果主要的返回类型 function是一种兼容的类型 int,从最初的调用返回到 主要功能相当于 用the调用exit函数 main函数返回的值为 它的论点;达到那个 终止main函数返回一个 值为0.如果返回类型不是 兼容int,终止 状态返回给主机 环境未明确。
因此,它不是“未定义的行为”:它的行为就像main
函数返回一样,但在C89中,返回的值不是由标准指定的。对于您的示例程序,在您的实现中,返回的值似乎始终为12,可能是因为Ben Voigt说。因为你在linux上,所以编译你的代码可能不是一个很大的改变(或者无论如何,使用gcc几乎兼容的C99模式编译它)。
对于除main
以外的任何返回值的函数, 是未定义的行为,除非调用者不使用返回值(n1256) ,6.9.1 / 12):
如果终止函数的}是 达到了,功能的价值 呼叫由呼叫者使用 行为未定义。
我不确定是否应该提及main
的初始调用被排除在此一般规则之外。它不需要:从标准的POV,该调用没有调用者,所以我认为函数调用的值不是“调用者使用”,即使它成为终止状态对于该计划。
答案 2 :(得分:1)
如果您完全熟悉汇编语言,您可能会记得函数的“返回值”是通过EAX寄存器传递的。
在这种情况下,正在从EAX读取返回值。在这种情况下,恰好是12。
但是,你没有明确地设置这个值,它只是来自其余代码的一个工件(或者只是偶然)。
如前所述,这绝对是undefined behavior
。如果您只是好奇为什么会这样,请考虑这个解释。
但在任何情况下都不要试图故意将此值用作有意义的事物。
答案 3 :(得分:0)
你的程序在没有返回任何内容时会导致未定义的行为,因此调用程序通常会在程序返回时获取eax寄存器的值(在x86上,x64上的rax),这是通常从上次使用eax(通过返回值的函数或仅基于寄存器的变量)的垃圾,在这种情况下,它可能是printf写入stdout缓冲区的char的数量