Complex data types Structures Defined types Structures and functions Structures and pointers.

41
Structures

Transcript of Complex data types Structures Defined types Structures and functions Structures and pointers.

Page 1: Complex data types  Structures  Defined types  Structures and functions  Structures and pointers.

Structures

Page 2: Complex data types  Structures  Defined types  Structures and functions  Structures and pointers.

Structures

Complex data types Structures Defined types Structures and functions Structures and pointers

Page 3: Complex data types  Structures  Defined types  Structures and functions  Structures and pointers.

Representing Complex Data

Page 4: Complex data types  Structures  Defined types  Structures and functions  Structures and pointers.

Representing Data

Many programs require complex data to be represented That cannot easily be represented using

base type variables and arrays▪ Base types are the defined C types like int, char,

float, etc. C allows structures to be defined and

used in a program A structure is a complex type that collects a

number of variables, arrays or even other structures

Page 5: Complex data types  Structures  Defined types  Structures and functions  Structures and pointers.

Representing Students

Let’s assume that we want to represent student data for a small university

For each student we want to maintain First name – a string Last name – a string Student number – an integer GPA – a float

this is a simplified version of what would be necessary, some of the complicating issues will be discussed later

Page 6: Complex data types  Structures  Defined types  Structures and functions  Structures and pointers.

Students without Structures

If we wanted to maintain a list of a hundred students we could use four separate arrays One for each of the four attributes▪ First name, last name, student number, GPA

Referred to as parallel arrays Whenever we want to retrieve

student data we would use the same index in all arrays

Page 7: Complex data types  Structures  Defined types  Structures and functions  Structures and pointers.

Parallel Arrays

index 0 1 2 ... 33 ... 97 98 99

id 1101

7234

5678

4864

1789

2457

4444

index 0 1 2 ... 33 ... 97 98 99

first Bob Kate Sue Dave Joe Ella Ann

a

index 0 1 2 ... 33 ... 97 98 99

last Wing

Smith Abel Dod

d Ng Moss

Frenc

index 0 1 2 ... 33 ... 97 98 99

gpa 3.00 3.50 2.75 3.75 2.25 4.00 3.50

Represents the student Dave Dodd

Page 8: Complex data types  Structures  Defined types  Structures and functions  Structures and pointers.

Parallel Array Drawbacks

Maintaining parallel arrays can be hard We must make consistent changes to all

arrays▪ If we delete an element from one, elements

at the same index must be deleted from the others▪ If we sort one array then all the other arrays

must be sorted in the same way Passing student data to functions is

tedious▪ A function to print student data needs four

parameters Or we can use structures

Page 9: Complex data types  Structures  Defined types  Structures and functions  Structures and pointers.

Sort Error in a Parallel Array

index 0 1 2 3 4 5 6 7 8

id 9101

7234

5678

4475

4864 3459 178

9245

7444

4

index 0 1 2 3 4 5 6 7 8

first Bob Kate Sue Alan Dave Joy Joe Ella Ann

a

index 0 1 2 3 4 5 6 7 8

last Wing

Smith Abel Flim Dod

d Shae Ng Moss

Frenc

index 0 1 2 3 4 5 6 7 8

gpa 3.00 3.50 2.75 2.00 3.75 3.50 2.25 4.00 3.50

Sort index

Page 10: Complex data types  Structures  Defined types  Structures and functions  Structures and pointers.

Sort Error in a Parallel Array

index 0 1 2 3 4 5 6 7 8

id 1101

7234

5678

4475

4864 3459 178

9245

7444

4

index 0 1 2 3 4 5 6 7 8

first Bob Kate Sue Alan Dave Joy Joe Ella Ann

a

index 0 1 2 3 4 5 6 7 8

last Wing

Smith Abel Flim Dod

d Shae Ng Moss

Frenc

index 0 1 2 3 4 5 6 7 8

gpa 3.00 3.50 2.75 2.00 3.75 3.50 2.25 4.00 3.50

Sort index

index 0 1 2 3 4 5 6 7 8

