UNIT-V
Structure, Union and Files
Structures –Pointers to Structures – Array of
Structures – Structures within a Structure –
Functions and Structures – typedef and
Structures –
Unions–Practical Applications of Unions –
Enumerations – Bit fields – Storage Classes
– C Preprocessor –
Files: Streams – File type – File operations –
Command line arguments.
Structures
• C language provides the flexibility to
create new data types.
• These data types are known as user-
defined data types and can be created by
using structures, unions and
enumerations.
• Arrays can be used for the storage of
homogeneous data.
• However, they cannot be used for the
storage of data of different types.
• The data of different types can be grouped
together and stored by making use of
structures.
• One of the similarities between arrays and
structures is that both of them contain a
finite number of elements.
• Thus, array types and structure types are
collectively known as aggregate types.
Structures
A structure is a collection of variables
under a single name and provides a
convenient way of grouping several pieces
of related information together.
Unlike arrays, it can be used for the storage
of heterogeneous data (i.e. data of
different types).
There are three aspects of working
with structures:
1.Defining a structure type, i.e. creating a
new type
2.Declaring variables and constants (i.e.
objects) of the newly created type
3.Using and performing operations on the
objects of the structure type
Defining a Structure
The general form of structure-type definition
(or just structure definition) is:
[storage_class_specifier][type_qualifier]
struct [structure_tag_name]
{
type member_name1[, member_name11,
…];
[type member_name2[, member_name22,
…]];
………
} [variable_name];
Important points about structure definition
1.The terms enclosed within the square
brackets are optional and might not be
present in a structure definition statement.
However, the terms shown in bold are the
mandatory parts of the structure definition.
2.A structure definition consists of the
keyword struct followed by an optional
identifier name, known as structure tag-
name, and a structure declaration-list
enclosed within the braces.
The structure definition defines a new type,
known as structure type. For example, in
Table (a) the structure type is struct book.
After the definition of the structure type, the
keyword struct is used to declare its
variables.
If the tag-name is present, it will act as a
name for the newly created data type.
//The defined structure type is visible only
in the scope in which it is defined
#include<stdio.h>
func(); //Declaration of the function func
main()
{
struct coord //The type struct coord is
defined in the scope local to the function
main
{
int x,y;
};
struct coord pt1, pt2; //Declaring variables
pt1 and pt2 of the created type struct coord
//Other statements in the function main
// ………………………….
}
func()
{
struct coord pt3; //The tag name coord is
not visible here
//Other statements in the function func
// ………………………….
}
Compilation errors
“Undefined structure ‘coord’ in
function func()”
“Size of ‘pt3’ is unknown or zero
in function func()”
Structure members can be variables of the
basic types (e.g. char, int, float, etc.),
pointer types (e.g. char*, etc.) or
aggregate type (i.e. arrays or other
structure types).
They are declared in the same way as
normal identifiers are declared.
A structure declaration-list cannot contain a
member of void type or incomplete type
or function type.
Hence, a structure definition cannot contain
an instance of itself.
However, it may contain a pointer to an
instance of itself.
Such a structure is known as a self-
referential structure.
Two different structure types may contain
members of the same name without any
conflict.
It is important to note that a structure definition
does not reserve any space in the memory.
If a structure definition does not contain a
structure tag-name, the created structure
type is unnamed.
The unnamed structure type is also known as
an anonymous structure type.
It is not possible to declare its objects (i.e.
variables and constants) after its definition.
//Use of storage class specifier
while defining a structure type
#include<stdio.h>
static struct point
{
int x;
int y;
};
main()
{
struct point pt1;
//Other statements
}
Compilation error “Storage class
‘static’ not allowed here”.
Remark:
• The storage class specifiers
except typedef should not be
used in a structure-type
definition if the objects are not
declared at the time of structure
definition
Declaring Structure Objects
• Variables and constants (i.e. objects) of
the created structure type can be declared
either at the time of structure definition or
after the structure definition.
• Variables and constants of the created
structure type can be created after the
structure definition only if the defined
structure type is named or tagged.
• The general form of declaring
structure objects is:
[storage class specifi er] [type_qualifi er] struct
named_structuretype identifier_name
[=intialization_list [,…]];
The terms shown in bold are the mandatory
parts of the structure object declaration
• A structure object declaration consists of:
i. The keyword struct for declaring structure
variables.
It can also be used in conjunction with const
qualifier for declaring structure constants.
ii. The tag-name of the defined structure type.
iii. Comma-separated list of identifiers (i.e. variable
names or constant names).
A variable can optionally be initialized by providing
an initializer.
However, initialization of a constant is must.
iv. A terminating semicolon
• The following structure variable declarations are
valid:
struct book c_book, algorithm_book;
struct phonebook_entry entry;
struct two_dimensional_coordinate pt1={2,3}, pt2;
• The following structure constant declarations are
valid:
const struct book c_book, algorithm_book={“C
Programming”, “Anirudh”, 450, 225.50};
const struct phonebook_entry
entry={{“Mohit”,”Virmani”}, “1234567899”};
const struct two_dimensional_coordinate pt1={2,3},
pt2={4,5};
• In C language, the objects of the defined structure
type cannot be declared without using the keyword
struct.
• Upon the declaration of a structure object, the
amount of the memory space allocated to it
is equal to the sum of the memory space required
by all of its members.
• The memory space allocated to a structure object
can be determined by using the sizeof operator.
• The structure members are assigned memory
addresses in increasing order, with the first
structure member starting at the beginning address
of the structure itself.
• Initializing members of a structure object: Like
variables and array elements, the members of a
structure object can also be initialized at the
compile time.
• The syntactic rules about structure member
initialization are as follows:
i. The members of a structure object can be initialized
by providing an initialization list. An initialization list
is a comma-separated list of initializers.
ii. The order of initializers must match the order of
structure members in the structure definition.
iii. The type of each initializer should be the same as
the type of corresponding structure member in the
structure definition.
iv. The number of initializers in an initialization list can
be less than the number of members in a structure
object and if it happens, the leading structure
members (i.e. occurring first) will be initialized with
the initializers in the initialization list.
The rest of the members will automatically be
initialized with 0 (if they are of integer type)
Examples of structure member initialization are as follows:
struct book c_book={“My Life”, “C Motilal”, 400, 210.50};
struct phonebook_entry entry={{“Rajesh”,”Kumar”},
“9814000561”};
struct two_dimensional_coordinate pt1={2}, pt2={2,3};
//Using type qualifiers while declaring
a structure object
#include<stdio.h>
struct point
{
int x;
int y;
};
main()
{
const struct point pt={2,3};
pt.x=20;
pt.y=40;
//Other statements...
}
Compilation errors “Cannot modify
a constant object in function
main()”
Remarks:
• To access the members of a
structure object, the member
access operator, i.e. dot operator is
used.
• The type qualifier const is
applied to all the members of the
structure object. Hence, the type of
pt.x and pt.y is const int and thus, it
is not possible to place them on the
left side of the assignment operator
A structure object declaration can optionally have a
storage class specifier.
i. If a structure object is declared with a storage class
specifier other than typedef, the properties resulting
from the storage class specifier except with respect
to linkage, also apply to the members of the object.
//Declaring structure object with a
storage class specifier other than
//typedef
#include<stdio.h>
struct point
{
int x;
int y;
};
main()
{
struct point pt1;
static struct point pt2;
printf(“The coordinates of pt1 are
%d,%dn”, pt1.x, pt1.y);
printf(“The coordinates of pt2 are
%d,%dn”, pt2.x, pt2.y);
}
The coordinates of pt1 are
9495,19125
The coordinates of pt2 are 0.0
• Since the structure object pt2 is
declared with static storage class
qualifier, all the properties resulting
from it except linkage, are
applicable to all the members of the
structure object pt2
•• To access the members of a
structure object, the member
access operator, i.e. dot operator is
used.
Operations on Structures
• The operations that can be performed on
an object (i.e. variable or constant) of a
structure type are classified into two
categories:
1.Aggregate operations
2. Segregate operations
Aggregate Operations
An aggregate operation treats an operand as an
entity and operates on the entire operand as a
whole instead of operating on its constituent
members. The four aggregate operations that
can be applied on an object of a structure type
are as follows:
1.Accessing members of an object of a structure
type
2.Assigning a structure object to a structure
variable
3.Address of a structure object
4.Size of a structure (i.e. either structure type or a
Accessing Members of an Object of a
Structure Type
The members of a structure object can be
accessed by using:
1. Direct member access operator (i.e. .,
also known as dot operator).
2. Indirect member access operator (i.e.
->, also known as arrow operator).
#include<stdio.h>
struct coord //Definition of type struct
coord
{ // Creation of new type for 2-D
coordinate
int x,y;
};
main()
{
struct coord pt1={4,5}; //pt1 is a
variable of type struct coord
const struct coord pt2={2,3}; //pt2 is a
qualified constant of type struct coord
int tx, ty;
printf(“Enter values of translation
vector:n”);
scanf(“%d %d”,&tx, &ty);
printf(“After translation, coordinates
are:n”);
printf(“Pt1 (%d,%d)n”, pt1.x+tx,
pt1.y+ty);
printf(“Pt2 (%d,%d)n”, pt2.x+tx,
pt2.y+ty);
}
Enter values of translation vector:
4 2
After translation, coordinates are:
Pt1 (8,7)
Pt2 (6,5)
Assigning a Structure Object to a Structure
Variable
Like simple variables, a structure variable
can be assigned with or initialized with a
structure object (i.e. variable or constant)
of the same structure type.
//Initialization and assignment of a structure variable
#include<stdio.h>
struct book //Structure definition
{
char title[25];
char author[20];
int price;
};
main()
{
//Initializing a structure variable by providing an initialization list
struct book b1={“Cutting Stone”, “Abraham”, 200}:
//Initializing a structure variable with another structure variable
struct book b2=b1;
// Declaring an uninitialized structure variable
struct book b3;
b3=b2; //Assigning a structure variable to a structure variable
printf(“%s by %s is of Rs. %d rupeesn”, b1.title, b1.author, b1.price);
printf(“%s by %s is of Rs. %d rupeesn”, b2.title, b2.author, b2.price);
printf(“%s by %s is of Rs. %d rupeesn”, b3.title, b3.author, b3.price);
}
Address-of a Structure Object
• The address-of operator when applied on
a structure object gives its base (i.e.
starting) address.
• It can also be used to find the addresses
of the constituting members of a structure
object.
//Address-of operator and structures
#include<stdio.h>
struct complex
{
int re, im;
};
main()
{
struct complex c1={2,3};
const struct complex c2={4,5};
printf(“Address of c1 is %pn”,&c1);
printf(“Address of its real part is
%pn”,&c1.re);
printf(“Address of its imaginary part is
%pn”,&c1.im);
printf(“Address of c2 is %pn”,&c2);
printf(“Address of its real part is
%pn”,&c2.re);
printf(“Address of its imaginary part is
%pn”,&c2.im);
}
Address of c1 is 233F:222C
Address of its real part is
233F:222C
Address of its imaginary part is
233F:222E
Address of c2 is 233F:223C
Address of its real part is
233F:223C
Address of its imaginary part is
233F:223E
Byte aligned: If the members of a structure object are
byte aligned, then every structure member starts
from a new byte (i.e. they can appear at any byte
boundary).
In byte alignment, the data members are stored next
to each other.
Machine-word boundary aligned: Most of the
machines access objects of certain types
faster if they are aligned properly.
In order to increase the performance of the code on
such machines, the compiler aligns the members of
a structure object with the storage boundaries
whose addresses are multiple of their respective
sizes.
Equating Structure Objects of the Same Type
The use of an equality operator on the operands of
a structure type is not allowed and leads to a
compilation error.
//Equality operator and structures
#include<stdio.h>
#pragma pack(2)
struct pad
{
char a;
int b;
char c;
float d;
};
main()
{
struct pad var1={‘A’, 2, ‘B’, 2.5},
var2={‘A’, 2, ‘B’, 2.5};
if(var1==var2)
printf(“Structure variables are
equaln”);
else
printf(“Structure variables are
unequaln”);
}
Equating Structure Objects of the Same
Type
The use of an equality operator on the
operands of a structure type is not allowed
and leads to a compilation error.
Pointers to Structures
• The pointers to structures have the
following advantages:
1. It is easier to manipulate the pointers to
structures than manipulating structures
themselves.
2. Passing a pointer to a structure as an
argument to a function is efficient as
compared to passing a structure to a
function.
• The size of a pointer to a structure is
generally smaller than the size of the
structure itself.
• Thus, passing a pointer to a structure as an
argument to a function requires less data
movement as compared to passing the
structure to a function.
3. Some wondrous data structures (e.g.
linked lists, trees, etc.) use the structures
containing pointers to structures.
Pointers to structures play an important role
in their successful implementation.
Declaring Pointer to a Structure
• The general form of declaring a pointer to
a structure is:
[storage_class_specifi er] [type_qualifi er]
struct named_structure_type* identifi
er_name
1. The terms shown in bold are the mandatory
parts of a structure pointer declaration
statement.
2. A pointer to a structure type can be declared
in a separate declaration statement only if the
structure type is named. If the structure type
is unnamed, the structure pointer should be
created at the time of structure definition.
3. The declared structure pointer can optionally be
initialized with an l-value. The initializing l-value
should be of appropriate type, else there will be
a compilation error.
//Pointers to structures
#include<stdio.h>
struct coord
{
int x, y,z;
}pt1={2,3,5}, *ptr1; //Declaration of structure
pointer at the
// time of structure definition
main()
{
struct coord pt2={4,5,6};
struct coord *ptr2=&pt2; //Declaration of
structure pointer in a
// separate declaration statement
ptr1=&pt1;
printf(“Addresses of pt1 and pt2 are %p
%pn”,&pt1,&pt2);
printf(“Addresses of ptr1 and ptr2 are %p
%pn”,&ptr1,&ptr2);
printf(“ptr1 and ptr2 point to %p
%pn”,ptr1,ptr2);
printf(“Size of type (struct coord) is %dn”,
sizeof(struct coord));
printf(“Size of type (struct
coord*) is %dn”,sizeof(struct
coord*));
printf(“pt1 and pt2 take %d
bytesn”, sizeof(pt1));
printf(“ptr1 and ptr2 take %d
bytesn”, sizeof(ptr1));
}
Output
Addresses of pt1 and pt2 are
2397:0076 2397:2292
Addresses of ptr1 and ptr2 are
2397:0D38 2397:228E
ptr1 and ptr2 point to 2397:0076
2397:2292
Size of type (struct coord) is 6
Size of type (struct coord*) is 4
pt1 and pt2 take 6 bytes
ptr1 and ptr2 take 4 bytes
Accessing Structure Members Via a
Pointer to a Structure
• The members of a structure object can be
accessed via a pointer to a structure
object by using one of the following two
ways:
1.By using the dereference or indirection
operator and the direct member access
operator
2.By using the indirect member access
operator (i.e. ->, known as the arrow
operator)
Important points about accessing the
structure members, via a pointer to the
structure object are
1.The general form to access a structure
member
(*pointer_to_structure_type).structure_mem
ber_name
2. It is mandatory to parenthesize the
dereference operator and the structure
pointer
The members of a structure object can also be
accessed via the pointer to the structure object
by using known as the indirect member access
operator or arrow operator.
pointer_to_structure_object->structure_member_name
The expression pointer_to_structure_object-
>structure_member_name is equivalent to the
expression
(*pointer_to_structure_object).structure_member_
name.
//Accessing structure members
via pointer to the structure object
#include<stdio.h>
struct coord
{
int x, y;
};
main()
{
struct coord pt={2,3};
struct coord *ptr=&pt;
// line no. 11
printf(“Coordinates of Pt1 are
(%d,%d)n”,(*ptr).x, (*ptr).y);
//line no. 12
printf(“Coordinates of Pt1 are
(%d,%d)n”,ptr->x, ptr->y);
}
Coordinates of Pt1 are (2,3)
Coordinates of Pt1 are (2,3)
Remarks:
• In line number 11, the structure
members are accessed via the
pointer to the structure object by
using the dereference operator
and direct member access
operator
• In line number 12, the structure
members are accessed by using
the indirect member access
operator
Array of Structures
• It is possible to create an array whose
elements are of structure type.
• Such an array is known as an array of
structures.
struct car
{
char make[20];
char model[30];
int year;
};
Here is how we can declare an array
of structure car.
struct car arr_car[10];
Initializing Array of Structures
• We can also initialize the array of structures using the
same syntax as that for initializing arrays.
• Let's take an example:
struct car
{
char make[20];
char model[30];
int year;
};
struct car arr_car[2] = {
{"Audi", "TT", 2016},
{"Bentley", "Azure", 2002}
};
#include <stdio.h>
#include <string.h>
struct student
{
int id;
char name[30];
float percentage;
};
int main()
{
int i;
struct student record[2];
// 1st student's record
record[0].id=1;
strcpy(record[0].name, "Raju");
record[0].percentage = 86.5;
// 2nd student's record
record[1].id=2;
strcpy(record[1].name, "Surendren");
record[1].percentage = 90.5;
// 3rd student's record
record[2].id=3;
strcpy(record[2].name, "Thiyagu");
record[2].percentage = 81.5;
for(i=0; i<3; i++)
{
printf(" Records of
STUDENT : %d n", i+1);
printf(" Id is: %d n",
record[i].id);
printf(" Name is: %s n",
record[i].name);
printf(" Percentage is:
%fnn",record[i].percentage);
}
return 0;
}
Structures within a Structure
(Nested Structures)
• A structure can be nested within another
structure.
• Nested structure in C is nothing but structure
within structure. One structure can be declared
inside other structure as we declare structure
members inside a structure.
• The structure variables can be a normal
structure variable or a pointer variable to access
the data.
#include <stdio.h>
#include <string.h>
struct student_college_detail
{
int college_id;
char college_name[50];
};
struct student_detail
{
int id;
char name[20];
float percentage;
// structure within structure
struct student_college_detail clg_data;
}stu_data;
int main()
{
struct student_detail stu_data = {1,
"Raju", 90.5, 71145, "Anna University"};
printf(" Id is: %d n", stu_data.id);
printf(" Name is: %s n",
stu_data.name);
printf(" Percentage is: %f nn",
stu_data.percentage);
printf(" College Id is: %d n",
stu_data.clg_data.college_id);
printf(" College Name is: %s n",
stu_data.clg_data.college_name);
return 0;
}
Functions and Structures
• The three ways of passing a structure
object to a function are as follows:
1. Passing each member of a structure
object as a separate argument
2. Passing the entire structure object by
value
3. Passing the structure object by
address/reference
Passing Each Member of a Structure
Object as a Separate Argument
• A structure object can be passed to a
function by passing each member of the
structure object.
• The members of the structure object can
be passed by value or by address /
reference.
#include<stdio.h>
struct complex
{
int re;
int im;
};
add_complex(int, int, int, int);
mult_complex(int*,int*,int*,int*);
main()
{
struct complex no1, no2;
printf(“Enter the real and imaginary parts of 1st number:t”);
scanf(“%d %d”,&no1.re, &no1.im);
printf(“Enter the real and imaginary parts of 2nd number:t”);
scanf(“%d %d”,&no2.re, &no2.im);
add_complex(no1.re, no1.im, no2.re, no2.im);
mult_complex(&no1.re, &no1.im, &no2. re, &no2.im);
}
add_complex(int a, int b, int c, int d)
{
if(b+d<0)
printf(“The result of their addition is %d%din”,a+c,b+d);
else
printf(“The result of their addition is %d+%din”,a+c,b+d);
}
mult_complex(int* a, int* b, int* c, int*d)
{
int re, im;
re=*a * *c-*b * *d;
im=*a * *d + *b * *c;
if(im<0)
printf(“The result of their multiplication is %d%din”,re, im);
else
printf(“The result of their multiplication is %d+%din”,re, im);
}
Output
Enter the real and imaginary parts of 1st number: 2 –3
Enter the real and imaginary parts of 2nd number: 4 5
The result of their addition is 6+2i
The result of their multiplication is 23–2i
• This method of passing a structure object
to a function is highly inefficient,
unmanageable and infeasible if the
number of members in a structure object
to be passed is large.
Passing a Structure Object by
Value
• The member-by-member copy behavior of
the assignment operator when applied on
structures makes it possible to pass a
structure object to, and return a structure
object from a function by value.
//Passing and returning structure objects by value
#include<stdio.h>
struct complex
{
int re;
int im;
};
struct complex add_complex(struct complex, struct complex);
main()
{
struct complex no1, no2, no3;
printf(“Enter the real and imaginary parts of 1st number:t”);
scanf(“%d %d”,&no1.re, &no1.im);
printf(“Enter the real and imaginary part of 2nd number:t”);
scanf(“%d %d”,&no2.re, &no2.im);
no3=add_complex(no1,no2);
if(no3.im<0)
printf(“The result of their addition is %d%din”,no3.re, no3.im);
else
printf(“The result of their addition is %d+%din”,no3.re, no3.im);
}
struct complex add_complex(struct complex a, struct complex b)
{
struct complex temp;
temp.re=a.re+b.re;
temp.im=a.im+b.im;
//It is invalid to write temp=a+b
return temp;
}
Output
Enter the real and imaginary parts of 1st number: 2 –3
Enter the real and imaginary parts of 2nd number: 4 5
The result of their addition is 6+2i
• This method of passing a structure object
to a function is better than the previous
method of the structure passing in which
each member of the object is passed
individually.
• If the number of members in a structure
object is quite large, this method involves
large data movement. In such a case, the
method of passing structure object via the
pointer will be more efficient.
//Taking reflection of a point about a line inclined at 45˚ to the x-axis
#include<stdio.h>
struct point
{
int x;
int y;
};
reflectpoint(struct point);
main()
{
struct point pt;
printf(“Enter the x and y coordinates of the point:t”);
scanf(“%d %d”,&pt.x, &pt.y);
reflectpoint(pt);
printf(“The x and y coordinates of the reflected point: (%d,%d)”,pt.x, pt.y);
}
reflectpoint(struct point pt)
{
int temp;
temp= pt.x;
pt.x=pt.y;
pt.y=temp;
}
Passing a Structure Object by
Address/Reference
• If the number of members in a structure
object is quite large, it is beneficial to pass
the structure object by address/reference.
• This method of passing the structure
object requires fixed data (i.e. equal to the
size of a pointer) movement irrespective of
the size of the structure object.
//Passing and returning structure objects by address/reference
#include<stdio.h>
struct complex
{
int re;
int im;
};
struct complex mult_complex(struct complex*, struct complex*);
main()
{
struct complex no1, no2, no3;
printf(“Enter the real and imaginary parts of 1st number:t”);
scanf(“%d %d”,&no1.re, &no1.im);
printf(“Enter the real and imaginary parts of 2nd number:t”);
scanf(“%d %d”,&no2.re, &no2.im);
no3=mult_complex(&no1,&no2);
if(no3.im<0)
printf(“The result of their multiplication is %d%din”,no3.re, no3.im);
else
printf(“The result of their multiplication is %d+%din”,no3.re, no3.im);
}
struct complex mult_complex(struct complex* a, struct complex* b)
{
struct complex temp;
temp.re=a->re*b->re-a->im*b->im;
temp.im=a->re*b->im+a->im*b->re;
//It is invalid to write temp=a*b
return temp;
}
Output
Enter the real and imaginary parts of 1st number: 2 –3
Enter the real and imaginary parts of 2nd number: 4 5
The result of their multiplication is 23–2i
• In this method of passing a structure
object, instead of passing the entire
structure object, only the address of a
structure object is passed.
• Hence, this method of structure passing
requires less data movement.
typedef and Structures
• The usage of the keyword struct while
declaring a structure object sometimes
proves to be a bit inconvenient.
• typedef can be used for creating syntactically
convenient names (i.e. aliases).
• Thus, it can be used to create an alias for the
defined structure type so that the keyword
struct is not required repeatedly to declare
the structure objects.
//Use of typedef to create an alias for a structure type
#include<stdio.h>
typedef struct name
{
char first_name[20];
char last_name[20];
} NAME;
struct phonebook_entry
{
NAME person_name;
char mobile_no[11];
};
typedef struct phonebook_entry PH_ENTRY;
main()
{
PH_ENTRY p1, p2;
printf(“Enter the details of the first person:n”);
printf(“Enter the first name of the person:t”);
gets(p1.person_name.first_name);
printf(“Enter the last name of the person:t”);
gets(p1.person_name.last_name);
printf(“Enter the mobile number:t”);
gets(p1.mobile_no);
printf(“nRecords in the phone book are::n”);
printf(“-------------------------------------n”);
printf(“%s %s:t %10sn”,p1.person_name.first_name,
p1.person_name.last_name, p1.mobile_no);
}
Output
Enter the details of the first person:
Enter the first name of the person: Sam
Enter the last name of the person: Mine
Enter the mobile number: 9870096971
Records in the phone book are::
---------------------------------------
Sam Mine: 9870096971
Mani Kumar: 9922134654
SPC Unit 5

SPC Unit 5

  • 1.
  • 2.
    Structures –Pointers toStructures – Array of Structures – Structures within a Structure – Functions and Structures – typedef and Structures – Unions–Practical Applications of Unions – Enumerations – Bit fields – Storage Classes – C Preprocessor – Files: Streams – File type – File operations – Command line arguments.
  • 3.
    Structures • C languageprovides the flexibility to create new data types. • These data types are known as user- defined data types and can be created by using structures, unions and enumerations.
  • 4.
    • Arrays canbe used for the storage of homogeneous data. • However, they cannot be used for the storage of data of different types. • The data of different types can be grouped together and stored by making use of structures. • One of the similarities between arrays and structures is that both of them contain a finite number of elements. • Thus, array types and structure types are collectively known as aggregate types.
  • 5.
    Structures A structure isa collection of variables under a single name and provides a convenient way of grouping several pieces of related information together. Unlike arrays, it can be used for the storage of heterogeneous data (i.e. data of different types).
  • 6.
    There are threeaspects of working with structures: 1.Defining a structure type, i.e. creating a new type 2.Declaring variables and constants (i.e. objects) of the newly created type 3.Using and performing operations on the objects of the structure type
  • 7.
    Defining a Structure Thegeneral form of structure-type definition (or just structure definition) is: [storage_class_specifier][type_qualifier] struct [structure_tag_name] { type member_name1[, member_name11, …]; [type member_name2[, member_name22, …]]; ……… } [variable_name];
  • 8.
    Important points aboutstructure definition 1.The terms enclosed within the square brackets are optional and might not be present in a structure definition statement. However, the terms shown in bold are the mandatory parts of the structure definition. 2.A structure definition consists of the keyword struct followed by an optional identifier name, known as structure tag- name, and a structure declaration-list enclosed within the braces.
  • 9.
    The structure definitiondefines a new type, known as structure type. For example, in Table (a) the structure type is struct book. After the definition of the structure type, the keyword struct is used to declare its variables. If the tag-name is present, it will act as a name for the newly created data type.
  • 10.
    //The defined structuretype is visible only in the scope in which it is defined #include<stdio.h> func(); //Declaration of the function func main() { struct coord //The type struct coord is defined in the scope local to the function main { int x,y; }; struct coord pt1, pt2; //Declaring variables pt1 and pt2 of the created type struct coord //Other statements in the function main // …………………………. } func() { struct coord pt3; //The tag name coord is not visible here //Other statements in the function func // …………………………. } Compilation errors “Undefined structure ‘coord’ in function func()” “Size of ‘pt3’ is unknown or zero in function func()”
  • 12.
    Structure members canbe variables of the basic types (e.g. char, int, float, etc.), pointer types (e.g. char*, etc.) or aggregate type (i.e. arrays or other structure types). They are declared in the same way as normal identifiers are declared.
  • 13.
    A structure declaration-listcannot contain a member of void type or incomplete type or function type. Hence, a structure definition cannot contain an instance of itself. However, it may contain a pointer to an instance of itself. Such a structure is known as a self- referential structure.
  • 16.
    Two different structuretypes may contain members of the same name without any conflict. It is important to note that a structure definition does not reserve any space in the memory.
  • 17.
    If a structuredefinition does not contain a structure tag-name, the created structure type is unnamed. The unnamed structure type is also known as an anonymous structure type. It is not possible to declare its objects (i.e. variables and constants) after its definition.
  • 19.
    //Use of storageclass specifier while defining a structure type #include<stdio.h> static struct point { int x; int y; }; main() { struct point pt1; //Other statements } Compilation error “Storage class ‘static’ not allowed here”. Remark: • The storage class specifiers except typedef should not be used in a structure-type definition if the objects are not declared at the time of structure definition
  • 20.
    Declaring Structure Objects •Variables and constants (i.e. objects) of the created structure type can be declared either at the time of structure definition or after the structure definition. • Variables and constants of the created structure type can be created after the structure definition only if the defined structure type is named or tagged.
  • 21.
    • The generalform of declaring structure objects is: [storage class specifi er] [type_qualifi er] struct named_structuretype identifier_name [=intialization_list [,…]]; The terms shown in bold are the mandatory parts of the structure object declaration
  • 22.
    • A structureobject declaration consists of: i. The keyword struct for declaring structure variables. It can also be used in conjunction with const qualifier for declaring structure constants. ii. The tag-name of the defined structure type. iii. Comma-separated list of identifiers (i.e. variable names or constant names). A variable can optionally be initialized by providing an initializer. However, initialization of a constant is must. iv. A terminating semicolon
  • 23.
    • The followingstructure variable declarations are valid: struct book c_book, algorithm_book; struct phonebook_entry entry; struct two_dimensional_coordinate pt1={2,3}, pt2; • The following structure constant declarations are valid: const struct book c_book, algorithm_book={“C Programming”, “Anirudh”, 450, 225.50}; const struct phonebook_entry entry={{“Mohit”,”Virmani”}, “1234567899”}; const struct two_dimensional_coordinate pt1={2,3}, pt2={4,5};
  • 24.
    • In Clanguage, the objects of the defined structure type cannot be declared without using the keyword struct. • Upon the declaration of a structure object, the amount of the memory space allocated to it is equal to the sum of the memory space required by all of its members. • The memory space allocated to a structure object can be determined by using the sizeof operator. • The structure members are assigned memory addresses in increasing order, with the first structure member starting at the beginning address of the structure itself.
  • 25.
    • Initializing membersof a structure object: Like variables and array elements, the members of a structure object can also be initialized at the compile time. • The syntactic rules about structure member initialization are as follows: i. The members of a structure object can be initialized by providing an initialization list. An initialization list is a comma-separated list of initializers. ii. The order of initializers must match the order of structure members in the structure definition.
  • 26.
    iii. The typeof each initializer should be the same as the type of corresponding structure member in the structure definition. iv. The number of initializers in an initialization list can be less than the number of members in a structure object and if it happens, the leading structure members (i.e. occurring first) will be initialized with the initializers in the initialization list. The rest of the members will automatically be initialized with 0 (if they are of integer type) Examples of structure member initialization are as follows: struct book c_book={“My Life”, “C Motilal”, 400, 210.50}; struct phonebook_entry entry={{“Rajesh”,”Kumar”}, “9814000561”}; struct two_dimensional_coordinate pt1={2}, pt2={2,3};
  • 27.
    //Using type qualifierswhile declaring a structure object #include<stdio.h> struct point { int x; int y; }; main() { const struct point pt={2,3}; pt.x=20; pt.y=40; //Other statements... } Compilation errors “Cannot modify a constant object in function main()” Remarks: • To access the members of a structure object, the member access operator, i.e. dot operator is used. • The type qualifier const is applied to all the members of the structure object. Hence, the type of pt.x and pt.y is const int and thus, it is not possible to place them on the left side of the assignment operator
  • 28.
    A structure objectdeclaration can optionally have a storage class specifier. i. If a structure object is declared with a storage class specifier other than typedef, the properties resulting from the storage class specifier except with respect to linkage, also apply to the members of the object.
  • 29.
    //Declaring structure objectwith a storage class specifier other than //typedef #include<stdio.h> struct point { int x; int y; }; main() { struct point pt1; static struct point pt2; printf(“The coordinates of pt1 are %d,%dn”, pt1.x, pt1.y); printf(“The coordinates of pt2 are %d,%dn”, pt2.x, pt2.y); } The coordinates of pt1 are 9495,19125 The coordinates of pt2 are 0.0 • Since the structure object pt2 is declared with static storage class qualifier, all the properties resulting from it except linkage, are applicable to all the members of the structure object pt2 •• To access the members of a structure object, the member access operator, i.e. dot operator is used.
  • 30.
    Operations on Structures •The operations that can be performed on an object (i.e. variable or constant) of a structure type are classified into two categories: 1.Aggregate operations 2. Segregate operations
  • 31.
    Aggregate Operations An aggregateoperation treats an operand as an entity and operates on the entire operand as a whole instead of operating on its constituent members. The four aggregate operations that can be applied on an object of a structure type are as follows: 1.Accessing members of an object of a structure type 2.Assigning a structure object to a structure variable 3.Address of a structure object 4.Size of a structure (i.e. either structure type or a
  • 32.
    Accessing Members ofan Object of a Structure Type The members of a structure object can be accessed by using: 1. Direct member access operator (i.e. ., also known as dot operator). 2. Indirect member access operator (i.e. ->, also known as arrow operator).
  • 33.
    #include<stdio.h> struct coord //Definitionof type struct coord { // Creation of new type for 2-D coordinate int x,y; }; main() { struct coord pt1={4,5}; //pt1 is a variable of type struct coord const struct coord pt2={2,3}; //pt2 is a qualified constant of type struct coord int tx, ty; printf(“Enter values of translation vector:n”); scanf(“%d %d”,&tx, &ty); printf(“After translation, coordinates are:n”); printf(“Pt1 (%d,%d)n”, pt1.x+tx, pt1.y+ty); printf(“Pt2 (%d,%d)n”, pt2.x+tx, pt2.y+ty); } Enter values of translation vector: 4 2 After translation, coordinates are: Pt1 (8,7) Pt2 (6,5)
  • 34.
    Assigning a StructureObject to a Structure Variable Like simple variables, a structure variable can be assigned with or initialized with a structure object (i.e. variable or constant) of the same structure type.
  • 35.
    //Initialization and assignmentof a structure variable #include<stdio.h> struct book //Structure definition { char title[25]; char author[20]; int price; }; main() { //Initializing a structure variable by providing an initialization list struct book b1={“Cutting Stone”, “Abraham”, 200}: //Initializing a structure variable with another structure variable struct book b2=b1; // Declaring an uninitialized structure variable struct book b3; b3=b2; //Assigning a structure variable to a structure variable printf(“%s by %s is of Rs. %d rupeesn”, b1.title, b1.author, b1.price); printf(“%s by %s is of Rs. %d rupeesn”, b2.title, b2.author, b2.price); printf(“%s by %s is of Rs. %d rupeesn”, b3.title, b3.author, b3.price); }
  • 36.
    Address-of a StructureObject • The address-of operator when applied on a structure object gives its base (i.e. starting) address. • It can also be used to find the addresses of the constituting members of a structure object.
  • 37.
    //Address-of operator andstructures #include<stdio.h> struct complex { int re, im; }; main() { struct complex c1={2,3}; const struct complex c2={4,5}; printf(“Address of c1 is %pn”,&c1); printf(“Address of its real part is %pn”,&c1.re); printf(“Address of its imaginary part is %pn”,&c1.im); printf(“Address of c2 is %pn”,&c2); printf(“Address of its real part is %pn”,&c2.re); printf(“Address of its imaginary part is %pn”,&c2.im); } Address of c1 is 233F:222C Address of its real part is 233F:222C Address of its imaginary part is 233F:222E Address of c2 is 233F:223C Address of its real part is 233F:223C Address of its imaginary part is 233F:223E
  • 38.
    Byte aligned: Ifthe members of a structure object are byte aligned, then every structure member starts from a new byte (i.e. they can appear at any byte boundary). In byte alignment, the data members are stored next to each other.
  • 39.
    Machine-word boundary aligned:Most of the machines access objects of certain types faster if they are aligned properly. In order to increase the performance of the code on such machines, the compiler aligns the members of a structure object with the storage boundaries whose addresses are multiple of their respective sizes.
  • 40.
    Equating Structure Objectsof the Same Type The use of an equality operator on the operands of a structure type is not allowed and leads to a compilation error. //Equality operator and structures #include<stdio.h> #pragma pack(2) struct pad { char a; int b; char c; float d; }; main() { struct pad var1={‘A’, 2, ‘B’, 2.5}, var2={‘A’, 2, ‘B’, 2.5}; if(var1==var2) printf(“Structure variables are equaln”); else printf(“Structure variables are unequaln”); }
  • 41.
    Equating Structure Objectsof the Same Type The use of an equality operator on the operands of a structure type is not allowed and leads to a compilation error.
  • 42.
    Pointers to Structures •The pointers to structures have the following advantages: 1. It is easier to manipulate the pointers to structures than manipulating structures themselves.
  • 43.
    2. Passing apointer to a structure as an argument to a function is efficient as compared to passing a structure to a function. • The size of a pointer to a structure is generally smaller than the size of the structure itself. • Thus, passing a pointer to a structure as an argument to a function requires less data movement as compared to passing the structure to a function.
  • 44.
    3. Some wondrousdata structures (e.g. linked lists, trees, etc.) use the structures containing pointers to structures. Pointers to structures play an important role in their successful implementation.
  • 45.
    Declaring Pointer toa Structure • The general form of declaring a pointer to a structure is: [storage_class_specifi er] [type_qualifi er] struct named_structure_type* identifi er_name
  • 46.
    1. The termsshown in bold are the mandatory parts of a structure pointer declaration statement. 2. A pointer to a structure type can be declared in a separate declaration statement only if the structure type is named. If the structure type is unnamed, the structure pointer should be created at the time of structure definition. 3. The declared structure pointer can optionally be initialized with an l-value. The initializing l-value should be of appropriate type, else there will be a compilation error.
  • 47.
    //Pointers to structures #include<stdio.h> structcoord { int x, y,z; }pt1={2,3,5}, *ptr1; //Declaration of structure pointer at the // time of structure definition main() { struct coord pt2={4,5,6}; struct coord *ptr2=&pt2; //Declaration of structure pointer in a // separate declaration statement ptr1=&pt1; printf(“Addresses of pt1 and pt2 are %p %pn”,&pt1,&pt2); printf(“Addresses of ptr1 and ptr2 are %p %pn”,&ptr1,&ptr2); printf(“ptr1 and ptr2 point to %p %pn”,ptr1,ptr2); printf(“Size of type (struct coord) is %dn”, sizeof(struct coord)); printf(“Size of type (struct coord*) is %dn”,sizeof(struct coord*)); printf(“pt1 and pt2 take %d bytesn”, sizeof(pt1)); printf(“ptr1 and ptr2 take %d bytesn”, sizeof(ptr1)); } Output Addresses of pt1 and pt2 are 2397:0076 2397:2292 Addresses of ptr1 and ptr2 are 2397:0D38 2397:228E ptr1 and ptr2 point to 2397:0076 2397:2292 Size of type (struct coord) is 6 Size of type (struct coord*) is 4 pt1 and pt2 take 6 bytes ptr1 and ptr2 take 4 bytes
  • 49.
    Accessing Structure MembersVia a Pointer to a Structure • The members of a structure object can be accessed via a pointer to a structure object by using one of the following two ways: 1.By using the dereference or indirection operator and the direct member access operator 2.By using the indirect member access operator (i.e. ->, known as the arrow operator)
  • 50.
    Important points aboutaccessing the structure members, via a pointer to the structure object are 1.The general form to access a structure member (*pointer_to_structure_type).structure_mem ber_name 2. It is mandatory to parenthesize the dereference operator and the structure pointer
  • 51.
    The members ofa structure object can also be accessed via the pointer to the structure object by using known as the indirect member access operator or arrow operator. pointer_to_structure_object->structure_member_name The expression pointer_to_structure_object- >structure_member_name is equivalent to the expression (*pointer_to_structure_object).structure_member_ name.
  • 52.
    //Accessing structure members viapointer to the structure object #include<stdio.h> struct coord { int x, y; }; main() { struct coord pt={2,3}; struct coord *ptr=&pt; // line no. 11 printf(“Coordinates of Pt1 are (%d,%d)n”,(*ptr).x, (*ptr).y); //line no. 12 printf(“Coordinates of Pt1 are (%d,%d)n”,ptr->x, ptr->y); } Coordinates of Pt1 are (2,3) Coordinates of Pt1 are (2,3) Remarks: • In line number 11, the structure members are accessed via the pointer to the structure object by using the dereference operator and direct member access operator • In line number 12, the structure members are accessed by using the indirect member access operator
  • 53.
    Array of Structures •It is possible to create an array whose elements are of structure type. • Such an array is known as an array of structures.
  • 54.
    struct car { char make[20]; charmodel[30]; int year; }; Here is how we can declare an array of structure car. struct car arr_car[10];
  • 55.
    Initializing Array ofStructures • We can also initialize the array of structures using the same syntax as that for initializing arrays. • Let's take an example: struct car { char make[20]; char model[30]; int year; }; struct car arr_car[2] = { {"Audi", "TT", 2016}, {"Bentley", "Azure", 2002} };
  • 56.
    #include <stdio.h> #include <string.h> structstudent { int id; char name[30]; float percentage; }; int main() { int i; struct student record[2]; // 1st student's record record[0].id=1; strcpy(record[0].name, "Raju"); record[0].percentage = 86.5; // 2nd student's record record[1].id=2; strcpy(record[1].name, "Surendren"); record[1].percentage = 90.5; // 3rd student's record record[2].id=3; strcpy(record[2].name, "Thiyagu"); record[2].percentage = 81.5; for(i=0; i<3; i++) { printf(" Records of STUDENT : %d n", i+1); printf(" Id is: %d n", record[i].id); printf(" Name is: %s n", record[i].name); printf(" Percentage is: %fnn",record[i].percentage); } return 0; }
  • 57.
    Structures within aStructure (Nested Structures) • A structure can be nested within another structure. • Nested structure in C is nothing but structure within structure. One structure can be declared inside other structure as we declare structure members inside a structure. • The structure variables can be a normal structure variable or a pointer variable to access the data.
  • 58.
    #include <stdio.h> #include <string.h> structstudent_college_detail { int college_id; char college_name[50]; }; struct student_detail { int id; char name[20]; float percentage; // structure within structure struct student_college_detail clg_data; }stu_data; int main() { struct student_detail stu_data = {1, "Raju", 90.5, 71145, "Anna University"}; printf(" Id is: %d n", stu_data.id); printf(" Name is: %s n", stu_data.name); printf(" Percentage is: %f nn", stu_data.percentage); printf(" College Id is: %d n", stu_data.clg_data.college_id); printf(" College Name is: %s n", stu_data.clg_data.college_name); return 0; }
  • 59.
    Functions and Structures •The three ways of passing a structure object to a function are as follows: 1. Passing each member of a structure object as a separate argument 2. Passing the entire structure object by value 3. Passing the structure object by address/reference
  • 60.
    Passing Each Memberof a Structure Object as a Separate Argument • A structure object can be passed to a function by passing each member of the structure object. • The members of the structure object can be passed by value or by address / reference.
  • 61.
    #include<stdio.h> struct complex { int re; intim; }; add_complex(int, int, int, int); mult_complex(int*,int*,int*,int*); main() { struct complex no1, no2; printf(“Enter the real and imaginary parts of 1st number:t”); scanf(“%d %d”,&no1.re, &no1.im); printf(“Enter the real and imaginary parts of 2nd number:t”); scanf(“%d %d”,&no2.re, &no2.im); add_complex(no1.re, no1.im, no2.re, no2.im); mult_complex(&no1.re, &no1.im, &no2. re, &no2.im); } add_complex(int a, int b, int c, int d) { if(b+d<0) printf(“The result of their addition is %d%din”,a+c,b+d); else
  • 62.
    printf(“The result oftheir addition is %d+%din”,a+c,b+d); } mult_complex(int* a, int* b, int* c, int*d) { int re, im; re=*a * *c-*b * *d; im=*a * *d + *b * *c; if(im<0) printf(“The result of their multiplication is %d%din”,re, im); else printf(“The result of their multiplication is %d+%din”,re, im); } Output Enter the real and imaginary parts of 1st number: 2 –3 Enter the real and imaginary parts of 2nd number: 4 5 The result of their addition is 6+2i The result of their multiplication is 23–2i
  • 63.
    • This methodof passing a structure object to a function is highly inefficient, unmanageable and infeasible if the number of members in a structure object to be passed is large.
  • 64.
    Passing a StructureObject by Value • The member-by-member copy behavior of the assignment operator when applied on structures makes it possible to pass a structure object to, and return a structure object from a function by value.
  • 65.
    //Passing and returningstructure objects by value #include<stdio.h> struct complex { int re; int im; }; struct complex add_complex(struct complex, struct complex); main() { struct complex no1, no2, no3; printf(“Enter the real and imaginary parts of 1st number:t”); scanf(“%d %d”,&no1.re, &no1.im); printf(“Enter the real and imaginary part of 2nd number:t”); scanf(“%d %d”,&no2.re, &no2.im); no3=add_complex(no1,no2); if(no3.im<0) printf(“The result of their addition is %d%din”,no3.re, no3.im); else printf(“The result of their addition is %d+%din”,no3.re, no3.im); }
  • 66.
    struct complex add_complex(structcomplex a, struct complex b) { struct complex temp; temp.re=a.re+b.re; temp.im=a.im+b.im; //It is invalid to write temp=a+b return temp; } Output Enter the real and imaginary parts of 1st number: 2 –3 Enter the real and imaginary parts of 2nd number: 4 5 The result of their addition is 6+2i
  • 67.
    • This methodof passing a structure object to a function is better than the previous method of the structure passing in which each member of the object is passed individually. • If the number of members in a structure object is quite large, this method involves large data movement. In such a case, the method of passing structure object via the pointer will be more efficient.
  • 68.
    //Taking reflection ofa point about a line inclined at 45˚ to the x-axis #include<stdio.h> struct point { int x; int y; }; reflectpoint(struct point); main() { struct point pt; printf(“Enter the x and y coordinates of the point:t”); scanf(“%d %d”,&pt.x, &pt.y); reflectpoint(pt); printf(“The x and y coordinates of the reflected point: (%d,%d)”,pt.x, pt.y); } reflectpoint(struct point pt) { int temp; temp= pt.x; pt.x=pt.y; pt.y=temp; }
  • 69.
    Passing a StructureObject by Address/Reference • If the number of members in a structure object is quite large, it is beneficial to pass the structure object by address/reference. • This method of passing the structure object requires fixed data (i.e. equal to the size of a pointer) movement irrespective of the size of the structure object.
  • 70.
    //Passing and returningstructure objects by address/reference #include<stdio.h> struct complex { int re; int im; }; struct complex mult_complex(struct complex*, struct complex*); main() { struct complex no1, no2, no3; printf(“Enter the real and imaginary parts of 1st number:t”); scanf(“%d %d”,&no1.re, &no1.im); printf(“Enter the real and imaginary parts of 2nd number:t”); scanf(“%d %d”,&no2.re, &no2.im); no3=mult_complex(&no1,&no2); if(no3.im<0) printf(“The result of their multiplication is %d%din”,no3.re, no3.im); else printf(“The result of their multiplication is %d+%din”,no3.re, no3.im); }
  • 71.
    struct complex mult_complex(structcomplex* a, struct complex* b) { struct complex temp; temp.re=a->re*b->re-a->im*b->im; temp.im=a->re*b->im+a->im*b->re; //It is invalid to write temp=a*b return temp; } Output Enter the real and imaginary parts of 1st number: 2 –3 Enter the real and imaginary parts of 2nd number: 4 5 The result of their multiplication is 23–2i
  • 72.
    • In thismethod of passing a structure object, instead of passing the entire structure object, only the address of a structure object is passed. • Hence, this method of structure passing requires less data movement.
  • 73.
    typedef and Structures •The usage of the keyword struct while declaring a structure object sometimes proves to be a bit inconvenient. • typedef can be used for creating syntactically convenient names (i.e. aliases). • Thus, it can be used to create an alias for the defined structure type so that the keyword struct is not required repeatedly to declare the structure objects.
  • 74.
    //Use of typedefto create an alias for a structure type #include<stdio.h> typedef struct name { char first_name[20]; char last_name[20]; } NAME; struct phonebook_entry { NAME person_name; char mobile_no[11]; }; typedef struct phonebook_entry PH_ENTRY; main() { PH_ENTRY p1, p2; printf(“Enter the details of the first person:n”); printf(“Enter the first name of the person:t”); gets(p1.person_name.first_name); printf(“Enter the last name of the person:t”); gets(p1.person_name.last_name); printf(“Enter the mobile number:t”); gets(p1.mobile_no);
  • 75.
    printf(“nRecords in thephone book are::n”); printf(“-------------------------------------n”); printf(“%s %s:t %10sn”,p1.person_name.first_name, p1.person_name.last_name, p1.mobile_no); } Output Enter the details of the first person: Enter the first name of the person: Sam Enter the last name of the person: Mine Enter the mobile number: 9870096971 Records in the phone book are:: --------------------------------------- Sam Mine: 9870096971 Mani Kumar: 9922134654