【问题标题】:What is the output of this C code (run without any command line arguments)?此 C 代码的输出是什么(不带任何命令行参数运行)?
【发布时间】:2017-09-16 23:38:21
【问题描述】:

这段 C 代码的输出是什么(不带任何命令行参数运行)?

#include <stdio.h>
int main(int argc, char *argv[])
 {
    while (*argv  !=  NULL)
    printf("%s\n", *(argv++));
     return 0;
}

在这个程序中,argv给出了char指针数组的基地址

while(*argv !=NULL) 

条件为真,这应该给出编译时错误,因为 *(argv++),不是吗?但它显示了一些输出,为什么?

【问题讨论】:

  • 在显示的代码中,char *argv[]char **argv 完全相同 100%。我更喜欢最后一种格式:任何地方都没有数组。您可能想阅读c-faq 的第 6 部分。
  • @pmg: true - 我想我对 conceptual 数组(在这种情况下是一个连续的指针序列)和严格的“C 语言”中的数组进行了心理区分律师”的感觉。
  • @Ananya: ./prog 是命令行的第一部分——通常是用来调用程序的名称(但不一定)。在这种情况下,它只是运行一个名为prog 的程序,没有更多的命令行参数。没有编译错误,因为代码没有任何问题。
  • @Ananya:您阅读以下任何答案和cmets 吗? argv[] 包含程序名称(在元素 0 中)和任何命令行参数(在元素 1..argc-1 中)。

标签: c command-line-arguments argv argc


【解决方案1】:

无耻地引用 C11 规范,第 5.1.2.2.1 章,(强调我的

——argc 的值应为非负数。

argv[argc] 应为空指针。

——如果argc的值大于零,数组成员argv[0]through argv[argc-1] inclusive 应包含指向字符串的指针,这些指针是给定的 在程序启动之前由宿主环境定义的实现值。 意图是向程序提供在程序启动之前确定的信息 来自托管环境中的其他地方。如果宿主环境不能 提供带有大写和小写字母的字符串,实现 应确保以小写形式接收字符串。

——如果argc的值大于零,则argv[0]指向的字符串 代表程序名称; argv[0][0] 应为空字符,如果 程序名称在主机环境中不可用。 如果 argc 的值为 大于一,argv[1]argv[argc-1] 指向的字符串 表示程序参数。

上面的sn-p就是简单的打印提供的程序参数。

  • *argv != NULL 是检查我们没有到达 argv 数组的末尾。
  • printf("%s\n", *(argv++));,我们来分解一下,

    printf("%s\n", *argv));  //print the string pointed to by `argv`
    argv++;                  //increment argv to point to the next string 
    

现在,进入“标题”中的问题

[...](不带任何命令行参数运行)?

好吧,在这种情况下,argc 的值为1,并且只有argv[0] 持有指向包含程序名称的字符串的指针。 argv[1] 指向 NULL(或类似的空指针)。

所以,在循环中

  • 第一个条件检查成功(*argv == argv[0] 不为 NULL),打印程序名称
  • argv 作为后增量的副作用而递增。
  • 第二次迭代,*argv现在和argv[1]一样,为NULL,条件为假,到达最后的return语句。

正文中的问题

这应该是因为*(argv++)而导致编译时错误,不是吗?

不,不是。引用章节§6.7.6.3

将参数声明为‘‘数组类型’’应调整为‘‘限定指针 type'',其中类型限定符(如果有)是在 [ 和 ] 中指定的那些 数组类型推导。 [...]

因此,argv 是一个可修改的左值,可以在这里用作后缀自增运算符的操作数。

【讨论】:

  • 您可能还想解释一下,虽然命令行参数是char *argv[],但在函数内它衰减为char **argv,这使得增加argv是合法的,即argv++ -我认为这可能是让 OP 感到困惑的事情之一。
  • @PaulR 我想我终于做得更好了,您能评论一下先生吗?
猜你喜欢
  • 1970-01-01
  • 2016-12-01
  • 1970-01-01
  • 2011-08-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多