id 1789

2457

3459

4444 4475 486

4567

8723

4910

1

The data is now corrupt since the IDs do not match the students

Page 11: Complex data types  Structures  Defined types  Structures and functions  Structures and pointers.

Structures

Page 12: Complex data types  Structures  Defined types  Structures and functions  Structures and pointers.

Structure Declarations

A structure declaration is essentially the definition of a complex type

struct student{

int id;char first[MAXNAME];char last[MAXNAME];float gpa;

};

keyword

optional tag

student variables

the tag is optional but if we are going to declare the struct in one place and use it in another we need a tag

Page 13: Complex data types  Structures  Defined types  Structures and functions  Structures and pointers.

Defining a Structure Variable A structure declaration describes what

data types are associated with a struct It does not allocate space for any variables

Space is allocated when a variable is defined struct student s1; Instructs the compiler to reserve space for

an int, two character arrays and a float▪ The four components of s1 are allocated

memory on the stack in sequence

Page 14: Complex data types  Structures  Defined types  Structures and functions  Structures and pointers.

Tag-less structs

A struct can be declared without a tag If a variable is defined following the

declarationstruct {

int id;char first[MAXNAME];char last[MAXNAME];float gpa;

} s1; This is really only useful for one-off

structs

Page 15: Complex data types  Structures  Defined types  Structures and functions  Structures and pointers.

What Goes Where

It is common for struct definitions to appear outside any function So that they are available anywhere in

the file If a struct is defined inside a function it

is only available in that function Variables of a struct type are

declared wherever they are needed Just like any other variable

Page 16: Complex data types  Structures  Defined types  Structures and functions  Structures and pointers.

Initializing a Structure

A structure can be initialized in much the same way as an array Using a comma separated list of values

enclosed in curly brackets

struct student s1 = {12345,“Bob”,“Smith”,2.75

};

Page 17: Complex data types  Structures  Defined types  Structures and functions  Structures and pointers.

Accessing Structure Members

Variables of a structure have to be accessed individually using the member operator (.) To access a structure variable use the

structure name and the variable name separated by a dot▪ s1.id = 12345;

They can then be used like any variable of the same type▪ And can be accessed, assigned new values,

passed to functions and so on

Page 18: Complex data types  Structures  Defined types  Structures and functions  Structures and pointers.

Designated Initializers

Individual attributes of a structure can be initialized using dot notation The initializers can be in any order

struct student s2 = {.last = "Doe",.first = “Jane”

};

Page 19: Complex data types  Structures  Defined types  Structures and functions  Structures and pointers.

Enter Student Data

We will look at an example that enters and prints student data The student structure is declared A student variable is defined The user is requested to enter values for

the structure attributes The student data is printed

Page 20: Complex data types  Structures  Defined types  Structures and functions  Structures and pointers.

Student Data – Declarations

#include "stdio.h"const int MAXNAME = 10;

// Student structurestruct student{

int id;char first[MAXNAME];char last[MAXNAME];float gpa;

};

// Forward Declarationsvoid printStudent(struct student st);

the student structure

declares the student structure

Page 21: Complex data types  Structures  Defined types  Structures and functions  Structures and pointers.

Student Data – main

int main(){

struct student s1;printf("Enter ID: ");scanf("%d",&s1.id);while(getchar() != '\n');printf("Enter first name: ");gets(s1.first);printf("Enter last name: ");gets(s1.last);printf("Enter GPA: ");scanf("%f",&s1.gpa);

printStudent(s1);return 0;

}

note the important precedence here,as (&s1).id would make little sense

the one and only student

define a student variable and enter data

clear the input buffer

these variables are strings (char *) so we don’t need the address operator

Page 22: Complex data types  Structures  Defined types  Structures and functions  Structures and pointers.

CStudent Data – print

void printStudent(struct student st){

printf("\n%d %s %s GPA = %.2f\n", st.id, st.first, st.last, st.gpa);

}

passed by value

and finally print the student data

Page 23: Complex data types  Structures  Defined types  Structures and functions  Structures and pointers.

