modular programming

43
A.Abhari CPS125 1 Modular Programming Advantages of using functions (to make a modular program) are: •Changing the program into separate pieces •Code reusing •Easier modification and maintenance of the program •More understandable program •Functions can be called from anywhere in the main program with different input data •Functions enable the programmers to generate their own libraries of the functions. How is the information exchanging

Upload: ganya

Post on 06-Jan-2016

54 views

Category:

Documents


2 download

DESCRIPTION

Modular Programming. Advantages of using functions (to make a modular program) are: Changing the program into separate pieces Code reusing Easier modification and maintenance of the program More understandable program - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Modular Programming

A.Abhari CPS125 1

Modular ProgrammingAdvantages of using functions (to make a modular program) are:•Changing the program into separate pieces•Code reusing•Easier modification and maintenance of the program •More understandable program•Functions can be called from anywhere in the main program with different input data •Functions enable the programmers to generate their own libraries of the functions.How is the information exchanging between the main function and function subprograms?

Page 2: Modular Programming

2

Functions with input arguments•The arguments of the functions are used to carry information between the function subprogram and the main function•Input arguments carry information into the function subprogram•Output arguments are the return results of the functions

Examples:

c = factorial(n) / (factorial(r)*factorial(n-r));

print_rboxed(135.68);

actual parameters

Page 3: Modular Programming

3

• Calling print_rboxed(135.68)/* * Displays a real number in a box. */voidprint_rboxed(double rnum){ printf("***********\n"); printf("* *\n"); printf("* %7.2f *\n", rnum); printf("* *\n"); printf("***********\n");}************ ** 135.68 * Formal Parameter* ************

Page 4: Modular Programming

A.Abhari CPS125 4

/* * Computes n! for n greater than or equal to zero */int indicates function result is an integer number factorial(int n){ int i, /* local variables */ product = 1; /* Computes the product n x (n-1) x (n-2) x ... x 2 x 1 */ for (i = n; i > 1; --i) { product *= i; } /* Returns function result */ return (product);}

Page 5: Modular Programming

A.Abhari CPS125 5

Functions with input arguments

• The local and formal parameters of a function cannot be referenced by name in other functions

• Functions can not reference the variables defined in the main by the name

