C Programming Unit 3
C Programming Unit 3
C Programming Unit 3
1. Code reusability
2. Better readability
1. Library functions
2. User-defined functions
1. Library functions [Built-in functions]
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:
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 name and the number and the type of arguments in the function call
must be same as that given in the function declaration and the function
header of the function definition.
Names (and not the types) of variables in function declaration, function call,
and header of function definition may vary.
Arguments may be passed in the form of expressions to the called function.
In such a case, arguments are first evaluated and converted to the type of
formal parameter and then the body of the function gets executed.
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, ...);
… Actual arguments
…
}
{ Formal arguments
…….
….
return (value);
}
Calling function – The function that calls a function is known as a calling
function.
Called function – The function that has been called is known as a called function.
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.
1. After the execution of the function call statement, the program control is
transferred to the called function.
2. The execution of the calling function is suspended and the called function
starts execution.
3. After the execution of the called function, the program control returns to
the calling function and the calling function resumes its execution.
3 double exp(double x)- Returns the value of e raised to the xth power
double log(double x)
4 Returns the natural logarithm (base-e logarithm) of x.
double sqrt(double x)
5 Returns the square root of x.
2 scanf() This function is used to read a character, string, and numeric data
from keyboard.
Output: input_str:
Hello input_str:
World output_str:
World
Output:
The names are different
Example: Strupr() and strlwr() #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.
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)
{
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.
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
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
5
The factorial of a number=120
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
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)
printf("Number is not found.");
else printf("Number is
found.");
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
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.
int **p;
p is a pointer to a pointer to an
integer.
int a=12;
int *p=&a; a
int **pptr=&p;
12
p 4000 4000
6000
6000
pptr
8000
So **pptr=12
12.5
a
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;
12 int
a=12; a
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.
1 2
e operand *
T sizeof (T)
Preincrement
Result =
initial value of
pointer +
sizeof (T)
pe operand *
T sizeof (T)
E.g. float* int float* p=p-1 p=2000 1996 2000 – 1 *
4 = 2000-
4=1996
pe initial value of
T pointer
Predecrement
Result =
initial value of
pointer –
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
4000 4100 4400
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
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
Enter the Strings 1 kailash
Enter the Strings 2 Aswin
Enter the Strings 3 Zulphia
Enter the Strings 4 Babu
Enter the Strings 5 Clinton
Reorder list is
Aswin
Babu Clinton
kailash
Clinton
2. Pass by reference
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
After swapping: a =10 and b = 20
Main function
a b
10 20
1000 1002
Swap
function b1
10 20
a1
2000 2002
After swap function
a1 b1
20 10
2000 2002
#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
10 20
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);
printf("\nBefore Swaping x = %d and y = %d", x, y);
swap(&x, &y); // Function Call - Pass By Reference
printf("\nAfter Swaping x = %d and y = %d", x, y);
getch(); }
void swap(int *num1, int *num2) {
int temp; temp = *num1;
*num1 = *num2;
*num2 = temp;
}
Output:
Enter First number : 12
Enter Second number : 21