Structures and Functions

Structures can be used as function parameters and arguments In the same way as any other variable Parameter passing is pass by value▪ Structure variables are not pointers▪ Unlike array variables

When a structure is passed to a function the parameter is a copy of the original Even if the original structure contained

arrays!

Page 24: Complex data types  Structures  Defined types  Structures and functions  Structures and pointers.

typedef

Declaring student variables with the keyword struct is somewhat verbose It would be nicer if we could just declare

a variable of type student The typedef keyword allows a

programmer to use their own name for a type Somewhat similarly to #define It can be used to name a struct

Page 25: Complex data types  Structures  Defined types  Structures and functions  Structures and pointers.

Structures and typedef

This allows student structures to be declared using just the type name student

typedef struct{

int id;char first[MAXNAME];char last[MAXNAME];float gpa;

} student;

tag omitted

an alias for the struct defined above

Page 26: Complex data types  Structures  Defined types  Structures and functions  Structures and pointers.

Arrays of Structures

It is possible to create arrays of structures They are declared like any other kind of

array▪ e.g. struct student class[100];

Individual elements are also accessed like any other array struct attributes are accessed with dot

notation Let's say we want to find the first name

of the student with index 15▪ class[15].first

not class.first[15] ...

Page 27: Complex data types  Structures  Defined types  Structures and functions  Structures and pointers.

Assigning Structures

Unlike arrays one structure can be assigned to another Think of the assignment as copying the

bits that represent the RH struct into the LH structstruct student s1 = {1234, "Peter", "Parker", 3.67};

struct student s2;s2 = s1;

1234 P e t e r \0 P a r k e r \0 3.67s1

s2 1234 P e t e r \0 P a r k e r \0 3.67

Page 28: Complex data types  Structures  Defined types  Structures and functions  Structures and pointers.

More Complex Types

Let’s make the example more complex It isn’t realistic to just record GPA GPA is calculated from the grades that a

student receives for courses Create a simple course structure

Department (like CMPT) Number (like 130) Grade (A+, A, and so on)

Page 29: Complex data types  Structures  Defined types  Structures and functions  Structures and pointers.

Course and Student Structure

#include "stdio.h"const int MAXNAME = 10;const int MAXCOURSES = 20;const int DEPTLEN = 5;const int MAXFILENAME = 20;const int GRADELEN = 2;

// Course structuretypedef struct {

char dept[DEPTLEN];int number;char grade[GRADELEN];

}course;

here is the course structure

using typedef

typedef struct{

int id;char first[MAXNAME];char last[MAXNAME];course grades[MAXCOURSES];int coursesTaken;

} student;

it’s an array of courses!

it is perfectly OK to nest structures and to make arrays of structures

Page 30: Complex data types  Structures  Defined types  Structures and functions  Structures and pointers.

Calculating GPA

float gpa(student st){

float result= 0;for(int i=0; i < st.coursesTaken; i++){

if(strcmp(st.grades[i].grade, "A") == 0)result += 4;

else if(strcmp(st.grades[i].grade, "B") == 0)result += 3;

else if(strcmp(st.grades[i].grade, "C") == 0)result += 2;

else if(strcmp(st.grades[i].grade, "D") == 0)result += 1;

elseresult += 0;

}return result / st.coursesTaken;

}

now we need a function to calculate GPA

grades[i] is a course which contains a grade variable

you can imagine that this would really include A+, A-, ...

its a string so can’t use ==

Page 31: Complex data types  Structures  Defined types  Structures and functions  Structures and pointers.

Printing Student Data

void printStudent(student st){

printf("\n%d %s %s\n", st.id, st.first, st.last);

// Print list of courses takenfor(int i=0; i < st.coursesTaken; i++){

printf("%-4s %d: %s\n", st.grades[i].dept, st.grades[i].number,

st.grades[i].grade);}printf("GPA: %.2f\n", gpa(st));

}

we also need a new function to print student data

prints the result of calling the gpa function

Page 32: Complex data types  Structures  Defined types  Structures and functions  Structures and pointers.

