在此代码中:
int main(int a, int b)
{
printf(" main(int, int) works \n\n");
return 0;
}
main
的签名是main(int, int)
和it compiles successfully。为什么呢?
答案 0 :(得分:12)
因为C标准不禁止main
的非标准签名(参见例如C99标准的第5.1.2节)。
但是,您会发现,如果您使用-Wall
标志在GCC下编译, 1 ,它会抱怨:
test.c:4: warning: second argument of 'main' should be 'char **'
它假定您希望与标准环境交互(即处理命令行参数并返回退出状态),在这种情况下,您必须使用int main(int, char **)
或int main(void)
。如果你使用其他任何东西,参数的内容将是未定义的。
<小时/> <子> 1。我真的希望ideone.com允许你指定编译器标志!
答案 1 :(得分:3)
C标准明确禁止实现为main
提供原型(C99,§5.1.2.2.1/ 1:“程序启动时调用的函数名为main
。实现声明没有这个函数的原型。“),与原型的不匹配是(通常)停止编译的代码。
如果没有原型,你就会像过去那样重新编程,当你需要确保传递给函数的参数与预期相符时。值得庆幸的是,在main
的情况下,签名是众所周知的,但它很少是一个问题。
编辑:请注意,如果您想要足够严重,实际上甚至可以使用具有两个int
参数的版本(尽管C ++中禁止使用该技术)。 main
可以递归调用自身,在这种情况下可以/可以传递两个int
参数:
int main(int a, int b) {
if (a == 2)
main(2, 10);
printf("%d, %d", a, b);
return 0;
}
这是无用的,但它给出了一般的想法 - 你应该在没有命令行参数的情况下运行程序,在这种情况下a
(它将接收你通常称之为{{ 1}})通常是argc
(即,它试图传递的唯一参数是argv [0]中程序的名称)。在这种情况下,它会使用其他一些值来调用自身。当发生这种情况时,它会打印出这些值。
公平地说,我应该补充说,这非常接近纯理论,当然不推荐。它适用于大多数典型的实现,但标准并不能保证它。这是一种愚蠢,迂回的方式来完成它的工作 - 但至少对于大多数典型的编译器来说,无论如何都是(几乎不可能)。
答案 2 :(得分:1)
没有指定main签名的头文件,因此不会报告错误。对于main的情况,编译器通常仅检查返回值(main的签名警告依赖于编译器)。
答案 3 :(得分:1)
int main(int a, int b)
这是没有意义的,因为传递给main函数的参数总是
int main(int argc,char *argv[])
main是一个不寻常的函数。它由操作系统调用,并且由于C ++可以在许多系统上运行,并且C ++标准不能指示OS编写者将哪些数据传递给在该OS上运行的程序 - 您可以编写任何参数你喜欢主要功能,编译器会接受它。