我一直认为argc
需要argv
来标记argv[argc] == NULL
的结尾,但我根据定义才知道argc
。我是否正确地认为C
完全是多余的?如果是这样,我总是认为<html>
<body>
<img src = 'http://www.nationaldentalreviews.org/Handlers/ImageDisplay.ashx?qUID=8597&qType=__ProfileMicroSite'>
</body>
</html>
以效率的名义带来了冗余。我的假设是错误的还是背后的历史原因?如果原因是历史性的,你能详细说明吗?
答案 0 :(得分:6)
历史。
Harbison&amp;钢铁(第5版,9.9和#34;主程序&#34;)说明如下:
标准C要求
argv[argc]
为空指针,但在某些较旧的实现中则不然。
答案 1 :(得分:3)
这是历史。
在早于C的第一版UNIX中,exec将文件名作为参数,并将指向NUL终止的参数字符串的指针列表的地址作为NULL指针终止。从手册页:
sys exec; name; args / exec = 11.
name: <...\0>
...
args: arg1; arg2; ...; 0
arg1: <...\0>
...
内核对参数进行了计算,并在堆栈顶部为新映像提供了arg计数,后跟一个指向参数字符串副本的指针列表。从手册页:
sp--> nargs
arg1
...
argn
arg1: <arg1\0>
...
argn: <argn\0>
(内核源代码是here;我还没看过内核是否真的在指向最后一个参数的指针之后写了一些内容。)
在某些时候,直到第6版,exec,execl和execv的文档开始注意到内核在arg指针之后放置了-1
。该手册页说:
Argv不能直接在另一个execv中使用,因为argv [argc]是-1而不是0。
此时,您可能会认为argc
是多余的,但程序在一段时间内一直在使用它而不是查看-1
的参数列表。例如,这是cal.c的开头:
main(argc, argv)
char *argv[];
{
if(argc < 2) {
printf("usage: cal [month] year\n");
exit();
}
在第7版中,exec被更改为在参数字符串后面添加一个NULL指针,然后是一个指向环境字符串的指针列表,另一个是NULL。该手册页说:
Argv可直接在另一个execv中使用,因为argv [argc]为0。