• Functions can use the constant names (#define ..) if they are in the same file. Also functions should have been defined after the constant names definition

Page 6: Modular Programming

A.Abhari CPS125 6

Syntax of function definitionfunction interface commentreturn-type function-name(formal parameter declaration list){

local variable declarationsexecutable statements

}Example:/* Finds the larger of two numbers */double bigger(double n1, double n2){ double larger; if (n1 > n2) larger=n1; else larger=n2; return(larger); }

Page 7: Modular Programming

A.Abhari CPS125 7

•A function can be called with different actual parameters. for example for finding the number of combinations of selecting 2 items from 6 items without regards to order, the main program calls factorial function 3 times as the following: c = factorial(6) / (factorial (2) * factorial(6-2));

• Calling factorial with n=6 in the main program

intfactorial(int n) value of 6 copies into n{ int i, /* local variables */ product = 1; /* Computes the product n x (n-1) x (n-2) x ... x 2 x 1 */ for (i = n; i > 1; --i) { product *= i; } /* Returns function result */ return (product); Returns the result value of 720 }

Page 8: Modular Programming

A.Abhari CPS125 8

Logical FunctionsThe type int result by a function can be interpret as a logical value:

Function That Checks Whether a Value Is Even/* * Indicates whether or not num is even (divisible by 2): * returns 1 if it is, 0 if not */inteven(int num){ int ans; ans = ((num % 2) == 0); return (ans);}

Page 9: Modular Programming

A.Abhari CPS125 9

Function with Multiple Arguments

/* * Multiplies its first argument by the power of 10 specified * by its second argument. */doublescale(double x, int n){ double scale_factor; /* local variable */ scale_factor = pow(10, n); return (x * scale_factor);}• A function can be tested by a program (driver program)

included main function and a call to that function

Page 10: Modular Programming

10

Testing Function scale/* * Tests function scale. */#include <math.h>/* Function prototype */double scale(double x, int n);intmain(void){ double num 1; int num 2; /* Get values for num 1 and num 2 */ printf("Enter a real number> "); scanf("%lf", &num 1); printf("Enter an integer> "); scanf("%d", &num 2); /* Call scale and display result. */ printf("Result of call to function scale is %.3f\n", scale(nu_m 1, num 2)); return (0);}

Page 11: Modular Programming

11

double scale(double x, int n) { double scale_factor; /* local variable - 10 to power n */ scale_factor = pow(10, n); return (x * scale_factor);}---------------- Output:Enter a real number> 2.5Enter an integer> -2Result of call to function scale is 0.025------------------- After calling function scale in the main Function main data area Function scale data area num_1 = 2.5 x=2.5 num_2= -2 n=-2 scale_factor=?

Page 12: Modular Programming

A.Abhari CPS125 12

Argument List Correspondence

• The number of actual arguments in a call to a function must be the same as the number of formal arguments listed in the function definition

• The order of actual argument must be the same as the order of formal arguments

• Each actual argument must be of a data type that can be assigned to the corresponding formal parameter with no unexpected loss of information

Page 13: Modular Programming

A.Abhari CPS125 13

Case Study with Top-Down Design

• Problem: Write a program that finds the smallest divisor of a number or determines that the number is a prime number.

• Analysis

Constant: NMAX 1000

Input: int n

Output: int min_div

Page 14: Modular Programming

A.Abhari CPS125 14

• Design Algorithm:1. Get the number to check whether it is prime 1.1 Get a value for n 1.2 if n < 2

Display an error message else if n <= NMAX

Do Step 2 and 3 else

Display an error message2. Find smallest divisor other than 1, or determine number is

prime3. Display smallest divisor or a message number is prime 3.1 if the smallest divisor is n

Display a message that n is prime else

Display the smallest divisor of n

Page 15: Modular Programming

15

#include <stdio.h>#define NMAX 1000Int main(void){ int n, /* ckeck for prime*/ min_div; /* minimum divisor */ /* Gets a number to test. */ printf("Enter a number that you think is a prime number> "); scanf("%d", &n); /* Checks that the number is in the range 2...NMAX */ if (n < 2) { printf("Error: number too small. The smallest prime is 2.\n"); } else if (n <= NMAX) { /* Finds the smallest divisor (> 1) of n */ min_div = find_div(n); /* Displays the smallest divisor or a message that n is prime. */ if (min_div == n) printf("%d is a prime number.\n", n); else printf("%d is the smallest divisor of %d.\n", min_div, n); } else { printf("Error: largest number accepted is %d.\n", NMAX); } return (0);}

Page 16: Modular Programming

A.Abhari CPS125 16

Step 2 as a sub-problem: Function find_div

• Analysis Input (formal parameter) int n Output (result to return) int divisor Local variable int trial

• Design1. if n is even, set divisor to 2, otherwise, set

divisor to 0 and trial to 32. As long as divisor is 0, keep trying odd integers

(trial). If a divisor is found, store it in divisor. If trial exceeds , store n in divisor.

3. Return divisor

Page 17: Modular Programming

17

#include <math.h> /* Finds the smallest divisor of n between 2 and n (n is greater than 1) */Int find_div(int n){ int trial, /* current candidate for smallest divisor of n */ divisor; /* smallest divisor of n; zero means divisor not yet found */ /* Chooses initialization of divisor and trial depends on n being even or odd. */ if (even(n)) { divisor = 2; } else { divisor = 0; trial = 3; } /* Tests each odd integer as a divisor of n until a divisor is found */while (divisor == 0) { if (trial > sqrt(n)) divisor = n; else if ((n % trial) == 0) divisor = trial; else trial += 2; }return (divisor); /* Returns problem output to calling module. */}

Page 18: Modular Programming

18

Function Output Parameters with Pointers

• So far the return part of a function ,at most could only return one result value.

• By using pointers functions can return multiple result values to the caller

• So far the input argument values could be passed only by the values. It means the value of actual parameters are copied into the value of formal parameters and call to the functions can not change value of arguments.

• By using pointers the address of the arguments can be passed to the functions and the value of these arguments can be changed by the functions. For example the second argument of the scanf or fscanf is passing by address when calling scanf or fscanf

Page 19: Modular Programming

A.Abhari CPS125 19

Pointers

• A pointer is a variable whose value is the address of a memory cell that reserved for another variable

For example: int *nump means nump is a pointer to another variable of type int:

n nump

• Each pointer has two parts: 1- Direct value of a pointer, which is an address of a

memory cell. For example nump is 1024 2- Indirect value of a pointer, which is the value of the

memory cell whose address is the pointer’s direct value. For example *nump is 84

84 1024

Page 20: Modular Programming

20

Meaning of * Symbol“*” can be used for all of these purposes1. Binary operator. For example: 2 * 3 means 2

times 32. For file pointer. For example FILE *inp; means

inp is a pointer to file3. Definition of the pointers. For example: char *singp; means signp is of type “pointer to

char”. Note that signp is address of a memory cell.

4. Unary operator. for example “*nump” gets 84 which is the int value and can be used in the expressions. Also “*singp” is a char value such as ‘a’ or ‘b’

Page 21: Modular Programming

21

Example of a function that uses arguments of the type of pointers

/*Separates a number into three parts: a sign (+, -, or blank), a whole number magnitude, and a fractional part.*/

voidseparate(double num, /* input - value to be split */ char *signp, /* output - sign of num */ int *wholep, /* output - whole number magnitude of num */ double *fracp) /* output - fractional part of num */{ double magnitude; /* local variable - magnitude of num */ /* Determines sign of num */ if (num < 0) *signp = '-'; else if (num == 0) *signp = ' '; else *signp = '+'; /* Finds magnitude of num (its absolute value) and separates it into whole and fractional parts */ magnitude = fabs(num); *wholep = floor(magnitude); *fracp = magnitude - *wholep;}

Page 22: Modular Programming

22

Example of a program that calls a function with multiple output arguments

/* Demonstrates the use of a function with input and output parameters.*/#include <stdio.h>#include <math.h>void separate(double num, char *signp, int *wholep, double *fracp);intmain(void){ prototype of separate double value; /* input - number to analyze */ char sn; /* output - sign of value */ int whl; /* output - whole number magnitude of value */ double fr; /* output - fractional part of value*/ /* Gets data */ printf("Enter a value to analyze> "); scanf("%lf", &value); /* Separates data value into three parts */ separate(value, &sn, &whl, &fr); /* Prints results */ printf("Parts of %.4f\n sign: %c\n", value, sn); printf(" whole number magnitude: %d\n", whl); printf(" fractional part: %.4f\n", fr); return (0);} separate should be defined here….

Enter a value to analyze> 35.817Parts of 35.8170

sign: + whole number magnitude: 35

fractional part: 0.8170

Page 23: Modular Programming

23

Side effect of function call separate(value, &sn, &whl,&fr)

Function main Function separate Data Area Data Area

35.817

?

?

?

sn

whl

fr

value value

35.817

7421

7422

7423

?

sign

wholep

fracp

magnitude

Addressof sn =&sn

Page 24: Modular Programming

A.Abhari CPS125 24

More on Functions• When a pointer is passed to a function it can be used as

“output” or “input/output” parameter.• Scope of the name refers to the region of a program

where the name is visible• For example scope of the formal and local variables, is from their declaration to the closing brace of a

function in which they are declared• The scope of predefine constants is the whole program (they are global)• If the same name is repeated to declare the variables, one

of them may shadow another one. For example in the following example fun-two can be called by one, main and itself but function one can only be called by main and itself not fun-two

Page 25: Modular Programming

A.Abhari CPS125 25

#define MAX 950#define LIMIT 200void one(int anarg, double second); /* prototype 1 */int fun_two(int one, char anarg); /* prototype 2 */intmain(void){ int localvar; both of two functions one and fun_two can be called here . . .} /* end main */voidone(int anarg, double second) /* header 1 */{ int onelocal; /* local 1 */ function fun-two can be called here . . .} /* end one */intfun_two(int one, char anarg) /* header 2 */{ int localvar; /* local 2 */ function one can not be called here . . .} /* end fun_two */

Page 26: Modular Programming

A.Abhari CPS125 26

Using formal parameters as actual parameters

void scan_fraction(int *nump, /* output - numerator */ int *denomp) /* output - denominator */{ char slash; /* local - character between numerator & denominator

*/ int status; /* status code returned by scanf indicating number of valid values obtained */ int error; /* flag indicating whether or not an error has been detected in current input */ char discard; /* unprocessed character from input line */ do { /* No errors detected yet */ error = 0; /* Get a fraction from the user */ status = scanf("%d%c%d", nump, &slash, denomp ); ……………

} while (error);}

Page 27: Modular Programming

A.Abhari CPS125 27

Recursive Functions

• A function that calls itself is said to be recursive• Also if f1 calls f2 and f2 calls f1, f1 is considered

as a recursive function• A recursive algorithm has the following form: if this is a simple case solve it else redefine the problem using recursion• For the simple case of the problem a

straightforward, non-recursive solution is known

Page 28: Modular Programming

A.Abhari CPS125 28

Recursive Functions

• For example to calculate the multiplication of 6 by 3 when only we allowed to use the addition operation:

• The simple case is multiplication of 6 by 1• And the recursive algorithm is:

1. Multiply 6 by 2.

1.1 Multiply 6 by 1 simple case

1.2 Add 6 to the result

2. Add 6 to the result of problem 1

Page 29: Modular Programming

A.Abhari CPS125 29

Recursive Functions/* * Performs integer multiplication using + operator. * Assumes n > 0 */intmultiply(int m, int n){ int ans; if (n == 1) ans = m; /* simple case */ else ans = m + multiply(m, n - 1); /* recursive step */ return (ans);}

Page 30: Modular Programming

A.Abhari CPS125 30

m is 6n is 33 == 1 is falseans is 6 + multiply(6, 2)return ans

m is 6n is 22 == 1 is falseans is 6 + multiply(6, 1)return ans

m is 6n is 11 == 1 is trueans is 6return ans

multiply (6,3)

6

12

18Tracing a recursive function

Each activation frame corresponding to each function call

Page 31: Modular Programming

31

Local Variable and Parameter Stack of

multiply(6,3)?6 3

nm ans

6

6

2

3

?

?

6

6

2

3

?

?

6 1 ?

6

6

2

3

?

?

6 1 6

6

6

2

3

?

?

6

6

2

3

12

?

?6 3

nm ans

186 3

nm ans

1

2

3

5

6

7

84

return from the third call

return from the second call

return from the first call

Page 32: Modular Programming

32

Tracing a Recursive Functionintmultiply(int m, int n){ int ans; printf("Entering multiply with m = %d, n = %d\n", m, n); if (n == 1) ans = m; /* simple case */ else ans = m + multiply(m, n - 1); /* recursive step */ printf("multiply(%d, %d) returning %d\n", m, n, ans); return (ans);}

Entering multiply with m = 8, n = 3Entering multiply with m = 8, n = 2Entering multiply with m = 8, n = 1multiply(8, 1) returning 8multiply(8, 2) returning 16multiply(8, 3) returning 24

printf is usedto make a self-trace recursive function

Page 33: Modular Programming

A.Abhari CPS125 33

Case Study: Bisection Method for Finding Roots

• Problem: Develop a function bisect that approximates a root of a function f on an interval that contains an odd number of roots

• AnalysisInput: double x_l, x_r; /* endpoints of interval */

double epsilon; /* error tolerance */Output: double root; /* approximate root of f */Variable: double x_mid; /*interval midpoint */

Page 34: Modular Programming

A.Abhari CPS125 34

Design: Algorithm

1. if this is a simple case, solve it1.1 simple case 1 if interval shorter than

epsilon, return the midpoint1.2 simple case 2 if function value at midpoint

is zero, return midpointelse redefine the problem using recursion

1.3 bisect interval and execute a recursive call on the half interval that contains the root

1.3.1 if f(x_l)*f(x_mid)<0 1.3.2 Find the root by bisecting[x_l,x_mid] 1.3.3 Find the root by bisecting[x_mid, x_r]

Page 35: Modular Programming

A.Abhari CPS125 35

Implementation:double bisect(double x_l, /* input - endpoints of interval in which */ double x_r, /* to look for a root */ double epsilon) /* input - error tolerance */{ double root, /* approximate root */ x_mid; /* interval midpoint */ /* Compute midpoint of interval */ x_mid = (x_l + x_r) / 2.0; if (x_r - x_l < epsilon) /* simple case 1 */ root = x_mid; else if (f(x_mid) == 0.0) /* simple case 2 */ root = x_mid; else if (f(x_l) * f(x_mid) < 0.0) /* root in [x_l, x_mid] */ root = bisect(x_l, x_mid, epsilon); else /* root in [x_mid, x_r] */ root = bisect(x_mid, x_r, epsilon); return (root);}

Page 36: Modular Programming

A.Abhari CPS125 36

Case Study: Performing Arithmetic Operations on Common Fractions • Problem: Write a program that will allow

you to add, subtract, multiply, and divide common fractions. The program will prompt you for a fraction, an operator, and another fraction and then display the problem and the result. The process will be repeated until you enter an n to answer the question, Continue? (y/n)

Page 37: Modular Programming

A.Abhari CPS125 37

Analysis

Input: int n1, d1; /* numerator, denominator of first fraction */

int n2, d2; /* second fraction */ char op; /* arithmetic operator + - * / */ char again; /* whether to continue */

Output: int n_ans; /* numerator of answer */ int d_ans; /* denominator of answer */

Page 38: Modular Programming

A.Abhari CPS125 38

Design1. Initialize again to y2. As long as user wants to continue3. Get a fraction problem

3.1 Get first fraction3.2 Get operator3.3 Get second fraction

4. Compute the result 4.1 Select a task based on operator 4.2 Put the result fraction in reduced form5. Display problem and result6. Check if user wants to continue

Page 39: Modular Programming

39

Implementation (Step 4 of the Algorithm) /* Gets a fraction problem */ scan_fraction(&n1, &d1); op = get_operator(); scan_fraction(&n2, &d2); /* Computes the result */ switch (op) { case '+': add_fractions(n1, d1, n2, d2, &n_ans, &d_ans); break; case '-': add_fractions(n1, d1, -n2, d2, &n_ans, &d_ans); break; case '*': multiply_fractions(n1, d1, n2, d2, &n_ans, &d_ans); break; case '/': multiply_fractions(n1, d1, d2, n2, &n_ans, &d_ans); } reduce_fraction(&n_ans, &d_ans);

Page 40: Modular Programming

A.Abhari CPS125 40

Testing

• A stub is a skeleton function that consists of a header, trace messages and assigned values to the output parameters.

• Using stubs for incomplete functions enables testing of the flow of control among the other functions before these function are completed.

• The process of testing the flow control between a main and subordinate functions is called top-down testing.

Page 41: Modular Programming

41

Stup for Function multiply_fractions/* ***** STUB ***** * Multiplies fractions represented by pairs of integers. * Product of n1/d1 and n2/d2 is stored in variables pointed * to by n_ansp and d_ansp. Result is not reduced. */voidmultiply_fractions(int n1, int d1, /* input - first fraction */ int n2, int d2, /* input - second fraction */ int *n_ansp, /* output - */ int *d_ansp) /* product of two fractions */{ /* Displays trace message */ printf("\nEntering multiply fractions with\n"); printf("n1 = %d, d1 = %d, n2 = %d, d2 = %d\n", n1, d1, n2, d2); /* Defines output arguments */ *n_ansp = 1; *d_ansp = 1;}

Page 42: Modular Programming

A.Abhari CPS125 42

Testing

• The stub functions can be completed and test individually. A test of an individual function is referred to as unit test.

• When a module is completed and tested, it can be substituted for its stub in the program.

• Bottom-up testing is the process of testing individual functions of a program.

• Testing the entire program after replacing all its stubs with the pre-tested functions is referred to as system integration test.

Page 43: Modular Programming

A.Abhari CPS125 43

Common Programming Errors

• The correspondence between actual parameters and formal parameters (number, type, order)

• Actual output arguments must be of the same pointer types as the corresponding formal parameters.

• Recursive functions should be tested to make sure they terminate properly

• If return is using for the expression containing the call to the recursive function, every path through a non-void function should lead to a return statement.