Data Abstraction with Records and Linked Lists in C, Study notes of Computer Science

Data abstraction, a technique for encapsulating data details and manipulating large amounts of data. The document focuses on two methods for handling data abstraction problems: records for grouping related data and linked lists for a collection of similar or related data. Examples of defining records in c using the struct construct and accessing record fields using the dot and arrow operators.

Typology: Study notes

Pre 2010

Uploaded on 11/08/2009

koofers-user-oye-1
koofers-user-oye-1 šŸ‡ŗšŸ‡ø

9 documents

1 / 8

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
Introduction
We often want computers to process large amounts of data, so we need ways to
manipulate lists and other groupings of large amounts of data. To satisfy these
needs, we require more than just the few basic data types that are built-into the
language. The designers of the language can not possibly anticipate all the
different ways in which their language will be utilized, however, they can provide
the user with the means to ā€œextendā€ the language to best suit their particular
application.
Data abstraction is a way to encapsulate the data details of information. In
creating data abstractions we build data groupings that reflect the relationships
among various data and allow us to conveniently manipulate large amounts of
data.
In this course we’ll study two different methods for handling two different types of
data abstraction problems:
Records: Grouping related data items together.
Linked lists: A collection of a large amount of similar or related data.
Records
Records are a mechanism for data grouping.
Each record type is defined within its algorithm.
Each record is a heterogeneous collection of data. Data of all different
types (including records) are grouped into a single structure.
A record is a composite structure composed of some number of fields.
Each field has its own type.
A data field is an individual data item within a record type.
In the C language, records are created using the struct construct.
Examples of defining a struct in C
struct party {
int house_number;
int ime_starts;
int time_ends;
};
Data Abstraction (Records) - 1
Tools For Data Abstraction
pf3
pf4
pf5
pf8

Partial preview of the text

Download Data Abstraction with Records and Linked Lists in C and more Study notes Computer Science in PDF only on Docsity!

Introduction We often want computers to process large amounts of data, so we need ways to manipulate lists and other groupings of large amounts of data. To satisfy these needs, we require more than just the few basic data types that are built-into the language. The designers of the language can not possibly anticipate all the different ways in which their language will be utilized, however, they can provide the user with the means to ā€œextendā€ the language to best suit their particular application. Data abstraction is a way to encapsulate the data details of information. In creating data abstractions we build data groupings that reflect the relationships among various data and allow us to conveniently manipulate large amounts of data. In this course we’ll study two different methods for handling two different types of data abstraction problems:  Records: Grouping related data items together.  Linked lists: A collection of a large amount of similar or related data. Records  Records are a mechanism for data grouping.  Each record type is defined within its algorithm.  Each record is a heterogeneous collection of data. Data of all different types (including records) are grouped into a single structure.  A record is a composite structure composed of some number of fields. Each field has its own type.  A data field is an individual data item within a record type.  In the C language, records are created using the struct construct. Examples of defining a struct in C struct party { int house_number; int ime_starts; int time_ends; };

Tools For Data Abstraction

