这是:main(){}和int main(){}和int main(void){} 之间的差异
我正在学习c,到现在为止我已经提出了很多小程序。 但是我注意到它们中的许多主要function开始如下:
main() { //code }
要么
int main() { //code return 0; }
要么
int main(void) { //code return 0; }
那么,我该怎么用? 或者哪种方式最好? 感谢名单!
您的第一个示例使用从过时的C语言inheritance的特征,该特征早于第一个ANSI(1989)和ISO(1990)标准:即,您可以编写一个不指定其返回类型的函数,在这种情况下, type默认为int
。
在早期的C中, void
关键字和关联类型不存在。 当程序员想要编写程序(“具有副作用但不返回任何内容的函数”)时,他们使用此function对其进行模拟。 他们编写了一个函数,没有任何关键字指定返回类型。 它们允许函数执行它的最后一个语句而不返回一个值(或者,他们使用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)
黑客,为了跨语言兼容性而放弃了他们的arm并将其复制到C ++中。 当你看到今天语言如何分歧并且基本上不再关心这种程度的兼容性时,后见之明是惊人的。 所以(void)
unambiguosly意味着在C和C ++中“声明为没有参数”。 但是在C ++代码中使用它显然是纯粹的C ++从来没有打算成为C是丑陋的,而且风格很差:例如,在类成员函数上! 写class Foo { public: Foo(void); virtual ~Foo(void) /*...*/ };
没有多大意义class Foo { public: Foo(void); virtual ~Foo(void) /*...*/ };
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,但它有一个轻微的风格瑕疵:你正在编写一个旧式的ANSI-C之前的function,它不作为原型。 虽然在main
的情况下它在function上并不重要,但如果您以某种方式使用某些编译器,则可能会收到警告。 例如,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 int main(int, char **argv) // omitted param name: C++ only { // dump the arguments while (*argv) std::puts(*argv++); }
对于标准C.
对于托管环境(这是正常的环境),C99标准说:
5.1.2.2.1程序启动
程序启动时调用的函数名为
main
。 该实现声明此函数没有原型。 它应该使用返回类型int
并且没有参数来定义:int main(void) { /* ... */ }
或者使用两个参数(这里称为
argc
和argv
,尽管可以使用任何名称,因为它们是声明它们的函数的本地名称):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
不带参数。
第一:
声明一个函数main – 没有输入参数。 虽然main应该有返回(你的编译器会处理这个)
第二/第三:
声明一个函数main,它返回一个int并且不接受任何输入参数
你应该使用第3种格式 。 相反,这是最好的方法:
int main(int argc, char *argv[]){ return 0; }
您应该使用以下4种选择之一:
int main(void); int main(); int main(int argc, char **argv); int main(int argc, char *argv[]);
使用名称argc
和argv
的常规方法; 你可以改变它们但不要改变它们。
小心永远不要使用void main(void);
这在生产代码中经常出现。
-
默认情况下,main函数返回一个整数类型,因此它的“int main()”或者你可以简单地给出“main()”
-
“main(void)”与“main()”相同,它告诉编译器main函数没有参数。
-
如果你想通过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
是参数的默认数据类型,表示无输入。