41
$\begingroup$

So, in C-style languages, the for loop has a funny little syntax:

for (int i = 0; i < 100; i++) {
    // do something
}

If we order these sections in a natural, intuitive fashion, we would get something like:

for (1; 2; 3) {
    4
}

... which is how students seem to feel like things should be ordered. But, of course, the real execution order is 1, 2, 4, 3, 2, 4, 3, 2, 4, 3, 2, 4, 3...

What tricks have you developed for helping students make sense of for loops at the very start?

$\endgroup$
11
  • 8
    $\begingroup$ Actually that is legal, but is an infinite loop, with i always 1. Also: defaults of all kinds are frequent sources of error. Make your programs explicit. $\endgroup$
    – Buffy
    Jul 13, 2017 at 23:15
  • 6
    $\begingroup$ @GypsySpellweaver any or all of them can be empty, in any combination, but they all default to nothing (respectively: no initialization, no termination except by explicit break, and no post-loop-body expression). $\endgroup$
    – hobbs
    Jul 14, 2017 at 5:01
  • 2
    $\begingroup$ Can you add some specific problems your students seem to have with learning the for loop? $\endgroup$
    – AnoE
    Jul 14, 2017 at 13:43
  • 3
    $\begingroup$ A for loop in c style syntax is a shortcut for a while loop with post operation (increment being a common case). Show the expanded while form, then show the for form. $\endgroup$
    – pojo-guy
    Jul 15, 2017 at 12:41
  • 6
    $\begingroup$ This is why you shouldn't teach basic programming using C. It makes it extra hard to grasp the concept itself... $\endgroup$
    – vacip
    Jul 17, 2017 at 11:00

14 Answers 14

34
$\begingroup$

I know I'm coming late to this party but this is a really good question and I think it deserves a really good treatment.

The original for loop, the one with the semicolons in it, is amazingly flexible, powerful, and confusing as all get out. It is seldom taught well, it is a very easy place for bugs to hide, and it is not going away.

To master it you must learn the 1,   2, 4, 3,   2, 4, 3 pattern the OP mentioned. You must burn it into your soul. You must burn it into the souls of your students. The question is, how?

The best way is to actually see it. To watch it happen. Unfortunately debugging tools often insist on highlighting the entire line.

debugger highlighting the full line

Can you tell if i is about to be initialized, tested, or incremented here? Debugger highlighting is often useless for teaching or debugging the classic for loop.

However, there is a way around that problem. The c style languages all have a feature that lets us work around this debugger limitation. Whitespace. Whitespace is meaningless in these languages. You can take advantage of that.

So long as you're willing to explain that this:

for(int i=0; i<10; i++) {
    System.out.println(i);
}

will do the same thing as this:

for(
        int i=0; 
        i<10; 
        i++
) {
    System.out.println(i);
}

then you can show them this:

debugger single-stepping for-loop parts

Do that, and rather than just explaining, you are showing them how this works, you are teaching them how to debug it themselves when they get confused by it.

Now sure the multiline style isn't popular with for loops but the students certainly don't have to turn in code that looks like that. It's just a form to use while testing because our debugging tools aren't yet smart enough to highlight only the relevant parts of a line.

I've changed the speed and rhythm I use as I click. That's no accident. I'm using that to emphasize the starting and ending parts of each iteration. Students should not only feel like they can predict this. They should feel like they can use the debugger to re-teach themselves this pattern quickly if they ever need to.

Consider a cascading style that retains column position for those more visually oriented:

same as last, but for-loop parts stay in the column they would have if it was a single line

Now that's just the start of understanding loops. Writing correct, readable, efficient loops is a whole other issue that this answer hardly does justice to.

A lot of bugs hide right here. Don't undersell how worthy this is of close study.

