Unit Iii Functions and Pointers
Unit Iii Functions and Pointers
Library functions are predefined functions. These functions are already developed
by someone and are available to the user for use. Ex. printf( ), scanf( ).
2. User-defined functions
User-defined functions are defined by the user at the time of writing a program.
Ex. sum( ), square( )
Using Functions
A function can be compared to a black box that takes in inputs, processes it, and
then outputs the
result. Terminologies using functions are:
▪ A function f that uses another function g is known as the calling function,
and g is known as the called function.
▪ The inputs that a function takes are known as arguments.
▪ When a called function returns some result back to the calling function, it is
said to return that result.
▪ The calling function may or may not pass parameters to the called function.
If the called function accepts arguments, the calling function will pass
parameters, else not.
▪ Function declaration is a declaration statement that identifies a function’s
name, a list of arguments that it accepts, and the type of data it returns.
▪ Function definition consists of a function header that identifies the function,
followed by the body of the function containing the executable code for that
function.
value that it will return to the calling program. Placing the function declaration
statement prior to its use enables the compiler to make a check on the arguments
used while calling that function.
Syntax:
return_data_type function_name(data_type variable1, data_type variable2,..);
Here, function_name is a valid name for the function. Naming a function
follows the same rules that are followed while naming variables. A function should
have a meaningful name that must specify the task that the function will perform.
return_data_type specifies the data type of the value that will be returned
to the calling function as a result of the processing performed by the called
function.
(data_type variable1, data_type variable2, ...) is a list of variables of
specified data types.
These variables are passed from the calling function to the called function.
They are also known as arguments or parameters that the called function accepts to
perform its task.
.............
return(variable);
}
While return_data_type function_name(data_type variable1, data_type
variable2,...) is known as the function header, the rest of the portion comprising of
program statements within the curly brackets { } is the function body which
contains the code to perform the specific task.
Note that the function header is same as the function declaration. The only
difference between the two is that a function header is not followed by a semi-
colon.
▪ If the return type of the function is not void, then the value returned by the
called function may be assigned to some variable as given below.
variable_name = function_name(variable1, variable2, ...);
Working of a function
void main()
{
int x,y,z;
int abc(int, int, int) // Function declaration
…..
…..
abc(x,y,z) // Function Call
… Actual arguments
…
}
Actual arguments – The arguments of the calling function are called as actual
arguments.
Formal arguments – The arguments of called function are called as formal
arguments.
#include <stdio.h>
int main() {
char input_str[20];
char *output_str;
strcpy(input_str, "Hello");
printf("input_str: %s\n", input_str);
output_str = strcpy(input_str, "World");
Output:
input_str: Hello
input_str: World
output_str: World
Output:
The names are different
#include<stdio.h>
#include<string.h>
int main( )
{
char str[] = “ String Functions”;
printf(“%s \n”, strupr(str));
printf(“%s \n”, strlwr(str));
return 0;
}
Output:
STRING FUNCTIONS
string functions
3.6 Recursion
A function that calls itself is known as a recursive function.
Direct & Indirect Recursion:
Direct Recursion:
A function is directly recursive if it calls itself.
A( )
{
….
….
A( );// call to itself
….
}
Indirect Recursion:
Function calls another function, which in turn calls the original function.
10 B. Shanmuga Sundari csenotescorner.blogspot.com
CS8251 Programming in C UNIT III
A( )
{
…
…
B( );
…
}
B( )
{
…
…
A( );// function B calls A
…
}
Consider the calculation of 6! ( 6 factorial )
ie 6! = 6 * 5 * 4 * 3 * 2 * 1
6! = 6 * 5!
6! = 6 * ( 6 - 1 )!
n! = n * ( n - 1 )!
Types of Recursion
Direct Recursion
A function is said to be directly recursive if it explicitly calls itself. Here, the
function Func() calls itself for all positive values of n, so it is said to be a directly
recursive function.
int Func (int n)
{
11 B. Shanmuga Sundari csenotescorner.blogspot.com
CS8251 Programming in C UNIT III
if (n == 0)
return n;
else
return (Func (n–1));
}
Indirect Recursion
A function is said to be indirectly recursive if it contains a call to another function
which ultimately calls it. These two functions are indirectly recursive as they both
call each other.
int Funcl (int n)
{
if (n == 0)
return n;
else
return Func2(n);
}
int Func2(int x)
{
return Func1(x–1);
}
Tail Recursion
A recursive function is said to be tail recursive if no operations are pending to be
performed when the recursive function returns to its caller. When the called
function returns, the returned value is immediately returned from the calling
function.
12 B. Shanmuga Sundari csenotescorner.blogspot.com
CS8251 Programming in C UNIT III
int Fact(int n)
{
if (n == 1)
return 1;
else
return (n * Fact(n–1));
}
The above function is a nontail-recursive function, because there is a
pending operation of multiplication to be performed on return from each recursive
call. Whenever there is a pending operation to be performed, the function becomes
non-tail recursive. In such a non-tail recursive function, information about each
pending operation must be stored, so the amount of information directly depends
on the number of calls.
int Fact(n)
{
return Fact1(n, 1);
}
int Fact1(int n, int res)
{
if (n == 1)
return res;
else
return Fact1(n–1, n*res);
}
The same factorial function can be written in a tail recursive manner. In the code,
Fact1 function preserves the syntax of Fact(n). Here the recursion occurs in the
Fact1 function and not in Fact function. Fact1 has no pending operation to be
13 B. Shanmuga Sundari csenotescorner.blogspot.com
CS8251 Programming in C UNIT III
performed on return from recursive calls. The value computed by the recursive call
is simply returned without any modification. So in this case, the amount of
information to be stored on the system stack is constant (only the values of n and
res need to be stored) and is independent of the number of recursive calls.
E.g. Program:
#include<stdio.h>
#include<conio.h>
void main()
{
int fact(int);
int n,f;
printf(“Enter the number \n”);
scanf(“%d”,&n);
f=fact(n);
printf(“The factorial of a number =%d”,f);
getch();
}
int fact(int n)
{
if(n==1)
return(1);
else
return n*fact(n-1);
}
OUTPUT
Enter the number to find the factorial
14 B. Shanmuga Sundari csenotescorner.blogspot.com
CS8251 Programming in C UNIT III
5
The factorial of a number=120
return 1;
Observe the series of function calls. When the function pending operations in turn
calls the function
Fibonacci(7) = Fibonacci(6) + Fibonacci(5)
Fibonacci(6) = Fibonacci(5) + Fibonacci(4)
Fibonacci(5) = Fibonacci(4) + Fibonacci(3)
Fibonacci(4) = Fibonacci(3) + Fibonacci(2)
Fibonacci(3) = Fibonacci(2) + Fibonacci(1)
Fibonacci(2) = Fibonacci(1) + Fibonacci(0)
Now we have, Fibonacci(2) = 1 + 0 = 1
Fibonacci(4) = 2 + 1 = 3
Fibonacci(5) = 3 + 2 = 5
Fibonacci(6) = 3 + 5 = 8
Fibonacci(7) = 5 + 8 = 13
Tower of Hanoi
The tower of Hanoi is one of the main applications of recursion. It says, ‘if
you can solve n–1 cases, then you can easily solve the nth case’. The figure (a)
below shows three rings mounted on pole A. The problem is to move all these
rings from pole A to pole C while maintaining the same order. The main issue is
that the smaller disk must always come above the larger disk.
In our case, A is the source pole, C is the destination pole, and B is the spare
pole. To transfer all the three rings from A to C, we will first shift the upper two
rings (n–1 rings) from the source pole to the spare pole. We move the first two
rings from pole A to B as shown in figure (b) .
Now that n–1 rings have been removed from pole A, the nth ring can be
easily moved from the source pole (A) to the destination pole (C). Figure (c) shows
this step.
The final step is to move the n–1 rings from the spare pole (B) to the
destination pole (C). This is shown in Fig. (d)
To summarize, the solution to our problem of moving n rings from A to C using B
as spare can be given as:
Base case: if n=1
▪ Move the ring from A to C using B as spare
Recursive case:
▪ Move n – 1 rings from A to B using C as spare
▪ Move the one ring left on A to C using B as spare
▪ Move n – 1 rings from B to C using A as spare
Figure (a)
Figure (b)
Figure (c)
Figure (d)
{
int i, n ;
float x, val, sum, t ;
clrscr() ;
printf("Enter the value for x : ") ;
scanf("%f", &x) ;
printf("\nEnter the value for n : ") ;
scanf("%d", &n) ;
val = x ;
x = x * 3.14159 / 180 ;
t=x;
sum = x ;
for(i = 1 ; i < n + 1 ; i++)
{
t = (t * pow((double) (-1), (double) (2 * i - 1)) * x * x) / (2 * i * (2 * i + 1)) ;
sum = sum + t ;
}
printf("\nSine value of %f is : %8.4f", val, sum) ;
getch() ;
}
Output:
Enter the value for x : 30
Enter the value for n : 20
Sine value of 30.000000 is : 0.5000
int a[10],i,n,m,c,l,u;
l=0,u=n-1;
c=binary(a,n,m,l,u);
if(c==0)
20 B. Shanmuga Sundari csenotescorner.blogspot.com
CS8251 Programming in C UNIT III
return 0;
}
int mid,c=0;
if(l<=u)
{
mid=(l+u)/2;
if(m==a[mid])
{
c=1;
}
else if(m<a[mid])
{
return binary(a,n,m,l,mid-1);
}
else
return binary(a,n,m,mid+1,u);
}
else
21 B. Shanmuga Sundari csenotescorner.blogspot.com
CS8251 Programming in C UNIT III
return c;
}
Output:
Enter the size of an array: 5
Enter the elements of the array: 8 9 10 11 12
Enter the number to be search: 8
Number is found.
3.8 Pointers
Definition:
A pointer is a variable that stores the address of a variable or a function
Advantages
1. Pointers save memory space
2. Faster execution
3. Memory is accessed efficiently.
Declaration
datatype *pointername;
int a=10; p a
int *p=&a;
2000 10
4000 2000
p is an integer pointer & holds the address of an int variable a.
Pointer to pointer
A pointer that holds the address of another pointer variable is known as a
pointer to pointer.
E.g.
22 B. Shanmuga Sundari csenotescorner.blogspot.com
CS8251 Programming in C UNIT III
int **p;
6000
6000 pptr
8000
So **pptr=12
a 12.5
1000 1000
P
2000
2. Dereferencing a pointer
The object referenced by a pointer can be indirectly accessed by
dereferencing the pointer. Dereferencing operator (*) is used for this .This
operator is also known as indirection operator or value- at-operator
Eg) int b;
int a=12;
a 12 int *p;
23 B. Shanmuga Sundari csenotescorner.blogspot.com
1000
CS8251 Programming in C UNIT III
1000 p=&a;
b=*p; \\value pointed by p(or)value
at 1000=12,
p so b=12
2000
Example program
#include<stdio.h>
void main() Note
{
int a=12; %p is used for addresses; %u
int *p; can also be used.
int **pptr;
p=&a; *p=value at p
=value at (1000)=12
pptr=&p;
printf(“a value=%d”,a); *pptr=value at(pptr)
printf(“value by dereferencing p is %d \n”,*p); =value at(value at (2000))
printf(“value by dereferencing pptr is %d \n”,**pptr); =value at (1000)=12
printf(“value of p is %u \n”,p);
printf(“value of pptr is %u\n”,pptr);
}
Output:
a value=12
value by dereferencing p is 12
value by dereferencing pptr is 12
value of p is 1000
value of pptr is 2000
a 12
1000 p 1000
3000
1. Addition
(i) An addition of int type can be added to an expression of pointer type. The result
is pointer type.(or)A pointer and an int can be added.
Pre-
increment
Result =
initial value
of pointer +
sizeof (T)
Eg. post float* - float* ftr=p++ ftr=? ftr=2000
Pre-
decrement
Result =
initial value
of pointer –
sizeof(T)
Eg.pre float* - float* ftr=--p ftr=? ftr=1996
decrement p=2000 p=1996 Value of ptr
= Value of
ptr –
sizeof(T)
E.g.) E1[E2]=>*(E1+E2)
Example
#include<stdio.h>
void main()
{
int a[3]={10,15,20};
printf(“Elements are %d %d %d\n”, a[0],a[1],a[2]);
printf(“Elements are %d %d %d\n”, *(a+0),*(a+1),*(a+2);
}
Output:
Elements are 10 15 20
Elements are 10 15 20
10 20 30
Example:
Now look at another code in which we store the address of three individual arrays
in the array of pointers:
int main()
{
int arr1[]={1,2,3,4,5};
int arr2[]={0,2,4,6,8};
int arr3[]={1,3,5,7,9};
int *parr[3] = {arr1, arr2, arr3};
int i;
for(i = 0;i<3;i++)
printf(«%d», *parr[i]);
return 0;
}
Output
101
char *x[20];
int i,n=0;
void reorder(int n,char *x[]);
clrscr();
printf("Enter no. of String : ");
scanf("%d",&n);
printf("\n");
for(i=0;i<n;i++)
{
printf("Enter the Strings %d : ",i+1);
x[i]=(char *)malloc(20*sizeof(char));
scanf("%s",x[i]);
}
reorder(n,x);
printf("\nreorder list is : \n");
for(i=0;i<n;i++)
{
printf("%d %s\n",i+1,x[i]);
}
getch();
}
void reorder(int n,char *x[])
{
int i,j;
char t[20];
for(i=0;i<n-1;i++)
for(j=i+1;j<n;j++)
if(strcmp(x[i],x[j])>0)
{
strcpy(t,x[j]);
strcpy(x[j],x[i]);
strcpy(x[i],t);
}
return;
}
Output:
Enter no. of string 5
31 B. Shanmuga Sundari csenotescorner.blogspot.com
CS8251 Programming in C UNIT III
E.g. Program:
#include<stdio.h>
#include<conio.h>
void main()
{
int a,b;
void swap(int ,int);
a=10;
b=20;
printf("\n Before swapping: a = %d and b = %d",a,b);
swap(a, b);
printf("\n After swapping: a= %d and b= %d",a,b);
getch();
}
OUTPUT:
Before swapping: a =10 and b =20
33 B. Shanmuga Sundari csenotescorner.blogspot.com
CS8251 Programming in C UNIT III
Main function
a b
10 20
1000 1002
Swap function
a1 b1
10 20
2000 2002
After swap function
a1 b1
20 10
2000 2002
Example Program:
#include<stdio.h>
#include<conio.h>
void main()
{
int a,b;
void swap(int *,int *);
a=10;
b=20;
printf("\n Before swapping: a= %d and b= %d",a,b);
swap(&a,&b);
printf("\n After swapping: a= %d and b= %d",a,b);
getch();
}
void swap(int *a1,int *b1)
{
int t;
t = *a1;
*a1 = *b1;
*b1 = t;
}
OUTPUT:
Before swapping: a = 10 and b = 20
After swapping: a = 20 and b = 10
Main function
a b
36 B. Shanmuga Sundari csenotescorner.blogspot.com
CS8251 Programming in C UNIT III
10 20
1000 1002
Swap function
a1 b1
1000 1002
2000 2002
After swap function
a b
20 10
1000 1002
3.15 Example Program: Swapping of two numbers and changing the value of
a variable using pass by reference
#include<stdio.h>
#include<conio.h>
void swap(int *num1, int *num2);
void main() {
int x, y;
printf("\nEnter First number : ");
scanf("%d", &x);
printf("\nEnter Second number : ");
scanf("%d", &y);
37 B. Shanmuga Sundari csenotescorner.blogspot.com
CS8251 Programming in C UNIT III
Output:
Enter First number : 12
Enter Second number : 21