Structs - StudentActivitySheet

advertisement
STRUCTS
Student Activity Sheet
A Lego Mindstorms NXT Project Zero Activity
1
INTRODUCTION
In software development, many different mindsets (paradigms) exist as a framework to solve
different kinds of problems. The most intuitive paradigm and the paradigm you’ve been
programming in is the procedural paradigm. This paradigm is great for certain problems, such as
those that are sequentially-oriented.
Another such paradigm is the object-oriented paradigm, which views a program as interactions
between different types of objects. For example, a card object can be moved from a deck object
to a player object. Likewise, a bank object can have multiple account objects and perform actions
such as querying the account for information and deducting a maintenance fee from the account.
C (and henceforth RobotC) does not natively support objects. However, they support a construct
called a struct, which is similar to an object. A struct is a collection of variables that are related
in some way to each other. The advantage of this setup is that you may logically organize
variables.
In this Project Zero activity, you will learn how to create structs, reference variables within
structs, and how to use structs within functions.
2
LESSONS
2.1
CREATING A STRUCT
Here is a sample struct.
typedef struct {
string name;
int age;
} person;
This struct represents data about a person. This struct contains information about a person’s
name and age.
Here is another struct example:
typedef struct {
float x;
float y;
float z;
} point;
This struct represents a 3D Cartesian coordinate pair. With many points, you may also be able to
define a plot, line, or partial function.
Generally, structs are declared with the typedef struct as the first line, following with the
struct’s variables. The last line should contain the closing brace and the name (type) of the struct.
Remember that a semicolon and name must follow the last curly brace!
2.2
REFERENCING A STRUCT’S VARIABLES
Declaring a struct for use is the same as declaring a variable for use.
int scale;
// Declares an integer named scale
point vertex; // Declares a point named vertex
To access a struct’s variables, use a dot between the struct’s name and variable. For example,
point vertex;
vertex.x = 0; // Takes vertex's x variable and makes it 0
vertex.y = 3; // Takes vertex's y variable and makes it 3
vertex.z = 4; // Takes vertex's z variable and makes it 4
float distance = sqrt(vertex.x * vertex.x +
vertex.y * vertex.y +
vertex.z * vertex.z);
nxtDisplayTextLine(0, "Vertex Distance: %2.3f", distance);
The first section declares a point named vertex and assigns the vertex’s variables to various
variables. The second section calculates the (Pythagorean) distance to the vertex from the origin.
The third section displays the distance on-screen.
When I wanted the vertex’s x variable, I referenced it as vertex.x. Likewise, vertex’s y
variable is referenced by vertex.y.
2.3
USING STRUCTS IN FUNCTIONS
Struct types can be passed into functions just as normal variable types. For example, you could
declare a function like this:
float Distance(point p)
This would create a function that takes a point as a parameter and returns a float.
Using the point example from the previous section, we could extract the distance calculation into
its own specific function:
float Distance(point p) {
sum = p.x * p.x;
sum += p.y * p.y;
sum += p.z * p.z;
return sqrt(sum);
}
This technique only works for reading values. Inside the function, we cannot change the value of
the passed in variable. Internally, a copy of the variable is made and is passed onward to us. This
is called passing by value.
To modify the values of a struct within a function, we need to request a struct by reference. To
do that, we append an ampersand & before the variable name. Our previous example would
become:
float Distance(point &p)
Here is a more demonstrative example:
typedef struct {
int count;
} counter;
void AddByVal(counter c)
c.count++;
}
// No ampersand {
void AddByRef(counter &c) // With ampersand {
c.count++;
}
task main() {
counter laps;
nxtDisplayTextLine(0, "%d", laps.count);
// Display 0
AddByVal(laps);
nxtDisplayTextLine(0, "%d", laps.count);
// Display 0
AddByRef(laps);
nxtDisplayTextLine(0, "%d", laps.count);
// Displays 1
}
3
ACTIVITY
For this activity, you’ll define a note struct, which holds a frequency and duration. This
note type will be used as a convenient grouping for a PlayTone() call.
3.1
PROVIDED CODE
/* Structs.c */
// Create a note struct
// Integer var for frequency
// Integer var for duration
/**
* Plays the provided note
*
* @param n Note to play
*/
void PlayNote(note n) {
// PlayTone using note's variables
// Wait note's duration
wait10Msec(n.duration);
}
/**
* Program entry point
*/
task main() {
// Declare notes a, b, and c
// Note a is 440 for 500ms (50)
a.frequency = 440;
a.duration = 50;
// Note b is 740 for 250ms (25)
// Note a is 587 for 500ms (50)
// Play notes a, b, and c in order
}
Download