【问题标题】:What are the differences between: main(){}, int main(){} and int main(void){} [duplicate]有什么区别:main(){},int main(){}和int main(void){} [重复]
【发布时间】:2013-11-04 04:42:36
【问题描述】:

我目前正在学习C,我写了很多小程序。但是,我注意到 main 函数可以开始为

    main()
    {
       //code
    }

    int main()
    {
      //code
      return 0;
    }

    int main(void)
    {
       //code
       return 0;
    }

我应该使用哪个选项?谢谢!

【问题讨论】:

  • 查看stackoverflow.com/questions/2108192/… 和其中的链接
  • 好的,我现在看到了另一个问题..
  • 只使用最后一个,即使没有 return 语句,因为它是 C99 隐含的。如果你真的看到了其他问题,你不应该接受错误的答案......

标签: c main


【解决方案1】:

对于标准 C

对于托管环境(这是正常环境),C99 标准 说:

5.1.2.2.1 程序启动

程序启动时调用的函数名为main。实现没有声明这个函数的原型。应该是 使用int 的返回类型定义并且没有参数:

int main(void) { /* ... */ }

或带有两个参数(此处称为argcargv,尽管可以使用任何名称,因为它们对于它们所在的函数是本地的 已声明):

int main(int argc, char *argv[]) { /* ... */ }

或等效的;9) 或以其他一些实现定义的方式。

9) 因此,int 可以替换为定义为 int 的 typedef 名称,或者 argv 的类型可以写为 char **argv,并且 以此类推。

