0% found this document useful (0 votes)
51 views61 pages

PPS Unit-3

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
51 views61 pages

PPS Unit-3

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 61

UNIT-III

STRUCTURES, UNIONS, POINTERS AND PREPROCESSORS

Need of structures

Structure is a collection of variables of different types under a single name.

For example: You want to store some information about a person: his/her name, citizenship
number and salary. You can easily create different variables name, citNo, salary to store these
information separately.

However, in the future, you would want to store information about multiple persons. Now, you'd
need to create different variables for each information per person: name1, citNo1, salary1, name2,
citNo2, salary2

You can easily visualize how big and messy the code would look. Also, since no relation between
the variables (information) would exist, it's going to be a daunting task.

A better approach will be to have a collection of all related information under a single name Person,
and use it for every person. Now, the code looks much cleaner, readable and efficient as well.

This collection of all related information under a single name Person is a structure.

Structure Definition in C

Keyword structis used for creating a structure.

Syntax of structure

struct structure_name

data_type member1;

data_type member2;

data_type memeber;};
Note: Don't forget the semicolon }; in the ending line.

We can create the structure for a person as mentioned above as:

struct person

char name[50];
int citNo;
float salary;

};

This declaration above creates the derived data type struct person.

Structure variable declaration

When a structure is defined, it creates a user-defined type but, no storage or memory is allocated.
For the above structure of a person, variable can be declared as:

struct person

char name[50];
int citNo;
float salary;

};
int main()

struct person person1, person2, person3[20];


return 0;
}

Another way of creating a structure variable is

struct person

char name[50];
int citNo;
float salary;
} person1, person2, person3[20];

In both cases, two variables person1, person2 and an array person3 having 20 elements of type
struct person are created.

Accessing members of a structure

There are two types of operators used for accessing members of a structure.
1. Member operator(.)
2. Structure pointer operator(->) (is discussed in structure and pointers tutorial)
3. Any member of a structure can be accessed as:

structure_variable_name.member_name

Suppose, we want to access salary for variable person2. Then, it can be accessed as:

person2.salary

Example of structure

Write a C program to add two distances entered by user. Measurement of distance should be
in inch and feet. (Note: 12 inches = 1 foot)

#include <stdio.h> struct Distance


{
int feet; float inch;
} dist1, dist2, sum;

int main()
{
printf("1st distance\n");
// Input of feet for structure variable dist1 printf("Enter feet: ");
scanf("%d", &dist1.feet);

// Input of inch for structure variable dist1 printf("Enter inch: ");


scanf("%f", &dist1.inch);
printf("2nd distance\n");

// Input of feet for structure variable dist2 printf("Enter feet: ");


scanf("%d", &dist2.feet);

// Input of feet for structure variable dist2 printf("Enter inch: ");


scanf("%f", &dist2.inch);
sum.feet = dist1.feet + dist2.feet; sum.inch = dist1.inch + dist2.inch;

if (sum.inch > 12)


{
//If inch is greater than 12, changing it to feet.
++sum.feet;
sum.inch = sum.inch - 12;
}
// printing sum of distance dist1 and dist2
printf("Sum of distances = %d\'-%.1f\"", sum.feet, sum.inch); return 0;
}

Output
1st distance Enter feet: 12
Enter inch: 7.9 2nd distance Enter feet: 2
Enter inch: 9.8
Sum of distances = 15'-5.7"

Structure Initialization

1. When we declare a structure, memory is not allocated for un-initialized variable.

2. Let us discuss very familiar example of structure student , we can


initialize structure variable in different ways –

Way1: Declare and Initialize

struct student
{
char name[20];
int roll;
float marks;
}std1 = { "Pritesh",67,78.3 };
In the above code snippet, we have seen that structure is declared and as soon as after declaration
we have initialized the structure variable.

Way2: Declaring and Initializing Multiple Variables

struct student
{
char name[20];
int roll;
float marks;
}
std1 = {"Pritesh",67,78.3};
std2 = {"Don",62,71.3};

In this example, we have declared two structure variables in above code. After declaration of
variable we have initialized two variable.

Way3: Initializing single member


struct student
{
int mark1;
int mark2;
int mark3;
} sub1={67};
Though there are three members of structure,only one is initialized , Then remaining two members are
initialized with Zero. If there are variables of other data type then their initial values will be –

Data Type Default value if not initialized

integer 0

float 0.00

char NULL

Way4: Initializing inside main

struct student
{
int mark1;
int mark2;
int mark3;
};
void main()
{
struct student s1 = {89,54,65};
- - - - --
- - - - --
- - - - --
};

When we declare a structure then memory won‟t be allocated for the structure. i.e only writing
below declaration statement will never allocate memory
struct student
{
int mark1;
int mark2;
int mark3;
};

We need to initialize structure variable to allocate some memory to the structure

Accessing StructureMembers

1. Array elements are accessed using the Subscript variable , Similarly Structure members

are accessed using dot [.] operator.

2. (.) is called as “Structure member Operator”.

3. Use this Operator in between “Structure name” & “member name”.

#include<stdio.h>
struct stud
{

char name[20];
char fname[10];
};

struct stud s;
main()
{

scanf("%s%s",&s.name,&s.fname);
printf("%s%s",s.name,s.fname);
}

Output:
Vedha
srinivas
Vedhasrinivas

struct employee
{
char name[100];
int age;
float salary;
char department[50];

} employee_one = {"Jack", 30, 1234.5, "Sales"};

int age = employee_one.age;

float salary= employee_one.salary;

char department= employee_one.department;

ACCESSING ARRAY OF STRUCTURE ELEMTS

STRUCT STUD
{
Datatype member1;
Datatype member2;
.
.
} struct stud s[50];

Members of structures are accessed through dot operator. Eg:


stud[i].memeber1 Stud[i].member2

#include<stdio.h>
struct stud
{
char name[20];

};

struct stud s[10];


