Structured Operations And Statements

Overview

Control structures control the order in which statements will be acted upon by the computer. They can be divided into four basic categories:

  • Sequence structures (op-codes or statements) allow control, in both languages, to flow from one statement to the next in the order in which they were written in the program. That is, flow is sequential. Examples in RPG are the ADD, MOVE, SUB, and EVAL op-codes. An example in Java is the assignment statement. These statements (or op-codes) execute consecutively. They do not cause the flow of control to shift. When control comes to the end of a program, it usually terminates. These concepts are covered in Chapter 3.
  • Decision structures, or conditional statements allow control to flow in a different path, depending on the result of a condition. You can conditionally select alternate paths for your program. Decision control structures include the following:

    • The if conditional statement
    • The SELECT (RPG) or switch (Java) conditional statement
  • Loop structures allow control to flow iteratively for a specified number of times, or until a condition is met. These include the following:

    • The DO (RPG) and for (Java) loop statements
    • The DOW (RPG) and while (Java) loop statements
    • The DOU (RPG) and do-while (Java) loop structures
  • Transfer structures allow control to flow to another part of the program. Transfer control structures include the following:

    • The GOTO (RPG) statement
    • The LEAVE/ITER (RPG) and break/continue (Java) statements
    • The RETURN or return statement
    • The try-catch and throw (Java) statements

Table 4.1 shows structured op-codes that are available in RPG and their equivalent Java statements. Some less-common statements are not shown because they are not available in both languages.

Table 4.1: Structured Statements in RPG versus Java

RPG

Java

Description

IFXX/IF
ENDIF/END

if (expression)
{
// statements;
}

Enables you to execute a code fragment based on a boolean test.

SELECT
  WHENxx/WHEN
  OTHER
ENDSL/END

switch (test)
{
  case value:
  break
  default:
}

Enables you to switch a case (in Java) or select when (in RPG), based ont he value of an expression.

DO
ENDODO/END

for (init; expression;
increment)
{
// statements;
}

Loops a specific number of times based on an initial value, expression, and increment. Loops while the expression is true.

DOWxx/DOW
ENDDO/END

while (expression)
{
// statements;
}

Loops while the expression is true.

DOUxx/DOU
ENDDO/END

do
{
// statements;
}

Loops until the expression is false. The body is executed at least once.

GOTO and TAG

 

Java disallows it. RPG allows it, but our advice is do not use it!

LEAVE

break;

Transfers control out of the loop.

ITER

continue;

Ends the current iteration of the loop.

RETURN

return

Returns to the caller.

SETON LR

System.exit (0)

 

*PSSR, INFSR, and error indicators

try/catch

Catches all program and file exceptions. (See Chapter 10.)

send escape msg

throw statement

Causes an exception to be thrown (See Chapter 10.)



Alternate Paths Decision Strustures

Let's turn our focus to the RPG op-codes and Java statements that can alter the flow of control, such as if and SELECT/switch.

If, then what? Else, of course

The IF and ELSE op-codes in RPG, and the if and else statements in Java, enable you to execute different blocks of code based on a simple test. The if/else statement in Java is nearly identical to the if/else statement in C or C++. RPG IV, on the other hand, has two forms of the IF/ELSE op-codes: a fixed form that was inherited from RPG III, and a free-format factor-two form that enables you to write more expressive expressions. The if/else structures in RPG and Java are written differently, but they are the same in function. Listing 4.1 illustrates the two forms of the RPG IV IF/ELSE operations.

Listing 4.1: RPG IV Fixed-Format IF/ELSE and Free-Format IF/ELSE

D* fields
D age S 3P 0 INZ(10) 
D currday S 1B 0 INZ(MON) 
D price S 3P 2 INZ(0.0) 
D* constants
D MON C CONST(1) 
D TUE C CONST(2) 
D WED C CONST(3) 
D THU C CONST(4) 
D FRI C CONST(5) 
D SAT C CONST(6) 
D SUN C CONST(7)
C* Older fixed-format style of IF
C age IFGT 64
C currday ANDEQ MON 
C MOVE 10.00 price 
C ELSE
C MOVE 20.00 price 
C ENDIF
C price DSPLY
C* Newer free-format style of IF
C IF (age > 64) AND
C (currday = MON) 
C EVAL price = 10.00
C ELSE
C EVAL price = 20.00
C ENDIF
C price DSPLY
C* End the program
C EVAL *INLR = *ON

Listing 4.1 performs the same IF/ELSE test twice, once with the classic fixed-format style, and again with the newer free-format style. We think you will agree the new style is easier to read. The details of the new D-specifications for defining fields and constants are discussed in the next chapter, but they should be easy enough to read. Three fields named age, currday, and price are defined, along with seven constants representing days of the week. It then does logic to set the price based on the customer's age and the current day. The first version of the test uses the older fixed-format IF statement. In this format, the IFxx structure is used, where xx can be EQ, GT, LT, GE, LE, and NE. The disadvantage of using the fixed-format is that there is a need for additional op-codes (ANDXX or ORXX) to build each condition.

The second version illustrates the free-format IF operation. In this format, you first specify the IF op-code and then specify the expression that you want to be evaluated in the free-format factor-two entry. The free-format expression consists of the relational operators =, >, <, >=, <=, and , the logical operators AND and OR, and the unary negation operator NOT. The entire expression and sub-expressions can optionally be parenthesized, to aid in readability and to help the compiler parse the sub-expressions. If necessary, the expression can continue on subsequent C-spec lines.

Both the fixed and free versions test if age is greater than 64 and if currday is MON. If both are true, the code executes the statement after the IF op-code and sets price to 10.00; otherwise, execution flows to the ELSE op-code and we execute the statement after it, which sets price to 20.00 if either sub-condition is false. (Expressions and their rules of construction are covered in Chapter 3.). Note that the fixed-format MOVE is used in the former and the free-format EVAL in the latter, to do the assignment of price. In both forms, the IF must eventually match with an ENDIF. You could have multiple statements after the IF or after the ELSE, versus just the one in the example.

The Java if statement, as you might have guessed, is closer to the free-format version of the RPG IF op-code. Listing 4.2 illustrates the same example written in Java.

Listing 4.2: Java if and else Statements

public class TestIf 
{
 // constants 
 static final int MON = 1; 
 static final int TUE = 2; 
 static final int WED = 3; 
 static final int THU = 4; 
 static final int FRI = 5;
 static final int SAT = 6; 
 static final int SUN = 7;
 public static void main(String args[]) 
 {
 int age = 65; 
 int currDay = MON; 
 double price = 0.0;
 
 if ((age > 64) && (currDay == MON))
 price = 10.00; 
 else 
 price = 20.00;
 
 System.out.println(price);
 }
}//end of class TestIf