$\endgroup$
11
  • 4
    $\begingroup$ You may be late to our "party" and I haven't noticed you here before, but you are giving some great answers. I'd offer you a party hat if I had one. Oh, I do, +1. $\endgroup$
    – Buffy
    Feb 7, 2018 at 12:55
  • 1
    $\begingroup$ @Buffy hehe, thank you. This isn't my usual haunt but I can't resist a good question. $\endgroup$ Feb 7, 2018 at 14:30
  • 4
    $\begingroup$ This just might be the most useful answer I've seen in the last 3 months. $\endgroup$
    – ItamarG3
    Feb 8, 2018 at 13:28
  • $\begingroup$ A nice solution and in the "video" you made it even better than in the "code", as I think the "video" has a better indentation. $\endgroup$
    – Ola Ström
    Feb 8, 2020 at 21:47
  • 1
    $\begingroup$ @OlaStröm thank you. I realized the advantage of that form late and wanted to tack it on. After decades at this I'm still learning new tricks : ) $\endgroup$ Feb 8, 2020 at 22:01
58
$\begingroup$

Show then how the loop can be unfolded into a while loop:

int i = 0 // Step 1
while (i< 100) { // Step 2
    // Do something
    i++ // Step 3
}

Explain that the order is derived from that unfolding.

You could start out by only teaching while loops, forcing them to make these while loops with iterators, then showing that for loops are a condensed of those while loops with incrementing variables.

$\endgroup$
13
  • 9
    $\begingroup$ …and be prepared for the question "Why should we use for loops instead of while loops when they're doing equivalent things, what's their advantage?" $\endgroup$
    – Bergi
    Jul 14, 2017 at 1:34
  • 3
    $\begingroup$ @Bergi You're telling the compiler what you want more clearly, allowing more optimization, and they simply take up less space and look neater. $\endgroup$
    – thesecretmaster
    Jul 14, 2017 at 1:35
  • 20
    $\begingroup$ @thesecretmaster "Required to tell the compiler…" has never been a good reason. And I can only hope that the syntax choice does not affect the optimiser at all. The point is that they are easier to understand for the programmer(s) that have to read them. The iteration variable is (supposed to be) initialised and modified only in that single line, which makes for a an easily recognisable pattern and correct code where the update step is not forgotten. It also works with continue; $\endgroup$
    – Bergi
    Jul 14, 2017 at 1:45
  • 6
    $\begingroup$ @Bergi Keeping the loop control variable in the for scope is a practical advantage as well. The more correct "expansion" of a for loop would be: {int i = 0; while(i < 100){++i;}}. $\endgroup$ Jul 14, 2017 at 13:51
  • 2
    $\begingroup$ For loops do not optimise better than while loops (at least in gcc, clang and visual studio in C and C++). Arguments about easier to read code are sensible. $\endgroup$ Jul 15, 2017 at 17:50
26
$\begingroup$

I teach for loops using the following pseudocode, which we then translate into actual code:

for (initialization; condition; update)
{
    statement;
}

This logic helps justify why the order goes 1, 2, 4, 3 to start. I explain it as follows: a variable can only be initialized once so it happens first and never again. After that the variable is tested against the condition. If the condition is true, then the code proceeds to the statement. Only then will it reach update. If the first conditional test fails, the update code is never executed.

I have found that for loops are one of the few constructs that benefit most directly from drawing a flowchart. Using the visual diagram will help this logic become clearer.

Another benefit of teaching the for loop this way is that it becomes trivial to translate it into while or do-while with the same pseudocode constructs.

// while loop
initialization;
while (condition)
{
    statement;
    update;
}

// do-while loop
initialization;
do
{
    statement;
    update;
} while (condition);

Once I do this, I can focus on each of these four parts, so students understand the different components that make up a loop regardless of the structure thereof.

