The while loop is the only loop that needs to
exist. All other loops exist for the sake of convenience.
The basic structure of a C while loop looks like this:
initialization
while ( condition )
{
body
housekeeping
}
The basic structure of a Fortran while loop looks like this:
initialization
do while ( condition )
body
housekeeping
enddo
The condition can be any Boolean expression, i.e. any expression with a value of .true. or .false. in Fortran, and any integer expression in C.
Example 20.1. While Loop
Suppose we want to know the sine of every angle from 0 to 359 degrees. We could write 360 print statements, or we could use the following loop:
/***************************************************************************
* Description:
* Print sine of every angle in degrees from 0 to 360
***************************************************************************/
#include <stdio.h>
#include <math.h>
#include <sysexits.h>
int main(int argc,char *argv[])
{
double angle;
// Initialization
angle = 0.0;
// Condition
while ( angle <= 360.0 )
{
// Body
printf("sine(%f) = %f\n", angle, sin(angle * M_PI / 180.0));
// Housekeeping
angle += 1.0; // Note that we don't use ++ with floating point
}
return EX_OK;
}
!-----------------------------------------------------------------------
! Program description:
! Print sine of every angle in degrees from 0 to 360
!-----------------------------------------------------------------------
module constants
double precision, parameter :: PI = 3.1415926535897932d0
end module constants
program sine_loop
use constants ! Constants defined above
implicit none
real(8) :: angle
! Initialization
angle = 0.0d0
! Condition
do while ( angle <= 360.0d0 )
! Body
print *, 'sine(', angle, ') = ', sin(angle * PI / 180.0d0)
! Housekeeping
angle = angle + 1.0d0
end do
end program
Since C Boolean expressions are actually integers, it is possible to do some odd-looking things in a C program. For instance, since false is zero and true is any non-zero value, you could loop down from some number to zero without using a relational operator:
c = 10;
while ( c ) // Same as while ( c != 0 )
{
printf("%d squared = %d\n", c, c * c);
--c;
}
Some programmers think this makes them look clever,
but it's really just cryptic, and not a good practice. Looking
at this code, the reader has to wonder: Is c
a Boolean variable? If so, how is it set? Then they must waste
time searching the code to answer these questions.
Over the course of a long workday, these small unnecessary efforts,
add up to a lot of distraction, lost productivity, and fatigue.
Some may believe that it optimizes performance, but this is a myth. Most compilers will generate the same machine code whether we code an operator or not.
It's better to be explicit and clear. In fact, we can do better
than c != 0, since c should always
be positive for this loop. This makes the code a little more
self-documenting:
c = 10;
while ( c > 0 )
{
printf("%d squared = %d\n", c, c * c);
--c;
}
Example 20.2. A More Flexible Sine Printer
/***************************************************************************
* Description:
* Print sine of every angle in degrees from 0 to 360
***************************************************************************/
#include <stdio.h>
#include <math.h>
#include <sysexits.h>
int main(int argc,char *argv[])
{
double angle, final_angle;
// Initialization
printf("Initial angle? ");
scanf("%lf", &angle);
printf("Final angle? ");
scanf("%lf", &final_angle);
// Condition
while ( angle <= final_angle )
{
// Body
printf("sine(%f) = %f\n", angle, sin(angle * M_PI / 180.0));
// Housekeeping
angle += 1.0; // Note that we don't use ++ with floating point
}
return EX_OK;
}
!-----------------------------------------------------------------------
! Program description:
! Print sine of every angle in degrees from 0 to 360
!-----------------------------------------------------------------------
module constants
double precision, parameter :: PI = 3.1415926535897932d0
end module constants
program sine_loop
use constants ! Constants defined above
implicit none
real(8) :: angle, final_angle
! Initialization
print *, 'Initial angle?'
read *, angle
print *, 'Final angle?'
read *, final_angle
! Condition
do while ( angle <= final_angle )
! Body
print *, 'sine(', angle, ') = ', sin(angle * PI / 180.0d0)
! Housekeeping
angle = angle + 1.0d0
end do
end program
The condition in a while loop can be literally any Boolean
expression. Programmers can use their imagination and construct
loops with any conceivable condition. The examples above barely
scratch the surface of what is possible with while loops.
What distinguishes the while loop from other loops?
What is the advantage and disadvantage of the following loop, compared with one that uses a relational operator explicitly?
c = 10;
while ( c )
{
// Body
--c;
}
Write a C or Fortran program that prints the square root of every integer from 0 to 10. The exact format of the output is not important. Check the web for available math functions in C or Fortran, but verify your findings. Do not trust information from uncurated websites.
sqrt(0) = 0.000000
sqrt(1) = 1.000000
sqrt(2) = 1.414214
sqrt(3) = 1.732051
sqrt(4) = 2.000000
sqrt(5) = 2.236068
sqrt(6) = 2.449490
sqrt(7) = 2.645751
sqrt(8) = 2.828427
sqrt(9) = 3.000000
sqrt(10) = 3.162278