Exercises

* Ex 7.1, 7.2(a,c,e,h), 7.3a.

Reading Assignment

* Ch 7.5 - end of chapter.

Assignment #3

* due Fri July 14 (but feel free to turn in on Wed or even earlier).

Introduction to Pointers

* Every memory cell in a computer's memory has two characteristics:

1. a value (or contents)

2. a unique address

* You have already seen this (in CSE 142):

int x;

* To access the value of x:

x

* To access the address of x:

&x

Pointer Variables

* A pointer variable is one that contains the address, not the value, of a data object.

* To declare a pointer variable:

<Type>* <Identifier>;

* Example:

int* p_int; // an integer pointer

char* name; // a name, i.e., a character pointer

Complex* p_comp;

* Be careful about this:

int* p, q; // p is a pointer, but q is an int!

* Equivalent to:

int *p;

int q;

* You can declare two pointers this way.

int *p, *q;

* But better declare each in a separate statement.

int *p; // describe what this variable is for

int *q; // ...

*p = 400; // Oh No!

The address-of operator

int x = 45;

int* p = &x;

The dereference operator

p = 30; // Oh No!

*p = 30;

// what is x now?

The NULL pointer

* During program execution, a pointer variable can be in one of the following states:

1. It is unassigned.

2. It points to some data object.

3. It contains the pointer constant 0.

* The pointer constant 0 is called the NULL pointer. The NULL pointer does NOT point to any object.

* Instead of using the constant 0, many feel it is better style to use a constant identifier:

#include <stddef.h>

...

if (some_pointer == NULL) { ... }

A definition of C++ Pointer Types

* Domain

* The set of all memory addresses along with the NULL pointer.

* Operations (pp.292-293)

* We will only cover these:

1. = (assign)

int *p = &q;

2. * (dereference)

*p = 345;

3. == (test for equality)

if (p == &q) { ...

}

4. ! = (test for inequality)

if (p != &q) { ...

}

5. ! (logical not)

if (!p) { // if (p == NULL)

}

6. [ ] (subscript)

p[0] = 678;

7. delete (deallocate from memory)

delete p; // will talk more later

8. -> (select a member of the class that is pointed to)

void multiply(Complex* p, Complex* q)

{

p->real * q->imag; // assume this is a friend

}

Constant Pointer Expressions

* Both the pointer and what it points to can be changed:

int * p;

p = &x; // change the pointer

*p = 10; // change what it points to

* The pointer cannot be changed while what it points to can be changed.

int * const p = q; // must be initialized

p = &x; // error

*p = 10; // okay

* The pointer can be changed while what it points to cannot be changed. (e.g. parameter passage)

const int * p = q;

p = &x; // okay

*p = 10; // error

* Neither the pointer nor what it points to can be changed.

const int * const p;

p = &x; // error

*p = 10; // error

Pointers and subscripts

char name[6] = "HELLO";

char* p = name;

char* q = &name[0];

cout << name[2];

cout << p[2];

cout << q[2];

Passing arrays as parameters

* as an array

int length(char name[]);

* as a pointer, you can still use the subscript operator.

int

length(const char* name)

{ if (name[0] == `\0') { return 0;

} else {

return 1 + length(&name[1]);

}

}

* The iterative version of this function is available from the text (p.298).

Reference Types

* In general,

<Type>& <Identifier>;

* Example:

int x;

int& ref = x; // a reference variable should always

// be initialized

x = 40;

cout << ref; // what is the output?

ref = 20;

cout << x; // what is the output?

Passing variables by reference (again!)

* Pass-by-value (using pointers)

void swap(int* p, int* q)

{

int x = *p;

*p = *q;

*q = x;

}

main()

{

int y = 10;

int z = 6;

swap(&y, &z);

cout << y;

cout << z;

}

* Pass-by-reference (using references)

void swap(int& a, int& b)

{

int x = a;

a = b;

b = x;

}

main()

{

int y = 10;

int z = 6;

swap(y, z);

cout << y;

cout << z;

}

* Cleaner code due to pass-by-reference!

The concept of dynamic data

* Static data - retains its value from call to call

void fun()

{

static int retained;

}

* Automatic data - implicitly allocated and deallocated

void fun()

{

int x;

// x is destroyed when function exists

}

* Dynamic data - the lifetime of a dynamic data is completely controlled during execution by means of special instructions. i.e., you do all the work!

Dynamic Data (new and delete operators)

* Allocation (the new operator)

* The expression "new <Type>" returns a pointer to an newly created object of type <Type>.

int* p = new int;

Complex *q = new Complex[5];

* Deallocation (the delete operator)

* "delete <Pointer>" deallocates the object pointed to by <Pointer>.

delete p;

delete [] q;

The Heap Space

* Objects created by "new" are said to be on the free store (or heap), a region of memory set aside for dynamic variables.

* The new operator obtains a chunk of memory from the heap; the delete operator returns it to the heap.

* A dynamic data object is unnamed and cannot be directly addressed.

* It must be indirectly addressed through the pointer returned by the new operator.