$\endgroup$
5
  • 1
    $\begingroup$ That's a clear way to explain loops. I use a similar approach. $\endgroup$ Jul 14, 2017 at 15:31
  • 1
    $\begingroup$ The do while and while loops stated aren't exactly equivalent. If after initialization, condition is false, then you never execute statement+update in the while loop, but in the do-while loop, you always execute statement+update at least once. This could easily lead to confusion. $\endgroup$
    – Batman
    Jul 15, 2017 at 21:58
  • $\begingroup$ @Batman Absolutely. That would be part of a broader instruction on the differences between and among these three loop constructs. Nevertheless, the general pseudocode holds true. $\endgroup$
    – Peter
    Jul 15, 2017 at 22:05
  • 1
    $\begingroup$ This is pretty much how I do it but I'm a little more explicit in each section: pre-loop-initialisations, condition-for-doing-iteration, post-iteration-actions and iteration-actions. Once they understand that the iteration is a single execution of the body and the loop is the entire thing, this seems to be easy to pick up (even for teens). $\endgroup$
    – user2049
    Jul 17, 2017 at 1:49
  • $\begingroup$ My treatment of this differs only in that I call the third part "between' instead of update. This is the right approach. Also, it's' good to draw a diagram depicting the loop and pointing out the cycle in the graph. Hence "loop." $\endgroup$ Feb 23, 2020 at 23:08
9
$\begingroup$

It's about setting boundary conditions first. Provide them with a more concrete example, like filling a glass of milk. You kind of need a glass or container (let me know the next time you pour milk right on the counter) and that glass is some amount full. We'll just treat it as empty. Then, you stop filling the glass when it's full (or half full or whatever), unless you want milk everywhere.

Within those boundary conditions, you pour the milk jug. That is, mentally, you're thinking (in not so many terms):

repeat following until checks make you stop pouring milk
check: fullness of glass
check: how close the fullness is to the wanted end fullness
add some milk

That's exactly how a for loop thinks. It needs your conditions first, and then what you want to repeat while those conditions are true. (Yes, while - just like a while loop. I personally agree with thesecretmaster in that it makes a lot of sense to introduce while loops before for loops.) As you're pouring, you're constantly rechecking the level of the milk - "updating" a variable in your head as you act. So, if you were asking a computer to fill a glass of milk:

import milk
for (float glassFullness = 0; glassFullness < 1; glassFullness+=0.1) {
    milk.Fill()
}

That could, of course, also be written

import milk
float glassFullness = 0;
while (glassFullness < 1) {
    milk.Fill()
    glassFullness+=0.1
}

They're doing the same things; the for loop is just a condensed version.

Tl;dr: a for loop looks for the boundary conditions, and then does what it needs to do, rechecking with a redefined variable accounting for the change that has been made. You input what change needs to be made to the variable to account for the action.

$\endgroup$
1
  • $\begingroup$ Boundary conditions are very helpful in explaining loops. $\endgroup$
    – user737
    Jul 14, 2017 at 16:21
8
$\begingroup$

Theoretically, I teach the while loop first. Others have already explained how and why, but I'll go ahead with an example:

void showRating( int rating )
{
    int i = 0;
    while ( i < rating )
    {
        putchar( '*' );
        ++i;
    }
    putchar( '\n' );
}

Some of the examples will be better expressed as for loops, and that's where I introduce the for loop, as a way of containing the essential elements in a concise construct. I might ask what happens if I forget to increment i:

void showRating( int rating )
{
    int i = 0;
    while ( i < rating )
    {
        putchar( '*' );
    }
    putchar( '\n' );
}

And we compile it and run it.

Then I show how the for loop might help us not forget the counter:

void showRating( int rating )
{
    int i;
    for ( i = 0; i < rating; ++i )
    {
        putchar( '*' );
    }
    putchar( '\n' );
}

Too often, people think first of counting when they think of loops, and that's why they jump to the for loop first. But the C for loop is not really the counted loop that BASIC has led us to believe it is. And the English grammar for the word is not limited to counting, either.

So I'll throw some for loops in that don't strictly count.

I also teach the pun on forever that used to be the standard flag for an indeterminate loop:

