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