Today’s lab will help you get started to grouping data with struct.
To get started with this lab, download the archive file structures.tar.gz.
Run the following shell commands to unpack it:
$ cd csc161/labs
$ tar xvzf ~/Downloads/structures.tar.gz
$ cd structures
The .tar.gz file is a compressed archive that contains multiple files, a bit like the .zip files you may have used on other computers.
The files in a .tar.gz archive will generally be contained within a directory, which in this case was named structures.
A course that involves three tests and a final exam, the record for a single student might have the form:
struct student
{
char name[20];
double test1;
double test2;
double test3;
double final;
};
Open the program test-scores-1.c which
declares four student variables, initializes the variables, and prints
their records.
Driver: student farther from the whiteboard
test-scores-1 works.
struct student declared? Why do you think the
declaration comes before procedure printStudent and before
main?stu1 initialized?strcpy is used to initialize the name field
for stu4?printf
statements coordinated, so that the test scores appear in
aligned columns?%-20s is used to print the name of a student. What
does the minus sign accomplish? (Hint: What happens if the minus
sign is removed?)Add the function computeSemesterAverage to test-scores-1.c. This
function should take a struct student as a parameter and return
(not print) the weighted average that counts each test with a weight
of 1 and the final exam with a weight of 2. That is, the semester
average should be computed as:
(test1 + test2 + test3 + 2 * final) / 5.0;
Use computeSemesterAverage to add a column to the output of the
program. This should include two parts (plus the definition of the
function):
printf statement in printStudent to include
another value—the average for the student, andmain to label the new
column.As an experiment, change the value of the test1 field within
computeSemesterAverage to 120.0. Is this new value printed in
printStudent? Do you think the parameter struct student stu
references the original data or makes a copy? Explain.
main, step 3 illustrates that one must pass
the address of struct, so the parameter will refer back to the
original value. Write a procedure addTenPercent that adds 10% to
test2 of a student. The relevant procedure signature is:
void
addTenPercent (struct student * stu)
This function would be called within main with the address
operator (&), with a call such as
addTenPercent (&stu1);
Within addTenPercent, remember to use the asterisk * to refer
back to the original struct in main:
(*stu).test2 = ...
After printing the original records, call addTenPercent for each
of the four students, and then print their records again to check
that the test2 scores have been changed.
Although test-scores-1.c was satisfactory for four students, the
declaration of a different variable (e.g., stu1, stu2, stu3, stu4) for
each student is tedious. As an alternative, program
test-scores-2.c defines an array of
struct students.
In this program:
students represents the entire array,students[0], students[1], students[2], students[3] specify the
individual records for each of the four students,students[0].test1, students[1].test1, students[2].test1, students[3].test1
refer to the test1 scores for each of the students.Driver: student closer to the whiteboard
Working with test-scores-2.c, copy functions computeSemesterAverage and addTenPercent from
test-scores-1.c. Also, add the revised printStudent procedure and the revised printf for the title.
test-scores-2.c, and check that
the output is the same as you obtained from test-scores-1.c.students
array contains information for at least ten students.printMinMax that computes and prints the
maximum and minimum semester averages for the entire class. Do
NOT assume that all averages will be between 0.0 and 100.0, but
rather initialize your search for a maximum and minimum with the
averages of the first student. The signature of this procedure
should be
void
printMinMax (struct student students[], int numStudents)
where numStudents indicates the number of students in the
students array.
Modify printMinMax so that it prints the maximum and minimum
semester averages, but also the names of the students with those
averages.
test-scores-2.c so that 10% is added to each student’s
score for test 2, using the add10Percent procedure. This
adjustment of student scores should occur after initialization,
but before scores are printed or averages computed.typedef statementsWhen working with test-scores-1.c and test-scores-2.c, you may have
found it somewhat tedious to write struct student in the declaration
of every variable and parameter. To simplify this syntax, C allows
programmers to define new types. In this case, we might write
typedef struct
{
char name[20];
double test1;
double test2;
double test3;
double exam;
} student_t;
This defines a new data type student_t that you can use freely within
your program with no further explicit mention of the keyword struct.
Driver: whoever feels like they need more practice programming with structs
test-scores-3.c,
compile and run it, and review how the typedef statement works.
typedef declaration after the
definition of printStudent?semesterAvg, to the student_t
definition, but leave the initialization as it is. Does the
program compile and run?printStudent, and
observe what value is printed for stu.semesterAvg. How is a
field initialized, if other fields of a struct are
initialized, but not all fields are initialized?student_t array, use a loop to compute and
store each student’s semester average:
for (int i = 0; i < 4; i++)
{
students[i].semesterAvg = computeSemesterAverage(students[i]);
}
Check that these computed averages are now printed by the program.