(*++argv)[0] 和 while(c = *++argv[0]) 的区别 [英] Difference between (*++argv)[0] and while(c = *++argv[0])

查看:28
本文介绍了(*++argv)[0] 和 while(c = *++argv[0]) 的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码片段:

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;
          }

     ...
}

<小时>

包含以下表达式:


Containing the following expressions:

while(--argc > 0 && (*++argv)[0] == '-')

括号中的表达式(*++argv)[0] 与没有括号的while(c = *++argv[0]) 有区别吗?

Does this expression in the parentheses (*++argv)[0] differ from while(c = *++argv[0]) without parentheses?

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

If so, how? Does (*++argv) mean pointer to the next argument, and does *++argv[0] mean pointer to the next character in the current char array which is being pointed to?

推荐答案

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

First, K&R have an errata on this particular snippet:

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

117(§5.10): In the find example, the program increments argv[0]. This is not specifically forbidden, but not specifically allowed either.

现在开始解释.

假设您的程序名为 prog,并且您使用以下命令执行它:prog -ab -c Hello World.您希望能够解析参数以说明指定了选项 abc 以及 Hello> 和 World 是非选项参数.

Let's say your program is named prog, and you execute it with: prog -ab -c Hello World. You want to be able to parse the arguments to say that options a, b and c were specified, and Hello and World are the non-option arguments.

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

argv is of type char **—remember that an array parameter in a function is the same as a pointer. At program invocation, things look like this:

                 +---+         +---+---+---+---+---+
 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
                 +---+

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

Here, argc is 5, and argv[argc] is NULL. At the beginning, argv[0] is a char * containing the string "prog".

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

In (*++argv)[0], because of the parentheses, argv is incremented first, and then dereferenced. The effect of the increment is to move that argv ----------> arrow "one block down", to point to the 1. The effect of dereferencing is to get a pointer to the first commandline argument, -ab. Finally, we take the first character ([0] in (*++argv)[0]) of this string, and test it to see if it is '-', because that denotes the start of an option.

对于第二个构造,我们实际上想要遍历当前 argv[0] 指针指向的字符串.所以,我们需要把 argv[0] 当作一个指针,忽略它的第一个字符(也就是我们刚刚测试的 '-' ),并查看其他字符:

For the second construct, we actually want to walk down the string pointed to by the current argv[0] pointer. So, we need to treat argv[0] as a pointer, ignore its first character (that is '-' as we just tested), and look at the other characters:

++(argv[0]) 将增加 argv[0],以获得指向第一个非 - 字符的指针,并取消引用它会给我们那个字符的值.所以我们得到 *++(argv[0]).但是由于在 C 中,[]++ 绑定得更紧密,我们实际上可以去掉括号,得到我们的表达式为 *++argv[0].我们要继续处理这个字符,直到它是 0(上图中每一行的最后一个字符框).

++(argv[0]) will increment argv[0], to get a pointer to the first non- - character, and dereferencing it will give us the value of that character. So we get *++(argv[0]). But since in C, [] binds more tightly than ++, we can actually get rid of the parentheses and get our expression as *++argv[0]. We want to continue processing this character until it's 0 (the last character box in each of the rows in the above picture).

表达

c = *++argv[0]

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

assigns to c the value of the current option, and has the value c. while(c) is a shorthand for while(c != 0), so the while(c = *++argv[0]) line is basically assigning the value of the current option to c and testing it to see if we have reached the end of the current command-line argument.

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

At the end of this loop, argv will point to the first non-option argument:

                 +---+         +---+---+---+---+---+
                 | 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
                 +---+

这有帮助吗?

这篇关于(*++argv)[0] 和 while(c = *++argv[0]) 的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