Docstoc

Pointers

Document Sample
Pointers Powered By Docstoc
					             CS110: Lecture 21
               Structures With
             Arrays and Pointers
                     Jack Tumblin
                jet@cs.northwestern.edu


I hope you:
  –   Are much happier with PA-3(revised), Due Today.
  –   Are 'almost done' with PA-4 (short; due Wed. 11/19)
  –   Are trying tiny practice programs using pointers
  –   Are reading all about structures: Chap. 12 (no 12-8)
 Referencing and De-referencing
Recall:
• ‘referencing’ ==&== ‘get address’ operator
int k=2;
*pInt, arr[3]={5,6,7};

     pInt = &k;    /*   referencing */
     arr[2] =8;    /*   array indexing */
     pInt[0] =1;   /*   pointer indexing */
     *pInt = 1;    /*   pointer de-referencing */

        Dereferencing is same as indexing at zero!
Notation VERY confusing—looks like pointer declaration!
     ( *pInt == pInt[0] );      /* always true */
 Referencing and De-referencing
Recall:
• ‘indexing’ ==[#]== ‘get element’ operator
int k=2;
*pInt, arr[3]={5,6,7};

     pInt = &k;    /*   referencing */
     arr[2] =8;    /*   array indexing */
     pInt[0] =1;   /*   pointer indexing */
     *pInt = 1;    /*   pointer de-referencing */

        Dereferencing is same as indexing at zero!
Notation VERY confusing—looks like pointer declaration!
     ( *pInt == pInt[0] );      /* always true */
 Referencing and De-referencing
Recall: (Book does this too soon!)
• ‘de-referencing’==*== ‘value pointed to’ op
int k=2;
*pInt, arr[3]={5,6,7};

     pInt = &k;    /*   referencing */
     arr[2] =8;    /*   array indexing */
     pInt[0] =1;   /*   pointer indexing */
     *pInt = 1;    /*   pointer de-referencing */

        Dereferencing is same as indexing at zero!
Notation VERY confusing—looks like pointer declaration!
     ( *pInt == pInt[0] );      /* always true */
 Dynamic Allocation: Example
#include <stdlib.h>       malloc() and free() are
int main(void)            defined in stdlib.h
{
int k,kmax,*pKey,*pDone;
  ...
  pKey = (int *)malloc( kmax*sizeof(int) );
  for(k=0; k<kmax; k++)
  {
      pKey[k] = rand();           malloc(n) function:
  }                               reserve a block of n bytes
  ... (more work with pKey) ...      (Block has no name)
                              free(ptr) function:
  pDone = pKey;
  free(pDone);                release a block of bytes
  }                           at address ptr.
             CS110: Lecture 21
               Structures With
             Arrays and Pointers
                     Jack Tumblin
                jet@cs.northwestern.edu


I hope you:
  –   Are much happier with PA-3(revised), Due Today.
  –   Are 'almost done' with PA-4 (short; due Wed. 11/19)
  –   Are trying tiny practice programs using pointers
  –   Are reading all about structures: Chap. 12 (no 12-8)
   (Recall) Enumerated Types
Define a new ‘enum’ data type, Declare variables of it

typedef enum         /* define a new data type */
    {
        Sun, Mon, Tues, Wed, Thu, Fri, Sat
    }weekdayT;

     Name of our new data type   Declare some variables of type
                                 weekdayT
int main()
{
    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
  {
      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)
       1) Define a Data Structure
typedef struct workerT     /*****employee record *****/
{
   char *name;      /*    string variable           */
   float salary;    /*    in dollars                */
   char ssn[11];    /*    xxx-xx-xxxx               */
   int ded;         /*    tax deductions            */
} workerT;
                 ‘define a new type for me’
int main()                          ‘it is a data structure, and…’
{
  workerT emp1,staff[30];
                 ‘The name of the new data type is …’
     emp1.name = “Bob Cratchit”;
     emp1.salary = 10.00;
     strncpy(emp1.ssn,”022-85-7741”,11);
    ‘The members of the new data type are …’
     emp1.ded = 7;

}
2) Declare Variables of the new Type
 typedef struct workerT     /*****employee record *****/
 {
    char *name;      /*    string variable          */
    float salary;    /*    in dollars               */
    char ssn[11];    /*    xxx-xx-xxxx              */
    int ded;         /*    tax deductions           */
 } workerT;

 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   /*****employee record *****/
{
   char *name;      /*   string variable          */
   float salary;    /*   in dollars               */
   char ssn[11];    /*   xxx-xx-xxxx              */
   int ded;         /*   tax deductions           */
} workerT;

