'for' syntax: for (; *ptr; ptr++) ?

Trying to understand a code snippet (below). I think I understand the pointer stuff but I have never seen that 'for' usage before.

What does the ';' mean/do?

thanks!

for (; *ptr; ptr++){
  // do some stuff with *ptr
}

It just means there's a blank initialization; basically, it assumes that ptr has been set previously (prior to the for() loop).

that particualr loop is better coded as:

while (*ptr++)

But; explanation: A for loop consists of three mandatory operands: The initializer, the conditionand the increment.

When the coder simply does ; he explicitly indicates that there are no initialization necessary for this loop. Furthermore the condition is that the value of the cell that ptr currently points to has to be anything but zero, lastly he increments to the next cell in memory.

OK - thanks. Makes sense now.

fwiw - earlier in that code snippet, *ptr is initialized to a null terminated char array - so from your explanation, when it hits \0 (== 0) the loop will end.

@AlphaBeta: if the operations are 'mandatory', how come you can leave all three out?

#define EVER  (;;)
//
//
  for EVER {

}

@AlphaBeta: if the operations are 'mandatory', how come you can leave all three out?

I'm not sure about the "mandatory" part, but creating a four character define to replace four other characters doesn't make too much sense, other than from a "self-documenting" code standpoint, I suppose...?

Also - maybe "mandatory" means you need to have the sections (ie, "(;;)") - just not anything in them (ok, that's a stretch)...

;)

Oh see, your code does not violate my statement. The ; will serve as the initializer. There is still the need for a statement, only you choose to make it empty.

If they were not mandatory you could do:

#define EVER ()
for EVER {
}

But, you can't. Ergo, they are mandatory.

It’s funny, I never quite understood the syntax of the “for” loop, particularly the empty one.
The first two statements are clearly C statements - even if empty, they end with semicolons, but the third…? :-? ;D

that particualr loop is better coded as: while (*ptr++)

No it isn't. The code that examines *ptr in the while block will miss the first element and see the terminating null if you do this.

Andy,

No, the while is correct. The '*ptr++' expression says: take the value of 'ptr', de-reference it to the thing pointed to, THEN increment 'ptr'.

Now if it said, '*++ptr', you would be correct and it wouldn't work the same as the example 'for'.

Regards,

-Mike

The three elements of a ‘for’ are not statements, they are expressions (which may be omitted), separated by semicolons.

Incidentally, the ‘for’ statement is one of the places where the comma operator frequently hangs out. For example:

for (i = 0, j = 0; i_str[i] != '\0' && j_str[j] != '\0'; ++i, ++j)
{
  ...
}

Regards,

-Mike

No, the while is correct. The ‘*ptr++’ expression says: take the value of ‘ptr’, de-reference it to the thing pointed to, THEN increment ‘ptr’.

No Mike, I’m afraid you are wrong - and it’s because of the part of the quote I highlighted. It is this POST TEST increment that carries over into the while block allowing the code to operate on a value not yet tested.

Anyway, enough talk. I never make a statement about code without being able to prove it. Here’s the concrete proof. Run this through your preferred compiler if you don’t believe me.

#include <stdio.h>

const char *data="abc";

main() {
  testFor();
  putchar('\n');
  testWhile();
}

testFor() {
  const char *ptr=data;
      
  for(;*ptr;ptr++)
    printf("%d ",*ptr);
}

testWhile() {
  const char *ptr=data;
      
  while(*ptr++)
    printf("%d ",*ptr);
}

Output (comment annotations added):

$ gcc test.c && ./a.out
97 98 99      // for loop: a,b,c
98 99 0       // while loop: b,c, NULL

Andy,

You are absolutely correct, sir. My apologies for doubting you.

The part I missed was USING the pointer inside the while block. Duh.

Regards,

-Mike