Data structures: struct - ece.uwaterloo.caece150/Lecture_materials/Slides/1.29... · 12/10/2018 4...

13
12/10/2018 1 ECE 150 Fundamentals of Programming Prof. Hiren Patel, Ph.D. Douglas Wilhelm Harder, M.Math. LEL [email protected] [email protected] © 2018 by Douglas Wilhelm Harder and Hiren Patel. Some rights reserved. Data structures: struct 2 Data structures: struct Outline In this lesson, we will: Describe issues with the primitive data types Introduce the 3-body problem and an attempt to solve it Introduce the struct keyword and member variables Create a 3-dimensional vector data structure Describe assigning to and using the member variables Describe passing instances of data structures as arguments We will create a library of functions for vectors Initialize instances of data structures Revisit our 3-body problem Determine if we have a solution to arrays 3 Data structures: struct Limitations of primitive data types To this point, we have discussed primitive data types: char short int long float double bool In reality, most complex objects require more parameters to describe it 4 Data structures: struct The three-body problem Suppose we want to simulate the three-body problem: Given three planets, predict their orbits Given two bodies with masses m 1 and m 2 , positions x 1 , y 1 , z 1 and x 1 , y 1 , z 1 , and velocity vectors v x,1 , v y,1 , v z,1 and v x,2 , v y,2 , v z,2 the movement is defined by a simple differential equation: https://en.wikipedia.org/wiki/Gravitational_two-body_problem The three-body problem, however, has no such simple solution The some solutions are chaotic They are very sensitive to initial conditions

Transcript of Data structures: struct - ece.uwaterloo.caece150/Lecture_materials/Slides/1.29... · 12/10/2018 4...

12/10/2018

1

ECE 150 Fundamentals of Programming

Prof. Hiren Patel, Ph.D.

Douglas Wilhelm Harder, M.Math. LEL [email protected] [email protected]

© 2018 by Douglas Wilhelm Harder and Hiren Patel.

Some rights reserved.

Data structures: struct

2 Data structures: struct

Outline

• In this lesson, we will:

– Describe issues with the primitive data types

• Introduce the 3-body problem and an attempt to solve it

– Introduce the struct keyword and member variables

– Create a 3-dimensional vector data structure

– Describe assigning to and using the member variables

– Describe passing instances of data structures as arguments

• We will create a library of functions for vectors

– Initialize instances of data structures

– Revisit our 3-body problem

– Determine if we have a solution to arrays

3 Data structures: struct

Limitations of primitive data types

• To this point, we have discussed primitive data types:

char

short int long

float double

bool

• In reality, most complex objects require more parameters to describe it

4 Data structures: struct

The three-body problem

• Suppose we want to simulate the three-body problem:

– Given three planets, predict their orbits

• Given two bodies with

– masses m1 and m2,

– positions x1, y1, z1 and x1, y1, z1, and

– velocity vectors vx,1, vy,1, vz,1 and vx,2, vy,2, vz,2

the movement is defined by a simple differential equation:

https://en.wikipedia.org/wiki/Gravitational_two-body_problem

• The three-body problem, however, has no such simple solution

– The some solutions are chaotic

• They are very sensitive to initial conditions

12/10/2018

2

5 Data structures: struct

The three-body problem

• We can approximate a solution as follows:

– Based on the velocities of each object, we can assume for the next 0.1 s they are moving essentially in a straight line:

• x1 ← x1 + 0.1 vx,1

• y1 ← y1 + 0.1 vy,1

• z1 ← z1 + 0.1 vz,1

• x2 ← x2 + 0.1 vx,2

• y2 ← y2 + 0.1 vy,2

• z2 ← z2 + 0.1 vz,2

• x3 ← x3 + 0.1 vx,3

• y3 ← y3 + 0.1 vy,3

• z3 ← z3 + 0.1 vz,3

6 Data structures: struct

The three-body problem

• We can approximate a solution as follows:

– Based on the law of gravity (ignoring relativity), we can also determine the force vectors on each object:

• fx,1, fy,1, fz,1

• fx,2, fy,2, fz,2

• fx,3, fy,3, fz,3

– Given these, the accelerations are found by dividing the force by the corresponding masses:

• fx,1/m1, fy,1/m1, fz,1/m1

• fx,2/m2, fy,2/m2, fz,2/m2

• fx,3/m3, fy,3/m3, fz,3/m3

7 Data structures: struct

The three-body problem