for( ;; )

I'm likely to teach the post-test do ... while loop after having shown an indeterminate loop with a break at the end:

for ( ;; )
{
    /* Always executes once. */
    if ( condition ) break;
}

Now I would want to use something concrete here so I can show that it really always executes once, but I don't have time to make something up today.

Then I can show them the do .. while loop:

do
{
    /* Always executes once. */
} while ( !condition );

Somewhere along in here I'll introduce the faux style thing about bracket placement and warn them not to argue with the managers about where to place them.

$\endgroup$
1
  • $\begingroup$ Great set of variations. And, it is not good to argue with Visual Studio about how to format the code either! $\endgroup$
    – user737
    Jul 14, 2017 at 16:26
8
$\begingroup$

tl;dr A for loop is just a while loop that has extra slots for a pre-loop statement and a post-loop-run statement. Since they're pretty much the same thing just written differently, a for loop is best understood as syntactic sugar that's useful when it increases the readability of the code.

Sometimes new programmers are worried about performance, thinking that syntactic sugar might be less efficient. That's not the case; the compiler really doesn't care how you write these loops, it's all the same to it. So, students should be told to just write whichever's cleaner in the current context.

Homework/test question idea: Have students convert a for loop into an equivalent while loop, or a while loop into an equivalent for loop.


Mapping between for and while.

The for loop:

for (prestatement; condition; poststatement)
{
    // loop body
}

is equivalent to the while loop:

{
    prestatement;
    while (condition)
    {
        // loop body
        poststatement;
    }
}

, where:

  • prestatement is an executable statement that happens only once, before the loop starts.

    • If omitted, then the loop just doesn't do anything extra before starting.
  • condition is a Boolean expression that's evaluated at the start of each loop execution, breaking if false.

    • If omitted, then there's no break check there.
  • poststatement is an executable statement that happens after the end of each loop execution.

    • If omitted, then the loop just doesn't do anything extra after each execution.

Note on scope.

Even though

    int i = 0;
    int i = 0;

is illegal code because we can't declare i twice in the same scope,

{
    int i = 0;
}
{
    int i = 0;
}

is legal because both i's are in different scopes.

This scoping issue is why we have the while statement above wrapped in extra {}'s, since the prestatement belongs in that scope.


Note on continue.

The keyword continue can goto the end of a loop's body.

