1 / 72

Introduction to Functions for Program Design

Learn how to define and use functions in your programs, including dividing programs into smaller functions and using pre-existing functions from libraries.

mdanley
Download Presentation

Introduction to Functions for Program Design

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Functions

  2. Objectives You will be able to • Write a function definition. • Write a program that makes use of functions. • Design a small program by dividing it into multiple functions. • Make use of pre-existing functions in libraries.

  3. Functions • A function is a named block of code that can be executed by putting its name into a statement. • A very simple example: void say_hello() { printf ("Hello, world\n"); } int main () { say_hello(); return 0; } Function Name Function Definition Function Header Function Body Function “Call” Whenever the function name is reached in the stream of execution, the function body is executed.

  4. Functions • Our primary tool for coping with complexity. • Divide a big program into smaller pieces • Each piece performs a well defined action • Pieces can be further divided as needed • Final result is nothing but small, understandable pieces. • “Program Design”

  5. Functions • Some things to notice. void say_hello() { printf ("Hello, world\n"); } No semicolon at end of function header. No semicolon at end of function definition. The function body is delimited by curly brackets. For readability, align the curly brackets with the function header and indent the code within the function body by 3 spaces (The usual rules for alignment of curly brackets.)

  6. Functions This is NOT textual substitution like #define The compiler produces executable code from the function definition. The compiler generates code for the function call that transfers control to the function body. The function body includes executable code to return control back to the next statement after the function call.

  7. A Note about Examples • Examples used in this lecture will all be very simple. • Show the mechanisms • Avoid obscuring the concepts with details • In order to be useful, functions in real life are more complex. • But not a lot more complex. • Typically should fit on one page.

  8. Function Parameters • A function definition can include one or more variables, called parameters, to be supplied by the call. double average (double n1, double n2 ) { return (n1 + n2) / 2.0; } • The function call must provide values for function’s parameters. • A value passed to the function by the call is referred to as an argument. • Each argument becomes the initial value of a parameter when the function is called. • Inside the function body, parameters act like normal variables. Parameters

  9. Function Arguments void print_int (int x) { printf ("The integer is %d\n", x); } int main () { ... print_int (33); } Function Definition Parameter x = 33; /* Effect of call */ Function Call Argument

  10. Returned Value • A function can perform a computation and return the result. • The result is the “value” of the function name. • Can be used in assignment statement. • Can be used in an expression.

  11. Returning a Result This says that the function returns a value of type int. int square (int x) { return x*x; } int main () { int num; int num_squared; printf ("Enter number to be squared: "); scanf ("%d", & num); num_squared = square(num); printf ("The square of %d is %d\n", num, num_squared); return 0; } Function Definition The value of x*x becomes the value of square(num) The value of num becomes the value of x for the function num_squared is set to the value returned by function

  12. Returning a Result

  13. Using Returned Values in an Expression int main () { int a = 0; int b = 0; int c_squared = 0; printf ("Enter a: "); scanf ("%d", &a); printf ("Enter b: "); scanf ("%d", &b); c_squared = square(a) + square(b); return 0; } A function call can be used in any expressionjust like a variable.

  14. Returning a Result • If a function is declared with a type other than void, it must return a value of that type. return x*x; • If a function is declared as void, it must not return a result. • Can return using the statement: return; • Can simply run to completion.

  15. Function Prototypes • A function definition begins with a function header int average (int a, int b) Function name Parameters and their types. Type of returned value The compiler needs this information in order to compile the function call. This information is referred to as the function prototype a.k.a. function signature

  16. Function Prototypes • If the function definition appears in the source file before the function call, the compiler automatically knows the function prototype. • Otherwise, we have to provide it in the form of a function declaration somewhere prior to the function call. int average (int a, int b); A function declaration must be followed by a semicolon. In the function definition, this information is NOT followed by a semicolon. (It is followed by the function body.)

  17. Function Prototypes Programming Style Issue: • Function declarations, if needed, should appear near the beginning of the source file, following any #define lines.

  18. Function Declaration Example #include <stdio.h> int square (int x); int main () { int value = 0; int value_squared = 0; printf ("Enter value to be squared: "); scanf ("%d", &value); value_squared = square(value); printf ("The square of %d is %d\n", value, value_squared); return 0; } int square (int x) { return x*x; } Function declaration Function call Function definition

  19. Function Prototypes • If we tell the compiler the function prototype in a function declaration prior to any calls, the function definition can appear anywhere. • Even in a different file that is compiled separately. End of Section

  20. Libraries • Functions can be collected and compiled separately to form a library. • Standard Libraries • Defined by the C Language standards • Included with every C compiler • Example: The Standard IO Library • Details in Chapter 23. • Local Libraries • Locally written functions intended for reuse • Proprietary Libraries • Software products

  21. Standard Libraries • The standard libraries are essentially like extensions to the C language. • Standard I/O Library • printf(), getchar(), scanf(), others • Chapter 22 • The C Mathematics Library • sin(), cos(), exp(), log() • Complete list starting on page 593

  22. Libraries • Functions in libraries are compiled separately. • Separately compiled object code is added to the executable file by the linker. • Function prototypes for the library functions are collected in a header file for the library. • Added to user’s source file with #include.

  23. Example Function prototypes for all functions in the Standard I/O Library are inserted here by the preprocessor. #include <stdio.h> int square (int x); int main () { int value = 0; int value_squared = 0; printf ("Enter value to be squared: "); ... } The compiler knows the function prototype for printf() because or the #include. The call to function printf() causes the linker to add the precompiled code for function printf() to the executable file.

  24. Example: hypotenuse.c • A program to compute the length of the hypotenuse of a right triangle, given the lengths of the other two sides, a and b. • a and b must be in the range 0 < x < 1000000 • Will use a function to get user inputs for the two sides. • Verify that input is valid. • Ask user to provide a different value if not.

  25. Example: hypotenuse.c /* Compute length of hypotenuse of a right triangle */ #include <stdio.h> #include <math.h> /* Get user input for length of a side. */ double get_length() { double length = 0; while (1) { scanf ("%lg", &length); if ((length > 0) && (length <= 1000000)) { return length; } printf ("Value must be greater than 0 “); printf (“and no more than 1000000\n"); printf ("Please enter a valid value\n"); } } A local variable.

  26. Example: hypotenuse.c Local variables of function main() int main () { double a = 0; double b = 0; double c = 0; /* Hypotenuse */ printf ("This program computes the length of the hypotenuse\n"); printf ("of a right triangle, given the lengths of the other\n"); printf ("two sides, a and b\n"); printf ("a and b must be between zero and 1000000\n"); printf ("Enter a: "); a = get_length(); printf ("Enter b: "); b = get_length(); printf (“Sides are %10.4f and %10.4f\n", a, b); c = sqrt(a*a + b*b); printf ("Length of hypotenuse is %10.4f\n", c); return 0; } Get value of “a” from user. Get value of “b” from user. Function in the math library

  27. Example: hypotenuse.c • When we compile, we have to tell gcc to link with the math library. • Otherwise we get an “Undefined reference” error:

  28. Example: hypotenuse.c To tell the linker to link with the math library, include –lm in the command.

  29. Recursion Section 9.6

  30. Objectives You will be able to • write functions that call themselves in order to solve problems by dividing them into smaller but similar subproblems.

  31. Recursive Function A function that calls itself • Why? • Many algorithms can be expressed more clearly and concisely in recursive form. • "Divide and Conquer" • Solve a smaller problem. • Use result to solve original problem.

  32. The Run-Time Stack • Hidden data structure in every C program. • Maintained automatically. • Not directly accessible to the program. • Each call to a function allocates some space on the run-time stack. • Called a stack frame • Function’s parameters are allocated here. • Function’s local variables are allocated here, • Except variables declared as static. • Return address is stored here.

  33. The Run-Time Stack • Each successive function call allocates a new stack frame. • Caller’s local variables are still on the stack in a lower stack frame. • Not visible to the newly called function. • Will still be there when the called function returns. • This makes it possible for a function to call itself.

  34. Recursive Calls • If a function calls itself, there is a separate stack frame corresponding to each invocation. • arguments • local variables • return address • A function can call itself multiple times without overwriting its local variables. • But not an unlimited number of times. • Eventually will run out of stack space!

  35. A Very Simple Example void countdown(int n) { printf ("n = %d\n", n); n--; if (n >= 0) { countdown(n); } } int main ( ) { countdown(5); return 0; } Call self

  36. Compile and Run

  37. A Very Minor Change void countdown(int n) { //printf ("n = %d\n", n); n--; if (n >= 0) { countdown(n); } printf ("n = %d\n", n); } int main ( ) { countdown(5); return 0; } Now what is the output?

  38. Compile and Run Why did this happen?

  39. Program countdown2.c void countdown(int n) { //printf ("n = %d\n", n); n--; if (n >= 0) { countdown(n); } printf ("n = %d\n", n); } int main ( ) { countdown(5); return 0; } Last invocation prints first When it returns, next to last invocation prints. ... First invocation prints last Recursion can be tricky!

  40. Inappropriate Use of Recursion • A classic (and bad!) example of recursion is the factorial function.

  41. Factorial Program #include <stdio.h> #include <assert.h> int factorial(int n) { assert (n >= 0); if (n <= 1) { return 1; } return n*factorial(n-1); }

  42. Factorial Program int main() { int n = -1; printf ("This program uses a recursive function\n"); printf ("to compute N factorial\n\n"); printf ("Enter N as a nonnegative integer: "); while (n < 0) { scanf("%d", &n); if (n < 0) { printf ("Invalid entry. Please try again\n"); while (getchar() != 'n'); // Clear keyboard input buffer } } printf ("%d factorial is %d\n", n, factorial(n)); return 0; }

  43. Factorial Program in Action

  44. Inappropriate Use of Recursion • Why is this an inappropriate use of recursion? • The problem is not inherently recursive. • Can be solved just as easily with a loop. • Prefer loops over recursion when it is feasible to do so. • Avoid the performance cost and conceptual subtleties of recursion.

  45. An Inherently Recursive Calculation • The Fibonacci series is defined as 1, 1, 2, 3, 5, ... where after the first two members, each member is the sum of the two preceding members.

  46. Fibonacci main() int main() { int num, fibo; printf ("This program computes Fibonacci numbers\n\n"); while (1) { printf ("Enter a (fairly small) integer: "); if (scanf("%d", &num) == 1) { fibo = Fibonacci(num); printf ("\nFibonacci(%d) = %d\n\n", num, fibo); } else { printf ("Input error\n"); printf ("Please try again\n\n"); while (getchar() != '\n'); // Clear input buffer } } }

  47. Recursive Implementation int Fibonacci (int n) { if (n <= 2) { return 1; } return Fibonacci(n-1) + Fibonacci(n-2); } Try it!

  48. Stopped with Ctrl-c Fibonacci Program in Action

  49. Measure Run Time #include <time.h> ... int main() { int num, fibo; time_t start_time, end_time; printf ("This program computes Fibonacci numbers\n\n"); while (1) { printf ("Enter a (fairly small) integer: "); if (scanf("%d", &num) == 1) { time(&start_time); fibo = Fibonacci(num); time(&end_time); printf ("\nFibonacci(%d) = %d\n", num, fibo); printf ("%5.1f seconds\n\n", difftime(end_time, start_time)); } }

  50. Ctrl-c Measure Run Time

More Related