2012-09-01 174 views
50

什么下列平均:int main()和int main(void)之间的区别?

int main(void) {...} 

VS

int main() {...} 

我认为int main() {...}意味着主要不接收任何参数(来自命令行),但是:

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

一样。

int main(void) {...}是什么意思? void代表什么?

我看了here但它是某种不同的问题。

+0

C99和C11不再提及'int main()'。只需使用'int main(void)'。请参阅标准的5.1.2.2.1“程序启动”:http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf – superlukas

回答

47

在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类型的未命名参数的特殊情况下,在列表中唯一项目指定函数没有对米。

+2

在你的第一个例子中,'main(42);'是什么意思(你写了什么'//这是好的')? – ron

+1

这是一个函数调用('main'带有'42'的单个int参数)。 –

+7

是的,但它有什么作用?这是我第一次在main()中看到main()的调用。 – ron

1

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

0

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

main - 以参数或不是,程序仍然可以通过其他方式访问的命令行信息等__argv__argc,​​,或其他平台/编译器的特定符号。

+4

正确的C++,对C不正确。在C ,给定一个定义'void foo(){}',调用'foo(42)'具有未定义的行为;给定一个定义'void foo(void){}',调用'foo(42)'是违反约束的。 –

+0

我没有说什么反对! – Ajay

+3

是的,你做到了。你说他们完全一样。他们不是。 –

6

在C中,在原型(未在C++虽然)一个空的参数列表意味着函数可以采取任何参数(在一个函数的定义,这意味着无参数)。在C++中,一个空的参数列表意味着没有参数。在C中,要获取任何参数,您必须使用void。有关更好的解释,请参阅this问题。

+0

仅当声明符不是函数定义的一部分时才适用。 –

+0

@ eq-:对不起,但这意味着它仅适用于与实施分开的情况吗?所以它适用于'int foo(void); int foo(void){}'但不是'int foo(void){}'? – Linuxios

+1

在C中,'int foo();'没有指定关于函数​​参数的任何内容,而'int foo(){}'指定'foo'不带任何参数。 –

4

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

+1

你错过了点(C)。在一个定义中'int foo(){}'声明一个没有参数的函数。 –

+1

@JensGustedt in C,in a definition,'int foo(){}'实际上*定义了一个没有参数的函数,但它声明了一个函数,它接受了一个未指定数量的参数。 – RastaJedi

3

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

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

2

首先,托管系统和独立系统允许的区别是shown here

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

称为在程序启动的功能被命名为主力。该实现声明不具有此功能的原型 。它应为int的返回类型和不带 参数来定义:

int main(void) 

...(更多全文如下有关的argv/argc个等样式)。

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

10类型为void的未命名参数的特例是列表中唯一的项目,它指定该函数没有参数。

/-/

14的标识符列表只声明函数的参数的标识符。 作为该函数定义的一部分的函数声明器中的空 列表指定 函数没有参数。函数声明器中的空列表不是该函数的 定义的一部分,它指定不提供有关参数数量或类型的信息。145)

强调我的,粗体文本是什么适用于int main()。还有一个在文本,它说“见“未来的语言方向‘’(6.11.6)”的结尾注145):

6.11.6函数声明

使用功能带空括号的声明符(不是原型格式参数类型声明符)是过时的功能。

这就是区别。作为函数声明者,int main()坏风格由于上述原因,因为它不能保证在下一版本的C标准中工作。它在C11中被标记为过时的特征。

因此,您应始终在托管系统上使用int main (void),并且永远不要使用int main(),即使现在这两种表单相同。


在C++中这两种形式是完全等价的,但有int main()是主观的,化妆品的原因首选样式(Bjarne的Stroustrup的是这么说的......这可能解释为什么你在做一些很糟糕的理由具体做法)。

+0

“'int main()'是主观的,美观的原因的首选样式” - 也许是主观的,好的,但IMO仍然是正确的。 '()'显然是一个空元组。 '(void)'看起来像是'void'类型的单个参数,那么如果'f'是一个函数,那么你就会希望能够写出像'main(f())'这样的东西,“返回void ”。区分空集合(/ lists/arrays/tuples)和一个元素集合的成员本身是空的是一个好主意。 (除此之外,如果客观地说,只要你写'空白'或没有关系就没关系,那么按照Occam的样板剃须刀... – leftaroundabout

0

我知道线程已经老了,但这个问题在几年前还困扰了我一阵子,所以我想把我的半分钱扔掉(如果那样的话)。

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

int main(int argc, char **argv). 
即使没有传递参数

,该函数在栈上这些参数,因为主函数没有函数重载。

C通过假装参数不存在而具有原始重载的能力。在这种情况下,参数仍然被传递并且在堆栈中,但是您永远不会访问它,因此它只会减少源代码的大小。 ()只是意味着我知道该函数可能有参数,但我没有使用它们,所以我写了int main()。

说INT主要(无效)说,主肯定没有参数,并暗示有两种不同的函数原型:

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

由于C没有函数重载,这是有点误导我,我不相信有主要(无效)的代码。如果主要从不采取任何参数,我不会这样做,在这种情况下,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来实现。

如EQ-说以上:

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

因此说这个函数具有void作为参数,但实际上在栈上有参数是矛盾的。

我的观点是,参数仍然存在,所以明确断言主要是无效论据是不诚实的。诚实的方式是说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; 
} 

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

相关问题