Sie sind auf Seite 1von 8

Memory Addresses

When a program is executed, memory


locations are assigned to the variables.

CS1010 Lecture 7

Each of these memory locations has a


positive integer address that uniquely defines
the location.

Pointers
Henry Chia
hchia@comp.nus.edu.sg

When a variable is assigned a value, this


value is stored in the corresponding memory
location.

Semester 1 2011 / 2012


Department of Computer Science

The specific addresses used for the variables


are determined each time that the program is
executed and may vary from one execution to
another.

School Of Computing
National University Of Singapore

CS1010 Lecture 7 p.1/31

CS1010 Lecture 7 p.3/31

Memory Addresses

Lecture Outline
Memory addresses

For the following declaration:


int count = 1010;

Pointers
Declaration and assignment
Dereference
Pointer comparison

Detailed memory representation:


@100

count 1010

Pointers in functions
Pointer parameters
Address as return value

In the slides, a memory address value is


indicated with a @ sign.
Note: Addresses used for illustration are not representative

Pointers to structures

of the exact address allocation policy.

CS1010 Lecture 7 p.2/31

CS1010 Lecture 7 p.4/31

Address Operator

Pointer Declaration

The address of a variable can be referenced using the


address operator &,
double x = 1.23;

Consider the following declarations:


int count=1010, *ptr; // int count;
// int *ptr;

C uses an asterisk in declarations to indicate


that the variable is a pointer variable.

printf("%lf stored at %p\n", x, &x);

Address may be printed with a %p placeholder.


Apart from debugging with printf, actual address
values are not used explicitly as they are system
dependent and may vary from one execution to
another.

int *ptr is read from right to left as


declare ptr as a pointer to a int.
Identifier name is ptr; type is int *.
Although ptr can be initialized during
declaration, use separate assignment
statement to avoid notational confusion.

CS1010 Lecture 7 p.5/31

CS1010 Lecture 7 p.7/31

Pointer Variable

Pointer Declaration

The C language allows us to store the


address of a memory location in a special
type of variable called a pointer variable (or
simply pointer).

The memory representation for the


declaration on the previous slide is as follows:

When a pointer is defined, the type of variable


to which it will point must also be defined.
Thus, a pointer defined to point to an integer
variable cannot also be used to point to a
floating-point variable.

CS1010 Lecture 7 p.6/31

@100

<int> count 1010


@300

<int *> ptr

ptr stores an unknown address value;


however ptr is located at memory address
@300.

CS1010 Lecture 7 p.8/31

Pointer Assignment

More Pointer Assignments

To specify that ptr should refer (or point) to


the variable count, assign the address of
count (&count) to ptr:

Now consider the following declarations:


int count = 1020, *ptr1, *ptr2;

ptr = &count;

@300

The memory representation is as follows. To


avoid using memory address values, you may
use arrows to point to the desired variables.
1010

?
@100

<int> count 1020

@300

@100

<int> count

<int *> ptr1

<int *> ptr

@100

@400

<int *> ptr2

Is ptr = &ptr; valid?


CS1010 Lecture 7 p.9/31

CS1010 Lecture 7 p.11/31

More Pointer Assignments

Pointer Dereference
Consider the following statements:
int count, *ptr;
ptr = &count;
*ptr = 1020;
printf("Var at %p stores %d\n", ptr, *ptr);

ptr1 = &count;
Assign the address of variable count to
the variable ptr1.
@300

<int *> ptr1 @100

The asterisk used in statements is a


dereferencing or indirection operator.

@100

In the statement *ptr = 1020, assign 1020


to the variable pointed to by ptr, i.e.
variable count now stores the value 1020.
In the printf statement, *ptr is the value
pointed to by ptr, i.e. the value of count.
CS1010 Lecture 7 p.10/31

<int> count 1020


@400

<int *> ptr2

CS1010 Lecture 7 p.12/31

More Pointer Assignments


