- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有以下代码片段:
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;
}
...
}
包含以下表达式:
while(--argc > 0 && (*++argv)[0] == '-')
括号 (*++argv)[0]
中的表达式与不带括号的 while(c = *++argv[0])
有区别吗?
如果可以,怎么做? (*++argv)
是否表示指向下一个参数的指针,*++argv[0]
是否表示指向当前 char 数组中的下一个字符的指针被指着?
最佳答案
首先,K&R 对这个特定片段有一个勘误表:
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
。您希望能够解析参数以表明指定了选项 a
、b
和 c
,以及 Hello
和 World
是非选项参数。
argv
是 char **
类型——记住函数中的数组参数与指针相同。在程序调用时,事情看起来像这样:
+---+ +---+---+---+---+---+
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]
是一个包含字符串 "prog"
的 char *
。
在(*++argv)[0]
中,由于括号的原因,argv
先递增,然后解引用。增量的效果是将 argv ---------->
箭头“向下移动一个 block ”,指向 1
。解除引用的作用是获得指向第一个命令行参数 -ab
的指针。最后,我们取这个字符串的第一个字符([0]
in (*++argv)[0]
),测试它是否是'-'
,因为它表示选项的开始。
对于第二个构造,我们实际上想要遍历当前 argv[0]
指针所指向的字符串。所以,我们需要把argv[0]
当作一个指针,忽略它的第一个字符(也就是我们刚才测试的'-'
),再看其他字符:
++(argv[0])
将递增 argv[0]
,以获得指向第一个非 -
字符的指针,并取消引用它会给我们那个角色的值(value)。所以我们得到 *++(argv[0])
。但由于在 C 中,[]
比 ++
绑定(bind)得更紧密,我们实际上可以去掉括号并得到我们的表达式 *++argv[0 ]
。我们要继续处理这个字符,直到它为0
(上图中每一行的最后一个字符框)。
表达式
c = *++argv[0]
将当前选项的值赋给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
+---+
这有帮助吗?
关于c - (*++argv)[0] 和 while(c = *++argv[0]) 的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2020945/
平时很少在jquery中用到this。查看代码时发现用到了,就调试出this的值,心想原来如此。还是挺有用的。这里总结一下this与$(this)的区别和使用。 $(this)生成的是什么?
使用单例类和应用程序范围的托管 bean 来保存应用程序数据有区别吗? 我需要查找某些 JNDI 资源,例如远程 bean 接口(interface),因此我为自己编写了一个单例来缓存我的引用并且只允
如果您仔细查看包含的图片,您会注意到您可以使用 Eclipse IDE 重构 Groovy 代码并将方法转换为闭包,反之亦然。那么,闭包到底是什么,它与方法有什么不同呢?有人可以举一个使用闭包的好例子
vagrant box repackage有什么区别( docs ) 和 vagrant package ( docs )? 我意识到 vagrant package仅适用于 VirtualBox 提
我想看看是否有人可以解释为什么以下代码适用于 valueOf 但不适用于其他代码。 import java.math.BigDecimal; public class Change { publ
这个问题已经有答案了: 已关闭12 年前。 Possible Duplicates: What is Closures/Lambda in PHP or Javascript in layman te
This question already has answers here: Vagrant, Docker, Puppet, Chef (3个答案) 2年前关闭。 docker和chef有什么共同
以下代码在95%的机器上产生相同的输出,但是在几台机器上却有所不同。在 Debug模式下,输出: Changing from New to Fin OK 但在 Release模式下: Changing
////Creating Object var Obj; // init Object Obj= {}; 它们之间有什么区别两个? 有没有可能把它变成一个单行? 这样使用有什么好处吗?
我想找出定时器服务之间的区别。我应该使用哪个以及何时使用。我正在使用 Jboss 应用服务器。 1) java.ejb.Schedule。 @Schedule注解或配置自xml。 2) javax.e
我发现在 C++ 中可以通过三种不同的方式将对象传递给函数。假设我的类(class)是这样的: class Test { int i; public: Test(int x);
有什么区别。 public class Test { public static void main(String args[]) { String toBeCast = "c
如果我有一列,设置为主索引,设置为INT。 如果我不将其设置为自动递增,而只是将唯一的随机整数插入其中,与自动递增相比,这是否会减慢 future 的查询速度? 如果我在主索引和唯一索引为 INT 的
这两种日期格式有什么区别。第一个给出实际时间,第二个给出时间购买添加时区偏移值。 NSDateFormatter * dateFormatter = [[NSDateFormatter alloc]
如果有一个函数,请说foo: function foo() { console.log('bar'); } 那么在 JavaScript 中,从另一个函数调用一个函数有什么区别,如下所示: f
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭 4 年前。 Improv
代码是什么: class Time { private: int hours; int minutes; int seconds; pu
我知道这是非常基本的,但有人介意解释一下这两个数组声明之间的区别吗: #include array myints; ...和: int myints[5]; ...以及为什么 myints.size
我学会了如何根据 http://reference.sitepoint.com/css/specificity 计算 css 特异性但是,基于this reference,我不明白伪类(来自c)和伪元
为什么在运行 2) 时会出现额外的空行?对我来说 1 就像 2。那么为什么 2) 中的额外行? 1) export p1=$(cd $(dirname $0) && pwd) #
我是一名优秀的程序员,十分优秀!