This construct defines the type of the struct that we have named party. Before we can use the struct we need to declare variables to be of this type, just as we do with the built-in primitive types. struct party Halloween_party; NewYears_party: Once this is done, rather than a collection of six variable, we have 2 variables each containing 3 fields. Both variables are identical in structure. If we make a change to the underlying structure (i.e., the underlying type) then it changes for all variables declared to be of that type. Using our example, suppose that we add the following field to the struct: struct party { int house_number; int ime_starts; int time_ends; char police_came: //Y or N }; Creating New Data Types  In the C language, the atomic (primitive) types and arrays are built-into the language and we can simply make use of any of these types.  The atomic types can be used to create new ā€œuser-definedā€ data types.  Once the new data type is defined, then we can declare variables to be of that type, just as we do with the built-in types.  Creating variables of a new data type is a two-step process:

  1. Define the new type.
  2. Declare variables of that type.  Remember! Creating the new data type does not provide any variables, only the template by which new variables can be declared. Example Create a student information record that includes the student’s name, id number, an array of three test scores, and array of five quiz scores, their average grade, their major, and their grade for the course.

Before we had the capability of using arrays, the code would have looked something like this: When we added that capability of using arrays, the code immediately improved to the following: int main ( ) { int student1, student2, student3, student4; int quiz1, quiz2, quiz3, quiz4; int exam1, exam2, exam3, exam4; double avg1, avg2, avg3, avg4; printf(ā€œEnter student #1 id, quiz, and exam score\nā€); scanf(ā€œ%d%d%d\nā€, &student1, &quiz1, &exam1); avg1 = (quiz1+exam1)/200; printf(ā€œStudent #1 average is %d\nā€, avg1); printf(ā€œEnter student #2 id, quiz, and exam score\nā€); scanf(ā€œ%d%d%d\nā€, &student2, &quiz2, &exam2); avg2 = (quiz2+exam2)/200; printf(ā€œStudent #2 average is %d\nā€, avg2); printf(ā€œEnter student #3 id, quiz, and exam score\nā€); scanf(ā€œ%d%d%d\nā€, &student3, &quiz3, &exam3); avg3 = (quiz3+exam3)/200; printf(ā€œStudent #3 average is %d\nā€, avg3); printf(ā€œEnter student #4 id, quiz, and exam score\nā€); scanf(ā€œ%d%d%d\nā€, &student4, &quiz4, &exam4); avg4 = (quiz4+exam4)/200; printf(ā€œStudent #4 average is %d\nā€, avg4); } int main ( ) { int student[3]; /* declare arrays to hold data. each array has 4 cells */ int quiz[3]; int exam[3]; int avg[3]; for (int i = 0; i <= 3; i++) { printf(ā€œEnter student #%d id, quiz, and exam score\nā€, i); scanf(ā€œ%d%d%d\nā€, &student[i], &quiz[i], &exam[i]); avg[i] = (quiz[i]+exam[i])/200; printf(ā€œStudent #%d average is %d\nā€, i, avg[i]); }

However, the use of records will make this code even more readable and will group related data together even better than by simply using arrays. Using records this code would look like the following: Notice that the use of records has allowed us to group related data closely together. All of the data for a single student is now contained within a single record whereas before, it was maintained in four separate arrays. More Examples Patient record struct patient { char name[20]; int age; int height; int weight; char gender; }; struct patient p1; int main ( ) { #define SIZE 20; struct student_record{ int id; int quiz; int exam; int average; }; struct student_record student[SIZE]; for (int i = 0; i < SIZE; i++) { printf(ā€œEnter student #%d id, quiz, and exam score\nā€, i); scanf(ā€œ%d%d%d\nā€, &student[i],id, &student[i].quiz, &student[i].exam); student[i].average = (student[i].quiz + student[i].exam)/200; printf(ā€œStudent #%d average is %d\nā€, i, student[i].average); } }

In the calling function that utilizes these functions we would have statements like the following: Data Abstraction (Records) - (^7) void print_date(struct date d) { switch (d.month) { case 1: printf(ā€œJanuary ā€œ); break; case 2: printf(ā€œFebraury ā€œ); break; case 3: printf(ā€œMarch ā€œ); break; case 4: printf(ā€œApril ā€œ); break; case 5: printf(ā€œMay ā€œ); break; case 6: printf(ā€œJune ā€œ); break; case 7: printf(ā€œJuly ā€œ); break; case 8: printf(ā€œAugust ā€œ); break; case 9: printf(ā€œSeptember ā€œ); break; case 10: printf(ā€œOctober ā€œ); break; case 11: printf(ā€œNovember ā€œ); break; case 12: printf(ā€œDecember ā€œ); break; } printf(ā€œ%dā€, ā€˜ d.day); printf(ā€œ%d.\nā€, d.year); } int smaller_date (struct date d1, struct date d2) { if (d1.year < d2.year) return(1); else if (d1.year > d2.year) return (0); else { if (d1.month < d2.month) return(1); else if (d1.month > d2.month) return(0); else { if (d1.day < d2.day) return(1); else if (d1.day > d2.day) return(0); else return(0); } } } struct date today; struct date birthday1, birthday2; read_date(&today); print_date(today); if (smaller_date(birthday1, birthday2) printf(ā€œFirst person is older.\nā€);

Declaring and Using Complex Structures There is basically no limit on how complex of a structure that you can define. This allows you to tailor make a record to match virtually any application that you would need. Declaring records in records: struct student { int id; char name[20]; struct date dob; int test[3]; double average; char grade; } s1, s2; Declaring an array of records: struct student class[100], youngest; Reading and printing values: read_date(&s1.dob); print_date(s1.dob); Finding the youngest student in the class list: youngest = class[0]; for (int i = 1; i < 100; i++ { if (smaller_date(youngest.dob, class[i].dob) youngest = class[i]; }