ptr2 = ptr1;
Assign value of ptr1 to variable ptr2.
A pointer can be assigned to another
pointer of the same type, i.e. several
pointers can point to the same location.

Pointer Comparisons and NULL


Because different pointers can point to the
same variable, we use relational operators
== and != to compare pointers.
Other relational operators <, >, <=, >= more
relevant in the context of arrays.
A pointer can be assigned to or compared
with the constant NULL (which is the integer
zero) defined in <stdio.h>.

@300

<int *> ptr1 @100


@100

To zero a pointer, assign a NULL value to


indicate that the pointer has no address.

<int> count 1020


@400

ptr = NULL;

<int *> ptr2 @100


CS1010 Lecture 7 p.13/31

Pointer Assignment Errors


To illustrate some common errors that can be made
when working with pointers, assume
int y, *ptr1, *ptr2;

// or ptr = 0;
CS1010 Lecture 7 p.15/31

Pointers as Function Parameters


Recall the pass-by-value function mechanism
where copies of values are passed down from
the caller function to the callee function.
Pass-by-address-value involves function
arguments being first evaluated to address
values before passing to function parameters
(or more specially, pointer parameters).

Changing the address of an integer variable:


&y = ptr1;

Assigning pointer with a non-address value:

Nonetheless, it is still pass-by-value the


only argument passing mechanism.

ptr1 = y;
ptr1 = *ptr2;

Assigning an address to an integer variable:


y = ptr2;
*ptr1 = ptr2;
CS1010 Lecture 7 p.14/31

CS1010 Lecture 7 p.16/31

Swapping Revisited

Pointers as Function Parameters

Consider the following swap function.

cf . swap function with pointer parameters:


void swap(int *ptrX, int *ptrY)
{
int temp;

void swap(int x, int y)


{
int temp;

temp = *ptrX;
*ptrX = *ptrY;
*ptrY = temp;

temp = x;
x = y;
y = temp;
return;

return;

}
}

Pass-By-Value: calling swap(x,y) does not


swap values of x and y of the caller function.

If x and y are simple integer variables, then a


valid call to this function is swap(&x,&y);

CS1010 Lecture 7 p.17/31

Swapping Revisited
int main(void)
{
int x = 5, y = 2;
swap(x,y);

temp = x;
x = y;
y = temp;
return;

}
main
x

int main(void)
{
int x = 5, y = 2;
swap(&x,&y);
return 0;
}

}
main
x

swap(&x,&y);

void swap(int *ptrX,


int *ptrY)
{
int temp;
temp = *ptrX;
*ptrX = *ptrY;
*ptrY = temp;
return;
}
swap

swap

2
temp

swap(x,y);

Pointers as Function Parameters

void swap(int x, int y)


{
int temp;

return 0;

CS1010 Lecture 7 p.19/31


ptrX

ptrY

When an address is passed to a function, draw a reference from the function parameter to the specified location.
CS1010 Lecture 7 p.18/31

CS1010 Lecture 7 p.20/31

Pointers as Function Parameters


int main(void)
{
int x = 5, y = 2;
swap(&x,&y);
return 0;
}
main
x

void swap(int *ptrX,


int *ptrY)
{
int temp;
temp = *ptrX;
*ptrX = *ptrY;
*ptrY = temp;
return;
}
swap

swap(&x,&y);

ptrX
temp

Pointer Parameter as Function Output


With pointer parameters, one can use them to
return one or more values from a function.
Since these pointer parameters are used for
output from a function, they are termed output
parameters.
The function below finds the sum and product
of two arguments x and y.
void findSumProd(int x, int y,
int *sum, int *prod)
{
*sum = x + y;
*prod = x * y;
return;
}

ptrY
5

CS1010 Lecture 7 p.21/31

Pointers as Function Parameters


What happens in the following case?

CS1010 Lecture 7 p.23/31

Pointer Parameter as Function Output


The caller function calls findSumProd as
follows:

void swap(int *ptrX, int *ptrY)


{
int *temp;

int main(void)
{
int a, b, sum, prod;

temp = ptrX;
ptrX = ptrY;
ptrY = temp;

scanf("%d %d", &a, &b);


findSumProd(a,b,&sum,&prod);

return;

printf("The sum and product of ");


printf("%d and %d are %d and %d.\n",
a, b, sum, prod);

When using scanf, say scanf("%d", &x),


value read from the keyboard is stored at the
address specified by &x, the address of x.
CS1010 Lecture 7 p.22/31

return 0;
}

CS1010 Lecture 7 p.24/31

Address as Return Value

Pointers to Structures

Returning an address from a function is


possible but seldom useful apart from
function compositions.

Pointers variables can refer to structures.

Consider the example of finding which of two


variables a and b is bigger and making that
value twice as large.
Function findBigger takes two addresses of
variables as arguments, determines which variable
holds a larger value, and returns the address of this
variable.

struct Point
{
double x, y;
};

int main(void)
{
struct Point pt = {1,2},
*pPtr;
pPtr = &pt;
return 0;
}

pt

@500
1.0
2.0

@600

pPtr

@500

Function makeEvenBigger takes the above


address, finds the value, and multiples it by two.
CS1010 Lecture 7 p.25/31

Address as Return Value


int main(void)
{
int a, b;
scanf("%d %d", &a, &b);
makeEvenBigger(
findBigger(&a,&b));
return 0;
}

CS1010 Lecture 7 p.27/31

Structure Pointer Parameters

int *findBigger(int *a, int *b)


{
if (*a > *b)
return a;
else
return b;
}
void makeEvenBigger(int *c)
{
*c = *c * 2;
return;
}

To allow the callee function direct access to


the data members of the structure in the
caller, pass a pointer to the structure as
function argument.
void getPoint(struct Point *p)
{
double x, y;

Notice that functions need only communicate


the address values, and not the actual values.
Question to Ponder...
Suppose function f calls function g. Can we
return an address of a variable declared in
function g back to the caller function f ?
CS1010 Lecture 7 p.26/31

printf("Enter (x,y) values for point:\n");


scanf("%lf %lf", &x, &y);
(*p).x = x;
(*p).y = y;

// dereference then member access

// or.. scanf("%lf %lf", &((*p).x), &((*p).y));


}

Function call in main: getPoint(&pt);


CS1010 Lecture 7 p.28/31

Structure Pointer Parameters


As a shorthand to using (*p).x, the pointer
to structure member operator (->) can be
used instead, i.e. p->x.
void getPoint(struct Point *p)
{
double x, y;

Lecture Summary
If you are new to pointers, devise and use
memory addresses to assist in program
traces; then progress on to using arrows.
Ensure type-consistency when assigning
pointers.

printf("Enter (x,y) values for point: ");


scanf("%lf %lf", &(p->x), &(p->y));
}

Finding the midpoint of two points pt1 and


pt2 via output parameter midpt:

Addresses are passed to functions via


pass-by-address-value, i.e. a copy of the
address is passed to the pointer function
parameter.
Addresses and pointer dereferencing apply to
both primitive variables as well as to structure
variables.

void midPoint(struct Point *pt1,


struct Point *pt2,
struct Point *midpt);
CS1010 Lecture 7 p.29/31

Structure Pointer Parameters


int main(void)
{
struct Point pt1, pt2, midpt;
getPoint(&pt1);
getPoint(&pt2);
midPoint(&pt1,&pt2,&midpt);
printf("Midpoint: (%lf,%lf)\n", midpt.x, midpt.y);
return 0;
}
void midPoint(struct Point *pt1, struct Point *pt2,
struct Point *midpt)
{
midpt->x = (pt1->x + pt2->x) / 2;
midpt->y = (pt1->y + pt2->y) / 2;
return;
}
CS1010 Lecture 7 p.30/31

CS1010 Lecture 7 p.31/31

Das könnte Ihnen auch gefallen