1 / 41

Structures

Structures. Structures. Complex data types Structures Defined types Structures and functions Structures and pointers. Representing Complex Data. Representing Data. Many programs require complex data to be represented That cannot easily be represented using base type variables and arrays

sawyer
Télécharger la présentation

Structures

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Structures

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

  3. Representing Complex Data

  4. 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

  5. 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

  6. 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

  7. Parallel Arrays Represents the student Dave Dodd

  8. 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

  9. Sort Error in a Parallel Array Sort index

  10. Sort Error in a Parallel Array Sort index The data is now corrupt since the IDs do not match the students

  11. Structures

  12. Structure Declarations • A structure declaration is essentially the definition of a complex type optional tag structstudent { int id; char first[MAXNAME]; char last[MAXNAME]; floatgpa; }; keyword 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

  13. 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

  14. Tag-less structs • A structcan be declared without a tag • If a variable is defined following the declaration struct { int id; char first[MAXNAME]; char last[MAXNAME]; floatgpa; } s1; • This is really only useful for one-off structs

  15. 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

  16. 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 • };

  17. 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

  18. 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” • };

  19. 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

  20. Student Data – Declarations declares the student structure #include"stdio.h" const int MAXNAME = 10; // Student structure structstudent { intid; char first[MAXNAME]; char last[MAXNAME]; float gpa; }; // Forward Declarations void printStudent(struct student st); the student structure

  21. Student Data – main define a student variable and enter data 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; } the one and only student note the important precedence here, as (&s1).id would make little sense clear the input buffer these variables are strings (char *) so we don’t need the address operator

  22. CStudent Data – print and finally print the student data voidprintStudent(struct student st) { printf("\n%d %s %s GPA = %.2f\n", st.id, st.first, st.last, st.gpa); } passed by value

  23. 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!

  24. 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

  25. Structures and typedef • This allows student structures to be declared using just the type name student tag omitted typedefstruct { int id; char first[MAXNAME]; char last[MAXNAME]; floatgpa; } student; an alias for the struct defined above

  26. 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] ...

  27. 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 struct struct student s1 = {1234, "Peter", "Parker", 3.67}; struct student s2; s2 = s1; s1 s2

  28. 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)

  29. Course and Student Structure here is the course structure typedefstruct { int id; char first[MAXNAME]; char last[MAXNAME]; course grades[MAXCOURSES]; intcoursesTaken; } student; #include"stdio.h" const int MAXNAME = 10; const int MAXCOURSES = 20; const int DEPTLEN = 5; const int MAXFILENAME = 20; const int GRADELEN = 2; // Course structure typedefstruct { char dept[DEPTLEN]; intnumber; char grade[GRADELEN]; }course; it’s an array of courses! using typedef it is perfectly OK to nest structures and to make arrays of structures

  30. Calculating GPA now we need a function to calculate GPA you can imagine that this would really include A+, A-, ... floatgpa(student st) { float result= 0; for(inti=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; else result += 0; } return result / st.coursesTaken; } its a string so can’t use == grades[i] is a course which contains a grade variable

  31. Printing Student Data we also need a new function to print student data void printStudent(student st) { printf("\n%d %s %s\n", st.id, st.first, st.last); // Print list of courses taken for(inti=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)); } prints the result of calling the gpa function

  32. 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?

  33. 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

  34. What About Getting Data? finally we will write a function to read student data from a file void readStudent(student* pst) { FILE* fp; intcourses = 0; charfname[MAXFILENAME]; printf("Enter a file name: "); gets(fname); // Open file while((fp = fopen(fname, "r")) == NULL){ printf("Try again, q to quit: "); gets(fname); if(strcmp(fname, "q") == 0){ exit(1); } } its a pointer because we need the address of the student we want to store data in prompts user to enter an existing file name

  35. Reading Student Data now read the data from the file void readStudent(student* pst) { // ... // Read student data fscanf(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); } expects an int, and two strings accesses course attributes an int checks that three values were read sets number of courses

  36. Student Data Program here is the main function intmain() { student st1; readStudent(&st1); printStudent(st1); return 0; } passing the address of the structure sample output

  37. 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

  38. Pointers and Structures • It can be useful to create structure pointers • 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 function 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

  39. 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;

  40. 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!

  41. Finally • Since we've talked about it a lot here is a (not the) definition for the FILE struct typedefstruct { char *fpos; //position of file pointervoid *base; // Pointer to the base of the fileunsigned short handle; // File handleshort flags; // Flagsshortunget; // 1-byte buffer for ungetcunsigned longalloc; // Bytes allocated for the fileunsigned shortbuffincrement; // Byte allocation } FILE;

More Related