【问题标题】:C command line arguments - Where is the argv char array?C 命令行参数 - argv char 数组在哪里?
【发布时间】:2015-04-08 02:44:48
【问题描述】:

我想参考以下与我的问题相关的代码。

#include <stdio.h>  
int main(int argc, char *argv[]) {           
    printf("%c\n", argv[1][1]);                
    return 0;
}

通常在创建指针之前,首先必须存在变量。但在 C 命令行参数中,*argv[] 不是指已定义的char argv,而是实际上是一个二维数组,其中不仅包含地址,还包含命令行参数的元素。这怎么可能发生。我会欣赏这背后的理论。

我的第二个问题是指针数组如何包含命令行参数的元素?

【问题讨论】:

  • 这是由操作系统和 C 运行时库的启动代码完成的。
  • 另外,考虑到一个函数必须被调用才能执行——但是谁打电话给你的main()?魔法!至于“指针数组如何包含命令行参数的元素”——因为命令行参数是字符串,而在 C 中,字符串通常由指向其第一个字符的指针来引用。
  • 相关(如果不是重复):stackoverflow.com/q/12332/694576

标签: c arrays


【解决方案1】:

有一些代码在main 之前运行。实际上这段代码调用了main函数。

这段代码是什么? F.e.它会启动stdinstdoutstderr 等变量。它解析命令行并准备argv 数组。

请参阅http://en.wikipedia.org/wiki/Crt0 了解更多信息。

【讨论】:

    【解决方案2】:

    简短的回答是:

    1) 操作系统向新进程传递argc、argv[] ...等启动参数

    2) 大多数 C 实现都有一个“CRT0”库调用,该调用在执行之前“main()”被执行。 CRT0 的工作之一是将 argv[] 从 OS 程序加载器传递到 C 程序的“main()”。

    这里有更多细节:

    http://wiki.osdev.org/Creating_a_C_Library

    在 C 库中实现的第一个也是最重要的事情是 _start 函数,控制从程序加载器传递给该函数。它的任务是初始化和运行进程。通常这是完成的 通过初始化 C 库(如果需要),然后调用全局 构造函数,最后调用 exit(main(argc, argv))。

    ...

    the_start 函数调用 initialize_standard_library。注意程序加载器寄存器的使用如何很好地适应 x86_64 SysV 调用 约定,以及 initialize_standard_library(int argc, char* argv[], int envc, char* envp[]) 函数接受与 _开始。

    另见man execvp(3)

    【讨论】:

      【解决方案3】:

      有一些依赖于实现的方式来启动可执行文件,并通过它从主机环境接收或检索信息。对于 C 程序,该过程的一部分导致命令行参数存储在数组中。然后以某种方式调用main(),并给出适当的argc和argv值。

      这可以由主机系统自己完成(例如操作系统设置好,然后直接调用程序的main()),也可以在程序可执行文件开始执行后完成(例如程序中有启动代码可执行本身检索命令行信息,将其打包,然后调用 main())。

      【讨论】:

        【解决方案4】:

        调用 main() 函数(与其他函数一样)的 C 运行时库也设置并传入 3 个参数:(argc, argv, envp) 这是内置在引导代码中的,该代码开始运行所有已编译的 C 程序;在调用 main() 时,命令行已被读取并标记化并由 argv 指向。

        Argv 不是二维的,是 char* 指向文本的指针的一维数组;每个文本字符串都已复制到其自己的 char 数组中,该数组存储在其他地方。

        【讨论】:

          【解决方案5】:

          当系统(操作系统和标准库)通过调用函数 main(您必须提供)启动您的程序时,它会设置一个包含指向命令行参数字符串的指针的数组。 main 将使用两个参数调用:命令行参数的数量和数组本身。

          参考:https://www.gnu.org/software/libc/manual/html_node/Program-Arguments.html

          【讨论】:

            【解决方案6】:

            函数参数是变量声明(例如 int argc 是主函数中的局部变量)。 argv[] 是存储字符串地址的指针数组。由编译器为调用主函数而准备的代码分配的指针和字符串的内存,因此只有一个 int 和一个指针被分配给主函数的局部变量(argv 和 argc)。

            【讨论】:

              猜你喜欢
              • 2016-05-06
              • 2020-05-19
              • 2011-01-29
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2017-12-21
              • 2020-01-23
              • 2013-06-13
              相关资源
              最近更新 更多