Chapter 6 User-Defined Functions

Download as pptx, pdf, or txt
Download as pptx, pdf, or txt
You are on page 1of 44

Chapter 6

User-defined Function

1
Definition: A function is a block of statements that performs a
specific task. The function is also known as procedure or
subroutine in other programming languages

The general form of a function:

return-type function-name ( parameters )


{
declarations
statements
}

2
Examples:
Computing Averages:
Suppose we often need to compute the average of two double values. The C
library doesn’t have an “average” function, but we can easily define our own.
Here’s what it would look like:
double average(double a, double b)
{
return (a + b) / 2;
}
• The word double at the beginning is average’s return
type: the type of data that the function returns each time
it’s called.
• The identifiers a and b (the function’s parameters)
represent the two numbers that will be supplied when
average is called. Each parameter must have a type (just
like every variable has a type); in this example, both a and b
have type double.
• A function parameter is essentially a variable whose initial 3
Examples:
Computing Averages:
Every function has an executable part, called the body,
which is enclosed in
braces. The body of average consists of a single return
statement.

To call a function, we write the function name, followed by a


list of arguments.
For example, average(x, y) is a call of the average
function.

4
Examples:
Computing Averages:
/* Computes pairwise averages of three numbers */
#include <stdio.h>
double average(double a, double b)
{
return (a + b) / 2;
}
int main(void)
{
double x, y, z;
printf("Enter three numbers: ");
scanf("%lf%lf%lf", &x, &y, &z);
printf("Average of %g and %g: %g\n", x, y, average(x, y));
printf("Average of %g and %g: %g\n", y, z, average(y, z));
printf("Average of %g and %g: %g\n", x, z, average(x, z));
return 0;
} 5
Examples:
Computing Averages:

Each parameter is preceded by a specification of its type;


parameters are separated by commas.

double average(double a, b) /*** WRONG ***/


{
return (a + b) / 2;
}

The body of a function may include both declarations and


statements. For example, the average function could be written as:

double average(double a, double b)


{
double sum; /* declaration */
sum = a + b; /* statement */
return sum / 2; /* statement */
} 6
Examples:

