Download presentation
Presentation is loading. Please wait.
Published byPaul Hood Modified over 9 years ago
1
Pointers & References
2
Pointers Pointer arithmetic Pointers and arrays Pointer-related typedef’s Pointers and const References
3
Pointer Declarations Use an asterisk (*) int* p; –Read “p is a pointer to an int” Must always indicate type pointed to –No such thing as “just a pointer” –Pseudo-exception: void * (will see shortly) The only thing you can do with a void* is hold it Must cast to a concrete type to dereference it
4
Pointers to Pointers Occasionally use 2 levels Given int ** p; **p is an int => *p is a pointer to an int => p is a pointer to a pointer to an int
5
// ptr2ptr.cpp: Pointers to pointers #include using namespace std; int main() { int i = 7; int* ip = &i; int** ipp = &ip; cout << "Address " << ip << " contains " << *ip << endl; cout << "Address " << ipp << " contains " << *ipp << endl; cout << "**ipp == " << **ipp << endl; } // Output: Address 0012ff88 contains 7 Address 0012ff84 contains 0012ff88 **ipp == 7
6
Pointer Addition Add an integer to a pointer Moves the pointer up (if +) or back (if -) in memory that many objects – i.e., p+n increases address by n*sizeof(*p) Can only be used within an array –Except you can move one past the end –But you can’t dereference there
7
Pointer Subtraction Yields number of objects between two objects pointed to Could be negative Special type to hold result (ptrdiff_t) –Usually a typedef for long
8
About typedef “Type definition” Creates synonyms for existing types –For convenience and portability –Used heavily in STL typedef char myChar; typedef unsigned int wchar_t; typedef long ptrdiff_t; typedef unsigned long size_t; typedef int A5[5]; –A5 a; // Same as int a[5]
9
#include using namespace std; int main() { float a[] = {1.0, 2.0, 3.0}; // Increment a pointer: cout << "sizeof(float) == " << sizeof(float) << endl; float* p = &a[0];// or just a; cout << "p == " << p << ", *p == " << *p << endl; ++p; cout << "p == " << p << ", *p == " << *p << endl; // Subtract two pointers: ptrdiff_t diff = (p+1) - p; cout << "diff == " << diff << endl; diff = static_cast (p+1) – static_cast (p); cout << "diff == " << diff << endl; } /* Output: sizeof(float) == 4 p == 0012ff80, *p == 1 p == 0012ff84, *p == 2 diff == 1 diff == 4 */
10
Pointers and const Two degrees of freedom –Is the pointer itself const? –Or is the thing pointed to const? Usually the latter case (pointer-to-const) All depends on where you put the const –Relative to the asterisk Used extensively throughout the C library
11
Pointers and const const before the asterisk means that the contents is const const after the asterisk means that the pointer is const const char* p1; // *p1 = 'c' illegal; ++p1 OK char* const p2; // *p2 = 'c' OK; ++p2 illegal const char* const p3; // no changes at all allowed
12
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 Used often as function parameters Useful for: –treating any object as a sequence of bytes –implementing generic containers
13
void* memcpy(void* target, const void* source, size_t n) { // Copy any object to another char* targetp = static_cast (target); const char* sourcep = static_cast (source); while (n--) *targetp++ = *sourcep++; return target; } int main() { float x = 1.0, y = 2.0; memcpy(&x, &y, sizeof x);// same as x = y cout << x << endl; } 2
14
Incomplete Types Sometimes it is necessary to introduce a pointer to a type that hasn’t yet been fully defined –These are called incomplete types For example, the mutual reference problem: class A; class B {A* a; …}; class A {B* b; …}; Another example: pImpl idiom
15
Pointers and Arrays The name of an array becomes a pointer to its 1st element –Except as an operand to sizeof In other words: a is the same as &a[0] In other words: *a == a[0] More generally: a + i == &a[i] Or: *(a + i) == a[i]
16
Multi-dimensional Arrays Don’t really exist! “Arrays of arrays” instead int a[2][3] –an array of 2 elements –each element is an arrays of 3 ints –what is sizeof(a[0])?
17
Question How do you declare a pointer for the following: ??? = new int[2][3];
18
Partial Answer All arrays are considered 1-dimensional The expression new int[2][3] creates an array of two elements It returns a pointer to the first element We must have the condition: –sizeof(*p) == 3 * sizeof(int) So p must point to something with size 12! –(on a 32-bit machine, of course)
19
Higher and Deeper Repeat the process on the 3-d array: int a[2][3][4];
20
How does istream::get work? char c; cin.get(c);// reads next input byte into c cout << c;// prints the byte read as a char
21
References An alias for another memory location Can be function parameters –Implements “call by reference” –Implicit pointer indirection Does not exist in Java Can also be local –Merely another name for an existing variable Can be return values –Often used by operator[ ] –Appears throughout STL
22
References are Aliases #include int main() { using namespace std; int i = 7; int& r = i; ++r; cout << i << endl;// 8 }
23
Reference Parameters #include using namespace std; void swap(int& x, int& y) { int temp = x; x = y; y = temp; } int main() { int i = 1, j = 2; swap(i,j); cout << "i == " << i << ", j == " << j; } /* Output: i == 2, j == 1 */
24
Reference Returns #include int a[4] = {0,1,2,3}; int index = 0; int& current()// Returns a reference { return a[index]; } int main() { using namespace std; current() = 10; // replace a[0] index = 3; current() = 20; // replace a[3] for (int i = 0; i < 4; ++i) cout << a[i]; cout << endl; } /* Output: 10 1 2 20 */
25
const Reference Parameters When you won’t be changing the value The “best of both worlds” –Efficiency of call-by-reference –Safety of call-by-value Because calling argument is protected from change (Almost) Always pass objects by (const) reference
26
An Employee Class class Employee { string name; double rate; double timeWorked; public: Employee(const string& ename, double erate) : name(ename) { rate = erate; } string getName() const {return name;} double getRate() const {return rate;} double getTimeWorked() const {return timeWorked;} void recordTime(double etime) {timeWorked = etime;} double computePay() const; };
27
double Employee::computePay() const { const double& hours = timeWorked; if (hours > 40) return 40*rate + (hours - 40)*rate*1.5; else return rate * hours; } int main() { using namespace std; Employee e("John Hourly",16.50); e.recordTime(52.0); cout << e.getName() << " gets ” << e.computePay() << endl; } John Hourly gets 957.00
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.