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()