在主函数中,char * argv[] 参数是否以空字符结尾?

52
我想知道命令行参数是否始终以空字符结尾。谷歌似乎是肯定的,并且在GCC编译时也表明是这样,但我能保证这总是正确的吗?
int main(int argc, char** argv)
{
    char *p;

    for(int cnt=1; cnt < argc; ++cnt)
    {
        p = argv[cnt];
        printf("%d = [%s]\n", cnt, p);
    }
    return 0;
}

$ MyProgram -arg1 -arg2 -arg3
1 = -arg1
2 = -arg2
3 = -arg3

2
想一想:如果它们没有以NULL结尾,会发生什么? - user703016
1
思考一分钟...char []和char*并不自动意味着C风格字符串。显然,整个命令行字符串是NULL终止的,但这并不必须转换为命令行上传递的每个单独字符数组都是NULL终止的。对于argv来说,将命令行上的空格剥离出来并具有非NULL终止字符数组而不是C风格字符串是很容易的。 - LeviX
@LeviX - 如果字符数组没有以NULL结尾,你怎么能检测到它们的结尾呢? - shf301
@shf301 哦,好的,我明白你的观点了。char* argv[]。如果它们没有以 null 结尾,你怎么知道二维数组中一个字符串从哪里开始,另一个从哪里结束呢?明白了,我改正自己的错误了,现在这很有道理。谢谢。 - LeviX
@LeviX 这与知道每个字符串的结尾位置并能够将其传递给每个期望 NUL 终止符的其他 C 函数有关,与字符串是否在数组中无关。像 char* argv[] 这样的数组不是二维数组;它是指针数组。(在真正的二维数组中,每个字符串肯定必须具有相同的长度,因此我们不需要终止符?)所指向的对象不必相邻。也就是说,在这里,并不要求每个连续指针指向的地址必须在前一个编号参数的 NUL 终止符后 1 字节。 - underscore_d
2个回答

88

是的。在argv数组中非空指针指向C字符串,这些字符串按定义是以null结束的。

C语言标准简单地规定了数组成员“应包含指向字符串的指针”(C99 §5.1.2.2.1/2)。字符串是“由包括第一个null字符在内的一系列连续字符组成的”(C99 §7.1.1/1),因此它们按定义是以null结束的。

此外,在argv[argc]处的数组元素是空指针,因此从某种意义上说,该数组本身也是“以null结束”的。


能否解释一下当 argv 以 null 结尾时 argc 的用法。我们不能通过遍历数组直到遇到 '\0' 来检测参数的数量吗? - Snehasish
1
@Snehasish 是的,你可以从 argv 计算出 argc。至于为什么 main 有它自己的签名,我不确定。这个签名在我的存在之前就已经存在了。 - James McNellis
2
@Snehasish:只是为了好玩,我在Retrocomputing S.E.上问了这个问题——它是ANSI C之前的遗留物:https://retrocomputing.stackexchange.com/questions/5179/why-historically-include-the-number-of-arguments-argc-as-a-parameter-of-main - tonysdg
1
数组的最后一个元素是空指针,但是如果没有参数字符串,则可以具有argc == 0(尽管这非常少见并需要仔细设置)。 如果命令名称不可用但存在其他参数,则标准规定argv[0]应为空字符串,而不是空指针。 - Jonathan Leffler

4

是的,参数始终是以空字符结尾的字符串。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接