# Pointers

Document Sample

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
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
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
(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