Again, the next chapter covers the details of defining variables and constants in Java, but briefly, constants are coded using the modifiers static and final, and must be at the class level, instead of local to methods. The main method (recall this gets control when you run it from the command line) declares the local variables age, currDay, and price, and follows the same logic as RPG. The variables are of type integer (int) and double-precision floating-point (double). We could have used single-precision float (float), but then we'd have to put an f character after the decimal-point literals to get it to compile; all decimal-point literals in Java are considered double-precision, otherwise. (All of these data types and literals, as well as a better option for decimal-point data, are covered in the next chapter.)

The if/else logic of Listing 4.2 really just does the same test as in RPG. Notice a couple of things, though:

  • The entire expression in the if statement must always be surrounded by parentheses
  • The sub-expressions within the expression can optionally have parentheses.
  • Everything is free-format, as far as blanks are concerned.
  • There is nothing like RPG's ENDIF terminator.

Listing 4.2 is fine, as long as you only have a single line of code for the if body and the else body. If another line is added to either body, you must put the whole body inside braces to identify it as a block. With single lines, the braces are optional; with multiple lines they are required. A problem will result if you add a second line but forget to add the braces, as in:

if ((age > 64) && (currDay == MON)) 
 price = 10.00;
 discount = 1.00

This will compile, but you will get an unexpected outcome. The second statement will be executed regardless of the outcome of the if test because it is not part of the if body. To prevent this type of error, always use braces, even for single-statement blocks.

Here is the official Java syntax:

if (expression) 
 single-statement; or block of statements 
else 
 single-statement; or block of statements

The else is optional. Single statements end in semicolon, while blocks start and end with curly braces.

You can see that both languages allow you to specify an arbitrarily complex expression. If the expression evaluates to true, the following block of statements within the structure are executed. If the if expression evaluates to false, then if there is an else statement, the block following it is executed; otherwise, control goes to the subsequent line of code. Java only allows boolean expressions (or boolean variables, as you will discover in Chapter 5) that ultimately evaluate to true or false. If you know C or C++, be aware that Java does not support the idea of allowing numeric expressions and mapping a zero to false and any other number to true. Although Java's syntax is almost identical to C, this is one exception.

An interesting situation arises when you have more than two conditions. Let's take a look at an expanded example. Suppose you would like to have conditions perform one set of instructions if the person is at least 65 years old, a second set if the person is less than 65 but not younger than 12, a third set if the person is less than 12 but not younger than 2, and a default set if the person is 2 or less. That adds up to three different conditions (there could easily be more), plus a default condition that is processed if all three previous conditions are false. Both languages support this kind of testing by allowing you to nest the IF statements. Listing 4.3 illustrates the nesting feature in RPG.

Listing 4.3: Nested IF Statements in RPG

C IF age > 64 
C EVAL price = 10.00 
C ELSE
C IF age > 12 
C EVAL price = 20.00 
C ELSE
C IF age > 2 
C EVAL price = 5.00 
C ELSE
C EVAL price = 0 
C ENDIF 
C ENDIF 
C ENDIF

You add another IF operation after the ELSE operation, with the new condition you want to test. For more complex conditions, additional ELSE and IF structures can be added. The tricky part is ensuring you eventually have one ENDIF for every IF. By the way, in V5R1 of RPG IV, a very nice enhancement you get is the new op-code ELSEIF, which allows for easy nesting and only a single ENDIF:

C IF age > 64 
C EVAL price = 10.00 
C  ELSEIF age > 12 
C EVAL price = 20.00 
C  ELSEIF age > 2 
C EVAL price = 5.00 
C ELSE
C EVAL price = 0 
C ENDIF

Listing 4.4 is this example written in Java. Notice, as is commonly seen in Java, that the else and if statements are lumped together on the same line to aid readability. The rule to always remember, however, is that an else always matches the most previous if. Sound reasonable?

Listing 4.4: Nested if Statements in Java

 if (age > 64) 
 price = 10.00; 
 else if (age > 12) 
 price = 20.00; 
else if (age > 2)
 price = 5.00; 
else 
 price = 0;

You can easily get in trouble by using if statements as the body of the if statement itself, like this:

if (age < 65) 
 if (age > 12) 
 price = 20; 
else 
 price = 10;

It might look as if the else matches the outer if, but it does not. Instead, it matches the inner if. You could fix this by using curly braces, like this:

if (age < 65) 
 { 
 if (age > 12) 
 price = 20;
 }
else 
 price = 10;

Alternatively, you could avoid the situation altogether by writing these if-if statements as single if statements with compound expressions:

if ((age < 65) && (age > 12)) 
 price = 20;
else
 price = 10;

Too many IFs? Time to switch!

If you use the IF op-code or if statement to code too many tests, you can end up with a deeply nested set of if-else-if conditions. This can make the code clumsy to read and hard to maintain. Both Java and RPG provide you with a more elegant way of doing multiple tests. As an alternative to if-else statements, RPG and Java offer the SELECT op-code and the switch statement, respectively. These give the same results as nested if statements, but they have a simplified structure that is more readable and maintainable. Table 4.2 shows an example using switch and SELECT.

Table 4.2: The RPG SELECT versus the Java switch

RPG

Java

SELECT

switch (currDay)

 

{

WHEN   currday = MON

  case MON:

IF     age > 64

    if (age > 64)

EVAL     price = 10.00

    price = 20.00;

ELSE

    else

EVAL     price = 20.00

      price = 10.00;

ENDIF

    break;

WHEN     currday = TUE

  case TUE:

EVAL     price = 20.00

    price = 20.00; break;

WHEN     currday = WED

  case WED:

EVAL     price = 15.00

      price = 15.00;

 

      break;

OTHER

  default:

EVAL     price = 25.00

      price = 25.00;

ENDSL

}

The first important point to note is the improved readability of the SELECT/switch structure compared to the nested if statements. (For brevity, we show the RPG lines starting at the op-code column.) New for SELECT in RPG IV is that the WHEN statements use the free-format factor-two version of the C-spec, allowing you to write free-format expressions just as you do for the new IF statement, in the expanded column range 36 to 80.

You can almost map the structures one-to-one between the languages. The switch statement maps to the SELECT op-code, and the case statement maps to the WHEN op-code. One difference is that Java requires the break to indicate the end of the case statement, while RPG does not need this because the compiler finds the end of the WHEN operation body when it encounters the next WHEN or OTHER operation codes. Otherwise, the default statement in Java maps to the OTHER operation code in RPG, and the final curly brace that ends the switch statement in Java maps to the ENDSL operation code in RPG. Table 4.3 summarizes these mappings.