• We can approximate a solution as follows:

– Based on the accelerations of each object, we can assume for the next 0.1 s their velocities will change accordingly, too:

• vx,1 ← vx,1 + 0.1 fx,1/m1

• vy,1 ← vy,1 + 0.1 fy,1/m1

• vz,1 ← vz,1 + 0.1 fz,1/m1

• vx,2 ← vx,2 + 0.1 fx,2/m2

• vy,2 ← vy,2 + 0.1 fy,2/m2

• vz,2 ← vz,2 + 0.1 fz,2/m2

• vx,3 ← vx,3 + 0.1 fx,3/m3

• vy,3 ← vy,3 + 0.1 fy,3/m3

• vz,3 ← vz,3 + 0.1 fz,3/m3

8 Data structures: struct

The three-body problem

• We now have to repeat this 315 569 520 times to simulate the movement of these three bodies over the course of a year…

12/10/2018

3

9 Data structures: struct

The three-body problem

• Now consider programming this… void three_body_problem( ... ) {

unsigned int year{315569520}; // s/a

double dt{0.1}; // 0.1 s

double m1, m2, m3; // kg

double x1, y1, z1, x2, y2, z2, x3, y3, z3; // m

double vx1, vy1, vz1, vx2, vy2, vz2, vx3, vy3, vz3; // m/s

double fx1, fy1, fz1, fx2, fy2, fz2, fx3, fy3, fz3; // kg m/s/s

for ( unsigned int k{0}; k < year; ++k ) {

x1 += dt*vx1;

y1 += dt*vy1;

z1 += dt*vz1;

x2 += dt*vx2;

y2 += dt*vy2;

z2 += dt*vz2;

x3 += dt*vx3;

y3 += dt*vy3;

z3 += dt*vz3;

10 Data structures: struct

The three-body problem

// Determine the forces on each object

// - use Newton's laws

// - determine the center of mass

// - determine the force vectors

// - update f1x, ..., fz3

// Update the velocities

vx1 += dt*fx1/m1;

vy1 += dt*fy1/m1;

vz1 += dt*fz1/m1;

vx2 += dt*fx2/m2;

vy2 += dt*fy2/m2;

vz2 += dt*fz3/m2;

vx3 += dt*fx3/m3;

vy3 += dt*fy3/m3;

vz3 += dt*fz3/m3;

// Print the new positions...

}

}

11 Data structures: struct

The three-body problem

• This is a bureaucratic nightmare…

• Let us consider what we have:

– We have three objects

– Each object has

• A position vector

• A velocity vector

• A mass

12 Data structures: struct

Data structures: struct

• A 3-dimensional vector has three components: x, y and z

– We could use a 3-dimensional array

• but most physics formula use x, y and z

• We could create a data structure representing a 3-d vector

struct vector_3d_t; // Structure declaration

struct vector_3d_t { // Structure definition

double x;

double y;

double z;

};

• For the compiler, this defines a new type composed of three values

– These values are called member variables or just members

12/10/2018

4

13 Data structures: struct

Local variables

• We can now declare a local variable to be of this type:

void f() {

vector_3d_t position;

}

• The compiler sees this and now allocates memory for three doubles on the stack associated with the local variable position

– The local variable position is an instance of this data structure

– As with other local variables, this memory is cleaned up

14 Data structures: struct

Assignment of member variables

• We can now access these member variables using the dot operator:

void f() {

vector_3d_t position;

position.x = 3.275;

position.y = 2.983;

position.z = -0.635;

}

• This assigns the corresponding entries on the stack

15 Data structures: struct

Memory clean-up

• When the function exits, the memory again becomes available

void f() {

vector_3d_t position;

position.x = 3.275;

position.y = 2.983;

position.z = -0.635;

}

16 Data structures: struct

Alternative example

• The type of a data structure need not be the same:

// Data structure declaration

struct person_t;

// Data structure definition

struct person_t {

std::string given_name;

std::string surname;

unsigned char age; // years

unsigned short weight; // kg

};

12/10/2018

5

17 Data structures: struct

Using member variables

• You can manipulate the member variables just like you can manipulate local variables

– You can reassign them, copy them, use them in expressions

int main() {

vector_3d_t position;

position.x = 3.275;

position.y = 2.983;

position.z = -0.635;

double ss{position.x*position.x

+ position.y*position.y

+ position.z*position.z};

std::cout << "The sum of squares is " << ss << std::endl;

return 0;

}

