Presentation is loading. Please wait.

Presentation is loading. Please wait.

Pointers and References

Similar presentations


Presentation on theme: "Pointers and References"— Presentation transcript:

1 Pointers and References

2 Other C++ Features True reference parameters Readings: 3.3,

3 Outline Pointers in C Pointer parameters in swapping functions
bad and good and bad and good swaps True reference parameters how to define, how to call, how to use

4 Pointers in C and C++ One of the most confusing aspects of C and C++ can be the use of pointers. The & (address of), * (pointer to) and * (pointer dereference) operators are often difficult to decide on. In addition, when pointers are used as parameters for functions, the situation can get very complex.

5 Pointers in C (and C++) The most challenging aspect of pointer usage in C involves parameter passing. For example, how do you pass two pointers into a function and have it successfully swap the data pointed to by them?

6 A classic example: the swap function
A swap function, often used by sorting routines, is the classic example of a function that involves two pointers in an exchange of data. A common programming mistake in C is to deal with the pointers incorrectly.

7 A bad swap #1 void swap(int a, intb) { int temp; temp = a; a = b;
b = temp; } Compiles , runs, but... Even though it swaps the values in this function, when it is over the values in the main program have not changed. Why? The arguments were passed by value, not by address. int main() { int a, b; a = 5; b = 10; // print BEFORE... swap(a,b); // print BACK IN... BEFORE SWAP a is: 5, b is: 10 IN SWAP, READY TO RETURN a is: 10, b is: 5 BACK IN MAIN PROGRAM

8 What happened? Main program calls swap(a,b) Swap function
swap(int a, int b) a 5 5 b 10 10 When swap is called, copies of the data in a and b were passed in to it. The real variables a and b were left behind.

9 Bad swap: Establish local variables
Main program calls swap(a,b) Swap function swap(int a, int b) a 5 5 a 5 b 10 10 b 10 The values passed in are stored in temporary (local) variables. These vars might have the same name as variables in the main program but they are very different locations in memory.

10 Bad swap: Declare temp Main program calls swap(a,b) Swap function
swap(int a, int b) temp a 5 a 5 b 10 b 10 temp Now the swap takes place through the use of a new local variable called ‘temp’

11 Bad swap: Assign ‘a’ to ‘temp’
Main program calls swap(a,b) Swap function swap(int a, int b) temp a 5 a 5 b 10 temp = a; b 10 temp 5

12 Bad swap: Assign ‘b’ to ‘a’
Main program calls swap(a,b) Swap function swap(int a, int b) temp a 5 a 10 b 10 a = b; b 10 temp 5

13 Bad swap: Assign ‘temp’ to ‘b’
Main program calls swap(a,b) Swap function swap(int a, int b) temp a 5 a 10 b 5 b = temp; b 10 temp 5

14 Bad swap: Result of swap
Main program Swap function temp 5 a 5 a 10 b 10 b 5

15 Function ends: main program is unchanged
Swap function temp 5 a 5 a 10 b 10 b 5

16 Why? Main program Swap function temp a a b b 5 5 10 NOT RELATED 10 5
The problem is that data is ALWAYS passed into functions by value. That means it is never passed back because it only works on local copies!

17 Why is it set up like this?
If the changes made to variables in functions were allowed to effect main program variables by default, then programs could be very unstable. (global variables!) The effects of every variable assignment could ripple throughout the entire program. So, pass-by-value restricts the effects of changes made in functions.

18 So, what do we do? Values in the main program can be changed in functions, but we have to get tricky. Instead of passing them directly, we need to pass them indirectly. One method is to do it using pointers. Pointers are addresses of variables.

19 A good swap void swap(int* a, int*b) { int temp; temp = *a; *a = *b;
*b = temp; } This is the way to do it! Pass in the pointer, but use it to change the value stored in the memory cell it points to. int main() { int a, b; a = 5; b = 10; // print BEFORE... swap(&a,&b); // print BACK IN... BEFORE SWAP a is: 5, b is: 10 IN SWAP, READY TO RETURN a is: 10, b is: 5 BACK IN MAIN PROGRAM

20 Good swap: pass parameters
Main program calls swap(&a,&b) Swap function swap(int* a, int* b) 5 a 543785 543785 10 b 634428 634428 When swap is called, copies of the data in a and b were passed in to it. The real variables a and b were left behind.

21 Good swap: Establish local copies
Main program calls swap(&a,&b) Swap function swap(int* a, int* b) 5 a 543785 543785 a 543785 10 b b 634428 634428 634428 The values passed in are stored in temporary (local) variables.

22 Good swap: Declare temp
Main program calls swap(&a,&b) Swap function swap(int* a, int* b) 5 a 543785 a 543785 temp 10 b b 634428 634428 Now the swap takes place through the use of a new local variable called ‘temp’

23 Good swap: Assign value of ‘a’ to ‘temp’
Main program calls swap(&a,&b) Swap function swap(int* a, int* b) 5 a 543785 a 543785 temp = *a temp 5 10 b b 634428 634428

24 Good swap: Assign value of ‘b’ to be the value of ‘a’
Main program calls swap(&a,&b) Swap function swap(int* a, int* b) 10 a 543785 a 543785 *a = *b; temp 5 10 b b 634428 634428

25 Good swap: Assign ‘temp’ to be the value of ‘b’
Main program calls swap(&a,&b) Swap function swap(int* a, int* b) 10 a 543785 a 634428 temp 5 5 *b = temp; b b 634428 634428

26 Good swap: Function ends
Main program calls swap(&a,&b) Swap function swap(int* a, int* b) 10 a 543785 a 634428 temp 5 5 b b 634428 634428 When the function ends, it all passes out of scope BUT the changes to the main program have been made!

27 WARNING! HERE IS A COMMON ERROR!
Once you get used to using pointers it is easy to get yourself in trouble without realizing it. DO NOT try to swap values like this:

28 A bad swap #2 void swap(int* a, int*b) { int* temp; temp = a;
b = temp; } Compiles but produces runtime error. Segmentation fault because temp has not been allocated. int main() { int a, b; a = 5; b = 10; // print BEFORE... swap(&a,&b); // print BACK IN... BEFORE SWAP a is: 5, b is: 10 IN SWAP, READY TO RETURN a is: 10, b is: 5 BACK IN MAIN PROGRAM

29 A bad swap #3 void swap(int* a, int*b) { int* temp;
temp = (int*) malloc(sizeof(int)); temp = a; a = b; b = temp; } Compiles, runs, but... Fails to perform the swap. Why? It is working on a local copy of the arguments. When the function ends, these values for a and b pass out of scope and we return to the calling program unit, resuming the settings preserved there.

30 Bad swap: pass parameters
Main program calls swap(&a,&b) Swap function swap(int* a, int* b) 5 a 543785 543785 10 b 634428 634428 When swap is called, copies of the data in a and b were passed in to it. The real variables a and b were left behind.

31 Bad swap: Establish local copies
Main program calls swap(&a,&b) Swap function swap(int* a, int* b) 5 a 543785 543785 a 543785 10 b b 634428 634428 634428 The values passed in are stored in temporary (local) variables.

32 Bad swap: Declare temp Main program calls swap(&a,&b) Swap function
swap(int* a, int* b) 5 a 543785 a 543785 temp 000000 10 b b 634428 634428 Now the swap takes place through the use of a new local variable called ‘temp’

33 Bad swap: Assign value of ‘a’ to ‘temp’
Main program calls swap(&a,&b) Swap function swap(int* a, int* b) 5 a 543785 a 543785 temp 543785 temp = a; 10 b b 634428 634428

34 Bad swap: Assign value of ‘b’ to ‘a’
Main program calls swap(&a,&b) Swap function swap(int* a, int* b) 5 a 543785 a 634428 temp 543785 10 a = b; b b 634428 634428

35 Bad swap: Assign ‘temp’ to value of ‘b’
Main program calls swap(&a,&b) Swap function swap(int* a, int* b) 5 a 543785 a 634428 temp 543785 10 b b 634428 543785 b = temp;

36 Bad swap: Function ends
Main program calls swap(&a,&b) Swap function swap(int* a, int* b) 5 a 543785 a 634428 temp 543785 10 b b 634428 543785 The connections look good! But when the function ends, it all passes out of scope and is lost without affecting the main program!

37 Main program for swap A main program for swap would have to make sure that it is passing the proper parameters into the swap routine. But remember, ALL ARGUMENTS (EVEN POINTERS) ARE PASSED BY VALUE! This means a COPY of the argument is all the function ever sees.

38 A second good swap Another way to successfully pull off a swap is to use ‘double indirection’ Double indirection means a-pointer-to-a-pointer. Consider the following main program:

39 Double indirection main program
Int main() { int *a, *b, c, d; c = 5; d = 10; a = &c; b = &d; printf(“BEFORE SWAP\n”); printf(“a is: %d, b is: %d \n”, *a, *b); swap(&a, &b); printf(“AFTER SWAP\n”); return(0); }

40 A good swap void swap(int** a, int**b) { int* temp; temp = *a;
*a = *b; *b = temp; } This is a more complicated way to solve the problem. Pass in pointers to pointers, and use it to change the value stored in the memory cells pointed to.

41 Good swap: pass parameters
Main program calls swap(&a,&b) Swap function swap(int** a, int** b) &a 543785 543785 c a 5 745223 &b 634428 634428 d 10 When swap is called, copies of the data in a and b were passed in to it. The real variables a and b were left behind. b 845751

42 Good swap: Establish local variables
Main program calls swap(&a,&b) Swap function swap(int** a, int** b) &a 543785 543785 a 543785 c a 5 745223 &b b 634428 634428 634428 d 10 b 845751 The values passed in are stored in temporary (local) variables.

43 Good swap: Variable correspondence
Main program calls swap(&a,&b) Swap function swap(int** a, int** b) &a 543785 a 543785 c a 5 745223 &b b 634428 634428 d 10 b 845751 They are pointers to pointers used in the main program.

44 Good swap: Assign value of ‘a’ to ‘temp’
Main program calls swap(&a,&b) Swap function swap(int** a, int** b) &a 543785 a 543785 temp = *a; c a 5 temp 745223 745223 &b b 634428 634428 d 10 b 845751

45 Good swap: Assign value of ‘b’ to value of ‘a’
Main program calls swap(&a,&b) Swap function swap(int** a, int** b) &a *a = *b; 543785 a 543785 c a 5 temp 845751 745223 &b b 634428 634428 d 10 b 845751

46 Good swap: Assign temp to value of ‘b’
Main program calls swap(&a,&b) Swap function swap(int** a, int** b) &a 543785 a 543785 c a 5 temp 845751 745223 &b *b = temp; b 634428 634428 d 10 b 745223

47 Good swap: Function ends
Main program calls swap(&a,&b) Swap function swap(int** a, int** b) &a 543785 a 543785 c a 5 temp 845751 745223 &b *b = temp; b 634428 634428 d 10 b 745223 When the function ends, it all passes out of scope BUT the changes to the main program have been made!

48 Summary of C pointer passing
To change values in the main program you must pass pointers. Passing pointers alone is not enough to guarantee that your changes will go back to the main program. You must not work only on the local copies of the pointers

49 Moral To implement pass-by-address changes you must pass in pointers and then adopt one of these two strategies: change the values they point to, or change the values pointed to by pointers they point to.

50 C++ to the rescue C is unnecessarily complicated here.
C++ makes the situation a little easier by giving us a new tool: reference parameters. C++ does not change the fact that arguments are always passed by value, however, reference parameters make the syntax a little easier to swallow.

51 True Reference Parameters
C++ has another way of passing parameters -- true reference parameters A true reference parameter gives you a way to change a variable that is not part of a function without passing it as a pointer In a function definition you indicate a function parameter by putting an & after the type (no *) Type& Pname In a call to the function you give the name of the variable The parameter becomes another way to refer to the variable

52 A Simple True Reference Parameter
void updateInt(int& num) { // num becomes a synonym for the var // used in the function call num = num + 1; } int X = 5; updateInt(X); // num becomes name for X cout << X << endl; // Prints 6

53 Reference to a Pointer Reference parameters are useful for changing pointer vars (so you don’t have to pass a pointer to a pointer) Put & after * with type Example: void InitList(LLStruct*& start) { start = 0; } LLStruct *ListStart; InitList(ListStart);

54 Reference to a Structure
Can also pass a reference to a structure: struct TIME { // more on this later int hours, minutes, seconds; }; void springForward(TIME& thetime) { thetime.hours += 1; } TIME currtime = {0, 0, 0}; springForward(currtime);

55 Guidelines? Now that we have & (reference) and & (address-of) and * (pointer to) and * (dereference) things can get out of control unless you remember the rules. For those who cannot remember when to use each of these when passing parameters into functions I offer the following table:

56 When to use what: for the swap function
Pointer references in the function call & swap(&a,&b) * swap(aptr,bptr) None swap(a,b) NO SWAP NO SWAP None (int a, int b) INVALID Arguments in the function header & (int& a, int& b) INVALID INVALID YES! * (int* a, int* b) INVALID YES! YES! (see earlier C examples) *& (int*& a, int*& b) YES! INVALID INVALID


Download ppt "Pointers and References"

Similar presentations


Ads by Google