Systematic and Structured Programming, Part 2
Step Four - (Nearly) Finishing the Program With Functions
Going through step three took a little longer because you had to analyze what the program needs were, and specify what must happen to resolve those needs. Still, you were writing specifications and locating actions, and other than creating the stub functions, there was no coding, so the process should have been pretty smooth.
In this chapter, you will take the function specifications and locations and turn them into program code. The functions will not be implemented, but your main program will be completed as a result of this step. This, by the way, is exactly what you also did in the Four Step Programming Process. In essence, you will be writing the real program, but in the Six Step Programming Process, you are assuming the functions you have specified but not yet implemented will do what you said they would do.
By putting off the function-related details, you can focus on one problem, which at this point is the main program. Later, you can continue to focus on single problems as you flesh out the individual functions. The best part of this whole system is that you will always have developed instructions for yourself to follow in each succeeding step. This demonstrates the power of abstracting the process.
If you are working through this with the web page, you should copy the code from your QuadProg_StepThree.c to your new QuadProg_StepFour.c file so that you don't overwrite your third step. You will be reminded again to make this change at the end of this web page.
Now, you must work your way through the program from top to bottom again in the iterative refinement process. This time, you will use the functions in your program with the assumption that they will work (when you get them written).
Start here
Initialize the program
// initialize program
// initialize variables
// show title
// function: displayTitle
This is easy. You still won't know what your variables are yet, so you can put off working with them for a little bit. You do know what it takes to print the title, so you can place that here
// initialize program
// initialize variables
// show title
// function: displayTitle
displayTitle();
Now compile to make sure the code is correct
Get the coefficients from the user
// get coefficients from user
// get coefficient A
// function: promptForCoefficient
// get coefficient B
// function: promptForCoefficient
// get coefficient C
// function: promptForCoefficient
While the displayTitle function didn't do any processing you have now come to a place where your own processing functions will be used, but you will go ahead and write your program as if the functions were fully operational
Before you can actually use the promptForCoefficient function in the code, you will need to declare the variables necessary for this operation. The variable declaration process is shown here
// initialize program
// initialize variables
int coefA, coefB, coefC;
Compile after declaring the variables.
Then you simply place the function in the locations where you previously specified they would go, as shown. If you forget what the parameter should be, you can go up to the prototype/specification area and check. That's handy.
// get coefficients from user
// get coefficient A
// function: promptForCoefficient
coefA = promptForCoefficient ( 'A' );
// get coefficient B
// function: promptForCoefficient
coefB = promptForCoefficient ( 'B' );
// get coefficient C
// function: promptForCoefficient
coefC = promptForCoefficient ( 'C' );
After you type each one of these lines, make sure you compile your program.
Process the quadratic roots
// Process quadratic roots
// calculate the discriminant
// function: calcDiscriminant
// calculate the square root of the discriminant
// function: sqrt
// calculate the denominator
// function: calcDenominator
// calculate roots
// calculate root one
// function: calcRoot
// calculate root two
// function: calcRoot
For the calcRoot function, you must again declare the variable needed to accept the discriminant, as shown
// initialize program
// initialize variables
int coefA, coefB, coefC, discriminant;
Compile after adding the discriminant variable.
Now type the code in the main program, as shown here
// calculate the discriminant
// function: calcDiscriminant
discriminant = calcDiscriminant( coefA, coefB, coefC );
Notice that the actual parameters are coefA, coefB, and coefC while the formal parameters are cofA, cofB, and cofC. These are purposely different in this example -- although they don't have to be -- to show that the variable names are unrelated. What matters is that the data will be copied from the actual parameter (e.g., coefA) and passed to the formal parameter (e.g., cofA) where cofA will be used in the function as needed. When the called function has completed its operations, cofA will be out of scope and coefA will be the appropriate variable to be used in the calling function. Make sure you understand this difference
Remember to compile after typing this line.
The next function you have specified is the square root function, but since you are not creating this function, you only need to use it.
First, create the variable needed to acquire the data, as shown, and then compile. Note that this variable is a double value since the sqrt function returns double quantities.
// initialize program
// initialize variables
int coefA, coefB, coefC, discriminant;
double discSquareRoot;
Now use the function in your program, and then compile.
// calculate the discriminant square root
// function: sqrt
discSquareRoot = sqrt( (double)discriminant );
The next function you specified is the calcDenominator function.
As before, start by first declaring any needed variables, and then compiling.
// initialize program
// initialize variables
int coefA, coefB, coefC, discriminant;
int denominator;
double discSquareRoot;
Then you can write the function in the appropriate place in the program.
// calculate the denominator
// function: calcDenominator
denominator = calcDenominator( coefA );
The next function you need is calcRoot.
Create the necessary variables, rootOne and rootTwo.
// initialize program
// initialize variables
int coefA, coefB, coefC, discriminant;
int denominator;
double discSquareRoot, rootOne, rootTwo;
Then write the function in the program. In this case, you are using the same function for two operations, a process called code reusability.
// calculate roots
// calculate root one
// function: calcRoot
rootOne = calcRoot( coefB, denominator, discSquareRoot );
// calculate root two
// function: calcRoot
rootTwo = calcRoot( coefB, denominator, -discSquareRoot );
Note that the positive and negative square roots of the discriminant are sent to the function. The function will do the same thing for both, but you will have accomplished getting the "plus or minus" effect out of the process.
Display the roots
// display roots
// display user input values
// function: displayUserInput
// display root one
// function: displayRoot
// display root two
// function: displayRoot
Displaying the user input values with displayInputValues would look like the following:
// display roots
// display user input
// function: displayInputValues
displayInputValues( coefA, coefB, coefC );
The display user input values part will end the line in preparation for displaying the roots. Finally, the function displayRoot is needed.
Create any variables that are needed. In this case, you will need a variable for the root number, so this is added here
// initialize program
// initialize variables
int coefA, coefB, coefC, discriminant;
int denominator, rootNumber;
double discSquareRoot, rootOne, rootTwo;
Place the displayRoot functions in the main function as shown
// display roots
// display user input
// function: displayInputValues
displayInputValues( coefA, coefB, coefC );
// display root one
// function: displayRoot
rootNumber = 1;
displayRoot( rootNumber, rootOne );
// display root two
// function: displayRoot
rootNumber = 2;
displayRoot( rootNumber, rootTwo );
End the program
// end program
// display program end
// return success to the operating system
return 0;
This is another function that is already written for you, so you only need to place it in the main function, as shown
// end program
// display program end
// function: printString, printEndLine
printString( "Program End" );
printEndline();
// return success to the operating system
return 0;
Quick Review
- Your program was really already written for you since the steps and the functions were all specified. You just followed a simple iterative refinement or cyclic process each time you came to the need for a function
- The more you become comfortable with the Six Step Programming Process and the smaller refinement actions such as this one, the more fun you will have the programming. This is because you will be systematic and organized throughout your development activities
Wrapping Up Step Four
- In step one, you created a program outline. In step two, you made the solution clear by expanding on your step one overview. In step three, you identified the locations where supporting modules (i.e., functions) would be needed, you specified the functions (i.e., you explained what they would look like and what they would do), and you created their prototypes and stubs
- Now in step four, you have written the code necessary for the main function to work. Even though you do not have all the tools for running the program, you had all you needed to create the main operations of the program
- One of the powerful results of this systematic process is that you should rarely, if ever, have to go back and redo anything. At this point, your main function should be fully ready to go to work when it is called upon. You should not have to concern yourself with the operations necessary to solve the larger problem from here forward
- The next step will be to create solutions in pseudocode for the smaller, easier problems that you identified in step three
- Also remember that as long as you compiled after every line or two of code, you are also at this point of completion without any debugging or other extraneous problem-solving to conduct. In other words, you should be ready to move along without being held back by irritating issues that were much easier to resolve during your development process
- In order to conduct this part of the process, you must remember to copy your QuadProg_StepThree.c code to your new QuadProg_StepFour.c file before you make any changes. You want to keep your step three program exactly as it was so that if there are questions in the future about your overall strategy, you can go back and review the code.
This step puts your main function code into play. The program does not run yet, but you can be confident that it will when you have completed the last two steps. Programming is about science, technology, and structure; those folks that try a little of this and a little of that until they succeed (or think they have succeeded) can not make it in this discipline.
To see the step four process in action, watch this video; then develop your step four code with or without the video as needed.