为什么main(int argc, char* argv[])接受两个参数?



我一直认为argc需要标记argv的结尾,但我刚刚了解到argv[argc] == NULL的定义。我认为argc是完全多余的,对吗?如果是这样,我一直认为C以效率的名义消除了冗余。是我的假设错了,还是这背后有历史原因?如果是历史原因,你能详细说明吗?

历史记录

,哈比森《钢铁》(第5版,9.9"主程序")说:

标准C要求argv[argc]为空指针,但在一些旧的实现中并非如此。

历史记录

在第一版UNIX中(比C早),exec接受一个文件名和一个指针列表的地址作为参数,该列表指向以NULL指针结束的以NULL结尾的参数字符串。从手册页:

sys exec; name; args      / exec = 11.
name: <...>
...
args: arg1; arg2; ...; 0
arg1: <...>
...

内核对实参进行计数,并向新映像提供位于堆栈顶部的arg计数,后面是指向实参字符串副本的指针列表。从手册页:

sp--> nargs
      arg1
      ...
      argn
arg1: <arg1>
...
argn: <argn>

(内核源代码在这里;我还没有看到内核是否真的在指向最后一个参数的指针之后写了一些东西。)

从第6版开始,exec、execl和execv的文档开始注意到内核在参数指针后面放置了一个-1。手册页说:

Argv不能直接在另一个execv中使用,因为Argv [argc]是-1而不是0。

此时,您可能会认为argc是多余的,但是一段时间以来,程序一直使用它而不是查找-1的参数列表。例如,下面是cal.c的开头:
main(argc, argv)
char *argv[];
{
    if(argc < 2) {
        printf("usage: cal [month] yearn");
        exit();
    }

在第7版中,exec被更改为在参数字符串之后添加一个NULL指针,后面跟着一个指向环境字符串的指针列表,以及另一个NULL。手册页说:

Argv可以直接在另一个execv中使用,因为Argv [argc]是0。

最新更新