Download presentation
Presentation is loading. Please wait.
Published byLeona Morton Modified over 9 years ago
1
(6-2) Iteration in C II H&K Chapter 5 Instructor - Andrew S. O’Fallon CptS 121 (February 19, 2016) Washington State University
2
C. Hundhausen, A. O’Fallon 2 Don’t Forget About Flowcharts! Recall: flowcharts provide visual representations of algorithms and/or processes Excellent tool for verifying logical flow
3
C. Hundhausen, A. O’Fallon 3 General Structure of Flowchart for Loops Process body of loop Condition? Yes or T No or F
4
C. Hundhausen, A. O’Fallon 4 Conditional Loops (1) In the previous lecture, we considered loops whose number of iterations was known at the time the loop started In practice, we don’t always know in advance how many times a loop will execute! – Often, the loop body itself determines whether another execution is necessary
5
C. Hundhausen, A. O’Fallon 5 Conditional Loops (2) Consider, for example, the following extension to the Tollbooth application: – Suppose that, for safety reasons, the tollbooth limits the number of vehicles that can cross the bridge on a given day to a certain tonnage. – Suppose that you want to read in vehicle data from a file to simulate cars crossing the bridge. – When the maximum tonnage has been reached, not more data are read from file.The program prints out a message reporting the revenues collected for the day the number and total weight of all cars that crossed for the day – See next slide for a possible solution
6
C. Hundhausen, A. O’Fallon 6 Conditional Loops (3) #include #define MAX_TONS_PER_DAY 20 #define POUNDS_PER_TON 2000 … void main(void) { int vehicle_count, axles; double weight, tons, toll, total_tolls; FILE *infile; infile = get_and_open_file(); count = tons = total_tolls = 0; while (tons < MAX_TONS_PER_DAY) { axles = read_num_axles(infile); weight = read_weight(infile); toll = compute_toll(axles,weight); count++; /* Another car has crossed. */ tolls += toll; /* Another toll has been collected */ tons += weight/2000.0; /* Add weight of this car */ /* to running total*/ } printf("%d cars, weighing %.2f tons, crossed the bridge today.", count, tons); printf("$%.2f in tolls was collected today.",total_tolls); }
7
C. Hundhausen, A. O’Fallon 7 Conditional Loops (4) A possible sequence of questions that can guide loop design, applied to previous example QuestionAnswerImplications for design 1. What are the inputs?Weight of vehicle, # of axles Input vars: weight, axles 2. What are the outputs?# and weight of vehicles that cross bridge; tolls collected Output vars: count, tons, total_tolls
8
C. Hundhausen, A. O’Fallon 8 Conditional Loops (5) A possible sequence of questions that can guide loop design, applied to previous example (cont.) QuestionAnswerImplications for design 3. Is there repetition?Yes! We repeatedly Get # axles and weight Calculate toll Add weight to total weight Add toll to total tolls Add 1 to vehicle count Program variable needed: MAX_TONS_ PER_DAY
9
C. Hundhausen, A. O’Fallon 9 Conditional Loops (6) A possible sequence of questions that can guide loop design, applied to previous example (cont.) QuestionAnswerImplications for design 4. Do I know in advance how many steps will be repeated? No.Loop will NOT be controlled by counter 5. How do I know how long to keep repeating steps? As long as the total weight of the vehicles is below the maximum The loop repetition condition is total_tons < MAX_TONS_ PER_DAY
10
C. Hundhausen, A. O’Fallon 10 Sentinel-Controlled Loops (1) Often we want to continue looping until a certain value, called a “sentinel,” is encountered For example, suppose we change the requirements of the Tollbooth application slightly: – There is no maximum on the total weight of the vehicles that cross the bridge on a given day – We will read in vehicle data interactively – The user will tell us that there are no more vehicles for the day by entering ‘n’ when asked whether there is another vehicle that needs to cross (‘n’ = “No” the sentinel value)
11
C. Hundhausen, A. O’Fallon 11 Sentinel-Controlled Loops (2) #include #define SENTINEL_VALUE 'n' #define POUNDS_PER_TON 2000 … void main(void) { int count, axles; char continue; double weight, tons, toll, total_tolls; count = tons = total_tolls = 0; printf("Did at least one car cross the bridge? (y/n) "); scanf(" %c ",&continue); /* Note blanks absorb whitespace */ while (continue != SENTINEL_VALUE) { axles = read_num_axles(); /* assume these two functions read */ weight = read_weight(infile); /* prompt user interactively */ toll = compute_toll(axles,weight); count++; /* Another car has crossed. */ total_tolls += toll; /* Another toll has been collected. */ tons += weight/2000.0; /* Add weight of this car to total*/ printf("Did another car cross the bridge? (y/n) "); scanf(" %c ",&continue); /* Note blanks absorb whitespace */ } …
12
C. Hundhausen, A. O’Fallon 12 Sentinel-Controlled Loops (3) Note that this could also be rewritten as a for loop: … printf("Did at least one car cross the bridge? (y/n) "); for (scanf(" %c ",&continue); continue != SENTINEL; scanf(" %c ",&continue)) { axles = read_num_axles(); /* assume these two functions read */ weight = read_weight(infile); /* prompt user interactively */ toll = compute_toll(axles,weight); count++; /* Another car has crossed. */ total_tolls += toll; /* Another toll has been collected. */ tons += weight/2000.0; /* Add weight of this car to total*/ printf("Did another car cross the bridge? (y/n) "); } …
13
C. Hundhausen, A. O’Fallon 13 Endfile-Controlled Loops (1) Often, as in the original toll booth application, we read input data in from a file We want to continue processing data until there is no more data to process In other words, we want to continue processing data until the end of the file is encountered We can use the endfile-controlled loop pattern to do this
14
C. Hundhausen, A. O’Fallon 14 Endfile-Controlled Loops (2) For example, suppose that we change the requirements of the tollbooth application again – We will read the input values from a text file, as before – We will continue reading axle/weight pairs until we reach the end of the file – We will need to redesign two functions we wrote in class a couple of weeks ago: read_num_axles read_weight – Let's look at the implementation…
15
C. Hundhausen, A. O’Fallon 15 Endfile-Controlled Loops (3) fscanf actually returns a value indicating the number of items it successfully reads in If it encounters the end of the file, it returns as its result the value of the standard constant EOF (which is a negative integer) We can thus redesign read_num_axles to return EOF if it encounters the end of the file: int read_num_axles(FILE *infile) { int num_axles, input_status; input_status = fscanf(infile,”%d”,&num_axles); if (input_status != EOF) return (num_axles); else return input_status; }
16
C. Hundhausen, A. O’Fallon 16 Endfile-Controlled Loops (4) For the sake of simplicity, we will assume that data always come in pairs, so we won't check for EOF in read_weight Challenge question: Do you see another problem with adding EOF-checking to read_weight? Explain. The next slide puts the solution together
17
C. Hundhausen, A. O’Fallon 17 Endfile-Controlled Loops (5) #include #define POUNDS_PER_TON 2000 … void main() { int count, test_axles, axles; double weight, tons, toll, total_tolls; FILE *infile; infile = get_and_open_file(); count = tons = total_tolls = 0; test_axles = read_num_axles(infile); while (test_axles != EOF) { axles = test_axles; /* We can accept this value as valid. */ weight = read_weight(infile); /* Assume EOF won't be seen. */ toll = compute_toll(axles,weight); count++; /* Another car has crossed. */ total_tolls += toll; /* Another toll has been collected. */ tons += weight/2000.0; /* Add weight of this car to total*/ test_axles = read_num_axles(infile); /* Prepare for next */ /* iteration. */ } … }
18
C. Hundhausen, A. O’Fallon 18 Flag-Controlled Loops (1) In the previous examples, we have assumed that input data are always in the proper format: – When we ask for the number of axles, we will obtain an integer (either interactively from the user, or from the input file) – When we ask for the weight, we will obtain a double (either interactively from the user, or from the input file) In the real world, this assumption is faulty – People enter invalid data all the time – Files contain invalid data all the time Flag-controlled loops ensure that valid data are read in
19
C. Hundhausen, A. O’Fallon 19 Flag-Controlled Loops (2) Recall that the fscanf function returns EOF when the end of the file is encountered Likewise fscanf and scanf return the value 0 when at least one the data values it reads in could not be converted to the specified type – For example, assume the following scanf statement int my_int, input_status; printf("Please enter an integer: "); input_status = scanf("%d",&my_int); If the user were to type in "wow" here, i nput_status would be assigned the value 0, since "wow" cannot be converted to an int
20
C. Hundhausen, A. O’Fallon 20 Flag-Controlled Loops (3) The final C interative construct, the do-while loop, can be used to trap this situation and re-prompt the user: int my_int, input_status; char skip_ch; do { printf("Please enter an integer: "); input_status = scanf("%d",&my_int); do { /* nested do-while skips rest of data line */ scanf("%c", skip_ch); } while (skip_ch != '\n'); } while (input_status == 0); Notice that, unlike the while and for loop constructs, the do-while loop construct is guaranteed to execute at least once.
21
C. Hundhausen, A. O’Fallon 21 Flag-Controlled Loops (4) You try it: Given this pattern, tailor interactive versions of read_num_axles so that they only accept valid input (an int or a double ) from the user (work with a partner for 5 minutes) int read_num_axles() { int num_axles, input_status; /* your code goes here */ } double read_weight() { double weight; int input_status; /* your code goes here */ }
22
C. Hundhausen, A. O’Fallon 22 Flag-Controlled Loops (5) Now let's go one step further. Let's do a reality check on each input value to make sure it's not only of the correct type, but within an acceptable range: – Num_axles should be between 2 and 5 (no unicycles allowed!) int read_num_axles() { int num_axles, input_status, input_ok; char skip_ch; do { printf("Please enter the number of axles: "); input_status = scanf("%d",&num_axles); input_ok = (input_status != 0 && num_axles > 1 && num_axles < 6); /* status flag */ if (!input_ok) printf("The value you entered is invalid."); do { /* skip rest of data line */ scanf("%c", &skip_ch); } while (skip_ch != '\n'); } while (!input_ok); return num_axles; }
23
C. Hundhausen, A. O’Fallon 23 Flag-Controlled Loops (6) Now let's go one step further (cont.). – Weight should be between 200.0 and 4000.0 double read_weight() { int input_status, input_ok; char skip_ch; double weight; do { printf("Please enter the vehicle weight: "); input_status = scanf("%lf",&weight); input_ok = (input_status != 0 && weight >= 200.0 && weight <= 4000.0); if (!input_ok) printf("The value you entered is invalid."); do { /* skip rest of data line */ scanf("%c", &skip_ch); } while (skip_ch != '\n'); } while (!input_ok); return weight; }
24
C. Hundhausen, A. O’Fallon 24 References J.R. Hanly & E.B. Koffman, Problem Solving and Program Design in C (8 th Ed.), Addison- Wesley, 2016 P.J. Deitel & H.M. Deitel, C How to Program (7 th Ed.), Pearson Education, Inc., 2013.
25
C. Hundhausen, A. O’Fallon 25 Collaborators Chris Hundhausen
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.