【问题标题】:How do command line arguments work?命令行参数如何工作?
【发布时间】:2012-03-11 16:09:46
【问题描述】:

正如问题所提到的,命令行参数如何在 C 中工作(通常是任何语言)。我能想到的合乎逻辑的解释是,操作系统在进程启动时为其设置了某种环境值。 但如果这是真的,我应该无法以 argp[i] 等方式访问它们(我修改了 main 以期望第二个参数为 char **argp 而不是 **argv)。请解释一下。

【问题讨论】:

  • 为什么你认为你不应该能够以 argp[i] 的身份访问它们? (注意,函数参数名在编译的程序中通常没有意义,将 2. 参数命名为 main argv 只是一种约定,如果你愿意,可以将其命名为 FOOBAR
  • main 的参数与任何其他函数的参数一样。名称并不重要,您甚至可以在函数原型和实际函数中使用不同的参数名称,只要类型匹配即可。 main 的参数来自哪里并不重要,只需将它们视为任何整数和指针数组(或在您的情况下为指向指针的指针)。

标签: c command-line-arguments


【解决方案1】:

无论你给主要参数起什么名字,重要的是它们的类型和顺序。要获取环境变量,请使用此闭包:

int main(int argc, char ** myCommandLineArguments, char ** myEnvironmentVars)

这是你想知道的吗?

【讨论】:

  • 感谢您的回答。实际上,我的问题不是关于如何访问它们,而是关于谁以及如何使它们对程序可用。
【解决方案2】:

在 C 程序中,操作系统会创建一个指向零终止字符串的指针数组。计数作为argc 传递,数组作为argv 传递。你已经知道了。 argcargv 的名称无关紧要。您可以使用任何名称。数据类型和顺序很重要...argv 必须是 intargc 必须是 char*[]char**。其他语言也有类似的机制。例如,C# 传递一个 string[] 参数,它是一个 .NET 数组,并在内部跟踪它的长度。更多信息请点击此处:http://en.wikipedia.org/wiki/Main_function#C_and_C.2B.2B

环境变量名与程序中的变量名是分开的。 argcargv 不是环境变量...它们是 main() 的本地变量。

要访问环境变量,请使用getenv()

更新:您想知道这些是如何提供给程序的。正是操作系统做到了这一点。但是在操作系统可以这样做之前,调用您的可执行文件的程序——调用者——开始处理你的命令行。通常调用者是一个 shell(bashcshzshcmd.exe)或者像 GNOME 或 Windows 资源管理器这样的桌面环境。调用者通过execve(在*nix 上)或CreateProcess(在Windows 上)传递这些参数。

【讨论】:

    【解决方案3】:

    我将尝试比其他答案更多地解释实现。
    我确信其中存在不准确之处,但希望它对相关部分的描述足够好。

    在 shell 下,输入./myprog a b c
    Shell 对其进行解析,并确定您要使用三个参数运行 ./myproj
    它调用fork,创建一个新进程,./myprog 将在其中运行。
    仍在运行 shell 程序的子进程准备了一个由 5 个字符指针组成的数组。第一个将指向字符串./prog,接下来的三个指向字符串abc,最后一个设置为NULL。
    接下来,它调用execve 函数,在创建参数数组的情况下运行./myprog
    execve./myprog 加载到内存中,而不是shell 程序。它会释放由 shell 程序分配的所有内存,但要确保保留参数数组。
    在新程序中,main 被调用,参数数组作为argv 传递给它。

    【讨论】:

    • 为什么execve 不需要argc 参数?
    • 其实数组会包含五个条目,不要忘记第一个(第零个)位置的程序名。
    • 它可能会使用除 fork-exec 之外的其他机制来实际创建新进程。这完全取决于操作系统,对于这个问题来说,这并不重要。无论操作系统和 shell 使用何种机制来运行命令,它都必须涉及传递命令行参数。这是类 UNIX 的处理方式,其中参数由 fork“克隆”和“生存”execve
    • @JoachimPileborg,感谢您的更正,我编辑了答案。
    • @SteveJessop,你说得对,我解释了一种实现,这可能不是对任何操作系统的准确描述。但我认为描述一个可以使用的简单机制通常有助于更好地理解事情,而不是仅仅说你保证会得到什么。
    猜你喜欢
    • 2011-06-15
    • 2018-04-29
    • 1970-01-01
    • 1970-01-01
    • 2019-12-12
    • 2011-04-08
    • 1970-01-01
    • 2016-03-25
    • 1970-01-01
    相关资源
    最近更新 更多