main()
{

int i,n;
for(i=0;i<2;i++)
{

scanf("%s",&s[i].name);

printf("%s",s[i].name);

Output:
Swapna
Divya
Swapna
divya
Nested Structures

A structure can be nested inside another structure. In other words, the members of a
structure can be of any other type including structure.
Here is the syntax to create nested structures.

structure tagname_1
{
member1; member2; member3;...
Member n; structure tagname_2

{
member_1; member_2; member_3;...
member_n;
}, var1
} var2;

To access the members of the inner structure, we write a variable name of the outer structure, followed
by a dot(.) operator, followed by the variable of the inner structure, followed by a dot(.) operator, which
is then followed by the name of the member we want to access.

var2.var1.member_1 - refers to the member_1 of structure tagname_2


var2.var1.member_2 - refers to the member_2 of structure tagname_2

Let's take an example:

struct student
{
struct person

{
char name[20];
int age;

char dob[10];

}p;
int rollno;

float marks;

} stu;
Here we have defined structure person as a member of structure student. Here is how we can access
the members of person structure.

stu.p.name - refers to the name of the person

stu.p.age - refers to the age of the person stu.p.dob -

refers to the date of birth of the person

It is important to note that structure person doesn't exist on its own. We can't declare structure variable
of type struct person anywhere else in the program.

Instead of defining the structure inside another structure. We could have defined it outside and then
declare it's variable inside the structure where we want to use it. For example:

struct person
{
char name[20];
int age;
char dob[10];
};

We can use this structure as a part of a bigger structure

struct student

{
struct person info;

int rollno;

float marks;

Here the first member is of type struct person. If we use this method of creating nested structures then you
must first define the structures before creating variables of its types. So, it's mandatory for you to first
define person structure before using it's variable as a member of the structure student.

The advantage of using this method is that now we can declare a variable of type struct person in
anywhere else in the program.
Initializing nested Structures

Nested structures can be initialized at the time of declaration. For example:

struct person
{
char name[20]; int age; char dob[10];
};
struct student
{
struct person info; int rollno; float
marks[10];
}
struct student student_1 = {{"Adam", 25,1990},101,90};

The following program demonstrates how we can use nested structures.

#include<stdio.h>
struct person
{
char name[20];
int age;
char dob[10];
};

struct student
{
struct person info; int roll_no; float marks;
};

int main()
{
struct student s1;
printf("Details of student: \n\n");
printf("Enter name: "); scanf("%s", s1.info.name);
printf("Enter age: "); scanf("%d", &s1.info.age);
printf("Enter dob: "); scanf("%s", s1.info.dob);
printf("Enter roll no: "); scanf("%d", &s1.roll_no);
printf("Enter marks: "); scanf("%f", &s1.marks);
printf("\n*******************************\n\n");
printf("Name: %s\n", s1.info.name);
printf("Age: %d\n", s1.info.age);
printf("DOB: %s\n", s1.info.dob); printf("Roll no:%d\n", s1.roll_no); printf("Marks: %.2f\n",
s1.marks);
signal to operating system program ran fine return 0;
}
Need of array of structures:
Structure is collection of different data type. An object of structure represents a single record in memory,
if we want more than one record of structure type, we have to create an array of structure or object. As we
know, an array is a collection of similar type, therefore an array can be of structure type.
Structure is used to store the information of One particular object but if we need to store such 100 objects
then Array of Structure is used.

Syntax

Struct struct-name
{
datatype var1;
datatype var2;

datatype varN
};
Struct struct-name obj[size]

Initializing Array of Structure:

Array elements are stored in consecutive memory Location. Like Array , Array of Structure can
be initialized at compile time.

Way1 : Initializing After Declaring Structure Array :

struct Book

{
char bname[20];

int pages;

char author[20];

float price;

}b1[3] = {{"Let us C",700,"YPK",300.00},

{"Wings of Fire",500,"APJ AbdulKalam",350.00},

{"Complete C",1200,"HerbtSchildt",450.00}

};
Explanation:

As soon as after declaration of structure we initialize structure with the pre-defined values. For each
structure variable we specify set of values in curly braces. Suppose we have 3 Array Elements then we have
to initialize each array element individually and all individual sets are combined to form single set.

{"Let us C",700,"YPK",300.00}

Above set of values are used to initialize first element of the array. Similarly –

{"Wings of Fire",500,"APJ Abdul Kalam",350.00} is

used to initialize second element of the array.

Way 2 : Initializing in Main

struct Book

char bname[20];

int pages;

char author[20];

float price;

};

void main()

struct Book b1[3] = {{"Let us C",700,"YPK",300.00},

{"Wings of Fire",500,"AbdulKalam",350.00},

{"Complete C",1200,"HerbtSchildt",450.00}

};

}
C Program on book details using array of structures:

#include <stdio.h>
struct Bookinfo
{
char[20] bname;
int pages;
int price;
}book[3];
int main(int argc, char *argv[])
{
int i;
for(i=0;i<3;i++)
{
printf("\nEnter the Name of Book: ");
gets(book[i].bname);
printf("\nEnter the Number of Pages : ");
scanf("%d",book[i].pages);
printf("\nEnter the Price of Book : ");
scanf("%f",book[i].price);
}
printf("\n--------- Book Details ------------------ ");
for(i=0;i<3;i++)
{
printf("\nName of Book : %s",book[i].bname);
printf("\nNumber of Pages : %d",book[i].pages);
printf("\nPrice of Book : %f",book[i].price);
}
return 0;
}
Some Observations and Important Points:

Tip #1 : All Structure Members need not be initialized

#include<stdio.h>

struct Book

char bname[20];

int pages;

char author[20];

float price;

}b1[3] = {

{"Book1",700,"YPK"},

{"Book2",500,"AAK",350.00},

{"Book3",120,"HST",450.00}

};

void main()

printf("\nBook Name: %s",b1[0].bname);

printf("\nBook Pages : %d",b1[0].pages);

printf("\nBook Author : %s",b1[0].author);

printf("\nBook Price : %f",b1[0].price);

In this example , While initializing first element of the array we have not specified the price of book 1.It
is not mandatory to provide initialization for all the values. Suppose we have 5 structure elements and we
provide initial values for first two element then we cannot provide initial values to remaining elements.
{"Book1",700,,90.00}

above initialization is illegal and can cause compile time error. Tip #2 :

Default Initial Value

struct Book

char bname[20];

int pages;

char author[20];

float price;

}b1[3] = {

{},

{"Book2",500,"AAK",350.00},

{"Book3",120,"HST",450.00}

};

Output :

Book Name :

Book Pages : 0 Book

Author :

Book Price : 0.000000

Structures and functions

In C, structure can be passed to functions by two methods:

1.Passing by value (passing actual value as argument)

2.Passing by reference (passing address of an argument)


Passing structure by value

A structure variable can be passed to the function as an argument as a normal variable.

If structure is passed by value, changes made to the structure variable inside the function
definition does not reflect in the originally passed structure variable.

C program to create a structure student, containing name and roll and display the information.

