![]() |
![]() | |||||
|
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]()
|
Flow Control & Subprograms
Flow Control: Branching & LoopingAn important part of all programming languages is the ability to modify the normal top-to-bottom order of statement execution. In Java, this is accomplished with decision structures (e.g., branching or conditional statements) and loop structures.Branches enable you to selectively execute one part of a program instead of another. Loops, on the other hand, provide a means to repeat certain parts of a program. Together, branches and loops provide you with a powerful means to control the logic and execution of your code. The Guarded if StatementThe syntax for the if-else statement follows:if (Condition) Statement;A compound statement is a sequence of individual Java statements surrounded by curly brackets (i.e., { and }), with the result that the statements appear to an outer block as a single statement. The general form of a Java compound statement is shown below:
{
Statement1;
Statement2;
.
.
.
StatementN;
}
The following example illustrates the use of a compound
statement with the "guarded" form of the if statement:
if (performCalc)
{
x += y * 5;
y -= 10;
z = (x - 3) / y;
}
The if-else StatementThe if-else statement is the most commonly used branching structure in Java programming. It is used to select one of two possible outcomes based upon a conditional expression. The syntax for the if-else statement is shown below:if (Condition) Statement1; else Statement2;If the boolean Condition evaluates to true, Statement1 is executed. Similarly, if the Condition evaluates to false, Statement2 is executed. The following example shows one possible use of the if-else statement:
if (Count <= 25)
System.out.println("Recommended = " + Count+16);
else
System.out.println("Recommended = " + Count);
The syntax illustrated below uses compound statements to allow for multiple statements
to be executed as part of either the true or false branch of the
if-else statement.
if (Condition)
{
Statement1t;
Statement2t;
.
.
.
StatementNt;
}
else
{
Statement1f;
Statement2f;
.
.
.
StatementKf;
}
The if-else if StatementIf you need more than two conditional outcomes, you can string together a series of if-else statements to get the desired effect. The following example shows multiple if-else statements which are used to switch between multiple outcomes:if (x == 0) y = 5; else if (x == 2) y = 25; else if ((x >= 3) && (x <= 10)) y = 125; else if (x == 11) y = -1;In this example, three different comparisons are made, each with its own statement executed on a true conditional result. Notice, however, that subsequent if-else statements could also be viewed as being nested within the previous statement. The example below uses a different indentation technique to emphasize the "nested" view:
if (x == 0)
y = 5;
else
if (x == 2)
y = 25;
else
if ((x >= 3) && (x <= 10))
y = 125;
else
if (x == 11)
y = -1;
However you look at it, this arrangement of the if-else if statement
ensures that (at most) one statement is executed.
Switch StatementThe switch statement is similar in purpose to the if-else statement. However, the switch statement is specifically designed to conditionally switch among multiple outcomes. The syntax for the switch statement is shown below:
switch (Expression)
{
case Constant1:
StatementList1
case Constant2:
StatementList2
.
.
.
default:
DefaultStatementList
}
The switch statement evaluates and compares Expression to all
the case constants and branches the program's execution to the matching
case statement list. If no case constants match Expression,
the program branches to the DefaultStatementList (if one has been supplied,
the DefaultStatementList is optional). A statement list is simply a series,
or list, of Java statements. Unlike the if-else branch, which directs program flow to a
simple or compound statement, the switch statement directs the flow to a
list of statements.
When the program execution moves into a case statement list, it continues from there in a sequential manner. This means that you will need to resort to the break statement to exit the switch structure (just as in C). The Java break statement is described below. Looping or IterationFor repeated execution of program statements (iteration), loops are used. If you are familiar with other programming languages you have probably used for-loops, while-loops, and until-loops. Java supports five types of iteration statements:
for-loopsThe for loop provides a means to repeat a section of code a designated number of times. The for loop is structured so that a section of code is repeated until some limit has been reached. The syntax for the for loop follows:for (InitExp; LoopCondition; StepExp) Statement;The for loop repeats the Statement lines the number of times that is determined by the InitExp, the LoopCondition, and the StepExp. The InitExp is used to initialize a loop control variable. The LoopCondition compares the loop control variable to some limit value. Finally, the StepExp specifies how the loop control variable should be modified before the next iteration of the loop. The following example shows how a for loop can be used to print the numbers from 1 to 20: for (int i = 1; i < 21; i++) System.out.println(i);First, i is declared as an integer. The fact that i is declared within the body of the for loop might look strange to you at this point. However, is completely legal in Java. The variable i is initialized to 1 in the InitExp part of the for loop. Next, the conditional expression i < 11 is evaluated to see whether the loop should continue. At this point, i is still equal to 1, so LoopCondition evaluates to true and the Statement is executed (the value of i is printed to standard output). Next, i is incremented in the StepExpression part of the for loop, and the process repeats with the evaluation of LoopCondition once again. This continues until LoopCondition evaluates to false, which is when x equals 11 (ten iterations later). The following code segment is another example of a for loop:
for (int number=0; number<1000; number++)
{
if (number % 12 == 0)
System.out.println("#: " + number);
}
This for loop displays every number from 0 to 999 that is evenly
divisible by 12. Every for loop has a variable that is used
to determine when the loop should begin and end. This variable
often is called the counter. The counter in the preceding
loop is named number.
Fahrenheit to Celsius program
// Print a Fahrenheit to Celsius table
class FahrToCelsius
{
public static void main (String args[])
{
int fahr, celsius;
int lower, upper, step;
lower = 0;
upper = 300;
step = 20;
for (fahr=lower; fahr <= upper;
fahr = fahr + step)
{
celsius = 5 * (fahr-32) / 9;
System.out.println(fahr+" "+celsius);
} // end for loop
} // end main
} // end class
while-loopsLike the for loop, the while loop has a loop condition that controls the execution of the loop statement. Unlike the for loop, however, the while loop has no initialization or step expressions. The syntax for the while statement follows:while (LoopCondition) StatementIf the boolean LoopCondition evaluates to true, the Statement is executed and the process starts over. It is important to understand that the while loop has no step expression as the for loop does. This means that the LoopCondition must somehow be affected by code in the Statement or the loop will infinitely repeat, which is a bad thing. This is bad because an infinite loop causes a program to never exit, which hogs processor time and can ultimately hang the system. Another important thing to notice about the while loop is that its LoopCondition occurs before the body of the loop Statement. This means that if the LoopCondition initially evaluates to false, the Statement is never executed. Although this may seem trivial, it is in fact the only thing that differentiates the while loop from the do-while loop. The FahrToCelsius.java program shown below illustrates a Fahrenheit to Celsius conversion program.
class FahrToCelsius
{
public static void main (String args[])
{
double fahr, celsius;
double lower, upper, step;
lower = 0.0;
upper = 300.0;
step = 20.0;
fahr = lower;
while (fahr <= upper)
{
celsius = 5.0 * (fahr-32.0) / 9.0;
System.out.print(fahr);
System.out.print(" ");
System.out.println(celsius);
fahr = fahr + step;
} // end while loop
} // end main
} // end FahrToCelsius
do-while LoopsThe do-while loop is very similar to the while loop, as illustrated by the following syntax:do Statement while (LoopCondition);The major difference between the do-while loop and the while loop is that, in a do-while loop, the LoopCondition is evaluated after the Statement is executed. This difference is important because there may be times when you want the Statement code to be executed at least once, regardless of the LoopCondition. The Statement is executed initially, and from then on it is executed as long as the LoopCondition evaluates to true. As with the while loop, you must be careful with the do-while loop to avoid creating an infinite loop. An infinite loop occurs when the LoopCondition remains true indefinitely. The following example shows a very obvious infinite do-while loop:
do
System.out.println("I'm stuck!");
while (true);
Because the LoopCondition is always true, the message I'm Stuck!
is printed forever, or at least until you press Ctrl+C and break
out of the program. If this approach does not work, try disconnecting your
telnet session. When you end a telnet session, all programs that you started
will be stopped by the operating system.
do
{
i+=1;
System.out.println(i);
}
while (i<5);
break and continue StatementsYou have already seen how the break statement works with the switch branch. The break statement is also useful when dealing with loops. You can use the break statement to jump out of a loop and effectively bypass the loop condition. The example below shows how the break statement can help you out of an apparent infinite loop.The BreakLoop.java program (class) is shown below.
class BreakLoop
{
public static void main (String args[])
{
int i = 0;
do
{
System.out.println("I'm stuck!");
i++;
if (i > 100)
break;
}
while (true);
}
}
In BreakLoop.java, a seemingly infinite do-while loop is created by setting
the loop condition to true. However, the break statement is used to exit
the loop when i is incremented past 100.
Another useful statement that works similarly to the break statement is the continue statement. Unlike break, the continue statement is useful only when working with loops; it has no real application to the switch statement. The continue statement works like the break statement in that it jumps out of the current iteration of a loop. The difference with continue is that program execution is restored to the test condition of the loop. Remember that break jumps completely out of a loop. Use break when you want to jump out and terminate a loop; use continue when you want to jump immediately to the next iteration of the loop. The following example shows the difference between the break and continue statements:
int i = 0;
while (i++ < 100)
{
System.out.println("Looping with i.");
break;
System.out.println("Please don't print me!");
}
int j = 0;
while (j++ < 100)
{
System.out.println("Looping with j!");
continue;
System.out.println("Please don't print me!");
}
In this example, the first loop breaks out because of the break
statement after printing the looping message once. Note that the
second message is never printed because the break statement
occurs before we get to it. Contrast this with the second loop,
which prints the looping message 100 times. The reason for this
is that the continue statement allows the loop to continue its
iterations. In this case, the continue statement serves only to
skip over the second message, which still is not printed.
ArraysArrays in Java, as in other languages, are a way to store collections of like data as a single unit. Arrays also allow you to manipulate the data as a single entity, and access each variable (called an array element or component) within the array individually by means of an index (also called a subscript). Conceptually, an array has some number of slots, each of which holds an individual data item. You can add and delete items to those slots as needed. Unlike in other languages, arrays in Java are actual objects that can be passed around and treated just like other objects. In some ways, arrays are to data structures what loops are to control structures. This means that the time taken and complexity of writing programs that use many variables of the same type is reduced.
One-dimensional arraysArrays can contain any type of data value (primitive types or objects), but you cannot store different data types in a single array. You can have an array of integers or an array of strings or even an array of arrays, but you cannot have an array that contains, for example, both strings and integers.To create an array in Java, you simply follow these three steps:
Array DeclarationThe first step in creating an array is creating a variable that will hold the array, just as you would any other variable. Array variables indicate the type of object the array will hold (just as they do for any variable) and the name of the array, followed by empty brackets ([]). The following examples illustrate some typical array variable declarations:int k[]; float ytd[]; String names[]; String words[]; Point hits[]; int temp[];An alternate method of defining an array variable is to put the brackets after the type instead of after the variable. The two approaches are equivalent, but this latter form is considered by some to be more readable. So, for example, the declarations shown above could be written as follows: int[] k; float[] ytd; String[] names; String[] words; Point[] hits; int[] temp;Use the style you feel is most natural, and be consistent. Creating Array ObjectsThe second step is to create an array object and assign it to the variable you previously declared. There are two ways to accomplish this:
String[] names = new String[10];This statement creates a new array of Strings with 10 elements. When you create a new array object using the new operator, you must indicate how many elements the array will hold. The example above does not put actual String objects in the array slots ... you will need to do that later. Array objects can contain primitive types such as integers or booleans, just as they can contain objects. The examples below illustrate this variety: int[] k = new int[3]; float[] ytd = new float[7]; String[] names = new String[50]; int[] temp = new int[99];The numbers in the brackets above specify the dimension of the array; i.e., how many slots it has which can hold data values. With the dimensions above k can hold three ints, ytd can hold seven floats and names can hold fifty Strings. Therefore this step is sometimes called dimensioning the array. More commonly this is called allocating the array since this step actually directs the compiler to set aside the memory in RAM that the array requires. When you create an array object using the new operator, all of its elements are automatically initialized (0 for numeric arrays, false for boolean, '\0' for character arrays, and null for objects). You can then assign actual values or objects to the elements in that array. You can also create an array and initialize its contents at the same time. Instead of using new to create the new array object, enclose the elements of the array inside curley brackets, separated by commas, as illustrated in the example below:
String[] children = { "kim", "cindy", "tina",
"tony", "kelly", "martin", "dan" };
Each of the elements inside the brackets must be of the same type and must be the same
type as the variable that holds that array (the Java compiler will generate an error message if
they are not). An array the size of the number of elements you have included will
automatically be created for you. The example above creates an array of String
objects named children that contains seven elements.
Once you have an array with initial values, you can test and change the values in each slot of that array. To get at a value stored within an array, use the array subscript expression ([]): myArray[subscript];The myArray part of this expression is a variable holding an array object, although it can also be an expression that results in an array. The subscript part of the expression, inside the brackets, specifies the number of the slot within the array to access. Array subscripts start with 0, as they do in C and C++. So, an array with 10 elements has 10 array slots accessed using subscript 0 to 9. Note that all array subscripts are checked when your Java program is run to make sure that they are inside the boundaries of the array (greater than or equal to 0 but less than the array's length). Unlike in C, it is impossible in Java to access or assign a value to an array slot outside the boundaries of the array (thereby avoiding a lot of the common problems and bugs that result from overrunning the bounds of an array in C-like languages). Note the following two statements, for example: String[] arr = new String[10]; arr[10] = "eggplant";A program with that last statement in it produces an error at that line when you try to run it. (Actually, to be more technically correct, it throws an exception. The array stored in arr has only 10 slots numbered from 0, the element at subscript 10 doesn't exist. If the array subscript is calculated at runtime (for example, as part of a loop) and ends up outside the boundaries of the array, the Java interpreter also produces an error. How can you keep from accidentally overrunning the end of an array in your own programs? You can test for the length of the array in your programs using the length instance variable-it's available for all array objects, regardless of type: int len = arr.length // returns 10However, just to reiterate: The length of the array is 10, but its subscript can only go up to 9. Arrays in Java start numbering from 0. Whenever you work with arrays, keep this in mind and subtract 1 from the length of the array to get its largest element. To assign an element value to a particular array slot, merely put an assignment statement after the array access expression: myarray[1] = 15; sentence[0] = "The"; sentence[10] = sentence[0];An important thing to note is that an array of objects in Java is an array of references to those objects (similar in some ways to an array of pointers in C or C++). When you assign a value to a slot in an array, you're creating a reference to that object, just as you do for a plain variable. When you move values around inside arrays (as in that last line), you just reassign the reference; you don't copy the value from one slot to another. Arrays of primitive types such as ints or floats do copy the values from one slot to another. Two dimensional arrays are declared, allocated and initialized much like one dimensional arrays. However we have to specify two dimensions rather than one, and we typically use two nested for loops to fill the array. The array example below is to be filled with the sum of its row and column indices. Here is some code that would create and fill an array:
class FillArray
{
public static void main (String args[])
{
int[][] M;
M = new int[4][5];
for (int row=0; row < 4; row++)
{
for (int col=0; col < 5; col++)
{
M[row][col] = row+col;
}
}
}
}
Java ObjectsIf you plan to do any realistic programming using Java, you will need to spend some time reviewing the Java Platform 1.1 API Specification. This specification lists all of the Java packages, their objects and methods. All of the programs included in this overview of the Java language can be better understood if you read about the packages, objects and methods that they use by consulting the API descriptions found at the link above.The two sections which follow both rely on an understanding of the java.lang package and the java.lang.math class. SubprogramsIt is often the case that when writing programs, you would like to invoke another program from within the first and send it input and get output from it. How might this be done in Java? A simple example that runs the UNIX program "ls" to retrieve a listing of files in the current directory looks like this:
import java.io.*;
public class test1
{
public static void main(String args[])
{
try
{
Process cp = Runtime.getRuntime().exec("ls");
DataInputStream d =
new DataInputStream(cp.getInputStream());
String line = null;
while ((line = d.readLine()) != null)
System.out.println(line);
}
catch (Throwable e)
{
}
}
}
The call to exec() starts the process running, and returns a java.lang.Process object.
Then we query the java.lang.Process object to get a buffered input stream that is
connected to the output of the child process. We then can simply iterate
over this stream, reading lines in turn, that are the output of ls. In a
similar way, it is possible to send input to the child process or capture
its error output.
The java.lang.Process class has several additional methods available for controlling processes: waitFor() wait for the child process to complete exitValue() return the exit value for the process destroy() kill the processThere is also a variant of exec() that supports passing of environment variables to the child process. FunctionsJava has no user-defined functions. Being a purer object-oriented language than C++, Java forces programmers to bundle all routines into class methods. There is no limitation imposed by forcing programmers to use methods instead of functions. As a matter of fact, implementing routines as methods encourages programmers to organize code better. Keep in mind that, strictly speaking, there is nothing wrong with the procedural approach of using functions, it just doesn't mix well with the object-oriented paradigm that defines the core of Java. However, the Java approach does tend to promote code reuse, which is a distinct advantage over the procedural approach.The Java Math class, however, contains many invaluable mathematical functions along with a few useful constants. Each of these is accessible as a method. The Math class is not intended to be instantiated; it is basically just a holding class for mathematical functions (methods). Additionally, the Math class is declared as final so you cannot derive from it. The most useful methods implemented by the Math class include the following:
The trigonometric methods sin, cos, tan, asin, acos, and atan perform the standard trigonometric functions on double values. All the angles used in the trigonometric functions are specified in radians. Following is an example of calculating the sine of an angle: double dSine = Math.sin(Math.PI / 2);Notice in the example that the PI constant member of the Math class was used in the call to the sin method. Youll learn about the PI constant member variable of Math at the end of this section. The exp method returns the exponential number E raised to the power of the double parameter a. Similarly, the log method returns the natural logarithm (base E) of the number passed in the parameter a. The sqrt method returns the square root of the parameter number a. The pow method returns the result of raising a number to a power. pow returns a raised to the power of b. Following are some examples of using these math methods: double d1 = 12.3; double d2 = Math.exp(d1); double d3 = Math.log(d1); double d4 = Math.sqrt(d1); double d5 = Math.pow(d1, 3.0);The ceil and floor methods return the ceiling and floor for the passed parameter a. The ceiling is the smallest whole number greater than or equal to a, where the floor is the largest whole number less than or equal to a. The round methods round float and double numbers to the nearest integer value, which is returned as type int or long. Both round methods work by adding 0.5 to the number and then returning the largest integer that is less than or equal to the number. The rint method returns an integral value, similar to round, that remains a type double. Following are some examples of using these methods: double d1 = 37.125; double d2 = Math.ceil(d1); double d3 = Math.floor(d1); int i = Math.round((float)d1); long l = Math.round(d1); double d4 = Math.rint(d1);Notice in the first example of using round that the double value d1 must be explicitly cast to a float. This is necessary because this version of round takes a float and returns an int. The atan2 method converts rectangular coordinates to polar coordinates. The double parameters a and b represent the rectangular x and y coordinates to be converted to polar coordinates, which are returned as a double value. The random method generates a pseudo-random number between 0.0 and 1.0. random is useful for generating random floating point numbers. To generate random numbers of different types, you should use the Random class, which is located in the utilities package, java.util. The utilities package, including the Random class, is covered in the next chapter. The abs methods return the absolute value of numbers of varying types. There are versions of abs for working with the following types: int, long, float, and double. Following is an example of using the abs method to find the absolute value of an integer number: int i = -5, j; j = Math.abs(i);The min and max methods return the minimum and maximum numbers given a pair of numbers to compare. Like the abs methods, the min and max methods come in different versions for handling the types int, long, float, and double. Following is an example of using the min and max methods: double d1 = 14.2, d2 = 18.5; double d3 = Math.min(d1, d2); double d4 = Math.max(d1, 11.2);Beyond the rich set of methods provided by the Math class, there are also a couple of important constant member variables: E and PI. The E member represents the exponential number (2.7182...) used in exponential calculations, where PI represents the value of Pi (3.1415...).
| |||||
| |
| Added to the Web: October 31, 1999. Last updated: November 3, 1999. Web page design by Dan Solarek. |
![]() http://cset.sp.utoledo.edu/cset4250/ |