1 / 56

310201 Fundamental Programming

310201 Fundamental Programming. Introduction to Data Structures. Topics for this Week:. Data Structures Arrays of Structures Member Functions Member Data Public and Private Searching Arrays Sorting Arrays. Data Structures.

lphilips
Download Presentation

310201 Fundamental Programming

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. 310201Fundamental Programming Introduction to Data Structures.

  2. Topics for this Week: • Data Structures • Arrays of Structures • Member Functions • Member Data • Public and Private • Searching Arrays • Sorting Arrays

  3. Data Structures • A structure is a collection of variables that are referenced under one name, providing a convenient means of keeping related information together. • In some other programming languages the word record is used instead of structure, but both mean the same thing. • A structure definition forms a template that may then be used to create structure objects. i.e. variables declared to be of the structure type.

  4. Data Structures (cont …) • The variables that make up the structure are called the structure elements. • The general form of the structure definition is: struct struct_name { type variable_name1; type variable_name2; ::: etc for other variables in the structure ::: type variable_nameN; }; • Do NOT forget the semi-colon !!

  5. Data Structures (cont …) • We could define an Address structure as follows : struct Address { char Street_Name [30]; char City [20]; int Postcode [5]; }; • Now that we have defined our structure, we can then declare objects based on this structure, for example : Address Home_Address, Work_Address, Postal_Address;

  6. Data Structures (cont …) • We can then use these objects with a dot notation to store or retrieve data using the structure elements. • This dot notation consists of the object name, a full stop, and the structure element, as follows : strcpy (Home_Address.Street_Name, "125 Hodgkins Rd"); strcpy (Home_Address.City, "Rockhampton"); Home_Address.Postcode = 4703;

  7. Why use Data Structures ? • Let’s record details (Name, Weight_Kg, Height_Metres, and Colour details) for animals. • Using the “old” (pre-structure) approach : // Define a valid list of colours. enum Colours {brown, orange, grey, pink, black, white, various}; char Giraffe_Name [30]; // Giraffe's details. float Giraffe_Weight_Kg; int Giraffe_Height_Centimetres; Colours Giraffe_Colour; char Dog_Name [30]; // Dog's details. float Dog_Weight_Kg; int Dog_Height_Centimetres; Colours Dog_Colour;

  8. Why use Data Structures ? (cont …) • Now, to use these fields to store records about each animal, we could do so as follows : strcpy (Giraffe_Name, "Giraffe"); Giraffe_Weight_Kg = 2000; Giraffe_Height_Centimetres = 500; Giraffe_Colour = orange; // etc for each animal.

  9. Why use Data Structures ? (cont …) • What if we want to add another animal ? e.g. a Cat ? • We then need to define the list of variables again to hold the Cat's details, as follows : char Cat_Name [30]; // Cat's details. float Cat_Weight_Kg; int Cat_Height_Centimetres; Colours Cat_Colour;

  10. Why use Data Structures ? (cont …) • And then we could then use these Cat_ fields to store details for the Cat as follows : strcpy (Cat_Name, "Cat"); Cat_Weight_Kg = 1.5; Cat_Height_ Centimetres = 30; Cat_Colour = various;

  11. Why use Data Structures ? (cont …) • What happens if we want to store new details for each animal, such as their favourite foods ? • To achieve this, we would need to go and add an extra variable in for each animal so far defined, as follows : char Giraffe_Favourite_Foods [200]; char Dog_Favourite_Foods [200]; char Cat_Favourite_Foods [200];

  12. Why use Data Structures ? (cont …) • As you can see, this is a maintenance headache ! • Every time we add a new animal or a new piece of data we want to record, we are making numerous changes to our program. • Also, if we needed to store details for many animals, or store a lot of details for each animal, then this approach could become a real maintenance nightmare ! • Also, if the format of the data changed for the characteristics of an animal, we would need to make many program changes ! e.g. int to float, etc. • Don’t Panic – There is a much better way !!

  13. Data Structures to the rescue !! • Using structures, we could define an Animals structure and then define the data attributes for the animals once and once only as follows : // Define a valid list of colours. enum Colours {brown, orange, grey, pink, black, white, various}; // Define the attributes we want to use to describe an animal. struct Animals { char Name [30]; // Animal's Common Name. float Weight_Kg; // Animal's Average Weight in Kilograms. int Height_Centimetres; // Animal's Average Height in Centimetres. Colours Colour; // Animal's Colour (see: enum Colours). };

  14. Data Structures to the rescue !! (cont …) • All we need to do now is declare structure variables that use this Animals data structure : Animals Giraffe, Domestic_Pig, Dog; • To access the attributes of each animal, we use a dot notation as before :  strcpy (Giraffe.Name, "Giraffe"); Giraffe.Weight_Kg = 2000; Giraffe.Height_Centimetres = 1000; Giraffe.Colour = orange;

  15. Data Structures to the rescue !! (cont …) • If we want to add another animal, say a Cat, we simply add a declaration for it : Animals Cat; • Once we have done this, we can store details for the Cat in a similar way to the Giraffe and other animals.

  16. Data Structures to the rescue !! (cont …) • If we want to add new attribute to describe an animal, we simple add it to the Animals data structure. • For example, suppose we also want to record each animal's favourite foods, we could do it with a simple change as follows : struct Animals { char Name [30]; // Animal's Common Name. float Weight_Kg; // Animal's Average Weight in Kilograms. int Height_Centimetres; // Animal's Average Height in Centimetres. Colours Colour; // Animal's Colour (see: enum Colours). char Favourite_Foods [200]; // A list of the Animal's Favourite Foods. };

  17. Data Structures to the rescue !! (cont …) • And then we can use the Favourite_Foods structure element straight away to hold information for any animal we have defined so far, for example : strcpy (Cat.Favourite_Foods, "Fish, Whiskers, Dine, Steak, Chicken"); strcpy (Giraffe.Favourite_Foods, "Grass, Leaves, Berries, Pizza");

  18. Advantages of Structures over the “Old” Approach • If we want to add a new attribute, then we simply add a new structure element into the structure and the new attribute is ready for use in all structure objects. • If we want to change an existing attribute, then this is also very easy to do : we simply change the data type of the structure element in the structure. • If we add a new animal, then we simply add a declaration for the animal, and we can immediately record data for the animal straight away. • Data structures have saved us a lot of work and there is also less chance of inconsistencies and errors.

  19. Arrays of Structures • One of the great advantages of using structures is that you can use them with arrays. • For example, using the above Animals structure, we could define an array of 1,000 animals for a Zoo : const int MAX = 1000; Animals Zoo [MAX]; • We would then use a dot notation plus the array notation to get to the structure elements for each array location.

  20. Arrays of Structures (cont …) // Initialise the details for all animals. for (int i = 0; i < MAX; i++) { Zoo [i].Name[0] = '\0'; Zoo [i].Weight = 0; Zoo [i].Height_Centimetres = 0; Zoo [i].Colour = various; }

  21. Arrays of Structures (cont …) // Prompt the user to enter the details for all animals. // No validation of input – to keep things as simple as possible ! for (int i = 0; i < MAX; i++) { cout << "\nEnter the Name for animal " << (i+1) << " : "; gets (Zoo [i].Name[0]); cout << "\nEnter the Weight (in Kg) for animal " << (i+1) << " : "; cin >> Zoo [i].Weight; // etc for other animal attributes. }

  22. Arrays of Structures (cont …) • Arrays of structures are very useful when you need to store a number of objects with the same attributes. • For example, employee data, student data, product data, and other data types could all be conveniently stored in an array of structures.

  23. Structures of Arrays • It is also possible to have arrays inside the structure. • We have already seen with strings. • Just as easy to store arrays of other data types. enum Month {Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec, MAX_MONTH}; struct Country { char Name [40]; // The name of the country char Capital [40]; // The capital city of the country. int Num_States; // Number of states in the country float Area_Sq_Km; // The area of the country in square Km.   // An array of average daily temperature for each month of the year. float Average_Daily_Temperature [MAX_MONTH]; };

  24. Structures of Arrays (cont …) • Using this structure, we could define a country : Country Australia; • and store data for this country : strcpy (Australia.Name, "Australia"); strcpy (Australia.Capital, "Canberra"); Australia.Num_States = 8; // Including A.C.T. Australia.Area_Sq_Miles = 7713364; Australia.Average_Daily_Temperature [Jan] = 28; Australia.Average_Daily_Temperature [Feb] = 26; Australia.Average_Daily_Temperature [Mar] = 24; // Etc for each month …

  25. Structures of Arrays (cont …) • Or, store details for each country in the world : Country World [200]; • and then the store details for each country : strcpy (World [0].Name, "Australia"); strcpy (World [0].Capital, "Canberra"); World [0].Num_States = 8; // Including A.C.T. World [0].Area_Sq_Miles = 7713364; World [0].Average_Daily_Temperature [Jan] = 28; World [0].Average_Daily_Temperature [Feb] = 26; World [0].Average_Daily_Temperature [Mar] = 24; // Etc for each month … // Etc for each other country in the world …

  26. Structures and Arrays • As you can see, using arrays of structures, structures of arrays, and arrays of structures of arrays is very simple. • At the heart of all of these variations, dot notation is always the key for accessing the structure elements for each object.

  27. Nested Structures • A nested structure occurs when a structure contains another structure. • Normally, this occurs when one structure contains an array of another structure or structures. • As an example to illustrate this, let's extend the above Country structure, and let it contain an array of State structures, so that the details for each state in the country can also be stored.

  28. Nested Structures (cont …) struct State { char Name [40]; // The name of the country char Capital [40]; // The capital city of the country. unsigned long Capital_Population; // The population of the Capital. }; struct Country { char Name [40]; // The name of the country char Capital [40]; // The capital city of the country. int Num_States; // Number of states in the country float Area_Sq_Km; // The area of the country in square Km. float Average_Daily_Temperature [MAX_MONTH]; State State_Details [100]; // The States for each Country. };

  29. Nested Structures (cont …) • To store data in this nested structure, we need a dot notation to a Country structure element, and (in the case of States), a further dot notation to get to the State structure element. strcpy (Australia.State_Details [0].Name, "Queensland"); strcpy (Australia.State_Details [0].Capital, "Brisbane"); Australia.State_Details [0].Capital_Population = 1488883; // ** According to 1996 Census.

  30. Nested Structures (cont …) • In this way, a structure can contain arrays of other structures, with each in turn containing arrays of structures. • This provides a very powerful facility for data storage !!

  31. Passing Structures to Functions • Structures are ordinarily passed to functions "by value". i.e. by default they are value parameters. • If you want a function to be able to change structure data and have these changes reflected back in the calling program, you need to pass the structure by Reference (i.e. as a Reference Parameter). • That is, use an & (ampersand) prefix.

  32. Passing Structures to Functions (cont …) • The problem with passing structures by value (i.e. as value parameters) is that a complete copy of the structure is created in memory and this copy is used inside the function. • For large structures, the creating of a copy can cause some considerable overheads. • To avoid the overheads of Value Parameters, it is better to pass the structure by Reference (i.e. as a Reference Parameter). That is, use an & (ampersand) prefix.

  33. Passing Structures to Functions (cont …) • The problem with this is that any changes made to the structure in the function will then be reflected back in the calling program. • So we have solved one problem, but created another one in the process. • If a function is not allowed to change or update the data in a structure, then it is better still to pass the structure as Constant Reference Parameter. • Then the function is not allowed to change any values in the structure, and no copies of the structure are made each time the function is called.

  34. Passing Structures to Functions (cont …) • By using Constant Reference Parameters, we can reduce our program's memory and resource overheads while ensuring that data integrity is not compromised. • Example : struct Bank_Account { char Account_ID [10]; // e.g. SA-12345 char Account_Name [40]; // The account holder's name. float Account_Balance; // Bank balance in $.cents float Interest_FYTD; // Interest paid this financial year. };

  35. Passing Structures to Functions (cont …) void Display_Account (const Bank_Account &A_Person) // Display Account Details to screen. { // Floats output in fixed format with 2 decimal points. cout << setprecision (2) << setiosflags (ios::showpoint) << setiosflags (ios::left) << setiosflags (ios::fixed); // Display the account holders details. cout << setw(15) << A_Person.Account_ID << setw(30) << A_Person.Account_Name << setw(10) << A_Person.Account_Balance << setw(10) << A_Person. Interest_FYTD; }

  36. Union • Unions allow one same portion of memory to be accessed as different data types. union union_name { member_type1 member_name1; member_type2 member_name2; member_type3 member_name3; … }object_name; • Details on Page 82

  37. Enumerations (enum) • Enumerations create new data types to contain something different that is not limited to the values fundamental data types may take. enum enum_name {value1, value2, …}; Ex enum color_t = {black, green, blue}; color_t = mycolor; mycolor = green; if (mycolor == blue) mycolor = black;

  38. Structures : Member Data and Functions • Member Data is simply another name for the structure elements. i.e. the data attributes in the structure. • In the same way that a structure can contain data, it can also contain functions ! • Member Functions are functions that are tied to a particular structure. • Member Functions automatically have access to all of the data elements in a structure, so you no longer need to pass the structure objects to these functions as parameters.

  39. Structures : Member Data and Functions • To make a function a Member Function, we simply : • move the function prototypes into the structure, • and then remove the structure parameters from the function headers and prototypes, • For example :

  40. Structures : Member Data and Functions struct Bank_Account { char Account_ID [10]; // e.g. SA-12345 char Account_Name [40]; // The account holder's name. float Account_Balance; // Bank balance in $.cents float Interest_FYTD; // Interest paid this financial year. // Member Function prototypes. void Create_New_Account (); void Display_Account (); };

  41. Structures : Member Data and Functions (cont …) • We also need to change the functions themselves. • Because we now have member functions, we are no longer passing the structure as a parameter. • We simply access the structure data elements directly – we no longer have to use a dot notation with the structure object parameter of the function. • That is, there is no longer the A_Person object, and we don't need to use A_Person.Account_ID to get to the Account_ID for that structure object.

  42. Structures : Member Data and Functions (cont …) • In addition, we need to add a special flag to the function headers to show that these are the member functions we are referring to in the structure. • This flag is called a scoping operator, and is simple the structure name with a double colon, and is used as a prefix to the function name in the function header. • For the Bank_Accountstructure, the scoping operator would beBank_Account::

  43. Structures : Member Data and Functions (cont …) void Bank_Account::Display_Account () // Display Account Details to screen. { // Floats are output in fixed format with 2 decimal points. cout << setprecision (2) << setiosflags (ios::showpoint) << setiosflags (ios::left) << setiosflags (ios::fixed); // Display the account holders details. cout << setw(15) << Account_ID << setw(30) << Account_Name << setw(10) << Account_Balance << setw(10) << Interest_FYTD; }

  44. Structures : Member Data and Functions (cont …) • Finally, we need to change the way the functions are called, and use a dot notation : void main(void) { Bank_Account Ima_Student; // Declare a Bank_Account object. // Code to create / set up the account. // :::: etc :::: Ima_Student.Display_Account (); // Display the account details. }

  45. Structures : Private and Public Member Data • The data integrity problems (raised earlier) still remain however, and any function (member or otherwise) can still access and alter data in the structure. void main(void) { Bank_Account Ima_Student; // Declare an Account. Ima_Student.Create_New_Account (); // Setup the new account. Ima_Student.Account_Balance = 300; // Corrupt account balance. Ima_Student.Display_Account (); // Display account. }

  46. Structures : Private and Public Member Data (cont …) • We need a way to protect data so that only member functions can access it. • By default, all data elements in a structure are publicly accessible by *any* function, and are known as Public Member Data. • If we want data in a structure to only be accessible by member functions, then we can use a private keyword to make the data Private Member Data. • Private Member Data is only able to be accessed – read / viewed or changed / altered – by member functions of the structure.

  47. Structures : Private and Public Member Data (cont …) • By declaring data as private, we can ensure the data integrity of the data in our structure, because only our member functions will be allowed to view or change the data directly. • Unless there is a really good reason to do otherwise, all data elements in a structure should be declared as Private Member Data. i.e. use the private keyword.

  48. Structures : Private and Public Member Functions • Like Member Data, Member Functions can also be public or private. • Member unctions should be declared as public or private depending on how they are designed to be used. • Public Member Functions are those functions which we declare with a public keyword. • Normally, most member functions could be declared as public, so that other non-member functions can use these functions to work with the structure data.

  49. Structures : Private and Public Member Functions (cont …) • Private Member Functions are those functions which we declare with a private keyword. • Private Member Functions are those functions which are for use by other private and public member functions, but we do not want them to be called or used by functions which are external to the structure. i.e. non-member functions.

  50. Structures : Private and Public Member Functions and Data class Bank_Account { private: char Account_ID [10]; // e.g. SA-12345 char Account_Name [40]; // The account holder's name. float Account_Balance; // Bank balance in $.cents float Interest_FYTD; // Interest paid this financial year. public: // Member Function prototypes. void Create_New_Account (); void Display_Account (); };

More Related