490 likes | 667 Views
Chapter 16 - Pointers and Structures. sptr. "One". xsptr. "Two". "Three". Pointers. What is the difference sptr and ssptr? char* sptr[ ] = { "One", "Two", "Three" }; char** xsptr = sptr;. Concepts to Learn…. enum Structures typedef’s structs in structs Array of structs
E N D
sptr "One\0" xsptr "Two\0" "Three\0" Pointers • What is the difference sptr and ssptr? char* sptr[ ] = { "One", "Two", "Three" }; char** xsptr = sptr; Structures
Concepts to Learn… • enum • Structures • typedef’s • structs in structs • Array of structs • struct Pointers • Union • Bit Fields • Dynamic Memory Allocation • Linked List Structures
enum enum • Closely related to the #define preprocessor. • Define a list of aliases which represent integer numbers. • The advantage of enum over #define is that it has scope. • Only visible within the block it was declared. • Two types: • Named: enum greekType { ALPHA, BETA, GAMMA }; • Unnamed: enum { HOMER, MARGE, BART, LISA }; • Values start at zero, unless specified. Structures
enum enum Examples enum numbers { zero, one, two, three }; enum animals { cat=1, dog, cow=9, sheep, }; enum plants { grass, roses, cabbages, oaktree }; enum diseases { heart, skin, brain, circulatory }; enum quarks { charmed, strange, truth, beauty }; enum treasures { rubies, sapphires, gold, silver }; Structures
Structures Structures • A structure is a collection of variables, possibly of different types, grouped together under a single name (tag). • Structures help organize complicated data. • A structure must be defined prior to a structure variable being declared. • Structure definitions include a tag, member elements, and a variable definition. • The variable definition is optional. Structures
Structures Structures • Structure definitions inform the compiler what the structure will look like. struct flightType { char flightNum[7]; /* max 6 characters */ int altitude; /* in meters */ int longitude; /* in tenths of degrees */ int latitude; /* in tenths of degrees */ int heading; /* in tenths of degrees */ double airSpeed; /* in km/hr */ }; • Structure definition does not allocate memory. Structures
Structures Structures • To allocate memory for a struct, we declare a variable using the new structure definition type. struct flightType plane; • Structure members are laid out in the order specified by the definition. • Memory is now allocated, and can be accessed as individual members of thisvariable with the “dot” operator: plane.altitude = 10000; plane.heading = 800; Structures
Does not allocate memory Allocates two memory structs Structures Structure Example #include <stdio.h> #include <string.h> struct person { char name[80]; int 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 %d", fred.name, fred.ssn); printf(“\n%s %d", barney.name, barney.ssn); } Structures
typedef’s Typedef’s Using Naturally Named Data Types
typedef’s Why typedef? • You use variables with logical names. • Why not use data types with logical names? • Is an “int” 8-bits, 16-bits, 32-bits? • What’s a “long”? • Better question: why memorize it? • Most integer data types are platform dependent!!! • typedef’s make your code more portable. • Syntax: typedef <type> <name>; Structures
typedef’s How To Use typedef’s • Create a logical data type scheme. • A signed 8-bit number could be "s8" • An unsigned 16-bit number could be "u16" • Create a “typedef.h” file for each microcontroller platform you use. • #include "typedef.h" in each of your files. • Use your new data type names. typedef unsigned int u16; typedef unsigned char u8; u16 number; Structures
typedef’s typedef.h Example typedef unsigned char u8; typedef signed char s8; typedef unsigned short u16; typedef signed short s16; typedef unsigned long u32; typedef signed long s32; Replace: unsigned char variable; with: u8 variable; Structures
typedef’s typedef’s • Typedef declarations provide no additional functionality. • Makes code more readable by giving application-specific names to variable types. typedef int Color; typedef struct flightType Flight; Color pixels[500]; Flight plane1, plane2; Structures
structs in structs Structures in Structures • One field of a struct can be another structure struct addressStruct { char street[80]; char city[32]; int zipCode; }; struct person { char initials[4]; int ssn; int height; int weight; struct addressStruct address; } tom; int main() { tom.ssn = 555123456; tom.weight = 150; tom.address.zipCode = 84062; … person initials ssn height weight address street city zipCode Structures
Array of structs Arrays of Structures • Can declare an array of structs: typedef struct flightType { char flightNum[7]; /* max 6 characters */ int altitude; /* in meters */ int longitude; /* in tenths of degrees */ int latitude; /* in tenths of degrees */ int 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 you can use the “.” dot operator: planes[34].altitude = 10000; Structures
How Much Memory? Not Common More Common struct Pointers Pointers and Structures • Pointers can point at structures struct person { char name[80]; int ssn; } barney, *rubble; int main() { rubble = &barney; strcpy((*rubble).name, “Rubble, Barney”); (*rubble).ssn = 555234561; printf(“%s %d\n”, (*rubble).name, (*rubble).ssn); } strcpy(rubble->name, “Rubble, Barney”); rubble->ssn = 555234561; printf(“%s %d\n”, rubble->name, rubble->ssn); 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]; int 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); } 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 • 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 items created during run-time and are allocated on the heap. • malloc() – allocates memory • free() – frees memory SFR’s 0xffff Structures
Dynamic Memory Allocation Dynamic Memory Allocation • The sizeof() function determines how much space is necessary for allocation. #include <stdio.h> #include <stdlib.h> int main() { 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) ); } 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. • When building abstract structures like trees and linked lists. • 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. Structures
Dynamic Memory Allocation Dynamic Memory Allocation • Once allocated, the memory belongs to your program until it terminates or is free()’d. #include <stdio.h> #include <stdlib.h> main() { int *dynArray; /* Allocate space for 16 ints */ dynArray = (int *)malloc( 16 * sizeof(int) ); dynArray[6] = 65; dynArray[12] = 2; doSomething( dynArray ); free( dynArray ); } Structures
Dynamic Memory Allocation Pointers, Structures, & malloc() • Common to let malloc() create space for structures struct person { char initials[2]; int 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); } Structures
union union • A union is a value that may have any of several representations or formats; or a data structure that consists of a variable which may hold such a value. • 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. Structures
union union Example #include <stdio.h> union { char c; int i; } x; int main() { int i; char* c = &x.c; x.i = 0x12345678; printf("\ni = %08x\n", x.i); for (i=0; i<4; i++) printf(" %02x", c[i]); } Structures
union union Example union { char c; int i; float f; double d; } x; x.c = 'z'; x.i = 5180; x.f = 3.14; x.d = 3.141592653589793; char* c = &x.c; int* i = &x.i; float* f = &x.f; double* d = &x.d; printf("\nc = %p", c); printf("\ni = %p", i); printf("\nf = %p", f); printf("\nd = %p", d); Structures
Bit Fields Bit Fields • Allow specification of some very small objects of a given number of bits in length. • Allow specification of fields within some externally produced data files. • Can only be declared inside a structure or a union. • No guarantee of the ordering of fields within machine words, so programs will be non-portable and compiler-dependent. • Be careful using them. It can require a surprising amount of run-time code to manipulate these things and you can end up using more space than they save. • Bit fields do not have addresses—you can't have pointers to them or arrays of them. Structures
Bit Fields Bit Fields Example #pragma pack(push,1) // BYTE align in memory (no padding) typedef struct { // (total 16 bits--a unsigned short) unsigned short sec: 5; // low-order 5 bits are the seconds unsigned short min: 6; // next 6 bits are the minutes unsigned short hour: 5; // high-order 5 bits are the hour } FATTime; #pragma pack(pop) // End of strict alignment #pragma pack(push,1) // BYTE align in memory (no padding) typedef struct { // (total 16 bits--a unsigned short) unsigned short day: 5; // low-order 5 bits are the day unsigned short month: 4; // next 4 bits are the month unsigned short year: 7; // high-order 7 bits are the year } FATDate; #pragma pack(pop) // End of strict alignment Structures
Bit Fields Bit Fields Example typedef struct { FATTime time; FATDate date; } DirEntry; void setTimeDate(DirEntry* dir) { time_t a; struct tm *b; time(&a); b = localtime(&a); dir->date.year = b->tm_year + 1900 - 1980; dir->date.month = b->tm_mon; dir->date.day = b->tm_wday; dir->time.hour = b->tm_hour; dir->time.min = b->tm_min; dir->time.sec = b->tm_sec; return; } // end setDirTimeDate 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. Structures
75 99 50 NULL list Linked List Simple Linked List Example typedef struct element { int value; struct element* next; } Element; Element *list; Element* newElement(int v) { Element* tmp; tmp = (Element*)malloc( sizeof(Element) ); tmp->value = v; tmp->next = NULL; return tmp; } int main() { /* Create linked list */ list = newElement(50); list->next = newElement(75); list->next->next = newElement(99); } Structures
Linked List Linked Lists vs Arrays • Advantages of a linked list - • Dynamic size. • Easy to add additional nodes. • Easy to add or remove nodes from the middle of the list by adding or redirecting links. • Advantages of an array - • Can easily and quickly access arbitrary elements. • In a linked list in order to access the 5th element of the list you must start at the head and follow the links through four other nodes. Structures
Linked List Linked List Creation • There are three steps required to create a linked list - • Allocate space for predefined structure. • Fill in the structure fields. • Link the structure into the list using pointers. struct element* newElement(int v) { struct element* tmp; tmp = (struct element*)malloc( sizeof(struct element) ); tmp->value = v; tmp->next = NULL; return tmp; } Structures
30 45 10 NULL list Linked List Pre-pending Items to a Linked List /* Prepend an item to start of oldList, returning ptr to new list */ struct element* prepend(struct element* item, struct element* oldList) { item->next = oldList; return item; } int main() { struct element* tmp; list = newElement(45); /* Prepend item to list */ tmp = newElement(30); list = prepend(tmp, list); /* Can prepend in one statement */ list = prepend(newElement(10), list); printList(list); } Structures
201 202 200 NULL list Linked List Appending Items to a Linked List /* Append an item to the end of oldList, returning ptr to list */ struct element* append(struct element* item, struct element* oldList) { struct element* tmp; if (oldList == NULL) return item; /* oldList is empty */ tmp = oldList; while (tmp->next != NULL) tmp = tmp->next;/* Search for end of list */ tmp->next = item; return oldList; } int main() { /* Append some items to end of list */ list = append(newElement(200), list); list = append(newElement(201), list); list = append(newElement(202), list); printList(list); } Structures
Linked List Inserting Items into a Linked List • Search to find the proper location • link the new record into it’s proper place. • multiple cases to consider • list is empty • item belongs at front of existing list • item belongs somewhere in middle of existing list • item belongs at end of existing list Structures
Linked List Inserting Items into a Linked List struct element* insert(struct element* item, struct element* oldList) { struct element* tmp; /* oldList is empty */ if (oldList == NULL) return item; /* The new item goes first (pre-pend) */ if (item->value < oldList->value) { item->next = oldList; return item; } /* Search for proper location */ tmp = oldList; while ((tmp->next != NULL) && (tmp->next->value < item->value)) tmp = tmp->next; item->next = tmp->next; tmp->next = item; return oldList; } Structures
65 97 300 NULL 2 3 list Linked List Inserting Items into a Linked List struct element* insert(struct element* item, struct element* oldList) int main() { /* Insert some items into list */ list = insert(newElement(65), list); list = insert(newElement(2), list); list = insert(newElement(97), list); list = insert(newElement(3), list); list = insert(newElement(300), list); printList(list); } 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”. int main() { /* Create a linked list */ list = newElement(50); list->next = newElement(75); list->next->next = newElement(99); free(list->next->next); free(list->next); free(list); } Structures
Linked List Printing Items in a Linked List • Use a temporary pointer to walk down the list • print values as you go • end up with a newline void printList(struct element *ptr) { struct element *tmp; tmp = ptr; while (tmp != NULL) { printf(“ %d”, tmp->value); tmp = tmp->next; } printf("\n"); } void printList(struct element *ptr) { if (ptr == NULL) printf("\n"); else { printf(" %d", ptr->value); printList(ptr->next); } } Structures
Example 2 Example 2 • Thermostat temperature entry: typedef unsigned int u16; typedef unsigned char u8; enum { SUN, MON, TUE, WED, THUR, FRI, SAT }; typedef struct Setting_struct { struct Setting_struct* link; union { u16 time; // day:hour/minute struct { u8 day:3; // day of week (0-6) u8 hour:5; // hour (0-23) u8 minute; // minute (0-59) } times; } date; u8 high; u8 low; } Setting; Structures
Example 2 Create New Node // create a new entry Setting* newSetting(u8 day, u8 hour, u8 minute, u8 high, u8 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 Structures
Example 2 main enum { SUN=0, MON, TUE, WED, THUR, FRI, SAT }; int main() { 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 Structures
Example 2 Insert Setting Setting* insertSetting(Setting* setting, Setting* oldList) { Setting* temp; if (oldList == NULL) return setting; // oldList is empty // The new item goes first (pre-pend) if (setting->date.time < oldList->date.time) { setting->link = oldList; return setting; } // Search for proper location temp = oldList; while (temp->link != NULL) { if (temp->date.time == setting->date.time) { // replace temp->high = setting->high; 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 temp->link = setting; return oldList; } // end insertSetting Structures
Example 2 Print Setting char* days[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; void printList(Setting* ptr) { Setting* temp; temp = ptr; while (temp != NULL) { printf("\n%s %02d:%02d %4.1f-%4.1f", days[temp->date.times.day], temp->date.times.hour, temp->date.times.minute, (float)temp->high / 2.0, (float)temp->low / 2.0 ); temp = temp->link; } printf("\n"); } // end printList Structures
Example 2 Final Test void main(void) { Setting *list = NULL; eZ430X_init(CALDCO_1MHZ); // init board lcd_init(); // init LCD lcd_backlight(ON); // 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; } Structures