Introduction To Computing Lec 5
Introduction To Computing Lec 5
Program Modules in C
Functions
Modules in C Programs combine user-defined functions with library functions
C standard library has a wide variety of functions
Function calls
Invoking functions
Provide function name and arguments (data) Function performs operations or manipulations Function returns results
Note
Using the functions in the C Standard Library helps make programs more portable.
Calls function sqrt, which returns the square root of its argument All math functions return data type double
Note:
Include the math header by using the preprocessor directive #include <math.h> when using functions in the math library.
Function
sqrt( x )
Description
square root of x
Example
sqrt( 900.0 ) is 30.0 sqrt( 9.0 ) is 3.0
exp( x )
exponential function ex
log( x )
log( 2.718282 ) is 1.0 log( 7.389056 ) is 2.0 log10( 1.0 ) is 0.0 log10( 10.0 ) is 1.0 log10( 100.0 ) is 2.0
log10( x )
fabs( x )
absolute value of x
ceil( x )
Function
floor( x )
Description
rounds x to the largest integer not greater than x x raised to power y (xy)
Example
floor( 9.2 ) is 9.0 floor( -9.8 ) is -10.0 pow( 2, 7 ) is 128.0 pow( 9, .5 ) is 3.0
pow( x, y )
fmod( x, y )
remainder of x/y as a floatingpoint number trigonometric sine of x (x in radians) trigonometric cosine of x (x in radians) trigonometric tangent of x (x in radians)
sin( x )
cos( x )
tan( x )
Explanation
Contains macros and information for adding diagnostics that aid program debugging. Contains function prototypes for functions that test characters for certain properties, and function prototypes for functions that can be used to convert lowercase letters to uppercase letters and vice versa. Defines macros that are useful for reporting error conditions. Contains the floating-point size limits of the system. Contains the integral size limits of the system. Contains function prototypes and other information that enables a program to be modified for the current locale on which it is running. The notion of locale enables the computer system to handle different conventions for expressing data like dates, times, dollar amounts and large numbers throughout the world.
Explanation
Contains function prototypes for math library functions. Contains function prototypes for functions that allow bypassing of the usual function call and return sequence. Contains function prototypes and macros to handle various conditions that may arise during program execution. Defines macros for dealing with a list of arguments to a function whose number and types are unknown. Contains common definitions of types used by C for performing certain calculations.
Explanation
Contains function prototypes for the standard input/output library functions, and information used by them. Contains function prototypes for conversions of numbers to text and text to numbers, memory allocation, random numbers, and other utility functions. Contains function prototypes for string-processing functions. Contains function prototypes and types for manipulating the time and date.
<string.h> <time.h>
Functions
Functions
Modularize a program All variables defined inside functions are local variables
Known only in function defined
Parameters
Communicate information between functions Local variables
Benefits of functions
Divide and conquer
Manageable program development
Software reusability
Use existing functions as building blocks for new programs Abstraction - hide internal details (library functions)
Function Characteristics
Basically a function has the following characteristics:
1. Named with unique name . 2. Performs a specific task - Task is a discrete job that the program must perform as part of its overall operation, such as sending a line of text to the printer, sorting an array into numerical order, or calculating a cube root, etc. 3. Independent - A function can perform its task without interference from or interfering with other parts of the program. 4. May receive values from the calling program (caller) - Calling program can pass values to function for processing whether directly or indirectly (by reference). 5. May return a value to the calling program the called function may pass something back to the calling program.
Function Mechanism
C program does not execute the statements in a function until the function is called. When it is called, the program can send information to the function in the form of one or more arguments although it is not a mandatory. Argument is a program data needed by the function to perform its task. When the function finished processing, program returns to the same location which called the function.
Parts of a Function
C Function has got two parts:
Function Header Function Definition
C FUNCTIONS
The Function header The first line of every function definition is called function header. It has 3 components, as shown below,
1. Function return type - Specifies the data type that the function should returns to the caller program. Can be any of C data types: char, float, int, long, double, pointers etc. If there is no return value, specify a return type of void. For example,
int float void calculate_yield() // returns an int type mark() // returns a float type calculate_interest() // returns nothing
C FUNCTIONS
1. Function name - Can have any name as long as the rules for C / C++ variable names are followed and must be unique. 2. Parameter list - Many functions use arguments, the value passed to the function when it is called. A function needs to know the data type of each argument. Argument type is provided in the function header by the parameter list. Parameter list acts as a placeholder.
C FUNCTIONS
For each argument that is passed to the function, the parameter list must contain one entry, which specifies the type and the name. For example,
void myfunction(int x, float y, char z) void yourfunction(float myfloat, char mychar) int ourfunction(long size)
The first line specifies a function with three arguments: type int named x, type float named y and type char named z. Some functions take no arguments, so the parameter list should be void or empty such as,
long thefunction(void) void testfunct(void) int zerofunct()
C FUNCTIONS
Parameter is an entry in a function header. It serves as a placeholder for an argument. It is fixed, that is, do not change during execution. The argument is an actual value passed to the function by the caller program. Each time a function is called, it can be passed with different arguments. A function must be passed with the same number and type of arguments each time it is called, but the argument values can be different.
C FUNCTIONS
For the first function call:
Each time a function is called, the different arguments are passed to the functions parameter. z = half_of(y) and z = half_of(x), each send a different argument to half_of() through the k parameter. The first call send x, which is 3.5, then the second call send y, which is 65.11. The value of x and y are passed (copied) into the parameter k of half_of(). Same effect as copying the values from x to k, and then y to k. half_of() then returns this value after dividing it by 2.
C FUNCTIONS
Enclosed in curly braces, immediately follows the function header. Real work in the program is done here. When a function is called execution begins at the start of the function body and terminates (returns to the calling program) when a return statement is encountered or when execution reaches the closing braces (}). Variable declaration can be made within the body of a function. Which are called local variables. The scope, that is the visibility and validity of the variables are local. Local variables are the variables apply only to that particular function, are distinct from other variables of the same name (if any) declared elsewhere in the program outside the function. It is declared, initialized and use like any other variable. Outside of any functions, those variables are called global variables.
C FUNCTIONS
See program next slide
The function parameters are considered to be variable declarations. Function prototype normally placed before main() and your function definition after main() as shown below. For C++, the standard said that we must include the prototype but not for C.
printf(globalVar in (main())= %d\n,globalVar); printf(Before calling function demo(), x = %d and y = %d\n,x,y); demo(); printf(After calling function demo(), x = %d and y = %d\n,x,y); return 0; } void demo(){ int x = 88, y=99; /*local variables*/ printf(globalVar in ( demo()) = %d\n, ++globalVar); printf(Within demo(), x = %d and y = %d \n, x,y); }
#include /* function prototype */ int funct1(int); int main() { /* function call */ int y = funct1(3); }
C FUNCTIONS
But it is OK if we directly declare and define the function before main() as shown below.
#include /* declare and define */ int funct1(int x) { } int main() { /* function call */ int y = funct1(3); }
Three rules govern the use of variables in functions: 1. To use a variable in a function, we must declare it in the function header or the function body. 2. For a function to obtain a value from the calling program (caller), the value must be passed as an argument (the actual value). 3. For a calling program (caller) to obtain a value from function, the value must be explicitly returned from the called function (callee).
C FUNCTIONS
The Function Statements Any statements can be included within a function, however a function may not contain the definition of another function. For examples: if statements, loop, assignments etc are valid statements.
Returning a Value A function may or may not return a value. If function does not return a value, then the function return type is said to be of type void. To return a value from a function, use return keyword, followed by C expression. The value is passed back to the caller. The return value must match the return data type. A function can contain multiple return statements.
C FUNCTIONS
The Function Prototype
Must be included for each function that will be defined, (required by Standards for C++ but optional for C) if not directly defined before main(). In most cases it is recommended to include a function prototype in your C program to avoid ambiguity. Identical to the function header, with semicolon (;) added at the end. Function prototype includes information about the functions return type, name and parameters list and type. The general form of the function prototype is shown below,
function_name(type parameter1, type parameter2,,
C FUNCTIONS
Function prototype provides the C compiler the name and arguments of the functions and must appear before the function is used or defined. It is a model for a function that will appear later, somewhere in the program. From the previous prototype example, 'we' know the function is named cube, it requires a variable of the type long, and it will return a value of type long. Then, the compiler can check every time the source code calls the function, verify that the correct number and type of arguments are being passed to the function and check that the return value is returned correctly. If mismatch occurs, the compiler generates an error message enabling programmers to trap errors. A function prototype need not exactly match the function header. The optional parameter names can be different, as long as they are the same data type, number and in the same order. But, having the name identical for prototype and the function header makes source code easier to understand.
C FUNCTIONS
Normally placed before the start of main() but must be before the function definition. Provides the compiler with the description of a function that will be defined at a later point in the program. Includes a return type which indicates the type of variable that the function will return. And function name, which normally describes what the function does. Also contains the variable types of the arguments that will be passed to the function. Optionally, it can contain the names of the variables that will be returned by the function. A prototype should always end with a semicolon ( ; ).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 1
/* Fig. 5.3: fig05_03.c Creating and using a programmer-defined function */ #include <stdio.h> int square( int y ); /* function prototype */ /* function main begins program execution */ int main( void ) { int x; /* counter */
/* loop 10 times and calculate and output square of x each time */ for ( x = 1; x <= 10; x++ ) { printf( "%d ", square( x ) ); /* function call */ } /* end for */ printf( "\n" );
return 0; /* indicates successful termination */ } /* end main */ /* square function definition returns square of parameter */ int square( int y ) /* y is a copy of argument to function */ { return y * y; /* returns square of y as an int */ } /* end function square */ 4 9 16 25 36 49 64 81 100
Function definition
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
/* Fig. 5.4: fig05_04.c Finding the maximum of three integers */ #include <stdio.h> int maximum( int x, int y, int z ); /* function prototype */ /* function main begins program execution */ int main( void ) { int number1; /* first integer */ int number2; /* second integer */ int number3; /* third integer */ printf( "Enter three integers: " ); scanf( "%d%d%d", &number1, &number2, &number3 ); /* number1, number2 and number3 are arguments to the maximum function call */ printf( "Maximum is: %d\n", maximum( number1, number2, number3 ) ); return 0; /* indicates successful termination */
Function prototype
Function call
23 } /* end main */ 24
33
25 /* Function maximum definition */ 26 /* x, y and z are parameters */ 27 int maximum( int x, int y, int z ) Function 28 { definition 29 int max = x; /* assume x is largest */ 30 31 32 33 34 35 36 37 38 39 if ( y > max ) { /* if y is larger than max, assign y to max */ max = y; } /* end if */ if ( z > max ) { /* if z is larger than max, assign z to max */ max = z; } /* end if */ return max; /* max is largest value */
Call by reference
Passes original argument Changes in function effect original Only used with trusted functions
Pseudorandom
Preset sequence of "random" numbers Same sequence for every function call
Scaling
To get a random number between 1 and n
1 + ( rand() % n ) rand() % n returns a number between 1 + ( rand() % 6) Is a number between 1 and 6
0 and
n - 1
n
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/* Fig. 5.7: fig05_07.c Shifted, scaled integers produced by 1 + rand() % 6 */ #include <stdio.h> #include <stdlib.h> /* function main begins program execution */ int main( void ) { int i; /* counter */ /* loop 20 times */ for ( i = 1; i <= 20; i++ ) { /* pick random number from 1 to 6 and output it */ Generates a random printf( "%10d", 1 + ( rand() % 6 ) );
number between 1
and 6
/* if counter is divisible by 5, begin new line of output */ if ( i % 5 == 0 ) { printf( "\n" ); } /* end if */
39
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
/* Fig. 5.8: fig05_08.c Roll a six-sided die 6000 times */ #include <stdio.h> #include <stdlib.h> /* function main begins program execution */ int main( void ) { int frequency1 = 0; /* rolled 1 counter */ int frequency2 = 0; /* rolled 2 counter */ int frequency3 = 0; /* rolled 3 counter */ int frequency4 = 0; /* rolled 4 counter */ int frequency5 = 0; /* rolled 5 counter */ int frequency6 = 0; /* rolled 6 counter */ int roll; /* roll counter, value 1 to 6000 */ int face; /* represents one roll of the die, value 1 to 6 */ /* loop 6000 times and summarize results */ for ( roll = 1; roll <= 6000; roll++ ) { face = 1 + rand() % 6; /* random number from 1 to 6 */ /* determine face value and increment appropriate counter */ switch ( face ) { case 1: /* rolled 1 */ ++frequency1; break;
40
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
case 2: /* rolled 2 */ ++frequency2; break; case 3: /* rolled 3 */ ++frequency3; break; case 4: /* rolled 4 */ ++frequency4; break; case 5: /* rolled 5 */ ++frequency5; break; case 6: /* rolled 6 */ ++frequency6; break; /* optional */ } /* end switch */ } /* end for */
41
53 54 55 56 57 58 59 60
/* display results in tabular format */ printf( "%s%13s\n", "Face", "Frequency" ); printf( " printf( " printf( printf( printf( printf( " " " " 1%13d\n", frequency1 ); 2%13d\n", frequency2 ); 3%13d\n", 4%13d\n", 5%13d\n", 6%13d\n", frequency3 frequency4 frequency5 frequency6 ); ); ); );
1 /* Fig. 5.9: fig05_09.c 2 Randomizing die-rolling program */ 3 #include <stdlib.h> 4 #include <stdio.h> 5 6 /* function main begins program execution */ 7 int main( void ) 8 { 9 10 11 12 13 14 15 16 17 18 19 int i; /* counter */ unsigned seed; /* number used to seed random number generator */ Seeds the rand
function
printf( "Enter seed: " ); scanf( "%u", &seed ); /* note %u for unsigned */ srand( seed ); /* seed random number generator */ /* loop 10 times */ for ( i = 1; i <= 10; i++ ) {
20 21 22 23 24 25 26 27 28 29
/* pick a random number from 1 to 6 and output it */ printf( "%10d", 1 + ( rand() % 6 ) ); /* if counter is divisible by 5, begin a new line of output */ if ( i % 5 == 0 ) { printf( "\n" ); } /* end if */ } /* end for */
1 6
4 1
6 6
2 4
4 1
6 3
1 6
6 2
Enter seed: 67 6 1
45
1 6
4 1
6 6
2 4
Exercise:
Write down a function which generate the sum of two dies, print the value of each die generated and sum, then return sum.
78 79 /* roll dice, calculate sum and display results */ 80 int rollDice( void ) 81 { 82 int die1; /* first die */ 83 84 85 86 87 88 89 90 91 92 93 int die2; /* second die */ int workSum; /* sum of dice */ die1 = 1 + ( rand() % 6 ); /* pick random die1 value */ die2 = 1 + ( rand() % 6 ); /* pick random die2 value */ workSum = die1 + die2; /* sum die1 and die2 */ /* display results of this roll */ printf( "Player rolled %d + %d = %d\n", die1, die2, workSum ); return workSum; /* return sum of dice */
Storage Classes
Storage class specifiers
Storage duration how long an object exists in memory Scope where object can be referenced in program Linkage specifies the files in which an identifier is known (more in Later on )
Automatic storage
Object created and destroyed within its block auto: default for local variables
auto double x, y;
register: tries to put variable into high-speed registers Can only be used for automatic variables
register int counter = 1;
Note:
Automatic storage is a means of conserving memory, because automatic variables exist only when they are needed. They are created when the function in which they are defined is entered and they are destroyed when the function is exited.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
/* Fig. 5.12: fig05_12.c A scoping example */ #include <stdio.h> void useLocal( void ); /* function prototype */ void useStaticLocal( void ); /* function prototype */ void useGlobal( void ); /* function prototype */ int x = 1; /* global variable */
printf("local x in outer scope of main is %d\n", x ); { /* start new scope */ int x = 7; /* local variable to new scope */
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
printf( "local x in outer scope of main is %d\n", x ); useLocal(); useStaticLocal(); useGlobal(); useLocal(); useStaticLocal(); useGlobal(); /* /* /* /* /* /* useLocal has automatic local x */ useStaticLocal has static local x */ useGlobal uses global x */ useLocal reinitializes automatic local x */ static local x retains its prior value */ global x also retains its value */
printf( "\nlocal x in main is %d\n", x ); return 0; /* indicates successful termination */ } /* end main */ /* useLocal reinitializes local variable x during each call */ void useLocal( void ) { int x = 25; /* initialized each time useLocal is called */
printf( "\nlocal x in useLocal is %d after entering useLocal\n", x ); x++; printf( "local x in useLocal is %d before exiting useLocal\n", x ); } /* end function useLocal */
51
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
/* useStaticLocal initializes static local variable x only the first time the function is called; value of x is saved between calls to this function */ void useStaticLocal( void ) { /* initialized only first time useStaticLocal is called */ static int x = 50; Static variable with block scope printf( "\nlocal static x is %d on entering useStaticLocal\n", x ); x++; printf( "local static x is %d on exiting useStaticLocal\n", x ); } /* end function useStaticLocal */ /* function useGlobal modifies global variable x during each call */ void useGlobal( void ) { printf( "\nglobal x is %d on entering useGlobal\n", x ); x *= 10; Global variable printf( "global x is %d on exiting useGlobal\n", x ); } 52 /* end function useGlobal */
local x in outer scope of main is 5 local x in inner scope of main is 7 local x in outer scope of main is 5 local x in useLocal is 25 after entering useLocal local x in useLocal is 26 before exiting useLocal local static x is 50 on entering useStaticLocal local static x is 51 on exiting useStaticLocal global x is 1 on entering useGlobal global x is 10 on exiting useGlobal local x in useLocal is 25 after entering useLocal local x in useLocal is 26 before exiting useLocal local static x is 51 on entering useStaticLocal local static x is 52 on exiting useStaticLocal global x is 10 on entering useGlobal global x is 100 on exiting useGlobal local x in main is 5
Recursion
Recursive functions
Functions that call themselves Can only solve a base case Divide a problem up into
What it can do What it cannot do
What it cannot do resembles original problem The function launches a new copy of itself (recursion step) to solve what it cannot do
Recursion
Example: factorials
5! = 5 * 4 * 3 * 2 * 1
Notice that
5! = 5 * 4! 4! = 4 * 3! ...
Can compute factorials recursively Solve base case (1! = 0! = 1) then plug in
2! = 2 * 1! = 2 * 1 = 2; 3! = 3 * 2! = 3 * 2 = 6;
1 /* Fig. 5.14: fig05_14.c 2 Recursive factorial function */ 3 #include <stdio.h> 4 5 long factorial( long number ); /* function prototype */ 6 7 /* function main begins program execution */ 8 int main( void ) 9 { 10 int i; /* counter */ 11 12 13 14 15 16 17 /* loop 11 times; during each iteration, calculate factorial( i ) and display result */ for ( i = 0; i <= 10; i++ ) { printf( "%2d! = %ld\n", i, factorial( i ) ); } /* end for */
22 /* recursive definition of function factorial */ 23 long factorial( long number ) 24 { 25 26 27 28 29 30 31 /* base case */ if ( number <= 1 ) { return 1; } /* end if */ else { /* recursive step */ return ( number * factorial( number - 1 ) ); } /* end else */
1 2 3 4 5
/* Fig. 5.15: fig05_15.c Recursive fibonacci function */ #include <stdio.h> long fibonacci( long n ); /* function prototype */
6 7 /* function main begins program execution */ 8 int main( void ) 9 { 10 long result; /* fibonacci value */ 11 12 13 14 15 16 17 18 19 20 21 22 23 24 long number; /* number input by user */ /* obtain integer from user */ printf( "Enter an integer: " ); scanf( "%ld", &number ); /* calculate fibonacci value for number input by user */ result = fibonacci( number ); /* display result */ printf( "Fibonacci( %ld ) = %ld\n", number, result ); return 0; /* indicates successful termination */
25 } /* end main */ 26 60
27 /* Recursive definition of function fibonacci */ 28 long fibonacci( long n ) 29 { 30 31 32 33 34 35 36 37 /* base case */ if ( n == 0 || n == 1 ) { return n; } /* end if */ else { /* recursive step */ return fibonacci( n - 1 ) + fibonacci( n - 2 ); } /* end else */
Array Sum
Array Sum
Termination
Iteration: loop condition fails Recursion: base case recognized