1.10. Implementing Loops with For Statements

Problem

You want to implement a code that repeats a certain number of times, perhaps applying the same procedure to every element in an array or some other changing values.

Solution

Use the for statement. The format of this statement is:

for (<replaceable>code to execute before loop</replaceable>;
     <replaceable>condition to be met for the loop to terminate</replaceable>;
     <replaceable>code to execute in every iteration of the loop</replaceable>){

}

Note

All three clauses of the for loop are optional. In other words, you can have a for loop that looks like this:

for (;;){ YOUR CODE HERE }

This is known as an infinite-loop or a loop that has no condition to terminate and will run forever. This is a very bad programming practice indeed and you should avoid using it by all means while developing iOS programs.

Discussion

Loops are useful in programming because you will often need to start a loop from one place to another, from one index to another, or from start to stop. For instance, you might want to loop through all characters inside a string and count how many “A” characters you can find in it. Another example is a loop that finds all files in a directory. This is a loop that finds the number of files and then starts from the first one until it gets to the last one.

Usually, programmers require a counter in their loops. For instance, you might want to read all the characters inside a C-String. For this, you will need the index of each character. If your string is 10 characters long, you will need to go from index 0 to 9. If your string is 20 characters long, you have to read from index 0 to 19. Since the length of your string is a variable, you can put it as the exit-conditional of your loop. Here is an example:

char *myString = "This is my string";

NSUInteger counter = 0;
for (counter = 0; /* Start from index 0 */
     counter < strlen(myString); /* Exit loop when we reach last character */
     counter++){ /* Increment the index in every iteration */

  char character = myString[counter];

  NSLog(@"%c", character);

}

The code that gets executed before the loop (as noted in the Solution section of this recipe) is obviously optional. In fact, all three main parts of a for loop are optional, but it is recommended that you think about how you intend to use your loops and use the three main parts of the for statement accordingly.

Let’s have a look at where you would want to skip the first statement of your for loop. As you could see in the previous section, our counter variable was set to 0 before we even started our loop. However, we are setting it to 0 again once our loop is about to start. This is unnecessary in this example, but there is nothing wrong with that approach. If you feel you don’t need the redundant code, simply remove it:

char *myString = "This is my string";

NSUInteger counter = 0;
for (; /* empty section */
     counter < strlen(myString); /* Exit loop when we reach last character */
     counter++){ /* Increment the index in every iteration */

  char character = myString[counter];

  NSLog(@"%c", character);

}

The second clause of any for loop is very important because this is the conditional that allows your loop to exit. Having no condition in the second clause is similar to having a never-ending loop, or an infinite loop as it is known. Therefore, it is best to think about the condition that allows your program to end the loop and continue on its path of execution.

Any variable defined in the first clause of a for loop is accessible inside the loop but not outside it. For instance:

for (NSUInteger counter = 0;
     counter < 10;
     counter++){
  NSLog(@"%lu", (unsigned long)counter);
}
/* "counter" is NOT accessible here. This line will throw compile time error */
NSLog(@"%lu", (unsigned long)counter);

The third clause inside a for loop is very interesting indeed. This is the statement that gets executed after every iteration of your loop. This includes the last iteration. For instance:

NSUInteger counter = 0;
for (counter = 0;
     counter < 4;
     counter++){
  NSLog(@"%lu", (unsigned long)counter);
}
NSLog(@"%lu", (unsigned long)counter);

This will print the following values to the console:

0
1
2
3
4

So our counter did get to number 4 although in our loop we asked that the counter should be less than 4. This proves the point that when our loop finishes, in the last iteration, the third clause of our for loop gets executed. But the code inside our loop won’t be called since the end-condition (second clause) will not be met and our loop will finish.

Get iOS 5 Programming Cookbook now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.