We can rewrite this behavior more explicitly:

  1. Make the implicit-label explicit by writing it out.

  2. Rewrite continue; as goto [label's name];.

For example:

for (long i=0; i < 1000; ++i)
{
    if (i % 8 == 0) { continue; }
    //  rest of body
}

becomes

for (long i=0; i < 1000; ++i)
{
    if (i % 8 == 0) { goto end_of_body; }
    //  rest of body
end_of_body:
}

If we then rewrite this as a while loop, it'd be

{
    long i = 0;
    while (i < 1000)
    {
        if (i % 8 == 0) { goto end_of_body; }
        //  rest of body
end_of_body:
        ++i;
    }
}

That said, generally goto and related mechanisms (e.g., continue) are discouraged. Presumably students ought to understand how they work, though it's generally best to avoid new usage.


for loops can omit parts.

Might seem weird at first glance, but

for (;;) { }

is actually perfectly legal code! Since it omits a break condition and doesn't do anything, it's basically an infinite loop that runs forever without doing anything.

In C#, it doesn't consume CPU time, but it also blocks the thread from progressing. For example,

for (;;) { }    //  Infinite loop
foo();          //  Never happens because the above loop never ends
$\endgroup$
3
  • $\begingroup$ Not only syntactical sugar around a while loop, as the continue statement of the while loop skips the "poststatement". $\endgroup$ Jul 19, 2017 at 19:48
  • $\begingroup$ @MichelBillaud: Good point, I should clarify the issue with continue. Don't get me wrong, it's still just syntactic sugar, but probably ought to clarify that continue targets the spot after // loop body in the translation. $\endgroup$
    – Nat
    Nov 20, 2020 at 2:34
  • $\begingroup$ In C, control structures are mostly macros trying to hide some gotos under the carpet. But don't tell that to students. $\endgroup$ Nov 20, 2020 at 7:09
7
$\begingroup$

I think the way to teach it is not by talking about order of operation, but by teaching the overall concept of a looping. The for header contains the steps that are generally common to looping: initialize iteration variables, test whether the loop should proceed, and update variables between iterations.

As others have suggested, you could start by teaching while loops, since they have simpler structure. Then you could point out that many of these loops have some common structure: they initialize a variable before starting, and update that variable at the end of the body. This is so common that we have a special for statement that encapsulates it.

This is also useful as an illustration of modularity, which is a cornerstone of good programming. Whenever you find yourself doing similar things over and over, give that thing a name and encode it as a function, macro, structure/class, etc. In this case, it's just happening at a higher level, in language design: much of the evolution of languages over the decades has been finding common programming patterns and creating languages that have them as built-in operations and/or functions (e.g. foreach in PHP).

$\endgroup$
0
6
$\begingroup$

I used to have a role where I supported college students in CS1. I developed the following exercises to address this exact issue:


Counting code executions

Peer Instruction exercise about for loops

Text version:

How many times do each of the following pieces of code execute?

int sum = 0;
int i;
for(i = 1 /*A*/; i < 5 /*B*/; i = i + 1 /*C*/)
{
    sum = sum + i; /*D*/
}

Hint: translate a while loop -- the pieces should execute the same number of times as the do here.

Translating loops

Work on each of these individually first, then partner up. Switch partners between exercises.

A. Convert this while loop into a for loop:

int k = 0;
while (k < 7) {
    cout << "Hola " << k << endl;
    k = k + 2;
}

What is the output of the loop?

What is the value of k after the loop completes?

Watch your peer leader be a human compiler on this loop.

B. Convert this for loop into a while loop

for (int countdown = 10; countdown >= 0; countdown--) {
    cout << "T-minus " << countdown << endl;
}
cout << "BLASTOFF!!!" << endl;

What is the value of the countdown after the loop completes?


If you teach very well maybe the questions are too easy, but in my setting they led to a lot of improvement. Notice that I included a counter increasing by something other than 1, and a loop counting downwards, since my students often didn't see examples like that in class.

$\endgroup$
4
  • $\begingroup$ Hyper-clarity is teaching well. This is an excellent exercise. Welcome to Computer Science Educators. I hope we hear more from you in the future! $\endgroup$
    – Ben I.
    Jul 16, 2017 at 22:14
  • 1
    $\begingroup$ This isn't just an answer; it also has useful material in it that'd be of general value to educators. At current, SE.CSEducators doesn't really have a good mechanism for promoting this content, though there might be an argument for cloning StackOverflow's recent Documentation feature here - just, instead of being documentation on programming, it'd be a repository of teaching material. $\endgroup$
    – Nat
    Jul 16, 2017 at 22:53
  • 1
    $\begingroup$ @Nat That actually sounds like a fantastic idea! If you want to, create a meta question requesting it. It's certainly unprecedented, but it's worth asking :) $\endgroup$
    – thesecretmaster
    Jul 16, 2017 at 22:59
  • $\begingroup$ @Nat (and nova) I forgot to mention, come by the chat room. We'd love to meet you! $\endgroup$
    – Ben I.
    Jul 16, 2017 at 23:00
4
$\begingroup$

I am not an educator, but I hope my answer will be helpful.

In B.A.S.I.C, which I learned as a child, there are "for-to-step" loops and their argument order is the same as C style languages. I have to remember them like this in order to keep it right for myself.

This is QBASIC

FOR counter = start TO end [STEP]
    [Statement Block] 
NEXT counter

or

