While: The Universal Loop

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.

Practice

Note

Be sure to thoroughly review the instructions in Section 2, “Practice Problem Instructions” before doing the practice problems below.
  1. What distinguishes the while loop from other loops?

  2. 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;
        }
            
  3. 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