CIS 1057. Computer Programming in C

Chapter 3. Top-Down Design with Functions

 

1. Starting from existing information

Most programming processes don't start from a piece of blank paper. Instead, they may start by translating a document into a program, or by modifying an existing program.

Example: FIGURE 3.1 is a half-done program.

 

CASE STUDY: Finding the Area and Circumference of a Circle

A software development process, in terms of the steps defined in Chapter 1.

Problem: Get the radius of a circle, then compute and display the circle's area and circumference.

Analysis: The input is the circle's radius, and the outputs are the circle's area and circumference. The type double should be used for all the values.

The following data are needed:

    Constant: PI is 3.14159
    Input: radius
    Output: area, circum
    Formulas: area = PI * radius * radius; circum = 2 * radius * PI 
Design:
  1. Get the circle's radius.
  2. Compute the area.
  3. Compute the circumference.
  4. Display the area and the circumference.
These steps can be further refined to get a detailed algorithm.

Implementation: FIGURE 3.2 is the first draft got from the above design, then the details are provided in the second draft, FIGURE 3.3, which also includes a testing run result.

 

CASE STUDY: Computing the Weight of a Batch of Flat Washers

This example is similar to the previous one, with the implementation in FIGURE 3.5.

 

2. Library Functions

Code reuse is preferred for the productivity of software development. Furthermore, reused code is more likely to be error-free.

C comes with many predefined functions for mathematical calculations, in a math library. The functions can be used after "#include " is put into the preprocessor directives. For example, the program in FIGURE 3.7 performs three square root computations.

The textbook has a list of C math functions in Table 3.1 (page 121). An on-line list is at here.

C also allows the users to define their own functions.

 

3. Top-down Design

Top-down design means to repeatedly divide a problem into (smaller) sub-problems, until they are directly solvable.

A top-down design process can be represented by a structure chart.

 

CASE STUDY: Drawing Simple Diagrams

Assume we want to write a program to draw some diagrams, such as the following in FIGURE 3.9:

The design and analysis suggest the following structure chart (FIGURE 3.10):

 

4. Functions without Arguments

A function in C carries out a predetermined computation, as specified in a sequence of statements. If no input argument is needed for the computation, the function call looks like "fname()".

A user-defined function must be declared before it can be called (referenced). One way to declare a function is to insert a function prototype before all function definitions. Another way is to define the functions in such an order that every function is defined before it is called.

A function prototype tells the compiler the function name and its input/output data types. For a function without input (or output), the word "void" is used. For example, see FIGURE 3.11.

A function definition specifies not only the information in its prototype, but also a function body, which is a sequence of statements. For example, the function defined in FIGURE 3.12 draws a simple circle.

Each function body can contain variable declarations. Variables defined in this way are "local", in the sense that they can only be used within the function.

A function body can contain function calls, as in FIGURE 3.13. In this way, the program structure becomes hierarchical, as in a structure chart.

FIGURE 3.14 shows a complete program, with function definitions, for the drawing of simple figures. The order of the function definitions does not matter when their prototypes have been declared.

Each function should contain comments explaining what it does.

The compiler processes function calls so that the execution goes to the function when a function call happens, then return at the end of the function. For example, as in FIGURE 3.15:

There are many advantages to use function subprograms. It allows the same code to be reused, simplifies maintenance, and makes the structure of a program more clear.

For example, the function defined in FIGURE 3.16 displays certain user instruction, which can be modified independent of other functions.

 

5. Functions with Arguments

Very often, the calling function and the called function need to pass data between them. In C, each function may take some input arguments, then produce some output arguments. In this way, a function can work on different instances of a problem, by processing different data values according to the same procedure.

Some functions take input arguments, but with a return type void. They do not return anything to the calling function, but may still put output values to the monitor or some files. For example, see FIGURE 3.18.

The arguments defined in the header of a function are called "formal arguments" (or "formal parameter"), as the "rnum" in the previous example. When a function is coded, usually the programmer cannot determine the concrete values of the formal arguments — the function should work as far as the values are in their ranges, respectively.

When a function is called by another function, concrete values are provided by the calling function as "actual arguments", as the "135.68" in the previous example, which are implicitly assigned to the formal arguments, then the statements in the function body will process them. The type of an actual argument should match that of the corresponding formal argument.

If a function has a single return value to the calling function, it is declared at the beginning of the function header, and at the end of the function body, a return statement reports the output value (which can be assigned into a variable in the calling function), and returns the execution control back to the calling function.

For example, see FIGURE 3.21.

FIGURE 3.22 shows the relation between a calling function and a called function:

Again, the returned value must match the declared type.

The comment before a function is usually called "function interface comment", which should specify, beside the usual things, the precondition and postcondition of the function.

If a function has multiple input arguments, they are separated by ",", as in FIGURE 3.23. Between the calling function and the called function, the number, order, and type of arguments must agree with each other.

FIGURE 3.24 shows a complete program, with a main function and another function called by it.

A function can be tested in isolation, with its normal relations with the other parts of the program removed, but be called by a testing program, sometimes called a "driver".

 

6. Common errors

When using library functions, remember to add a "#include" preprocessor directive.

A common error in function call is mismatch of actual and formal arguments, in number, order, or type (remember the acronym "not").

For each argument, the valid value range should also be checked in testing.