You can start in the middle of a loop

I’ve always been quite free with the limits of my loops. When I first learned the do-while, for and while loops, the start and end points weren’t fixated in my mind. Let me explain.

The usual start and end points are 0 and the number of iterations required minus one (yes, I’m in zero-index C territory). The professor was very persistent in ensuring we know how many iterations there were (I was a freshman in university). I thought it’s obvious, but apparently it’s a common error to miscount.

Just as important, you shouldn’t be fixated on the number of iterations in a loop too. Say you need to iterate for each month in a year. That’s 12 iterations. For the first 8 months, you need to do one thing, and for the other 4 months, you need to do something else. This is not recommended:

int i = 0;
for (i=1; i<=12; ++i)
{
	if (i<=8)
	{
		// do A
	}
	else
	{
		// do B
	}
}

It's confusing to read if tasks A and B are complex. Better to just:

int i = 0;
for (i=1; i<=8; ++i)
{
	// do A
}

for (i=9; i<=12; ++i)
{
	// do B
}

The tasks are now clearly defined and the code is easier to read. With the current hardware, I think the absence of 1 if-else or the presence of a 2nd for loop won't make much of a speed issue, so it's not really for optimisation purposes either.

Another common code chunk I encounter is the do-the-first-one-differently loop. There's a list you need to iterate through, but for the first one, you have to do something extra or different.

Here's an idea. Why don't you do that first iteration by itself, and start the loop on the second iteration?

There is no restriction you have to start a loop with the first or last item, or with 0 or (list.Count - 1). Loop where it makes sense. I hereby give thee permission to start in the middle of a loop.

A for question

Recently, I’ve had the opportunity to stumble upon this for loop question in the Dream In Code forum. Appalling code aside, it took me awhile to convince myself that, yes, programming can be hard sometimes. Ok, let’s take a look at this excerpt from the original thread starter:

for (i=j+k;; j+k)
break;

He claimed it worked. While I think modern compilers would fail it, I seem to remember older compilers are a bit more forgiving. Particularly the j+k incrementor part. Basically, it’s like a single statement

j+k;

Doesn’t do anything. Sure it adds j and k together, but without doing anything with the result, it’s not useful. But it’s valid for the older compilers I’ve worked with.

Well, assuming it works, he just assigned the sum j+k to the variable i, do no loop checks, breaks immediately, and so doesn’t even hit the incrementor part. Did anyone notice anything yet?

He doesn’t need the for loop.

He could’ve just assigned j+k to i and be done with it.

To clear up the mystery of the for loop, we’ll take a value doubling example, so let’s study the following:

int i, sum;
sum = 1;
for (i = 0; i < 5; ++i)
{
    sum += sum;
}

There’s the multiply by 2 method. There’s the shift left by one placing method. I chose to simply add itself to itself in each iteration.

That was the standard for loop structure. Usually, the same variable appears in the initialiser part, the loop terminator part and the incrementor part.
for (initialiser; terminator; incrementor)

Here’s the short, one-liner version:

int i, sum;
for (i = 0, sum = 1; i < 5; ++i, sum += sum) ;

The incrementor part is just a place where any code is executed before the terminator condition is checked. Technically speaking, you can put any code here. But please don’t. There’s a proper place for whatever you can have in mind. It’s called the loop body.

How about using a while loop?

int i, sum;
i = 0;
sum = 1;
while (i < 5)
{
    sum += sum;
    ++i;
}

Note the incrementing code ++i is now at the end of the loop body. But the end result is equivalent to the for loops above.

Then there’s the do-while loop:

int i, sum;
i = 0;
sum = 1;
do
{
    sum += sum;
    ++i;
} while (i < 5);

do-while loops have this unique property. The loop body is executed at least once. It’s like “do loop body, then check condition”. The while loop works like “check condition, then do loop body”.

Because of this unique property, the following code

int i, sum;
i = 0;
sum = 1;
do
{
    sum += sum;
    ++i;
} while (i < 0);

ends up with the variable sum storing 2 instead of 1, even though the terminating condition is always false (hence it breaks from the loop immediately).

You might like to read up on my introductory article on for loops for more information.

Beginning C# – Loops and increments

Part of a computer’s charm is its ability to do repetitive tasks in a consistent manner. Doing lightning fast calculations? Good. Doing those calculations with accurate results? Better. Doing those calculations with accurate results everyday for the past year and not complaining? Oh my goodness!

The basis of programming this repetitive behaviour is the loop. There are 4 kinds of loops:

  • for loop
  • while loop
  • do-while loop
  • foreach loop

We’ll look at the for and while loops since they’re more common. In the following example code, we’ll be looking at the calculation of factorials. The factorial of 5, represented in mathematics as 5!, is equal to 1x2x3x4x5 = 120. From Wikipedia’s description of factorials,

In mathematics, the factorial of a non-negative integer n is the product of all positive integers less than or equal to n

