Structure
Structure in C allows us to create a complex data type. This new type can
hold multiple values of different types. If you are familiar with enum in C,
the syntax to define a structure will be easy for you.
A structure contains a number of data types grouped together. These data
types may or may not be of the same type.
Declaring a Structure
We create structures with the keyword struct. Normally we create them in a
separate header file. Another option is to define them in our .c files, outside
or inside of any function.
The general form of a structure declaration statement is given below:
struct <structure name>
structure element 1 ;
structure element 2 ;
structure element 3 ;
......
......
};
The keyword struct tells the compiler that we are creating a structure
The <structure name> is the name of the structure. We can use it later to
create variables. We call these variables instances.
Inside the body, we define the members. We can define as many as we need.
Their type could be any valid C type, including other structures, unions etc.
After the body we have the option to create a list of variables of the current
type. To do this, we just write their names and separate them with a comma.
Don’t forget the semicolon in the end! It is mandatory.
Example: Defining a structure in C
employee.h
struct Employee
char name[30];
char address[50];
int age;
};
Creating instances
There are several ways to create variables of the struct type that you
created. The first way is to list the variable names after the structure
definition like this:
struct Employee
char name[30];
char address[50];
int age;
} employee1, employee 2, employee 3;
Now you can work with the three employee variables.
I like to separate the types and the variables, so I prefer the second way.
After you define the structure, use its Tag and the keyword struct to create a
variable:
struct Employee worker1;
Also, you can declare a pointer:
struct Employee* worker2;
Accessing members
To access a member of a structure in C we use the dot ‘.’ and the arrow ‘->’
operators.
We use the dot operator when we work with an instance:
struct Employee worker1;
worker1.age = 20;
We use the arrow operator when we work with a pointer to an instance:
struct Employee* worker2;
worker2->age = 20;
Creating a complex structure in C
A complex structure is such that contains at least one member of complex
type – for instance another structure. Let’s take the address member from
above. Instead of keeping it in a string field, we can define it like this:
struct Employee
struct Address
char country[30];
char city[30];
char street[30];
char addressField[30];
} address;
char name[30];
int age;
};
or like this:
address.h
struct Address
{
char country[30];
char city[30];
char street[30];
char addressField[30];
};
employee.h
struct Employee
struct Address address;
char name[30];
int age;
};
Padding
In C, by default the data in a structure is automatically padded. The
padding is adding empty bytes in the memory in order to align the data.
This is done for two reasons:
For faster data access
On many processors data alignment is mandatory.
On most processor architectures data alignment is mandatory - for instance
on processors with RISC architectures (ARM, MIPS…). Unaligned data is
allowed on processors with CISC architecture (almost all desktop computers
x86, x64..).
Here is how we define an example structure in C:
struct A
char symbol;
int number;
short id;
};
And here is how it really looks in the memory:
struct A
char symbol; // 1 byte in memory
char CHAR_PADDING[3]; // 3 bytes padding
int number; // 4 bytes - no padding needed
short id; // 2 bytes in memory
char SHORT_PADDING[2]; // 2 bytes padding
};
We can optimize our structures, by sorting their members by size. This
results in more efficient placement in the memory and less padding bytes.
For instance, we can optimize the above definition like this:
struct A
int number;
short id;
char symbol;
};
Now only 1 byte padding is necessary at the end of the definition. In the
memory it looks like this:
struct A
int number; // 4 bytes - no padding needed
short id; // 2 bytes in memory
char symbol; // 1 byte in memory
char PADDING[1]; // 1 byte padding
};
Uses of Structures
a) Changing the size of the cursor
b) Clearing the contents of the screen
c) Placing the cursor at an appropriate position on screen
d) Drawing any graphics shape on the screen
e) Receiving a key from the keyboard
f) Checking the memory size of the computer
g) Finding out the list of equipment attached to the computer
h) Formatting a floppy
i) Hiding a file from the directory
j) Displaying the directory of a disk
k) Sending the output to printer
l) Interacting with the mouse
Example 1
void main( )
struct book
char name ;
float price ;
int pages ;
};
struct book b1, b2, b3 ;
printf ( "\nEnter names, prices & no. of pages of 3 books\n" ) ;
scanf ( "%c %f %d", &b1.name, &b1.price, &b1.pages ) ;
scanf ( "%c %f %d", &b2.name, &b2.price, &b2.pages ) ;
scanf ( "%c %f %d", &b3.name, &b3.price, &b3.pages ) ;
printf ( "\nAnd this is what you entered" ) ;
printf ( "\n%c %f %d", b1.name, b1.price, b1.pages ) ;
printf ( "\n%c %f %d", b2.name, b2.price, b2.pages ) ;
printf ( "\n%c %f %d", b3.name, b3.price, b3.pages ) ;
Example 2
/* Memory map of structure elements */
void main( )
struct book
char name ;
float price ;
int pages ;
};
struct book b1 = { 'B', 130.00, 550 } ;
printf ( "\nAddress of name = %u", &b1.name ) ;
printf ( "\nAddress of price = %u", &b1.price ) ;
printf ( "\nAddress of pages = %u", &b1.pages ) ;
Example 3
/* Usage of an array of structures */
void main( )
{
struct book
char name ;
float price ;
int pages ;
};
struct book b[100] ;
int i ;
for ( i = 0 ; i <= 99 ; i++ )
printf ( "\nEnter name, price and pages " ) ;
scanf ( "%c %f %d", &b[i].name, &b[i].price, &b[i].pages ) ;
for ( i = 0 ; i <= 99 ; i++ )
printf ( "\n%c %f %d", b[i].name, b[i].price, b[i].pages ) ;
Example 4
void main( )
struct employee
char name[10] ;
int age ;
float salary ;
};
struct employee e1 = { "Sanjay", 30, 5500.50 } ;
struct employee e2, e3 ;
/* piece-meal copying */
strcpy ( e2.name, e1.name ) ;
e2.age = e1.age ;
e2.salary = e1.salary ;
/* copying all elements at one go */
e3 = e2 ;
printf ( "\n%s %d %f", e1.name, e1.age, e1.salary ) ;
printf ( "\n%s %d %f", e2.name, e2.age, e2.salary ) ;
printf ( "\n%s %d %f", e3.name, e3.age, e3.salary ) ;
Example 5
void main( )
struct address
char phone[15] ;
char city[25] ;
int pin ;
};
struct emp
char name[25] ;
struct address a ;
};
struct emp e = { "jeru", "531046", "nagpur", 10 };
printf ( "\nname = %s phone = %s", e.name, e.a.phone ) ;
printf ( "\ncity = %s pin = %d", e.a.city, e.a.pin ) ;
Example 6
/* Passing individual structure elements */
void main( )
struct book
char name[25] ;
char author[25] ;
int callno ;
};
struct book b1 = { "Let us C", "YPK", 101 } ;
display ( b1.name, b1.author, b1.callno ) ;
display ( char *s, char *t, int n )
printf ( "\n%s %s %d", s, t, n ) ;
Example 7
struct book
char name[25] ;
char author[25] ;
int callno ;
};
void main( )
struct book b1 = { "Let us C", "YPK", 101 } ;
display ( b1 ) ;
display ( struct book b )
printf ( "\n%s %s %d", b.name, b.author, b.callno ) ;
Example 8
void main( )
struct book
char name[25] ;
char author[25] ;
int callno ;
};
struct book b1 = { "Let us C", "YPK", 101 } ;
struct book *ptr ;
ptr = &b1 ;
printf ( "\n%s %s %d", b1.name, b1.author, b1.callno ) ;
printf ( "\n%s %s %d", ptr->name, ptr->author, ptr->callno ) ;
Example 9
/* Passing address of a structure variable */
struct book
char name[25] ;
char author[25] ;
int callno ;
};
void main( )
struct book b1 = { "Let us C", "YPK", 101 } ;
display ( &b1 ) ;
display ( struct book *b )
printf ( "\n%s %s %d", b->name, b->author, b->callno ) ;