CSC 161 Grinnell College Spring, 2015
 
Imperative Problem Solving and Data Structures
 
 

Laboratory Exercise on Loops

Goals

The goal of this lab is to introduce loops in C programming to students and increase familiarity with different types of loops.

Preparation before Class

Introduction

The reading for today's lab identified three basic types of loops: for, while, and do..while. Program 3-loops.c uses each of these constructions to print the numbers 1 to 10 on separate lines.

Although the loops have many similarities, one loop may seem to fit a circumstance more naturally than another.

The for loop often focuses on the progression of one or more control variables. In what follows, the code emphasizes the values for i during the running of the code.

  /* for loop */
  printf ("for loop\n");
  for (i = start; i <= end; i++)
    {
      printf ("%5d", i);
    }
  printf ("\n");

A while loop often emphasizes the condition under which the loop will continue. Updating variables takes place in the body of the loop and may be complex.

  /* while loop */
  printf ("while loop\n");
  i = start;
  while (i <= end)
    {
      printf ("%5d", i);
      i++;
    }
  printf ("\n");

In contrast to for and while which may skip the loop completely if the condition is not satisfied, the do..while always executes its loop body at least once.

  /* do while */
  printf ("do..while loop\n");
  i = start;
  do
    {
      printf ("%5d", i);
      i++;
    }
  while (i <= end);
  printf ("\n");

Work Started in Class

Initial Experiments with Loops

  1. Copy 3-loops.c to your account, compile and run it, and be sure you understand how each loop works. Also, explain the purpose of the line printf ("\n");. Is this statement in the loop or not? Why?

  2. In the 3-loops.c program, change the initialization of start to 11, recompile, and rerun the program. Describe what happens and explain why.

Printing a Table

  1. In Module 0, you saw a program (quarts.c), that converted quarts to liters. Write a program that prints a table listing the conversions from one to twelve quarts into liters.

    • Use the line printf("%4d%16.4lf\n", quarts, liters); to keep proper spacing.

    Example Output:

    Table of quart and liter equivalents
    Quarts           Liters
       1             0.9463
       2             1.8927 
       3             2.8390 
       4             3.7853 
       5             4.7317 
       6             5.6780 
       7             6.6243 
       8             7.5707 
       9             8.5170 
      10             9.4633 
      11            10.4097 
      12            11.3560 
    
  1. In your first version of the program, implement the loop using a for construct.
  2. In your second version of the program, implement the loop using a while construct.

Loops with a Scribbler 2 Robot

  1. Simple Motion Commands: Write one or more programs that have the Scribbler 2 robot move in various ways:

    1. A for loop should move the scribbler forward 5 times.
    2. A while loop should move the Scribbler in some direction for increasing amounts of time.
    3. A for loop should move the Scribbler some number of times at changing speeds.
    4. A while loop should change both speed and time in the same loop.
  2. Rising Pitch: A program is supposed to beep once at 800 Hz, then increase by 20 Hz every beep for another twelve beeps. Write this program using the following template for a for loop based on an integer variable i:

    for (i = 0; i <= 12; i++)
    {
       int freq = /* compute frequency here */
       rBeep (1.0, freq);
    }
    
  3. Nested Loop: Modify the loop from Step 5, so that the program beeps i times at the given frequency, rather than just once, inside the loop. Thus, the resulting program should beep once at 800 Hz, then twice at 820 Hz, then three times at 840 Hz, etc.

Step 6 illustrates how loops may be nested inside one another. In this case, the outside loop systematically works through a sequence of main steps. The inside loop then supplies the processing for each particular element of the main sequence.

Programming Hint — Infinite Loops: Computers are quite patience, so once a loop starts, the loop will continue as long as the appropriate condition remains true. If the condition never becomes false, the loop will never stop. For example, the following loop will continue forever

while (1)
{

}

Although this type of construct may seem peculiar, such loops can be useful from time to time. For example, we expect to type commands in a terminal window for as long as the window remains open. Thus, the code behind the terminal window might use a while (1) construct to keep reading and processing commands.

As a practical matter, if you encounter this situation with a program, and if you want the program to stop, you can use the key combination ctrl-c to end your program in the terminal window. In this situation, turning the Scribbler 2 off or pressing the reset button resets the robot.

Another Nested Loop

  1. Write a program that consecutively beeps more times in a row, until seven beeps in a row are reached. So, the robot would beep once and sleep for one second, then beep twice and sleep for one second, then three times and sleep for one second, and so on.

Homework

The reading on Scribbler 2 motion provides numerous details regarding motion commands.

Blocking and Nonblocking Commands

The Scribbler 2 movement commands may be organized into two basic groups:

  1. Consider the following code segment which includes a movement command and the sounding of three notes.

       rForward (1.0, 5.0);
       rBeep (1.0, 880);
       rBeep (1.0, 1280);
       rBeep (1.0, 1760);
    
    1. Include this code segment in a program, and observe what happens. When the motion starts, do the beeps sound as the robot moves (nonblocking movement), or do the beeps sound after the robot movement has finished (blocking movement)?
    2. Change the duration in rForward from 5.0 to -5.0. Then repeat part a.

    Write, in your own words, what it means for a command to be blocking or nonblocking.

Spiral Motion

Consider how to make the robot move spirally. Spirals begin from a center point, with the line moving in a circular motion, with a gradually greater distance from the origin. There are two straightforward ways that move the Scribbler 2 in a spiral motion for at least ten seconds.

  1. Write a program that makes the Scribbler 2 robot behave like turtles in CSC 151. So, the robot would move forward, then turn (e.g., rTurnLeft or rTurnRight), then move forward a little further, then turn, and so on in a spiral shape. Just a single loop is needed here.

Motion With Obstacles

While blind motion can be interesting, sensing obstacles is where motion really gets awesome!

  1. Write a simple program which moves the robot forward until it sees an obstacle.

    Hint: Experimentation with the obstacle sensors suggests moderate variability in the readings obtained. One way to reduce the variability of these readings is to take several readings and average.

    • With the traditional MyroC package, one might use the rGetObstacleTxt(char * value) function. Here the value parameter specifies the desired sensor: "left", "middle" or "middle", "right".

    • With the MyroC package under development MyroCDev, one might use the rGetObstacleTxt(char * value, int sampleSize) function. Here the sampleSize parameter allows one to take several readings of the sensor and compute an average. To get a single reading, use 1 as the sampleSize.

  2. Write a simple program which moves the robot forward until it sees an obstacle, then turns right, then moves forward again until it sees an obstacle.

  3. Now generalize your program so that your robot moves forward until it sees an obstacle, then turns right, moves forward until it sees an obstacle, turns right, moves forward until obstacle, turns right, etc. It should do this until the program is terminated.

Feedback Welcome

Development of laboratory exercises is an iterative process. Prof. Walker welcomes your feedback! Feel free to talk to him during class or stop by his office.