简体   繁体   中英

C while loop condition

I'm reading Computer Systems for my CS class and I've come across a while loop condition that's puzzling me, here's the code:

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 */ 

the while loop has two operands to logical && but I don't understand what is the purpose of the first operand (*buf) . The second operand is checking for empty space, but I would think that the second operand by itself would suffice for the purpose of this loop.

Yes, the *buf && is superfluous.


*buf is false for '\\0' and true for everything else.

*buf == ' ' is true for ' ' and false for everything else, including '\\0' .

The following is functionally the same as while (buf == ' ') if the quote marks ' are changed to ' .

//                      v-v--- not standard quote marks.
while (*buf && (*buf == ’ ’))  

With a good compiler, neither is faster as an optimizing compiler with emit the same code.

To me it is simply pedantic code insuring the loop is not taken with a null character .


What is bad about the code includes:

buf[strlen(buf)-1] = ' '; is a UB if buf[0] == 0 .

buf[strlen(buf)-1] = ' '; /* Replace trailing '\\n' with space */ buf[strlen(buf)-1] = ' '; /* Replace trailing '\\n' with space */ may lop off a non- '\\n' .

A better alternative that address the 2 preceding concerns: buf[strcspn(buf, "\\n")] = '\\0';

Instead of "Ignoring spaces", it is more C-like to ignore white-spaces .

"Build the argv list" usually requires a final argv[argc] == NULL .

Of course these are sides issues to the main question and without the larger context may/may not apply.

The second operand is checking for empty space, but I would think that the second operand by itself would suffice for the purpose of this loop.

  while (*buf && (*buf == ’ ’)) /* Ignore leading spaces */
        buf++;

It would suffice. The loop would break for *buf == '\\0' .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM