Title: CS101 Lecture 21
1Lectures 22 23
2What will I learn in this lecture?
- Understand how structure data types are
implemented in C. - Use . operator to access members of a
structure. - See how to declare pointers to structure
variables. - Use - operator to access members of a
structure when using pointers. - Related Chapters FER Chapter 14
3Example - Auto parts
1. Problem Definition Write a program that keeps
an inventory for an auto parts store. Previously,
the information for each auto part was kept on an
index card. Each index card had the following
fields id --- a unique identifier for your
parts name ---- a category name for the part,
like air filter quantity --- the quantity in
stock price ---- retail priceThe auto
parts store can have as many as 30,000 different
parts. Your program should define a new C
data type named part. You will declare 30,000
variables of data type part. Each variable
(like an index card) should hold the values for
all of the fields listed above.
4Auto parts
2. Refine, Generalize, Decompose the problem
definition (i.e., identify sub-problems, I/O,
etc.) We first define a new data type part.
Then in main we will declare an array of 30,000
variables each of data type part. Your
program will display a menu with the following
choices 0. Exit 1. Display the
parts. 2. Find a part. 3. Enter information for
a new part.For each menu item we will write a
corresponding function to carry out that menu
option. Input A choice from the menu. For menu
choice 2. the user must supply the part id. For
choice 3. the user must supply all the
information for the new auto part. Output For
choice 1. all the fields of all the parts will be
displayed on the computer screen.
5include include define
MAX_SIZE 30000 typedef struct / user defined
data-type called part / int id
/ this is a definition/ char name32
/ no variables are declared / int
quantity / location is outside any
block / float price part int
menu(void) int choice / C merges strings
/ printf("\n0. Exit \n" "1. Display
the parts.\n" "2. Find a part.\n"
"3. Enter information for a new part.\n"
"choice ") scanf("i",choice) return
choice / end of menu / / continued on next
slide /
6void display_one_part(part p) printf(-9i
-31s -5i .2f \n, p.id ,
p.name , p.quantity
, p.price) / end of display_one_part
/ int display_parts(part parts,int
count) int i for(i 0 i display_one_part(partsi) / end of
display_parts / / continued on next slide
/
7 int find_part(part parts, int count) int
i, id_sought / return the index of the array
for given id / / return the value -1 if
id_sought not found / printf("Enter an id
number ") scanf("i",id_sought) for(i 0
i partsi.id) return i return -1
/ end of find_part / / continued
on next slide /
8int add_part(part parts,int count, int
max_size) int i if (count max_size)
printf(insufficient space to add another
part\n) return count / use C
regular expression to read a string with
blanks/ / means NOT / printf("Enter one
part in format \n" printf(" id part name
quantity price \n") scanf(" i i
f", partscount.id ,
partscount.name ,
partscount.quantity
, partscount.price) return count1 /
end of add_part / / continued on next slide /
9void main(void) int choice, index part
partsMAX_SIZE / MAX_SIZE is a constant
30000 / int count 0 / actual number of
parts in array / while(1) / infinite loop /
choice menu()
switch(choice) case 0 printf("Bye
bye!\n") return case 1
display_parts(parts,count) break
case 2 index find_part(parts,count)
if ( index ! -1)
display_one_part(partsindex) else
printf("Part not found!\n")
break case 3 count add_part(parts,count,MAX
_SIZE) / end of switch / / end of
while / / end of main /
10Example - Execution
(see demo in lecture)
11Structures - How it Works
Note The built-in data types (e.g. int, float,
char,) can be used to declare variables in the C
language. These data types dont have to be
defined by the user. Structures provide the user
with the means to define custom designed data
types.
To set up a structure in C, we need to (1)
Define a structure type. There are
several ways to do this in C. In general,
we will use the typedef mechanism to do
this. (2) Declare variables to be of that type.
12Structures - How it Works
You can use the typedef mechanism in C to create
an alias for a structure.
typedef struct int id char
name32 int quantity float price
part
The code above names part as a alias for,
struct int id char
name32 int quantity float price
13Structures - How it Works
Structure definitions do not reserve storage,
they are used to define a new data type.
typedef struct int id char
name32 int quantity float price
part
For example, the code above doesnt allocate any
storage. It doesnt reserve memory for id, name,
quantity or price --- the fields or members of
the structure. Also, part is not a variable its
like int, char ,float, double.
14Structures - How it Works
Once you have defined a new data type, you can
declare (and initialize) a variable of this data
type as in,
part p 1001,Air Filter, 100, 12.49
The variables p is declared to be of data type
part where part is a synonym for the
structure,
struct int id char name32 int
quantity float price
Structure variables, like p above, are
initialized in the same way you initialize an
array.
15Structures - How it Works
After the declaration of p, the picture of memory
looks like,
part p 1001,Air Filter,100, 12.49
1000
.id
1001
1004
Air Filter
.name
Address
1036
100
.quantity
p
.price
1040
12.49
16Structures - How it Works
A second, alternative method in using structures
in C is to code the following immediately after
the preprocessor directives as in slide 5,
struct Part int id char
name32 int quantity float price
The name Part is called a tag name.In order to
declare variable p you would write,
struct Part p 1001,Air Filter, 100, 12.49
17Structures - How it Works
A third, alternative method in using structures
in C is to combine the struct and declaration of
the variable in one statement.
struct Part int id char
name32 int quantity float price
p 1001, "Air Filter", 100, 12.49
18Structures can have members of different
data-types
Structures provide the mechanism in C for
grouping values of different data types. Example
typedef struct int employeeID float
salary int departmentID char name30 / not
same as char name / Employee
19Structures - Accessing Fields
Accessing(storing and fetching) values from/to
fields in the structure is accomplished with the
"dot operator" (.), also called the "structure
member operator ".Example (From slide 14)
p.id 1001 / use the . to access individual
fields / p.quantity 100 Example (From the
previous slide) Employee emp1 / declare a
variable of type Employee / emp1.employeeID
1004 / initialize the variable / emp1.salary
45123.50
20Structures - Accessing Fields
scanf("f",emp1.salary) / you can also use
scanf / emp1.departmentID 37
strcpy(emp1.name, "John")/ strcpy function
/ scanf("s",emp1.name) / no needed
/ emp1.name0 J / this also works
/ emp1.name1 o emp1.name2
h emp1.name3 n emp1.name4 \0
21Structures Passed As Call-By-Value
Function calls with an argument having a
structure data-type are implemented as
call-by-value. In this regard structures differ
from arrays in that arrays are passed as
call-by-reference. For example, in slide 6,
function display_one_part is called with argument
partsi of data-type part.
display_one_part(partsi)
The header for the function display_one_part ,
void display_one_part(part p) has one
parameter, p . The variable p is local in
scope to the function display_one_part. In
call-by-value the value of partsi is copied
into p. p is not a synonym for partsi.
22Functions can return values of structure data-type
Functions can return values of structure
data-type. For example, in slide 7, we could
modify the find_part function,
part find_part(part parts, int count) int
i, id_sought printf("Enter an id number ")
scanf("i",id_sought) for(i 0 i i) if (id_sought partsi.id)
return partsi / end of find_part /
so that it returns the actual part. Of course
the above code wont work if the user types an
invalid part id. Also, the call to find_part in
main would have to be modified in order for the
program to work.
23Example - Sort an array of structures
1. Problem Definition Write a program that reads
in data for the elements in the periodic system,
(e.g. Hydrogen, Helium,...) the name as a string
, symbol as a string, atomic number as an int and
atomic weight as a double. After the elements
have been entered they are sorted using qsort in
ascending alphabetical order and then printed
back to the terminal. 2. Refine, Generalize,
Decompose the problem definition (i.e., identify
sub-problems, I/O, etc.) We have four values per
atomic element name,symbol,atomicNum and
atomicWt Rather than using five separate arrays
of 102 elements we will use one array
AtomicElement of 102 elements. The data-type
of AtomicElement is a user-defined structure
named Element. Input Input data from keyboard
as above. Output Sort the elements by atomic
name, using qsort.
24include include typedef
struct / user defined data-type called Element
/ char name15 / this is a definition, no
variables are declared / char symbol3/
location of this definition is outside any block
/ int atomicNum double atomicWt
Element int cmpnames(Element ptr1, Element
ptr2) / prototype / / see explanation of the
above in subsequent slides / void main(void)
int num, i Element AtomicElement102 /
AtomicElement is an array / printf("How many
elements are you going to enter? ")
scanf("i",num) for(i0iscanf("s s i lf",AtomicElementi.name
,AtomicElementi.symbol
,AtomicElementi.atomicNum
,AtomicElementi.atomicWt)
25 / sort the arrays by name /
qsort(AtomicElement, num, sizeof(AtomicElement0)
, cmpnames) / print the sorted array /
printf("\n") for (i0iprintf("s s i .5lf ",AtomicElementi.name
,AtomicElementi.symbol
,AtomicElementi.atomicNum
,AtomicElementi.atomicW
t) printf("\n") / print one element per line
/ / end of for / / end of main / int
cmpnames(Element ptr1, Element ptr2)
return strcmp(ptr1-name, ptr2-name) / why
arrow and not dot? / / end of cmpnames /
26Example - Execution
a.out How many elements are you going to
enter?4 Hydrogen H 1 1.00794 Beryllium Be 4
9.01218 Gold Au 79 196.96655 Carbon C 6
12.0107 Beryllium Be 4 9.01218 Carbon C 6
12.01070 Gold Au 79 196.96655 Hydrogen H 1
1.00794
input
output
27strcmp
From Lecture 15 slide 21 strcmp(str1, str2) -
returns a negative , zero or positive int
depending on whether str1 is alphabetically
less than, equal or greater than str2
respectively. qsort calls our function cmpnames
and passes two addresses which are assigned to
the pointer variables, ptr1 and ptr2.
strcmp(ptr1-name, ptr2-name)
If the string ptr1-name name
(alphabetically) then strcmp(ptr1-name,
ptr2-name) has a negative value else if
ptr1-name ptr2-name then
strcmp(ptr1-name, ptr2-name) has a positive
value else if ptr1-name ptr2-name then
strcmp(ptr1-name, ptr2-name) has the value 0.
These are the correct values we want to return to
qsort and we do this by
return strcmp(ptr1-name, ptr2-name)
28Sorting Example
When qsort calls cmpnames
prt1 ptr2 AtomicElement0
2030
2000
Hydrogen
H
1
1.00794
Address 2000
AtomicElement1
Beryllium
Be
4
9.01218
Address 2030
29Sorting Example
After qsort calls cmpnames
prt1 ptr2 AtomicElement0
2030
2000
9.01218
Beryllium
Be
4
Address 2000
AtomicElement1
Hydrogen
H
1
1.00794
Address 2030
Since cmpnames function returns a positive
value to the function qsort. The function
qsort does the work ofswapping the 30 bytes of
AtomicElement0 withthe 30 bytes of
AtomicElement1.
30Arrays of structure data-type
Given the data-type definition
typedef struct int id char name30
AutoPart
We can declare an array of the struct data type
Autopart.
AutoPart structArray50
declares structArray as an array which contains
50 cells (in memory) of type AutoPart.
31Pointers to variables of structure data-type
We can access the field in the structure with
pointers and arrow operator - (also called
the indirect component selection operator ). The
general format of the use of the arrow operator
is (see example on next slide)
pointer_to_structure - member_name
32Pointers to variables of structure data-type
typedef struct int employeeID float
salary int departmentID char name30
Employee Employee emp1,emp2 Employee empPtr
/ pointer to data-type Employee
/ emp1.employeeID 1004 emp1.salary
45123.50 emp1.departmentID 37strcpy(emp1.name
, "John Smith")empPtr emp1 / empPtr now
points to emp1 / printf("employeeID is i in
department i \n", empPtr-employeeID,
empPtr-departmentID)emp2 emp1/ assigns
values in ALL fields of emp1 to emp2 /
33Why use the arrow " - " ?
Rather than use the arrow operator we could use
the dereferencing operator. From the last
example printf("employeeID is i in department
i \n", (empPtr).employeeID,
(empPtr).departmentID) However, do not write
printf("employeeID is i in department i
\n", empPtr.employeeID, empPtr.departmentID)
because in C this means (see operator
precedence rules) printf("emplayeeID is i in
department i \n", (empPtr.employeeID),
(empPtr.departmentID)) and these expressions
are not equivalent. Why? Therefore, it may be
safer to use the arrow operator, so that we
dont make the mistake shown above.