For many new programmers, procedural programming is the natural paradigm. A program can often be
conceived simply as a list of instructions to be executed in order; that is, a procedure to be followed by the
computer. Procedural programming languages are also called imperative languages.
In procedural programming, the code for a specific job is contained in a named procedure. Another name
for a procedure is often subroutine. For instance, one might create a procedure to find the standard deviation of
an array of numbers.
The standard deviation of a measure is defined as the square root of the average squared deviation from the
mean. Here σ is the population standard deviation, and μ is the population mean:
(4.1)
If one is working from a sample and intending to infer the standard deviation of the larger population, the
best estimate will be obtained by dividing the sum of deviations by (n−1) instead of n. Here s is the sample standard
deviation, and is the sample mean:
(4.2)
An equivalent formula often useful for computation is the following:
(4.3)
To write a procedure to perform this calculation, one might write a program to do the following:
Set SUM and SUMSQUARES equal to 0.0
Set n = size of the array of scores
Start with the first score, and continue until all the scores have been processed
Set SUM = SUM + score
Set SUMSQUARES = SUMSQUARES + score2
End of loop
Set MEAN = SUM/n
Return the SquareRoot of (SUMSQUARES − n * MEAN2) / (n − 1)
This is the recipe, the procedure, the pseudocode, for calculating the standard deviation of an array of
numbers. Here is a Java class called Sd that implements such a procedure in a routine called stdDev:
import java.lang.Math;
class Sd {
public static void main( String args[] ){
float[] numbers = { 3, 5, 7, 9 };
System.out.println( "Std. dev. = " + stdDev( numbers) );
}
public static float stdDev( float scores[] ) {
float sum = 0;
float sumSquares = 0;
int n = scores.length;
for( int i = 0; i < n; i++ ) {
sum = sum + scores[i];
sumSquares = sumSquares + scores[i]*scores[i];
}
float mean = sum / n;
float variance = (sumSquares - n*mean*mean) / (n - 1);
return (float)Math.sqrt( variance );
}
}
s x nx n i
i
n
= − −
= Σ
( 2 ) / ( )
1
2 1
s x x n i
i
n
= − −
= Σ
( )2 / ( )
1
1
x
s = − m
= Σ
(x ) / n i
i
n
2
1
Execution starts at main. The main program creates an array of four floating-point numbers, and then it
prints the character string "Std. dev. = ", followed by the number returned from the stdDev routine when
stdDev is passed the array of four numbers. The code in stdDev follows our pseudocode above, using a for
loop to iterate through all the numbers in the array that the main passed to stdDev.
Java was designed to be an object-oriented language, and object orientation provides even more sophisticated
ways to create modules of code than a strictly procedural language like FORTRAN offers. Nevertheless, one
can program procedurally in Java, as we have done above.
Procedural programming captures standard solutions to computational problems in blocks of code that
can be accessed by name, that are reusable by means of a standard set of inputs (arguments—the variables
passed into the routine), and that return a standard set of outputs. Notice, too, that variables have procedure
“scope;” variables that are declared within the procedure, like sum and sumSquares, and are visible only
within the procedure. This helps avoid confusion regarding the variables being used, and thus adds to program
reliability.
Once you have a routine that calculates the standard deviation of an array of numbers, that routine can be
used again and again. Such reuse can be accomplished by including the routine in whatever new program one
writes, or by adding the routine to a library where other programs can access the procedure by name.
This structuring of code is a giant step beyond unstructured programming where the entire program, whatever
it is, consists of a single monolithic block of code. With unstructured code, branching and repetitive use of code
are accomplished using conditional statements and GOTO or JUMP statements. The result can be programs that
are difficult to read, prone to errors, and difficult to debug—“spaghetti code.”
Structured programming divides the programming task into modular procedures. This important advance
in program design greatly improves program readability, reliability, and reusability. The larger task is broken
down into a series of subprocedures. The subprocedures are then defined (written), and the structured programming
task then becomes one of calling the well-tested subprocedures in the appropriate order.
No comments:
Post a Comment