Output: The sum of squares is 20.0271

18 Data structures: struct

Using member variables

• Try this yourself: #include <iostream>

// Declarations

struct vector_3d_t;

int main();

// Definitions

struct vector_3d_t {

double x;

double y;

double z;

};

int main() {

vector_3d_t position;

position.x = 3.275;

position.y = 2.983;

position.z = -0.635;

double ss{position.x*position.x

+ position.y*position.y

+ position.z*position.z};

std::cout << "The sum of squares is " << ss << std::endl;

return 0;

}

19 Data structures: struct

Passed as an argument: norm

• If a parameter is declared to be of a given data structure

– When you call the function, sufficient memory is placed on the stack for that data structure

• The parameter is a new instance of the structure

– Each value for each member variable is copied from any argument to this new instance

double norm( vector_3d_t v );

double norm( vector_3d_t v ) {

return std::sqrt( v.x*v.x + v.y*v.y + v.z*v.z );

}

20 Data structures: struct

Passed as an argument: norm

• We can now call the norm function on our instance position: struct vector_3d_t;

int main();

double norm( vector_3d_t v );

int main() {

vector_3d_t position;

position.x = 3.275;

position.y = 2.983;

position.z = -0.635;

std::cout << norm( position ) << std::endl;

return 0;

}

Output: 4.47517

12/10/2018

6

21 Data structures: struct

Passed as an argument: norm

• Try this yourself: #include <iostream>

#include <cmath>

struct vector_3d_t;

int main();

double norm( vector_3d_t v );

struct vector_3d_t {

double x;

double y;

double z;

};

int main() {

vector_3d_t position;

position.x = 3.275;

position.y = 2.983;

position.z = -0.635;

std::cout << norm( position ) << std::endl;

return 0;

}

double norm( vector_3d_t v ) {

return std::sqrt( v.x*v.x + v.y*v.y + v.z*v.z );

}

22 Data structures: struct

Passed as an argument: distance

• Recall that the distance between two vectors is the norm of the difference:

double distance( vector_3d_t u, vector_3d_t v );

double distance( vector_3d_t u, vector_3d_t v ) {

vector_3d_t difference;

difference.x = u.x - v.x;

difference.y = u.y - v.y;

difference.z = u.z - v.z;

return norm( difference );

}

23 Data structures: struct

Modifying a parameter

• Any changes to a parameter do not affect the original argument void print_normalized( vector_3d_t v );

void print_normalized( vector_3d_t v ) {

double norm_v{norm( v )};

if ( norm_v != 0.0 ) {

v.x /= norm_v;

v.y /= norm_v;

v.z /= norm_v;

}

std::cout << "(" << v.x << "," << v.y << "," << v.z << ")"

<< std::endl;

}

24 Data structures: struct

Modifying a parameter

• Consider this program: int main() {

vector_3d_t position;

position.x = 3.275;

position.y = 2.983;

position.z = -0.635;

std::cout << norm( position ) << std::endl;

print_normalized( position );

std::cout << norm( position ) << std::endl;

return 0;

}

Output: 4.47517 (0.731816,0.666567,-0.141894) 4.47517

12/10/2018

7

25 Data structures: struct

Modifying a parameter

• Try this yourself: #include <iostream>

#include <cmath>

// Delcarations

struct vector_3d_t;

int main();

double norm( vector_3d_t v );

void print_normalized( vector_3d_t v );

// Definitions

struct vector_3d_t {

double x;

double y;

double z;

};

int main() {

vector_3d_t position;

position.x = 3.275;

position.y = 2.983;

position.z = -0.635;

std::cout << norm( position ) << std::endl;

print_normalized( position );

std::cout << norm( position ) << std::endl;

return 0;

}

double norm( vector_3d_t v ) {

return std::sqrt( v.x*v.x + v.y*v.y + v.z*v.z );

}

void print_normalized( vector_3d_t v ) {

double norm_v{norm( v )};

if ( norm_z != 0.0 ) {

v.x /= norm_v;

v.y /= norm_v;

v.z /= norm_v;

}

std::cout << "(" << v.x << "," << v.y << "," << v.z << ")" << std::endl;

}

26 Data structures: struct

Modifying the argument

• You will notice that we cannot currently write a function that normalizes the arugment vector:

// Declarations

struct vector_3d_t;

void normalize( vector_3d_t v );

int main();

