• No se han encontrado resultados

DISTRIBUCIÓN Se alimentan de invertebrados.

CHAVELA GRIS

DISTRIBUCIÓN Se alimentan de invertebrados.

Before looking at the details of Java’s while and for statements, it is useful to take a step back and think holistically about the role that iteration—which is just a fancier computer science term for repetition—plays in the programming process. Think back for a moment to the Add2Integers program from Chapter 2. While that example helped illustrate how simple programs are written, it was hardly anything to get excited about. Most people are perfectly capable of adding two integers together with reasonable speed and accuracy. For a job that simple, a computer isn’t necessary. But what if you needed to add ten

FIGURE 4-3 Program to convert an integer to its rank as a playing card

/*

* File: CardRank.java * ---

* This program reads in an integer between 1 and 13 and * writes out the appropriate symbol for a playing card * of that rank.

*/

import acm.program.*;

public class CardRank extends ConsoleProgram { public void run() {

println("This program converts integers to card ranks."); int n = readInt("Enter an integer between 1 and 13: "); switch (n) {

case 1: println("Ace"); break; case 11: println("Jack"); break; case 12: println("Queen"); break; case 13: println("King"); break; default: println(n); break; }

} }

integers, or a thousand integers, or a million integers. At that point, the advantages of a computer become more clear.

But how would you go about changing the Add2Integers program so that it was able to add up integers on a larger scale? If you wanted to add four integers, you could simply add a few lines to the run method, as follows:

public void run() {

println("This program adds four integers."); int n1 = readInt("Enter n1: ");

int n2 = readInt("Enter n2: "); int n3 = readInt("Enter n3: "); int n4 = readInt("Enter n4: "); int total = n1 + n2 + n3 + n4;

println("The total is " + total + "."); }

While this approach is suitable for adding four integers, it would quickly become tedious if you tried to apply the same strategy for ten integers, let alone a thousand or a million.

Suppose that you wanted to find a way to write the program for adding ten integers in a way that did not require the declaration of ten variables. Solving problems like this one is what makes computer programming hard; it is also what makes it interesting and fun. Think about the problem for a minute. Imagine that you are adding up 10 numbers— without a computer—and that I start calling those numbers out to you: 7, 4, 6, and so on. What would you do? You could write down the numbers and then add them at the end. This strategy is analogous to the one used in the Add2Integers program. It’s effective, but it won’t win any prizes for speed or cleverness. Alternatively, you could try adding

the numbers as you go: 7 plus 4 is 11, 11 plus 6 is 17, and so on. You don’t have to keep track of each individual number, just the current total. When you hear the last number, you’re all set to announce the answer.

The fact that you don’t have to remember each individual number should help answer the question of how to add 10 integers without declaring 10 variables. With this new strategy, you should be able to write a new Add10Integers program using only two variables: one for each number as it comes in (value) and one for the sum of the numbers so far (total). Each time you read in a new number into value, you simply add it to total, which keeps track of the running total. Once you’ve done so, you can go back and reuse value to hold the next number, which is treated in precisely the same way. This insight should enable you to begin the task of coding a program that uses the new strategy. For each input value, you know that you must execute the following steps: 1. Request an integer value from the user and store it in the variable value.

2. Add value to the running sum stored in the variable total.

You already know how to code the first step; it is a perfect example of the read-an- integer-from-the-user pattern that you saw many times in Chapter 2 and that has the following general form:

int variable = readInt(prompt);

You also know how to code the second step. Adding value to total is an instance of the shorthand assignment patterns introduced in Chapter 3. To add value to total, the idiom is

total += value;

The two patterns—one for reading in an integer and one for adding that integer to a running total—give you everything you need to code the operations that must occur for each input value in the Add10Integers program. For each of the 10 input values, the program must execute the following statements:

int value = readInt(" ? "); total += value;

At this point, all you need to do is find some way to make the program execute this set of statements 10 times.

The repeat-N-times pattern

As you already learned in your encounters with Karel the Robot, Java contains an idiomatic pattern for repeating a block of code a predetermined number of times. That idiom is the repeat-N-times pattern, which has the following form:

for (int i = 0; i < N; i++) { statements to be repeated

}

In the repeat-N-times pattern, the value N indicates the number of repetitions you want. For example, if you replace N with 5, the statements enclosed within the braces will be executed five times. To use this pattern in the Add10Integers program, you need to replace N by 10. The statements enclosed in the braces are the statements that (1) read an

integer into value and (2) add that value to total. If you make these substitutions in the paradigm, you get the following code:

for (int i = 0; i < 10; i++) { int value = readInt(" ? "); total += value;

}

At this point, you are almost set to write the complete Add10Integers program, but there is a minor wrinkle that must still be addressed. The variable value is declared as an integer as part of the pattern for reading in an integer from the user. The variable total, however, is not yet declared. For this loop to work properly, total must be declared outside the loop and given an initial value of 0. Thus, before the for loop, you need to include the declaration

