3

在这段代码中:

int main(int a, int b)
{
    printf(" main(int, int) works \n\n");
    return 0;
}

mainis的签名,main(int, int)编译成功。为什么?

4

4 回答 4

12

因为 C 标准不禁止非标准签名main(参见例如 C99 标准的第 5.1.2 节)。

但是,您会发现,如果您在 GCC 下使用-Wallflag, 1进行编译,它会报错:

test.c:4: warning: second argument of 'main' should be 'char **'

它假定您要与标准环境交互(即处理命令行参数并返回退出状态),在这种情况下您必须使用int main(int, char **)or int main(void)。如果你使用其他任何东西,参数的内容将是未定义的。


1. 我真的希望 ideone.com 允许您指定编译器标志!

于 2012-06-16T15:06:42.153 回答
3

C 标准明确禁止实现为main(C99, §5.1.2.2.1/1: "The function called at program startup is named main. The implementation declarations no prototype for this function.") 提供原型,并且不匹配来自原型是(通常)阻止代码编译的东西。

如果没有原型,您将回到过去糟糕的编程状态,那时您需要确保传递给函数的参数与预期相符。值得庆幸的是,在 的情况下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(它将接收您通常调用的内容argc)通常是1(即,唯一的参数它试图传递的是 argv[0] 中的程序名称)。在这种情况下,它用一些其他值调用自己。发生这种情况时,它会打印出这些值。

公平地说,我应该补充一点,这非常接近纯理论,当然不推荐。它适用于大多数典型的实现,但标准不保证这一点。这是一种愚蠢的、迂回的方式来完成它的工作——但至少对于大多数典型的编译器来说,无论如何它(几乎)是可能的。

于 2012-06-16T15:12:06.443 回答
1

没有指定main签名的头文件,所以不会报错。对于 main 的情况,编译器通常只检查返回值(main 签名的警告取决于编译器)。

于 2012-06-16T15:08:02.170 回答
1
int main(int a, int b)

这是没有意义的,因为传递给主函数的参数总是

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

main 是一个不寻常的函数。它由操作系统调用,因为 C++ 可以在许多系统上运行,而 C++ 标准不能规定操作系统编写者将哪些数据传递给在该操作系统上运行的程序 - 你可以编写任何你喜欢的参数主要功能和编译器将接受它。

于 2012-06-16T15:08:32.327 回答