int main() {

// A direction vector

vector_3d_t dir;

dir.x = -1;

dir.y = 2

dir.z = 4

// The goal is to normalize 'dir'

// - that is, divide each entry by the norm of 'dir'

normalize( v );

return 0;

}

If we want to change dir, we must do so in main() itself, as we did in the print_normalized(...) function

27 Data structures: struct

Printing a structure

• We should create and use a print_vector(...) function: void print_vector( vector_3d_t v );

void print_normalized( vector_3d_t v );

void print_vector( vector_3d_t v ) {

std::cout << "(" << v.x << "," << v.y << "," << v.z << ")"

<< std::endl;

}

void print_normalized( vector_3d_t v ) {

double norm_v{norm( v )};

if ( norm_v != 0.0 ) {

v.x /= norm_v;

v.y /= norm_v;

v.z /= norm_v;

}

print_vector( v );

}

28 Data structures: struct

The inner product

• From linear algebra, you have learned the inner product

– Sometimes called the dot product double inner_product( vector_3d_t u, vector_3d_t v );

double inner_product( vector_3d_t u, vector_3d_t v ) {

return u.x*v.x + u.y*v.y + u.z*v.z;

}

12/10/2018

8

29 Data structures: struct

The inner product

• You can now calculate this inner product: struct vector_3d_t;

int main();

double inner_product( vector_3d_t u, vector_3d_t v );

int main() {

vector_3d_t p1, p2;

p1.x = 3.275;

p1.y = 2.983;

p1.z = -0.235;

p2.x = -5.235;

p2.y = 4.523;

p2.z = -15.543;

std::cout << inner_product( p1, p2 ) << std::endl;

return 0;

}

Output: 8.9e-05

30 Data structures: struct

The inner product

• Try this yourself: #include <iostream>

#include <cmath>

struct vector_3d_t;

int main();

double inner_product( vector_3d_t u, vector_3d_t v );

struct vector_3d_t {

double x;

double y;

double z;

};

int main() {

vector_3d_t p1, p2;

p1.x = 3.275;

p1.y = 2.983;

p1.z = -0.235;

p2.x = -5.235;

p2.y = 4.523;

p2.z = -15.543;

std::cout << inner_product( p1, p2 ) << std::endl;

return 0;

}

double inner_product( vector_3d_t u, vector_3d_t v ) {

return u.x*v.x + u.y*v.y + u.z*v.z;

}

31 Data structures: struct

Updating the norm

• You know that the norm is the square root of the inner product of a vector with itself:

// Declarations

struct vector_3d_t;

double inner_product( vector_3d_t u, vector_3d_t v );

double norm( vector_3d_t v );

// Definitions

double inner_product( vector_3d_t u, vector_3d_t v ) {

return u.x*v.x + u.y*v.y + u.z*v.z;

}

double norm( vector_3d_t v ) {

return std::sqrt( inner_product( v, v ) );

}

32 Data structures: struct

The cross product

• From linear algebra, you have learned the cross product of two three-dimensional vectors

vector_3d_t cross_product( vector_3d_t u, vector_3d_t v );

vector_3d_t cross_product( vector_3d_t u, vector_3d_t v ) {

vector_3d_t result;

result.x = u.y*v.z - u.z*v.y;

result.y = u.z*v.x - u.x*v.z;

result.z = u.x*v.y - u.y*v.x;

return result;

}

12/10/2018

9

33 Data structures: struct

The cross product

• Just like arguments, the values of the member variable are copied back when an instance is returned from a function:

struct vector_3d_t;

int main();

void print_vector( vector_3d_t v );

double inner_product( vector_3d_t u, vector_3d_t v );

vector_3d_t cross_product( vector_3d_t u, vector_3d_t v );

int main() {

vector_3d_t p1, p2, p3;

p1.x = 3.275;

p1.y = 2.983;

p1.z = -0.235;

p2.x = -5.235;

p2.y = 4.523;

p2.z = 3.543;

p3 = cross_product( p1, p2 );

print_vector( p3 );

std::cout << inner_product( p1, p3 ) << std::endl;

std::cout << inner_product( p2, p3 ) << std::endl;

return 0;

}

Output: (11.6317,-10.3731,30.4288) 8.88178e-16 0

34 Data structures: struct

The cross product

• Try this yourself: #include <iostream>

#include <cmath>

struct vector_3d_t;

int main();

double inner_product( vector_3d_t u, vector_3d_t v );

