PPS Unit-3
PPS Unit-3
Need of structures
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
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.
struct person
char name[50];
int citNo;
float salary;
};
This declaration above creates the derived data type struct person.
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
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.
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)
int main()
{
printf("1st distance\n");
// Input of feet for structure variable dist1 printf("Enter feet: ");
scanf("%d", &dist1.feet);
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
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.
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.
integer 0
float 0.00
char NULL
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;
};
Accessing StructureMembers
1. Array elements are accessed using the Subscript variable , Similarly Structure members
#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];
STRUCT STUD
{
Datatype member1;
Datatype member2;
.
.
} struct stud s[50];
#include<stdio.h>
struct stud
{
char name[20];
};
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.
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.
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];
};
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
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};
#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]
Array elements are stored in consecutive memory Location. Like Array , Array of Structure can
be initialized at compile time.
struct Book
{
char bname[20];
int pages;
char author[20];
float price;
{"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 –
struct Book
char bname[20];
int pages;
char author[20];
float price;
};
void main()
{"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:
#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()
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 :
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 :
Author :
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
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;
}
#include<stdio.h>
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.
To access structure member using pointers, memory can be allocated dynamically using malloc()
function defined under "stdlib.h" header file.
#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
2
3.2
2.3
Displaying Information:
Adam 2 3.20
Eve 6 2.30
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;
};
// 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
Output
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;
};
//passing structure variables dist1 and dist2 by value whereas passing structure variable dist3 by
reference
return 0;
}
void add(struct distance d1,struct distance d2, struct distance *d3)
{
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
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.
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.
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.
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.
#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));
}
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.
Syntax for accessing any union member is similar to accessing structure members,
union test
{
int a;
float b;
char c;
}t;
#include <stdio.h>
union item
{
int a;
float b;
char ch;
};
int main( )
{
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
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:
struct
{
type [member_name] : width ;
};
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.
#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: 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..
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 −
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
struct student
{
float average;
136
nd
2 way :
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”.
#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
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;
}
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).
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:
true;
};
#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.
Datatype *variable_name
Asterisk(*)
Explanation:
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
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
#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.
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 :
Explanation of Example:
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 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 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.
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;
count = 0;
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.
#include <stdio.h>
#define SIZE 5
int main()
{
int arr[SIZE] = {10, 20, 30, 40, 50};
int *ptr;
int count;
count = 0;
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.
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]
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;
#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);
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
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.
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 other type.
Write a C function to accept an array and print its elements. The function must accept array of
different types
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 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.
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.
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)
{
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
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.
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.
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.
#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.
#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);
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
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.
#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);
}
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.
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);
#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
#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 :
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.
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.
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
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
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:
To undefine a macro means to cancel its definition. This is done with the
#undef token
define and undefine example
#include <stdio.h>
#define PI 3.1415
#undef PI
main()
{ printf("%f",PI);
}
Output:
4. #ifdef
Syntax:
#ifdef MACRO
//code
#endif
5. #ifndef
The #ifndef preprocessor directive checks if macro is not defined by #define. If yes, it
Syntax:
#ifndef MACRO
//code
#endif
6. #if
The #if preprocessor directive evaluates the expression or condition. If condition is true, it
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
#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