Oh yes, the example code:

            const int cnFactorial = 7;
            // the following line of code will fail
            // because cnFactorial is a constant
            //cnFactorial = 5;

            int i, result;

            result = 1;
            for (i = 1; i <= cnFactorial; ++i)
            {
                result = result * i;
            }
            Console.WriteLine("Factorial for {0} is {1}", cnFactorial, result);

            result = 1;
            i = 1;
            while (i < cnFactorial + 1)
            {
                result = result * i;
                i++;
            }
            Console.WriteLine("Result is {1} for {0}!", cnFactorial, result);

            Console.WriteLine("End of program");
            Console.ReadLine();

Constants
Right there on the first line, we hit our new keyword const. It makes our integer variable cnFactorial a constant. Any value first assigned to cnFactorial can never be changed thereafter. Certain values are always the same, like PI (3.14159) or the number of months in a year (12). Adding the const keyword in front of a variable declaration fixes that value, reducing programming errors in case we super coders forget and happen to change an unchangeable value.

The resulting executable is also leaner because the computer compiler will, in effect, replace every occurrence of the constant variable’s name with the constant value. This means that program only has the constant value, and not the constant variable! Constant values take up less space in a program than variables.

Anatomy of a for loop
The for loop has 3 parts, separated by semicolons: initialiser, terminator and incrementor.
for (initialiser; terminator; incrementor)

The initialiser sets the starting conditions for the for loop. This is a good place to code any variable assignments such as resetting variable values.

The terminator is where you code the stopping condition for the for loop. Many a programmer has failed at least once, where they gave the wrong stopping condition and the for loop never ends. At best, the infinite loop keeps printing out messages. At worst, the computer crashes. Code with caution!

The incrementor is where something is usually changed, before checking the terminating condition.

It’s easier to just go through the code:

            result = 1;
            for (i = 1; i <= cnFactorial; ++i)
            {
                result = result * i;
            }

First, we assign the value of 1 to the variable “result”. Then in the initialiser of the for loop, we assign 1 to the variable i. There’s this unofficial type of variable which I’ll call the “loopers”. These looper variables are declared for the sole purpose of running through the for loop. They are also usually single characters by name. i, j, k and a, b, c and p, q, r and x, y, z are the more common ones.

Then the terminating condition reads “If i is less than or equal to cnFactorial, continue”.

The code in the incrementor, ++i, is a shortcut for “Add 1 to the value of i, then assign this new value to i”. It is equivalent to

i = i + 1;

Then the contents of the for loop reads “Multiply the value in variable ‘result’ by the value in variable ‘i’, and then assign this new value to ‘result’.”

The whole flow of the logic is like this:

  1. result has value of 1
  2. Start of for loop, i has value of 1
  3. Check that i (1) is less than or equal to cnFactorial (7), which is true so…
  4. Assign result (1) * i (1) which is 1 (1*1) to result
  5. Do ++i, so i now has value of 2
  6. Check that i (2) is less than or equal to cnFactorial (7), which is true so…
  7. Assign result (1) * i (2) which is 2 (1*2) to result
  8. Do ++i, so i now has value of 3
  9. Check that i (3) is less than or equal to cnFactorial (7), which is true so…
  10. Assign result (2) * i (3) which is 6 (2*3) to result
  11. Do ++i, so i now has value of 4
  12. Check that i (4) is less than or equal to cnFactorial (7), which is true so…
  13. Assign result (6) * i (4) which is 24 (6*4) to result
  14. Do ++i, so i now has value of 5
  15. Check that i (5) is less than or equal to cnFactorial (7), which is true so…
  16. Assign result (24) * i (5) which is 120 (24*5) to result
  17. Do ++i, so i now has value of 6
  18. Check that i (6) is less than or equal to cnFactorial (7), which is true so…
  19. Assign result (120) * i (6) which is 720 (120*6) to result
  20. Do ++i, so i now has value of 7
  21. Check that i (7) is less than or equal to cnFactorial (7), which is true so…
  22. Assign result (720) * i (7) which is 5040 (720*7) to result
  23. Do ++i, so i now has value of 8
  24. Check that i (8) is less than or equal to cnFactorial (7), which is false so we terminate the loop! Whoopee!

The purpose of that incredibly and mind-numbingly long and tedious explanation is so you can appreciate how obliging the computer is when performing repetitive tasks. Anyway, we then print the result. This time, we format the output a little.

            Console.WriteLine("Factorial for {0} is {1}", cnFactorial, result);

The {0} and {1} are placeholders, where {0} refers to the first value (cnFactorial) and {1} refers to the second value (result) after the string.

Why does {0} refer to the first value? Good question. Unfortunately I don’t have an easy answer. It is primarily due to the ancient programming custom of offsets, where the first item is offset by 0 positions. The second item is offset by 1 position. This has caused many beginner programmers to falter.

Homework
Unravel the logic for the while loop in the manner demonstrated above. Yes it’s tedious, but it’ll make you a better person. The while loop takes in only the terminating condition.

You’ll also notice the i++ and it does exactly the same thing as ++i. What’s the difference? Ahhh… but that is your second piece of homework. *grin*

Download source code.