Date post: | 04-Jan-2016 |
Category: |
Documents |
Upload: | cameron-horton |
View: | 213 times |
Download: | 0 times |
Pointers
What is pointer Everything stored in a computer program
has a memory address. This is especially true of variables.
char c=‘y’;
int i=2; According to the information to the right,
the address of variable i is 0020 The memory address can be used to
reference a variable, addresses can be stored in a variable of a
special type called a pointer (variable) The variable ptr as shown on the right is a
pointer variable to the int variable i So, a pointer is just a reference to
something; it’s content is an address;
name memory address
i‘y’c2
0019 0020
name memory address
i‘y’c2
0019 0020
0020ptr
Declaring a Pointer A Pointer variable is declared as follows:
data_type *pointer_name; Examples:
double *p;int *ptr;int* q;
Be careful, int* x, y; declares x as a pointer to an integer while y is just a regular int.
Note the memory/storage associated with what ptr is pointing to is NOT allocated/created just by the defining of ptr, i.e., int *ptr; this does not allocate any memory for ptr to point to
A variable can be a pointer to any data type including another pointer:char **p; or even char ***p;
An example that we have already used for a pointer to a pointer is when talking about command line arguments --- arguments to the main program is : char *argv[];
Declaring a Pointer Used in conjunction with the concept of a pointer is the address
operator: & The address operator when applied returns the memory address of its
operand. Example: int *p; int x=7; p = &x; Another operator used in conjunction with the concept of a pointer
dereferencing operator: * The dereferencing operator returns the contents of the memory
referenced by the operand. Example with the above assignment of p=&x; then cout << *p; would print the value 7
Finding the address of a memory location/variable
The address of a variable can be found by using the address operator &
For example, if one has char c;int x;int *p;Then cout << &c << endl; // will print 19 whilecout << &x << endl; // will print 20cout << p << endl; // on most systems prints 0cout << *p << endl; // will cause an errorWhen printing p, if p has the value of 0, then *p is
generally a reference to memory outside the bounds of the program.
name memory address
x‘y’c2
0019 0020
Finding the address of a memory location/variable
If one initializes p to a value such as p = &x;
Then cout << p << endl; // produces 20cout << *p << endl; // produces 14cout << x << endl; // produces 14
The use of * in the above is a dereferencing of p, i.e, * used in the context is a dereferencing operator.
name memory address
x‘y’c14
0019 0020
0020p
Dereferencing a location/variable
If one initializes p to a value such as p = &x;
Then *p is a reference to the x
If we,p = &x;*p = 47;
Thencout << p << endl; // produces 20cout << *p << endl; // produces 47cout << x << endl; // produces 47
name memory address
x‘y’c47
0019 0020
0020p
Don’t be confused by pointers…
Pointer variable, p does not hold the value of x Its value is an address points to the memory location
of x is a variable itself has its own memory location
(1002300)
Pointer Constants
x
p
1048575
1048574
1048573
000000
000001
00004000
To004003
00 11 00
4 0 0 0 1002300
int x;
int *p;
x = 10;
P = &x;
Using pointers note that star (*) at declaration is not a dereference operator - it just
signifies that the variable is a pointer.
A pointer can be assigned a value at declaration
int x;
int *ip=&x; multiple pointer variables can point to the same variable
int a;
int *p, *q, *r;
P = q = r = &a;
Multiple Pointers to One Variable
int a, *p, *q, *r;p = &a;q = &a;r = q;
Using pointersWhat does this piece of code do? DRAW a picture!!!
int *p1, *p2, one=1, two=2;
p1 = &one;
p2 = p1;
*p1 = *p1 + 1;
p1 = &two;
*p1 -= 1;
cout << *p2 << “ “ << *p1 << endl;
Bad Pointers A pointer that is not initialized holds an arbitrary value. Hence
any reference via the pointer may cause a run time error. This is referred to as a dangling reference.
Assigning a value to the location where an uninitialized pointer points to can lead to unpredictable results:
int *ptr;
*ptr = 5; // ERROR – dangling reference NULL is a constant that is assigned to a pointer that does not
have a value
int *ptr = NULL; //this assigns ptr not *ptr assigning NULL to pointer does not eliminate the dangling
reference problem but it is a convenient constant to compare to
int *ptr = NULL, x=5;
// ERROR *ptr2 = 5;
if (ptr == NULL) ptr = &x;
cout << *ptr; // prints 5
Always Initialize Pointer Variables
Array names and constant pointers Array name is in fact a constant pointer A constant pointer is a pointer object where we cannot change the
location to which the pointer points We can however change the value pointed to by the pointer Confused? Example
int *p; // this is a pointerint x[3]; // this is an arrayp = x; // p references first
// element of an array
*p = 112; // changes the 107 to 112
p = p + 1; // assigns 20 to p
*p = 102; // changes the 14 to 102
x = p; // is illegal, you cannot change the address of an array. Array names are constants.
name memory address
0016p
107x14
0016 0020
71 0024
Array names are constant an array name can be used as name and as a (constant) pointer:
x[2]=22; // as name*x=22; // as pointer
a pointer can also be used similarlyp[2]=44; // as name*(p+2)=10; // as pointer
since array name is a constant pointer - it’s modification is not legalx = p; // ERROR!P = x; // Is legal and ok
Pointers and Arrays For an array declared in the following way:
int x[200]; The array’s name becomes a pointer to its 1st
element except when the array name is used as an operand to sizeof
That is: x is the same as &x[0] *x == x[0]
More generally: x + i == &x[i] *(x + i) == x[i]
Pointer Arithmetic
Addition and subtraction of pointers is ok Pointer + number Pointer - Pointer
Can be used to traverse through memory A substitute for array subscript notation.
Pointer Addition Adds an integer to a pointer Moves the pointer
Forward (if positive), backward (if negative) Moves in memory by that many objects
–Not bytes! I.e., p+n increases address by n*sizeof(*p)
Must only be used within an array! Except you may move one past the end But you must not dereference there!
Pointer Subtraction
Yields number of objects between the two objects pointed to.
Result can be negative. Special type to hold result …usually a typedef for long.
Pointer Arithmetic Given a pointer p, p+n refers to the element
that is offset from p by n positions.
Pointer Arithmetic & Different Data Types
address = pointer + (offset * size of element)
c
c+1
c+2
/* arith.cpp: Illustrates pointer arithmetic */#include <iostream>using namespace std; int main(){ float a[] = {1.0, 2.0, 3.0}; cout << "sizeof(float) == " << sizeof(float) << endl;
// Increment a pointer: float* p = &a[0];// or just a; cout << "p == " << p << ", *p == " << *p << endl; ++p; cout << "p == " << p << ", *p == " << *p << endl; // Subtract two pointers: float* diff = (p+1) - p; cout << "diff == " << diff << endl; diff = (char *)(p+1) - (char *)p; cout << "diff == " << diff << endl;}
/* Output:sizeof(float) == 4p == 0012ff80, *p == 1p == 0012ff84, *p == 2diff == 1diff == 4 */
Pointer Arithmetic Example
*(a+n) is identical to a[n]
Dereferencing Array Pointers
Multi-dimensional Arrays
Muti-dimensional arrays are actually arrays of arrays int a[2][3];
a is an array of 2 elements Each of the two elements is an array of 3 integers
What is sizeof(a[0])?
12, assuming 32-bit integers
Draw picture….
Pointer to 2-Dimensional Arrays
What is **table?
table[i][j]
Pointers to objects Pointers can point to objects:
class MyClass{
public:
void setD(int i){d=i;};
int getD() const {return d;};
private:
int d;
};
MyClass object, *objptr=&object; members can be accessed using pointers:
(*objptr).setD(5); parentheses around (*objptr) are needed because the dot-operator
has a higher priority than the dereferencing operator a shorthand -> is used for accessing members of the object the pointer
points to:
cout << objptr->getD();
Exercise 1
100100…… …… …… ……Memory address:
1024
int a = 100;
int *b = &a;
cout << a;
cout << &a;
cout << b;
cout << *b;
cout << &b;
……1020
a
1028
What is the output of the following program ?
Exercise 2
What is the output of the following program ?
int a = 100, b = 88, c = 8;
int *p1 = &a, *p2, *p3 = &c;
p2 = &b; // p2 points to b
p2 = p1; // p2 points to a
b = *p3; //assign c to b
*p2 = *p3;//assign c to a
cout << a << b << c;
Exercise 3
What is the output of the following program ?
int a = 3;char s = 'z';double d = 1.03;int *pa = &a;char *ps = &s;double *pd = &d;cout << sizeof(pa) << sizeof(*pa) << sizeof(&pa) << endl;cout << sizeof(ps) << sizeof(*ps) << sizeof(&ps) << endl;cout << sizeof(pd) << sizeof(*pd)
<< sizeof(&pd) << endl;
Generic Pointers
void* Allows holding a pointer to any type
Can store any pointer in a void* Must explicitly cast back to original type to
use it Used often as function parameters Useful for:
Treating any object as a sequence of bytes Implementing generic containers
Pointer Indirection (Pointers to Pointers)
What is
a? &a? *a?
p? &p? *p? **p?
q? &q? *q? **q?58
Pointers Indirection
How to access a from p? *p How to access a from q? **q How to access a from r? ***r
58
Pointer Types Must Match
Array of Pointers & Pointer to Array
int *aryOfPtrs[5]; // array of 5 pointers to integer
int table [5];int * ptrToAry = table;
Lvalue vs Rvalue
A C++ expression is either an rvalue or lvalue. An rvalue expression appears at the right of an
assignment. It refers to a value that is to be assigned to a memory cell, i.e. can be used to supply a value for further use, e.g. examine or copy the value. Examples: x= 5; y= a+2; z=a*6; x=a[2]+3; i=i++;
A lvalue expression appears at the left of an assignment. It identifies a memory cell that is going to receive an rvalue, i.e. the memory cell is being modified. Example: a = … a[5] = … (a) = … *p =
…
Exercise 4
Given the following lines of codes,
int ival = 1024;
int ival2 = 2048;
int* pi1 = &ival;
int* pi2 = &ival2;
int** pi3 = 0; Are the following statements legal or illegal?
1. (1) pi2 = *pi1;
2. (2) ival = pi1;
3. (3) pi3 = &pi2;
Exercise 5: what is wrong?
int a = 58;int *p = &a;int **q = &p;int ***r = &q;int ****s = &r;
q = &a;s = &q;
Exercise 5: what is the output?
#include <iostream>using namespace std;int main(){
int a[5] = {2,4,6,8,22};int *p = &a[1];cout << a[0] << " " << p[-1];cout << a[1] << " " << p[0];cout << a[2] << *(p+2);
cout << (a[4] = = *(p+3)); return 0;}