1 Pointers & functions Pointers allow us to simulate pass by reference. void swap(int &a, int &b) { int temp = a; a = b; b = temp; } int main () { int x = 3, y = 5; swap(x,y); return 0; } void swap(int *a, int *b) { int temp =* a; *a = *b; *b = temp; } int main () { int x = 3, y = 5; swap(&x, &y); return 0; }
2 Pointers & functions Function arguments that are pointers copy an address to the formal parameters Dereferencing the formal parameter lets us modify the value pointed to by the pointer. But changing the pointer itself NEVER changes the actual parameter Example 1: int main () { int x, *px; px = &x; initialize(px); return 0; } void initialize (int *ptr) { *ptr = 34; } here x has become 34
3 Pointers & functions Function arguments that are pointers copy an address to the formal parameters Dereferencing the formal parameter lets us modify the value pointed to by the pointer. But changing the pointer itself NEVER changes the actual parameter Example 2: int main () { int x, *px; px = &x; initialize(px); return 0; } void initialize (int *ptr) { *ptr = 34; ptr++; } here x has become 34 but px is unchanged. ptr goes out of scope when we exit the function
4 Pointers & functions Be very careful with functions that return pointers. Make certain that the pointer points to something valid on return and that space has been properly allocated. Example: int * func () { int x, *p; x = 10; p = &x; return p; } int main () { int *ptr ; ptr = func(); cout << *ptr << endl; return 0; } This program will print out garbage. Why? p and x are local variables, statically stored in func()'s stack frame. They "disappear" on exit from func(), so *ptr cannot contain the value of x.
5 More on pass by reference When an argument is passed by value, enough memory must be allocated for a copy of that argument. This may slow down our program if the argument is a large object. The solution is to pass it by reference. HOWEVER, we may not want to allow the function to modify the value of the argument. In that case, we must use the keyword const to specify that the argument cannot be changed. This is called a const reference
6 Examples Example 1: class bigTypeT {... }; void func (const bigTypeT &arg) { // arg cannot be modified in here } int main () { bigTypeT arg; func(arg); return 0; }
7 Examples Example 2: void func (const int arr[ ]) { // arr cannot be modified here } int main () { int arr[10]; func(arr); return 0; }
8 Examples Example 3: void func (const int *ptr) { // *ptr cannot be modified // ptr can be modified but this will have no effect in main() // since ptr is local to func() } int main () { int *pnum, x; pnum = &x; func(pnum); return 0; }
9 Examples Example 4: class Ship {... } int main () { Ship *fleet[10]; // an array of pointers to Ship objects for (int i=0; i<10; i++) { fleet[i] = new Ship; } return 0; }
10 Examples Example 5: typedef enum {FRIGATE, DESTROYER, CRUISER} USshipT; class Ship { public: USshipT type;... } int main () { Ship *boat; // an array of pointers to Ship objects boat = new Ship; (*boat).type = FRIGATE; boat -> type = FRIGATE; return 0; } these statements are exactly the same. The -> operator is shorthand for *.