1
StructuresEtter Chapter 7
• In engineering, we need to process or visualize data– Some of you have done Matlab simulations and
visualizations
• Sometimes we work with a single piece of data– E.g. the temperature reading at this point in time.
• But usually we’d work with a large set of data.– E.g. the temperature reading every minute for the last 8
hours.– This works out to 480 pieces of data.
2
StructuresPages 327 to 332
• In Lecture 8, we solved this problem by using arrays.
• BUT arrays can only store data of a single type!– E.g. you can’t store strings in this array:
double mydata[1024];
3
Structures
• Fortunately C gives us a way of representing related information of different types, in a “structure.”
• E.g. hurricanes have names, intensities and categories.– Name: This is a string.– Intensity: Integer.– Category: Intger.
4
Structures
struct hurricane{
char name[10];int year, category;
};
• “name”, “year” and “category” are called “members” of the structure “hurricane”
• This statement declares a new type!– IT DOES NOT DECLARE A NEW VARIABLE!
This “;” is very important and often forgotten!
5
Self Help Questions
1. What are the differences between a “variable” and a “type”?
6
Answer
1. A “type” tells C what the variable is. E.g. “int” is a type. “double” is a type. After declaring our structure “hurricane”, “struct hurricane” is also a type! Types do not occupy memory and cannot store values.To declare a variable, we always use “type varname;”. So to declare an integer variable, we use “int xl;”. This tells C that “x1” is a variable of type “int”. Variables occupy memory and can be assigned values.
7
Structure Variables
• To declare a new variable of the “hurricane” type, we do:
struct hurricane h1;
?
?
?
h1name
year
category
8
Structure Variables
• You can declare multiple variables of this type:
struct hurricane h1, my_hurricane;
?
?
?
h1name
year
category
?
?
?
my_hurricane
name
year
category
9
Structure Variables
• You can also initialize the members of a structure variable.
struct hurricane h1 = {“Camille”, 1969, 5};
Camille
1969
5
h1name
year
category
10
Structure Variables
• Alternatively you can initialize the members using C statements:struct hurricane h1;
h1.name = “Camille”;
h1.year = 1969;
h1.category = 5;
• Notice how we used the “.” operator to access members of a structure variable!
11
Structure Example
• We can use scanf or fscanf statements to write to structure variable members.
• We can use printf or fprintf to read them.
• We will now write a program that reads hurricane information from a file, and prints them out.
12
Structure Example
#include <stdio.h>
#define FILENAME "storms2.txt"
struct hurricane
{
char name[10];
int year, category;
};
13
Structure Example
int main(void)
{
/* Declare variables */
struct hurricane h1;
FILE *storms;
storms = fopen(FILENAME, "r");
if(storms == NULL)
printf("Error opening data file.\n");
14
Structure Example
else{
while(fscanf(storms, "%s %d %d", h1.name, &h1.year, &h1.category) == 3)
{printf("Hurricane: %s\n", h1.name);printf("Year: %d, Category: %d\n",
h1.year, h1.category);}fclose(storms);
} /* else */return 0;
}
15
Self Help Questions
1. In the fscanf statement:fscanf(storms, "%s %d %d", h1.name,
&h1.year, &h1.category)
- h1.year and h1.category are both passed to fscanf with “&”, but not h1.name. Why?
16
ANSWERS
• The “name” member of “hurricane” is defined as char name[10];struct hurricane
{
char name[10];
int year, category;
};
17
ANSWERS
• This makes “name” an array of 10 characters.• In an array:
– The name of the array is a pointer to the first item of the array.
• “fscanf” expects pointers to the variable arguments. E.g.:
fscanf(fptr, “%d”, &a);– This is so that fscanf can return the values read using
these variables.– So we use “&” to get the address of the variable.
18
ANSWERS
• Since “name” is already a pointer to the first item of the “name” array, there is no need to use “&”. We can just pass in “name” instead of “&name”.– Further question: What does &name give
you?
19
Computations with Structures
• We use the “.” operator to access individual members of a structure variable:
h1.name=“Hazel”;
• If we use the structure variable’s name without the “.” operator, then we are accessing the entire array.
20
Computations with Structures
• You can do assignments with structures:– Given two structures “h1” and “h2”.
• To make h2 equal to h1, just do:
h2 = h1;
21
Computation with Structures
• E.g.struct hurricane h1 ={“Hazel”, 1954, 4}, h2;
………
h2 = h1;
Hazel
1954
4
h1name
year
category
?
?
?
h2name
year
category
Initially:
22
Computation with Structures
• E.g.struct hurricane h1 ={“Hazel”, 1954, 4}, h2;
………
h2 = h1;
Hazel
1954
4
h1name
year
category
Hazel
1954
4
h2name
year
category
After h2=h1:
23
Computation with Structures
• Other operations like “+”, “-”, “*”, “/”, “>”, “<“, “>=“, “==“ etc. can only be performed on individual structure variable members.
E.g. h1.category += 1; /* Increment */
24
Computation Example
• We will modify our hurricane program to print only the Category 5 hurricanes.– Can just do this by:
if(h1.category == 5)
/* Print hurricane data */
25
Computation Example
#include <stdio.h>
#define FILENAME "storms2.txt"
struct hurricane
{
char name[10];
int year, category;
};
26
Computation Example
int main(void){struct hurricane h1;FILE *storms;
storms = fopen(FILENAME, "r");if(storms == NULL)
printf("Error opening data file.\n");
27
Computation Example
else{
printf("Category 5 hurricanes\n\n");while(fscanf(storms, "%s %d %d",
h1.name, &h1.year, &h1.category) == 3)if(h1.category == 5)
printf("%s\n", h1.name);fclose(storms);
} /* else */}
28
Passing Structures to FunctionsPages 332 to 334
• Entire structures can be passed into functions.– Structures are passed by value:
• Members of the actual arguments are copied into corresponding members of the formal parameters.
29
Passing Structures to Functions#include <stdio.h>
struct hurricane{
char name[10];int year, category;
};
void print_struct(struct hurricane my_h){
printf("INSIDE print_struct function\n");printf("Contents of parameter my_h: %s, %d, %d\n", my_h.name, my_h.year, my_h.category);printf("Address of parameter my_h: %u\n\n", &my_h);
}
Formal parameter declaration for a structure.
30
Passing Structures to Functions
int main(void)
{
struct hurricane h1 = {"Hazel", 1954, 4};
printf("\nContents of h1: %s, %d, %d\n", h1.name, h1.year, h1.category);
printf("Address of h1: %u\n", &h1);
printf("Passing h1 in as argument to print_struct\n\n");
print_struct(h1);
}
Declaration for struct variable h1.
Structure variable is passed in just like any other variable.
31
Passing Structures by Reference.
• Ordinarily, structures are passed by value.– This means that you cannot modify the
members of a structure from within a function.
• To be able to modify structure members, you must pass in a pointer to the argument, rather than the argument itself.
32
Passing Structures by Reference
Self Help Question• If:
– int *ptr declares a pointer to int.– double *ptr declares a pointer to a double.
– char *ptr declares a pointer to a char.
• How do you:– Declare a pointer to a struct hurricane?
33
Passing Structures by Reference
#include <stdio.h>
#include <string.h>
/* This program has a function that modifies a structure passed to it */
struct hurricane
{
char name[10];
int year, category;
};
34
Passing Structures by Reference
void modify_structure(struct hurricane *hur)
{
/* Modify the structure values */
strncpy(hur->name, "Grace", 10);
hur->year=1972;
hur->category = 5;
}
Pointer to a struct hurricane.
When accessing structure members from a pointer, use “->” instead of “.”.
35
Passing Structures by Reference
int main(void){
struct hurricane h1={"Audrey", 1957, 4};
printf("Contents of h1: %s %d %d\n", h1.name, h1.year, h1.category);printf("\nCalling modify_structure to change the contents of h1.\n\n");
modify_structure(&h1);
printf("Contents of h1: %s %d %d\n\n", h1.name, h1.year, h1.category);
}
Pass in the address of h1, instead of h1 itself.
36
Passing Structures by Reference
• One point to note:– When accessing members of a structure
variable, we use the “.” operator.– E.g.
struct hurricane my_hurricane;
my_hurricane.year=1852;
37
Passing Structures by Reference
• One point to note:– When accessing members of a pointer to a
structure variable, we use the “->” operator.– E.g.
struct hurricane *ptr = &my_hurricane;
ptr->year=1952;– “ptr->year” is a shortcut for (*ptr).year;
38
Returning Structures from Functions.
• A function can return whole structures.• To declare a function that returns an int, we do:
int myfun1(){
…}
• To declare a function that returns a char, we do:char myfun2(){
…}
39
Returning Structures from Functions.
• To call these functions:char c;
int num;
num = myfun1();
c = myfun2();
40
Returning Structures from Functions.
• Likewise, to declare a function that returns struct hurricane:struct hurrican myfun3(…)
{…
}
• To call myfun3:struct hurricane my_h;
my_h = myfun3();
41
Example
#include <stdio.h>
struct tsunami{int mo, da, yr, fatalities;double max_height;char location[20];
};
struct tsunami get_info(void);
42
Examplestruct tsunami get_info(void){
/* Declare variables */struct tsunami t1;
printf("Enter information for tsunami in the following order:\n");printf("Enter month, day, year, number of deaths:\n");scanf("%d %d %d %d", &t1.mo, &t1.da, &t1.yr,
&t1.fatalities);printf("Enter location (<20 characters.):\n");scanf("%s", t1.location);
return t1;}
t1 will temporarily store what the user keys in.
t1 is returned here.
43
Example
int main(void){
struct tsunami my_t;
my_t = get_info();
printf("\nThe information you entered:\n\n");printf("Date (day/month/year): %d/%d/%d\n",
my_t.da, my_t.mo, my_t.yr);printf("Location: %s\n", my_t.location);printf("Fatalities: %d\n\n", my_t.fatalities);
return 0;}
We declare a variable of type struct tsunami, the exact same type as the function get_info.
We call get_info just like any other function.
44
Arrays of Structures(Pages 334 to 336)
• Refresher:– To declare an array of 20 ints:
int my_array1[20];
– To declare an array of 20 doubles:double my_array2[20];
– To declare an array of 20 chars:char my_array3[20];
• Question: How do we declare an array of “struct hurricane”?
45
Array of Structures
• Assuming we have already declared “struct hurricane”, do declare an array of 20 “struct hurricane”:
struct hurricane my_array4[20];
46
Array of Structures
• This creates 20 “struct hurricane” variables, each with:– name– year– category
• All values are un-initialized.
? ? ?
? ? ?
? ? ?
? ? ?
… … …
? ? ?
name year category
0
1
2
3
19
47
Array of Structures
• Refresher: – To access individual ints in my_array1:
• myarray1[2] = 5;
– To access individual doubles in my_array2:• myarray2[5] = 3.1;
– To access individual chars in my_array3:• myarray3[2] = ‘c’;
• So:– How to we access individual struct variables?
48
Array of Structures
Answer:
my_array4[0].name = “Camille”;
my_array4[0].year = 1969;
my_array4[0].category = 5;
49
Example
/* Program ch7_4.c */
#include <stdio.h>#define FILENAME "storms2.txt"
struct hurricane{
char name[10];int year, category;
};
void print_hurricane(struct hurricane h);
50
Exampleint main(void){
int max_category=0, k=0, npts;struct hurricane h[100];
FILE *storms;
storms = fopen(FILENAME, "r");if(storms == NULL)
printf("Error opening data file.\n");else{
printf("Hurricanes with Maximum Category:\n");
51
Examplewhile(fscanf(storms, "%s %d %d", h[k].name,
&h[k].year, &h[k].category) == 3){
if(h[k].category > max_category)max_category = h[k].category;
k++;} /* while */npts = k;
for(k=0; k<npts; k++)if(h[k].category == max_category)
print_hurricane(h[k]);
fclose(storms);} /* else */
}
52
Example
void print_hurricane(struct hurricane h)
{
printf("Hurricane: %s\n", h.name);
printf("Year: %d, Category: %d\n", h.year, h.category);
}
53
Case Study(Pages 336 to 340)
• Tsunamis are large destructive waves:– Caused by sudden movements in the sea
floor.
• Wave speeds:– Shallow water: 125 mph.– Deep water: 400 mph.
• Heights:– 30 to 200+ feet high.
54
Case Study
• Problem Statement: Print a report giving:– Maximum wave height for tsunamis in a data
file.– Average wave height.– Location of all tsunamis with heights higher
than the average.
55
Case Study
• Analysis:– Open file “waves2.txt”
• Tell the user if the file open fails.
– Find largest maximum height.• Set max to 0 first.• Assume the tsunami array is called t:
– If t[k].max_height > max, set max = t[k].max_height.
– Find average• Add t[k] to sum.• Average = sum / # of data points
56
Case Study
– Print locations with wave heights larger than the average:
• if t[k].max_height > average, print t[k].location.
• Note: Height data in file is in meters. Report is in feet:– 1 m = 3.28 feet.– z m = z * 3.28 feet.
57
Case Study
/* ch7_5.c */
#include <stdio.h>#define FILENAME "waves1.txt"
struct tsunami{
int mo, da, yr, fatalities;double max_height;char location[20];
};
58
Case Study
int main(void){
/* Declare variables */int k=0, npts;double max=0, sum=0, ave;struct tsunami t[100];
FILE *waves;
waves = fopen(FILENAME, "r");if(waves == NULL)
printf("Error opening data file.\n");
59
Case Study
else{
while(fscanf(waves, "%d %d %d %d %lf %s", &t[k].mo, &t[k].da, &t[k].yr,&t[k].fatalities, &t[k].max_height, t[k].location) == 6)
{
sum += t[k].max_height;
if(t[k].max_height > max)max = t[k].max_height;
k++;} /* while */
60
Case Study
npts = k;
ave = sum/npts;
printf("Summary Information for
Tsunamis\n");
printf("Maximum wave height (in feet): %.2f\n", max * 3.28);
printf("Average wave height (in feet): %.2f\n", ave * 3.28);
61
Case Study
printf("Tsunamis with greater than average heights:\n\n");
for(k=0; k<npts; k++)if(t[k].max_height > ave)
printf("%s\n", t[k].location);
fclose(waves);} /* else */
}
62
Summary
• In this lecture we learnt:– How to aggregate data together in structures.– How to pass structures to functions.– How to return structures in functions.– How to declare arrays of structures.
Top Related