UNIT I
INTRODUCTION
The basic data types in C are int, float and char. using these data
types, we can derive some other data types, the data types that are
derived from the basic data types are called derived data types.
We have already discussed three of the six derived types: arrays,
functions and pointers. In this unit, we discuss the three remaining
derived types: structure, union and enumerated. We will also discuss
the use of type definition and Bit field. The derived data types are
shown in Figure 0.
Figure 0 Derived Types in C
MRLIT N. RAENSH PNO: 1
1 STRUCTURES
We have seen that arrays can be used to represent a group of data
items that belong to the same type. However in real world, we often
deal with entities that are collection of dissimilar data items. Using
array variables we cannot store different items under one name. C
supports a derived data type known as structure, which is a method
for storing data of different types.
Structure Definition
A structure is a collection of logically related elements, possibly of
different types, having a single name.
Advantages
❖ Structures help to organize complex data in a more meaningful
way.
❖ Being able to manipulate several variables as a single group
makes your programs easier to manage.
❖ Business data processing uses the concepts of structures in
almost every program. Example, student database and employee
database management.
Good candidates for structures:
MRLIT N. RAENSH PNO: 2
Time: year, month, day, hour, minutes, second
Complex number: real part, imaginary part
Point in a 2-dimensional plane: x axis, y axis
1.1 DEFINITION OF STRUCTURES
As variables are defined before they use in the program, structures are
also defined and declared before they are used.
A structure definition forms a template that may be used to crate
structure objects. The variables that make up the structure are called
members of the structure.
A structure can be defined using three different ways,
❖ Tagged Structure
❖ Structure Variables
❖ Typedef Structure
Tagged Structure
The structure definition associated with the structure name is referred
as tagged structure. It does not create an instance of a structure and
Does not allocate any memory.
The general form or syntax of tagged structure definition is as follows,
MRLIT N. RAENSH PNO: 3
Where,
❖ struct is the keyword which tells the compiler that a
structure is being defined.
❖ Tag_name is the name of the structure.
❖ member1, member2 … are called members of the structure.
The members are declared within curly braces.
❖ The closing brace must end with the semicolon.
Example: student details using tagged structure
struct student
{
MRLIT N. RAENSH PNO: 4
char name [10];
int roll_number;
float avg_marks;
}; // no memory is allocated for the structure
Note the following points with respect to above structure definition,
❖ struct is the keyword which tells the compiler structure is being
defined.
❖ student is an identifier representing the structure name
(tag_name).
❖ name, roll_number and avg_marks are members of a structure
and are themselves are not variables. They do not occupy any
memory.
Memory is not reserved for the structure definition since no variables
are associated with the structure definition. The members of the
structure do not occupy any memory until they are associated with the
structure variables.
The declaration of the structure variable takes of the form,
where, struct is the keyword. Tag_name is the name of the structure.
Structure variables are separated by comma, followed by semicolon.
We can declare structure variables any where in the program.
MRLIT N. RAENSH PNO: 5
For the above example the variable declaration as follows,
struct student s1; // memory is allocated for the variable
now a variable of type struct student (derived type) is created, the
memory is allocated for the variable s1.
The following figure shows the memory organization for the above
example.
s1
Figure 1 Memory map for structure variable
The number of bytes allocated for the structure variable is the sum of
sizes of the individual members. In the above example the size of
s1=16 bytes (10+2+4).
Note: Normally, structure definition appears at the beginning of the
program file, before any variables or functions defined.
Structure Variables
Here we are combining both the template declaration and variable
declaration in one statement, is referred as structure variables. The
syntax of tagged structure is as follows,
MRLIT N. RAENSH PNO: 6
Where,
❖ struct is the keyword which tells the compiler that a
structure is being defined.
❖ tag_name is the name of the structure.
❖ member1, member2 … are called members of the structure.
The members are declared within curly braces.
❖ var1, var2… are structure variables that follow curly braces.
Here each variable occupies memory.
❖ The closing brace must end with the semicolon.
Example: student details using structure variables
struct student
{
char name [10];
int roll_number;
float avg_marks;
} s1;
MRLIT N. RAENSH PNO: 7
Here, name, roll_number and avg_marks are the structure members.
s1 is the structure variable, the compiler allocates memory for the
variable s1 as shown in Figure 1.
We can omit the tag name from the structure definition, the following
is valid.
struct
{
char name [10];
int roll_number;
float avg_marks;
} s1, s2;
Declares s1 and s2 as structure variables representing two students.
This structure definition and declaration is normally not used because
we can not declare variables in later stage in the program.
Typedefined Structure
❖ The structure definition associated with keyword typedef is called
type-defined structure.
❖ This is the most powerful way of defining the structure.
❖ The syntax of typedefined structure is
MRLIT N. RAENSH PNO: 8
where,
❖ typedef is keyword added to the beginning of the definition.
❖ struct is the keyword which tells the compiler that a structure
is being defined.
❖ member1, member2…are called fields of the structure.
❖ The closing brace must end with type definition name which
in turn ends with semicolon.
Example: Student details
//Structure Definition
typedef struct
{
char name [10];
int roll_number;
float avg_marks;
} STUDENT; //no memory is allocated for structure
/* structure declaration */
MRLIT N. RAENSH PNO: 9
STUDENT s1, s2; //memory is allocated for the variables.
Note: Using typedef it is not possible to declare a variable. But, we
can have user defined data type. TYPE_ID can be treated as the new
data type.
1.2 INITIALIZATION OF STRUCTURES
The rules for structure initialization are similar to the rules for array
initialization. The initializers are enclosed in braces and separate by
commas. They must match their corresponding types in the structure
definition.
The syntax is shown below,
struct tag_name variable = {value1, value2,… valuen};
Structure initialization can be done in any of the following initialization.
Initialization along with Structure definition
Consider the structure definition for student with three fields name,
roll number and average marks. The initialization of variable can be
done as shown below,
struct student
{
char name [5];
MRLIT N. RAENSH PNO: 10
int roll_number;
float avg;
} s1= {“Ravi”, 10, 67.8};
The various members of the structure have the following values.
🡨--- name --------------> 🡨 roll_number -> 🡨------ avg -------->
Figure 2 Initial Value of S1
Initialization during Structure declaration
Consider the structure definition for student with three fields name,
roll number and average marks. The initialization of variable can be
done as shown below,
struct student
{
char name[5];
int roll_number;
float avg;
};
struct student s1= {“Ravi”, 10, 67.8};
MRLIT N. RAENSH PNO: 11
The various members of the structure have the values as shown in
Figure 2.
We can also initialize multiple variables using comma between
variables.
Points to Remember
❖ The members of the structure cannot be initialized in the
structure definition.
For example,
struct s
{
char name [10] ="ravi”;
int rno;
} s1;
is invalid.
❖ The initial values are assigned to members of the structure on
one-to-one basis i.e., the values are assigned to various
members in the order specified from the first member.
For example,
s1= {“ravi”, 60, 56.7};
MRLIT N. RAENSH PNO: 12
is valid. Here, the string “ravi” will be assigned to the first
member. 60 is assigned to the second member and 56.7 is
assigned to the third member.
❖ During partial initialization, the values are assigned to members
in the order specified and the remaining members are initialized
with garbage values.
For example,
s1= {“ravi”};
will assign the string “ravi” to name and the remaining members
are initialized to garbage values.
However the statement,
s1= {40, 67.8};
is invalid, because, without initializing the first member name,
we are trying to initialize last two members.
❖ During initialization, the number of initializers should not exceed
the number of members. It leads to syntax error.
For example,
s1= {“ravi”, 45, 78.9, 89};
the compiler issues a syntax error “too many initializers”
MRLIT N. RAENSH PNO: 13
1.3 ACCESSING STRUCTURES
We know that variables can be accessed and manipulates using
expressions and operators. On the similar lines, the structure
members can be accessed and manipulated. The members of a
structure can be accessed by using dot(.) operator.
dot (.) operator
Structures use a dot (.) operator to refer its elements, also known as
period operator.
Before dot, there must always be a structure variable. After the dot,
there must always be a structure element.
The syntax to access the structure members as follows,
structure_variable_name. structure_member_name
For example, consider the example as shown below,
struct student
{
char name [5];
int roll_number;
float avg;
};
MRLIT N. RAENSH PNO: 14
struct student s1= {“Ravi”, 10, 67.8};
The members can be accessed using the variables as shown below,
[Link] --> refers the string “ravi”
s1.roll_number --> refers the roll_number 10
[Link] --> refers avg 67.8
Arrays with in structures
It is also possible to declare an array as a member of structure, like
declaring ordinary variables.
For example to store marks of a student in three subjects the we can
have the following definition of a structure.
struct student
{
char name [5];
int roll_number;
int marks [3];
float avg;
};
Then the initialization of the array marks done as follows,
struct student s1= {“ravi”, 34, {60,70,80}};
MRLIT N. RAENSH PNO: 15
The values of the member marks array are referred as follows,
[Link] [0] --> will refer the 0th element in the marks
[Link] [1] --> will refer the 1st element in the marks
[Link] [2] --> will refer the 2ndt element in the marks
The below program illustrates how to define a structure, declare a
structure and access the members of the structure.
MRLIT N. RAENSH PNO: 16
MRLIT N. RAENSH PNO: 17
MRLIT N. RAENSH PNO: 18
2 STRUCTURE OPERATIONS
Any operation that can be performed on ordinary variables can also be
performed on structure members. But, some operations can not be
performed on structure variables. The following sections deals with
operations that carried on structure and structure members.
Copying of structure Variables or members
MRLIT N. RAENSH PNO: 19
Copying of two structure variables is achieved using assignment
operator. But, one structure variable can be assigned to another
structure variable of the same type.
Example,
struct student
{
char name [10];
float avg;
} a, b;
a=b; //copies b in to a
[Link] = [Link]; // copies b average in to [Link]
We can not copy the variables of different structure type.
MRLIT N. RAENSH PNO: 20
MRLIT N. RAENSH PNO: 21
Comparison of two structure variables or members
Two variables of same structure type or dissimilar type is not allowed.
For example, the following operations are invalid, even though s1 and
s2 are of the same type,
s1==s2; (or) s1! = s2; invalid: because comparison is not allowed
between structure variables.
However, the members of two structure variables of same type can be
compared the same way as ordinary variables. s1 and s2 are two
structures, and then the following operations are valid.
Operation Meaning
MRLIT N. RAENSH PNO: 22
Compares member1 of a with
s1.member1 == s2.member1
member1 of b and return true if
they are same, false otherwise.
returns if the member1 of a and
s1.member1 != s2.member1 member1 of b are not same and
false otherwise.
Table 1 Comparison of Structure Members
Arithmetic Operations on Structures
The members of a structure are same to any ordinary variable and so
any operation that can be performed on a variable can also be
performed on structure members. The following operations are valid.
Expression Meaning
increments the salary before
++[Link] accessing its value.
increments the salary after
[Link]++
accessing its value.
&[Link] Access the address if [Link].
Access the beginning address of
&e
the structure.
MRLIT N. RAENSH PNO: 23
Table 5.2 Arithmetic Operations on Structure Members
Note: The arithmetic, relational, logical and other various operations
can be performed on individual members of the structures but not on
structure variables.
3 NESTED STRUCTURES
A structure which includes another structure is called nested structure
i.e a structure can be used as a member of another structure.
The syntax for the nesting of the structure as follows,
struct tag_name1
{
type1 member1;
…….
…….
};
struct tag_name2
{
type1 member1;
……
……
struct tag_name1 var;
MRLIT N. RAENSH PNO: 24
……
};
The syntax for accessing members of a nested structure as follows,
Good candidates for nested structures:
Student: dob -> day, month, year
Employee: allowance -> da, ta, hra
Player: tests, one days, T20
Example: Consider the student information name, roll no, DOB and
avg. The DOB consists of day, month, and year. It can be defined as
shown below,
struct data
{
int day;
int month;
int year;
};
struct student
{
char name [10];
MRLIT N. RAENSH PNO: 25
int roll_number;
struct data dob;
int marks [3];
float avg;
} s1;
Note that the above structure consists of a member identified by dob
whose type is struct data.
The members contained in the inner structure namely day, month and
year can be referred to as
[Link]
[Link]
[Link]
An inner-most member in a structure can be accessed by chaining all
the concerned structure variables (from outer-most to inner-most).
The memory organization of variable s1 is shown in Figure 3.
s1
MRLIT N. RAENSH PNO: 26
Figure 3: Memory organization of nested structure
We can nest two structures by using the following syntax,
in the
In the above definition it is mandatory to initialize variable to the inner
most structure. The members are accessed same way as first method.
Below program illustrates nesting of structures.
MRLIT N. RAENSH PNO: 27
MRLIT N. RAENSH PNO: 28
MRLIT N. RAENSH PNO: 29
4 ARRAY OF STRUCTURES
As we have an array of integers, we can have an array of structures
also. For example, suppose we want to store the information of class
of students, consisting of name, roll_number and marks, A better
approach would be to use an array of structures.
MRLIT N. RAENSH PNO: 30
Array of structures can be declared as follows,
struct tag_name arrayofstructure[size];
After having the above declaration a list of variables of type struct
tag_name.
Let’s take an example, to store the information of 3 students, we can
have the following structure definition and declaration,
struct student
{
char name[10];
int rno;
float avg;
};
struct student s[3];
Defines array called s, which contains three elements. Each element is
defined to be of type struct student.
For the student details, array of structures can be initialized as follows,
struct student s[3]={{“ABC”,1,56.7},{“xyz”,2,65.8},{“pqr”,3,82.4}};
The memory organization of the variables is illustrated in the below
Figure,
MRLIT N. RAENSH PNO: 31
s
s [0]
s [1]
s [2]
Figure 4: Memory organization of array of structures
MRLIT N. RAENSH PNO: 32
MRLIT N. RAENSH PNO: 33
MRLIT N. RAENSH PNO: 34
5 STRUCTURES AND POINTERS
The way we can have a pointer pointing to an int, or a pointer pointing
to a char, similarly we can have a pointer pointing to a struct. Such
pointers are known as ‘structure pointers’.
To access the values of the members of the structure using pointers
we need to perform following things,
1. Declare structure variable: struct tag_name var;
2. Declare a pointer to a structure: struct tag_name *ptr;
3. Store the address of structure variable in structure pointer:
ptr=&var;
4. Access the members of the structure.
Members of the structures can be accessed in following ways.
Using De-Reference Operator * and Dot (.) Operator
If ptr is a pointer to a structure, then the structure itself can be
accessed using indirection operator as shown below,
struct tag_Name *ptr; // Refers to the whole structure
Once the structure pointer is initialized, then each member of the
structure can be accessed using dot operator as shown below,
MRLIT N. RAENSH PNO: 35
(*ptr).structure_member1
(*ptr).structure_member2
…
Let’s take the following segment of code
struct student
{
int rno;
char name[10];
float avg;
};
struct student s1={101,”ABC”,78.98};
struct student *ptr;
ptr=&s1;
Now the members of the structure can be accessed by using the dot
operator as shown below,
(*ptr).name // Access the name
(*ptr).rno // Access roll number
(*ptr).avg // Access average
Note: The parenthesis to all three expressions is necessary. We should
not omit the parenthesis. For example,
*ptr .name // invalid way of accessing the member
MRLIT N. RAENSH PNO: 36
Using Selection Operator (->)
If ptr is a pointer to structure, then the members of the structure can
also be accessed using selection operator denoted by ->(which is
formed by minus sign and greater than symbol).
Using this various members of the structure can be accessed as shown
below,
ptr -> structrure_member
For the above example the members can be accessed as follows,
ptr - > name // Access the name
ptr - > rno // Access roll number
ptr - > avg // Access average
Remember that on the left hand side of the dot operator, there must
always be a structure variable, whereas on the left hand side of ->
operator there must be always be a pointer to structure. This method
is efficient, preferred over the previous method.
[Link] [Link] [Link]
4001 4003 4013
ptr
MRLIT N. RAENSH PNO: 37
5001
Figure 5: Memory Representation of Structure Pointer
The arrangement of structure variable and pointer to structure in
memory is as shown in the Figure 5,
// C program to read and display student details using pointer to
structure
MRLIT N. RAENSH PNO: 38
MRLIT N. RAENSH PNO: 39
MRLIT N. RAENSH PNO: 40
Structure Containing Pointers
We can also contain pointers as members of the structures. The
pointer is pointing to a value of the structure member or some other
variable. In general to reduce memory wastage we are using this
concept to declare strings as structure members using character
pointer.
The below code illustrates pointers as members of structures.
MRLIT N. RAENSH PNO: 41
6 STRUCTURES AND FUNCTIONS
We should note that structures are more useful if we are able to pass
them to functions and return them. The structures members can be
passed to the function in various ways as shown below,
1. BY passing individual members of structure
2. By passing the whole structure
3. By passing structures through pointers
MRLIT N. RAENSH PNO: 42
Passing Individual Members
The first method is to pass each member of the structure as an actual
argument of the function call. The actual arguments are treated
independently like ordinary variables.
// Passing individual structure elements
MRLIT N. RAENSH PNO: 43
MRLIT N. RAENSH PNO: 44
Explanation
MRLIT N. RAENSH PNO: 45
Observe that in the declaration of the structure, rno is declared as int,
marks are declared as integer array and avg as float. Therefore, when
we call the function display using
display ([Link], [Link], &[Link]);
We are passing the structure individual member value, the base
address of the array marks and the address of structure member.
Thus, this is a mixed of call-a call by reference as well as a call by
value.
Note: This method is inefficient when the structure size becomes
large. A better way would be to pass the entire structure variable at a
time.
Passing Whole Structure
The second method involves passing a copy of the entire structure to
the called function. Any changes to structure members within the
function are not reflected in the original structure. It is therefore,
necessary for the function to return the entire structure back to the
calling function.
The general format of sending a copy of a structure to the called
function is:
MRLIT N. RAENSH PNO: 46
return_type function_name (structure_variable_name);
The called function takes the following form:
data_type function_name(struct_type tag_name)
{
………
………
return(expression);
}
The called function must be declared for its type, appropriate to the
data type it is expected to return.
The structure variable used as the actual argument and the
corresponding formal argument in the called function must of the same
struct type.
The return statement is necessary only when the function is returning
some data back to the calling function. The expression may be any
simple variable or structure variable or an expression using simple
variables.
When a function returns a structure, it must be assigned to a structure
of identical type in the calling function. The called functions must be
declared in the calling function appropriately.
MRLIT N. RAENSH PNO: 47
// Passing Entire Structure
MRLIT N. RAENSH PNO: 48
MRLIT N. RAENSH PNO: 49
Explanation
Note that here the calling of function fun becomes quite compact,
fun (s1); Then the formal argument in the called function defined as
struct type struct student.
Returning Structure from a function
It is also possible that using return statement we can return structure
to the calling function. Here the return type of the function and the
return value both must be of type structure.
When the function call comes with an assignment to the structure
variable, after executing the called function the structure is returned
MRLIT N. RAENSH PNO: 50
and it is copied into the structure variable in the assignment
statement.
// Program illustrating function returning structure
MRLIT N. RAENSH PNO: 51
MRLIT N. RAENSH PNO: 52
Passing Structures Through Pointers
We have a pointer pointing to a structure. such pointers are known as
“structure pointers. The third approach employs the concept of
pointers to pass the structure as an argument. In this case, the
address location of the structure is passed to the called function. The
function can access indirectly the entire structure and work on it.
// C program illustrate Passing address of a structure variable
MRLIT N. RAENSH PNO: 53
MRLIT N. RAENSH PNO: 54
7 SELF-REFERENTIAL STRUCTURE
❖ A structure definition which includes at least one member as a
pointer to the same structure is known as self-referential
structure.
❖ Can be linked together to form useful data structures such as
lists, queues, stacks and trees.
❖ Terminated with a NULL pointer (0).
The syntax for using the self referential structure as follows,
MRLIT N. RAENSH PNO: 55
Example,
struct node
{
I int data;
struct node *next;
} n1, n2;
Diagram of two self-referential structure objects linked together is
shown in below Figure 6.
MRLIT N. RAENSH PNO: 56
Figure 6 Self Referential Structure Object Linking
Here next points to an object of type node referred to as a link ties one
node to another node.
8 UNIONS
❖ A union is one of the derived data type.
❖ Union is a collection of variables referred under a single name.
❖ The syntax, declaration and use of union is similar to the
structure but its functionality is different.
❖ The major distinction between structure and union is, in terms of
storage.
❖ In structure each member has its own storage location.
❖ Whereas all the members of a union use the same location.
❖ Although a union may contain many members of different types,
it can handle only one member at a time.
The general format or syntax of a union definition is as follows,
MRLIT N. RAENSH PNO: 57
Observe the following points while defining a union.
❖ union is the keyword which tells the compiler that a union is
being defined.
❖ member1, member2, … are called members(or fields) of the
union.
❖ The members are declared within curly braces.
❖ The compiler allocates a piece of storage that is large enough to
hold the largest variable type in the union.
❖ There should be semicolon at the end of closing braces.
A union variable can be declared same way as structure variable.
union tag_name var1, var2...;
A union definition and variable declaration can be done by using any
one on the following Figure 7.
MRLIT N. RAENSH PNO: 58
tagged union variable union typedef union
Figure 7 Types of Union Definitions
To access the members of union, the same syntax used to access
various members of a structure can be used, by using the dot
operator (“. “). For above example, we can access various members
of the union as shown below,
a.c
a.i
a.f
For the above example, union contains three members, each with a
different data type. However, we can use only one of them at a time.
a
MRLIT N. RAENSH PNO: 59
Figure 8: Memory Organization Union
In the above declaration, the member f requires 4 bytes which is the
largest among the members. Figure 8 shows how all the three
variables share the same address. The size of the structure here is 4
bytes.
During accessing, we should make sure that we are accessing the
member whose value is currently stored. For example look at the
below program, would produces erroneous output (which is machine
dependent).
MRLIT N. RAENSH PNO: 60
MRLIT N. RAENSH PNO: 61
In the above program we are initializing all the members of the union
at a time, the member which is large enough to hold the largest
variable type in the union occupies the memory, here float value is
stored in all memory locations of the union.
MRLIT N. RAENSH PNO: 62
MRLIT N. RAENSH PNO: 63
A union creates a storage location that can be used by any one of its
members at a time. When a different member is assigned a new value,
the new value supersedes the previous members’ value.
The above program illustrates the effective use of union memory
locations.
We can also create a pointer to a union; the syntax is as follows,
union tag_name *ptr;
MRLIT N. RAENSH PNO: 64
For the pointer variables, the indirection operator * and dot operator
or selection operator -> can be used to access the members. For the
above example, using pointer variable ptr, the various members of the
union as shown below,
ptr -> c or (*ptr).c
ptr.i -> i or (*ptr).i
ptr.f -> f or (*ptr).f
structure with in union
It also possible union may also contain structures as members of it.
The following code illustrates this concept.
MRLIT N. RAENSH PNO: 65
MRLIT N. RAENSH PNO: 66
In the above program we have two structure declarations a and b
followed by one union declaration u. Here the members of the union
are two structure variables. Now the size of the union is 4 bytes,
because the first structure contains two integer members so its size is
MRLIT N. RAENSH PNO: 67
4 bytes, and the second structure contains two character members so
its size is 2 bytes, therefore the size of the union is 4 bytes and entire
memory locations are occupied by the first structure variable.
Figure 9: Sharing of Union Members
MRLIT N. RAENSH PNO: 68
Difference between Array, Structure and Union
Arrays Structures Unions
Keyword … struct union
Defini-tio An array is a A structure is a A structure is a
n homogeneous collection of collection of logically
collection of logically related related elements,
data. elements, possibly possibly of different
of different types, types, having a
having a single single name, shares
name. single memory
location.
Declarati data_type struct tag_name union tag_name
on array_Name[s { {
ize]; type1 member1; type1 member1;
type1 member2; type1 member2;
…………… ……………
…………… ……………
}; };
struct tag_name union tag_name var;
var;
MRLIT N. RAENSH PNO: 69
Initializat Done by Same. Same.
ion separating list
of values with
comma (,),
specified in
Curly braces {
}.
Accessing Accessed by Accessed by Accessed by
specifying specifying specifying
array name structure Union
with subscript [Link] [Link]
bername ername
Memory Each array Each member of Memory is allocated
Allocatio element the structure by considering the
n occupies occupies unique size of largest
memory, location, stored in member. All the
stored in contigenous members share the
contigenous locations. common location
locations.
Size Size of the Size of the Size is given by the
array is structure depends size of largest
depending on on the type of member storage.
the array type members, adding
and size. size of all sizeof(un_variable);
members.
sizeof (arr); sizeof (st_var);
MRLIT N. RAENSH PNO: 70
Using An array Structure members Same as structure.
pointers elements can be accessed by
values can be using
accessed by de-referencing
using operator dot
de-referencing operator and
operator(*) selection
operator(->)
We can have We can have We can have array
array of arrays as a as a member of
structures or member of union.
unions. here structures.
the array type
is structure or
union.
All elements All members can Only one member
can be be accessed at a can be accessed at a
accessed at a time time.
time
… Nesting of Same. It is possible
structures is union may contain
possible. It is structure as a
possible union with member
in structure as a
member.
Table 3: Difference Between Array, Structure and Union
9 TYPEDEF
MRLIT N. RAENSH PNO: 71
C supports a feature known as “type definition” that allows users to
define an identifier that would represent an existing data type. Its
purpose is to redefine the name of an existing variable type.
The general syntax of the typedef is as follows,
typedef data_type IDENTIFIER;
where,
❖ typedef is the keyword tells the compiler about the type
definition.
❖ data_type refers to an existing data type.
❖ IDENTIFIER refers the “new” name given to the data type.
❖ Usually, uppercase letters are used to make it clear that we are
dealing with a renamed data type
Note that using typedef, we are not creating new data types. Instead
we are creating only new name for the existing data type. These new
data type names are called user-defined data types.
Suppose we want to store marks scored in various subjects in
variables sub1, sub2 and sub3. These variables can be declared as
follows,
int sub1, sub2, sub3;
MRLIT N. RAENSH PNO: 72
Using the user-defined data types, the variables can be declared as
shown below,
typedef int MARKS;
MARKS sub1, sub2, sub3;
Advantages
❖ Provides a meaningful way of declaring the variables.
❖ Increase the readability of the program.
❖ A complex declaration can be reduced to short and meaningful
declaration.
❖ typedef is widely used while dealing with structures.
MRLIT N. RAENSH PNO: 73
typedef with structures
using typedef, it is efficient way to define a structure. It can be defined
as follows,
Following are examples of typedef structure
MRLIT N. RAENSH PNO: 74
members can be accessed same way as normal structure. But here
we are creating new type. For the above example the type name is
EMP.
typedef can also be used to rename pointer data types as shown
below:
MRLIT N. RAENSH PNO: 75
The below program illustrates the definition of structure with typedef,
declaring variables and accessing members.
MRLIT N. RAENSH PNO: 76
MRLIT N. RAENSH PNO: 77
MRLIT N. RAENSH PNO: 78
MRLIT N. RAENSH PNO: 79
UNIT I
INTRODUCTION
Pointers are one of the derived types in C. One of the powerful tool
and easy to use once they are mastered.
Some of the advantages of pointers are listed below:
❖ A pointer enables us to access a variable that is defined outside
the function.
❖ Pointers are more efficient in handling the data tables.
❖ Pointers reduce the length and complexity of a program.
❖ The use of a pointer array to character strings save data storage
space in memory.
The real power of C lies in the proper use of pointers.
1 POINTER CONCEPTS
The basic data types in C are int, float, char double and void. Pointer is
a special data type which is derived from these basic data types.
There are three concepts associated with the pointers are,
❖ Pointer Constants
❖ Pointer Values
❖ Pointer Variables
1.1 POINTER CONSTANT
❖ As we know, computers use their memory for storing the
instructions of a program, as well as the values of the variables
that are associated with it.
❖ The computer’s memory is a sequential collection of ‘storage
cells’.
❖ Each cell can hold one byte of information, has a unique number
associated with it called as ‘address’.
❖ The computer addresses are numbered consecutively, starting
from zero. The last address depends on the memory size.
❖ Let us assume the size of the memory is 64K then,
MLRIT N. RAMESH PNO: 1
The total memory locations = 64K
= 64 * 1K
= 64 * 1024 bytes
= 65536 bytes (locations)
❖ So, here the last address is 65535(started with 0).
❖ Physically they are divided into even bank and odd bank.
❖ Even bank is set of memory locations with even addresses.
Like 0, 2, 4, 6……65534.
❖ Odd bank is set of memory locations with odd addresses. Like
1, 3, 5 ….65535.
Address Memory Locations Address
0 1
2 3
4 5
.. ..
.. ..
32278 32279
.. ..
65530 65531
65532
65534 65535
even bank odd bank
Figure: 1 Memory Organization.
❖ These memory addresses are called pointer constants.
❖ We cannot change them, but we can only use them to store data
values.
MLRIT N. RAMESH PNO: 2
❖ For example, in the above memory organization, the addresses
ranging from 0 to 65535 are known as pointer constants.
❖ Remember one thing, the address of a memory location is a
pointer constant and cannot be changed .
1.2 POINTER VALUE
Whenever we declare a variable, the system allocates , an appropriate
location to hold the value of the variable somewhere in the memory,.
Consider the following declaration,
int i=10;
This declaration tells the C compiler to perform the following activities:
❖ Reserve space in the memory to hold the integer value.
❖ Associate the name i with this memory location.
❖ Store the value 10 at this location.
We can represent i’s location in the memory by the following memory
map:
i Variable Name
Variable value
65510 Variable address
Pointer Values
❖ Memory is divided into number of storage cells called locations.
❖ Out of these the addresses, the system assigns some addresses
of the memory locations to the variables.
❖ These memory locations assigned to the variables by the system
are called pointer values.
❖ For example, the address 65510 which is assigned to the
variable i is a pointer value.
The & Operator
MLRIT N. RAMESH PNO: 3
❖ The address of the variable cannot be accessed directly. The
address can be obtained by using address operator(&) in C
language.
❖ The address operator can be used with any variable that can be
placed on the left side of an assignment operator.
❖ The format specifier of address is %u(unsigned integer),the
reason is addresses are always positive values. We can also use
%x to know the address of a variable.
❖ Example, to know the address of variable n, just use &n.
Note: Constants, expressions, and array name cannot be placed on
the left side of the assignment and hence accessing address is invalid
for constants, array names and expressions.
The following are illegal use of address Operator.
&125 (Pointing at constant)
int a[10];
&a (pointing to array name)
&(x+y) (pointing at expressions)
1.3 POINTER VARIABLE
❖ A variable Which holds the address of some other variable is
called pointer variable.
❖ A pointer variable should contain always the address only.
The * Operator
❖ It is called as ‘Value at address’ operator. It returns the value
stored at a particular address.
❖ It is also Known as Indirection or Dereferencing Operator
2 ACCESSING A VARIABLE THROUGH POINTER
For accessing the variables through pointers, the following sequence of
operations have to be performed ,to use pointers.
1. Declare an ordinary variable.
2. Declare a pointer variable.
MLRIT N. RAMESH PNO: 4
3. Initialize a pointer variable(Provide link between pointer variable
and ordinary variable).
4. Access the value of a variable using pointer variable.
We already familiar with the declaration and initialization of variable.
Now we will discuss the remaining here.
Declaring a pointer variable
In C , every variable must be declared before they are used. Since the
pointer variables contain address that belongs to a separate data type,
they must be declared as pointers before we use them.
The syntax for declaring a pointer variable is as follows,
This tells the compiler three things about the variable ptr_name.
1. The asterisk(*) tells that the variable ptr_name is a pointer
variable.
2. ptr_name needs a memory location.
3. ptr_name points to a variable of type data type.
For example,
int *pi;
declares the variable p as a pointer variable that points to an integer
data type. Remember that the type int refers to the data type of the
variable being pointed by pi.
Initializing Pointers
❖ Once a pointer variable has been declared, it can be made to
point to a variable using statement such as
❖ Which cause ptr_name to point to [Link] ptr_name contains
the address of var. This is known as pointer initialization.
❖ Before a pointer is initialized it should not be used.
Access the value of a variable using pointer variable
MLRIT N. RAMESH PNO: 5
Once a pointer variable has been assigned the address of a variable,
we can access the value of a variable using the pointer. This is done by
using the indirection operator(*).
Example1
MLRIT N. RAMESH PNO: 6
The above program illustrates how to access the variable using
pointers. After finding the first statement i=10 ,the compiler creates a
variable i with a value of 10 at a memory location. Then coming to line
2 and 3 a pointer variable pi is create and initialized with the address
of the i variable. then the compiler automatically provides a link
between these two variables as follows.
i pi
8342 8338
Note: Pointer variable always points to a address of the another
variable .Following statements are not valid with respect to pointers.
int i=10, k, *pi=&i;
k=pi; // pointer value cannot be accessed by integer
pi=65506(constant); // we cannot directly assign a value to a pointer
variable
Example2
MLRIT N. RAMESH PNO: 7
The following code illustrates how to declare int ,char and float
pointers. Here we have declared three variables of type int, float and
char ,also three pointer variables points to int, float and char.
Remember here pf points to the value of type float but its type is
unsigned integer only.
MLRIT N. RAMESH PNO: 8
Declaration versus Redirection:
❖ When an asterisk is used for declaration, it is associated with a
type.
❖ Example:
int* pa;
int* pb;
❖ On the other hand, we also use the asterisk for redirection.
When used for redirection, the asterisk is an operator that
redirects the operation from the pointer variable to a data
variable.
❖ Example:
Sum = *pa + *pb;
Dangling Pointers
A pointer variable should contain a valid address. A pointer variable
which does not contain a valid address is called dangling pointer.
MLRIT N. RAMESH PNO: 9
For example, consider the following declaration,
int *pi;
This declaration indicates that pi is a pointer variable and the
corresponding memory location should contain address of an integer
variable. But , the declaration will not initialize the memory location
and memory contains garbage value as shown in below.
pi
Garbage Value
Note: We cannot use a pointer variable to the register variable. The
reason is that, user does not know the address of the register variable.
So we are not able to use pointer variable on register variables.
3 POINTER ARITHMETIC
The following operations can be performed on a pointer:
❖ Addition of a number to a pointer. Pointer can be incremented to
point to the next locations.
Example:
int i=4 ,pi=&i; //(assume address of i=1000)
float j,*pj=&j;// (assume address of j=2000)
pi = pi + 1; // here pi incremented by (1*data type times)
pi = pi + 9; // pi = 1000 + (9*2) 🡪 1018 address
pj = pj + 3; // pj=1018+(3*4)🡪1030 address
❖ Subtraction of a number from a pointer. Pointer can be
decremented to point to the earlier locations.
Example:
int i=4,*pi=&i; //assume address of i =1000)
char c, *pc=&c; // assume address of c = 2000
double d, *pd=&d; // assume address of d=3000
pi = pi-2; /* pi=1000-(2*2)=996 address */
pc = pc-5; /* pc=2000-(5*1)=1985 address
pd = pd-6; /* pd=3000-(6*8)=2952 address */
MLRIT N. RAMESH PNO: 10
❖ Pointer variables may be subtracted from one another. This is
helpful while finding array boundaries. Be careful while
performing subtraction of two pointers.
❖ Pointer variables can be used in comparisons, but usually only in
a comparison to NULL.
❖ We can also use increment/decrement operators with pointers
this is performed same as adding/subtraction of integer to/from
pointer.
The following operations cannot be performed on pointers.
❖ Addition of two pointers.
❖ Multiplication of a pointer with a constant, two pointers.
❖ Division of a pointer with a constant, two pointers.
POINTER EXPRESSIONS
Like other variables, pointer variables can be used in expressions. For
example, if p1 and p2 are two valid pointers ,then the following
statements are valid.
a= *p1 + *p2;
sum = sum + *p1;
z = 10 / *p2;
f = *p1 * i;
Note: be careful while writing pointer expressions .The expression
*p++ will result in the increment of the address of p by data type
times and points to the new value. Whereas the expression (*p) ++
will increments the vale at the address. If you are not properly coded
you will get some unwanted result.
NULL Pointer
❖ If wish to have a pointer that points to “nowhere”, should make
this explicit by assigning it to NULL.
❖ If it is too early in the code to assign a value to a pointer, then it
is better to assign NULL (i.e., \0 or 0).
double *pval1 = NULL;
double *pval2 = 0;
❖ The integer constants 0 and 0L are valid alternatives to NULL,
but the symbolic constant is (arguably) more readable.
MLRIT N. RAMESH PNO: 11
❖ A NULL pointer is defined as a special pointer.
❖ It can be used along with memory management functions.
4 POINTERS TO POINTERS
❖ It is possible to make a pointer to point to another pointer
variable. But the pointer must be of a type that allows it to point
to a pointer.
❖ A variable which contains the address of a pointer variable is
known as pointer to pointer.
❖ Its major application is in referring the elements of the two
dimensional array.
❖ Syntax for declaring pointer to pointer,
❖ This declaration tells compiler to allocate a memory for the
variable ptr_ptr in which address of a pointer variable which
points to value of type data type can be stored.
❖ Syntax for initialization
❖ This initialization tells the compiler that now ptr_ptr points to the
address of a pointer variable.
❖ Accessing the element value,
❖ It is equalent to *(*(&ptr_name));
Example
MLRIT N. RAMESH PNO: 12
The above program illustrates the use of pointers to pointers. Here,
using two indirection operators the data item 16 can be accessed (i.e.,
*ppi refers to pi and **ppi refers to i).
5 POINTER COMPATIBILITY
❖ We should not store the address of a data variable of one type
into a pointer variable of another type.
❖ During assigning we should see that the type of data variable
and type of the pointer variable should be same or compatible.
❖ Other wise it will result in unwanted output.
❖ The following program segment is wrong,
int i=10;
float *pf;
pf=&i; // data variable is integer and pointer
variable is float
It is possible to use incompatible pointer types while assigning with
type casting pointer.
Casting pointers
MLRIT N. RAMESH PNO: 13
When assigning a memory address of a variable of one type to a
pointer that points to another type it is best to use the cast operator to
indicate the cast is intentional (this will remove the warning).
Example:
int V = 101;
float *P = (float *) &V; /* Casts int address to float * */
Removes warning, but is still a somewhat unsafe thing to do.
Void Pointer
❖ A pointer to void is a generic type that is not associated with a
reference type.
❖ It is neither the address of a character nor an integer, nor a float
nor any other type.
❖ It is compatible for assignment purposes only with all other
pointer types.
❖ A pointer of any reference type can be assigned to a pointer to
void type.
❖ A pointer to void type can be assigned to a pointer of any
reference type.
❖ Certain library functions return void * results.
❖ No cast is needed to assign an address to a void * or from a void
* to another pointer type.
❖ Where as a pointer to void can not be deferenced unless it is
cast.
void
Figure 2 pointer to void
❖ Example:
int V = 101;
float f=98.45;
void *G = &V; /* No warning */
printf (“%d”,*((int*)G)); /* Now it will display 101
float *P = G; /* No warning, still not safe */
printf (“%f”,*((float*)G)); /* Now it will display 98.45
6 POINTERS AND FUNCTIONS
MLRIT N. RAMESH PNO: 14
❖ Pointers can be used to pass addresses of variables to called
functions, thus allowing the called function to alter the values
stored there.
❖ We looked earlier at a swap function that did not change the
values stored in the main program because only the values were
passed to the function swap.
❖ This is known as "call by value".
❖ Here we are going to discuss how to pass the address.
Call by Reference
Instead of passing the values of the variables to the called function, we
pass their addresses, so that the called function can change the values
stored in the calling routine. This is known as "call by reference",
since we are referencing the variables.
Here the addresses of actual arguments in the calling function are
copied into formal arguments of the called function. Here The formal
parameters should be declared as pointer variables to store the
address.
The following shows the swap function modified from a "call by value"
to a "call by reference". Note that the values are now swapped when
the control is returned to main function.
Observe the following points when the program is executed,
MLRIT N. RAMESH PNO: 15
❖ The address of actual parameters a and b are copied into formal
parameters pa and pb.
❖ In the function header of swap (), the variables a and b are
declared as pointer variables.
❖ The values of a and b accessed and changed using pointer
variables pa and pb.
Call by Value Call by Reference
When Function is called the When a function is called address
values of variables are passed. of variables is passed.
Formal parameters contain the Formal parameters contain the
value of actual parameters. address of actual parameters.
Change of formal parameters The actual parameters are
in the function will not affect changed since the formal
the actual parameters in the parameters indirectly manipulate
calling function the actual parameters
Execution is slower since all
Execution is faster since only
the values have to be copied
addresses are copied.
into formal parameters.
Table: 1 Difference between Call by Value and Call by Reference
6.1 FUNCTION RETURNING POINTERS
❖ The way function return an int, float and char, it can return a
pointer.
❖ To make a function return a pointer it has to be explicitly
mentioned in the calling function as well as in the function
declaration.
❖ Three things should be done to avail the feature of functions
return pointer.
1. Declaration of function returning pointer
2. Declaring pointer and assigning function call
Defining function returning pointer
❖ Syntax for declaration of function returning pointer
MLRIT N. RAMESH PNO: 16
This declaration helps the compiler to recognize that this
function returns address.
❖ Now declare pointer variable and place the function call
❖ After executing above statement ptr consisting of the address
that is returned by the function. Remember the return type of
the function and pointer type should match here.
❖ The function Definition returning pointer takes of the form,
Example:
MLRIT N. RAMESH PNO: 17
The execution of the program as follows,
❖ Execution of the program starts at main.
❖ Two variables and b are created and initialized at run-time.
❖ A pointer variable is created and initialized with the return value
of the function max ().
❖ Once the control is transferred from function main () to max (),
it got executed and returns the pointer value to main().
❖ Here we are having the address of the maximum variable
address to display it just use indirection operator (*).
Note: function return pointer does not have any advantage except in
the handling of strings.
6.2 POINTERS TO FUNCTIONS
Pointer to a function (also known as function pointer) is a very
powerful feature of C. Function pointer provides efficient and elegant
programming technique. Function pointers are less error prone than
normal pointers since we will never allocate or de-allocate memory for
the functions.
Every variable with the exception of register has an address. We have
seen how we can refer variables of type char, int and float. Through
their addresses, by using pointers.
Functions exist in memory just like variables. C will allow you to define
pointers to functions. Just like variables, a function name gives the
starting address of function stored in memory.
The below code illustrate how to get the address of a function.
MLRIT N. RAMESH PNO: 18
6.2.1 DEFINING POINTERS TO FUNCTIONS
Like declaring pointer variables, we can define pointers to function
variables and store the address. The below figure illustrate how
function pointer can be represented.
main
Code for main ()
display
f_ptr Code for display ()
Figure: Functions in Memory.
MLRIT N. RAMESH PNO: 19
The syntax for declaring pointer to function as follows,
Everything is same as function declaration except the braces for the
name, to tell the compiler that this is a fuction pointer braces are
required here and as usual for pointer declarations * is used.
Note that the return type of function pointer, number of arguments
and type of arguments must match with the normal function.
The next after the declaration is calling the function using function
pointer. before calling takes place we must initialize the function
pointer with the address of the function.
The syntax for this assignment,
After this assignment we need to call the function, the syntax
associated with the function call is as follows,
This is another way of calling the function. There are no changes in the
declaration of the function body.
The below program simulates a simple calculator using function
pointers.
MLRIT N. RAMESH PNO: 20
MLRIT N. RAMESH PNO: 21
MLRIT N. RAMESH PNO: 22
MLRIT N. RAMESH PNO: 23
7 POINTERS AND ARRAYS
❖ An array is a collection of similar elements stored in contiguous
memory locations.
❖ When an array is declared, the compiler allocates a base address
and sufficient amount of memory depending on the size and data
type of the array.
❖ The base address is the location of the first element of the array.
❖ The compiler defines the array name as a constant pointer to the
first element.
7.1 POINTERS AND ONE DIMENSIONAL ARRAY
Let us take the following declaration,
int num [5] = {1, 2, 3, 4, 5};
❖ After having this declaration, the compiler creates an array with
name num, the elements are stored in contiguous memory
locations, and each element occupies two bytes, since it is an
integer array.
❖ The name of the array num gets the base address. Thus by
writing *num we would be able to refer to the zeroth element of
the array, that is 1.
❖ Then *num and *(num+0) both refer to the element [Link]
*(num+2) will refer
❖ When we have num[i] , the compiler internally converts it to
*(num+i).
❖ In this light the following notations are same.
❖ Then we can also define a pointer and initialize it to the address
of the first element of the array (base address).
❖ Example, for the above array we can have the following
statement,
int *ptr=a; (or) int *ptr=&a[0];
MLRIT N. RAMESH PNO: 24
❖ To refer the array elements by using pointer the following
notations are used.
❖ p++ will point to the next location in the array.
❖ Accessing array elements by using pointers is always faster than
accessing them by subscripts.
❖ The below figure shows the array element storage in the
memory.
num [0] num [1] num [2] num [3]num [4] elements
values
1000 1002 1004 1006 1008 address
ptr
base address
Figure 4 Storage representation of array
Example
MLRIT N. RAMESH PNO: 25
The above program illustrates displaying the array elements using
pointers.
Note: Note that the array name num is a constant pointer points to
the base address, then the increment of its value is illegal, num++ is
invalid.
MLRIT N. RAMESH PNO: 26
7.2 POINTERS AND TWO DIMENSIONAL ARRAYS
A two dimensional array is an array of one dimensional arrays. The
important thing to notice about two-dimensional array is that, just as
in a one-dimensional array, the name of the array is a pointer constant
the first element of the array, however in 2-D array, the first element
is another array.
Let us consider we have a two-dimensional array of integers. When we
dereference the array name, we don’t get one integer, we get an array
on integers. In other words the dereference of the array name of a
two-dimensional array is a pointer to a one-dimensional array. Here we
require two indirections to refer the elements
Let us take the declaration
int a [3][4];
Then following notations are used to refer the two-dimensional array
elements,
a -----> points to the first row
a+i -----> points to ith row
*(a+i) -----> points to first element in the ith row
*(a+i) +j -----> points to jth element in the ith row
*(*(a+i)+j)----->value stored in the ith row and jth column
Columns
0 1 2 3
0
Rows 1
Example
MLRIT N. RAMESH PNO: 27
MLRIT N. RAMESH PNO: 28
7.3 POINTERS AND THREE DIMENSIONAL ARRAYS
Three-dimensional array can be thought of array of two-dimensional
array. To refer the elements here we require tree indirections.
The notations are,
*(*(a+i) +j) +k --> points to the address of kth dimension in ith
row jth column
*(*(*(a+i) +j) +k) --> value stored at kth dimension ith row jth
column
MLRIT N. RAMESH PNO: 29
Example
MLRIT N. RAMESH PNO: 30
8 FUNCTIONS AND ARRAYS
To process arrays in large program, we have to be able to pass them
to function. We can pass arrays in two ways,
❖ Passing individual elements
❖ Passing entire array elements
Passing individual elements
We can pass individual elements by either their data values or by
passing their addresses.
1. Passing Data Values
❖ This is same as passing data values. Here we are passing an
individual array element at a time tp the function.
❖ The called function cannot tell whether the value it receives
comes from an array, or a variable.
Example
MLRIT N. RAMESH PNO: 31
2. Passing Addresses of array elements
Here we are passing the individual elements address. the called
function requires declaration of arguments as pointer variables.
Example
MLRIT N. RAMESH PNO: 32
Passing the Entire Array
Here we see the first situation in which C does not pass values to a
function. The reason for this change is that a lot of memory and time
would be used in passing large arrays every time we wanted to use
one in function.
For example, if an array containing 1200 elements were passed by
value to a function, another 1200 elements would have to be allocated
in the called function and each element would be copied from one
array to the other. So, instead of passing the whole array, C passes the
address of the array.
In C, the name of the array value is address of the first element in the
array. When we pass the name, it allows the called function to refer to
the array back in the calling function. Passing both two dimensional
array and one dimensional are same but subscripts are changed.
The above program find the squares of the elements of the array .Here
we passed the name of the array as an argument to the function an in
MLRIT N. RAMESH PNO: 33
the called function the formal argument is created and points to the
elements of the calling function argument array.
MLRIT N. RAMESH PNO: 34