Structures

download Structures

If you can't read please download the document

description

Structures. C and Data Structures Baojian Hua [email protected]. Why need “ Structure ” ?. So far, we ’ d discussed two kinds of data: Simple: char, int, long, double, etc. Scalar: array, pointer, etc. It ’ s inconvenient in some applications: See next slides for an example. Example. - PowerPoint PPT Presentation

Transcript of Structures

  • StructuresC and Data StructuresBaojian [email protected]

  • Why need Structure?So far, wed discussed two kinds of data:Simple: char, int, long, double, etc.Scalar: array, pointer, etc.Its inconvenient in some applications:See next slides for an example

  • Example// We want to represent time as year/month/date:int f (){ int year1, year2, month, date;

    year1 = 2050; year2 = 2020; month = 12; date = 30; date++; // Should we increase year1 or year2?}// The problem is that there is no logical// connection between them. We need structure!

  • Structure Declaration// Start with key word struct and followed by // an optional structure tag, and then a list // (one or more) of fields. // Example, to represent a two-dimensional point:struct point2d{int x; int y;}; // note the semicolon// point2d contains two fields x and y, both of // type int.// struct point2d (as a whole) is a (user-defined) // new type.

  • Variable Definition// Given the declaration above, we may declare a // variable pt:struct point2d pt;// to be of type struct point2d, just the same // way as we write:int i;

  • Structure Fields// Given the variable definitionstruct point2d pt;// fetching its fields x or y:pt.x;pt.y;// which act as ordinary variables, such as:pt.x = 9;pt.y = 10;// or:printf (%d\n, pt.x + pt.y);

  • Structure in Structure// Having known that structures are types, we may// study its memory layout. Technically, a// structure occupies a piece of continuous space:// So, we may even nest structures// in other structures, as in:struct rect{struct point2d pt1;struct point2d pt2;};

  • Structures and Functions// A function creating a point2d structure:struct point2d create (int ax, int ay){ struct point2d pt;

    pt.x = ax; pt.y = ay; return pt;}

    // And a sample call:struct point2d p = create (3, 4);34ax==3ay==4

  • Structures and Functions// A function creating a point2d structure:struct point2d create (int ax, int ay){ struct point2d pt;

    pt.x = ax; pt.y = ay; return pt;}

    // And a sample call:struct point2d p = create (3, 4);34ax==3ay==4

  • Structures and Functions// A function creating a point2d structure:struct point2d create (int ax, int ay){ struct point2d pt;

    pt.x = ax; pt.y = ay; return pt;}

    // And a sample call:struct point2d p = create (3, 4);34ax==3ay==4

  • Structures and Functions// A function creating a point2d structure:struct point2d create (int ax, int ay){ struct point2d pt;

    pt.x = ax; pt.y = ay; return pt;}

    // And a sample call:struct point2d p = create (3, 4);34ax==3ay==4

  • Structures and Functions// A function creating a point2d structure:struct point2d create (int ax, int ay){ struct point2d pt;

    pt.x = ax; pt.y = ay; return pt;}

    // And a sample call:struct point2d p = create (3, 4);34ax==3ay==4

  • Structures and Functions// A function creating a point2d structure:struct point2d create (int ax, int ay){ struct point2d pt;

    pt.x = ax; pt.y = ay; return pt;}

    // And a sample call:struct point2d p = create (3, 4);34ax==3ay==4

  • Structures and Functions// A function creating a point2d structure:struct point2d create (int ax, int ay){ struct point2d pt;

    pt.x = ax; pt.y = ay; return pt;}

    // And a sample call:struct point2d p = create (3, 4);p34

  • Structures as Functions Arguments// Like the structure return value, passing// structures to functions copy the whole // structure field-by-field (call-by-value):struct point2d mult2 (struct point2d pt){ pt.x *= 2; pt.y *= 2; return pt;}

    // A sample call:struct point2d p = mult2 (initPt);// Much like the previous example// Analysis leave to you

  • MoralStructures returned from function and passed to functions are call-by-valuePros: a simple style of functional programmingresult in elegant and easy-to-reason codeideas from functional languages (lisp, ML, F#), but may also be useful in imperative and OO languagesCons: may be too inefficientstupidly copy a big valuesemantics inconsistent with arrayNext, wed discuss a more imperative styleUpdate in place

  • Pointers to Structures// Pointers to structures are just like pointers // to any other kind of data:struct point2d *pt;// declares pt to be a pointer to a structure // ponit2d, which looks like:// To reference x and y, we use:(*pt).x;(*pt).y;// or a more concise shorthand:pt->x;pt->y;pt

  • Structure Pointers as Functions Arguments// Address passing:void mult2 (struct point2d *pt){ pt->x *= 2; pt->y *= 2; return;}

    // A sample call (no return value):struct point2d p = creat (3, 4);mult2 (&initPt);// Analysis leave to you

  • Self-referential Structures// With structures pointer mechanism, we may// write self-referential structures (structures// fields point to same type of structures):struct node{ int data; struct node *next;};

  • UnionA union may hold (at different times) objects of different types and sizescompilers take care of the space allocation, alignment, etc.Unions provide a way to manipulate different kinds of data in a single area of storage

  • Union// A sample union type:union intOrArray{ int i; int a[2];};// which declares intOrArray to have two fields:// integer i and int array a of length 2.

  • Union// A sample union type:union intOrArray{ int i; int a[2];};// which declares intOrArray to have two fields:// integer i and int array a of length 2.union intOrArray u;u.a[0] = 88;u.a[1] = 99; // u.i == ???

  • Union// A sample union type:union intOrArray{ int i; int a[2];};// which declares intOrArray to have two fields:// integer i and int array a of length 2.union intOrArray u;u.i = 77;;// u.a[2] = ???

  • Union// A sample union type:union intOrArray{ int i; int a[2];};// Even worse. What if we write an output?void output (union intOrArray x){printf (%d\n, x.i);// or:printf (%d, %d\n, x.a[0], x.a[1]);}

  • Moral on UnionUnion gives us a magical bag to let us bypass the Cs type systemstore an integer, but take out an arrayIts the programmers responsibility to keep union data consistentBut what if the union value is written by others or from a library, which we may know nothing about?

  • Tagged Union// In order to distinguish union states, we // annotate unions with tags:struct ss{ enum {INT, ARRAY} tag; union intOrArray { int i; int a[2]; } u;};

  • Tagged Union// And for variable temp:struct ss temp;// now we must take care of temps tag fields:temp.u.i = 99;temp.tag = INT;// Or to store an array:temp.u.a[0] = 3;temp.u.a[1] = 4;temp.tag = ARRAY;

  • Tagged Union// data accessing is guarded:void output (struct ss x){switch (x.tag) {case INT: printf (%d, x.u.i); break;case ARRAY: printf (%d, %d, x.u.a[0], x.u.a[1]); break; default: // error handling }}

  • typedef---Define Our Own TypesAnd its rather stupid and annoying to always write long type names like these:struct point2d pt;struct point2d *pp;And even some types are rather crazy:int (*f[10])(int, int);int (*f(char c))(int, int);Are there some better methods?Yes! Its the typedef

  • typedef---Define Our Own Types// C has a mechanism called typedef allowing us // to define our own types (abbreviations).// For instance:typedef struct point2d pt2d;// defines pt2d to be a type equivalent to // struct point2d. And next, pt2d could be// used just as any other type:pt2d pt;pt.x = 3;pt.y = 4;

  • typedef---Define Our Own Types// Not only structures can be typedefed, but also // any type name, even the pre-defined ones in C:typedef int sizeT;

    sizeT i;i = sizeof (int);sizeT j;j = i;

  • typedef---Define Our Own Types// More examples of typedef:typedef int *t1;typedef int (*t2)();typedef char **t3;typedef int *t4[10];typedef int (*t5)[10];typedef int *t6();typedef char (*(*t7())[])();typedef (*(*t8[3])())[5];

  • typedef---Define Our Own Types// More examples of typedef:typedef int *t1;typedef int (*t2)();typedef char **t3;typedef int *t4[10];typedef int (*t5)[10];typedef int *t6();typedef char (*(*t7())[])();typedef (*(*t8[3])())[5];

    // How to read these crazy stuffs? // Next, to show the general principal, Ill take // type t7 as a running example:

  • Inorder Analysistypedef char (*(*t7())[])();

    // t7 is a function, takes void// function returns a pointer// pointing to an array// array storing pointers// pointing to functions (taking void returning // char)

    // Really annoying! Better solutions? Yes!

  • Preordertypedef char (*(*t7())[])();

    // Step by step:typedef char (*t71)();typedef t71 t72[];typedef t72 *t7();

    // Question: How to rewrite t8?

  • Type Cast RevisitWed discussed type castEx: (int)3.14unsafe in generalType cast on pointers is more flexible, subtle, and dangerouswed discuss an example below

  • Type Cast on Pointerschar c = a;char *p = &c;

    int *q = (int *)p;*q = 9999;

    short *r = (short *)q;*r = 88;

    a????p10001001100210031004

  • Exampleint sum (int x, int y){int temp = x + y; return temp;}

    int main () { char *s = (char *)sum;

    return 0;}

  • Exampleint sum (int x, int y){int temp = x + y; return temp;}

    int main () { char *s = (char *)sum;char a[100];

    return 0;}

  • Exampleint sum (int x, int y){int temp = x + y; return temp;}

    int main () { char *s = (char *)sum;char a[100];int i;for (i=0; i

  • Example

    int main () { char *s = (char *)sum;char a[100];int i;for (i=0; i

  • Example

    int main () { char *s = (char *)sum;char a[100];int i;for (i=0; i

  • An Array Can be Called!

    typedef int (*tf)(int, int);int main () { char *s = (char *)sum;char a[100];int i;for (i=0; i

  • Summary of Typedefstypedef doesnt create any new type nameit creates shorthands for known typestypedef is an important mechanism:to make program maintenance and porting easyto enable information hidingmore on this later

  • Bit-fields// Whats bit-fields, and why do we want them?// We start by defining a student structure:struct student{char *name;int gender; // 0 or 1int classNum; // 0~7int isLeader; // 0 or 1};// See the problem?

  • Bit-fields// To save space, We use bit-fields:struct student{char *name;unsigned int gender : 1; // 0 or 1unsigned int classNum : 3; // 0~7unsigned int isLeader : 1; // 0 or 1};// Question: what the size of struct student?

  • Bit-fields// Sample operations:#define FEMALE 0x00#define MALE 0x01#define CLASS1 0x00#define CLASS8 0x07

    struct student s;s.name = Bill Gates;s.gender = MALE;s.classNum = CLASS0;s.isLeader = 0x00;

  • Bit-fields for Data // Besides saving space, some externally-imposed // data formats require compact data rep.// As a final example in this slide, we discuss// x86s interrupt descriptor (id):

  • Bit-fields for Data struct idtEntry{unsigned int offset0_15 : 16;unsigned int selector : 16;unsigned int notUsed : 5;unsigned int zeros : 3;unsigned int reserved : 5;unsigned int dpl : 2;unsigned int p : 1;unsigned int offset16_31 : 16;};