vector_3d_t cross_product( vector_3d_t u, vector_3d_t v );

void print_vector( vector_3d_t v );

struct vector_3d_t {

double x;

double y;

double z;

};

int main() {

vector_3d_t p1, p2, p3;

p1.x = 3.275;

p1.y = 2.983;

p1.z = -0.235;

p2.x = -5.235;

p2.y = 4.523;

p2.z = 3.543;

p3 = cross_product( p1, p2 );

print_vector( p3 );

std::cout << inner_product( p1, p3 ) << std::endl;

std::cout << inner_product( p2, p3 ) << std::endl;

return 0;

}

void print_vector( vector_3d_t v ) {

std::cout << "(" << v.x << "," << v.y << "," << v.z << ")" << std::endl;

}

double inner_product( vector_3d_t u, vector_3d_t v ) {

return u.x*v.x + u.y*v.y + u.z*v.z;

}

vector_3d_t cross_product( vector_3d_t u, vector_3d_t v ) {

vector_3d_t result;

result.x = u.y*v.z - u.z*v.y;

result.y = u.z*v.x - u.x*v.z;

result.z = u.x*v.y - u.y*v.x;

return result;

}

35 Data structures: struct

The cross product

• The other vector operations you learned were scalar multiplication and vector addition:

vector_3d_t scalar_multiply( vector_3d_t v, double a );

vector_3d_t vector_add( vector_3d_t u, vector_3d_t v );

vector_3d_t scalar_multiply( vector_3d_t v, double a ) {

vector_3d_t result;

result.x = a*v.x;

result.y = a*v.y;

result.z = a*v.z;

return result;

}

vector_3d_t vector_add( vector_3d_t u, vector_3d_t v ) {

vector_3d_t result;

result.x = u.x + v.x;

result.y = u.y + v.y;

result.z = u.z + v.z;

return result;

}

36 Data structures: struct

Projections

• Recall now that the projection of a vector u onto a vector v is defined by the formula

• We can implement this function using the functions we have: vector_3d_t project( vector_3d_t u, vector_3d_t v );

vector_3d_t project( double a, vector_3d_t v ) {

double denom{inner_product( v, v )};

if ( denom == 0.0 ) {

// If 'v' is the zero vector, return the zero vector

return v;

} else {

double scalar{inner_product( v, u )/denom};

return scalar_multiply( v, scalar );

}

}

def ,

proj,

v

v uu v

v v

12/10/2018

10

37 Data structures: struct

A vector library

• We now have a full library of vector functions that manipulate our 3-dimensional vectors:

// Structure declarations

struct vector_3d_t;

// Function declarations

vector_3d_t scalar_multiply( double a, vector_3d_t v );

vector_3d_t vector_add( vector_3d_t u, vector_3d_t v );

vector_3d_t project( vector_3d_t u, vector_3d_t v );

vector_3d_t cross_product( vector_3d_t u, vector_3d_t v );

double norm( vector_3d_t v );

double inner_product( vector_3d_t u, vector_3d_t v );

double distance( vector_3d_t u, vector_3d_t v );

void print_vector( vector_3d_t v );

void print_normalized( vector_3d_t v );

38 Data structures: struct

Arrays of vectors

• It is possible to create an array of data structures: struct vector_3d_t;

int main();