FOR i= 100 TO 0 STEP -1
    PRINT i 
NEXT i

This helps me personaly understand what's happening in those loops.

Another thing you might try is an alteration of what you posted above:

 for (1; //initialize
      2; /* are we done? */ 4 /*increment*/){
      3 //do the work
 } // finish
$\endgroup$
0
4
$\begingroup$

Maybe the

for (int i=0; i<10; i++)
{ ... }

loops seems funny when you compare it to the "interval" loop of other languages, like Pascal's

for I:=1 to 10 by 1 do

but the C for loop was designed as a much more general linguistic mechanism than loops with counters.

The objective was to keep all elements of the "control" of the loop together on one side for better maintenance, and the body of the loop on the other side.

So we have a lot of additional common idioms, like

for (char *ptr = string; ptr != '\O'; ptr++) { ... }

for (struct Cell *p = first; p != NULL;  p = p->next) { ... }

The loop over an interval is only an instance. Maybe the problem is in the overuse of counters in the exercices for beginners (even when the range-based for loop is available). A survival from good old Fortran programming :-) ?

$\endgroup$
0
3
$\begingroup$

However, don't neglect the fact that the first and last of the three sections between the parentheses can have (in C, anyway) multiple statements separated by commas (comma is an operator in C).

for(int i = 0, j = 100; i < 100; i++, j = 2 * j + i) {
    //do something strange
};

You can write quite a lot of a program in a single for statement. The final section needn't just increment or decrement things. Arbitrary complexity is possible. Probably not a good idea to encourage it, however. But students reading code of others may come across it, so should be aware.

One use of this is to iterate over a two (or more) dimensional array in a single for statement.

Because of the complexity, it is probably best to show how it maps to a while statement as suggested in another answer here

$\endgroup$
9
  • $\begingroup$ Is the order of evaluation in your "step" even defined? $\endgroup$
    – Džuris
    Jul 14, 2017 at 3:14
  • 1
    $\begingroup$ @Džuris yes. There is a sequence point between the evaluation of the left and right hand sides of the comma operator. $\endgroup$
    – hobbs
    Jul 14, 2017 at 5:06
  • 1
    $\begingroup$ (but calling it "multiple statements" isn't accurate. It's a single expression. And the int i = 0, int j = 100 part actually isn't valid because that's not how declarations work, though it would be without the second int). $\endgroup$
    – hobbs
    Jul 14, 2017 at 5:08
  • $\begingroup$ @hobbs oops and Thanks. Corrected to remove the declaration from the loop. $\endgroup$
    – Buffy
    Jul 14, 2017 at 9:08
  • $\begingroup$ Yay for the comma operator! I have used it to achieve some significant and very necessary functionality in the past, which I could not do otherwise (trying to fit a macro in place of a function, what is called 'inlining' these days). $\endgroup$
    – user737
    Jul 14, 2017 at 16:23
3
$\begingroup$

Another way of looking at this is to explore what is missing or lost at various stages:

In Java

For each:

for ( String s : < some iteratable collection > )
    foo();

loses the index of the loop. It never has one unless you add it.

for (int i = 0; i< n; i++)
    foo();

loses the index after the loop when completed,

while other loops preserve it.

Many of the posts offer good advice for explaining the behaviour of the for loop. Translations to and from while loops are traditionally used. Strictly speaking a for loop is never required, it's a convenience, as is the for each loop.

The more tricky uses of a for loop should be very carefully considered before teaching -- high risk low reward.

$\endgroup$
2
  • $\begingroup$ I agree about de-stressing low reward features. However, they can't be neglected entirely as students (and professionals) still need to read the code of others who might not exhibit such "sanitary" practices. $\endgroup$
    – Buffy
    Feb 6, 2018 at 15:17
  • $\begingroup$ I would add that it is also heavily tested on the AP CS A test, where they love to introduce off-by-one errors and tricky ending conditions. $\endgroup$
    – Ben I.
    Feb 6, 2018 at 16:58
