C while循环条件

3

我正在上计算机科学课程,遇到了一个让我困惑的while循环条件,以下是代码:

int parseline(char *buf, char **argv)
{
    char *delim; /* Points to first space delimiter */
    int argc; /* Number of args */
    int bg; /* Background job? */

    buf[strlen(buf)-1] = ’ ’; /* Replace trailing ’\n’ with space */
    while (*buf && (*buf == ’ ’)) /* Ignore leading spaces */
        buf++;

     /* Build the argv list */
     argc = 0;
     while ((delim = strchr(buf, ’ ’))) {
         argv[argc++] = buf;
         *delim = ’\0’;
          buf = delim + 1;
          while (*buf && (*buf == ’ ’)) /* Ignore spaces */
              buf++;
     }

In

while (*buf && (*buf == ’ ’)) /* Ignore spaces */ 
while循环有两个操作数用于逻辑运算符&&,但我不理解第一个操作数(*buf)的目的。第二个操作数检查空格,但我认为第二个操作数本身足以满足此循环的目的。

如果buf == NULL会发生什么?我尝试运行一个buf == NULL的简化代码版本,由于循环条件试图推迟一个NULL指针,所以得到了一个段错误。在循环条件中使用指针是不是一种糟糕的编程实践?应该使用带有标志条件的循环吗? - David
buf cannot be NULL after this: buf = delim + 1; - Jean-François Fabre
3个回答

3

是的,*buf && 是多余的。


*buf 对于 '\0' 为假,对于其他所有字符都为真。

*buf == ' ' 对于 ' ' 为真,对于其他所有字符,包括 '\0' 都为假。


1
另一种方法:(*buf && (*buf == ' ')):当*buf ==' '时,第一个条件也是真的,所以它是多余的。 - Jean-François Fabre

1
第二个操作数用于检查空格,但我认为只使用第二个操作数就足以满足此循环的目的。
  while (*buf && (*buf == ’ ’)) /* Ignore leading spaces */
        buf++;

这就足够了。当*buf == '\0'时,循环会终止。


1
如果将引号更改为',则以下内容在功能上与while (buf == ' ')相同。
//                      v-v--- not standard quote marks.
while (*buf && (*buf == ’ ’))  

有一个好的编译器,无论哪个都不会比优化编译器发出相同的代码更快。

对我来说,这只是一段迂腐的代码,确保循环不会使用空字符


代码中存在的问题有哪些:

buf[strlen(buf)-1] = ’ ’;如果buf[0] == 0则会产生未定义行为。

buf[strlen(buf)-1] = ’ ’; /* 用空格替换尾随的 '\n' */可能会截断一个非'\n'的字符。

一个更好的替代方案,可以解决上述两个问题:buf[strcspn(buf, "\n")] = '\0';

与其说“忽略空格”,不如说是C语言风格更倾向于忽略空白字符

通常“构建argv列表”需要一个最终的argv[argc] == NULL

当然,这些都是主要问题的附带问题,在没有更大的上下文情况下,可能会/可能不会适用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接