Go Down

Topic: 'for' syntax: for (; *ptr; ptr++) ? (Read 1 time) previous topic - next topic

roypardi

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!

Code: [Select]

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

cr0sh

It just means there's a blank initialization; basically, it assumes that ptr has been set previously (prior to the for() loop).
I will not respond to Arduino help PM's from random forum users; if you have such a question, start a new topic thread.

AlphaBeta

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

But; explanation:
A for loop consists of three mandatory operands:
The initializer, the condition and 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.

roypardi

#3
Dec 20, 2010, 06:26 pm Last Edit: Dec 20, 2010, 06:27 pm by roypardi Reason: 1
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.

Groove

@AlphaBeta: if the operations are 'mandatory', how come you can leave all three out?  
Code: [Select]
#define EVER  (;;)
//
//
 for EVER {

}
Per Arduino ad Astra

cr0sh

Quote
@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)...

;)
I will not respond to Arduino help PM's from random forum users; if you have such a question, start a new topic thread.

AlphaBeta

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.

AWOL

#7
Dec 20, 2010, 09:31 pm Last Edit: Dec 20, 2010, 09:31 pm by AWOL Reason: 1
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
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Andy Brown

Quote

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.
Home of the Nokia QVGA TFT LCD hacks: http://andybrown.me.uk

Mike Murdock

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

Mike Murdock

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:
Code: [Select]
for (i = 0, j = 0; i_str[i] != '\0' && j_str[j] != '\0'; ++i, ++j)
{
 ...
}
Regards,

-Mike

Andy Brown

Quote

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

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.

Code: [Select]

#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):

Code: [Select]

$ gcc test.c && ./a.out
97 98 99      // for loop: a,b,c
98 99 0       // while loop: b,c, NULL
Home of the Nokia QVGA TFT LCD hacks: http://andybrown.me.uk

Mike Murdock

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

Go Up