Arrays of Structures

You can define arrays of user-defined types, and you can define standard containers involving them. You will often need to keep collections of objects like Persons or Points.

Plain Arrays

You declare arrays of structures the same way you declare any other array, and you access them by using subscripting, as in the following example:

;> Point pts[5];
;> sizeof(pts);
(const int) 40
;> sizeof(Point);
(const int) 8
;> sizeof(pts)/sizeof(pts[0]);
(int) 5
;> pts[0].x = 1;
(int) 1
;> pts[1] = make_point(30,40);
(Point&) Point { }
;> show_point(pts[1]);
30 40

You can initialize arrays of structures. UnderC does not currently support such initialization, but the following is a small program that compiles with standard C++, together with its output:


#include <iostream>
using namespace std;

struct Point {
  int x,y;
};

Point pts[] = {
   { 234,543} , { 260,677} , { 302,700} , { 244,760}
 };

int main()
{
  for(int i = 0; i < sizeof(pts)/sizeof(Point); i++)
    cout << pts[i].x << ' ' << pts[i].y << endl;
  return 0;
}


234 543
260 677
302 700
244 760

In this example, be careful about the semicolon after the brace in the list of initial values; the error message is obscure if you leave out the semicolon!

Lists and Vectors of Structures

Often a vector of structures is more appropriate than an array, if the number of elements is not known at compile time. Otherwise, vectors of structures and arrays of structures are used in the same way. Similarly, lists of structures can be very useful, as in the following example:

;> vector<Point> vp;   // initially empty
;> vp.push_back(make_point(10,20));
;> vp[0].x;
(int) 10
;> list<Point> lp;
;> for(int I=0;I<10;I++) lp.push_back(make_point(I,I*I));
;> lp.back().x;
(int) 9

When you have any container of structures, it is straightforward to iterate over that collection:

void dump_points(const list<Point>& lp) {
  list<Point>::iterator lpi;
  for(lpi = lp.begin(); lpi != lp.end(); ++lpi)
    cout << '(' << (*lpi).x << ',' << (*lpi).y << ")
";
}

It is very common to find expressions such as (*lpi).x when using iterators; because the dot operator (.) has a greater precedence than the dereference operator (*), you need to include parentheses in the preceding expression (*lpi.x is read as *(lpi.x), which is wrong.) It is such a common operation that an operator shortcut, lpi->x, exists. As mentioned in the “Iterators,” section of Chapter 3 a map has a find() method, which returns an iterator, but I didn't tell you how you can use that iterator (apart from saying that it may be equal to end()). The iterator refers to a pair of values: the key (which we know) called first and the value (which we are trying to find out), called second. Rather than using (*imsi).first, you can use imsi->first. In this example I have declared a map<string,int> and associated the string “fred” with the number 648. The iterator returned from find() has information about both the key and the value:

;> map<string,int> msi;
;> msi["fred"] = 648;
;> map<string,int>::iterator imsi = msi.find("fred");
;> cout << "key = " << imsi->first
							<< " value = " << imsi->second << endl;
key = fred value = 648

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.144.248