Printing a Countdown
Not every function returns a value. For example, a function whose
job is to produce output may not need to return anything.
Consider the following function, which prints the message T
minus n and counting, where n is supplied when the function is
called:
void print_count(int n)
{
printf("T minus %d and counting\n", n);

7
Examples:
Printing a Countdown
/* Prints a countdown */
#include <stdio.h>
void print_count(int n)
{
printf("T minus %d and counting\n", n);
}

int main(void)
{
int i;
for (i = 10; i > 0; --i)
print_count(i);
return 0;
}
Output
T minus 10 and counting
T minus 9 and counting and so on. 8
Function Calls
A function call consists of a function name followed by a list of
arguments, enclosed in parentheses:
average(x, y);
average(x, y)
print_count(i)
A call of a void function is always followed by a semicolon to turn
it into a
statement:
print_count(i);

A call of a non-void function, on the other hand, produces a value


that can be
stored in a variable, tested, printed, or used in some other way:
avg = average(x, y);
if (average(x, y) > 0)
printf("Average is positive\n");
printf("The average is %g\n", average(x, y)); 9
Examples:

Testing Whether a Number Is


Prime
Write a program that tests whether a number is prime
or not. The program will prompt the user to enter a
number, then respond with a message indicating
whether or not the number is prime:

Enter a number: 34
Not prime

10
Testing Whether a Number Is
Prime
/* Tests whether a number is prime */
#include <stdio.h>
int is_prime(int n)
{
int divisor;
if (n <= 1)
return false;
for (divisor = 2; divisor * divisor <= n; divisor++)
int main(void)
if (n % divisor == 0) {
return 0; int n;
return 1; printf("Enter a number: ");
} scanf("%d", &n);
if (is_prime(n) == 1)
printf("Prime\n");
else
printf("Not prime\n"); 11
Flow of control of
a program with
functions

12
Class Practice:
Write a C program with a function that
takes 2 numbers as integer parameters and
returns the minimum of the two numbers.

13
Class Assignment 1:
Write a C program with a function that
takes n as an integer parameter and
returns the sum from 1 to n.

14
Function Declarations
A function declaration provides the compiler with
a brief indication of a function whose full
definition will appear later. A function declaration
as follows:

return-type function-name ( parameters ) ;

15
Example forward declaration

#include <stdio.h>
double average(double a, double b); /* DECLARATION */
int main(void)
{
double x, y, z;
printf("Enter three numbers: ");
scanf("%lf%lf%lf", &x, &y, &z);
printf("Average of %g and %g: %g\n", x, y, average(x,
y));
printf("Average of %g and %g: %g\n", y, z, average(y,
z));
printf("Average of %g and %g: %g\n", x, z, average(x,
z));
return 0;
}
double average(double a, double b) /* DEFINITION */
{ 16
Arguments

Parameters appear in function definitions;


they’re dummy names that represent values
to be supplied when the function is called.
Arguments are expressions that appear in
function calls.

These two parameters mainly defined by the


following names:

Formal parameters: the list of parameters


used during the function definition.
Actual parameters: the list of parameters used
during the function call
17
Arguments

While calling a function, the arguments can be passed


to a function in two ways
Call by value
Call by reference
Call by Value
The call by value method of passing arguments to a
function copies the actual value of an argument into the
formal parameter of the function

In this case, changes made to the parameter inside the


function have no effect on the argument

Such function calls are called calls by value


18
Arguments
Call by Value Example
#include<stdio.h>
void swap (int a, int b); //Forward declaration
int main(void){
int x = 5, y = 10;
printf("Before calling the swap function\n");
printf(" x = %d, y = %d\n", x, y);
swap(x,y); //Function call
printf("After calling the swap function\n");
printf(" x = %d, y = %d\n", x, y);
return 0;
} void swap (int a, int b){
int temp;
temp = a;
a = b;
b = temp;
printf(" Inside the function after swapping \n");
printf(" a = %d, b = %d\n", a, b);
} 19
Arguments

Call by Reference

Here, address of the parameters are passed in the function, so


actual and formal arguments shares the same address space

In call by reference, original value is modified because we


pass reference (address)

Hence, value changed inside the function, is reflected inside as


well as outside the function

20
Arguments
Call by reference Example
#include<stdio.h>
void swap (int *a, int *b); //Forward declaration
int main(void){
int x = 5, y = 10;
printf("Before calling the swap function\n");
printf(" x = %d, y = %d\n", x, y);
swap(x,y); //Function call
printf("After calling the swap function\n");
printf(" x = %d, y = %d\n", x, y);
return 0;
} void swap (int *a, int *b){
int temp;
temp = *a;
*a = *b;
*b = temp;
printf(" Inside the function after swapping \n");
printf(" a = %d, b = %d\n", *a, *b);
} 21
Self study:

Compare between call by value and call


by reference

22
Array Arguments
Arrays are often used as arguments. When a
function parameter is a one-dimensional array,
the length of the array can be (and is normally)
left unspecified:

int f(int a[]) /* no length specified */


{

}
A question: how will f know how long the array
is?
The sizeof function may help:
int f(int a[])
{
int len = sizeof(a) / sizeof(a[0]);
23
/*** WRONG: not the number of elements in a ***/
Array Arguments
The following function sum_array returns the sum of
the elements in a. Since sum_array needs to know
the length of a, we must supply it as a second
argument.
int sum_array(int a[], int n)
{
int i, sum = 0;
for (i = 0; i < n; i++)
sum += a[i];
return sum;
}
The prototype for sum_array has the following
appearance:
int sum_array(int a[], int n);
24
Array Arguments
When sum_array is called, the first argument will be
the name of an array, and the second will be its
length. For example:
#define LEN 100
int main(void)
{
int b[LEN], total;

total = sum_array(b, LEN);

}

Note that
total = sum_array(b[], LEN); /*** WRONG ***/

A function has no way to check that we’ve passed it


the correct array length. If we have 50 elements in
the array then we write
total = sum_array(b, 50); /* sums first 50 elements */ 25
Array Arguments
Be careful not to tell a function that an array
argument is larger than it really is:
total = sum_array(b, 150); /*** WRONG ***/

Another important thing to know is that a function is


allowed to change the elements of an array
parameter, and the change is reflected in the
corresponding argument. For example,
void store_zeros(int a[], int n)
{
int i;
for (i = 0; i < n; i++)
a[i] = 0;
}

If we call as follows what will it change


store_zeros(b, 100);
26
Array Arguments

For example, we might call sum_array in the


following way:
int b[] = {3, 0, 3, 4, 1};
total = sum_array(b, 5);
If b isn’t needed for any other purpose, it can be mildly annoying
to create it solely for the purpose of calling sum_array.
The following call of sum_array has a compound literal (shown in
bold) as its first argument:
total = sum_array((int []){3, 0, 3, 4, 1}, 5);
We also have the option of specifying a length
explicitly: (int [4]){1, 9, 2, 1} is equivalent to (int []){1, 9, 2, 1}.
27
Multidimensional Array
If the parameter is a multidimensional array, only
the length of the first dimension may be omitted
when the parameter is declared. For example,
#define LEN 10
int sum_two_dimensional_array(int a[][LEN], int n)
{
int i, j, sum = 0;
for (i = 0; i < n; i++)
for (j = 0; j < LEN; j++)
sum += a[i][j];
return sum;
}

28
The return Statement
A non-void function must use the return statement to specify
what value it will return. The return statement has the form

return expression ;
The expression is often just a constant or variable:

Example:

return 0;
return status;

29
Program Termination
Since main is a function, it must have a return type. A program
terminates with the return statement or end of main function for a
void main function.

The exit Function


Executing a return statement in main is one way to terminate a
program. Another is calling the exit function, which belongs to
<stdlib.h>.
The argument passed to exit has the same meaning as main’s
return value: both indicate the program’s status at termination.
To indicate normal termination, we’d pass 0:

exit(0); /* normal termination */

30
Program Termination
The exit Function
C allows us to pass EXIT_SUCCESS instead (the effect is the
same):
exit(EXIT_SUCCESS); /* normal termination */
Passing EXIT_FAILURE indicates abnormal termination:
exit(EXIT_FAILURE); /* abnormal termination */

EXIT_SUCCESS and EXIT_FAILURE are macros defined in


<stdlib.h>. The values of EXIT_SUCCESS and EXIT_FAILURE
are typical values are 0 and 1, respectively.

31
Program Termination
The exit Function

As methods of terminating a program, return and exit are closely


related. In fact, the statement

return expression;

in main is equivalent to

exit(expression);

32
Recursion
A function is recursive if it calls itself. For example, the
following function computes n! recursively, using the formula n!
= n × (n – 1)!:
int fact(int n)
{
if (n <= 1)
return 1;
else
return n * fact(n - 1);
}

33
Recursion
Some programming languages rely heavily on recursion, while
others don’t even allow it. C falls somewhere in the middle: it
allows recursion, but most C programmers don’t use it that often.

To see how recursion works, let’s trace the execution of the


statement
i = fact(3);

fact(3) finds that 3 is not less than or equal to 1, so it calls


fact(2), which finds that 2 is not less than or equal to 1, so it calls
fact(1), which finds that 1 is less than or equal to 1, so it returns 1, causing
fact(2) to return 2 × 1 = 2, causing
fact(3) to return 3 × 2 = 6.

34
Recursion
Here’s another example of recursion: a function that computes xn,
using the formula xn = x * xn–1.
int power(int x, int n)
{ if (n == 0)
return 1;
else
return x * power(x, n - 1);
}
The call power(5, 3) would be executed as follows:
power(5, 3) finds that 3 is not equal to 0, so it calls
power(5, 2), which finds that 2 is not equal to 0, so it calls
power(5, 1), which finds that 1 is not equal to 0, so it calls
power(5, 0), which finds that 0 is equal to 0, so it returns 1, causing
power(5, 1) to return 5 × 1 = 5, causing
power(5, 2) to return 5 × 5 = 25, causing
power(5, 3) to return 5 × 25 = 125.
35
Recursion
We can find the factorial and power of a number using recursion.
But we have other options to find the quantities.

Then what is the necessity of recursion?

Recursion is much more helpful for sophisticated


algorithms that require a function to call itself two or
more times.

In practice, one of the main requirement of recursion


is divide-and-conquer algorithm, in which a large
problem is divided into
smaller pieces.

A classic example of the divide-and-conquer


36
Recursion
Quick Sort Algorithm:

1. Choose an array element e (the “partitioning element”), then


rearrange the array so that elements 1, …, i – 1 are less than or
equal to e, and elements i + 1, …, n are greater than or equal
to e.
2. Sort elements 1, …, i – 1 by using Quicksort recursively.
3. Sort elements i + 1, …, n by using Quicksort recursively.

37
an array with
Recursion 7 elements

Quick Sort Algorithm:


The first element, 12, is the
partitioning element. Number in
high < low. Copy it somewhere
else leaves a hole.

Increase low

Increase low

38
Recursion
Quick Sort Algorithm:

18 is greater than 12

Send 18 to high
location, decrease high

39
Recursion
Quick Sort Algorithm:

115 is greater than


12, decrease high

7 is less than 12, send 7


to low, increase low,
low = high

Put 12 to ow or high
40
Recursion
Quick Sort Program:
#include <stdio.h> /* Sorts an array of integers using Quicksort algorithm */
#define N 10
void quicksort(int a[], int low, int high);
int split(int a[], int low, int high);
int main(void)
{
int a[N], i;
printf("Enter %d numbers to be sorted: ", N);
for (i = 0; i < N; i++)
scanf("%d", &a[i]);
quicksort(a, 0, N - 1);
printf(“\nIn sorted order: ");
for (i = 0; i < N; i++)
printf("%d ", a[i]);
printf("\n");
return 0;
} 41
Recursion
Quick Sort Program:
void quicksort(int a[], int low, int high)
{
int middle;
if (low >= high) return;
middle = split(a, low, high);
quicksort(a, low, middle - 1);
quicksort(a, middle + 1, high);
}

42
Recursion
Quick Sort Program:
int split(int a[], int low, int high)
{
int part_element = a[low];
for (;;) {
while (low < high && part_element <= a[high])
high--;
if (low >= high) break;
a[low++] = a[high];
while (low < high && a[low] <= part_element)
low++;
if (low >= high) break;
a[high--] = a[low];
}
a[high] = part_element;
return high;
}
43
44

You might also like