我目前正在学习C,我写了很多小程序。但是,我注意到主要功能可以作为
main()
{
//code
}
或者
int main()
{
//code
return 0;
}
或者
int main(void)
{
//code
return 0;
}
我应该使用哪个选项?谢谢!
对于标准 C
对于托管环境(这是正常环境),C99 标准说:
5.1.2.2.1 程序启动
程序启动时调用的函数名为
main
. 实现没有声明这个函数的原型。它应定义为返回类型int
且不带参数:int main(void) { /* ... */ }
或带有两个参数(这里称为
argc
andargv
,尽管可以使用任何名称,因为它们对于声明它们的函数是本地的):int main(int argc, char *argv[]) { /* ... */ }
或同等学历; 9)或以其他一些实现定义的方式。
9)因此,
int
可以用定义为 的 typedef 名称替换int
,或者argv
可以写为的类型char **argv
,以此类推。
这(在 C89 中有效)main()
隐含的意思是(以前)int main(void)
。但是,默认返回类型规则已在C99中被放弃。还:
main()
表示 - 一个函数main
,其参数数量未指定。
main(void)
意思是“一个不main
带参数的函数。
您的第一个示例使用从 C 的过时方言继承的功能,该方言早于第一个 ANSI(1989)和 ISO(1990)标准:也就是说,您可以编写一个不指定其返回类型的函数,在这种情况下类型默认为int
.
在早期的 C 中,void
关键字和关联类型不存在。当程序员想要编写过程(“具有副作用但不返回任何内容的函数”)时,他们会使用此功能对其进行模拟。他们编写了一个没有任何关键字指定返回类型的函数。他们允许函数在不返回值的情况下执行最后一条语句(或者,他们过去常常return;
在不提供值的情况下从中间退出),并且他们编写了对函数的调用,这样这些调用就不会尝试使用 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++ 采用。使用void
C++ 中的关键字,可以声明一个实际上不返回任何内容的函数(并且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++ 在其他地方确实有这样的语法:即,类构造函数和析构函数不需要有返回类型说明符。
好的,现在关于()
vs (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
如果您以某种方式使用某些编译器,您可能会收到警告。例如,GCC,有以下-Wstrict-prototypes
选项:
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++);
}
您应该使用以下 4 个选项之一:
int main(void);
int main();
int main(int argc, char **argv);
int main(int argc, char *argv[]);
习惯使用名称argc
和的地方argv
;你可以改变它们,但不要。
注意不要使用void main(void);
在生产代码中经常出现的内容。
第一的 :
声明一个函数 main - 没有输入参数。虽然 main 应该有回报(你的编译器会处理这个)
第二/第三:
声明一个 main 函数,它返回一个 int 并且不接受任何输入参数
您应该使用第三种格式。相反,这是最好的方法:
int main(int argc, char *argv[]){
return 0;
}
默认情况下,主函数返回一个整数类型,因此它是“int main()”,或者你可以简单地给出“main()”
“main(void)”与“main()”相同,它告诉编译器主函数没有参数。
如果您想通过主函数传递参数:
int main(int argc, char *argv[]){
return 0;
}
main(){}
上面的行给你一个错误。c 中任何函数的默认返回类型都是 int。由于上面的代码没有返回任何内容,它会给你一个错误。
int main(){
//body
return 0;
}
在上面的代码中,它满足所有要求,因此上面的代码将运行。在上面的代码中,我们在函数中不传递任何参数。所以这个函数可以带全局变量和局部变量来处理。
int main(void)
{
//code
return 0;
}
在上面的代码中,我们没有在函数中传递任何参数。但是指定void
告诉编译器它不接受任何参数。void
是表示没有输入的参数的默认数据类型。