Data Structures

There are often occasions when it is desirable to view a group of data items with different data types as a single entity. A student record in a database, for example, might consist of the student's name, address, telephone number, date of birth and student ID number. These data items provide information about the student, and each student record will consist of a similar set of data items. A structure is a set of related data elements grouped together as a single entity. Each data element is a member of the structure, with its own data type. Structures are declared in C++ using the following syntax:

struct structure_name
{
  type variable_name_1;
  type variable_name_2;
  type variable_name_3;
  .
  .
  .
} object_names;

In the above example, structure_name is the name given to the structure type, while object_names represents an optional list of objects of type structure_name. The data members are listed between the opening and closing curly braces { }. The declaration for each data member specifies the member's data type, followed by its variable name (or identifier). Once the structure has been declared, objects of this new type can be declared and initialised in the program in the same way as other types of variable. The following code fragment creates a structure type called stock_item and declares two objects of that type:

struct stock_item
{
  int quantity;
  float value;
};
.
.
.
stock_item widget, grommet;

In the example above, the objects widget and grommet are declared in a separate program statement, but we could also declare them at the same time we define the stock_item structure, as shown here:

struct stock_item
{
  int quantity;
  float value;
} widget, grommet;

An object such as widget is said to be an instantiation of a structure type (in this case stock_item). Once a structure type has been declared, we can create as many objects of that data type as we like.

In order to work with the individual structure elements for an object of a given structure type, we need to identify both the object and the element within that object with which we wish to work. The following code fragment assigns values to the data items in the object widget:

widget.quantity = 24;
widget.value = 2.49;

Note that each element is referenced using the object's name, and the name of the data element, separated by a period. The simple program below demonstrates the creation and use of a structure.

// Example Program 1

#include <iostream>
#include <string.h>
#include <sstream>
using namespace std;

struct film
{
  string title;
  int year;
} favourite;

void show_favourite (film fav_film);

int main ()
{
  string input_str;
  cout << "Enter the title of your favourite film: ";
  getline (cin, favourite.title);
  cout << "\nEnter the year the film was released: ";
  getline (cin, input_str);
  stringstream(input_str) >> favourite.year;

  cout << "\nYour favourite film is: ";
  show_favourite (favourite);

  cout << "\nPress ENTER to continue.";
  getline( cin, input_str );
  return 0;
}

void show_favourite (film fav_film)
{
  cout << fav_film.title;
  cout << " (" << fav_film.year << ")\n";
}


The output from example program 1

The output from example program 1

Note that a structure variable can be passed to a function as a parameter in the same way that standard variable types can. We can also create an array of structures, as demonstrated by the following program:

// Example Program 2

#include <iostream>
#include <string.h>
#include <sstream>
using namespace std;

struct film
{
  string title;
  int year;
} myfilms [3];

void show_film (film my_film);

int main ()
{
  string input_str;
  int n;

  for (n=0; n<3; n++)
  {
    cout << "\nEnter the title of film number " << n+1 << ": ";
    getline (cin, myfilms[n].title);
    cout << "\nEnter the year the film was released: ";
    getline (cin, input_str);
    stringstream(input_str) >> myfilms[n].year;
  }

  cout << "\nYou have listed the following films:\n\n";
  for (n=0; n<3; n++)
  show_film (myfilms[n]);

  cout << "\nPress ENTER to continue.";
  getline( cin, input_str );
  return 0;
}

void show_film (film my_film)
{
  cout << my_film.title;
  cout << " (" << my_film.year << ")\n";
}


The output from example program 2

The output from example program 2

Pointers to structures

As with other variable types, it is possible to create pointers to structure variables. The following code fragment demonstrates this:

struct film
{
  string title;
  int year;
};

film myfilm;
film * ptr_myfilm;

Here, myfilm is an object of type film, and ptr_myfilm is a pointer to an object of type film. The following statement sets ptr_myfilm to point to myfilm:

ptr_myfilm = & myfilm;

The following short program demonstrates how pointers can be used with structures:

// Example Program 3

#include <iostream>
#include <string.h>
#include <sstream>
using namespace std;

struct film
{
  string title;
  int year;
};

int main ()
{
  string input_str;

  film myfilm;
  film * ptr_myfilm;
  ptr_myfilm = & myfilm;

  cout << "Enter the title of your favourite film: ";
  getline (cin, myfilm.title);
  cout << "\nEnter the year the film was released: ";
  getline (cin, input_str);
  (stringstream) input_str >> ptr_myfilm->year;

  cout << "\nYour favourite film is: ";
  cout << ptr_myfilm->title;
  cout << " (" << ptr_myfilm->year << ")\n";

  cout << "\nPress ENTER to continue.";
  getline( cin, input_str );
  return 0;
}


The output from example program 3

The output from example program 3

Note the use here of the arrow operator (->), which is used exclusively to dereference struct or class members (we will deal with classes elsewhere).

Nested structures

We have said already that structure members can be of any valid data type, and this includes other structures, as demonstrated in the following code fragment:

struct film
{
  string title;
  int year;
};
.
.
.
struct film_club_member
{
  string name;
  string email;
  film fav_film;
} sara, alan, simon, olga;