(*++ argv)[0]和while(c =*++ argv [0])之间的区别

Too*_*ool 13 c string pointers argv

我有以下代码片段:

int main(int argc, char *argv[])
{   

     char line[MAXLINE];
     long lineno = 0;
     int c, except = 0, number = 0, found = 0;

     while(--argc > 0 && (*++argv)[0] == '-') //These two lines
        while(c = *++argv[0])                 //These two lines
          switch(c) {
             case 'x':
                  except = 1;
                  break;
             case 'n':
                  number = 1;
                  break;
             default:
                  printf("find: illegal option %c\n", c);
                  argc = 0;
                  found = -1;
                  break;
          }

     ...
}
Run Code Online (Sandbox Code Playgroud)

包含以下表达式:

while(--argc > 0 && (*++argv)[0] == '-')
Run Code Online (Sandbox Code Playgroud)

括号中的这个表达式是否(*++argv)[0]while(c = *++argv[0])没有括号不同?

如果是这样,怎么样?(*++argv)是指向下一个参数的指针,是否指向指向*++argv[0]当前char数组中的下一个字符的指针?

Alo*_*hal 40

首先,K&R在这个特定的片段上有一个勘误表:

117(§5.10):在查找示例中,程序递增argv[0].这不是特别禁止的,但也没有特别允许.

现在来解释一下.

比方说,你的程序被命名为prog和你执行它:prog -ab -c Hello World.你想成为能够分析的论点说,期权a,bc进行了指定,Hello并且World都是非选项参数.

argv类型为char **-remember,函数中的数组参数与指针相同.在程序调用时,事情看起来像这样:

                 +---+         +---+---+---+---+---+
 argv ---------->| 0 |-------->| p | r | o | g | 0 |
                 +---+         +---+---+---+---+---+
                 | 1 |-------->| - | a | b | 0 |
                 +---+         +---+---+---+---+
                 | 2 |-------->| - | c | 0 |
                 +---+         +---+---+---+---+---+---+
                 | 3 |-------->| H | e | l | l | o | 0 |
                 +---+         +---+---+---+---+---+---+
                 | 4 |-------->| W | o | r | l | d | 0 |
                 +---+         +---+---+---+---+---+---+
                 | 5 |-------->NULL
                 +---+
Run Code Online (Sandbox Code Playgroud)

这里argc是5,argv[argc]NULL.一开始,argv[0]是一个char *包含字符串"prog".

(*++argv)[0],因为括号的,argv首先被递增,然后解除引用.增量的作用是将argv ---------->箭头"向下移动一个块",指向1.解除引用的效果是获取指向第一个命令行参数的指针-ab.最后,我们取这个字符串的第一个字符([0]in (*++argv)[0]),并测试它是否是'-',因为它表示一个选项的开始.

对于第二个构造,我们实际上想要沿着当前argv[0]指针指向的字符串向下走.因此,我们需要将其argv[0]视为指针,忽略其第一个字符('-'就像我们刚刚测试过的那样),并查看其他字符:

++(argv[0])将增加argv[0],以获得指向第一个非-字符的指针,并取消引用它将为我们提供该字符的值.所以我们得到了*++(argv[0]).但是因为在C中,[]绑定比++我们更紧密,我们实际上可以摆脱括号并将我们的表达式视为*++argv[0].我们希望继续处理这个字符,直到它0(上图中每行中的最后一个字符框).

表达方式

c = *++argv[0]
Run Code Online (Sandbox Code Playgroud)

分配c当前选项的值c,并具有该值. while(c)是一个简写while(c != 0),所以该while(c = *++argv[0])行基本上是将当前选项的值分配给c并测试它以查看我们是否已到达当前命令行参数的末尾.

在这个循环结束时,argv将指向第一个非选项参数:

                 +---+         +---+---+---+---+---+
                 | 0 |-------->| p | r | o | g | 0 |
                 +---+         +---+---+---+---+---+
                 | 1 |-------->| - | a | b | 0 |
                 +---+         +---+---+---+---+
                 | 2 |-------->| - | c | 0 |
                 +---+         +---+---+---+---+---+---+
 argv ---------->| 3 |-------->| H | e | l | l | o | 0 |
                 +---+         +---+---+---+---+---+---+
                 | 4 |-------->| W | o | r | l | d | 0 |
                 +---+         +---+---+---+---+---+---+
                 | 5 |-------->NULL
                 +---+
Run Code Online (Sandbox Code Playgroud)

这有帮助吗?


Ale*_*own 5

是的,你是对的.

while(--argc > 0 && (*++argv)[0] == '-')
Run Code Online (Sandbox Code Playgroud)

正在逐个扫描命令行参数的数组(长度为argc),查找以-选项前缀开头的数组.对于每一个:

while(c = *++argv[0])
Run Code Online (Sandbox Code Playgroud)

通过该组的后面的第一开关字符扫描-在当前参数(即tn-tn,直至它碰到该字符串空终止\0,终止while循环中,由于它的计算结果为假.

这种设计允许两者

myApp -t -n
Run Code Online (Sandbox Code Playgroud)

myApp -tn
Run Code Online (Sandbox Code Playgroud)

工作和被理解为有选择tn.


小智 5

增加argv是一个非常糟糕的主意,因为一旦你这样做,很难恢复原始值.使用整数索引更简单,更清晰,更好 - 毕竟argv是一个数组!

要回答你的问题,++ argv会增加指针.然后将其应用于间接以获取第一个字符.