Grouping Data with struct
Introduction
Often different types of data naturally come together in a single unit. For example, a color is a compound data type consisting of three integers, one each for the red, green, and blue channels. Usually we find it more convenient to refer to the color as a single unit, rather than three separate data values. This is particularly true when we need to pass them as parameters or create arrays where the cohesion among the red, green, and blue values might otherwise be lost.
Like many languages (Scheme included, though we do not discuss
it in CSC 151), C offers programmers the ability to customize
their own compound data types. C provides several mechanisms
for grouping data together into logical units. Already, we
have seen the use of 1-dimensional arrays to store and retrieve
data of the same type using an index. In this module, we
consider two additional mechanisms for collections:
a struct to store data of
different types, and 2-dimensional arrays to store tables.
Today's reading introduces
the struct concept; the next
reading covers two-dimensional arrays, and the third puts the
ideas of a struct and 2-dimensional arrays
together to address the processing of image data.
The struct Concept
C groups variables together
using structs. Using
a struct, you can simplify
parameters, organize data, and protect information.
Conceptually, structs allow a
programmer to group related data together; pragmatically, the
programmer needs to be able to work with the collection of data
at some times and with individual pieces at other times.
Within a program, the use
of structs draws upon basic
syntax and semantics, as described in these readings from your
textbook:
- King, Sections 16.1-16.2, pp. 377-386
Additional Background
A structure in C is the same as a record
in many
other (pre-object-oriented) programming
languages. A struct is a
collection of data. Functions that operate on
a struct are not embedded
within the struct; rather, we write such functions
separately and pass structs to
them as arguments.
For example, a program for keeping track of students might use the following collection of variables:
struct student {
int number;
double testGrades[2];
double grade;
};
The struct is named student while
its members
are number, testGrades,
and grade. The name of a struct
is also called a tag.
A later declaration of
struct student hannah;
will create a structure variable named hannah. The
individual member variables can be referred to using the syntax
variableName.memberName, as in the following example:
hannah.number = 991234567;
hannah.testGrades[0] = 10.;
hannah.testGrades[1] = 11.;
hannah.grade = (hannah.testGrades[0] / 15. + hannah.testGrades[1] / 12.) / 2.;
The declaration
struct student csc161[30];
might be used to create an array of student records.
Using the typedef Declaration
Including the struct modifier
in all variables of type struct student can
sometimes feel a bit cumbersome. Alternatively, we can
explicitly define a new data type to describe our student
information with the following instruction:
typedef struct {
int number;
double testGrades[2];
double grade;
} student_t;
and then declare our variables using this new type, with instructions like:
student_t hannah;
student_t csc161[30];
You might find it helpful to think of
the typedef instruction as
giving a blueprint
for the creation of a
student_t struct variable, while the
declarations cause the construction
of variables having
type
student_t by setting aside memory.
Although almost any name can be specified as a type using
a typedef statement, a common
approach uses a struct
followed by name with an underscore and a t. For example,
in the student example,
-
struct studentwas the original name for thestructincluding student information, and -
student_twas the name given to the new type for this student information.
With this convention student_t is a new type
for a student.
Representing Time with a Struct
The following struct may be used to represent a time value in hours, minutes and seconds format (e.g., 12:34:56.123):
typedef struct {
int hours;
int mins;
double secs;
} timeinfo_t;
The timeinfo_t identifier is the struct
tag
. A new type called timeinfo_t is created.
(We did not call it time, because there is
already a C library function called time).
Structure types may be used as return types or argument types in functions. A function that converts time values given in seconds (e.g., 12345.67) to time values given in hh:mm:ss.sss format might have the prototype:
timeinfo_t convertTime( double realTime )
and would look like:
timeinfo_t convertTime( double realTime )
{
timeinfo_t result;
.
.
.
return result;
}
Examples
During class we may discuss some of the following examples.
