Tuesday, September 21, 2010

for Loop Variations

The previous discussion described the most common form of the for loop. However,
several variations of the for are allowed that increase its power, flexibility, and
applicability to certain programming situations.
One of the most common variations uses the comma operator to allow two or more
variables to control the loop. (Remember, you use the comma operator to string
together a number of expressions in a "do this and this" fashion. See Chapter 2.) For
example, the variables x and y control the following loop, and both are initialized
inside the for statement:
for(x=0, y=0; x+y<10; ++x) {
y = getchar();
y = y - '0'; /* subtract the ASCII code for 0
from y */
.
.
.
}
Commas separate the two initialization statements. Each time the loop repeats, x is
incremented and y's value is set by keyboard input. Both x and y must be at the correct
value for the loop to terminate. Even though y's value is set by keyboard input, y must
be initialized to 0 so that its value is defined before the first evaluation of the
conditional expression. (If y were not defined, it could by chance contain the value 10,
making the conditional test false and preventing the loop from executing.)
The converge() function, shown next, demonstrates multiple loop control variables
in action. The converge() function copies the contents of one string into another by
moving characters from both ends, converging in the middle.
/* Demonstrate multiple loop control variables. */
#include <stdio.h>
#include <string.h>
void converge(char *targ, char *src);
int main(void)
{
char target[80] = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
converge(target, "This is a test of converge().");
printf("Final string: %s\n", target);
return 0;
}
/* This function copies one string into another.
It copies characters to both the ends,
converging at the middle. */
void converge(char *targ, char *src)
{
int i, j;
printf("%s\n", targ);
for(i=0, j=strlen(src); i<=j; i++, j--) {
targ[i] = src[i];
targ[j] = src[j];
printf("%s\n", targ);
}
}
Here is the output produced by the program.
XXXXXXXXXXXXXXXXXXXXXXXXXXXXX
TXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ThXXXXXXXXXXXXXXXXXXXXXXXXXX.
ThiXXXXXXXXXXXXXXXXXXXXXXXX).
ThisXXXXXXXXXXXXXXXXXXXXXX().
This XXXXXXXXXXXXXXXXXXXXe().
This iXXXXXXXXXXXXXXXXXXge().
This isXXXXXXXXXXXXXXXXrge().
This is XXXXXXXXXXXXXXerge().
This is aXXXXXXXXXXXXverge().
This is a XXXXXXXXXXnverge().
This is a tXXXXXXXXonverge().
This is a teXXXXXXconverge().
This is a tesXXXX converge().
This is a testXXf converge().
This is a test of converge().
Final string: This is a test of converge().
In converge() , the for loop uses two loop control variables, i and j, to index the
string from opposite ends. As the loop iterates, i is increased and j is decreased. The
loop stops when i is greater than j, thus ensuring that all characters are copied.
The conditional expression does not have to involve testing the loop control
variable against some target value. In fact, the condition may be any relational or
logical statement. This means that you can test for several possible terminating
conditions.
For example, you could use the following function to log a user onto a remote
system. The user has three tries to enter the password. The loop terminates when the
three tries are used up or the user enters the correct password.
void sign_on(void)
{
char str[20];
int x;
for(x=0; x<3 && strcmp(str, "password"); ++x) {
printf("Enter password please:");
gets(str);
}
if(x==3) return;
/* else log user in ... */
}
This function uses strcmp() , the standard library function that compares two strings
and returns 0 if they match.
Remember, each of the three sections of the for loop may consist of any valid
expression. The expressions need not actually have anything to do with what the
sections are generally used for. With this in mind, consider the following example:
#include <stdio.h>
int sqrnum(int num);
int readnum(void);
int prompt(void);
int main(void)
{
int t;
for(prompt(); t=readnum(); prompt())
sqrnum(t);
return 0;
}
int prompt(void)
{
printf("Enter a number: ");
return 0;
}
int readnum(void)
{
int t;
scanf("%d", &t);
return t;
}
int sqrnum(int num)
{
printf("%d\n", num*num);
return num*num;
}
Look closely at the for loop in main() . Notice that each part of the for loop is
composed of function calls that prompt the user and read a number entered from the
keyboard. If the number entered is 0, the loop terminates because the conditional
expression will be false. Otherwise, the number is squared. Thus, this for loop uses the
initialization and increment portions in a nontraditional but completely valid sense.
Another interesting trait of the for loop is that pieces of the loop definition need not
be there. In fact, there need not be an expression present for any of the sections—the
expressions are optional. For example, this loop will run until the user enters 123:
for(x=0; x!=123; ) scanf("%d", &x);
Notice that the increment portion of the for definition is blank. This means that each
time the loop repeats, x is tested to see if it equals 123, but no further action takes place.
If you type 123 at the keyboard, however, the loop condition becomes false and the
loop terminates.
The initialization of the loop control variable can occur outside the for statement.
This most frequently happens when the initial condition of the loop control variable
must be computed by some complex means as in this example:
gets(s); /* read a string into s */
if(*s) x = strlen(s); /* get the string's length */
else x = 10;
for( ; x<10; ) {
printf("%d", x);
++x;
}
The initialization section has been left blank and x is initialized before the loop is
entered.

No comments:

Post a Comment