340 likes | 485 Views
Chapter 12 - Structures. Concepts to Learn…. e num typedef’s Structures structs in structs Array of structs struct Pointers Dynamic Memory Allocation Linked List u nion Bit fields. enum. Enum.
E N D
Concepts to Learn… • enum • typedef’s • Structures • structs in structs • Array of structs • struct Pointers • Dynamic Memory Allocation • Linked List • union • Bit fields Chapter 12 - Structures
enum Enum • Enums in C are a way to map identifiers to integral values (thus avoiding magic numbers in your code). • The advantage of enum over #define is that it has scope. • Only visible within the block it was declared. • Easier to change values – let the compiler do the work. • Two types of enum’s: • Named: enumgreekType { ALPHA, BETA, GAMMA }; • Unnamed: enum { HOMER, MARGE, BART, LISA }; • Values start at zero, unless specified. enum{ zero, one, two, three }; enum animals { cat=1, dog, cow=9, sheep, goat }; enum plants { grass, roses, cabbages, oaktree }; enum BOOLEAN { FALSE, TRUE }; Chapter 12 - Structures
typedef’s Why typedef? • We use variables with logical names - why not use data types with logical names? • What’s an "int"? 8-bits, 16-bits, 32-bits? • What’s a “long”? • Better question: why memorize it? • Most data types are platform dependent! • typedef’s introduce synonyms for types which could have been declared some other way. • typedef’s make your code more portable. • typedef’s usually declared in single .h file. • Syntax: typedef <type> <name>; Chapter 12 - Structures
typedef’s Why typedef? • How to use typedef’s: • Create a logical data type scheme. • Create a “typedef.h” file for each microcontroller platform you use. • #include "typedef.h" in each of your files. • Use the new data type names. typedef signed char int8; typedef unsigned char uint8; typedef signed short int16; typedef unsigned short uint16; typedef signed long int32; typedef unsigned long uint32; Replace: unsigned char variable; with: uint8 variable; Chapter 12 - Structures
Structures Structures • A structure is a collection of variables, possibly of different types, grouped together under a single name (tag). • Help organize complicated data. • Must be defined prior to a structure variable being declared. • Definitions include a tag, member elements, and a variable definition. structflightType { char flightNum[6]; // max 6charactersint altitude; // in metersint longitude; // in tenths of degreesint latitude; // in tenths of degreesint heading; // in tenths of degrees double airSpeed; // in km/hr }; • Structure definition does not allocate memory. Chapter 12 - Structures
Structures Structures • Memory for a struct is allocated when a variable is declared using the new structure definition type: structflightType plane; • Structure members are laid out in the order specified by the definition. • Members of an allocated struct can be accessed with the “dot” operator: plane.altitude = 10000; plane.heading = 800; Chapter 12 - Structures
Does not allocate memory Allocates two global memory structs Structures Structure Example #include <stdio.h> #include <string.h> struct person { char name[80]; long ssn; }; struct person barney, fred; int main() { strcpy(barney.name, "Rubble, Barney"); barney.ssn = 555234561; strcpy(fred.name, "Flintstone, Fred"); fred.ssn = 123451234; printf(“\n%s %ld", fred.name, fred.ssn); printf(“\n%s %ld", barney.name, barney.ssn); } Chapter 12 - Structures
structs in structs Structures in Structures • One field of a struct can be another structure structaddressStruct { char street[80]; char city[32]; long zipCode; }; struct person { char initials[4]; long ssn; int height; int weight; structaddressStruct address; } tom; int main() { tom.ssn = 555123456; tom.weight = 150; tom.address.zipCode = 84062; } person initials ssn height weight address street city zipCode Chapter 12 - Structures
Array of structs Arrays of Structures • struct's are data types and hence an array of struct's makes sense: typedefstructflightType { char flightNum[6];// max 6 charactersint altitude; // in metersint longitude; // in tenths of degreesint latitude; // in tenths of degreesint heading; // in tenths of degrees double airSpeed; // in km/hr } Flight planes[100]; • Each array element is a structure. • To access a member of a particular element in the array, used array index and the “.” dot operator: planes[34].altitude = 10000; Chapter 12 - Structures
How Much Memory? Not Common More Common struct Pointers Pointers and Structures • As a data type, pointer variables can point to structures struct person { char name[80]; long ssn; } barney, *rubble; int main() { rubble = &barney; strcpy((*rubble).name, “Rubble, Barney”); (*rubble).ssn = 555234561; printf(“%s %ld\n”, (*rubble).name, (*rubble).ssn); } strcpy(rubble->name, “Rubble, Barney”); rubble->ssn = 555234561; printf(“%s %ld\n”, rubble->name, rubble->ssn); Chapter 12 - Structures
father mother bill susan tom is a struct and mother is a field in that struct, thus tom.mother is correct. mother is a pointer to a struct and thus mother->height is correct. Combine them for tom.mother->height struct Pointers Pointers and Structures • Since pointers can point to structures, then it’s easy to make links between structures. tom struct person { char initials[2]; long ssn; int height; struct person *father; struct person *mother; }; /* Declare variables and initialize them at the same time */ struct person tom = { "tj", 555235512, 74, NULL, NULL }; struct person bill = { "wj", 351003232, 75, NULL, NULL }; struct person susan = { "sd", 980332153, 70, NULL, NULL }; int main() { /* Set tom's parents pointers */ tom.father = &bill; tom.mother = &susan; printf(“\nTom's mother's height is: %d in", tom.mother->height); } Chapter 12 - Structures
0x0100 Global Data Section Heap SP Run-time stack 0x0600 0x8000 Program (Flash) PC Interrupt Vectors Dynamic Memory Allocation Memory Usage + Heaps 0x0000 • Variable memory is allocated in three areas: • Global data section • Run-time stack • Dynamically allocated - heap SFR’s • Global variables are allocated in the global data section and are accessible after declaration. • Local variables are allocated during execution on the stack. • Dynamically allocated variables are allocated memory at run-time from the heap. • malloc() – allocates memory • free() – frees memory 0xffff Chapter 12 - Structures
Dynamic Memory Allocation Dynamic Memory Allocation • Dynamic memory allocation using malloc() is used for many kinds of programs. • When data size is unknown or variable. • Building abstract structures like trees and linked lists. The sizeof() function determines how much space is necessary for allocation. intmain() { int *dynArray; double *ddynArray; /* Allocate space for 16 ints */ dynArray = (int *)malloc( 16 * sizeof(int) ); dynArray[6] = 65; dynArray[12] = 2; /* Allocate space for 20 doubles */ ddynArray = (double *)malloc( 20 * sizeof(double) ); } Chapter 12 - Structures
Dynamic Memory Allocation Dynamic Memory Allocation #include <stdio.h> #include <stdlib.h> main() { int *dynArray; /* Allocate space for 16 ints */ dynArray = (int *)malloc( 16 * sizeof(int) ); if (dynArray != NULL) { dynArray[6] = 65; dynArray[12] = 2; doSomething( dynArray ); free( dynArray); } } A NULL pointer returned from malloc() means it failed and you are likely out of memory. Dynamic allocation can be a source of bugs in C code. Memory leak - allocating memory and forgetting to free it during program execution. Chapter 12 - Structures
Dynamic Memory Allocation Pointers, Structures, & malloc() • Common to let malloc() create space for structures struct person { char initials[2]; long ssn; int height; struct person *father; struct person *mother; } *tom, *bill, *susan; int main() { tom = (struct person *)malloc( sizeof( struct person ) ); bill = (struct person *)malloc( sizeof( struct person ) ); susan = (struct person *)malloc( sizeof( struct person ) ); strncpy(tom->initials, "tj“, 2); tom->ssn = 555235512; tom->father = bill; tom->mother = susan; susan->height = 68; /* Since tom is now a pointer, tom->mother->height is correct. */ printf(“\nTom's mother's height is: %d", tom->mother->height); } Chapter 12 - Structures
Quiz 11.1 • How is an int passed to a function? • How is a char array passed to a function? • How is an auto struct passed to a function? • How is a malloc’d struct passed to a function? • How many bytes of the heap is removed by a function call to malloc(4)? How many returned? • How much memory is allocated for fred? barney? struct person { uint8* name[2]; uint32 ssn; } fred, *barney; Chapter 12 - Structures
75 99 50 NULL list Linked List Linked List Data Structure • A linked list is an collection of nodes, each of which contains data and is connected using pointers. • Each node points to the next node in the list. • The first node in the list is called the head. • The last node in the list is called the tail. • Advantages of a linked list - • Dynamic size. • Easy to add/remove nodes. • Advantages of an array - • Easy to quickly access arbitrary elements. Chapter 12 - Structures
75 99 50 NULL list Linked List Example 11.1 typedefstruct element { intvalue; struct element* next; } Element; Element* newElement(intvalue) { Element* temp; temp = (Element*)malloc( sizeof(Element) ); temp->value = value; temp->next = NULL; return temp; } int main() { /* Create linked list */ Element *list = NULL; list = newElement(50); list->next = newElement(75); list->next->next = newElement(99); printList(list); } Pattern Factory void printList(Element* ptr) {while (ptr != NULL) {lcd_printf(" %d", ptr->value); ptr= ptr->next; } lcd_printf("\n"); } Chapter 12 - Structures
30 45 myList 10 NULL Linked List Pre-pending Items to a Linked List // Prepend element to oldList, return ptr to new list ----- Element* prepend(Element* element, Element* oldList) { element->next = oldList; return element; // return ptrto new head } // end prepend intmain() { Element* myList = newElement(45); myList= prepend(newElement(30), myList); myList= prepend(newElement(10), myList); printList(myList); } Chapter 12 - Structures
201 202 myList 200 NULL Linked List Appending Items to a Linked List // --- Append element to oldList, return ptr to list --- Element* append(Element* element, Element* oldList) { Element* temp = oldList; if (oldList == NULL) return element; // empty list while (temp->next != NULL) temp = temp->next; // find end temp->next = element; return oldList; } // end append int main() { Element* myList= append(newElement(200), myList); myList= append(newElement(201), myList); myList= append(newElement(202), myList); printList(myList); } Chapter 12 - Structures
Linked List Inserting Items into a Linked List // Insert element into oldList, return ptr to list ---- Element* insert(Element* element, Element* oldList) { Element* temp; if (oldList== NULL)return element; // new list if (element->value < oldList->value) // prepend element { element->next = oldList; return element; } temp = oldList; while ((temp->next != NULL) && (temp->next->value < element->value)) temp = temp->next; element->next = temp->next; temp->next = element; return oldList; } // end insert Chapter 12 - Structures
Linked List Inserting Items into a Linked List intmain() { Element *myList= NULL; RBX430_init(_12MHZ); // init board lcd_init(); // init LCD lcd_clear(); // clear LCD // Insert some items into list myList = insert(newElement(65), myList); myList = insert(newElement(2), myList); myList = insert(newElement(97), myList); myList = insert(newElement(3), myList); myList = insert(newElement(300), myList); printList(myList); } // end main myList 2 3 65 97 300 NULL Chapter 12 - Structures
Linked List Freeing Items in a Linked List • Elements in a linked list need to be “freed” or you will have a memory leak. • When “freeing” items in a linked list, be careful not to “saw off the limb you’re standing on”. void freeList(Element* list) { if (list == NULL) return; freeList(list->next); free(list); // free end node } intmain() { freeList(myList); // free linked list } Chapter 12 - Structures
union Union • A union is a value that may have any of several representations or formats. • Unions are defined like structures (structs), except that each data member begins at the same location in memory. • The union object occupies as much space as the largest member. • Unions are similar to "variant records" in other languages. union { char c; inti; float f; } x; c 0 1 2 3 i x.c= 'z'; x.i = 5180; x.f = 3.14; f Chapter 12 - Structures
Bit Fields Bit Fields • Specify bit-sized objects within structs or unions. • Bit fields do not have addresses—you can't have pointers to them or arrays of them. • Be careful using them. • Require run-time code to manipulate - could end up using more space than they save. • No guarantee of the ordering of fields within machine words, so programs will be non-portable and compiler-dependent. typedefstruct { unsigned short hour:5; unsigned short min:6; unsigned short sec:5; } Time time; time Chapter 12 - Structures
Quiz 11.2 • How many bytes are allocated for mySetting? • How do you set hours in mySettingto 12? typedefstructSetting_struct { structSetting_struct* link; union { uint16 time; struct { uint8 day:3; uint8 hour:5; uint8 minute; } times; } date; uint8 high; uint8 low; } Setting mySetting; Chapter 12 - Structures
Temperatures Example 11.2 • Thermostat temperature entry: typedef unsigned int uint16; typedef unsigned char uint8; enum{SUN=0, MON, TUE, WED, THUR, FRI, SAT}; typedefstructSetting_struct { structSetting_struct* link; union { uint16 time; // day:hour/minute struct { uint8 day:3; // day of week (0-6) uint8 hour:5; // hour (0-23) uint8 minute; // minute (0-59) } times; } date; uint8 high; uint8 low; } Setting; Chapter 12 - Structures
Temperatures Create New Node // create a new entry Setting* newSetting(uint8 day, uint8 hour, uint8 minute, uint8 high, uint8 low) { // malloc a new node Setting* temp = (Setting*)malloc(sizeof(Setting)); // store entries temp->date.times.day = day; temp->date.times.hour = hour; temp->date.times.minute = minute; temp->high = high; temp->low = low; // null link temp->link = NULL; return temp; } // end newSetting Chapter 12 - Structures
Temperatures main intmain() { Setting *list = NULL; // Create linked list list = newSetting(MON, 6, 30, 22<<1, 20<<1); list->link = newSetting(WED, 20, 30, 17<<1, 15<<1); list->link->link = newSetting(FRI, 8, 30, 22<<1, 20<<1); list->link->link->link = newSetting(SAT, 18, 30, 20<<1, 18<<1); } 0256 025e 0266 026e 0000 1e31 1ea3 1e45 1e96 2c 22 2c 28 28 1e 28 24 Chapter 12 - Structures
Temperatures Insert Setting Setting* insertSetting(Setting* setting, Setting* oldList) { Setting* temp = oldList; if (oldList == NULL) return setting; // oldList is empty if (setting->date.time < oldList->date.time) { setting->link = oldList; // pre-pend setting return setting; } while (temp->link != NULL) // Search for location { if (temp->date.time == setting->date.time) { temp->high = setting->high; // replace setting temp->low = setting->low; free(setting); return oldList; } if (temp->link->date.time > setting->date.time) break; temp = temp->link; // next } setting->link = temp->link; // insert setting temp->link = setting; return oldList; } // end insertSetting Chapter 12 - Structures
Temperatures Print Setting constchar* days[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; void printList(Setting* ptr) { while (ptr!= NULL) { lcd_printf("\n%s %02d:%02d %4.1f-%4.1f", days[ptr->date.times.day], ptr->date.times.hour, ptr->date.times.minute, (float)ptr->high / 2.0, (float)ptr->low / 2.0 ); ptr= ptr->link; } lcd_printf("\n"); } // end printList Chapter 12 - Structures
Temperatures Final Test void main(void) { Setting *list = NULL; RBX430_init(_1MHZ); // init board lcd_init(); // init LCD lcd_clear(0); // Create linked list list = newSetting(MON, 6, 30, 22<<1, 20<<1); list->link = newSetting(WED, 20, 30, 17<<1, 15<<1); list->link->link = newSetting(FRI, 8, 30, 22<<1, 20<<1); list->link->link->link = newSetting(SAT, 18, 30, 20<<1, 18<<1); // Insert some items into list list = insertSetting(newSetting(MON, 6, 30, 24<<1, 18<<1), list); list = insertSetting(newSetting(SUN, 6, 30, 22<<1, 20<<1), list); list = insertSetting(newSetting(TUE, 6, 30, 22<<1, 20<<1), list); list = insertSetting(newSetting(MON, 6, 30, 20<<1, 10<<1), list); list = insertSetting(newSetting(SAT, 20, 30, 22<<1, 20<<1), list); printList(list); return; } Chapter 12 - Structures