C++ Structures

Programming Workshop 2 (CSCI 1061U)

Faculty of Science, UOIT

http://vclab.science.uoit.ca

`struct` keyword can be used to define new data types in C++.

Defining a struct

The following code defines a `Rect` data type that can be used to store the height and the width of a rectangle.

``````struct Rect {
int h;
int w;
};``````

We can also do the following

``````typedef struct {
int h;
int w;
} Rect;``````

This tells the compiler that we are defining a struct named Rect. This struct contains 2 variables inside of it: an int named h and an int named w. These variables that are part of the struct are called members (or fields). Currently no memory is allocated for this struct. This simply tells the compiler how the struct Rect looks like.

Declaring variables

To use this struct, we can declare a variable of type Rect

``Rect r1;``

Above statement declares a variable of type Rect. It allocates the memory necessary to hold struct contents. It is possible to see how much memory a struct takes by using the `sizeof()` function. E.g., `sizeof(Rect)` will return the size (in bytes) of this struct.

Accessing members

We use the `.` (dot) operator to access the members as follows

``````r1.h = 23;
r1.w = 90;``````

The above lines set the height and the width of `r1` equal to 23 and 90, respectively.

As with normal variables, struct member variables are not initialized, and will typically contain junk. We must initialize them manually.

Assignment

Assignment works as expected.

``````Rect r1;
r1.h = 23;
r1.w = 90;

Rect r2 = r1;``````

`r2` is a copy of `r1`, i.e., it too represents a rectangle of height 23 and width 90.

Reading and writing to binary files

The following code writes and read struct from a file.

``````Rect r1;
r1.h = 23;
r1.w = 90;

ofstream f("tmp.dat", ios::binary);
f.write((char*) &r1, sizeof(Rect));
f.close();``````

``````Rect r;
ifstream f("tmp.dat", ios::binary);
f.close();``````

The following, however, won't work.

``````Rect r1;
r1.h = 23;
r1.w = 90;

ofstream f("tmp.txt");
f << r1;
f.close();``````

or

``````Rect r;
ifstream f("tmp.txt");
f >> r;
f.close();``````

This is because struct is a user-defined type. And currently operators `>>` and `<<` are not defined for it.

Pointers to struct

Similar to regular variables, it is possible to declare a pointer to a struct variable.

``````Rect r;
...

Rect* pR;

pR = &r;``````

Notice that we use `&` to get the address of the struct variable (similar to other variables).

Accessing members when using struct pointers

Use the `->` operator to access the members as follows:

``````Rect r;
Rect* pR;
pR = &r;

pR->h = 3;
pR->w = 34;``````

Now the variable r represents a rectangle with height 3 and width 34.

Initializing struct

Lets consider the following struct that represents an Employee

``````struct Employee {
long id;
short age;
double wage;
};``````

It is possible to define and initialize a variable of type Employee in one go as follows:

``````Employee e = {1033242, 34, 100000.34};

cout << e.id << endl; // prints 1033242
cout << e.age << endl; // prints 34
cout << e.wage << endl; // prints 100000.34 ``````

Using struct with functions

It is possible to pass the entire struct to a function.

``````#include <iostream>
using namespace std;

struct Rect {
int h;
int w;
};

int area(Rect r)
{
return r.h * r.w;
}

int main()
{
Rect r = {5, 23};

cout << "Area of rectangle = " << area(r) << endl;

return 0;
}``````

It is also possible to return a struct from a function. This is one of the few ways to return multiple values from a function.

``````#include <iostream>
using namespace std;

struct Employee {
long id;
short age;
double wage;
};

Employee make_CEO(int id, int age)
{
Employee e;
e.id = id;
e.age = age;
e.wage = 10000.0;
return e;
}

int main()
{
Employee e = make_CEO(1, 24);

return 0;
}``````

Nested struct

struct can contain other struct

``````struct Employee
{
short id;
int age;
double wage;
};

struct Company
{
Employee CEO; // Employee is a struct within the Company struct
int numberOfEmployees;
};

Company c;``````

Use the `.` (dot) operator to get to the members

``c.CEO.age = 25;``

This sets the age of the CEO of company c equal to 25.

Struct alignment

Typically, the size of a struct is the sum of the size of all its members, but not always!

The size of the struct below is 8 as expected: (2*sizeof(int)).

``````struct Rect {
int h;
int w;
};``````

The size of the struct below on my machine is 12, which is odd since char only takes 1 byte.

``````struct Rect {
char a;
int h;
int w;
};``````

In general, the size of a struct is at least as large as the size of all the variables it contains. But it could be larger. For performance reasons, the compiler will sometimes add gaps into structures (this is called padding).

• Absolute C++, 6th Edition, W. Savitch. (Ch. 6)