PPS Unit-Iv
PPS Unit-Iv
PPS Unit-Iv
RECURSION
Programmers use two approaches for writing repetitive algorithms: One approach uses loops and the other
uses recursion.
Recursion is a repetitive process in which a function calls itself.
Some older languages do not support recursion. One major language that does not support recursion is
COBOL.
To study the concept of recursion let us consider the example of finding factorial of a given number.
In our study we’ll see both iterative definition and recursive definition for finding the factorial.
Iterative Definition
The factorial of a number is the product of the integral values from 1 to the given number.
The iterative definition can be shown as:
An iterative function can be defined which will take only the iteration counter to calculate the factorial but
not the function call.
Example: factorial (4) = 4 * 3 * 2 * 1 = 24
Recursive Definition
A function is defined recursively whenever the function itself appears within the definition itself.
The recursive definition of factorial function can be shown as:
The decomposition of factorial (3), using the above formula is shown in the following formula.
Observe it carefully; the recursive solution for a problem involves a two-way journey: the decomposition
will be from top to bottom, and then we solve it from bottom to the top.
Every recursive call must either solve part of the problem or reduce the size of the problem.
The recursive calculation looks more difficult when using pen and paper, but it is often much easier and
more elegant solution when a computer is used.
Every recursive solution to the problem will have a base-case and general-case. A base-case will provide
the solution to the problem and all other cases will be known as general-cases.
In the factorial example the base-case is factorial of (0) and all other cases are general-cases.
Fibonacci Numbers
void fibonacci(int n)
{
int i, term1 = 0, term2 =1, nextTerm;
for (i = 1; i <= n; ++i)
{
printf("%d, ", term1);
nextTerm = term1 + term2;
term1 = term2;
term2 = nextTerm;
}
}
Output:
Enter the number of terms: 6
0, 1, 1, 2, 3, 5,
Recursive solution to factorial problem
int fibonacci(int n)
{
if(n == 0 || n == 1)
return n;
return (fibonacci(n - 1) + fibonacci(n - 2));
}
Output:
Enter the nuumber of terms:6
Fibonacci series terms are:
0, 1, 1, 2, 3, 5,
The HCF (Highest Common Factor) or GCD (Greatest Common Divisor) of two integers is the largest
integer that can exactly divide both numbers (without a remainder).
Each element in a structure is called a field. A field is the smallest element of named data that has meaning.
It has many of the characteristics of the variables. It has a type, an identifier and it also exists in the
memory. It can be initialized a value, and later can be used for manipulations. The only difference between
the variable and a structure field is that, structure field is a part of the structure.
The difference between an array and a structure is that, all elements in an array must be of same type, but
the elements in a structure can be of same or different types.
A structure is a convenient way in which data are grouped into one single name. It provides flexibility and
an increased control over accessing the data when it needed. Using structures data can be accessed as a
single grouped object or individual elements can be accessed.
1. Tagged Structures:
It is a more powerful way of declaring a structure. By using the keyword typedef the structure will be declared.
Syntax: Example:
typedef struct typedef struct
{ {
Filed list; char name[20];
}TYPE; char ID[10];
int marks;
}STUDENT;
The type-defined structure differs from the tagged declarations in two ways:
First, the keyword, type-def, is added in the beginning of the declaration.
Second, an identifier is required at the end of the block. The identifier will be the structure
type name.
After a structure has been declared, a variable of structure type can created using it.
The structure type can be declared in the global area of the program, to make it visible to all functions.
The structure variables are declared in the local declarations.
Initialization
The rules for structure initialization are similar to the rules for array initialization.
The initializing values are enclosed in braces and separated by commas.
They must match the corresponding types in the structure definition.
Examples:
Accessing Structures:
The elements in a structure can be accessed individually or the complete structure can assigned as a whole.
Structure fields can be accessed and manipulated using operators just like any other normal variables.
To refer to a field in a structure the structure and the field both has to be referred.
C uses a hierarchical naming convention that first uses the structure variable identifier and then the field
identifier.
The structure variable identifier is separated from the field identifier by a dot.
The dot is known as the direct selection operator.
Example1: Example2:
aStudent.ID SAMPLE sam1={2,5,3.2,’A’};
aStudent.name scanf(“%d %d %f %c”, &sam1.x, &sam1.y,
aStudent.marks &sam1.t, &sam1.u);
prinf(“%d %d %f %c”, sam1.x, sam1.y,
sam1.t, sam1.u);
void main(void)
{
//declaring, defining and initializing the structure variable sam1
SAMPLE sam1 = {5,4,3.2,'A'};
SAMPLE sam2;
printf("sam1 contents:\n");
printf("%d %d %f %c", sam1.x,sam1.y,sam1.t,sam1.u);
printf("\nEnter contents for sam2:\n");
scanf("%d %d %f %c",&sam2.x,&sam2.y,&sam2.t,&sam2.u);
//Modifying sam1
sam1.x=45;
sam1.y=32;
sam1.t=5.4;
sam1.u='d';
printf("\nsam1 contents after modification:");
printf("%d %d %f %c", sam1.x,sam1.y,sam1.t,sam1.u);
printf("\nsam2 contents after modification:");
printf("%d %d %f %c", sam2.x,sam2.y,sam2.t,sam2.u);
}
Output:
sam1 contents:
5 4 3.200000 A
Enter contents for sam2:
3 5 2.45 s
Only one operation is allowed on the structure that is the assignment of a structure to another structure.
A structure can only be copied to another structure of the same type using the assignment operator.
When one structure needs to be copied to another structure, instead of assigning the individual members to
another structure’s members, the whole structure can be initialized to another structure.
void main(void)
{
//declaring, defining and initializing the structure variable sam1
SAMPLE sam1 = {5,4,3.2,'A'};
SAMPLE sam2;
sam2 = sam1;
printf("sam1 contents:\n");
printf("%d %d %f %c", sam1.x,sam1.y,sam1.t,sam1.u);
printf("\nsam2 contents:\n");
printf("%d %d %f %c", sam2.x,sam2.y,sam2.t,sam2.u);
}
Output:
sam1 contents:
5 4 3.200000 A
sam2 contents:
5 4 3.200000 A
Pointer to structure:
The parenthesis in the above example are absolutely required, without the parenthesis the compiler will
consider *ptr.x as *(ptr.x). C applies the dot (.) operator first and then the asterisk operator next.
The reason the parenthesis are needed is that the precedence of the direct selection operator (.) is higher
than the indirection operator (*).
Here *ptr.x will be interpreted as *(ptr.x) which is wrong. *(ptr.x) means a completely different undefined
structure called ptr that contains a member x, which must be a pointer. Since this is not true, a compile time
error will be generated.
To avoid the above confusion (to eliminate the problem with pointers to structures) a special operator
known as indirect selection operator is used.
The symbol used for indirect selection operator is an arrow formed by minus sign and the grater than
symbol (->).
The indirection operator is placed between the pointer identifier of structure and the member to be
referenced.
void main(void)
{
//declaring, defining and initializing the structure variable sam1
SAMPLE sam1 = {5,4,3.2,'A'};
SAMPLE* strPtr;
strPtr = &sam1;
printf("Accessing sam1 contents through structure variable and direct selection operator (dot(.)):\n");
printf("%d %d %f %c", sam1.x,sam1.y,sam1.t,sam1.u);
printf("\nAccessing sam1 contents through pointer to structure and direct selection operator (dot(.)):\n");
printf("%d %d %f %c", (*strPtr).x,(*strPtr).y,(*strPtr).t,(*strPtr).u);
printf("\nAccessing sam1 contents through pointer to structure and indirect selection operator (->):\n");
printf("%d %d %f %c", strPtr->x,strPtr->y,strPtr->t,strPtr->u);
}
Output:
Accessing sam1 contents through structure variable and direct selection operator (dot(.)):
5 4 3.200000 A
Accessing sam1 contents through pointer to structure and direct selection operator (dot(.)):
5 4 3.200000 A
Accessing sam1 contents through pointer to structure and indirect selection operator (->):
5 4 3.200000 A
COMPLEX STRUCTURES
Structures within structures (nested structure), arrays within structure, and arrays of structures are some of
the complex forms of structures.
i. Nested Structures
ii. Structures containing Arrays
iii. Structures containing pointers
iv. Array of structures
i. Nested Structures:
Example:
//type declarations
typedef struct
{
int month;
int day;
int year;
}DATE;
typedef struct
// A more complex form {
typedef struct int hour;
{ int min;
STAMP startTime; int sec;
STAMP endTime; }TIME;
}JOB;
typedef struct
//variable declaration {
JOB job; DATE date;
TIME time;
}STAMP;
//variable declarations
STAMP stamp;
The most important point to remember when nesting structures is, they must be declared from inside
out. That is they must be declared from lowest level to the highest level. When nesting a structure into
the other structure the inner structure must be declared first before its inclusion.
To access fields of nested structures the direct referencing operator dot(.) is used from highest level to
inner component level.
stamp stamp
stamp.date stamp.time
stamp.date.month stamp.time.hour
stamp.date.day stamp.time.min
stamp.date.year stamp.time.sec
job.startTime.time.hour
job.endTime.time.hour
To initialize a Nested Structure simply pass the values using sets to the outermost structure variable using
assignment operator.
The outermost structure will have the instances of inner structure and hence initializes the values
accordingly.
typedef struct
{
int hour;
int min;
int sec;
}TIME;
typedef struct
{
DATE date;
TIME time;
}TIMESTAMP;
void main(void)
{
TIMESTAMP tstamp = {{05, 10, 2019}, {23, 45, 01}};
printf("Event Date (mm:dd:yyyy): %d / %d / %d", tstamp.date.month, tstamp.date.day, tstamp.date.Year);
printf("\nEvent Time (hh:mm:ss): %d : %d : %d", tstamp.time.hour, tstamp.time.min, tstamp.time.sec);
}
Output:
Event Date (mm:dd:yyyy): 5 / 10 / 2019
Event Time (hh:mm:ss): 23 : 45 : 1
To define arrays within structures just defined in their regular approach within the structure.
Referencing arrays within a structure is same like referencing other elements from the structure.
First we need to qualify the element with structure name and then with index or pointer the array can be
accessed from the structure.
Initializing Arrays within a structure
Since array is a separate member and it will have other members as part of it, hence the value for an array
within a structure must be separated using a set of braces.
Example:
void main(void)
{
STUDENT student = {"John", {18, 17, 15}};
student.final = student.midterm[0]+student.midterm[1]+student.midterm[2];
printf("Student Name: %s",student.name);
printf("\nStudent midterm Marks: %d %d %d", student.midterm[0], student.midterm[1], student.midterm[2]);
printf("\nStudent Final Marks: %d", student.final);
}
Output:
Student Name: John
Student midterm Marks: 18 17 15
Student Final Marks: 50
Point of Consideration:
A pointer can be used to refer directly the array elements within a structure.
Consider the above example to store the starting location of midterm array a pointer pScore can be used.
Later using this pScore one can access the complete array midterm without depending on the structure.
Example:
int* pScore = student.midterm;
int total = *pScore + *(pScore+1) + *(pScore+2);
typedef struct
{
DATE date;
}STAMP;
//variable declarations
STAMP tstamp;
//Initialization
stamp.date.month = may;
typedef struct
{
DATE date;
}TIMESTAMP;
void main(void)
{
TIMESTAMP tStamp = {"May", 9, 2019};
printf("Event DATE: %dth %s - %d", tStamp.date.day, tStamp.date.month, tStamp.date.year);
}
Output:
Event DATE: 9th May - 2019
void main(void)
{
STUDENT std[5];
int i;
// storing information
for(i=0; i<5; i++)
{
std[i].rollno = i+1;
printf("\n");
}
printf("Displaying Information:\n\n");
// displaying information
for(i=0; i<5; i++)
{
printf("\nRoll number: %d\n",std[i].rollno);
printf("Name: ");
puts(std[i].name);
printf("Marks: %d %d %d",std[i].midmarks[0], std[i].midmarks[1], std[i].midmarks[2]);
printf("\n");
}
}
Output:
Enter information of students:
Displaying Information:
Roll number: 1
Name: John
Marks: 12 13 15
Roll number: 2
Name: Asif
Marks: 15 17 19
UNIONS
typedef union
{
char chAry[2];
int num;
}SHAREDATA;
Referencing Unions
When a union is being referenced through a pointer, the indirect selection operator ( ) can be used.
SHAREDATA* ptrShareData;
ptrShareDatanum;
ptrShareDatachAry[0];
ptrShareDatachAry[1];
Initializing a Union:
Only the first type declared in the union can be initialized when the union variable is defined. The other
types can be initialized by assigning values or reading values into the union.
When initializing a union, the value must be enclosed in a set of braces, even if there is only one value.
//Demonstration of Unions
#include<stdio.h>
typedef union
{
int num;
char chAry[2];
}SHAREDATA;
void main(void)
{
SHAREDATA shareData;
shareData.num = 16706;
printf("Integer Value: %d", shareData.num);
shareData.chAry[0] = 'X';
shareData.chAry[1] = 'Y';
printf("\nValues from character array: %c %c",shareData.chAry[0], shareData.chAry[1]);
printf("\nInteger Value: %d", shareData.num);
}
Output:
Integer Value: 16706
Values from character array: X Y
Integer Value: 22872
DIFFERENCE BETWEEN UNION AND STRUCTURE