1

In the following code from an Arduino sketch will it run the first "for" statement before enacting the second "for" statement. Also how does it know go run the first stamens again? Will it continue to run till both statements are true?

for(int r = 0; r < 8; r++){
    for(int c = 0; c < 8; c++){
        lc.setLed(0, r, c, HIGH);
    }
}
3

A for statement repeats everything between { and }, (or just the next line if there is no { and } a certain number of times. It's not as simple as you might at first think, but it makes more sense if you write it out as a while loop explicitly.

For instance, for (a; b; c) { ... } could be re-written as:

a;
while (b) {
    c;
}

So if you had:

for (int i = 0; i < 100; i++) { 
    Serial.println(i);
}

it could be re-written as:

int i = 0;
while (i < 100) {
    Serial.println(i);
    i++;
}

The two mean exactly the same thing. A for has the three elements - initializer, comparison and iterator. The initializer is run before the loop starts, the comparison is used to work out when the loop should finish, and the iterator is used to move through each iteration of the loop.

To re-write your specific example:

for(int r = 0; r < 8; r++){
    for(int c = 0; c < 8; c++){
        lc.setLed(0, r, c, HIGH);
    }
}

You would end up with:

int r = 0;
while (r < 8) {
    int c = 0;
    while (c < 8) {
        lc.setLed(0, r, c, HIGH);
        c++;
    }
    r++;
}

Now, if we were to do away with the loops altogether and write it all out longhand, what would it look like? Well, let's start with the inner c loop. That loops from 0 to 7 (while less than 8), so replacing that loop with 8 discrete calls to the function replacing c each time would end up with:

int r = 0;
while (r < 8) {
    lc.setLed(0, r, 0, HIGH);
    lc.setLed(0, r, 1, HIGH);
    lc.setLed(0, r, 2, HIGH);
    lc.setLed(0, r, 3, HIGH);
    lc.setLed(0, r, 4, HIGH);
    lc.setLed(0, r, 5, HIGH);
    lc.setLed(0, r, 6, HIGH);
    lc.setLed(0, r, 7, HIGH);
    r++;
}

We could take it a step further and unroll the outer r loop. A subset of what you would end up with would be like this (note, I have skipped a lot of the middle ones):

lc.setLed(0, 0, 0, HIGH);
lc.setLed(0, 0, 1, HIGH);
lc.setLed(0, 0, 2, HIGH);
lc.setLed(0, 0, 3, HIGH);
lc.setLed(0, 0, 4, HIGH);
lc.setLed(0, 0, 5, HIGH);
lc.setLed(0, 0, 6, HIGH);
lc.setLed(0, 0, 7, HIGH);
lc.setLed(0, 1, 0, HIGH);
lc.setLed(0, 1, 1, HIGH);
... skipped a lot ...
lc.setLed(0, 6, 6, HIGH);
lc.setLed(0, 6, 7, HIGH);
lc.setLed(0, 7, 0, HIGH);
lc.setLed(0, 7, 1, HIGH);
lc.setLed(0, 7, 2, HIGH);
lc.setLed(0, 7, 3, HIGH);
lc.setLed(0, 7, 4, HIGH);
lc.setLed(0, 7, 5, HIGH);
lc.setLed(0, 7, 6, HIGH);
lc.setLed(0, 7, 7, HIGH);

There would, of course, be 8 × 8 = 64 entries in there.

for loops can be used in lots of other fun ways too. It's not just a simple "run this X number of times". For instance, you can loop through a C string until you reach the NULL character at the end of the string:

for (char *p = str; *p != 0; p++) {
    ... do something with *p
}

You can iterate through the entries in a linked list:

for (struct mylist *scan = myListHead; scan; scan = scan->next) {
    ... do something to scan->whatever ...
}

You can even embed functions in there:

for (char c = 0; c != '\n'; c = Serial.read()) {
    ... Do something with character `c` until `c` is a line feed ...
}

As you can see for is an incredibly powerful and flexible tool that is often overlooked in favour of the more explicit while.

  • This was incredibly useful. Expressing it in terms of while made it easier to understand. Thank you. – Gabe Ruiz Sep 17 '15 at 1:37
  • Mr. Majenko, I'm a teacher trying to teach junior high kids programming using Arduino. I can do the basic "if," "else," etc. The kids wanted to learn how to program a game, I'm using this code itopen.it/arduino-pong-with-8x8-led-matrix-and-max7219 I've tried to figure out the code with great success but I still have a few questions. Where is good place to ask them? Your answer was very useful but I often feel intimidated asking questions in this "forum." Thank you for your time. – Gabe Ruiz Sep 17 '15 at 2:21
  • 1
    @GabeRuiz Don't be intimidated. We're here to help. It's only when people ask "Tell me how to do this project" and things like that we get a bit shirty with them. Questions like yours, along the lines of "How does this work" or "I don't understand this bit, can you explain it" are bread and butter for this site. Feel free to ask away. – Majenko Sep 17 '15 at 9:42
  • The preferable approach is to make an attempt on your own, and if it doesn't quite do what you want, post your code, describe what happened, and compare it to what your expectations were. Or if it does work, you might ask if there is a better way of doing it. – Nick Gammon Sep 18 '15 at 0:39
2

What you have there is a nested loop. The first for statement runs 8 times, incrementing r from 0 to 7. For each of those 8 iterations the second for statement runs, incrementing c from 0 to 7. Thus the setLed statement is executed 64 times.

Will it continue to run till both statements are true?

Yes. Unless you have a break or return statement somewhere in the part of the code you haven't shown.

Strictly-speaking, a statement does not become true. They will run while the test inside the for remains true (both tests).

This is standard C++ or C programming. You may wish to consult a C tutorial if you find this sort of thing puzzling.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.