int main()和int main(void)之间的区别?

时间:2012-09-01 05:30:33

标签: c main void

以下内容是什么意思:

int main(void) {...} 

VS

int main() {...}

我认为int main() {...}表示main不接收任何参数(来自命令行),但是:

int main(int argc, char *argv[])

确实

但是int main(void) {...}意味着什么? void 代表什么?

我看了here,但这是一个不同的问题。

9 个答案:

答案 0 :(得分:50)

在C ++中,没有区别。


在C中,差异是值得怀疑的。有人喜欢争辩说后一版本(没有void的版本)在技术上只是一个常见的实现扩展,并且由于标准中的措辞而无法保证按标准工作。但是,该标准明确指出,在函数定义中,一组空参数具有明确定义的行为:该函数不接受任何参数。因此,这种主要定义符合标准中的以下描述:

  

它[main]应该用返回类型int定义,不带参数。

然而,两者之间存在明显差异:即没有void的版本无法为函数提供正确的原型:

// this is OK.
int main()
{
  if (0) main(42);
}

// this requires a diagnostic to be shown during compiling
int main(void)
{
  if (0) main(42);
}

哦,只是为了完成:void在所有函数声明符中都有以下含义:

  

(6.7.6.3p10)void类型的未命名参数作为列表中唯一项的特殊情况指定该函数没有参数。

答案 1 :(得分:6)

在C中,在原型中(不是在C ++中),空参数列表意味着该函数可以使用任何参数(在函数的定义中,它意味着没有参数)。在C ++中,空参数列表表示没有参数。在C中,要获得无参数,必须使用void。有关更好的解释,请参阅this问题。

答案 2 :(得分:4)

在C ++中,函数foo(void)foo()是一回事。但是,在C中它是不同的:foo(void)是一个没有参数的函数,而foo()是一个带有未指定参数的函数。

答案 3 :(得分:3)

在C ++中,没有区别,两者都是相同的。

这两个定义也适用于C,但带有void的第二个定义在技术上被认为更好,因为它明确指出main只能在没有任何参数的情况下调用。 在C中,如果函数签名没有指定任何参数,则意味着可以使用任意数量的参数或没有任何参数调用该函数。例如,尝试编译并运行以下两个C程序(记得将文件保存为.c)。

答案 4 :(得分:2)

首先,托管系统和独立系统允许的内容有所不同,如shown here

对于托管系统,5.1.2.2.1程序启动适用:

  

程序启动时调用的函数名为main。实施宣布否   这个功能的原型。它应该使用返回类型int和no来定义   参数:

int main(void)

...(关于argv / argc等样式的更多文字如下)。

有趣的部分是“没有参数”。 int main()int main (void)当前是等效的,因为它们都是函数声明符并且没有参数。以下适用(6.7.6.3):

  

10 void类型的未命名参数作为列表中唯一项的特殊情况指定该函数没有参数。

     

/ - /

     

14标识符列表仅声明函数参数的标识符。 空   函数声明符中的列表是该函数定义的一部分,用于指定   function没有参数。函数声明符中不属于a的空列表   该函数的定义指定没有关于数量或类型的信息   提供参数.145)

强调我的,粗体文本适用于int main()。文本末尾还有注释145),上面写着“看''未来语言方向''(6.11.6)”:

  

6.11.6函数声明符

     

使用带有空括号的函数声明符(不是prototype-format参数类型声明符)是一个过时的功能。

这就是区别。由于上述原因,作为函数声明符,int main() 错误样式,因为它不能保证在下一版本的C标准中起作用。它被标记为C11中的过时功能。

因此,您应始终在托管系统上使用int main (void),而不要int main(),即使这两种表单目前是等效的。

在C ++中,两种形式都是完全等价的,但int main()是出于主观,美观原因的首选风格(Bjarne Stroustrup这么说......这可能是解释你为什么要做某事的原因。特别的方式)。

答案 5 :(得分:1)

在C ++中,两者之间没有区别,int main()main的合法签名和返回类型。

答案 6 :(得分:0)

Type foo(void)的函数原型与Type foo()完全相同,两者之间没有区别。前者可用于提高可读性。

main一样 - 不论是否接受参数,程序仍然可以通过__argv__argcGetCommandLine或其他平台/其他方式访问命令行信息编译器特定符号。

答案 7 :(得分:0)

我知道线程已经老了,但几年前这个问题困扰了我一段时间,所以我想投入我的半分钱(如果那样)。

除非他们使用va_args,否则我总是将C函数视为具有固定数量的参数而不管上下文。也就是说,我相信主要总是拥有原型:

int main(int argc, char **argv).

即使没有传递参数,该函数在堆栈上也有这些参数,因为main函数没有函数重载。

C确实能够通过假装参数不存在来进行原始重载。在这种情况下,参数仍然传递并且在堆栈上但你永远不会访问它,所以它只是减少了源代码的大小。

说int main()只是意味着我知道函数可能有参数,但我没有使用它们,所以我写了int main()。

说int main(void)表示main CERTAINLY没有参数,并暗示有两种不同的函数原型:

int main(void);
int main(int argc, char **argv);

由于C没有函数重载,这对我来说有点误导,我不信任其中包含main(void)的代码。如果主要不接受任何参数,我不会,在这种情况下,main(void)将完全正常。

注意:在某些实现中,main中有比argc和argv更多的参数,例如env,但这并不会让我感到烦恼,因为我知道我没有明确说那些是唯一的两个参数,但是那些是最小的参数,可以有更多,但不是更少。这与直言不讳地说int main(void)对我大喊大叫,因为这个功能没有参数,这不是真的,因为它确实存在,它们只是被省略了。

这是我的基础代码:

/* sample.c - build into sample. */
#include <stdio.h>

int main(void)
{
    int _argc = *((int *)2686800);
    char ***_pargv = (char ***)2686804;
    int i;

    for (i = 1; i < _argc; ++i) {
        printf("%s ", (*_pargv)[i]);
    }

    return 0;
}

./ sample我明显有参数

该函数显然已将参数传递给它,尽管明确表示它不是通过在函数原型中键入void而不是这样。

如上所述:

  

(6.7.6.3p10)类型为void的未命名参数的特例   列表中只有项目指定该函数没有参数。

因此说函数作为参数有空但实际上在堆栈上有参数是矛盾的。

我的观点是,参数仍然存在,因此明确断言main不存在参数是不诚实的。诚实的方式是说int main(),它没有声明它有多少参数,只有你关心的参数数量。

注意2:_argc,_pargv是系统相关的,要找到你必须通过运行这个程序找到它们的值:

/* findargs.c */
#include <stdio.h>

int main(int argc, char **argv)
{
    printf("address of argc is %u.\n", &argc);
    printf("address of argv is %u.\n", &argv);

    return 0;
}

这些值应该对您的特定系统保持正确。

答案 8 :(得分:0)

在C ++中, int main() int main(void)之间没有区别。
但是在C语言中它们有点不同。
int main()表示可以使用任意数量的参数或不使用任何参数来调用main函数。另一方面, int main(void)表示将在不带任何参数的情况下调用main函数

#include <stdio.h> 
int main() 
{ 
    static int i = 5; 
    if (--i){ 
        printf("%d ", i); 
        main(10); 
    } 
}

输出:4 3 2 1

#include <stdio.h> 
int main(void) 
{ 
    static int i = 5; 
    if (--i){ 
        printf("%d ", i); 
        main(10); 
    } 
} 

它将显示错误。因为在int main(void)中参数为空,但是在程序中我们采用了main(10)(它定义了一些值,而不是void)