int main()                      Use ‘dot’ operator to access
{
   workerT emp1,staff[30];
                                the ‘members’ or ‘fields’;
   int i,imax;                  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       /* ****employee record ******/
{
    char *name;      /*   string variable         */
    float salary;    /*   in dollars              */
    char ssn[11];    /*   xxx-xx-xxxx             */
    int ded;         /*   tax deductions          */
} workerT;

int main()
{
workerT emp1,staff[30];
int i,imax;
    workerT.name = “Bob Cratchit”;
                                        Compiler Errors!!
    workerT.salary = 10.00;             ?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        /* ****employee record ******/
{
    char *name;       /*   string variable         */
    float salary;     /*   in dollars              */
    char ssn[11];     /*   xxx-xx-xxxx             */
    int ded;          /*   tax deductions          */
} workerT;
                    Data type!
int main()
{
workerT emp1,staff[30];      Error—Undeclared Variable?!?
int i,imax;
    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          /* ****employee record ******/
{
    char *name;       /*   string variable            */
    float salary;     /*   in dollars                 */
    char ssn[11];     /*   xxx-xx-xxxx                */
    int ded;          /*   tax deductions             */
} workerT;
                    Data type
int main()
                    Variable names
{
workerT emp1,staff[30];                      Correct way:
int i,imax;                                  Variables of type
    emp1.name = “Bob Cratchit”;              'workerT'
    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:
   –   WILL copy char, int, float, double, enum values,
   –   WILL copy array contents (because its size is fixed),
   –   WILL copy a pointer, but
   –   WON’T copy strings or other data located at pointers…
  Operators & Data Structures
typedef struct workerT          /* ****employee record ******/
{
   char *name;         /*   string variable   */
   float salary;       /*   in dollars        */
   char ssn[11];       /*   xxx-xx-xxxx       */
   int ded;            /*   tax deductions    */
} workerT;


  int main()
  {
  workerT staff[30], emp1;
                      /* copy Scrooge’s info*/
      staff[0].name = “Ebenezer Scrooge”;
      staff[0].salary = 250.00;
      strncpy(staff[0].ssn,”001-34-8902”,11);
      staff[0].ded = 1;
      emp1 = staff[0];
      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 group of variables’
 workerT emp1;
    ...                     Data structure ‘members’
              emp1.name = “Bob Cratchit”;
Array element emp1.salary = 10.00;
              emp1.ssn = “022-85-774”;
              emp1.ded = 7; etc. ...

                 NAME          Salary    Social Sec#   Ded.
      0
staff[0]   Ebenezer Scrooge   250.00    001-34-8902     1

emp1 1     Bob Cratchit         10.00   022-85-7741     7

staff[2]
      2    Phineas Fogg         20.00   001-02-0837     1

      3…
staff[3]           …            …            …         …
...
       Arrays of Data Structures
 Data Structure: ‘a named group of variables’

 How can we describe lots of complicated 'objects',
  where each 'object' has SEVERAL variable types?
   EXAMPLE: employee ledger; moving objects in a videogame...

 Answer: make an array of Data Structures…
                 NAME            Salary     Social Sec#    Ded.
      0
staff[0]   Ebenezer Scrooge      250.00    001-34-8902      1

staff[1]
      1    Bob Cratchit           10.00    022-85-7741      7

staff[2]
      2    Phineas Fogg           20.00    001-02-0837      1

      3…
staff[3]            …              …            …           …
...
        Arrays of Data Structures
Example:
typedef struct workerT      /* ****employee record ******/
{
    char *name;     /*   string variable         */
    float salary;   /*   in dollars              */
    char ssn[11];   /*   xxx-xx-xxxx             */
    int ded;        /*   tax deductions          */
} workerT;

    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;     /* struct variables               */
workerT *pGood;              /* pointer-to-struct              */
...
    pGood = &emp1;           /* point to 'emp1'                */
    pGood = staff + 3;       /* point to staff[3]              */


• Use indirection (* or [0]) to get members:
      pGood[0].salary += 1000;        /* Give a raise      */
                                      /* OR you can write: */
      (*pGood).salary += 1000;        /* Give a 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 */

       • Operator precedence for ‘*’ makes a mess!
SAME




                           (ANOTHER reason to hate the * form of de-referencing)

             *pGood.salary += 1000;         !NO! --!ERROR!

       • INSTEAD: use this nearly-pictorial operator:
             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;


    pWho = (workerT *)malloc(30*sizeof(workerT));
    /* now pWho points to 30 workerT elements...*/

    pWho[0].name =(char *)malloc(31*sizeof(char));
    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;
    ...
Dynamic Alloc. for Structures II
Data structures can have pointer members, too...:
 typedef struct workerT       /* ****employee record ******/
 {
     char *name;      /*   string variable         */
     float salary;    /*   in dollars              */
     char ssn[11];    /*   xxx-xx-xxxx             */
     int ded;         /*   tax deductions          */
 } workerT;

workerT emp1;

     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’
    • 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)                        formal parameters
         actual argument
{
double val=1.234;                   void dfixit2(double *x)
double *pd;                         {
                                        x[0] = 42.0;
      pd = &val;             NO!        x++;    /* move!? */
      dfixit(pd);                   }
}    /* now val=42.0 */
     /* pd unchanged */
 Functions and Data Structures
• What if function arguments are 'struct'-type variables?
  works just fine: copies struct to formal parameters...
  workerT give_raise(workerT b4);    /*costly prototype!     */

  int main(void)
  {
  workerT emp1;
    ...
        emp1 = give_raise( emp1 );   /*costly fcn call */
    ...
  }                     COPY
  workerT give_raise(workerT b4)     /* costly fcn body */
  {
     b4.salary += 1000.00;
     ...
     return(b4);
  }
 Functions and Data Structures
• Recall that we call a function,
  we copy actual arguments to formal parameters
  workerT give_raise(workerT b4);    /*costly prototype!    */

  int main(void)
  {
  workerT emp1;
    ...
        emp1 = give_raise( emp1 );   /*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);    /*costly prototype!     */

  int main(void)
  {
  workerT emp1;
    ...
        emp1 = give_raise( emp1 );   /*costly fcn call */
    ...
  }
                      COPY
  workerT give_raise(workerT b4)     /* costly fcn body */
  {
     b4.salary += 1000.00;
     ...
     return(b4);
  }
 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 500KB 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               COPY THE BIG
   RETURNED STRUCT to emp1       INPUT STRUCT to b4
 Functions and Data Structures
• Make a habit of Pass-by-Reference for structures:
   – Copies only the address to function—FAST!
   – No return value needed—Efficient!
void give_raise(workerT *pGood);     /* efficient prototype!*/

  int main(void)
  {
  workerT emp1;
    ...
       give_raise(&emp1);          /* Better! use a pointer */
     ...
  }

void give_raise(workerT *pGood)    /* efficient function body*/
       {
       pGood->salary += 1000.0;    /* Note the 'shorthand' */
      }/* (same as (pGood[0]).salary or (*pGood).salary    */

				
DOCUMENT INFO
Shared By:
Categories:
Tags:
Stats:
views:3
posted:10/2/2011
language:English
pages:29