Table 4.3: Mapping RPG's SELECT to Java's switch

RPG SELECT

Java Switch

SELECT

switch

WHEN or WHENxx

case

OTHER

default

ENDSL

end brace '}'

Although RPG's SELECT op-code and Java's switch statement seem to be very similar, they differ in the expression that is tested. Here are the details of this important distinction:

  • In the Java switch statement, the expression is only specified once, as part of the "switch (expression)" syntax. The result of the expression is then compared to each of the case statement values until a match is found. If found, that case body is executed. If no match is found, the default body is executed, if it exists. Otherwise, the switch statement completes without doing anything. The expression must resolve to a value of type integer. Further, the case statements can only test for equality with the expression value.
  • The RPG SELECT op-code is superior in this regard. The WHEN op-code allows you to specify any valid expression you like, and each WHEN can specify a different one. RPG simply selects the first WHEN that evaluates to true. Further, the expression is open to any data type available.

There is, in fact, an additional important difference. Did you notice that the RPG SELECT statement in the example was more compact than the Java switch statement? This is primarily because of the Java requirement to end each case statement block with a break. (Note that you can code multiple lines of code before the break without having to use braces as you do for other statement types.) RPG, on the other hand, implicitly defines the end of a WHEN op-code when it sees another one, or an OTHER or ENDSL statement.

This use of break makes Java more verbose than RPG. There are more sinister implications than size of code, however. What do you think will happen if you forget to insert the break statement in Java to terminate the case clause? Rather than implicitly ending the block of code at the next case statement, Java will continue to execute all statements until it finally finds a break statement or the end of the switch statement. This can lead to some nasty bugs that are quite time-consuming to track down. Why does it have this behavior (inherited from C, by the way)? It is actually by design. It allows you to group cases together that have common code. For example, suppose you want to execute one block of code for MON, TUE, and WED, and another one for THUR and FRI. Listing 4.5 shows how you would exploit the break-less behavior for this.

Listing 4.5: Using Breakless Behavior in a Java switch Statement

switch (currDay) 
{
 case MON: 
 case TUE: 
 case WED:
 // first block of code 
 price = 20;
 break;
 case THU:
 case FRI:
 // second block of code 
 price = 30;
 break;
 default:
 price = 40;
} // end switch statement

The conditional operator, ?

Chapter 3 introduces the ?: conditional or ternary operator. Under certain circumstances, you can use a shorthand version of the if statement to indicate alternate paths through the code. RPG IV does not support this. The advantages to using this operator are simply reduced typing. However, if you are more comfortable using the if statement, or get paid by the line of code, just use if. The same results will be produced. The following example illustrates an if statement that does a simple test of age < 2. If the test is true, a boolean variable (discussed in Chapter 5) is set to true; otherwise, the variable is set to false:

if (age < 2) 
 freeTicket = true; 
else 
 freeTicket = false; 
// ternary equivalent 
freeTicket = (age < 2) ? true : false;

In some cases, this is a valid alternative to more tedious if statements. (For more details, see Chapter 3.)

Loop structures They get around

The three most common loop structures available in all modern languages, including RPG and Java, are the for loop (DO in RPG), the while loop (DOW in RPG), and the do while loop (DOU in RPG).

Table 4.4 summarizes these different loops. The Java column of Table 4.4 shows the Java constructs for the three types of loops (loop with index, loop while true, loop until false). In all cases, the body is shown inside braces or a block. As with the if statement, however, these braces are optional if the body contains only a single statement.

Table 4.4: RPG IV Loops versus Java Loops

RPG

Java

C     start     DO     limit     index
C*     :
C ENDDO

for (initialization; condition;
   increments)
{
    // body
}

C     DOW expression
C*     :
C ENDDO

