【问题标题】:How does main() handle a variable number of arguments without ellipses? [closed]main() 如何在没有省略号的情况下处理可变数量的参数? [关闭]
【发布时间】:2014-12-21 07:55:04
【问题描述】:

main() 函数如何在不使用省略号 (...) 的情况下处理可变数量的参数?对于处理可变数量的参数,函数的最后一个参数应该是...,而main() 函数则不是这样。

【问题讨论】:

  • 它得到一个指向 char* 数组的指针...
  • 只需用谷歌搜索main 的签名,即对于初学者来说,这个网站上有很多问题
  • 参考this
  • 如果调用代码提供的参数比被调用函数预期的多,如果调用代码负责根据传递的参数数量在返回后恢复堆栈,则不会导致问题。未使用的参数将被忽略。

标签: c++ c


【解决方案1】:

基本上,main() 是特殊的,它有两种标准定义的形式:

int main(int argc, char **argv)
int main(void)

系统可能支持其他形式;环境也可以使用是很常见的:

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

这些表格是固定的。唯一不寻常的是,系统必须支持前两个中的任何一个(有些系统也支持其他系统)。

与 POSIX 中的 execl() 不同,通过指向字符串的指针数组(即上面的 argv)处理可变数量的命令行参数。

另见:


rahul manglanicommented:

你提到的两个链接很清楚。那里列出了不同的可能方法,但没有提到实际使用的方法。

从某种意义上说,没关系;系统必须工作,而生产“系统”的人必须使其工作。作为使用系统的程序员,你不需要知道它是如何工作的;您可以简单地假设它确实有效。

在幕后,通常会发生调用main() 的“启动”函数进行一些修复工作(特别是在 C++ 程序的情况下,很多修复工作 - 例如确保所有构造函数必须在main()starts 实际上执行之前执行),但以固定顺序结束,例如:

exit(main(argc, argv, environ));

请注意,environ 是一个全局变量,extern char **environ;(在 POSIX 定义的全局变量中是唯一的,因为没有头文件声明它),它包含指向环境变量的指针。 “开始”代码必须确保已设置;因此,将environ 作为参数传递给main() 是微不足道的。

这会使用固定的参数列表调用main(),如果/当它返回时调用exit()。事实上,Apple 更进一步,将第四个参数传递给main()。如果被调用的函数被定义为int main(void) { … },它会简单地忽略它传递的参数;如果它被定义为int main(int argc, char **argv) { … },它可以像往常一样访问命令行参数;如果定义为int main(int argc, char **argv, char **envp) { … },那么它也可以访问环境。

通常,系统的设置是为了避免额外的参数造成损害。这就是为什么 C 在其调用约定中不寻常的原因,也是被调用函数不清理压入堆栈的参数的原因——被调用函数不知道实际压入堆栈的参数有多少。它假定提供了它期望的那些并使用那些没有问题的,但调用代码知道它推送了什么,因此它可以正确清理。如果被调用函数需要 N 个参数,但调用者传递了 M 个参数并且 M

【讨论】:

  • 谢谢乔纳森。你提到的两个链接说得很清楚。那里列出了不同的可能方法,但没有提及实际使用的方法。
【解决方案2】:

在 C/C++ 中 main 有 2 个参数,通常称为 argcargvargv 参数是 argc char 数组的数组。命令行参数在argv 中传递给程序。这个主题有不同的参数数量,但 main 的签名通常是

int main(int argc, char **argv);

【讨论】:

    【解决方案3】:

    我将这个问题解释为:main 怎么可能接受零个参数或两个参数?

    虽然细节显然取决于实现,但在大多数实现中,默认的 C 调用约定是调用者清理堆栈。因此,无论main 的声明是什么,调用main 的代码总是可以将两个参数压入堆栈(argcargv)。如果main 声明时没有参数,那么main 根本不会访问它接收到的参数的值。 main返回后,调用代码清栈。

    应该指出,main 在这个意义上甚至没有什么特别之处。试试这个:

    int printf();
    int main() { printf("Hello, world!\n"); }
    

    C 编译器很乐意允许您调用 printf,即使缺少 #include <stdio.h> 指令,它也不知道 printf 实际需要多少参数。据推测,调用main 的代码在概念上是这样的:

    int main(int argc, char** argv); /* declare "main" */
    main(argc, argv);                /* call "main" */
    

    如果main 的定义实际上指定了零参数,这仍然有效(尽管我相信如果您实际上这样做,这在技术上将是未定义的行为。

    在 C++ 的情况下,尽管标准未指定 main 的链接,但大多数实现只是将其视为具有 C 链接,因此名称不会被破坏,以上所有内容仍然适用。

    【讨论】:

      【解决方案4】:

      它通过接受一个数组和数组长度设置为变量argcargv来处理它

      您可以在这里找到更多数据:

      http://crasseux.com/books/ctutorial/argc-and-argv.html

      【讨论】:

        猜你喜欢
        • 2012-12-29
        • 2014-07-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-07-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多