• Nem Talált Eredményt

Structures and arrays

In document Mechatronic Systems Programming in C++ (Pldal 96-100)

8. User-defined data types

8.1. The structure type

8.1.4. Structures and arrays

struct person { string name;

date birthday;

};

Let's create two persons in the following way: the first one will be initialized by an initialization list, and let's assign values separately to the members for the other one.

person brother = { "Ivan", {2004, 10, 2} };

person student;

student.name = "Bill King";

student.birthday.year = 1990;

student.birthday.month = 10;

student.birthday.day = 20;

In the initialization list, constants initializing inner structure do not necessarily have to be enclosed within curly brackets. In the second case, student.birthday refers the structure birthday of the structure student. This is followed by the dot operator (.) and the name of a data member of the inner structure.

If the structure of type date is not used anywhere else then it can be integrated directly as an anonymous structure in the structure person:

struct person { string name;

struct {

int year, month day;

} birthday;

};

When creating more complex dynamic data structures (e.g. linear lists), elements of a given type have to be concatenated into a chain. Elements of this kind contain some kind of data and a pointer in general. C++ makes it possible to define a pointer with the type of the structure to be declared. These structures, which contain a pointer to themselves as a data member, are called self-referential structures. As an example, let's see the declaration of list_element.

struct list_element { double data_member;

list_element *link;

};

This recursive declaration makes it possible that the pointer link points to the structure of type list_element. The declaration above does not nest the two structures in each other since the structure which we will reference later with the pointer will be placed somewhere else in memory. However, C++ compilers need this declaration in order to be able to allocate memory in compliance with the declaration, that is to get to know the size of the variable to be created. The declaration above makes compilers allocate for the pointer memory space the size of which is independent of that of the structure.

8.1.4. Structures and arrays

Programming can be made much more efficient if arrays and structures are used together in one data type. In the following simple codes, we first place a dimensional array within a structure then we create a one-dimensional array of structure type elements.

8.1.4.1. Arrays as data members of a structure

In the following example, besides an integer vector (v), we also store the number of valuable elements (n) in the structure svector:

const int maxn = 10;

struct svector { int v[maxn];

int n;

};

svector a = {{23, 7, 12}, 3};

svector b = {{0}, maxn};

svector c = {};

int sum=0;

for (int i=0; i<a.n; i++) { sum += a.v[i];

} c = a;

In the expression a.v[i], there is no need to use parentheses since the two operations has the same precedence so the expression is evaluated from left to right. So first the member v is selected from the structure a, then the ith element of the array a.v is accessed. Another interesting part of the solution is that the elements of the vector are also copied from one of the structures to another when value assignment takes place between the two structures.

The structure of type svector can also be created dynamically. However, in that case, the structure should be accessed by an arrow operator.

svector *p = new svector;

p->v[0] = 2;

p->v[1] = 10;

p->n = 2;

delete p;

8.1.4.2. Structures as array elements

A structure array has to be defined exactly in the same way as arrays of any other type. As an example, let's make use of the type musicCD declared above to create a CD-catalogue of 100 elements and let's give initial values for the first two elements of CDcatalog.

musicCD CDcatalog[100]={{"Vivaldi","The Four Seasons",2004,1002},{} };

In order to reference the data members of structures as array elements, we have to first select the array element and then the structure member:

CDcatalog[10].price = 2004;

If the CD-catalogue is intended to be created dynamically, identification has to be done with a pointer:

musicCD *pCDcatalog;

Memory space for structure elements can be allocated by the operator new in the dynamically managed memory space:

pCDcatalog = new musicCD[100];

The structure stored in an array element can be accessed by using the dot operator:

pCDcatalog[10].price = 2004;

If array elements are not needed anymore, then the allocated memory space should be freed by the operator delete []:

delete[] pCDcatalog;

Certain operations (like sorting) can be carried out more efficiently if the pointers of the dynamically created CDs are stored in a pointer array:

musicCD* dCDcatalog[100];

The following loop allocates space for the structures in the dynamically managed memory:

for (int i=0; i<100; i++) dCDcatalog[i] = new musicCD;

Then, the structures selected by the array elements can be referenced by the arrow operator:

dCDcatalog[10]->price = 2004;

If these structures are not needed anymore, then we should iterate through the elements and delete them from the memory space:

for (int i = 0; i < 100; i++) delete dCDcatalog[i];

The following example searches for all CDs published between 2010 and 2012 in a dynamically created CD catalogue containing a fix number of CDs.

#include <iostream>

musicCD *pCDcatalog = new (nothrow) musicCD[num];

if (!pCDcatalog) {

cout<<endl<<"The data of the "<<i<<"th CD:"<<endl;

cout<<"Performer: ";

if (pCDcatalog[i].year >= 2010 &&

pCDcatalog[i].year <= 2012) {

cout<<endl<<pCDcatalog[i].performer<<endl;

cout<<pCDcatalog[i].title<<endl;

cout<<pCDcatalog[i].year<<endl;

found++;

} }

// Printing out the results if (found)

cout<<"\nThe number of found elements: "<<found<<endl;

else

cout<<"There is no CD that matches the criteria!"<<endl;

// Deallocating memory space delete [] pCDcatalog;

}

This program is interactive, that is data should be provided by a user, and prints out results on the screen.

Testing with a bigger amount of data is more difficult in that way.

However, most operating systems make it possible to redirect the standard input and output of a program to a file. For that purpose, the input data should be typed in a file exactly in the same way the program expects them (e.g. CDs.txt), and this file name should be provided after a lower than sign when the program (CDCatalogue) is executed from the command line:

CDCatalogue <CDs.txt

CDCatalogue <CDs.txt >Results.txt

The second command writes the results to a separate file (I.25. ábra - Processing data in the program CDCatalogue). (In the development environment of Visual C++ , the redirection properties can be set in the window Project /project Properties , on the tab named Debugging , in the line of Command Arguments .)

I.25. ábra - Processing data in the program CDCatalogue

In document Mechatronic Systems Programming in C++ (Pldal 96-100)