这(在 C89 中有效main() 隐含意味着(以前)int main(void)。但是,C99 中已经放弃了默认的返回类型规则。另外:

main() 表示 - 一个函数 main 采用 未指定 个参数。

main(void) 表示“一个函数 main 接受 no 参数。

【讨论】:

    【解决方案2】:

    您的第一个示例使用从 C 的过时方言继承的功能,该方言早于第一个 ANSI(1989)和 ISO(1990)标准:即,您可以编写一个不指定其返回类型的函数,并且在这种情况下,类型默认为int

    在早期的 C 中,void 关键字和相关类型不存在。当程序员想要编写过程(“具有副作用但不返回任何内容的函数”)时,他们会使用此功能对其进行模拟。他们编写了一个没有任何关键字指定返回类型的函数。他们允许函数在不返回值的情况下执行最后一条语句(或者,他们使用return; 从中间退出而不提供值),并且他们编写了对函数的调用,以便这些调用不会尝试使用返回值:

    parse_input() /* similar to a procedure in Pascal, but fake! */
    {
       /* ... */
       if (condition())
         return; /* no value */
       /* ... */
       /* fall off end here */
    }
    
    int main()
    {
       parse_input(); /* no return value extracted, everything cool! */
       return 0;
    }
    

    不幸的是,一些程序员也开始不关心程序的终止状态,并以这种程序风格编写main

    main()
    {
      /* do something */
      /* fall off the end without returning a value */
    }
    

    (也存在混合样式:省略 int 声明符但返回整数值。)

    这些未能返回值的程序具有不确定的终止状态。对于操作系统来说,它们的执行可能看起来成功或失败。 试图依赖这样一个程序的终止状态的脚本编写者有祸了!

    然后事情变得更糟了。 C++ 出现并引入了 void,并被 C++ 采用。使用 C++ 中的 void 关键字,可以声明一个实际上不返回任何内容的函数(并且在任何其他语句中使用 return; 语句会成为错误一种功能)。以前写main 没有返回类型的傻瓜程序员变得更笨了,开始把这个新奇的、新鲜的C++ void 贴在前面:

    void main() /* yikes! */
    {
      /* do something */
      /* fall off the end without returning a value */
    }
    

    这时候他们忘记了,写main()的时候,其实是int main(),这使得函数的类型与环境调用的启动调用兼容(除了忽略返回一个价值)。现在他们实际上有一个与预期不同的函数类型,甚至可能没有成功调用!

    现在的情况是,在 C++ 和最新的 C++ 标准中,main 仍然需要返回 int。但是这两种语言都为最初的虚拟程序员做出了让步:您可以让执行“下降”到 main 的末尾,并且行为就好像 return 0; 已经在那里执行了一样。所以这个琐碎的程序现在在 C99 和我认为 C++98(或者可能更早)中具有成功终止状态:

    int main()
    {
    }
    

    但是这两种语言都没有为第二代笨拙的程序员(以及阅读这些程序员在 1980 年代及以后编写的 C 书籍的其他所有人)做出让步。也就是说,void 不是 main 的有效返回声明符(除非平台记录它被接受,并且仅适用于这些平台,不适用于可移植语言)。

    哦,在 C99 中从 C 中删除了缺少声明符的余量,因此 main() { } 在 C 的新方言中不再正确,并且不是有效的 C++。顺便说一句,C++ 在其他地方确实有这样的语法:即,类构造函数和析构函数不需要有返回类型说明符。

    好的,现在关于 ()(void)。回想一下 C++ 引入了void。此外,虽然 C++ 引入了void,但它没有引入(void) 参数语法。 C++ 更严格的类型化引入了原型声明,并摒弃了非原型函数的概念。 C++ 改变了() C 语法的含义,赋予它声明的权力。在 C++ 中,int func(); 声明了一个没有参数的函数,而在 C 中,int func(); 没有做这样的事情:它声明了一个我们不知道参数信息的函数。当 C 采用 void 时,委员会有一个丑陋的想法:为什么我们不使用语法 (void) 来声明一个没有参数的函数,然后 () 语法可以保持向后兼容松散-goosey 遗留行为迎合无类型编程。

    你可以猜到接下来会发生什么:C++ 人看了这个(void) hack,为了跨语言兼容性,举起手臂将其复制到 C++ 中。事后看来,当你看到今天的语言是如何分化的,并且基本上不再关心那种程度的兼容性时,这真是令人惊讶。所以(void) 在 C 和 C++ 中明确表示“声明为没有参数”。但是在 C++ 代码中使用它显然是纯 C++ 从来没有打算成为 C 是丑陋的,而且风格很差:例如,在类成员函数上!写class Foo { public: Foo(void); virtual ~Foo(void) /*...*/ };这样的东西没有多大意义

    当然,当你定义int main() { ... }这样的函数时,无论是哪种语言,定义的函数都没有参数。不同之处在于引入了哪些声明信息范围。在 C 语言中,我们可能会遇到一种荒谬的情况,即函数可以在同一程序文本单元中完全定义,但不声明!

    当我们编写main 时,通常不会从程序内部调用它,因此定义声明的内容并不重要。 (在 C++ 中,main 不能从程序中调用;在 C 中可以)。因此,无论您使用的是 C 还是 C++,您是否编写 int main()int main(void) 都无关紧要。调用main 的东西看不到它的任何声明(无论如何,你在程序中编写)。

    所以请记住,如果你写:

    int main()  /* rather than main(void) */
    { 
    }
    

    那么,尽管它是完美的 C++ 和正确的 C,但作为 C,它有一点文体瑕疵:您正在编写一个旧式的 pre-ANSI-C 函数,它不能用作原型。尽管在 main 的情况下它在功能上并不重要,但如果您以某种方式使用某些编译器,您可能会收到警告。例如,使用 -Wstrict-prototypes 选项的 GCC:

    test.c:1:5: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
    

    因为-Wstrict-prototypes 是在 C 中编程时打开的非常有用的警告,以提高类型安全性(与 -Wmissing-prototypes 一起),并且我们努力从编译作业中消除警告,因此我们应该编写:

    int main(void) /* modern C definition which prototypes the function */
    {
    }
    

    这将使该诊断消失。

    如果您希望main 接受参数,那么参数名称由您决定是int main(int argc, char **argv)

    在 C++ 中,您可以省略参数名称,因此这个定义是可能的,它很好地代替了main()

    int main(int, char **) // both arguments ignored: C++ only
    {
    }
    

    由于参数向量是空指针终止的,因此您不需要argc,C++ 让我们可以在不引入未使用变量的情况下表达这一点:

    #include <cstdio>
    
    int main(int, char **argv)  // omitted param name: C++ only
    {
      // dump the arguments
      while (*argv)
        std::puts(*argv++);
    }
    

    【讨论】:

    • 其实这应该被标记为答案,而不是另一个带有一些错误信息的答案。
    • @mfxm 完成!当我标记答案时,这个答案不存在!
    【解决方案3】:

    第一:

    声明一个函数 main - 没有输入参数。虽然 main 应该有返回(你的编译器会处理这个)

    第 2 次/第 3 次:

    声明一个 main 函数,它返回一个 int 并且不接受任何输入参数

    您应该使用第三种格式这是最好的方法:

    int main(int argc, char *argv[]){
         return 0;
    }
    

    【讨论】:

      【解决方案4】:

      您应该使用以下 4 个选项之一:

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

      通常使用名称argcargv;你可以改变它们,但不能。

      注意永远不要使用在生产代码中经常出现的void main(void);

      【讨论】:

        【解决方案5】:
        1. 默认情况下 main 函数返回一个整数类型,因此它的“int main()”或者你可以简单地给出“main()”

        2. “main(void)”和“main()”一样,告诉编译器main函数没有参数。

        3. 如果你想通过主函数传递参数:

          int main(int argc, char *argv[]){ return 0; }

        【讨论】:

        • 对于像我这样的新手的简单答案!谢谢
        • By default main function returns an integer type - 这不完全正确 - 编写任何函数而不指定 return 默认为 int。不仅仅是main
        • 默认返回类型规则在 C 中早已被废弃。这不是有效的 C。
        • 页。 2错了。在 C 中 foo() 和 foo(void) 是不同的。
        • @JensGustedt - 感谢您指出这一点。已经完全错过了。这在 C89 中有效,但在 C99 中不再有效。
        【解决方案6】:
        main(){} 
        

        上面的行给你一个错误。 c 中任何函数的默认返回类型都是 int。由于上面的代码没有返回任何内容,它会给你一个错误。

        int main(){
        //body
        return 0;
        }
        

        在上面的代码中,它满足所有要求,所以上面的代码将运行。在上面的代码中,我们在函数中不传递任何参数。所以这个函数可以带全局变量和局部变量来处理。

        int main(void)
        {
           //code
           return 0;
        }
        

        在上面的代码中,我们没有在函数中传递任何参数。但是指定void 会告诉编译器它不接受任何参数。 void 是参数的默认数据类型,表示没有输入。

        【讨论】:

          猜你喜欢
          • 2018-03-16
          • 2016-07-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-08-26
          • 1970-01-01
          • 1970-01-01
          • 2010-10-12
          相关资源
          最近更新 更多