int main() {

// An array of 10 random points

size_t n{10};

vector_3d_t points[n];

for ( size_t k{0}; k < n; ++k ) {

points[k].x = 0.0;

points[k].y = 0.0;

points[k].z = 0.0;

}

// Use these points...

39 Data structures: struct

Authoring

• With these functions, you could now implement an algorithm such as the Gram-Schmidt method:

– Given an array of n vectors v1, …, vn:

1. For each k = 1, …, n

a. For each j = 1, …, k – 1:

Update vk ← vk – proj (vk)

b. Normalize vk

• Important: when you describe mathematical algorithms, they will invariably be described with indices going from 1 to n

– It is up to you to transcribe this to an array going from 0 to n – 1

vj

40 Data structures: struct

Initializing data structures

• Up to this point, we have explicitly assigned the member variables:

vector_3d_t v;

v.x = 3.259;

v.y = 2.913;

v.z = -0.325;

• We can, however, also initialize them:

vector_3d_t v{3.259, 2.913, -0.325};

– Benefit: This immeidately initalizes all member variables in the data structure

– Issue: Change the order of the member variables in the structure definition and all initializations are void

12/10/2018

11

41 Data structures: struct

Our three-body problem

• Let us return to our three-body problem:

– Each object has

• A position vector

• A velocity vector

• A mass

struct massive_body_t;

struct massive_body_t {

double mass; // kg

vector_3d_t position; // m

vector_3d_t velocity; // m/s

};

42 Data structures: struct

Our three-body problem

• We can now use this: int main() {

massive_body_t sun{1.98847e30, // kg

{0.0, 0.0, 0.0}, // m

{0.0, 0.0, 0.0}}; // m/s

massive_body_t earth{5.97237e24, // kg

{1.471e11, 0.0, 0.0}, // m

{0.0, 2.97e4, 0.0}}; // m/s

massive_body_t moon{7.342e22, // kg

{1.471e11 + 3.63104e8, 0.0, 0.0}, // m

{0.0, 2.97e4 + 1.023e3, 0.0}}; // m/s

print_vector( moon.position );

print_vector( moon.velocity );

return 0;

};

It is always critical to indicate all units in any local variables or member variables.

Output: (1.47463e+11,0,0) (0,30723,0)

43 Data structures: struct

Our three-body problem

• Try this yourself: #include <iostream>

struct vector_3d_t;

struct massive_body_t;

void print_vector( vector_3d_t v );

int main();

struct vector_3d_t {

double x;

double y;

double z;

};

struct massive_body_t {

double mass; // kg

vector_3d_t position; // m

vector_3d_t velocity; // m/s

};

int main() {

massive_body_t sun{1.98847e30,

{0.0, 0.0, 0.0},

{0.0, 0.0, 0.0}};

massive_body_t earth{5.97237e24, // kg

{1.471e11, 0.0, 0.0}, // m

{0.0, 2.97e4, 0.0}}; // m/s

massive_body_t moon{7.342e22, // kg

{1.471e11 + 3.63104e8, 0.0, 0.0}, // m

{0.0, 2.97e4 + 1.023e3, 0.0}}; // m/s

print_vector( earth.position );

print_vector( earth.velocity );

return 0;

}

void print_vector( vector_3d_t v ) {

std::cout << "(" << v.x << "," << v.y << "," << v.z << ")" << std::endl;

}

44 Data structures: struct

Arrays?

• Remember that previously, when we passed arrays to functions, we had to include the capacity as a separate parameter

double average( double data[], std::size_t capacity );

double average( double data[], std::size_t capacity ) {

double sum{0.0};

for ( std::size_t k{0}; k < capacity; ++k ) {

sum += data[k];

}

return sum/capacity;

}

12/10/2018

12

45 Data structures: struct

Arrays?

• This would be ideal:

double average( array_t data );

double average( array_t data ) {

double sum{0.0};

for ( std::size_t k{0}; k < data.capacity; ++k ) {

sum += data.entries[k];

}

return sum/capacity;

}

46 Data structures: struct

Arrays?

• This would require a data structure such as: struct array_t;

struct array_t {

std::size_t capacity;

double entries[capacity];

};

Problem: Any explicit arrays must have capacities known at compile time

• You must be able to read the source code and deduce what the exact capacity is

• Another case of static determination

Solving this problem will require pointers and dynamic memory allocation… …future topics.

47 Data structures: struct

Summary

• Following this lesson, you now

– Understand the struct keyword

– Know how to declare, access and manipulate the member variables

– Know how to pass instances of data structures to functions

– Understand how to initialize instances

– Understand how data structures can contain data structures

– Know that this simple solution cannot solve our issues with arrays

48 Data structures: struct

References

[1] No references?

12/10/2018

13

49 Data structures: struct

Colophon

These slides were prepared using the Georgia typeface. Mathematical equations use Times New Roman, and source code is presented using Consolas.

The photographs of lilacs in bloom appearing on the title slide and accenting the top of each other slide were taken at the Royal Botanical Gardens on May 27, 2018 by Douglas Wilhelm Harder. Please see

https://www.rbg.ca/

for more information.

50 Data structures: struct

Disclaimer

These slides are provided for the ECE 150 Fundamentals of Programming course taught at the University of Waterloo. The material in it reflects the authors’ best judgment in light of the information available to them at the time of preparation. Any reliance on these course slides by any party for any other purpose are the responsibility of such parties. The authors accept no responsibility for damages, if any, suffered by any party as a result of decisions made or actions based on these course slides for any other purpose than that for which it was intended.