为啥 argv[argc] 是指向 NULL 的指针?

Posted

技术标签:

【中文标题】为啥 argv[argc] 是指向 NULL 的指针?【英文标题】:Why is argv[argc] a pointer to NULL?为什么 argv[argc] 是指向 NULL 的指针? 【发布时间】:2020-04-22 20:30:43 【问题描述】:

在 C 标准 ISO/IEC 9899:2018 (C18) 中,第 5.1.2.2.1 节 - “程序启动”是这样写的:

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

——argv[argc] 应该是一个空指针。


我的问题是:

为什么char *argv[argc]/char **argv应该/是指向NULL的指针?

这对我来说没有意义。 argv[] 是一个指向 char 的指针数组。 argv 是一个指向指针数组的指针,指向char。即使调用没有给出标志,指针也不应该变成指向NULL的指针。

char* argv[] 不是指向char 的指针数组,char **argv 不是指向char 指针的嵌套指针吗?指向char (char**) 的嵌套指针如何成为指向NULL 的指针?


我已经阅读了argv[argc] ==? 的答案,其中引用了标准中的上述短语作为答案,并且还向@pmg´s answer 提出了问题,@pmg´s answer 给了我答案:

独立于使用的名称,由 c 规范 char *argv[argc] 声明一个名为 argv 的数组,该数组能够保存指向 char 的 argc 指针。当传递给函数时,数组被转换为指向其第一个元素的指针(因此指向 char 指针的指针 [这就是为什么通常会看到 main(int argc, char **argv)])丢失有关大小的信息(char *a[10] 有 10 个元素;char **a 是一个指针 --- 如果指针指向一个数组,则无法知道底层数组有多少个元素)。

但不幸的是,尽管付出了不起的努力,我仍然无法理解为什么指向 char (char**) 的指针(嵌套指针)变成指向 NULL 的指针。

Is argv[argc] equal to NULL Pointer 的答案也没有回答 为什么 它应该是指向 NULL 的指针,只是 指向 NULL 的指针,同时引用上述标准声明。


提前致谢。

【问题讨论】:

由于argcargv 数组中的元素数,因此有效条目的最高索引是argc-1。也就是说,最后一个“参数”是argv[argc-1]。从技术上讲,这可能会使argv[argc] 未定义。选择使其为 NULL。这样做是提供了循环遍历参数列表的其他方法(检查 NULL 而不是使用 argc 作为循环计数)。 “为什么”需要参考 1970 年的数据/作者 - 否则我们只能猜测。 argv[argc] 不是指向NULL 的指针。它是一个空指针。它的NULL。它不指向NULL @qwerty_url: NULL 是(实际上)指针可以具有的值。 (我说“有效”是因为它和“空指针常量”的技术定义在这里不相关。)指针要么指向某个对象或函数,要么是空指针(在这种情况下它不指向到任何对象或功能)。如果我们考虑一些具有定义值的char *x,那么x 要么指向char,要么它是一个空指针。如果是空指针,则不指向任何东西;它不指向NULL @qwerty_url:如果我们有一个char **p,那是一个指向指针的指针,所以它可以指向我们存储空指针的某个地方。即便如此,这将是一个指向空指针的指针;它不是指向NULL 的指针(由于NULL 的技术定义为具有某种形式的宏)。 【参考方案1】:

这样做有两个原因:

    1234563文件。

    为方便起见:这样你就可以在不知道argc的情况下使用argv

它是如何工作的:

真的没有什么神奇的,这里是内存布局:

char**  |    char*     |  char[]
--------+--------------+---------
argv -> | argv[0] ->   | "arg1"
        | argv[1] ->   | "arg2"
        | argv[2] NULL |

【讨论】:

这没有回答所提出的问题。这回答了为什么argv[argc]NULL,但问题是(错误地)问为什么argv[argc] 是指向NULL 的指针。【参考方案2】:

来自

国际标准编程语言 C 的基本原理 修订版 5.10 2003 年 4 月

5.1.2.2.1 程序启动

argcargv 的规范作为 ma​​in 的参数 承认广泛的先前实践。 argv[argc] 必须是 为列表末尾提供冗余检查的空指针, 也是根据惯例。


更新: 正如 Eric Postpischil 所指出的,这回答了为什么 argv[argc] 是一个空指针。当然argv[argc] 不是 指向 NULL 的指针,正如问题中所问的那样(NULL 是一个定义为空指针常量的宏;指向NULL 没有意义)。所以问题和答案可能会变得毫无意义。

【讨论】:

@EricPostpischil 够公平的。已更新。【参考方案3】:

什么意思

——argv[argc] 应该是一个空指针。

数组argv的索引argc是空指针吗?

那是

if (argv[argc] == NULL)

总是会成真。

【讨论】:

【参考方案4】:

IMO 这是为了方便while(*argv != NULL) ....

【讨论】:

以上是关于为啥 argv[argc] 是指向 NULL 的指针?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 main(int argc, char* argv[]) 需要两个参数? [复制]

为啥要检查 (*argv == NULL)? [复制]

main(argc,argv[])

int main(int argc,char *argv[])与int main(int argc,char **argv)区别?

main中的argv和argc

将“argc”拼写为“argv”会导致 char ** 和 int 之间的比较 - 为啥?