while (expression) { // body }

C     DOU expression
C*     :
C ENDDO

do
{
    // body
} while (expression);

The following sections describe all three loops. Notice that the DOW and DOU loops in RPG still have both the fixed-format form that they inherited from RPG III and the free-format factor-two form introduced in RPG IV. Because the free-format form is more structured and easy to code than the fixed-format form, and because we want to encourage you to use the free-format form in your future RPG IV programming, we only use it in the examples that compare RPG loops to Java.

Going for a loop Just do it

The DO loop in RPG and the for loop in Java are used when a known number of iterations are required to execute a block of statements. This kind of loop structure is called a determinant loop. In this kind of loop, there is a starting and ending value, and an index controls the iteration steps for the loop. Here is the syntax in RPG IV:

C* FACTOR 1 OPCODE FACTOR 2 RESULT 
C* ———————— —————— ———————— —————— 
C Start DO End Index 
C**** loop body 
C ENDDO

The starting value is specified in factor one and defaults to one if not specified. Factor two contains the ending or limit value, and also defaults to one if not specified. The result column contains the index field. (If not specified, RPG generates an internal field to contain your index.) To delimit the end of your DO loop block, use the ENDDO operation code after the last op-code in the body of the loop. RPG iterates the loop, executing the statements in the body, until the index field reaches the end value. Thus, if the Start field contains a one, and the End field contains a 10, the loop will iterate 10 times. The default increment value is one if you do not specify it. However, you could use factor two of the ENDDO op-code to give RPG a negative or positive increment, or a step value to add or subtract after each loop iteration. Listing 4.6 shows how to use DO.

Listing 4.6: Using DO to Compute Factorial in an RPG IV Procedure

D total S 10U 0 
 D* Prototype for procedure: Factorial 
 D Factorial PR 10U 0 
 D number 10U 0 VALUE
 C EVAL total = Factorial(4) 
 C total DSPLY 
C EVAL *INLR = *ON
P*—————————————————————————————————————————————————————— 
P* Procedure name: Factorial
P* Purpose: Test DO loop by computing a factorial 
P* Returns: Factorial of given parameter value
P* Parameter: number=>number to compute factorial of 
P*—————————————————————————————————————————————————————— 
P Factorial B 
D Factorial PI 10U 0 
D number 10U 0 VALUE
D* Local fields
D index S 5U 0 
D total S 10U 0 INZ(1)
C* Code to compute factorial 
C 1 DO number index 
C EVAL total = total * index 
C ENDDO
C* Return factorial to the caller 
C RETURN total
P Factorial E

This example has a procedure prototype for a procedure named Factorial, mainline C-specs code to call that procedure and display the results, and finally the Factorial procedure itself. This procedure computes the factorial of a given unsigned integer, and returns the result to the caller. The mainline code is tested by passing in the number four, and you can verify yourself the result is 24 (4*3*2*1). The important part is the DO loop inside the Factorial procedure, which loops from one until the given number, and for each value of the index (from one to four), computes the factorial to be the product of the current index times the factorial of the previous index.

The Java for statement contains all the functionality that RPG provides. Listing 4.7 is the same example as Listing 4.6, but written in Java.

Listing 4.7: Using for to Compute Factorial in a Java Method

public class Factorial 
{ 
 public static void main(String args[]) 
 { 
 System.out.println("Welcome to class Factorial"); 
 int total;
 total = factorial(4); 
 System.out.println(total);
 }
 /** Compute and return factorial of given number */ 
 public static int factorial(int inputValue)
 {
 int total = 1; 
 for (int index=1; index <= inputValue; index++) 
 total = index * total;
 return total;
 } 
} // end of class Factorial

The static factorial method loops from one to the given number, computing the factorial in the same way as RPG. The difference is the syntax of the for statement, which initializes the index value to one, tells Java to loop while index <= inputValue, and increments the index by one on each iteration of the loop (using index++). Since the for loop's body has only one statement, you do not have to code the braces.

The general format of the Java for statement is as follows:

for (expression) 
 single-statement; or block-of-statements

The expression consists of three parts, separated by semicolons:

for (initialization; condition; increment)

These pieces are typically used as follows:

  • Initialization is a specification of the initial value of the index variable. (You can also declare it here.) Multiple variables can be initialized by separating each initialization statement with a comma.
  • Condition is a boolean expression. The loop continues while the expression is not false, which is evaluated at the top of the loop on each iteration. The loop executes zero times if the expression is false on the initial run. Typically, this is a comparison of the index value to a predetermined maximum value, such as the dimension limit on an array.
  • Increment is an assignment or increment statement of your choosing, but typically increments the index value. This part is executed at the end of every iteration. Multiple statements are permitted here, as long as they are comma-separated.

In Java, unlike RPG, all management of the loop indexing is your responsibility. The only thing Java gives you in terms of built-in support in the for loop is the promise to keep looping as long as the boolean conditioning expression is not false. Absolutely everything else is up to you. So, if you want to have an index variable and increment it per loop iteration, it is your job to take care of that.

Let's look at an example of a typical simple for loop in Java that loops through all elements of an array and prints out the contents. In Java, arrays start at index zero, and they support a special built-in variable named length, which represents the number of items in the array:

char myCharArray[] = new char[20]; // declare an array of 20 
characters 
for (int idx = 0; idx < myCharArray.length; idx++)
{
 myCharArray[idx] = ' '; // set idx'th character to blank
}

This first declares an array of 20 characters (arrays are covered in Chapter 6), and then loops through the array, assigning a blank character to each position in it. This example does the following:

  • Declares and initializes the indexing variable: int idx = 0;
  • Keeps looping as long as the indexing variable is less than the size of the array: idx < myCharArray.length;
  • Increments the indexing variable by one after each iteration: idx++

The following example runs backward through the array:

char myCharArray[] = new char[20]; // declare an array of 20 
characters 
for (int idx = myCharArray.length-1; idx >= 0; idx—)
{
 myCharArray[idx] = ' '; // set idx'th character to blank
}

This example initializes the indexing variable to the size of the array minus one (to account for the zero-based indexing in Java arrays), and decrements the variable by one until it hits zero.

Notice how we declare and initialize the idx variable in one shot. This is handy, but because of Java's scoping rules, it does mean that the variable is not accessible outside the scope of the for loop. It is accessible, however, in all three parts of the for expression and in the body of the loop itself.

Another point about the for loop is that, like all Java multi-statement structures, the braces are optional if the block or body has but one statement. For example, you could write this:

for (int idx = 0; idx < salaries.length; idx++)
 System.out.println("Salary is: " + salaries[idx]);

Again, however, we caution you that not using braces risks problems when additional statements are added later. (If you forget the braces, then the first statement remains the only one executed per loop iteration.) For the sake of thoroughness, we do show you examples with and without the braces, however.

As it turns out, all three parts of the for statement are optional in Java. For example, you can legally define a for loop with none of the three parts (although the two delimiting semicolons are still required), as in:

for ( ; ; )
 System.out.println("looping...");

What does this mean? Because Java agrees to loop as long as the condition expression is not false, this loop will simply run forever. Of course, we humbly recommend not writing infinite-loop programs! What is very interesting about the for loop construct, though, is that it is a completely general construct—that is, the initialization part can contain any statement, the conditional part can contain any boolean expression, and the increment part can contain any statement. It is merely convention, although a convention we recommend you follow, that these are used for index initialization, loop termination checking, and index incrementing or decrementing. The initialization part and the incrementing part actually allow multiple statements to be specified. However, they must be separated by commas, not the usual semicolons. This gives tremendous flexibility.

For a first example of this, let's go back to the for loop, which initialized a character array to all blanks. Because the body of the loop is very small, you actually have the option of performing it in the third part of the for expression, as follows:

for (int idx = 0; idx < myCharArray.length; myCharArray[idx]=' ', 
idx++)
{ 
}

Notice that the assignment statement is put together with the idx++ statement, separated by a comma, in the increment part. This is perfectly legal, and you will see it done often. Because all the necessary work is done in the increment part, there is no need for a body, so an empty block is used. You could also use an empty statement—a simple semicolon. In fact, to be really concise, you could also increment the idx variable right in the assignment statement, as follows:

for (int idx = 0; idx < myCharArray.length; myCharArray[idx++]=' ') 
 ;

You often see this kind of compact for statement in Java code. There is a trick to its interpretation. The expression idx++ uses the current value of idx as the index into the array, and then increments it after. (This is discussed in Chapter 3.) Compact for statements are also commonly used to find the first non-blank character in a character array, like this:

char myCharArray[] = {' ', ' ', 'a', 'b', 'c'}; 
int idx; 
for (idx = 0; myCharArray[idx] == ' '; idx++)
 ;
System.out.println("first blank char position = " + idx);

In this example, the index variable idx is declared outside the for loop so it can be accessed later. The for loop then initializes the index to zero, loops as long as the array character indexed by it is blank, and increments the index each time. In this case, the output is 2. Note that myCharArray is declared as an array of characters and initialized to contain the five characters blank, blank, a, b, and c. This implicitly sets its length to five. The number 2 that you get as a result is zero-based; in fact, it is the third position.

Of course, if the input is an array of all blank characters, this example runs into trouble. The terminating condition stays true until the index variable is beyond the limit of the array. This results in a runtime exception, which is not at all unlike an "unmonitored exception" error in RPG:

java.lang.ArrayIndexOutOfBoundsException: 5

To fix this, you need the condition expression to also check for the end of the array:

for (idx = 0; 
 idx < myCharArray.length && myCharArray[idx] == ' '; 
 idx++)
 ;

Now you have a robust and compact example to check for the first non-blank character. Note that each of the three parts of the for statement is on its own line. Because Java is a free-format language, this is perfectly legal, and is often done for readability. Your subsequent code will want to check if idx is greater than the array's length, which will determine if the array was all blanks or not:

if (idx >= myCharArray.length)
 System.out.println("All blank array!"); 
else
 System.out.println("first blank char position = " + idx);

How would you find the last non-blank character, which is another common programming requirement? You'd code it like this:

for (idx = myCharArrar.length-1; 
 idx >= 0 && myCharArray[idx] == ' '; 
 idx—)
 ;

In Java, as you will see in Chapter 6, you can have multi-dimensional arrays. Imagine, then, that you have a two-dimensional array named raster, and that you want to initialize it to one for each position. The for loop can handle this easily. It is an array's best friend! Two-dimensional arrays are declared using two sets of empty brackets and the new operator, which specifies the length for each dimension. Note that arrayVariable.length gives the length of the first dimension, and arrayVariable[x].length gives the length of the xth row. Listing 4.8 provides a fully compilable example.

Listing 4.8: Nested for Loops in Java

public class TestFor 
{
 public static void main(String args[]) 
 { 
 int raster[][] = new int[3][2]; // matrix 3 by 2 
 System.out.println();
 for (int x=0; x < raster.length; x++)
 {
 for (int y=0; y < raster[x].length; y++) 
 {
 raster[x][y] = x + y;
 System.out.println("raster " + x + "," + y + 
 " = " + raster[x][y]); 
 }
 }
 } 
} // end TestFor class

The example in Listing 4.8 results in the following output:

raster 0,0 = 0 
raster 0,1 = 1 
raster 1,0 = 1 
raster 1,1 = 2 
raster 2,0 = 2 
raster 2,1 = 3

This illustrates the ability to nest for loops. That is, the body of one for loop can be yet another for loop. This means the inner loop is executed for its duration multiple times, once per iteration of the outer loop. This example is a little bit longer than necessary. Here is the smallest possible version of this nested for loop for initializing a two-dimensional array (without the println statement):

for (int x=0; x < raster.length; x++) 
 for (int y=0; y < raster[x].length; raster[x][y] = x + y++) 
 ;

A FOR loop in RPG Yes, in RPG

As of V4R4 of RPG IV, you have a free-format alternative to the fixed-format DO loop. There is a new op-code named FOR that makes it very easy to write a loop that increments a given index field from a given start value to a given end value. Listing 4.9 is the Factorial procedure originally from Listing 4.6, with the DO loop replaced by a FOR loop.

Listing 4.9: A Free-Format FOR Loop in RPG

P Factorial B
D Factorial PI 10U 0 
D number 10U 0 VALUE 
D* Local fields 
D index S 5U 0 
D total S 10U 0 INZ(1) 
C* Code to compute factorial
C  FOR index = 1
C  BY 1
C  TO number 
C EVAL total = total * index 
C  ENDFOR
C* Return factorial to the caller 
C RETURN total 
P Factorial E

The FOR op-code uses a free-format version of the C-spec that ranges from column 36 to column 80, as do the other free-format factor-two op-codes: CALLP, DOU, DOW, EVAL, EVALR, IF, RETURN, and WHEN. Not only does this give you more room for writing free-format expressions, it also allows you to easily continue that expression in the same column range of subsequent continued C-spec lines.

Here is the official syntax for the RPG IV FOR loop op-code:

OPCODE EXTENDED-FACTOR 2 
—————— ———————————————-——————————————— 
FOR index-name < = starting-value >
 < BY increment-value > 
 < TO | DOWNTO limit-value > 

ENDFOR | END

The entries inside angle brackets are optional. The index field must be declared before the loop, on a D-spec, and must be numeric with zero decimal positions. The starting, increment, and limit values can be a numeric literal or a numeric expression, including a built-in function call or a procedure call. The increment value is always positive. To decrement, specify DOWNTO instead of TO, which causes the increment-value to be subtracted from the index field. Note that all three parts of the FOR op-code can be placed on one line or multiple lines. RPG exits the body of the loop when the index field's value reaches the limit value. Unlike Java, the index field is automatically incremented or decremented by the runtime.

Like the DO loop, to exit the loop prematurely, you have to either set the index field value to be the limit value, or use the LEAVE op-code. Unlike Java, there is no way to test an arbitrary expression to determine when to exit. However, this is okay because typically you'll use the DOW or DOU op-codes for loops that need to do this.

We think you have to agree this FOR loop is easy to code and easy to read, and it certainly is a closer match to Java than the older fixed-format DO loop. See the RPG IV reference manual for more examples of the FOR loop. (Here's another way to find more information: in the CODE/400 editor, position the cursor on the FOR op-code and press F1.)

Looping for a while

Now that you have mastered the for loop, you will find the while loop in Java and DOW loop in RPG IV to be a breeze. It is a subset of the for loop's functionality and brings nothing new to the table—except ease of use. The while statement is simpler than the for statement because the while loop only takes an expression for evaluation and does not have as many parameters. Its use is for those cases where the termination of the loop is not predetermined and you simply want to loop while a given condition is true. You will decide in the body of the code when to set that condition to false. (If this procedure is not performed correctly, you will have an infinite loop.) This is called an indeterminant loop because you can't predict when it will end. It is especially useful when reading or asking for input, since the end will be determined by the end of file marker or by a user-initiated action, for example.

The while loop for both Java and RPG executes zero or more times. This point becomes important in contrast to the next section, describing the do until loop, which executes one or more times.

In the free-format DOW operation code in RPG, you specify an expression in the free-format factor two to be evaluated each time the loop iterates. If the expression evaluates to true, the next iteration is executed. However, if the condition or the expression specified in factor two is false, the loop is terminated and control is transferred to the operation after the ENDDO op-code. Here is the syntax:

C* FACTOR 1 OPCODE EXTENDED-FACTOR 2 
C* ———————— —————— ————————————————
C DOW Expression
C**** loop body
C  ENDDO

To show this op-code in use, imagine your child asks you for a loan, and you want to give them a printout of the payment schedule. Because you are a softee for your kids, you don't charge them any interest. (We know—you have no "interest" in such a loan, but it is the "principal" that is important here!) Listing 4.10 shows an RPG IV procedure to calculate and print out the amount paid and amount owing after each payment. The procedure takes as input the total amount of the loan and the amount to pay each payment and returns the total number of payments.

Listing 4.10: A DOW Loop in an RPG Loan-Payment Procedure

P CalcPayments B
D CalcPayments PI 5U 0 
D* Parameters
D loan 5P 0 VALUE 
D payment 5P 0 VALUE 
D* Local fields
D payments S 5U 0 INZ(0) 
D remaining S 5P 0 INZ(0) 
D paid S 5P 0 INZ(0) 
D output S 32A
C* Calculate and display payments 
C EVAL remaining = loan 
C DOW remaining > 0 
C IF ((paid + payment) > loan) 
C EVAL payment = loan - paid 
C ENDIF 
C EVAL paid = paid + payment 
C EVAL remaining = loan - paid 
C EVAL payments = payments + 1 
C EVAL output = %CHAR(paid) + ', ' + 
C %CHAR(remaining) 
C output DSPLY
C ENDDO 
C RETURN payments 
P CalcPayments E

This loops while there is a remainder left to pay. Each iteration of the DOW loop first checks if the new payment will reduce the debt to or below zero. If so, it changes this month's payment to just what's left. The remaining logic evaluates the total paid so far by adding to it this month's payment, and evaluates the new amount remaining by deducting this month's payment. It also bumps up the total payments counter, and finally prints the amount paid and amount remaining. We don't show the prototype of this procedure for simplicity, but here is the mainline code to call it:

C EVAL payments = CalcPayments(335:100) 
C payments DSPLY 
C EVAL payments = CalcPayments(200:100) 
C payments DSPLY

The output of this is as you would expect:

100, 235 
200, 135 
300, 35 
335, 0
4 
100, 100 
200, 0
2

The equivalent in Java is the while statement, which has the following syntax:

while (expression) 
{
 // statement(s)
}

Like the if and for statements, the braces around the body are required if the body is more than one statement, and optional otherwise. The expression is any boolean expression evaluating to true or false. The loop iterates as long as the expression is true. Listing 4.11 is the same code as Listing 4.10, but in OO style it is a class that uses instance variables, versus passing parameters.

Listing 4.11: A while Loop in a Java Loan-Payment Class

public class Loan 
{ 
 private int loan; // amount of loan 
 private int payment; // amount per payment
 public Loan(int loan, int payment) // constructor 
 {
 this.loan = loan;
 this.payment = payment; 
 }
 public int calcPayments() 
 {
 int payments = 0; 
 int remaining = loan; 
 int paid = 0;
 
 while (remaining > 0) 
 {
 if ((paid + payment) > loan) 
 payment = loan - paid; 
 paid += payment; 
 remaining = loan - paid; 
 ++payments;
 System.out.println(paid + ", " + remaining);
 }
 return payments; 
 }
 
 public static void main(String args[]) 
 {
 Loan loanTest1 = new Loan(335,100); 
 int payments = loanTest1.calcPayments(); 
 System.out.println("============"); 
 System.out.println("payments: " + payments); 
 System.out.println(); 
 Loan loanTest2 = new Loan(200,100); 
 payments = loanTest2.calcPayments(); 
 System.out.println("============"); 
 System.out.println("payments: " + payments); 
 } // end main
} // end of class Loan

The output of this is exactly the same as the output of the RPG version. (Note that the contracted += operator from the previous chapter is used to add payment to paid.)

In Java, the expression is very often a variable of type boolean (described in Chapter 5), which itself evaluates to true or false. This makes it a perfect match for the condition expression. The variable is usually declared and initialized to true first, then set to false inside the loop when some ending condition is met, such as reading the end of the file:

boolean notDone = true;
while (notDone) 
{
 // read input 
 if (input.eof()) // end of file for input? 
 notDone = false;
}

In fact, you will usually see the boolean variable initialized to false and its negation checked in the condition expression, which accomplishes the same thing:

boolean done = false; 
while (!done)
{
 // read input 
 if (input.eof()) // end of file for input? 
 done = true;
}

The while loop is actually equivalent to the for loop; each can be completely mapped to the other. All you do is move the initialization part of the for loop outside, preserve the condition expression, and move the incrementing part to the bottom of the while loop body. Here is a typical for loop:

for (int x = 0; x < myArray.length; x++) 
 myArray[x] = 1;

Here is the exact equivalent, but as a while loop:

int x = 0; 
while (x < myArray.length) 
 myArray[x++] = 1;

So, when do you use the for loop and when do you use the while loop? It is your decision, really, because they are functionally equivalent. In general, though, the for loop is used when you can predict the number of iterations of the loop, and while is used when you cannot.

Looping until done

The last loop structure covered here is the do until loop. This is the DOU op-code in RPG, and the do while statement in Java. Here is RPG's DOU syntax:

C* FACTOR 1 OPCODE EXTENDED-FACTOR 2 
C* ———————— —————— ————————————————
C DOU Expression
C**** loop body
C  ENDDO

Except for its name, the DOU op-code is exactly the same as DOW. In the DOU operation, just like DOW, you specify an expression in the free-form factor two. If DOW and DOU are so similar, why have two of them? The DOU operation expression is evaluated after the body of the structure has been executed, in contrast to before for DOW.

Here is Java's equivalent, the do while statement (note the ending semicolon):

do 
{
 // statement(s) 
} while (expression);

As with RPG's DOW versus DOU, Java's do while statement is functionally identical to the while statement. The difference is that the condition expression is not evaluated until the end of the loop, which guarantees at least one iteration of the loop. Our experience is that programmers tend to use one or the other of these exclusively. That underlines their equivalent functionality.

Consider the job of reading input from a file. (Hey, you've done that, right?) You have to read until the end of the file. Which loop structure is best? It's up to you. Both have pros and cons. If you use while, you must do the initial read outside the loop to initialize the end-of-file flag. Then, you must do the subsequent reads inside the loop, as follows:

boolean eof; // a variable that will be true or false 
eof = myFile.getRecord(); // get the first record from the file 
while (!eof)
{
 // ... process record 
 eof = myFile.getRecord();
}

The disadvantage here is clear. You have to duplicate the read statement. That can create bugs later on if that statement is changed in one place but not the other. Alternatively, you could code this using do while (or DOU in RPG), and avoid the redundancy, as follows:

boolean eof; // a variable that will be true or false 
do
{
 eof = myFile.getRecord();
 if (!eof)
 { 
 // ... process record
 }
} while (!eof);

The disadvantage of this approach is that the if statement adds complexity to ensure that the last read does not result in the end of the file. Again, the choice is completely a personal decision. (Our preference is while versus do while, but what do we know!)



Transfer Structures

Let's now turn our attention to those statements that directly alter flow of control by explicitly transferring control to another statement.

If you continue, I will need a break

You have seen the looping constructs in RPG and Java, and how their termination is determined by a conditional expression at the top or bottom of the loop. The language runtime evaluates the expression at each iteration of the loop, and continues iterating as long as the expression does not evaluate to false.

Controlling when the loop ends is usually a simple matter of setting the appropriate variables to force the expression evaluation to false. This is the preferred and structured approach. However, for reasons of completeness, both languages offer alternative shortcuts to this. They take the form of the LEAVE op-code in RPG and the break statement in Java. Both of these, when used in the body of a switch, while, do, or for structure, force the immediate end of the loop. Control is then passed by default to the statement after the loop structure. The Java break statement also allows an optional tag parameter to force the exit of a loop labeled with that tag. This is for nested loops.

In addition, both languages offer a shortcut to force iteration of the loop from within the body, thus skipping all subsequent code in the body. This is done using the ITER op-code in RPG and the continue statement in Java. The continue statement, like the break statement, allows an optional tag value to explicitly identify the outer loop to be iterated. The continue statement is valid inside while, do, and for structures in Java. Both break and continue apply to the innermost loop structure by default. That is, they exit or iterate the innermost loop. In a nested loop, to exit or iterate a more outer loop, you use the optional tag value to skip to a labeled outer loop.

We caution you that both of these constructs for forcing termination and iteration offer nothing new in function over a little bit of proper if-else coding, and can be avoided. They make for some nasty maintenance problems, and are really nothing but special-case goto statements. Some people avoid them altogether. Other people insist that they can offer a more readable and elegant-looking solution than the nasty use of conditioning. Our preference is to not use them by default. In our years of experience with C and C++ programming, where they also exist, we have found them to be very rarely worth using. But then again, they make up another tool to put in your programming toolbox, so Listing 4.12 shows an RPG IV example using ITER and LEAVE.

Listing 4.12: RPG's ITER and LEAVE Op-codes in the FindLastChar Procedure

 *890123456789012345678901234567890123456789012345678901234567890 
D* Local fields
D pos S 5U 0
D* Prototype for procedure: FindLastChar 
D FindLastChar PR 5U 0 
D inString 32767A VARYING CONST
C* Mainline code
C EVAL pos = FindLastChar(' a test ') 
C pos DSPLY 
C EVAL pos = FindLastChar(' ') 
C pos DSPLY
C* End the program 
C EVAL *INLR = *ON
P*————————————————————————————— 
P* Procedure name: FindLastChar 
P* Purpose: Find position of last non-blank character 
P*—————————————————————————————
P FindLastChar B
D FindLastChar PI 5U 0 
D inString 32767A VARYING CONST 
D* Local fields
D index S 5U 0 
D lastNonBlank S 5U 0 INZ(0) 
C* Code
C FOR index = %LEN(inString) 
C BY 1 DOWNTO 1 
C IF %SUBST(inString:index:1) = ' ' 
C  ITER
C ELSE 
C EVAL lastNonBlank = index
C  LEAVE
C ENDIF
C ENDFOR 
C RETURN lastNonBlank
P FindLastChar E

In this example, a procedure named FindLastChar takes any character field or literal as input, and returns to the caller the position of the last non-blank character, or zero if the input is all blanks. To find the last non-blank character, it uses the new FOR op-code to loop from the ending position of the string down to one. Inside the loop, it tests if the character at the current index position is blank or not, using the %SUBST (substring) built-in function. If it is, it uses ITER to keep looping. Otherwise, it has found what it wants, and so it records the index position in lastNonBlank and leaves the loop. Finally, it returns lastNonBlank to the caller. The mainline code tests the procedure by calling it with two literals, and displays the returned value. What you get when you run this is 7 and 0.

By the way, Listing 4.12 shows how to write procedures in RPG that will accept character fields of any length: by declaring the length as the maximum character field length (32767) and by coding the keywords VARYING and CONST on the parameter D-specs for both the prototype and actual interface.

Listing 4.13 is the same example written in Java, using its continue and break statements. Notice that to get the lengths of strings in Java, we use the Java-supplied method length, and to extract a character at a given zero-based position, we use charAt. Since zero is a valid character position in Java (the first), we have to return -1 for the special case of all-blank input. (Strings are covered in detail in Chapter 7.) The input lines are continue, which iterates the current for loop, and break, which exits the loop.

Listing 4.13: Java's break and continue Statements

public class TestBreak 
{ 
 public static void main(String args[]) 
 {
 int pos;
 pos = findLastChar(" a test "); 
 System.out.println(pos);
 pos = findLastChar(" "); 
 System.out.println(pos);
 }
 
 /** Find last non-blank character position in a string */ 
 public static int findLastChar(String inString)
 {
 int lastNonBlank = -1; 
 for (int index = inString.length()-1; 
 index >= 0; index—)
 {
 if (inString.charAt(index) == ' ') 
 continue;
 else 
 { 
 lastNonBlank = index; 
 break;
 }
 }
 return lastNonBlank;
 }
}

The break and continue statements also allow an optional label to identify the loop to exit or iterate, as shown in Listing 4.14.

Listing 4.14: Labeled continue Statements in Java

outer: for (int classes = 0; 
 classes < marksByClass.length; classes++) 
{
 for (int marks = 0; 
 marks < marksByClass[0].length; marks++) 
 {
 if (marksByClass[classes][marks] == -1) 
 continue outer; 
 else if (marksByClass[classes][marks] == -2) 
 continue;
 totalPerClass[classes] += marksByClass[classes][marks]; 
 countPerClass[classes] += 1;
 } // end inner for loop
} // end outer for loop

This example is a snippet from the full sample in TestLabeledLoop.java on the CD-ROM included with this book. It computes the average marks for all classes, given a two-dimensional array of marks per student per class. If an array entry contains –1, it marks the end of the array for that class, and if it contains –2, it marks a student who has quit the class. Hence, while processing this two-dimensional array, we need to iterate the labeled outermost loop if we see –2, and iterate the innermost non-labeled loop if we see –1. This is done using continue with a tag (outer) that is used to label the outermost for loop. Note that loops are labeled the same as statements are labeled in CL programs. However, only loops can be labeled in Java, and only for the purpose of identifying them on continue or break.

This is typically used to force your way out of deeply nested loops, and is in contrast to the procedure of setting a variable and checking that variable in the remainder of the code in all structures.

Go to where?

The GOTO op-code or statement is an example of a transfer structure that does not follow structured programming design, and its use has fallen out of favor. In fact, Java designers decided to not even include it in the language, although the word is reserved. It is interesting that they took such a strong stand on GOTO while still advocating the use of break and continue, which are quite similar.

RPG IV, however, still has a GOTO op-code for historical reasons, and its syntax remains the same:

C 99 GOTO EXIT 
C EXIT TAG 
C EVAL *INLR = *ON

In this example, if indicator 99 is on, you want control to transfer to the EXIT statement, which is identified as a target by the TAG op-code. Notice that the IF operation is a cleaner and more structured replacement for the GOTO and TAG op-codes.

Return to caller

In RPG IV, the RETURN operation code does more than its predecessor in RPG III. The RETURN op-code is used to return a value to the caller from a procedure. Listing 4.15 shows an RPG procedure named Max that returns the larger of two integers, and its prototype. It also shows some mainline code to test it.

Listing 4.15: The RPG Max Procedure Showing the RETURN Statement

D* Global fields
D result S 5I 0 
D* Prototype for procedure: Max 
D Max PR 5I 0 
D value1 5I 0 VALUE 
D value2 5I 0 VALUE
* Code to call max
C EVAL result = Max(100 : 200) 
C result DSPLY 
C EVAL result = Max(200 : 100) 
C result DSPLY 
C EVAL *INLR = *ON
P*———————————————————————
P* Procedure name: Max
P* Purpose: Return maximum of two integers 
P*———————————————————————
P Max B
D Max PI  5I 0 
D value1 5I 0 VALUE 
D value2 5I 0 VALUE
C* Determine and return the maximum value 
C IF value1 > value2
C  RETURN value1 
C ELSE
C  RETURN value2 
C ENDIF
P Max E

The output of running this is 200, twice. The RETURN op-code in RPG uses the free- format factor-two version of the C-spec, and you can code any literal, field, or expression in factor two. The type of that literal, field, or expression must match the declared return type of the procedure, however, which is the length, type, and decimal positions specified on the PI (Procedure Interface) and PR (Procedure Prototype) D-specs for the procedure. If these values are blank, then the procedure does not return anything, and a RETURN statement with nothing in factor two is optional.

Listing 4.16 shows the same method, max, coded in Java and called from the main method with the same inputs.

Listing 4.16: The Java max Method Showing the return Statement

public class TestReturn 
{
 public static void main(String args[]) 
 {
 int result;
 result = max(100, 200); 
 System.out.println(result); 
 result = max(200, 100); 
 System.out.println(result); 
 }
 public static int max(int value1, int value2) 
 {
 return value1 > value2 ? value1 : value2;
 }
}

This is a very compact version of max, using the conditional operator to decide which of the two parameters to return. It tests if value1 > value2, and if true, returns value1; otherwise, it returns value2. This highlights the fact that the value returned on Java's return statement can also be a literal, a variable, or indeed an expression. The type of literal, variable, or expression must match the return type declared on the signature line, which in this case is int. If void is coded there, you can optionally code a return statement with no value.

Like RPG, there can be more than one return statement in a method. However, in general, you should strive as much as possible to only have a single return statement except for very simple procedures or methods, such the RPG Max procedure. This is because you will often need to do some coding or cleanup before returning, and if you have multiple return statements, you have to duplicate that code, which leads to maintenance problems. More theoretically, the more exit points in a procedure or method, the less structured and predicable it is considered to be.

With the above discussion in mind, and the fact that procedures are so much better than subroutines, we point out that RPG has added a new op-code in V4R4: LEAVESR. This allows you to exit a subroutine prematurely at any point in it. This was added to the language simply because it was so heavily requested by programmers, but we still caution you to use it sparingly, and indeed to consider using procedures instead of subroutines.

Notice that, in the case of RPG, the RETURN operation behaves just like its counterpart Java statement only if it is used in a subprocedure. If, however, the RETURN op-code is used in the mainline code, its behavior is different than Java's. The following occurs if RETURN is used in the mainline C-specs in RPG IV:

  • The program ends abnormally if a halt indicator is on.
  • If the halt indicator is not on, the Last Record indicator (LR) is checked.
  • If LR is on, normal termination occurs.
  • Finally, if none of the above indicators is on, the return goes back to the calling routine, and all data are preserved for the next time the program is called (for better performance).

      Note 

    This description is not a change from RPG III. Programmers used the RETURN operation code in the mainline to avoid total shutdown of the program and, thereby, increased their performance by avoiding the startup performance penalty.

In Java, you can specify a return statement in your main method as well, which signifies the end of the program. It does not have the same implications, however. The program ends whether a return statement was entered in the main, or whether the end of code was reached in main. You will see in the discussion of threads in Chapter 11, however, that there is a better way to exit your programs than to use return. We recommend using System.exit(0);. This, much like setting on the LR indicator in RPG, causes total and complete termination of the program.



Summary

This chapter introduced you to the control flow statements in Java and compared them with RPG's. It covered the following points:

  • RPG and Java have the most common structured statements available in most modern programming languages, including the following:

    • if and else structures
    • The SELECT and switch op-code and statement, respectively
    • Loops (including DO/for, DOW/while, and DOU/do-while)
    • LEAVE/break and ITER/continue
    • A return statement for returning from RPG procedures or Java methods
  • Use an if statement if only a few expressions are to be tested. For deeply nested if-else conditions, consider using the switch statement in Java or the SELECT op-code in RPG IV.
  • RPG's WHEN op-code is more powerful than Java's switch statement, since it allows you to specify any kind of expression with any data type. In Java's switch statement, the expression can only be one of the primitive data types byte, char, short, or int.
  • Use the DO/for loop when you have a predictable number of iterations you want the loop to go through.
  • Use the DOW/while loop when you want to iterate zero or more times through the loop.
  • Use the DOU/do-while loop when you want the body of the loop to execute at least once.
  • Use break and continue sparingly in Java, for forcing exit or iteration of a loop.
  • The GOTO op-code is available in RPG, but not in Java.
  • Java supports other transfer statements, including try/catch and throw, for dealing with exceptions. These are discussed in Chapter 10, which covers exceptions.




Java for RPG Programmers
Java for RPG Programmers, 2nd Edition
ISBN: 193118206X
EAN: 2147483647
Year: 2002
Pages: 191

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net