int total = 0;

to make sure that this variable can serve its function as a running total. Setting a variable to its proper starting value is called initialization. In many languages, failure to initialize variables is a common source of bugs. Java, however, is pretty good about checking for uninitialized variables and letting you know that such initialization is needed.

This final piece of the puzzle is all you need to complete the Add10Integers program. The run method you need would look like this:

public void run() {

println("This program adds ten integers."); int total = 0;

for (int i = 0; i < 10; i++) { int value = readInt(" ? "); total += value;

}

println("The total is " + total + "."); }

This program, however, is not engineered as well as one would like. You won’t always be in the position of adding exactly ten integers, and it should be easy to change your code so that it added a different number of integers. As things stand, you would have to go into the guts of the code and change both the initial message and the limit in the for loop. A better approach is to introduce a named constant as described in Chapter 3. If you choose to call this constant NVALUES, you would come up with a program that looked something like the AddNIntegers program in Figure 4-4.

The read-until-sentinel pattern

Even with the specification of the number of values as a named constant, the AddNIntegers program is unlikely to meet the needs of any significant number of users in its present form. Although making the change is comparatively easy, updating the program so that it adds a different number of integers still requires an explicit change in the program and a recompilation. What you really need is a more general program that can add any number of input values, where that number does not have to be specified in advance. From the user’s point of view, having to count the numbers in advance is a bad idea. If you were using such a program, what you would like to do is enter the numbers until you’ve finished your list. At that point, you’d like to be able to tell the program that you have run out of numbers.

FIGURE 4-4 Program to add a predefined number of integers

/*

* File: AddNIntegers.java * ---

* This program adds a predefined number of integers and * then prints the sum at the end. To change the number * of integers, change the definition of NVALUES.

*/

import acm.program.*;

public class AddNIntegers extends ConsoleProgram {

/* Specifies the number of values */

private static final int NVALUES = 10;

/* Runs the program */

public void run() {

println("This program adds " + NVALUES + " integers."); int total = 0;

for (int i = 0; i < NVALUES; i++) { int value = readInt(" ? "); total += value;

}

println("The total is " + total + "."); }

}

A common approach to solving this problem is to define a special input value and let the user enter that value to signal the end of the input list. A special value used to terminate a loop is called a sentinel. The choice of an appropriate value to use as a sentinel depends on the nature of the input data. The value chosen as a sentinel should not be a legitimate data value; that is, it should not be a value that the user would ever need to enter as normal data. For example, when adding a list of integers, the value 0 is an appropriate sentinel. There might be some 0s in a column of figures, but the user can always ignore them because they don’t affect the final total. Note that the situation would be different if you were writing a program to average exam scores. Averaging in a 0 score does change the result, and some students have been known to get 0 scores from time to time. In this situation, 0 is a legitimate data value. To allow the user of the program to enter 0 as a score, it is necessary to choose a different sentinel value that does not represent an actual score. On most exams, it is impossible to have a negative score, so it would make sense to choose a value like –1 as the sentinel for that application.

To extend AddNIntegers into a new AddIntegerList program, the only change you need to make is in the loop structure. The for loop, which is most commonly used to execute a set of operations a predetermined number of times, is no longer appropriate. You need a new pattern that reads data until the special input sentinel is found. That pattern is the read-until-sentinel pattern and has the following form:

while (true) {

prompt user and read in a value

if (value == sentinel) break; rest of body

This new pattern for a sentinel-based loop enables you to complete the AddIntegerList program, which is shown in Figure 4-5.

FIGURE 4-5 Program to add a list of integers where the end is marked by a sentinel

/*

* File: AddIntegerList.java * ---

* This program reads integers one per line until the * user enters a special sentinel value to signal the * end of the input. At that point, the program * prints out the sum of the numbers entered so far. */

import acm.program.*;

public class AddIntegerList extends ConsoleProgram {

/* Specifies the value of the sentinel */

private static final int SENTINEL = 0;

/* Runs the program */

public void run() {

println("This program adds a list of integers.");

println("Enter values, one per line, using " + SENTINEL); println("to signal the end of the list.");

int total = 0; while (true) {

int value = readInt(" ? "); if (value == SENTINEL) break; total += value;

}

println("The total is " + total + "."); }

}

Later in this chapter, you will learn the details of the control statements out of which the read-until-sentinel pattern is formed. Even before you understand the details, you will find the pattern very useful. As you learn more about programming, however, you will discover that even expert programmers often use code that they don’t understand in detail. In fact, one of the marks of an expert programmer is being able to use a library or a piece of code without understanding those details. As programs become more complex, the ability to use tools you understand only at the holistic level is an increasingly important skill.

Syntax for the while statement: while (condition) {

statements

} where:

condition is the conditional test used to determine whether the loop should continue for another cycle

statements are the statements to be repeated

Documento similar