To share this page click on the buttons below;
Structures
Structures give the programmer the possibility to group together 2 or more related variables of different types. The purpose is very different from arrays: with arrays you create long sequences of the same type of variable, with structures you group different kind of variables which describe all together something a single variable is not able to.
That is something very common. For example you want to identify each point of the screen using 2 Cartesian coordinates: in this case you can use a ‘Point‘ structure to group together the horizontal and the vertical position. Perhaps you want to implement a simple telephone book and you need to group together all the information (name, address, phone, e-mail and so on...) of your contacts: a structure is the suitable construct for that purpose.
Defining a structure
You define a structure by using the reserved word struct
following by a tag (just the name of your structure) followed by a pair of braces: inside the braces you define all the variables that will set up your structure (i.e. all the variables that belong to the structure). The definition of these variables is done using the same syntax used to define a single variable (but here we are inside the braces of the structure).
For example the previous structures for a Point and for a book phone contact can be defined in this way:
struct tagPoint {
unsigned int x;
unsigned int y;
};
struct tagPhoneContact {
char name[32];
char first_name[32];
char phone[16];
char e_mail[64];
int age;
};
As you can see a structure can contain arrays and can contain structures too: you can define a structure that contains another structure. For example suppose that you want to use the Point structure defined above to store the information about a rectangle: a good solution might be to memorize the coordinates of the top left corner and the coordinates of the bottom right corner of the rectangle.
You can in this case define a Rectangle
structure that contains 2 Point
structures, one for the top left corner and one for the bottom right corner.
Structure variables and fields
A good way to think about a structure is simply as a new type of variable (a composite one). The true meaning of this sentence is much deeper than what might appear at a first glance, this is a fairly complex argument that starts from the concept of type definition (which is still inside the boundaries of the C language) and leads to the object oriented languages, but we will see all that later on.
If you think a structure as a new type you can declare a new variable using the usual syntax: type – variable name. So to define a "Point" variable or a "PhoneContact" variable you can write something like that:
struct tagPoint pt;
struct tagPhoneContact cnt
You can initialize (and so define a variable) by assigning a series of values of the correct type in the correct order enclosed in a pair of braces. So if you want to initialize the "Point" variable you can do something like the following:
struct tagPoint pt = {3 , 5};
As well if you want to initialize a "PhoneContact" variable you can use something like that:
struct tagPhoneContact cnt = {
"John",
"Smith",
"555-123456",
"j.smith@mail.com",
32
};
The variables used inside the structure are usually referred as the fields of the structure. Given the name of the struct variable it is possible to access each field of the structure using the . (dot) operator. That is very simple: the point allows you to access each individual variable inside the structure, use the name of the variable "dot" the name of inner variable. If the inner variable is again a structure you can add a new "dot" to access the field of this inner structure and so on. Once you have the access to the variable you want you can use it as you do for any other regular variable.
So you access the x coordinate of the point by writing something like the following (here we access the fields of the point structure print them on the screen):
pt.x = 12;
pt.y = 15;
printf("\nPoint pt is at x = %u, y = %u\n",pt.x, pt.y);
In the same way you access the name and all the other fields of a Phone Contact variable by writing
printf("\nThe Phone of %s %s (age %i) is %s and the e-mail is %s\n",
cnt.name,
cnt.first_name,
cnt.age,
cnt.phone,
cnt.e_mail);
You can assign a whole structure variable to another one like this:
pt = pt1;
printf("\nPoint pt is now is at x = %u, y = %u\n",pt.x, pt.y);
You can write a function that takes one or more structure variables as argument and a structure variable is a valid return value. On the fact to use structures as function argument it is worth to remind that by default the arguments of a functions are passed by copy: in other word each time the function is called a whole copy of the variable is performed and put into the scope of the function. This operation has 2 consequences: the first is well known, each change you made on the structure variable argument is local to the function and it will not affect the value of the variable outside the function; the second one is less obvious, but sometimes it has to be taken into account: making a copy requires resources (memory) and time, for this reason sometimes it is preferable to pass a pointer to structure variable instead of the variable itself. Bear that in mind, a following chapter will be devoted to see how function calling is performed and why sometimes (on small low resources system) that has to be taken into account.
A complete example
The following example summarizes all the previous concepts.
#include <stdio.h>
/* program to demonstrate structures */
/* a struct to group together 2 cartesian coordinates */
struct tagPoint {
unsigned int x;
unsigned int y;
};
/* a Rectangle structure made up by two point structure */
struct tagRect {
struct tagPoint top_left;
struct tagPoint bottom_right;
};
/* a phone contact structure example */
struct tagPhoneContact {
char name[32];
char first_name[32];
char phone[16];
char e_mail[64];
int age;
};
void main(void) {
printf("PROGRAM to demonstrate some stuff on STRUCTURES\n");
/* declaration of a variable pt "of type" struct tagPoint */
struct tagPoint pt;
/* declaration of a variable rc "of type" struct tagRect */
struct tagRect rc;
/* definition of a pt1 variable "of type" struct tagPoint */
struct tagPoint pt1 = {3 , 5};
printf("\nPoint 1 a is at x = %u, y = %u\n",pt1.x, pt1.y);
/* definition of a cnt variable "of type" struct tagPhoneContact */
struct tagPhoneContact cnt = {
"John", "Smith", "555-123456", "j.smith@mail.com", 32
};
printf("\nThe Phone of %s %s (age %i) is %s and the e-mail is %s\n",
cnt.name,
cnt.first_name,
cnt.age,
cnt.phone,
cnt.e_mail);
/* definition of a rc1 variable "of type" struct tagRect */
struct tagRect rc1 = {
3,5,6,7
};
printf("\nThe rectangle rc1 is %i wide",rc1.bottom_right.x - rc1.top_left.x);
printf(" and %i high\n",rc1.bottom_right.y - rc1.top_left.y);
/* definition of a rc2 variable "of type" struct tagRect */
struct tagRect rc2 = {
{18,14} , {51,42}
};
printf("\nThe rectangle rc2 is %i wide",rc2.bottom_right.x - rc2.top_left.x);
printf(" and %i high\n",rc2.bottom_right.y - rc2.top_left.y);
/* deferred initialization of the 2 fields of the point structure */
pt.x = 12;
pt.y = 15;
printf("\nPoint pt is at x = %u, y = %u\n",pt.x, pt.y);
/* assignement of the whole structure */
pt = pt1;
printf("\nPoint pt is now is at x = %u, y = %u\n",pt.x, pt.y);
/* deferrend initialization of the fields of the variable rc*/
rc.top_left.x = 5;
rc.top_left.y = 56;
rc.bottom_right.x = 15;
rc.bottom_right.y = 104;
printf("\nThe rectangle rc is %i wide",rc.bottom_right.x - rc.top_left.x);
printf(" and %i high\n",rc.bottom_right.y - rc.top_left.y);
}
To share this page click on the buttons below;