#include <stdio.h>
struct student
{
char name[50];
int roll;
};
void display(struct student stu);
int main()
{
struct student stud;
printf("Enter student's name: ");
scanf("%s", &stud.name);
printf("Enter roll number:");
scanf("%d", &stud.roll);
display(stud); // passing structure variable stud as argument return 0;
}
void display(struct student stu){
printf("Output\nName: %s",stu.name);
printf("\nRoll: %d",stu.roll);

Output :
Enter student's name: Raju
Enter roll number: 48
Name: Raju
Roll : 48

Passing structure by reference

The memory address of a structure variable is passed to function while passing it by reference. If structure
is passed by reference, changes made to the structure variable inside function definition reflects in the
originally passed structure variable.

C program to add two distances and display the result without the return statement.

#include <stdio.h>
struct distance
{
int feet;
float inch;
};
void add(struct distance d1,struct distance d2, struct distance *d3);
int main()
{
struct distance dist1, dist2, dist3;
printf("First distance\n");
printf("Enter feet: ");
scanf("%d", &dist1.feet);
printf("Enter inch: ");
scanf("%f", &dist1.inch);
printf("Second distance\n");
printf("Enter feet: ");
scanf("%d", &dist2.feet);
printf("Enter inch: ");
scanf("%f", &dist2.inch);
add(dist1, dist2, &dist3);
printf("\nSum of distances = %d\'-%.1f\"", dist3.feet, dist3.inch);
return 0;
}
void add(struct distance d1,struct distance d2, struct distance *d3)
{
d3-> feet = d1.feet + d2.feet;
d3-> inch = d1.inch + d2.inch;
if (d3->inch >= 12)
{
d3->inch -= 12;
++d3->feet;
}
}

Output:

First distance
Enter feet: 12
Enter inch: 6.8
Second distance
Enter feet: 5
Enter inch: 7.5
Sum of distances = 18'-2.3"
Structure and Pointer
Structures can be created and accessed using pointers. A pointer variable of a structure can be created as below:

struct name
{
member1;
member2;
.
.
.
};

int main()
{
struct name *ptr;
}

Here, the pointer variable of type struct name is created.

Accessing structure's member through pointer

A structure's member can be accesssed through pointer in two ways:

Referencing pointer to another address to access memory


Using dynamic memory allocation

1. Referencing pointer to another address to access the memory

Consider an example to access structure's member through pointer.

#include<stdio.h>

typedef struct person


{
int age;
float weight;
};

int main()
{
struct person *personPtr, person1;
personPtr = &person1; // Referencing pointer to memory address of person1
printf("Enterinteger: ");
scanf("%d",&(*personPtr).age);
printf("Enter number: ");
scanf("%f",&(*personPtr).weight);
printf("Displaying: ");
printf("%d%f",(*personPtr).age,(*personPtr).weight);
return 0;
}

In this example, the pointer variable of type struct person is referenced to the address of person1. Then,
only the structure member through pointer can can accessed.

Using -> operator to access structure pointer member

Structure pointer member can also be accessed using -> operator.

(*personPtr).age is same as personPtr->age

(*personPtr).weight is same as personPtr->weight

2. Accessing structure member through pointer using dynamic memory allocation

To access structure member using pointers, memory can be allocated dynamically using malloc()
function defined under "stdlib.h" header file.

Syntax to use malloc()


ptr = (cast-type*) malloc(byte-size)

Example to use structure's member through pointer using malloc() function.

#include<stdio.h>
#include<stdlib.h>
struct person {
int age;
float weight;
char name[30];
};
int main()
{
struct person *ptr;
int i, num;
printf("Enter number of persons: ");
scanf("%d", &num);
ptr = (struct person*) malloc(num * sizeof(struct person));

// Above statement allocates the memory for n structures with pointer personPtr pointing to base
address */ for(i = 0; i < num; ++i)
{
printf("Enter name, age and weight of the person respectively:\n"); scanf("%s%d%f", &(ptr+i)-
>name, &(ptr+i)->age, &(ptr+i)->weight);
}
printf("Displaying Infromation:\n");
for(i = 0; i < num; ++i)
printf("%s\t%d\t%.2f\n", (ptr+i)->name, (ptr+i)->age, (ptr+i)->weight);
return 0;
}

Output

Enter number of persons: 2


Enter name, age and weight of the person respectively:
Adam

2
3.2

Enter name, age and weight of the person respectively: Eve 6

2.3

Displaying Information:

Adam 2 3.20
Eve 6 2.30

In C, structure can be passed to functions by two methods:

 Passing by value (passing actual value as argument)

 Passing by reference (passing address of an argument)

Passing structure by value

A structure variable can be passed to the function as an argument as a normal variable.

If structure is passed by value, changes made to the structure variable inside the function
definition does not reflect in the originally passed structure variable.

C program to create a structure student, containing name and roll and display the information.

#include <stdio.h>
struct student
{
char name[50];
int roll;
};

void display(struct student stu);

// function prototype should be below to the structure declaration otherwise compiler shows error
int main()
{
struct student stud;
printf("Enterstudent's name: ");
scanf("%s",&stud.name);
printf("Enter rollnumber:");
scanf("%d",&stud.roll);
display(stud); // passing structure variable stud as argument return 0;
}
void display(struct student stu){
printf("Output\nName: %s",stu.name);
printf("\nRoll: %d",stu.roll);
}

Output

Enter student's name: Kevin Amla


Enter roll number: 149

Output

Name: Kevin Amla


Roll: 149

Passing structure by reference

The memory address of a structure variable is passed to function while passing it by reference.

If structure is passed by reference, changes made to the structure variable inside function
definition reflects in the originally passed structure variable.

C program to add two distances (feet-inch system) and display the result without the return
statement.

#include <stdio.h>
struct distance
{
int feet;
float inch;
};

void add(struct distance d1,struct distance d2, struct distance *d3);


int main()
{
struct distance dist1, dist2, dist3;
printf("First distance\n");
printf("Enter feet: ");
scanf("%d", &dist1.feet);
printf("Enter inch: ");
scanf("%f", &dist1.inch);
printf("Second distance\n");
printf("Enter feet: ");
scanf("%d", &dist2.feet);
printf("Enter inch: ");
scanf("%f", &dist2.inch);
add(dist1, dist2, &dist3);

//passing structure variables dist1 and dist2 by value whereas passing structure variable dist3 by
reference

printf("\nSum of distances = %d\'-%.1f\"", dist3.feet, dist3.inch);

return 0;
}
void add(struct distance d1,struct distance d2, struct distance *d3)
{

//Adding distances d1 and d2 and storing it in d3 d3-

>feet = d1.feet + d2.feet;

d3->inch = d1.inch + d2.inch;

if (d3->inch >= 12) { /* if inch is greater or equal to 12, converting it to feet. */ d3-
>inch -= 12;
++d3->feet;
}
}
Output

First distance
Enter feet: 12
Enter inch: 6.8

Second distance Enter


feet: 5
Enter inch: 7.5

Sum of distances = 18'-2.3"

In this program, structure variables dist1 and dist2 are passed by value to the addfunction
(because value of dist1 and dist2 does not need to be displayed in main function).

But, dist3 is passed by reference ,i.e, address of dist3 (&dist3) is passed as an argument.

Due to this, the structure pointer variable d3 inside the add function points to the address of dist3
from the calling main function. So, any change made to the d3 variable is seen in dist3 variable
in main function.

As a result, the correct sum is displayed in the output.

Self Referential Structures:

Self referential structures contain a pointer member that points to a structure of the same
structure type.
In other words, a self-referential C structure is the one which includes a pointer to an instance
of itself.

Syntax of Self-Referential Structure in C Programming

struct demo
{
Data_type member1, member2;
struct demo *ptr1, *ptr2;
}
As you can see in the syntax, ptr1 and ptr2 are structure pointers that are pointing to the structure
demo, so structure demo is a self referential structure. These types of data structures are helpful
in implementing data structures like linked lists and trees.

It is an error to use a structure variable as a member of its own struct type structure or union type
union, respectively.

Self Referential Structure Example

struct node
{
int data;
struct node *nextPtr;
}

nextPtr

 is a pointer member that points to a structure of the same type as the one being declared.
 is referred to as a link. Links can tie one node to another node.

The concept of linked lists, stacks, queues, trees and many others works on the principle
of self-referential structures.
One important point worth noting is that you cannot reference the typedef that you create within
the structure itself in C programming.

An example of Self-Referential Structure in C

#include<stdio.h>
#include<stdlib.h>-
struct node //structure of the node in the list
{
int info;
struct node * link;
};
int main()
{
int choice;
typedef struct node NODE;
NODE *PTR, *START;
START = NULL;//Initialising START to NULL
while(1)
{
printf("\n1.Enter the new node at the start\n");
printf("2.Display the elements of the list\n");
printf("3.Exit\n");
printf("Enter Choice\n");
scanf("%d",&choice);
switch(choice)
{
case 1:PTR = (NODE*)malloc(sizeof(NODE)); //Allocating Memory to new node
printf("Enter the number you want to enter at the start\n");
scanf("%d",&PTR->info);
if(START == NULL)
{
START = PTR;
PTR->link = NULL;
}
else
{
PTR->link = START;
START = PTR;
}
break;
case 2:PTR = START;
printf("The elements in the list are::\n");
while(PTR->link != NULL)
{
printf("%d\t",PTR->info);
PTR = PTR->link;
}
printf("%d",PTR->info);
break;
case 3:exit(1);
break;
default: printf("\nEnter Valid Choice");
}
}
return 0;
}

Unions in C Language
Unions are conceptually similar to structures. The syntax to declare/define a union is also similar to that
of a structure. The only differences is in terms of storage. In structure each member has its own storage
location, whereas all members of union uses a single shared memory location which is equal to the size
of its largest data member.
#include<stdio.h>
struct student
{
char sname[20];
char fname[50];
int marks;
}s;

main()
{
printf("size of union=%d",sizeof(union student));
}

Output:size of union =50


Maximum size of the variable is the size of union so its size is 50.

This implies that although a union may contain many members of different types, it cannot
handle all the members at the same time. A union is declared using the union keyword.

union item
{
int m; float
x; char c;
}It1;
This declares a variable It1 of type union item. This union contains three members each with a
different data type. However only one of them can be used at a time. This is due to the fact that
only one location is allocated for all the union variables, irrespective of their size. The compiler
allocates the storage that is large enough to hold the largest variable type in the union.

In the union declared above the member x requires 4 bytes which is largest amongst the members
for a 16-bit machine. Other members of union will share the same memory address.

Accessing a Union Member

Syntax for accessing any union member is similar to accessing structure members,

union test
{
int a;
float b;
char c;
}t;

t.a; //to access members of union t


t.b;
t.c;

Time for an Example

#include <stdio.h>

union item
{
int a;
float b;
char ch;
};

int main( )
{

union item it; it.a=12;

it.b = 20.2;
it.ch = 'z';

printf("%d\n", it.a);
printf("%f\n", it.b);
printf("%c\n", it.ch);

return 0;
}

output
-26426
20.1999

As you can see here, the values of a and b get corrupted and only variable c prints the expected result. This
is because in union, the memory is shared among different data types. Hence, the only member whose value
is currently stored will have the memory.

In the above example, value of the variable c was stored at last, hence the value of other variables is lost.

Bit fields

Suppose your C program contains a number of TRUE/FALSE variables grouped in a structure


calle status, as follows:

struct
{
unsigned int
widthValidated;
unsigned int
heightValidated;
} status;

This structure requires 8 bytes of memory space but in actual we are going to store either 0 or 1
in each of the variables. The C programming language offers a better way to utilize the memory
space in such situation. If you are using such variables inside a structure then you can define the
width of a variable which tells the C compiler that you are going to use only those number of
bytes. For example, above structure can be re-written as follows:

struct
{
unsigned int
widthValidated : 1;
unsigned int
heightValidated :
1;
} status
Now, the above structure will require 4 bytes of memory space for status variable but only 2 bits will be
used to store the values. If you will use up to 32 variables each one with a width of 1 bit , then also status
structure will use 4 bytes, but as soon as you will have 33 variables, then it will allocate next slot of the
memory and it will start using 8 bytes. Let us check the following example to understand the concept:

#include <stdio.h>
#include <string.h>
/* define sim ple structure * / struct
{
unsigned int widthValidated;
unsigned int heightValidated;
} status1;
/* define a structure with bit fields * / struct
{
unsigned int widthValidated : 1;
unsigned int heightValidated : 1;
} status2;
int m ain( )
{
printf( "Mem ory size occupied by status1 : %d\n", sizeof(status1));
printf( "Mem ory size occupied by status2 : %d\n", sizeof(status2));
return 0;
}

When the above code is compiled and executed, it produces the above result:

Memory size occupied by status1 : 8


Memory size occupied by status2 : 4

Bit Field Declaration

The declaration of a bit-field has the form inside a structure:

struct
{
type [member_name] : width ;
};

Below the description of variable elements of a bit field:


Elements Description

type An integer type that determines how the bit-field's value is

interpreted. The type may be int, signed int, unsigned int.

member_name The name of thebit-field.

width The number of bits in the bit-field. The width must be less than
or equal to the bit width of the specified type.

The variables defined with a predefined width are called bit fields. A bit field can hold more than
a single bit for example if you need a variable to store a value from 0 to 7 only then you can
define a bit field with a width of 3 bits as follows:

struct
{
unsigned int age :3;
} Age;

The above structure definition instructs C compiler that age variable is going to use only 3 bits to
store the value, if you will try to use more than 3 bits then it will not allow you to do so.

Let us try the following example:

#include <stdio.h>
#include <string.h>
struct
{
unsigned int age : 3;
} Age;
int m ain( )
{
Age.age = 4;
printf( "Sizeof( Age ) : %d\n", sizeof(Age) );
printf( "Age.age : %d\n",Age.age );
Age.age = 7;
printf( "Age.age : %d\n", Age.age );
Age.age = 8;
printf( "Age.age : %d\n", Age.age );
return 0;
}
When the above code is compiled it will compile with warning and when executed, it produces
the following result:

Sizeof( Age) :4
Age.age : 4
Age.age : 7
Age.age : 0

Typedef:

The C programming language provides a keyword called typedef, which you can use to give a
type, a new name.

Syntax:

typedef data_type new_name;

typedef: It is a keyword.
data_type: It is the name of any existing type or user defined type created using structure/union.
new_name: alias or new name you want to give to any existing type or user defined type.

Following is an example to define a term BYTE for one-byte numbers − typedef unsigned char
BYTE;

After this type definition, the identifier BYTE can be used as an abbreviation for the type
unsigned char, for example..

BYTE b1, b2;

By convention, uppercase letters are used for these definitions to remind the user that the type
name is really a symbolic abbreviation, but you can use lowercase, as follows −

typedef unsigned char byte;

You can use typedef to give a name to your user defined data types as well. For example, you
can use typedef with structure to define a new data type and then use that data type to define
structure variables directly as follows −

#include <stdio.h>
#include <string.h>
typedef struct Books {
char title[50];
char author[50];
char subject[100];
int book_id;
} Book;
int main( )
{
Book book;
strcpy( book.title, "C Programming");
strcpy( book.author, "Nuha Ali");
strcpy( book.subject, "C Programming Tutorial");
book.book_id = 6495407;
printf( "Book title : %s\n", book.title);
printf( "Book author : %s\n",book.author);
printf( "Book subject : %s\n", book.subject);
printf( "Book book_id : %d\n", book.book_id);
return 0;
}

OUTPUT:
Book title : C Programming Book
author : Nuha Ali
Book subject : C Programming Tutorial Book
book_id : 6495407

Structures with typedef:

Consider the following student structure

struct student
{

int mark [2];

char name [10];

float average;

Variable for the above structure can be declared in two ways.


st
1 way :

struct student record; /* for normal variable */ struct


student *record; /* for pointer variable */

136
nd
2 way :

typedef struct student status;

When we use “typedef” keyword before struct <tag_name> like above, after that we can simply use type
definition “status” in the C program to declare structure variable. Now, structure variable declaration will
be, “status record”. This is equal to “struct student record”. Type definition for “struct student” is status.
i.e. status = “struct student”.

An Alternative Way for Structure Declaration Using Typedef in C:

typedef struct student


{
int mark [2];
char name [10];
float average;
} status;

To declare structure variable, we can use the below statements.

status record1; /* record 1 is structure variable */ status

record2; /* record 2 is structure variable */

// Structure using typedef:

#include <stdio.h>
#include <string.h>
typedef struct student
{
int id;
char name[20];
float percentage;
} status;
int main()
{
status record;
record.id=1;
strcpy(record.name, "Raju");
record.percentage = 86.5;
printf(" Id is: %d \n", record.id);
printf(" Name is: %s \n", record.name);
printf(" Percentage is: %f \n",
record.percentage);
return 0;
}
OUTPUT:

Id is: 1

Name is: Raju

Percentage is: 86.500000

Another Example

#include <stdio.h>
#include <limits.h>
int main()
{
typedef long long int LLI;
printf("Storage size for long long
int data " \"type : %ld \n", sizeof(LLI));
return 0;
}

OUTPUT: Storage size for long long int data type : 8

Enumeration data type:

An enumeration is a user-defined data type that consists of integral constants. To define an


enumeration, keyword enum is used.

Syntax:
enum flag {const1, const2,……constN};

Here, name of the enumeration is flag. Constants like const1, const2, .............. , constN are values
of type flag.

By default, const1 is 0, const2 is 1 and so on. You can change default values of enum elements
during declaration (if necessary).

// Changing the default value of enum elements enum

suit{

club=0;
diamonds=10;
hearts=20;
spades=3;

};
Declaration of enumerated variable

Above code defines the type of the data but, no any variable is created. Variable of type enum
can be created as:

enum boolean{ false;

true;

};

enum boolean check;

Here, a variable check is declared which is of type enum boolean.

Example of enumerated type

#include <stdio.h>
enum week{ sunday, monday, tuesday, wednesday, thursday, friday, saturday};
int main(){
enum week today;
today=wednesday;
printf("%d day",today+1);
return 0;
}

Output
4 day

Pointers

A pointer is a variable whose value is the address of another variable, i.e., direct address of the
memory location.

Like any variable or constant, you must declare a pointer before using it to store any variable
address.

The general form of a pointer variable declaration is

Datatype *variable_name

Asterisk(*)

Asterisk is called as Indirection Operator. It is also called as Value at address Operator


It Indicates Variable declared is of Pointer type. pointer_name must follow the rules of identifier.
Examples for different pointer declarations:

int *ip; /* pointer to an integer */

double *dp; /* pointer to a double */

float *fp; /* pointer to a float */

char *ch; /* pointer to a character */

Diff Between pointer and normal variable:

int *ptr; //Here ptr is Integer Pointer Variable


int ptr; //Here ptr is Normal Integer Variable Pointer

Overview: int i; int *j; j=&i;

Explanation:

i is the name given for particular memory location of ordinary variable.

Let us consider it‟s Corresponding address be 65624 and the Value stored in variable „i‟ is 5

The address of the variable „i‟ is stored in another integer variable whose name is „j‟ and which is
having corresponding address 65522

j = &i; i.e j = Address of i

Here j is not ordinary variable , It is special variable and called pointer variable as it stores the address
of the another ordinary variable. We can summarize it like –
Variable Name Variable Value Variable Address

i 5 65524

j 65524 65522

Pointer Basic Example:

#include
int main()

{
int *ptr, i; i = 11;
/* address of i is assigned to ptr */ ptr = &i;
/* show i's value using ptr variable */ printf("Value of i : %d", *ptr); return 0;
}

Output
You will get value of i = 11 in the above program.

Whitespace while Writing Pointer:

pointer variable name and asterisk can contain whitespace because whitespace is ignored by
compiler. int *ptr;

int * ptr;

int * ptr;

All the above syntax are legal and valid. We can insert any number of spaces or blanks
inside declaration. We can also split the declaration on multiple lines.

Pointer information:

When we declare integer pointer then we can only store address of integer variable into that pointer.
Similarly if we declare character pointer then only the address of character variable is stored into the
pointer variable.
Simple Pointer Example #1 :

#include<stdio.h> int main()


{
int a = 3; int *ptr; ptr = &a;
printf(“the value of is %d”, *ptr);
printf(“the value of a is %d”,a);
return(0);
}

Explanation of Example:

Point Variable 'a' Variable 'ptr'

Name of Variable a ptr

Type of Value that it holds Integer Address of Integer 'a'

Value Stored 3 2001

Address of Variable 2001 (Assumption) 4001 (Assumption)

Reference operator (&) and Dereference operator (*)

The operator, & is called reference operator. It gives you the address of a variable.

One more complement operator is dereference operator (*), that gets the value from the address
Program on Reference and Dereference operator

#include <stdio.h>
int main()
{
int* pc; int c; c=22;
printf("Address of c:%u\n",&c);
printf("Value of c:%d\n\n",c); pc=&c;
printf("Address of pointer pc:%u\n",pc);
printf("Content of pointer pc:%d\n\n",*pc);
c=11;
printf("Address of pointer pc:%u\n",pc);
printf("Content of pointer pc:%d\n\n",*pc);
*pc=2;
printf("Address of c:%u\n",&c);
printf("Value of c:%d\n\n",c);
return 0;
}

OUTPUT:

Address of c: 2686784
Value of c: 22

Address of pointer pc: 2686784

Content of pointer pc: 22

Address of pointer pc: 2686784


Content of pointer pc: 11

Address of c: 2686784

Value of c: 2D

Pointer Arithmetic
Pointer is a variable that points to a memory location. Memory addresses are numeric value that ranges
from zero to maximum memory size in bytes. These addresses can be manipulated like simple variables.
You can increment, decrement, calculate or compare these addresses manually.

C language provides a set of operators to perform arithmetic and comparison of memory addresses.
Pointer arithmetic and comparison in C is supported by following operators -

 Increment and decrement ++ and --


 Addition and Subtraction + and -
 Comparison <, >, <=, >=, ==, !=

Pointer increment and decrement

Increment operator when used with a pointer variable returns next address pointed by the pointer. The
next address returned is the sum of current pointed address and size of pointer data type.

Or in simple terms, incrementing a pointer will cause the pointer to point to a memory location
skipping Nbytes from current pointed memory location. Where N is size of pointer data type.

Similarly, decrement operator returns the previous address pointed by the pointer. The returned address is
the difference of current pointed address and size of pointer data type.

For example, consider the below statements.


int num = 5; // Suppose address of num = 0x1230
int *ptr; // Pointer variable

ptr = &num; // ptr points to 0x1230 or ptr points to num


ptr++; // ptr now points to 0x1234, since integer size is 4 bytes
ptr--; // ptr now points to 0x1230

Example program to perform pointer increment and decrement

Array in memory are stored sequentially, hence is the best example to demonstrate pointer
increment, decrement operations.

#include <stdio.h>
#define SIZE 5

int main()
{
int arr[SIZE] = {10, 20, 30, 40, 50};
int *ptr;
int count;

ptr = &arr[0]; // ptr points to arr[0]

count = 0;

printf("Accessing array elements using pointer \n");


while(count < SIZE)
{
printf("arr[%d] = %d \n", count, *ptr);

// Move pointer to next array element


ptr++;

count++;
}

return 0;

Output -

arr[0] = 10
arr[1] = 20
arr[2] = 30
arr[3] = 40
arr[4] = 50
Pointer addition and subtraction

Pointer increment operation increments pointer by one. Causing it to point to a memory location
skipping N bytes (where N is size of pointer data type).

We know that increment operation is equivalent to addition by one. Suppose an integer pointer
int * ptr. Now, ptr++ is equivalent to ptr = ptr + 1. Similarly, you can add or subtract any integer
value to a pointer.

Adding K to a pointer causes it to point to a memory location skipping K * N bytes. Where K is


a constant integer and N is size of pointer data type.

Let us revise the above program to print array using pointer.

#include <stdio.h>
#define SIZE 5

int main()
{
int arr[SIZE] = {10, 20, 30, 40, 50};
int *ptr;
int count;

ptr = &arr[0]; // ptr points to arr[0]

count = 0;

printf("Accessing array elements using pointer \n");


while(count < SIZE)
{
printf("arr[%d] = %d \n", count, *(ptr + count));

count++;
}

return 0;

 When count = 0, (ptr + count) is equivalent to (ptr + 0) which points to arr[0] and hence
prints 10.
 When count = 1, (ptr + count) is equivalent to (ptr + 1) which points to arr[1] and hence
prints 20.
 Similarly when count = 4, (ptr + count) is equivalent to (ptr + 4) which points
to arr[4]and hence prints 50.
Output of above program is same as first program.

Pointer comparison

In C, you can compare two pointers using relational operator. You can perform six different type
of pointer comparison <, >, <=, >=, == and !=.

Note: Pointer comparison compares two pointer addresses to which they point to, instead of
comparing their values.

Pointer comparisons are less used when compared to pointer arithmetic. However, I frequently
use pointer comparison when dealing with arrays.

Pointer comparisons are useful,

 If you want to check if two pointer points to same location. For example,

int main()
{
int num = 10;
int *ptr1 = &num ; // ptr1 points to num
int *ptr2 = &num ; // ptr2 also points to num

if(ptr1 == ptr2)
{
// Both pointers points to same memory location
// Do some task
}

return 0;
}

 If you want to check if a pointer points within an array range. For example,
int main()
{
int arr[5] = {10, 20, 30, 40, 50};
int *ptr = &arr[0]; // ptr points to arr[0]

while(ptr <= &arr[4])


{
// ptr will always point within the array
// Do some task
// Move ptr to next array element
ptr++;
}

return 0;

Pointer to pointer

Pointers are used to store the address of other variables of similar datatype. But if you want to store
the address of a pointer variable, then you again need a pointer to store it. Thus, when one pointer
variable stores the address of another pointer variable, it is known as Pointer to Pointer variable
or Double Pointer.

Syntax:
int **p1;

Here, we have used two indirection operator(*) which stores and points to the address of a pointer
variable i.e, int *. If we want to store the address of this (double pointer) variable p1, then the syntax
would become:
int ***p2;

Simple program to represent Pointer to a Pointer

#include <stdio.h>
int main()
{
int a = 10;
int *p1; //this can store the address of variable a
int **p2;
/*
this can store the address of pointer variable p1 only.
It cannot store the address of variable 'a'
*/
p1 = &a;
p2 = &p1;
printf("Address of a = %u\n", &a);
printf("Address of p1 = %u\n", &p1);
printf("Address of p2 = %u\n\n", &p2);

// below print statement will give the address of 'a'


printf("Value at the address stored by p2 = %u\n", *p2);
printf("Value at the address stored by p1 = %d\n\n", *p1);
printf("Value of **p2 = %d\n", **p2); //read this *(*p2)
/*
This is not allowed, it will give a compile time error-
p2 = &a;
printf("%u", p2);
*/
return 0;
}

Output

Address of a = 2686724
Address of p1 = 2686728
Address of p2 = 2686732
Value at the address stored by p2 = 2686724
Value at the address stored by p1 = 10
Value of **p2 = 10
Explanation of the above program

 p1 pointer variable can only hold the address of the variable a (i.e Number of indirection

operator(*)-1 variable). Similarly, p2 variable can only hold the address of variable p1. It cannot
hold the address of variable a.
 *p2 gives us the value at an address stored by the p2 pointer. p2 stores the address of p1pointer

and value at the address of p1 is the address of variable a. Thus, *p2 prints address of a.

 **p2 can be read as *(*p2). Hence, it gives us the value stored at the address *p2. From above

statement, you know *p2 means the address of variable a. Hence, the value at the address *p2 is

10. Thus, **p2 prints 10.

Generic pointers

A Generic pointer is a special pointer that can point to object of any type. A Generic pointer is
typeless pointer also known as void pointer. void pointer is an approach towards generic
functions and generic programming in C.

Note: Writing programs without being constrained by data type is known as generic
programming. A generic function is a special function that focuses on logic without confining to
data type. For example, logic to insert values in array is common for all types and hence can be
transformed to generic function.

Syntax to declare void or Generic pointer


void * pointer-name;

Example to declare void or Generic pointer

void * vPtr;
How to dereference a void or Generic pointer

Dereferencing is the process of retrieving data from memory location pointed by a pointer. It
converts block of raw memory bytes to a meaningful data (data is meaningful if type is
associated).
While dereferencing a void or Generic pointer, the C compiler does not have any clue about
type of value pointed by the void pointer. Hence, dereferencing a void pointer is illegal in C.
But, a pointer will become useless if you cannot dereference it back.

To dereference a void pointer you must typecast it to a valid pointer type.

Example to dereference a void or Generic pointer


int num = 10;
void * vPtr = &num; // void pointer pointing at num int
value = *((int *) vPtr); // Dereferencing void pointer

void or Generic pointer arithmetic

void or Generic pointer arithmetic is illegal in C programming, due to the absence

of type. However, some compiler supports void pointer arithmetic by assuming it as


a char pointer. To perform pointer arithmetic on void pointer you must first typecast

to other type.

Example of void or Generic pointer arithmetic

int arr[] = {10, 20, 30, 40, 50};


void * vPtr = &arr; // void pointer pointing at arr
vPtr = ((int *) vPtr + 1); // add 1 to void pointer

Example program to use void pointer

Write a C function to accept an array and print its elements. The function must accept array of
different types

/**C program to demonstrate void pointer */


#include <stdio.h>
#define SIZE 10
/* Function declaration */
void printArray(void * vPtr, int size, int type);
int main()
{
int num[SIZE] = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
float fractional[SIZE] = {1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, 1.7f, 1.8f, 1.9f, 2.0f}; char
characters[SIZE] = {'C', 'o', 'd', 'e', 'f', 'o', 'r', 'w', 'i', 'n'}; printf("\nElements of integer array: ");
printArray(&num, SIZE, 1);
printf("\nElements of float array: ");
printArray(&fractional, SIZE, 2);
printf("\nElements of character array: ");
printArray(&characters, SIZE, 3);
return 0;
}
/**
*Function to print array of different types.
*@vPtr Pointer to an array
*@size Size of the array
*@type Integer value specifying type of array. 1 - Integer,
*2 - Float,
*3 - Character
*/
void printArray(void * vPtr, int size, int type)
{
int i;
for(i=0; i<size; i++)
{
//Print array elements based on their type switch(type)
{
case 1:
/* Typecast void pointer to integer then print
*/ printf("%d, ", *((int *)vPtr + i)); break;
case 2:
/* Typecast void pointer to float then print */ printf("%f, ", *((float *)vPtr + i));
break; case 3:
/* Typecast void pointer to char then print */ printf("%c, ", *((char *)vPtr + i));
break;
}
}
}

Output:
Elements of integer array: 10, 20, 30, 40, 50, 60, 70, 80, 90, 100,
Elements of float array: 1.100000, 1.200000, 1.300000, 1.400000, 1.500000, 1.600000,1.700000,
1.800000, 1.900000, 2.000000,
Elements of character array: C, o, d, e, f, o, r, w, i, n
while not end of file and array not exhausted, read a string store it in an array of strings and assign
the string to an element of a pointer array access the array of strings and print them out access the
array of pointers .

Arrays and Pointers

Arrays and pointers are closely related in C. In fact an array declared as int A[10];

can be accessed using its pointer representation. The name of the array A is a constant pointer to
the first element of the array. So A can be considered a const int*. Since A is a constant pointer,
A = NULL would be an illegal statement. Arrays and pointers are synonymous in terms of how
they use to access memory. But, the important difference between them is that, a pointer variable
can take different addresses as value whereas, in case of array it is fixed.

Consider the following array:

int age[5];

In C , name of the array always points to the first element of an array. Here, address of first element
of an array is &age[0]. Also, age represents the address of the pointer where it is pointing. Hence,
&age[0] is equivalent to age. Note, value inside the address &age[0] and address age are equal.
Value in address &age[0] is age[0] and value in address age is *age. Hence, age[0] is equivalent to
*age.

C arrays can be of any type. We define array of ints, chars, doubles etc. We can also define an array
of pointers as follows. Here is the code to define an array of n char pointers or an array of strings.

char* A[n];

each cell in the array A[i] is a char* and so it can point to a character. Now if you would like to
assign a string to each A[i] you can do something like this.

A[i] = malloc(length_of_string + 1);


Again this only allocates memory for a string and you still need to copy the characters into this
string. So if you are building a dynamic dictionary (n words) you need to allocate memory for n
char*‟s and then allocate just the right amount of memory for each string.

In C, you can declare an array and can use pointer to alter the data of an array. This program declares
the array of six element and the elements of that array are accessed using pointer, and returns the
sum.

Program to find the sum of six numbers with arrays and pointers.

#include <stdio.h>
int main()
{
int i,class[6],sum=0;
printf("Enter 2 numbers:\n");
for(i=0;i<6;++i)
{

scanf("%d",(class+i)); // (class+i) is equivalent to &class[i]


sum+= *(class+i); // *(class+i) is equivalent to class[i]
}

printf("Sum=%d",sum);
return 0;
}
Output
Enter 2 numbers:
2
3
Pointer Array
A pointer is a place in memory that keeps address An array is a single, pre allocated chunk of
of another place inside contiguous elements (all of the same type), fixed
in size and location.
Allows us to indirectly access variables. In other Expression a[4] refers to the 5 th element of the
words, we can talk about its address rather than array a.
its value

Pointer can‟t be initialized at definition Array can be initialized at definition. Example

int num[] = { 2, 4, 5}
Pointer is dynamic in nature. The memory They are static in nature. Once memory is
allocation can be resized or freed later. allocated , it cannot be resized or freed
dynamically

Pointer Definition:

A pointer is a variable whose value is the address of another variable, i.e., direct address of the
memory location. Like any variable or constant, you must declare a pointer before using it to store
any variable address.

Function basics:

A function is a group of statements that together perform a task. Every C program has at least
one function, which is main(), and all the most trivial programs can define additional
functions.

A function declaration tells the compiler about a function's name, return type, and
parameters. A function definition provides the actual body of the function.

To call a function, you simply need to pass the required parameters along with the function
name, and if the function returns a value, then you can store the returned value.

Functions Parameter passing methods:

Call by value

This method 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.

Syntax: datatype function_name(datatype variable_name);

Call by reference:

This method copies the address of an argument into the formal parameter. Inside the function, the
address is used to access the actual argument used in the call. This means that changes made to the
parameter affect the argument.

Syntax: datatype function_name(datatype *variable_name);


Function example: Call by value

#include <stdio.h>
void swap(int i, int j)
{
int t;
t=i;
i=j;
j=t;
}
void main()
{
int a,b;
a=5;
b=10;
printf("%d %d\n", a, b);
swap(a,b);
printf("%d %d\n", a, b);
}

Analysis: When you execute this program, you will find that no swapping takes place. The values
of a and b are passed to swap, and the swap function does swap them, but when the function returns
nothing happens.

Function example: Call by reference:

#include <stdio.h>
void swap(int *i, int *j)
{
int t;
t = *i;
*i = *j;
*j = t;
}

void main()
{
int a,b;
a=5;
b=10;
printf("%d %d\n",a,b);
swap(&a,&b);
printf("%d %d\n",a,b);
}

Analysis: The above code uses *i and *j, it means a and b. When the function completes, a and b
have been swapped.
Passing Pointer to a Function:

When we pass a pointer as an argument instead of a variable then the address of the variable
is passed instead of the value. So any change made by the function using the pointer is
permanently made at the address of passed variable.

Example:1

#include <stdio.h>
void salaryhike(int *var, int b)
{
*var = *var+b;
}
int main()
{
int salary=0, bonus=0;
printf("Enter the employee current salary:");
scanf("%d", &salary);
printf("Enter bonus:");
scanf("%d", &bonus);
salaryhike(&salary, bonus);
printf("Final salary: %d", salary);
return 0;
}
OUTPUT:
Enter the employee
current salary:10000
Enter bonus:2000
Final salary: 12000

Example: 2

#include <stdio.h>
void swapnum(int *num1, int *num2)
{
int tempnum;

tempnum = *num1;
*num1 = *num2;
*num2 = tempnum;
}
int main( )
{
int v1 = 11, v2 = 77 ;
printf("Before swapping:");
printf("\nValue of v1 is: %d", v1);
printf("\nValue of v2 is: %d", v2);

/*calling swap function*/


swapnum( &v1, &v2 );

printf("\nAfter swapping:");
printf("\nValue of v1 is: %d", v1);
printf("\nValue of v2 is: %d", v2);
}
Output:
Before swapping:
Value of v1 is: 11
Value of v2 is: 77
After swapping:
Value of v1 is:77
Value of v2 is: 11

Functions of returning pointers

It is also possible for functions to return a function pointer as a value. This ability increases the
flexibility of programs. In this case you must be careful, because local variables of function doesn't
live outside the function. They have scope only inside the function. Hence if you return a pointer
connected to a local variable, that pointer will be pointing to nothing when the function ends.

Example of function pointers as returned values

#include <stdio.h>
int* larger(int*, int*);
void main()
{
int a = 15;
int b = 92;
int *p;
p = larger(&a, &b);
printf("%d is larger",*p);
}

int* larger(int *x, int *y)


{
if(*x > *y)
return x;
else
return y;
}
Note:
1. Either use argument with functions. Because argument passed to the functions are declared inside
the calling function, hence they will live outside the function as well.
2. Or, use static local variables inside the function and return them. As static variables have a
lifetime until the main() function exits, therefore they will be available throughoutthe program.

Pointer to functions

It is possible to declare a pointer pointing to a function which can then be used as an argument in
another function.
A pointer to a function is declared as follows,
type (*pointer-name)(parameter);
A function pointer can point to a specific function when it is assigned the name of that function.

int sum(int, int);


int (*s)(int, int);
s = sum;

Here s is a pointer to a function sum. Now sum can be called using function pointer s along with
providing the required argument values.

s (10, 20);

Example of Pointer to Function

#include <stdio.h>
int sum(int x, int y)
{
return x+y;
}
int main( )
{
int (*fp)(int, int);
fp = sum;
int s = fp(10, 15);
printf("Sum is %d", s);
return 0;
}

Out put: 25

Example function returning pointer

#include <stdio.h>
int* findLarger(int*, int*);
void main()
{
int numa=0;
int numb=0;
int *result;
printf("\n\n Pointer : Show a function returning pointer :\n");
printf(" \n");
printf(" Input the first number : ");
scanf("%d", &numa);
printf(" Input the second number : ");
scanf("%d", &numb);
result=findLarger(&numa, &numb);
printf(" The number %d is larger. \n\n",*result);
}
int* findLarger(int *n1, int *n2)
{
if(*n1 > *n2) return n1;
else
return n2;
}

Out put:
Pointer : Show a function returning pointer :

Input the first number : 5


Input the second number : 6
The number 6 is larger.
Preprocessor directives

The C preprocessor is a macro processor that is used automatically by the C compiler to transform
your program before actual compilation (Proprocessor direcives are executed before
compilation.). It is called a macro processor because it allows you to define macros, which are
brief abbreviations for longer constructs. A macro is a segment of code which is replaced by the
value of macro. Macro is defined by #define directive.

Preprocessing directives are lines in your program that start with #. The # is followed by an
identifier that is the directive name. For example, #define is the directive that defines a macro.
Whitespace is also allowed before and after the #.

The # and the directive name cannot come from a macro expansion. For example, if foo is defined
as a macro expanding to define, that does not make #foo a valid preprocessing directive.

All preprocessor directives starts with hash # symbol.

List of preprocessor directives :

1. #include
2. #define
3. #undef
4. #ifdef
5. #ifndef
6. #if
7. #else
8. #elif
9. #endif
10. #error
11. #pragma

1. #include

The #include preprocessor directive is used to paste code of given file into current file. It is
used include system- defined and user-defined header files. If included file is not found,
compiler renders error. It has three variants:
#include <file>

This variant is used for system header files. It searches for a file named file in a list of
directories specified by you, then in a standard list of system directories.
#include "file"

This variant is used for header files of your own program. It searches for a file named file first
in the current directory, then in the same directories used for system header files. The current
directory is the directory of the current input file.

#include anything else

This variant is called a computed #include. Any #include directive whose argument does not fit
the above two forms is a computed include.

2. Macro's (#define)

Let's start with macro, as we discuss, a macro is a segment of code which is replaced by the
value of macro. Macro is defined by #define directive.

Syntax

#define token value


There are two types of macros:

1. Object-like Macros
2. Function-like Macros

1. Object-like Macros

The object-like macro is an identifier that is replaced by value. It is widely used to represent
numeric constants. For example:

#define PI 3.1415
Here, PI is the macro name which will be replaced by the value 3.14. Let's see an example of
Object-like Macros
:

#include
<stdio.h>
#define PI
3.1415 main()
{ 100
Output:

3.14000

2. Function-like Macros

The function-like macro looks like function call. For example:

#define MIN(a,b) ((a)<(b)?(a):(b)

Here MIN is the macro name. Let's see an example of Function-like Macros :
#include <stdio.h>
#define MIN(a,b) ((a)<(b)?(a):(b))
void main()
{
printf("Minimum between 10 and 20 is: %d\n", MIN(10,20));
}
Output:
Minimum between 10 and 20 is: 10

Preprocessor Formatting

A preprocessing directive cannot be more than one line in normal circumstances. It may be
split cosmetically with Backslash-Newline. Comments containing Newlines can also divide
the directive into multiple lines.
for example, you can split a line cosmetically with Backslash-Newline anywhere:

is equivalent into #define FOO 1020.


3. #undef

To undefine a macro means to cancel its definition. This is done with the

#undef directive. Syntax:

#undef token
define and undefine example
#include <stdio.h>
#define PI 3.1415
#undef PI
main()
{ printf("%f",PI);
}
Output:

Compile Time Error: 'PI' undeclared

4. #ifdef

The #ifdef preprocessor directive checks if macro is defined by #define. If yes, it

executes the code.

Syntax:

#ifdef MACRO
//code
#endif

5. #ifndef

The #ifndef preprocessor directive checks if macro is not defined by #define. If yes, it

executes the code.

Syntax:

#ifndef MACRO
//code
#endif

6. #if

The #if preprocessor directive evaluates the expression or condition. If condition is true, it

executes the code.

Syntax:

#if expression
//code
#endif

7. #else

The #else preprocessor directive evaluates the expression or condition if condition of #if is
false. It can be used with #if, #elif, #ifdef and #ifndef directives.

102
Syntax:

#if expression
//if code
#else
//else code
#endif

Syntax with #elif

#if expression
//if code
#elif expression
//elif code
#else
//else code
#endif

8. #error

The #error preprocessor directive indicates error. The compiler gives fatal error if #error
directive is found and skips further compilation process.

C #error example

#include<stdio.h>
#ifndef MATH_H
#error First include then compile #else
void main(){ float a; a=sqrt(7);
printf("%f",a);
}
#endif

9. #pragma

The #pragma preprocessor directive is used to provide additional information to the compiler.
The #pragma directive is used by the compiler to offer machine or operating-system feature.
Different compilers can provide different usage of #pragma directive.

Syntax:
#pragma token

You might also like