CS110_08a._structArray

CS110_08a._structArray - EECS110: 8a Structures With Arrays...

Info iconThis preview shows page 1. Sign up to view the full content.

View Full Document Right Arrow Icon
This is the end of the preview. Sign up to access the rest of the document.

Unformatted text preview: EECS110: 8a Structures With Arrays and Pointers Jack Tumblin [email protected] . (Recall) Enumerated Types Define a new `enum' data type, Declare variables of it typedef enum weekdayT // define a new data type { Sun, Mon, Tues, Wed, Thu, Fri, Sat }weekdayT; Name of our new data type Declare some variables of type int main() weekdayT { weekdayT today,tomorrow; // declare vars today = Sat; tomorrow = (today-1)%7; ... // computed as int (Recall) Enumerated Types Mostly a notational convenience Works just like #define statements: 0 1 2 3 4 5 6 typedef enum weekdayT { Sun, Mon, Tues, Wed, Thu, Fri, Sat } weekdayT; enum variables given int values internally, or you can assign them explicitly (see book) No restrictions on value-today = 578; allowed (but meaningless) New! 1) Define a Data Structure //*****employee record ***** string variable in dollars xxx-xx-xxxx tax deductions New! typedef struct workerT { char *name; // float salary; // char ssn[11]; // int ded; // } workerT; int main() { workerT emp1,staff[30]; `define a new type for me' `it is a data structure, and...' `The name of the new data type is ...' emp1.name = "Bob Cratchit"; emp1.salary = 10.00; strncpy(emp1.ssn," new data type are `The members of the 022-85-7741",11);...' emp1.ded = 7; } 2) Declare Variables of the new Type typedef struct workerT { char *name; // float salary; // char ssn[11]; // int ded; // } workerT; //*****employee record ***** string variable in dollars xxx-xx-xxxx tax deductions int main() { workerT emp1, *pGood, staff[30]; int i,imax; `workerT' is now a data type. emp1.name = "Bob Cratchit"; emp1.salary = 10.00; strncpy(emp1.ssn,"022-85-7741",11); emp1.ded = 7; Declare an ordinary variable emp1, } and a pointer-to-workerT variable pGood, and an array of workerT elements staff[30] 3) Initialize and Use struct Variables typedef struct workerT { char *name; // float salary; // char ssn[11]; // int ded; // } workerT; //*****employee record ***** string variable in dollars xxx-xx-xxxx tax deductions int main() { workerT emp1,staff[30]; int i,imax; Use `dot' operator to access the `members' or `fields'; of the data structure emp1.name = "Bob Cratchit"; emp1.salary = 10.00; strncpy(emp1.ssn,"022-85-7741",11); emp1.ded = 7; } A Beginner's Mistake Don't confuse data type you defined with a data structure and the variables of that type: typedef struct workerT { char *name; float salary; char ssn[11]; int ded; } workerT; int main() { workerT emp1,staff[30]; int i,imax; workerT.name = "Bob Cratchit"; workerT.salary = 10.00; ... // // // // string variable in dollars xxx-xx-xxxx tax deductions //*****employee record ****** Compiler Errors!! ?What's wrong? A Beginner's Mistake Don't confuse data type you defined with a data structure and the variables of that type: typedef struct workerT { char *name; float salary; char ssn[11]; int ded; } workerT; int main() { workerT emp1,staff[30]; int i,imax; // // // // string variable in dollars xxx-xx-xxxx tax deductions //*****employee record ****** Data type! Error--Undeclared Variable?!? workerT.name = "Bob Cratchit"; workerT.salary = 10.00; ... A Beginner's Mistake Don't confuse data type you defined with a data structure and the variables of that type: typedef struct workerT { char *name; float salary; char ssn[11]; int ded; } workerT; int main() // // // // string variable in dollars xxx-xx-xxxx tax deductions //*****employee record ****** Data type Variable names Correct way: Variables of type 'workerT' { workerT emp1,staff[30]; int i,imax; emp1.name = "Bob Cratchit"; emp1.salary = 10.00; ... Operators & Data Structures For the basic data types, many operators work: =, +, -, *, /, <, >, <=, ==, >=, !=, . etc. Data structure types: ONLY assignment (=) works (=) is a Member-by-Member / Field-by-field copy To: To WILL copy char, int, float, double, enum values, WILL copy array contents (because its size is fixed), WILL copy a pointer's value (a location), but WON'T copy strings or other data located at pointers... ASSIGN (=) for Data Structures typedef struct workerT { char *name; // float salary; // char ssn[11]; // int ded; // } workerT; //*****employee record ****** string variable in dollars xxx-xx-xxxx tax deductions !! CAREFUL !! int main() { workerT boss, emp1; // set Scrooge's info boss.name = "Ebenezer Scrooge"; boss.salary = 250.00; strncpy(boss.ssn,"001-34-8902",11); boss.ded = 1; emp1 = boss; printf("%s, $%5.2f, ssn=%s, ded=%d\n", emp1.name,emp1.salary,emp1.ssn, emp1.ded); } RESULT: > Ebenezer Scrooge, $250.00, ssn=001-34-8902, ded=1 > ASSIGN (=) for Data Structures typedef struct workerT { char *name; // float salary; // char ssn[11]; // int ded; // } workerT; /*****employee record ******/ string variable in dollars DANGER! Copies POINTER, xxx-xx-xxxx tax deductions But NOT it's target But NOT it's target One string, two pointers to it! address 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 int main() { E b e emp1; S c r o o g e \0 workerT boss, n e z e r /* set Scrooge's info*/ boss.name = "Ebenezer Scrooge"; boss.salary = 250.00; boss.name emp1.name strncpy(boss.ssn,"001-34-8902",11); boss.ded = 1; emp1 = boss; printf("%s, $%5.2f, ssn=%s, ded=%d\n", emp1.name,emp1.salary,emp1.ssn, emp1.ded); } RESULT: > Ebenezer Scrooge, $250.00, ssn=001-34-8902, ded=1 > Arrays of Data Structures Data Structure: `a named packet of variables' How can we describe lots of complicated 'objects', where each 'object' holds SEVERAL variable types? EXAMPLE: employee ledger; moving objects in a videogame... Answer: make an array of Data Structures... Structures NAME Salary 250.00 10.00 20.00 Social Sec# 001-34-8902 022-85-7741 001-02-0837 Ded. 1 7 1 0 staff[0] 1 staff[1] staff[2] 2 staff[3] 3... ... Ebenezer Scrooge Bob Cratchit Phineas Fogg ... ... ... ... Arrays of Data Structures Data Structure: `a named packet of variables' workerT staff[30]; ... Array element Data structure `members' staff[1].name = "Bob Cratchit"; staff[1].salary = 10.00; staff[1].ssn = "022-85-774"; staff[1].ded = 7; etc. ... NAME Salary 250.00 10.00 20.00 Social Sec# 001-34-8902 022-85-7741 001-02-0837 Ded. 1 7 1 0 staff[0] 1 staff[1] staff[2] 2 staff[3] 3... ... Ebenezer Scrooge Bob Cratchit Phineas Fogg ... ... ... ... Arrays of Data Structures Example: typedef struct workerT { char *name; float salary; char ssn[11]; int ded; } workerT; // // // // string variable in dollars xxx-xx-xxxx tax deductions //*****employee record ****** float cost; int k,kmax; workerT staff[30]; staff[0].name = "Ebenezer Scrooge"; staff[0].salary = 250.00; strncpy(staff[0].ssn,"001-34-8902",11); staff[0].ded = 1; staff[1].name = "Bob Cratchit"; staff[1].salary = 10.00; . . . Pointers-to-Struct Pointers work on structs exactly as before... workerT staff[30], emp1; workerT *pGood; ... pGood = &emp1; pGood = staff + 3; // struct variables // pointer-to-struct // point to 'emp1' // point to staff[3] Use indirection (* or [0]) to get members: pGood[0].salary += 1000; (*pGood).salary += 1000; // // // Give a OR you Give a raise can write: raise Operator precedence for `*' makes a mess: (ANOTHER reason to hate the * form of de-referencing) *pGood.salary += 1000; !NO! -- !ERROR! Pointers-to-Struct : -> Pointers work on structs exactly as before... workerT staff[30], emp1; // struct variables workerT *pGood; // pointer-to-struct ... pGood = &emp1; // point to 'emp1' pGood[0].salary += 1000; // Give a raise pGood = staff + 3; // point to staff[3] (*pGood).salary += 1000; // Give another raise SAME Operator precedence for `*' makes a mess! (ANOTHER reason to hate the * form of de-referencing) *pGood.salary += 1000; !NO! --!ERROR! INSTEAD: use this nearly-pictorial operator: INSTEAD pGood->salary += 1000; Dynamic Alloc. for Structures I Just as we can have fixed arrays of structures (e.g. workerT staff[30]; ) We can have dynamically allocated arrays of structs: int k,kmax; workerT *pWho; // pointer-to-struct pWho = (workerT *)malloc(30*sizeof(workerT)); // now pWho points to 30 workerT elements... strncpy(pWho[0].name,"Ebenezer Scrooge",30); pWho[0].salary = 250.00; strncpy(pWho[0].ssn,"001-34-8902",11); pWho[0].ded = 1; pWho[1].name = "Bob Cratchit"; pWho[1].salary = 10.00; ... free(pWho); // RELEASE allocated memory Dynamic Alloc. for Structures I Just as we can have fixed arrays of structures (e.g. workerT staff[30]; ) We can have dynamically allocated arrays of structs: int k,kmax; workerT *pWho, *pSel; // pointers-to-struct pWho = (workerT *)malloc(30*sizeof(workerT)); // now pWho points to 30 workerT elements... // BETTER: USE -> operator, like this: pSel = pWho; // point to start of array; strncpy(pSel->name,"Ebenezer Scrooge",30); pSel->salary = 250.00; strncpy(pSel->ssn,"001-34-8902",11); pSel->ded = 1; pSel++; // point to the NEXT employee; pSel->name = "Bob Cratchit"; pSel->salary = 10.00; ... free(pWho); // RELEASE allocated memory Dynamic Alloc. for Structures II Data structures can have pointer members, too...: typedef struct workerT { char *name; float salary; char ssn[11]; int ded; } workerT; // // // // string variable in dollars xxx-xx-xxxx tax deductions //*****employee record ****** workerT emp1; // BETTER! Allocate memory for the `name' pointer emp1.name =(char *)malloc(31*sizeof(char)); strncpy(emp1.name,"Ebenezer Scrooge",30); emp1.salary = 250.00; strncpy(emp1.ssn,"001-34-8902",11); emp1.ded = 1; emp1.name = "Bob Cratchit"; emp1.salary = 10.00; `Pass by Reference' Subtlety (Recall) For function arguments that are pointers Copy an address to the formal parameters, But changing formal parameter (the address) in the function NEVER changes the actual argument! main (void) { double val=1.234; double *pd; actual argument pd = &val; dfixit(pd); // now val=42.0 // pd unchanged formal parameters void dfixit(double *x) { x[0] = 42.0; x++; // move!? } NO! } Functions and Data Structures What if function arguments are 'struct'-type variables? works just fine: copies the struct to formal parameters... workerT give_raise(workerT b4); int main(void) { workerT emp1; ... emp1 = give_raise( emp1 ); ... } COPY // costly prototype! // costly fcn call COPY workerT give_raise(workerT b4) { b4.salary += 1000.00; ... return(b4); } // costly fcn body Functions and Data Structures Recall that we call a function, we copy actual arguments to formal parameters workerT give_raise(workerT b4); int main(void) { workerT emp1; ... emp1 = give_raise( emp1 ); ... } // costly prototype! // costly fcn call workerT give_raise(workerT b4) // costly fcn body { b4.salary += 1000.00; COMPUTE ... return(b4); } Functions and Data Structures And when return something from a function, we copy it from local variables... workerT give_raise(workerT b4); int main(void) { workerT emp1; ... emp1 = give_raise( emp1 ); ... } // costly prototype! // costly fcn call COPY workerT give_raise(workerT b4) { b4.salary += 1000.00; ... return(b4); } // costly fcn body Functions and Data Structures Structs are just one more data type it all works fine. BUT data structures may be HUGE!: (suppose the workerT struct includes a 12.5MB photo...) do you need to copy back and forth to/from functions? workerT give_raise(workerT b4); // costly prototype! int main(void) { workerT emp1; ... emp1 = give_raise( emp1 ); // costly fcn call } COPY THE BIG RETURNED STRUCT to emp1 COPY THE BIG INPUT STRUCT to b4 Functions and Data Structures Make a habit of Pass-by-Reference for structures: Copies only the address for function to use--FAST! No return value needed--Efficient! void give_raise(workerT *pGood); int main(void) { workerT emp1; ... give_raise(&emp1); ... } // efficient prototype! // Better! use a pointer void give_raise(workerT *pGood) // efficient func. body { pGood->salary += 1000.0; // Note the 'shorthand' } // (same as (pGood[0]).salary or (*pGood).salary ...
View Full Document

This note was uploaded on 10/05/2011 for the course COMPUTER S 110-1 taught by Professor Tumblin during the Spring '11 term at Northwestern.

Ask a homework question - tutors are online