【发布时间】: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 的指针,同时引用上述标准声明。
提前致谢。
【问题讨论】:
-
由于
argc是argv数组中的元素数,因此有效条目的最高索引是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的技术定义为具有某种形式的宏)。