Programming Workshop 2 (CSCI 1061U)
Faculty of Science, Ontario Tech University
struct
keyword can be used to define new data types in
C++.
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.
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.
We use the .
(dot) operator to access the members as
follows
.h = 23;
r1.w = 90; r1
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 works as expected.
;
Rect r1.h = 23;
r1.w = 90;
r1
= r1; Rect r2
r2
is a copy of r1
, i.e., it too represents
a rectangle of height 23 and width 90.
The following code writes and read struct from a file.
;
Rect r1.h = 23;
r1.w = 90;
r1
("tmp.dat", ios::binary);
ofstream f.write((char*) &r1, sizeof(Rect));
f.close(); f
and for reading
;
Rect r("tmp.dat", ios::binary);
ifstream f.read((char*) r1, sizeof(Rect));
f.close(); f
The following, however, won’t work.
;
Rect r1.h = 23;
r1.w = 90;
r1
("tmp.txt");
ofstream f<< r1;
f .close(); f
or
;
Rect r("tmp.txt");
ifstream f>> r;
f .close(); f
This is because struct is a user-defined type. And currently
operators >>
and <<
are not
defined for it.
Similar to regular variables, it is possible to declare a pointer to a struct variable.
;
Rect r...
* pR;
Rect
= &r; pR
Notice that we use &
to get the address of the
struct variable (similar to other variables).
Use the ->
operator to access the members as
follows:
;
Rect r* pR;
Rect= &r;
pR
->h = 3;
pR->w = 34; pR
Now the variable r represents a rectangle with height 3 and width 34.
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:
= {1033242, 34, 100000.34};
Employee e
<< e.id << endl; // prints 1033242
cout << e.age << endl; // prints 34
cout << e.wage << endl; // prints 100000.34 cout
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()
{
= {5, 23};
Rect r
<< "Area of rectangle = " << area(r) << endl;
cout
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;
};
(int id, int age)
Employee make_CEO{
;
Employee e.id = id;
e.age = age;
e.wage = 10000.0;
ereturn e;
}
int main()
{
= make_CEO(1, 24);
Employee e
return 0;
}
struct can contain other struct
struct Employee
{
short id;
int age;
double wage;
};
struct Company
{
; // Employee is a struct within the Company struct
Employee CEOint numberOfEmployees;
};
; Company c
Use the .
(dot) operator to get to the members
.CEO.age = 25; c
This sets the age of the CEO of company c equal to 25.
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).