为了账号安全,请及时绑定邮箱和手机立即绑定

C的main()函数的有效签名是什么?

C的main()函数的有效签名是什么?

C
繁星coding 2019-06-26 17:21:00
C的main()函数的有效签名是什么?C中主函数的有效签名是什么?我知道:int main(int argc, char *argv[])还有其他有效的吗?
查看完整描述

3 回答

?
绝地无双

TA贡献1946条经验 获得超4个赞

在作出这一答复时,目前的标准(C11)明确提到以下两点:

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

虽然它确实提到了“或等同”一语,但有以下脚注:

因此,int可以用typedef定义为int的类型argv可以写成char ** argv等等。

此外,它还提供了更多(实现定义的)可能性。

相关章节(C11第5.1.2.2.1节,但这一特定方面与C99没有变化)指出:

在程序启动时调用的函数名为main..该实现没有声明此函数的原型。它应定义为返回类型为int在没有参数的情况下:

int main(void) { /* ... */ }

或者有两个参数(在这里称为argcargv(虽然可以使用任何名称,因为它们是声明它们的函数的本地名称):

int main(int argc, char *argv[]) { /* ... */ }

或等效;或以其他实现-定义的方式。

如果声明了这些参数,则main职能应遵守下列限制:

  • 价值argc应该是非否定的。

  • argv[argc]将为空指针。

  • 如果argc大于零,则数组成员argv[0]贯通argv[argc-1]包容性应该包含指向字符串的指针,这些指针是由主机环境在程序启动之前给出的实现定义的值。其目的是从宿主环境中的其他地方向程序启动之前确定的程序信息提供。如果主机环境不能同时提供大写字母和小写字母,则实现应确保以小写接收字符串。

  • 如果argc值大于零,所指向的字符串为argv[0]表示程序名称;argv[0][0]如果程序名在主机环境中不可用,则为空字符。如果argc大于1,所指向的字符串由argv[1]贯通argv[argc-1]表示程序参数。

  • 参数argcargv和字符串所指向的argv数组应由程序修改,并在程序启动和程序终止之间保留其最后存储的值。

请注意,这是一个托管环境,您通常在C程序中看到。正如同一标准的5.1.2.1所述,独立的环境(例如嵌入式系统)的约束要小得多:

在一个独立的环境中(在这个环境中,C程序可以在没有操作系统任何好处的情况下执行),在程序启动时调用的函数的名称和类型都是实现定义的。任何可供独立程序使用的库设施,除了第4条所要求的最小设置外,都是实现定义的。


查看完整回答
反对 回复 2019-06-26
?
慕森王

TA贡献1777条经验 获得超3个赞

标准C

对于宿主环境(这是正常的),C99标准说:

5.1.2.2.1启动程序

在程序启动时调用的函数名为main..该实现没有声明此函数的原型。它应定义为返回类型为int在没有参数的情况下:

int main(void) { /* ... */ }

或者有两个参数(在这里称为argcargv(虽然可以使用任何名称,因为它们是声明它们的函数的本地名称):

int main(int argc, char *argv[]) { /* ... */ }

或同等;9)或者以其他实现定义的方式。

9)因此,int可以用定义为int的类型argv可以写成char **argv等等。

C11和C18标准基本上与C99标准相同。

标准C+

C+98标准规定:

3.6.1主要功能[basic.start.main]

1程序应包含一个称为Main的全局函数,它是程序的指定开始。[.]

2实施不应预定义主要职能。此功能不应超载。它应该有一个int类型的返回类型,但否则它的类型是定义的。所有实现都应允许Main的以下两种定义:

int main() { /* ... */ }

int main(int argc, char* argv[]) { /* ... */ }

C+标准明确表示“它[主函数]应该有一个int类型的返回类型,但否则它的类型是实现定义的”,并且需要与C标准相同的两个签名。因此,C+标准直接不允许使用“voidmain()”,尽管它无法阻止非标准一致性实现允许替代品(也不允许标准一致性实现作为标准的扩展)。

C+03、C+11、C+14和C+17标准与C+98基本相同。

公共延伸

传统上,Unix系统支持第三种变体:

int main(int argc, char **argv, char **envp) { ... }

第三个参数是指向字符串的以空结尾的指针列表,每个字符串都是一个环境变量,它有一个名称、一个等号和一个值(可能是空的)。如果您不使用这个,您仍然可以通过extern char **environ;“”很长一段时间以来,它没有一个标头来声明它,但是POSIX 2008标准现在要求它在<unistd.h>.

C标准承认这是一项共同的扩展,载于附件J:

J.5.1环境论点

在宿主环境中,主函数接收第三个参数,char *envp[],它指向以空结尾的指针数组。char,每个字符串指向一个字符串,该字符串提供有关此程序执行环境的信息(5.1.2.2.1)。

微软C

这个微软诉2010编译器很有趣。该网站说:

main的声明语法是

 int main();

或者,可以选择,

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

或者,mainwmain函数可以声明为返回。void(无返回值)。如果你宣布mainwmain作为返回空,您不能使用返回语句将退出代码返回到父进程或操作系统。若要返回退出代码,请执行以下操作:mainwmain被宣布为void,您必须使用exit功能。

对于我来说,不清楚当程序返回到父程序或o/s时会发生什么(退出代码返回给父程序或o/s)。void main()退出-和MS网站也是沉默的。

有趣的是,MS没有规定main()C和C+标准所要求的。它只规定了三个参数形式,其中第三个参数是char **envp指向环境变量列表的指针。

微软的网页还列出了其他一些选择-wmain()这需要很宽的字符串,还有更多。

Microsoft与2005版本的本页不列void main()作为另一种选择。这个版本从微软到2008年以后。

int main()int main(void)?

有关详细分析,请参阅我对什么应该main()返回C和C+..(我似乎曾经认为这个问题指的是C+,尽管它没有而且从来没有提到过。在C+中,int main()int main(void)int main()是习语C+)

在C中,这两种符号之间有区别,但您只注意到在深奥的情况下。具体来说,如果您调用main()函数从您自己的代码中执行,您可以在C中执行,而在C+中不允许这样做。

这个int main()表示法不提供main(),但只有当您递归地调用它时,这才重要。带着int main(),您可能稍后(在同一个函数中或在另一个函数中)写入int rc = main("absolute", "twaddle", 2):在形式上,编译器不应该抱怨到拒绝编译代码的程度,尽管它可能会合理地抱怨(警告您)(并使用-WerrorGCC将把警告转化为错误)。如果你用int main(void)的后续呼叫main()应该产生一个错误-你说过这个函数不带参数,但试图提供三个。当然,你不能合法地打电话main()在声明或定义它之前(除非您仍然使用C90语义)-而且实现不声明原型main()..注:C11标准说明了两者int main()int main(void)在不同的例子中,两者在C中都是有效的,尽管它们之间有细微的区别。


查看完整回答
反对 回复 2019-06-26
?
偶然的你

TA贡献1841条经验 获得超3个赞

POSIX支持execve(),这反过来又支持

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

添加的参数是环境,即表单name=value的字符串数组。


查看完整回答
反对 回复 2019-06-26
  • 3 回答
  • 0 关注
  • 602 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信