问题描述
我有以下代码片段:
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]
.这不是特别禁止,但也不是特别允许.
现在开始解释.
假设您的程序名为 prog
,并且您使用以下命令执行它:prog -ab -c Hello World
.您希望能够解析参数以说明指定了选项 a
、b
和 c
以及 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]) 的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!