Reading Student Data

At the moment we can calculate GPA and print student data

But, imagining this is part of a larger system, we need a way get data into the students It would be useful to read student data from

a file This brings up some issues▪ What will the file look like?▪ How can we write a function to read data into a

structure defined outside the function?

Page 33: Complex data types  Structures  Defined types  Structures and functions  Structures and pointers.

File Format

We need a format for the student files The main thing is to make some rules and

then ensure that they are followed Let’s assume that a file contains the data

for a single student The first line contains the student’s ID and

name Subsequent lines contain courses and grades The number of courses taken can be derived

from the number of course lines

Page 34: Complex data types  Structures  Defined types  Structures and functions  Structures and pointers.

What About Getting Data?

void readStudent(student* pst){

FILE* fp;int courses = 0;char fname[MAXFILENAME];printf("Enter a file name: ");gets(fname);

// Open filewhile((fp = fopen(fname, "r")) == NULL){

printf("Try again, q to quit: ");gets(fname);if(strcmp(fname, "q") == 0){

exit(1);}

}

finally we will write a function to read student data from a file

prompts user to enter an existing file name

its a pointer because we need the address of the student we want to store data in

Page 35: Complex data types  Structures  Defined types  Structures and functions  Structures and pointers.

Reading Student Data

void readStudent(student* pst){

// ...// Read student datafscanf(fp, "%d%s%s", &pst->id, pst->first, pst->last);while(fscanf(fp, "%s%d%s",

pst->grades[courses].dept,&pst->grades[courses].number,pst->grades[courses].grade) == 3)

{courses++;

}pst->coursesTaken = courses;printf("courses = %d\n", courses);

}

now read the data from the file

sets number of courses

expects an int, and two strings

checks that three values were read

accesses course attributes

an int

Page 36: Complex data types  Structures  Defined types  Structures and functions  Structures and pointers.

Student Data Program

int main(){

student st1;readStudent(&st1);printStudent(st1);return 0;

}

here is the main function

passing the address of the structure

sample output

Page 37: Complex data types  Structures  Defined types  Structures and functions  Structures and pointers.

File Errors

The file reading program is not very robust It will read incorrect data from a file that

is not in the right format▪ Although it does illustrate the use of fscanf

One solution would be to check the number and types of values on each line And reject the file if they were incorrect This is hard to do with fscanf as it

ignores whitespace

Page 38: Complex data types  Structures  Defined types  Structures and functions  Structures and pointers.

Pointers and Structures

It is common to create pointers to structures In the example this was done to change the

variable passed to the read function's parameter It also saves time and storage to pass structures

to functions via pointers▪ Particularly if the structure is large

Structures may also be function return values Returning structures and passing structures as

parameters was not allowed in older C compilers

Page 39: Complex data types  Structures  Defined types  Structures and functions  Structures and pointers.

Dereferencing Structure Pointers

Consider this This fails to compile Because the dot operator has

precedence over the dereference operator▪ The statement is therefore attempting to

dereference an integer variable! Here is a corrected version

This is ugly, and easy to get wrong Therefore the equivalent -> operator

was created

*pst.id = 123; //pst is a student*

(*pst).id = 123;

pst->id = 123;

Page 40: Complex data types  Structures  Defined types  Structures and functions  Structures and pointers.

Pointers in Structures

A structure can contain pointers to arrays or other structures If this is desired, care must be taken to

ensure that memory is allocated to such pointers

Otherwise data might be assigned to a pointer that has not been allocated storage

In short – be careful!

Page 41: Complex data types  Structures  Defined types  Structures and functions  Structures and pointers.

Finally

Since we've talked about it a lot here is a (not the) definition for the FILE struct

typedef struct {char *fpos; //position of file pointervoid *base; // Pointer to the base of the fileunsigned short handle; // File handleshort flags; // Flagsshort unget; // 1-byte buffer for ungetcunsigned long alloc; // Bytes allocated for the fileunsigned short buffincrement; // Byte allocation

} FILE;