【问题标题】:Is there a real difference between int main() and int main(void) in C? [duplicate]C 中的 int main() 和 int main(void) 之间有真正的区别吗? [复制]
【发布时间】:2020-03-01 06:52:11
【问题描述】:

前言:

这可能会被标记为重复,我理解,但我问这个,因为我觉得其他答案可能不太清楚。事实上,我发现对我最有意义的最接近的答案是这个:from 2015 和这个:from 2013, about return 0;

我的编程经验很少——几年前我搞砸了 Java,有点弄清楚我需要复制和粘贴什么来编辑我正在玩的程序,我用 python 编写了一个简单的程序,我在学校里和 Scratch 一起玩。但是,我终于决定坐下来,学习一门语言,C,然后继续学习。

所以,我想问的是,我的解释是否正确?因为,如果是这样,那么可以说,对于大多数意图和目的,int main()(没有参数)和int main(void) 之间没有区别。

实际重要性:

总结一下我目前的理解:

  1. 如果使用int main(),则应在末尾添加return 0;,表示程序终止。
  2. 尽管可能,但使用int main() 而不使用return 0; 是不合适的,因为许多编译器可能无法识别这一点。
  3. 如果使用int main(void),则无需添加return 0;

用简单的英语来说,这是否可以说是一个好的和/或准确的解释?

示例:

/*
 * Program example using scanf, printf, and int main() with no variable
 * This program reads a string from the user
 */

#include <stdio.h>

int main() {
        char name[10];                /* number in square brackets is for max characters in name */
        printf("Enter name: ");
        scanf("%s", name);            /* scanf will read input until it sees blank space, then stop */
        printf("Hello, %s!\n", name);
        return 0;
}

对比

/*
 * Program example using scanf, printf, and int main(void)
 * This program reads a string from the user
 */

#include <stdio.h>

int main(void) {
        char name[10];                /* number in square brackets is for max characters in name */
        printf("Enter name: ");
        scanf("%s", name);            /* scanf will read input until it sees blank space, then stop */
        printf("Hello, %s!\n", name);
}

【问题讨论】:

  • return 是关于返回类型,而不是参数。
  • 回答(是),虽然有点语义问题,但在 C 中,带有空 () 的函数采用 indeterminate 个参数,而 (void) 指定 个参数。
  • Actual Importance: 中的所有 3 个点都是错误的。 1)您不需要在int main() 中添加return 0。 2) 可以使用int main() 而不使用return 0。 3) 不必在int main(void) 中添加return 0In plain English 用简单的英语,如果main 返回一个int,则不需要写return 0。不管参数列表里面有什么。 int main(/*anything here*/) { /* always returns 0 by default */ }
  • 嗯..也许标准会澄清一些事情。确切的规则是C11 5.1.2.2.3p1:If the return type of the main function is a type compatible with int, .... reaching the } that terminates the main function returns a value of 0。如果它返回int 并且执行到达main 中的关闭},则它充当return 0
  • 风格差异很大。 int main() 看起来您要么正在编写 C++,要么生活在 1987 年。

标签: c


【解决方案1】:

如果使用int main(),则应在末尾添加return 0;,表示程序终止。

大部分是真的。正如我们将看到的,这是一种很好的做法,尽管并非绝对必要。

虽然可能,但使用int main()而不使用return 0;是不合适的,因为许多编译器可能无法识别这一点。

大部分是错误的。一段时间以来,作为一个名为 main() 的函数独有的特殊情况,如果您不提供 return 语句,编译器需要安排 main 隐式返回 0。

旧的编译器可能仍然需要return 0;,如果省略它会表现不佳——尽管故障通常很小。此外,不符合此要求的旧编译器肯定会担心许多其他更重要的兼容性问题。

如果使用int main(void),则无需添加return 0;

正确,但具有误导性。在这方面int main()int main(void) 之间没有任何区别。同样(根据上述),如果使用int main(),则无需添加return 0

【讨论】:

  • 我会说这不是好的做法。这只是噪音。
  • 具体而不是“大部分”:它在 C89 中是必需的,在 C99 及更高版本中是多余的
  • @M.M 如果您需要在 C89 编译器上编译代码(不太可能),那么只需激活警告(这是一种很好的做法)
【解决方案2】:

不同之处在于int main() 没有为main 指定原型声明。作为函数的定义,两者是等价的,以相互兼容的方式定义函数。但是,int main() 在作用域中引入了较少的编译时信息。

在 C 中(与 C++ 不同),main 允许递归。因此我们可以考虑以下愚蠢的程序:

int main(void)
{
   main(42);
}

因为main 已完全声明,所以main(42) 调用是违反约束的,需要进行诊断。如果我们将程序更改为:

int main()
{
   main(42);
}

那么函数并没有改变:它仍然是一个不带参数的函数。但该信息并未声明为main 标识符类型信息的一部分,因此该调用不需要诊断。 (如果翻译和执行,它会调用未定义的行为;但即使有诊断也可能发生这种情况。)

这是一种旧风格,在 C 有函数原型声明之前,该声明在 1989 年的 ANSI C 中首次标准化并在此之前得到广泛使用。

【讨论】:

    【解决方案3】:

    最新标准允许您省略return 0 语句。至于main()的原型,同样有3种变体:

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

    C 中的空参数列表意味着您可以传递任意数量的参数,但函数不会关心其中的任何一个。指定 void 参数列表意味着您必须明确传递 no 参数,否则会出错。

    虽然标准只明确接受版本 #2 和 #3,但版本 #1 也可以工作,因为操作系统传递版本 #3 的参数,而您的函数不会关心它们。

    希望我的回答足够清楚。

    【讨论】:

    • 所以,如果我理解正确,如果您添加void,那么您在使用 gcc、make 等时不能添加参数,这些参数会以某种方式、形状、或形式,目前超出我的理解范围?
    • “C 中的空参数列表意味着您可以传递任意数量的参数,但函数不会关心其中的任何一个。” - 根据标准这是不正确的
    • @M.M 它是 UB,但这是实际发生的情况。
    猜你喜欢
    • 2012-08-26
    • 2018-03-16
    • 1970-01-01
    • 1970-01-01
    • 2010-10-12
    • 2016-07-24
    • 2013-11-04
    • 2012-11-12
    • 2011-04-12
    相关资源
    最近更新 更多