Lecture #21: Pointers
November
22, 1999
Bob
Pitha
the nature of memory
Way
back, we talked about computer memory
its a bunch
of bytes
each byte
can hold 256 values
adjacent
bytes can be combined to hold larger values
usually
grouped in powers of 2 (2, 4, 8, 16,
)
Whats
adjacent mean?
bytes in
memory are numbered sequentially
sequential numbering
So
memory is a long sequence of storage spaces for numbers
like a long
line of lockers
each locker
is given a number
C lets us
use that number
addresses
In
C, we call these locker numbers addresses
an address
is the number of the byte we want
or if were
talking about a grouped byte, its the first byte of the group
When
a variable contains an address, we call it a pointer
because it
points to some other data in memory
its like a treasure hunt
Up
to now, weve dealt only with straightforward variables
they hold
the data we care about
just like a
locker holding something for me
I can put my
book in my locker and get it again later
Pointers
introduce a level of indirection
instead of
holding the data, they hold information about where to find the data
so now my
locker would only hold a piece of paper, telling me which locker to look in for
my book
whats the point?
Indirection
can be helpful
when the
actual data location may change
mail sent to
this address goes to me
but next
term, if someone else is teaching CSE 5a, it will go to that person
just more numbers
Like
every other kind of data we use, addresses are numbers
up to now,
though, our data has been numbers we care about
temperatures
dates
results of
calculations
addresses
are numbers too, but ones that only are useful to the program while its
running
data types
A
pointer isnt a new data type
its just
kind of a modification, because the pointer should point to a data type
or another
pointer, that must eventually find a data type
declaring a pointer
We
declare a pointer using a *
this
declaration creates a variable named ptr

ptr is a
variable whose value is an address
the thing we
expect to find at that address is an int
since an int
is 4 bytes (on our computers, at least), this is the address of the first byte
of a group of 4 bytes
but ptr has
not yet had its value set, so it does not yet contain a valid address of
anything
the address-of (&) operator
The
unary operator & is used to find an objects address
that is, its
operand is an object
remember
that an object is something with memory associated with it
the value of
the expression (operator and operand) is the address in memory of the operand
example
So,
lets put this all together:

the first
line defines a variable named i
it is an
int, and thus has 4 bytes of memory reserved for it
its value is
set to 1

example
So,
lets put this all together:
the second
line defines a variable named ptr
it is a
pointer to an int
it is
initialized to the address of i
thus, it
contains a number which is an address
if you look
at the 4 bytes starting at that address, you will find the value 1

the contents-of (*) operator
The
unary operator * is used to access whatever is at a given address
its operand
is an address
the value of
the expression is an lvalue
remember
that an lvalue is an expression that refers to an object
and an
object is something with memory associated with it
an address
is supposed to refer to a location in memory
so an
expression using the * operator refers to an object, and thus is an lvalue
that means
we can assign its value as well as look at it
example
What
does this print?

example
What
does this print?

we know the
first two lines create the variables i and ptr
i
is an int, containing the value 1
ptr
is a pointer, containing the address of i

example
What
does this print?

*ptr refers
to the thing that ptr points to
ptr points
to the memory that stores the value of i
so this line
assigns the value 2 to i

example

What
does this print?
it just
prints the value of i
which is now
2

confusion
This
is going to be confusing for a while
We
have 2 values now:
the value of
the pointer
which
determines what the pointer points to
and the
value in the location the pointer points to
confusion
We
can change the value of the pointer:
example

What
does this do?
example
What
does this do?

this
declaration creates the variable i
i is an int,
containing the value 42

example
What
does this do?

this
declaration creates the variable j
j is an int,
containing the value 17

example
What
does this do?

this
declaration creates the variable ptr
ptr is a
pointer
initially,
it points to i

example
What
does this do?

this statement
assigns the value 1 to whatever ptr points to
which, as we
already know, is i

example
What
does this do?

this statement
reassigns the value of ptr
so it now
points to j instead of i

example
What
does this do?

and finally,
we assign the value 2 to whatever ptr points to
which is now
j

operations on pointers
What
weve seen so far:
assignment
(=)
dereferencing
(*)
address
(&)
pointer assignment
As
with arithmetic assignment:
the object
on the left side must be an lvalue
therefore,
this is not valid:

Both operands must be pointers to the same data type
valid:

invalid

pointer dereferencing
Single
operand, must be a pointer
The
data type of the expression is the data type of whatever the pointer points to
thus, given
this declaration,

the
data type of the expression *ptr
is int
address-of operator (&)
Operand
must be something with memory associated
so the
expression &(i+j)
is invalid
The
data type of the expression is pointer to T
where T is
whatever the data type of the operand is