C的main()函数的有效签名是什么?
C中main函数的有效签名是什么? 我知道:
int main(int argc, char *argv[])
还有其他有效的吗?
这个答案(C11)当前的标准明确提到了这两个:
int main(void); int main(int argc, char* argv[]);
尽pipe它提到了“或同等”一词,并附有以下脚注:
因此,
int
可以被定义为int
的typedef
名称replace,或者argv
的types可以被写为char ** argv
,依此类推。
另外,它还提供了更多(实现定义的)可能性。
相关部分(C11中的5.1.2.2.1节,但这个特定方面与C99没有任何变化)表示:
程序启动时调用的函数名为main。 这个实现声明了这个函数没有原型。 它应该用int的返回types来定义,并且不带参数:
int main(void) { /* ... */ }
或者带有两个参数(这里称为argc和argv,尽pipe可以使用任何名称,因为它们是声明它们的函数的本地):
int main(int argc, char *argv[]) { /* ... */ }
或同等学历; 或者以某种其他实现定义的方式。
如果声明了,主函数的参数应该遵守以下约束条件:
argc
的值应该是非负的。
argv[argc]
应该是一个空指针。如果argc的值大于零,则
argv[0]
至argv[argc-1]
包含的数组成员应该包含指向string的指针,这些string在程序启动之前由主机环境给出实现定义的值。 其目的是向程序提供在程序启动之前从托pipe环境中的其他地方确定的信息。 如果主机环境不能提供大小写字母的string,则实现应确保string以小写forms接收。如果
argc
的值大于零,则argv[0]
指向的string表示程序名称; 如果程序名称在主机环境中不可用,则argv[0][0]
应为空字符。 如果argc
的值大于1,则argv[1]
至argv[argc-1]
指向的string表示程序参数。参数
argc
和argv
以及argv
数组所指向的string应该可以被程序修改,并且在程序启动和程序终止之间保留它们的最后存储的值。
请注意,这是针对托pipe环境的,通常在C程序中看到的环境。 独立环境(如embedded式系统)的限制要less得多,如同一标准的5.1.2.1所述:
在一个独立的环境中(C程序的执行可能没有任何操作系统的好处),程序启动时调用的函数的名称和types是实现定义的。 任何独立程序提供的图书馆设施,除第4条所要求的最低限度设置外,都是实施定义的。
POSIX支持execve()
,这反过来支持
int main(int argc, char *argv[], char *envp[])
添加的参数是环境,即NAME = VALUEforms的string数组。
标准C
对于托pipe环境(这是正常的),C99标准说:
5.1.2.2.1程序启动
程序启动时调用的函数名为
main
。 这个实现声明了这个函数没有原型。 它应该用int
的返回types来定义,并且不带参数:int main(void) { /* ... */ }
或者带有两个参数(这里称为
argc
和argv
,尽pipe可以使用任何名称,因为它们是声明它们的函数的本地):int main(int argc, char *argv[]) { /* ... */ }
或同等学历; 9)或者其他一些实现定义的方式。
9)因此,
int
可以被定义为int
的typedef名称replace,或者argv
的types可以被写为char **argv
,依此类推。
标准C ++
C ++ 98标准说:
3.6.1主要function[basic.start.main]
1程序应该包含一个名为main的全局函数,它是程序的指定开始。 […]
2实现不应该预定义主函数。 该function不得超载。 它应该有一个types为int的返回types,否则其types是实现定义的。 所有的实现都应该允许main的以下两个定义:
int main() { /* ... */ }
和
int main(int argc, char* argv[]) { /* ... */ }
C ++标准明确地说“它的主函数应该有一个types为int的返回types,否则其types是实现定义的”,并且需要与C标准相同的两个签名。 所以一个'void main()'是C ++标准直接不允许的,尽pipe没有任何事情可以阻止一个非标准的实现允许替代。
共同扩展
Unix系统经典地支持第三个变体:
int main(int argc, char **argv, char **envp) { ... }
第三个参数是一个以空字符结尾的指向string的指针列表,每个指针都是一个具有名称,等号和值(可能为空)的环境variables。 如果你不使用这个,你仍然可以通过' extern char **environ;
'来获得extern char **environ;
”。 很长一段时间,它没有声明它的头文件,但POSIX 2008标准现在要求在<unistd.h>
声明它。
这被C标准认为是一个通用的扩展,logging在附件J中:
J.5.1环境参数
¶1在托pipe环境中,主函数接收第三个参数
char *envp[]
,该参数指向一个以char
为空的终止指针数组,每个指向一个string,该string提供有关此执行的环境的信息(5.1.2.2.1)。
微软C
Microsoft VS 2010编译器很有趣。 该网站说:
main的声明语法是
int main();
或者可选地,
int main(int argc, char *argv[], char *envp[]);
或者,
main
和wmain
函数可以被声明为返回void
(无返回值)。 如果将main
或wmain
声明为返回void,则不能使用return语句将退出代码返回到父进程或操作系统。 要将main
或wmain
声明为void
时返回一个退出代码,您必须使用exit
函数。
当有一个带有void main()
的程序确实退出时,我不清楚发生了什么(退出代码返回给父类或o / s),而且MS网站也是无声的。
有趣的是,MS并没有规定C和C ++标准要求的main()
的双参数版本。 它只规定了三个参数的forms,其中第三个参数是char **envp
,一个指向环境variables列表的指针。
微软的网页还列出了一些其他的select – wmain()
需要宽字符string,还有一些。
本页面的Microsoft VS 2005版本没有列出void main()
作为替代。 从微软VS 2008开始的版本呢 。
http://en.wikipedia.org/wiki/Main_function_(programming)#C_and_C.2B.2B
除了通常的int main(int argc, char *argv[])
和POSIX int main(int argc, char **argv, char **envp)
,Mac OS X还支持
int main(int argc, char* argv[], char* envp[], char* apple[]);
当然,这只是Mac。
在Windows上
int wmain(int argc, wchar_t* argv[], wchar_t* envp[]);
作为Unicode(实际上是宽字符)变体。 当然也有WinMain
。
int main(void)
在某些操作系统下(例如Windows)也是这样的:
int main(int argc, char **argv, char **envp)
envp
给出了一个环境,否则通过getenv()