为什么我们需要argc而argv末尾总是有一个null?


116

似乎argv[argc]总是NULL如此,因此我认为我们可以不用遍历参数列表argc。一个while循环就可以做到这一点。

如果总是NULL在结尾处argv,为什么我们需要一个argc


17
这可能是为了方便。如果没有足够的参数,则程序员可以轻松地进行早期救援,而无需循环。否则,我们肯定会调用一些函数来int argc(char *argv[])执行此操作:
cnicutar

5
请注意,它"\0"与NULL指针不同(0相当于C ++中的NULL)
Mats Petersson

31
如果我们有argc,为什么我们需要argv [argc]为NULL?
2013年

7
您还如何确定恒定时间内的参数数量?
avakar 2013年

4
不要认为linux / unix标签在这里合适,因为这种行为对于所有操作系统中的所有编译器都应如此。
2013年

Answers:


106

是的,argv[argc]==NULL有保证。参见C11 5.1.2.2.1程序启动(我的重点是)

如果声明了它们,则主函数的参数应遵守以下约束:

argc的值应为非负数。 argv [argc]应为空指针。

argc因此,提供并不是至关重要的,但仍然有用。除其他外,它允许快速检查是否已传递了正确数量的参数。

编辑:该问题已被修改为包括C ++。n3337草案3.6.1主要功能

2 ... argc是从运行程序的环境传递到程序的参数数。.... argc的值应为非负数。argv [argc]的值应为0


36
而且argc可能是相当大的,因为外壳是做扩展(所以ls **由前壳扩展execve/bin/ls可执行文件)。在我的系统上,我可以拥有argc数十万个。
Basile Starynkevitch

这很酷,因为我一直认为argc足够,所以这从来没有发生过,但是我绝对可以想到这种保证是相关的甚至是必要的情况。+1
托马斯

6
@BasileStarynkevitch与生成指针数组所花费的时间相比,仅一步步遍历指针值数组直到获得NULL的时间是微不足道的,与在程序中实际使用每个参数值相比,这无关紧要。而且,如果仅检查参数计数是否大于N,则不需要遍历整个数组。但是,我完全同意,那argc是过去,也是一件好事。
海德

43

是的,argv[argc]保证是空指针。argc为方便起见。

引用C99基本原理的官方解释,请注意冗余检查一词:

国际标准的理由-编程语言 -C§5.1.2.2.1 程序启动

的规范argcargv作为main广泛认可的先验实践的论据。argv[argc]也是根据惯例,必须为空指针,以提供对列表末尾的冗余检查。


19

这是出于历史原因,并且与旧代码兼容。最初,不能保证存在一个空指针作为argv数组的最后一个元素。但是argc 一直存在。


...某种程度上是一种耻辱。如果我们有int main(char *argv[], int argc, ...),则某些程序可能会忽略argc它们,因为它们不需要它。相反(需要argc而不是argv)在实际程序中可能永远不会有用。
海德

@hyde:请参阅上文Basile Starynkevitch的评论
zentrunix

6

我们“需要”它,因为各种标准都要求它。

我们可以完全忽略该值,但是由于它是的第一个参数main,因此必须在参数列表中包含它。在C ++(可能是非标准C语言)中,您可以省略参数名称,例如C ++代码片段(易于转换为C):

#include <stdio.h> // C-compatible include, guarantees puts in global namespace

// program will print contents of argv, one item per line, starting from argv[0]

int main(int /*argc*/, char *argv[]) { // uncomment argc for C

    //(void)argc; // uncomment statement for C

    for (int i=0; argv[i]; ++i) {
        puts(argv[i]);
    }

    return 0;
}

在标准C中,使用通用警告设置,未使用的参数会生成警告,该警告可以通过一条语句进行修复,例如(void)argc;,该语句无需使用任何代码即可使用该名称。

argc很高兴,因为否则许多程序将需要遍历参数来获取计数。而且,在许多编程语言中,数组的长度是一定的,没有任何argc参数,只有一个包含项的数组。


问题是关于C和C ++的。在C中,参数名称是必需的。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.