Pages: [1]   Go Down
Author Topic: 'for' syntax: for (; *ptr; ptr++) ?  (Read 1537 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Sr. Member
****
Karma: 0
Posts: 296
Got Karma?
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
for (; *ptr; ptr++){
  // do some stuff with *ptr
}
Logged

Phoenix, Arizona USA
Offline Offline
Faraday Member
**
Karma: 40
Posts: 5570
Where's the beer?
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

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

Norway@Oslo
Offline Offline
Edison Member
*
Karma: 13
Posts: 2033
loveArduino(true);
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

0
Offline Offline
Sr. Member
****
Karma: 0
Posts: 296
Got Karma?
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
« Last Edit: December 20, 2010, 12:27:23 pm by roypardi » Logged

UK
Offline Offline
Faraday Member
**
Karma: 17
Posts: 2884
Gorm deficient
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

}
Logged

Per Arduino ad Astra

Phoenix, Arizona USA
Offline Offline
Faraday Member
**
Karma: 40
Posts: 5570
Where's the beer?
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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, "(;smiley-wink") - just not anything in them (ok, that's a stretch)...

 smiley-wink
Logged

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

Norway@Oslo
Offline Offline
Edison Member
*
Karma: 13
Posts: 2033
loveArduino(true);
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 299
Posts: 26195
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
« Last Edit: December 20, 2010, 03:31:43 pm by AWOL » Logged

"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.

Essex, UK
Offline Offline
Full Member
***
Karma: 4
Posts: 150
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Home of the Nokia QVGA TFT LCD hacks: http://andybrown.me.uk

Huntsville, Alabama, USA
Offline Offline
Sr. Member
****
Karma: 2
Posts: 327
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Huntsville, Alabama, USA
Offline Offline
Sr. Member
****
Karma: 2
Posts: 327
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

-Mike
Logged

Essex, UK
Offline Offline
Full Member
***
Karma: 4
Posts: 150
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
#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:
$ gcc test.c && ./a.out
97 98 99      // for loop: a,b,c
98 99 0       // while loop: b,c, NULL
Logged

Home of the Nokia QVGA TFT LCD hacks: http://andybrown.me.uk

Huntsville, Alabama, USA
Offline Offline
Sr. Member
****
Karma: 2
Posts: 327
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Pages: [1]   Go Up
Jump to: