Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Chapter 16 Pointers and Structures Pointers What is the difference sptr and ssptr? char* sptr[ ] = { "One", "Two", "Three" }; char** xsptr = sptr; sptr "One\0" xsptr "Two\0" "Three\0" BYU CS/ECEn 124 Structures 2 Concepts to Learn… enum Structures typedef’s structs in structs Array of structs struct Pointers Union Bit Fields Dynamic Memory Allocation Linked List BYU CS/ECEn 124 Structures 3 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. Two types: Only visible within the block it was declared. Named: enum greekType { ALPHA, BETA, GAMMA }; Unnamed: enum { HOMER, MARGE, BART, LISA }; Values start at zero, unless specified. BYU CS/ECEn 124 Structures 4 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 }; BYU CS/ECEn 124 Structures 5 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. BYU CS/ECEn 124 Structures 6 Structures Structures Structure definitions inform the compiler what the structure will look like. struct flightType { char flightNum[7]; int altitude; int longitude; int latitude; int heading; double airSpeed; }; /* max 6 characters */ /* in meters */ /* in tenths of degrees */ /* in tenths of degrees */ /* in tenths of degrees */ /* in km/hr */ Structure definition does not allocate memory. BYU CS/ECEn 124 Structures 7 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 this variable with the “dot” operator: plane.altitude = 10000; plane.heading = 800; BYU CS/ECEn 124 plane.flightNum[0] plane.flightNum[1] plane.flightNum[2] plane.flightNum[3] plane.flightNum[4] plane.flightNum[5] plane.flightNum[6] plane.altitude plane.longitude plane.latitude plane.heading plane.airspeed Structures 0x0000(SP) 0x0002(SP) 0x0004(SP) 0x0006(SP) 0x0008(SP) 0x000a(SP) 0x000c(SP) 0x000e(SP) 0x0010(SP) 0x0012(SP) 0x0014(SP) 0x0016(SP) 8 Structures Structure Example #include <stdio.h> #include <string.h> Does not allocate memory struct person { char name[80]; int ssn; }; struct person barney, fred; Allocates two memory structs 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); } BYU CS/ECEn 124 Structures 9 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>; BYU CS/ECEn 124 Structures 11 typedef’s How To Use typedef’s 1) Create a logical data type scheme. A signed 8-bit number could be "s8" An unsigned 16-bit number could be "u16" 2) Create a “typedef.h” file for each microcontroller platform you use. 3) #include "typedef.h" in each of your files. 4) Use your new data type names. typedef unsigned int u16; typedef unsigned char u8; u16 number; BYU CS/ECEn 124 Structures 12 typedef’s typedef.h Example typedef typedef typedef typedef typedef typedef unsigned char u8; signed char s8; unsigned short u16; signed short s16; unsigned long u32; signed long s32; Replace: unsigned char variable; with: u8 variable; BYU CS/ECEn 124 Structures 13 typedef’s typedef’s Typedef declarations provide no additional functionality. Makes code more readable by giving applicationspecific names to variable types. typedef int Color; typedef struct flightType Flight; Color pixels[500]; Flight plane1, plane2; BYU CS/ECEn 124 Structures 14 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; person initials ssn height weight address street city int main() { tom.ssn = 555123456; tom.weight = 150; tom.address.zipCode = 84062; … BYU CS/ECEn 124 zipCode Structures 15 Array of structs Arrays of Structures Can declare an array of structs: typedef struct flightType { char flightNum[7]; int altitude; int longitude; int latitude; int heading; double airSpeed; } Flight planes[100]; /* max 6 characters */ /* in meters */ /* in tenths of degrees */ /* in tenths of degrees */ /* in tenths of degrees */ /* in km/hr */ 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; BYU CS/ECEn 124 Structures 16 struct Pointers Pointers and Structures Pointers can point at structures struct person { char name[80]; int ssn; } barney, *rubble; How Much Memory? int main() Not Common { rubble = &barney; strcpy((*rubble).name, “Rubble, Barney”); (*rubble).ssn = 555234561; printf(“%s %d\n”, (*rubble).name, (*rubble).ssn); } More Common strcpy(rubble->name, “Rubble, Barney”); rubble->ssn = 555234561; printf(“%s %d\n”, rubble->name, rubble->ssn); BYU CS/ECEn 124 Structures 17 struct Pointers Pointers and Structures Since pointers can point to structures, then it’s easy to make links between structures. struct person { char initials[2]; int ssn; int height; struct person *father; struct person *mother; }; tom father bill /* 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); } BYU CS/ECEn 124 Structures mother 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 18 Dynamic Memory Allocation Memory Usage + Heaps 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 runtime and are allocated on the heap. malloc() – allocates memory free() – frees memory BYU CS/ECEn 124 0x0000 0x0100 Global Data Section Heap SP 0x0600 Run-time stack 0x8000 PC Program (Flash) 0xffff Structures SFR’s Interrupt Vectors 19 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) ); } BYU CS/ECEn 124 Structures 20 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. BYU CS/ECEn 124 Structures 21 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 ); } BYU CS/ECEn 124 Structures 22 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); } BYU CS/ECEn 124 Structures 23 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. BYU CS/ECEn 124 Structures 24 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]); } BYU CS/ECEn 124 Structures 25 union union Example union { char c; int i; float f; double d; } x; x.c x.i x.f x.d = = = = char* c = &x.c; int* i = &x.i; float* f = &x.f; double* d = &x.d; printf("\nc printf("\ni printf("\nf printf("\nd 'z'; 5180; 3.14; 3.141592653589793; BYU CS/ECEn 124 Structures = = = = %p", %p", %p", %p", c); i); f); d); 26 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 compilerdependent. 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. BYU CS/ECEn 124 Structures 27 Bit Fields Bit Fields Example #pragma pack(push,1) typedef struct { unsigned short sec: 5; unsigned short min: 6; unsigned short hour: 5; } FATTime; #pragma pack(pop) // BYTE align in memory (no padding) #pragma pack(push,1) typedef struct { unsigned short day: 5; unsigned short month: 4; unsigned short year: 7; } FATDate; #pragma pack(pop) // BYTE align in memory (no padding) BYU CS/ECEn 124 // // // // (total 16 bits--a unsigned short) low-order 5 bits are the seconds next 6 bits are the minutes high-order 5 bits are the hour // End of strict alignment // // // // (total 16 bits--a unsigned short) low-order 5 bits are the day next 4 bits are the month high-order 7 bits are the year // End of strict alignment Structures 28 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 BYU CS/ECEn 124 Structures 29 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. list BYU CS/ECEn 124 50 75 Structures 99 NULL 30 Linked List Simple Linked List Example typedef struct element { int value; struct element* next; } Element; Element *list; list Element* newElement(int v) { Element* tmp; tmp = (Element*)malloc( sizeof(Element) ); tmp->value = v; tmp->next = NULL; return tmp; } 50 75 99 NULL int main() { /* Create linked list */ list = newElement(50); list->next = newElement(75); list->next->next = newElement(99); } BYU CS/ECEn 124 Structures 31 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. BYU CS/ECEn 124 Structures 32 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; } BYU CS/ECEn 124 Structures 33 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); } list BYU CS/ECEn 124 10 30 Structures 45 NULL 34 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; tmp->next = item; return oldList; /* Search for end of list */ } 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); } list BYU CS/ECEn 124 200 201 Structures 202 NULL 35 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 BYU CS/ECEn 124 Structures 36 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; } BYU CS/ECEn 124 Structures 37 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); } list 2 BYU CS/ECEn 124 3 65 Structures 97 300 NULL 38 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); } BYU CS/ECEn 124 Structures 39 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"); } BYU CS/ECEn 124 void printList(struct element *ptr) { if (ptr == NULL) printf("\n"); else { printf(" %d", ptr->value); printList(ptr->next); } } Structures 40 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; BYU CS/ECEn 124 Structures link date high low NULL 41 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 BYU CS/ECEn 124 Structures 42 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 BYU CS/ECEn 124 025e 0266 026e 0000 1e31 1ea3 1e45 1e96 2c 22 2c 28 28 1e 28 24 Structures 43 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 BYU CS/ECEn 124 Structures 44 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 BYU CS/ECEn 124 Structures 45 Example 2 Final Test void main(void) { Setting *list = NULL; eZ430X_init(CALDCO_1MHZ); lcd_init(); lcd_backlight(ON); // init board // init LCD // 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, list = insertSetting(newSetting(SUN, list = insertSetting(newSetting(TUE, list = insertSetting(newSetting(MON, list = insertSetting(newSetting(SAT, } 6, 30, 24<<1, 18<<1), list); 6, 30, 22<<1, 20<<1), list); 6, 30, 22<<1, 20<<1), list); 6, 30, 20<<1, 10<<1), list); 20, 30, 22<<1, 20<<1), list); printList(list); return; BYU CS/ECEn 124 Structures 46 BYU CS/ECEn 124 Structures 47