3
$\begingroup$

I love thesecretmaster's answer of showing the mapping between the two loops (and I will almost certainly do that in the future). However, as an AP Computer Science A teacher, I teach in Java, and there is a subtle trap in saying that

for (int i = 0; i < 100; i++) {
    // do something
}

is equal to

int i = 0;
while (i < 100) {
    // do something
    i++;
}

The two loops are identical, but of course there is one subtle but important difference: the scope of i (and its corresponding pollution of the namespace). Java considers the int declared in the first section of the for-loop header to be declared in the loop, and therefore out of scope once the loop ends.

The while loop is really equivalent to this loop in C:

int i;
for (i = 0; i < 100; i++) {
    // do something
}

If you are to take the path of mapping equivalencies between the loops, you really should also point out this trap.

$\endgroup$
6
  • 1
    $\begingroup$ You have a good point about the scope issue, though that's less a difference and more an issue of an incomplete translation. As noted in @IllusiveBrian's comment, {} need to be included to control for scope - which may look unusual since most people don't care enough about scope, but it's needed to maintain equivalence. $\endgroup$
    – Nat
    Jul 14, 2017 at 15:08
  • 1
    $\begingroup$ For example, the int i = 0; while (i< 100) { /* do something */ i++; } above should be { int i = 0; while (i< 100) { /* do something */ i++; } }. $\endgroup$
    – Nat
    Jul 14, 2017 at 15:11
  • $\begingroup$ Sometimes you want to be able to see the final state of the loop control variable outside the body of the loop. I teach that also. "Students do the darndest things." $\endgroup$
    – user737
    Jul 14, 2017 at 16:28
  • $\begingroup$ scope and pollution can be limited by a pair of curly brackets around declaration + loop. $\endgroup$ Jul 19, 2017 at 20:14
  • $\begingroup$ anyway, a continue statement in the body breaks the equivalence of the 2 pieces of code. $\endgroup$ Feb 10, 2018 at 16:59
0
$\begingroup$

I know I am very late to this party (and this idiom), but..

The trick to teaching loops is pink hippos.

There are five basic parts to a loop.

  1. Control Init (initialize the control variable)
  2. Loop Back Spot (a stupid name for the place the code jumps back to)
  3. Work (what you are repeating in the loop)
  4. Control Step (changing the loop control variable)
  5. Exit Check (checking the exit condition and jumping back as needed)

Take a for loop (java for example)

  for (int ii = 2; ii < 20; ii = ii + 2)
     System.out.println(ii);

with the parts labeled:

  <loop back spot> for (<control init>; <exit check>; <control step>) 
                        <work>

To demonstrate this in class I take out of large jar with 30 little pink hippos and write the five parts left to right across the board. I then have five students come up to the front of the class room and stand under each of the loop parts. The one under the control step gets the jar of hippos.

I then have a sixth student join the group at the front as the computer to run the code. The computer student receives one hippo at the start from the first student. That students job is done. The computer student then moves right passing the loop spot to the student at work. The student standing there then rights number of hippos the computer student is holding on the board. The exit check student then evaluates the total hippos and gets to declare if the computer student is done. Not enough hippos! Go back to the loop back spot. Continue with the computer student having to hang onto an increasingly hilarious number of hippos. As this is taking place I'm pointing out the order that things happen, and important details like you will never have a value outside the range while inside the for loop.

The important points are made, and the students have a clear visual to hang the somewhat esoteric idea onto.

$\endgroup$
2
  • $\begingroup$ Your loop back spot appears before the for declaration. Why? $\endgroup$
    – Ben I.
    May 12, 2022 at 3:27
  • $\begingroup$ The loop back spot is the for declaration. Hard to show using text. When I'm explaining this in class I simply write a 2 and draw an arrow pointing at for. $\endgroup$
    – codingCat
    May 12, 2022 at 11:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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