C中main()的不同约定

C中main()的不同约定,c,main,C,Main,我唯一接触编程的是Java,在Java中,我没有遇到(到目前为止)编写主方法的不同约定。我一直遵循学习c的来源(K&R和c编程是一种现代方法),它们使用非常不同形式的主方法(函数) K&R版本至今: main() { blah blah blah; } C编程是一种现代方法 int main() { blah blah blah; return 0; } 或 int main() { blah blah blah; //returns nothing

我唯一接触编程的是Java,在Java中,我没有遇到(到目前为止)编写主方法的不同约定。我一直遵循学习c的来源(K&R和c编程是一种现代方法),它们使用非常不同形式的主方法(函数)

K&R版本至今:

main() {
    blah blah blah;
}
C编程是一种现代方法

int main() {
    blah blah blah;
    return 0;
}

int main() {
    blah blah blah; 
    //returns nothing
}
为了让事情变得更混乱,我看到人们这样做:

int main(void) {
    blah blah blah;
}
而它们要么返回0,要么不返回。 我并不认为这只是一个标准问题,但可能是一个概念性的或深层次的问题。
有人能解释一下这个问题吗?

C标准将
main
的签名定义为

int main(void)

添加
返回0作为
main
函数中的最后一条语句是可选的。
标准还提到了一些实现定义的原型<编译器接受code>int main()

main()
是一个老式的原型,几乎被弃用。

  • K&R样式已经过时,根据C标准不再正确

  • 有效签名为

    int main(void)
    

    或者,等效,因为函数中的数组类型被调整为指针类型:

    int main(int argc, char **argv)
    
  • 签名

    int main()
    
    恰好也是有效的,因为空参数列表表示任意数量的参数,这些参数没有被描述*)。好了,这可能会改变,所以不要这样写。编写
    void
    是表示此函数不接受C中的参数的方式

  • C的实现可以自由地提供其他实现定义的入口点。但我上面列出的两个是该标准唯一保证的

  • C99为
    main()
    引入了一条特殊规则,该规则规定如果函数不返回任何内容,则隐式返回
    0
    的值。因此仅在main中,您可以跳过
    返回。我的建议是:不要。只是让人困惑。但这是一种观点



在C++中,这是<强> > < <强> >,在偏执> <强>实际上< /强>之间没有任何含义。

预标准化版本的C(称为K&R C)没有默认类型的概念<代码> int <代码>。因此,在K&R中:

main() {
同:

int main() {
至于
int main()
int main(void)
之间的区别,空参数列表表示函数采用了未指定数量的参数,而
(void)
作为参数列表表示函数不采用参数。前者是可以接受的,但后者是首选的,因为它更明确

关于
return
语句的使用,具有非无效返回类型的函数必须使用
return
返回值,但
main
函数(从C99标准开始)除外。在
main
的情况下,缺少
return
语句意味着返回值为0

由于在C99中添加了main的隐式
return 0
,因此您将看到一些代码显式返回,有些代码不返回,这取决于程序员遵守的标准版本。

自最新的C语言标准起,
main
有两个标准签名:

int main( void ) // void indicates "takes no arguments"

名称
argc
argv
是任意的;如果您愿意,可以使用不同的名称

实现可能会为
main
提供额外的有效签名-请查看编译器文档

如果程序不接受任何命令行参数,请使用第一种形式,否则使用第二种形式

C函数声明和定义语法随着时间的推移有了一些发展,这就是为什么不同的引用使用不同的约定

隐式键入

首先,C最初允许隐式
int
声明-如果编译器看到没有类型说明符的函数定义或声明,则它假定函数返回
int

foo(); // modern equivalent: int foo( void )
这在1999年之前是允许的,尽管在那之前我们大多数人都认为这是一种糟糕的风格

直到1989年标准才引入了
void
关键字。作为类型说明符,它表示没有值的类型。作为函数参数列表中的标识符,它指示函数不接受任何参数

在引入
void
关键字之前,没有好的方法(文档除外)来区分返回您要使用的值的函数和仅执行某些操作的函数。我们中的一些人使用“隐式
int
”约定来表示这些函数并不打算返回任何有意义的内容:

foo();     /* returns int, but return value not meant to be used */
int bar(); /* returns int, return value meant to be used */
同样,这只是一个惯例,远远不是普遍的。现在我们将使用
void
关键字:

void foo(); /* does not return a value */
int bar();  /* returns int */
函数原型语法

最初,函数定义如下所示:

foo( bar, bletch, blurga )
  int bar;
  double bletch;
  char *blurga;
{
  /* function body */
}
参数列表仅指定参数的名称,而不指定其类型;这是在函数声明器和函数体的开头
{
之间的一组单独声明中完成的。不带参数的函数在函数定义中有一个空标识符列表:

foo( int bar, double bletch, char *blurga );
函数声明只指定了函数的名称和返回类型;它根本没有指定参数:

foo( ); /* no bar, bletch, or blurga */
函数声明中的空标识符列表表示该函数采用的参数数量未指定,而不是零参数。编译器可以检查函数调用的返回类型是否正确使用,但无法检查调用中的参数数量和类型是否正确

198
foo( bar, bletch, blurga )
  int bar;
  double bletch;
  char *blurga;
{
  /* function body */
}
blah( )  
{
  /* function body */
}
foo( ); /* no bar, bletch, or blurga */
foo( int bar, double bletch, char *blurga )
{
  /* function body */
}
foo( int bar, double bletch, char *blurga );
blah( void ); /* declaration, returns int, takes no parameters */

blah( void )  /* definition */
{
   /* function body */
}
main()                            main( argc, argv )
{                                   int argc;
  ...                               char *argv[];
}                                 {
                                    ...
                                  }
main( void )                      main( int argc, char *argv[] )
{                                 {
  ...                               ...
}                                 }
int main( void )                  int main( int argc, char *argv[] )
{                                 {
  ...                               ...
}                                 }