Presentation is loading. Please wait.

Presentation is loading. Please wait.

(Walls & Mirrors - Beginning of Chapter 4)

Similar presentations


Presentation on theme: "(Walls & Mirrors - Beginning of Chapter 4)"— Presentation transcript:

1 (Walls & Mirrors - Beginning of Chapter 4)
Pointers (Walls & Mirrors - Beginning of Chapter 4)

2 What’s a Pointer? A pointer variable is a variable that can contain the location of another variable as its value. The location of a variable is usually implemented by indicating its address in (RAM) memory. The location (or address) of a variable is called a pointer. Sometimes, for brevity, a pointer variable is simply called a pointer. You will need to be careful to understand whether pointer refers to a variable or the address of a variable.

3 Pointers -“Real Life” Examples
Suppose that your friend, Sam, borrows your copy of Walls & Mirrors. In its place, he leaves you the note Borrowed your Walls & Mirrors book. Thanks, Sam This note is like a pointer, since it it not your book, but it tells you where to go to find it. (The paper on which the note is written is like a pointer variable.)

4 Pointers - Graphical Representation
A variable is often represented as a box. The value of the variable is written inside the box. If the variable is a pointer variable, containing a pointer, the box will contain the “tail” of an arrow that points to another variable. Pointer variable Other variable

5 Pointers - Suggestion If you have a problem with pointers, draw the layout. It may be difficult to understand what is going on without a graphical representation of the pointer relationships.

6 Pointer Declarations int *iptr; // iptr is a pointer to an int
char *cptr; // cptr is a pointer to a char float *fptr; // fptr is a pointer to a float List *Lptr; // Lptr is a pointer to a List object Sphere *Sptr; // Sptr is a pointer to a Sphere object

7 Pointer Operations Assignment: =
A pointer variable can be assigned only a pointer (i.e. the address of a variable) or NULL (which equals 0). Comparison: = =, != Pointers can be compared for equality. Addition/Subtraction: +,  Pointers can be incremented or decremented with an integer. Dereferencing: * *ptr returns the value of the object pointed to by ptr. Address of: & &ptr returns the address of ptr (i.e. pointer to ptr).

8 Pointer Operations - Address of
The Address of operator & returns the address of an object. float PI = ; float *PIptr; &PI returns the address of the variable PI, not (the value stored in PI). PIptr = &PI stores the address of variable PI in variable, PIptr. &PIptr returns the address of variable PIptr.

9 Pointer Operations - Dereferencing
The Dereferencing operator * returns the value of the object to which its operand points. float PI = ; float *PIptr; float X; PIptr = Π // PIptr contains the address of PI X = *PIptr; // Value stored in PI ( ) is // assigned to X *(*(&PIptr)) = *PIptr = *(&PI) = PI =

10 Pointer Initialization
int *ptr; // pointer to int declared, value undefined int x = 5; // int declared and initialized to 5 cout << x; // prints 5 cout << *ptr; // Error! Prints undefined value, since ptr not // initialized ptr = &x; // ptr now contains the address of x cout << *ptr; // prints 5

11 Pointer Initialization - Suggestion
When a pointer variable is declared it is (by default) uninitialized. Therefore, where it is pointing is undefined. It’s a good practice to initialize newly declared pointer variables to the NULL pointer (= 0). This will insure that the pointer variable is not pointing anywhere it shouldn’t. This will help you determine if a valid pointer has been assigned to it. if( ptr = = NULL ) cout << “ptr has not been initialized” << endl;

12 new Operator The operator new creates a new object of a given type.
new returns a pointer to the newly created object. ptr = new int; ptr new int variable

13 new Operator (Cont’d.) An object created with new does not have a name and is not declared. An object created with new can only be used by following (dereferencing) a pointer to it. You need to be careful to not lose the pointer to an object created with new, since there is no other way to access it. Memory that was allocated with new and has become inaccessible is called a memory leak. For programs that run for long periods of time, memory leaks can be the reason for system failure.

14 new Operator - Example 1 int *ptr; // pointer to int declared, value undefined *ptr = 5; // Error! ptr contains invalid address and // space for int not allocated ptr = new int; // space for int allocated and pointer to it // assigned to ptr *ptr = 5; // 5 is stored in the int pointed to by ptr

15 new Operator - Example 2 int *p, *q; // declare two pointer to int variables p = new int; // allocate space for an int; make p point to it *p = 25; // store 25 in the int pointed to by p What is the effect of the following? q = p;

16 new Operator - Example 2 (Cont’d.)
Draw a picture! p q new int 25

17 new Operator - Example 3 int *p, *q; // declare two pointer to int variables p = new int; // allocate space for an int; make p point to it q = new int; // allocate space for an int; make q point to it *p = 35; // store 35 in the int pointed to by p What is the effect of the following? *q = *p;

18 new Operator - Example 3 (Cont’d.)
Draw a picture! p new int 35 q

19 new Operator - Example 3 (Cont’d.)
What would have happened if we had executed q = p; instead of *q = *p;

20 new Operator - Example 3 (Cont’d.)
new int 35 ? q The new int, previously pointed to by q is LOST and cannot be recovered. This is called a memory leak.

21 Arrays and Pointers int a[50]; int *aptr = a; a is equivalent to &a[0]
aptr = a; is equivalent to aptr = &a[0]; aptr+5 is equivalent to &a[5] *(aptr+5) is equivalent to a[5]

22 (Walls & Mirrors - Chapter 4)
Linked Lists (Walls & Mirrors - Chapter 4)

23 Overview Insert into a Sorted, Linked List
Displaying the Data in a Linked List Delete from a Sorted, Linked List Copy Constructor Saving a Linked List to a File Circular Linked Lists Dummy-Headed Linked Lists Doubly Linked Lists

24 Definitions Recall, a list is an ordered collection of elements.
A linked-list is a list in which each element (or node) contains a link (or pointer) to the next element in the list.

25 Insert into a Sorted, Linked List
Steps: 1) Determine where to insert. 2) Create a new node and store the new data in it. 3) Connect the new node into the linked list.

26 Determine Where to Insert
Suppose that we would like to insert 50 into the following, sorted linked list. newValue 50 12 27 38 head 53 NULL

27 Determine Where to Insert (Cont’d.)
struct ListNode { int value; ListNode *next; }; ListNode *head; // assume that a sorted, linked list of // ListNodes has been created ListNode *cur = head; while( newValue > cur -> value ) cur = cur -> next; newValue 50 head 12 27 38 53 cur

28 Determine Where to Insert (Cont’d.)
Searching through the list ends in this configuration. Problem: We can’t insert unless we have a pointer to the node before the position we want to insert. newValue 50 head 12 27 38 53 cur

29 Determine Where to Insert (Cont’d.)
ListNode *prev = NULL; ListNode *cur = head; while( newValue > cur -> value ) { prev = cur; cur = cur -> next; } newValue 50 head 12 27 38 53 prev cur

30 Determine Where to Insert (Cont’d.)
Problem: If newValue is greater than all the values in the list, then when we get to the last ListNode cur = cur -> next will assign NULL to cur. The subsequent cur -> value will cause program termination, due to an illegal reference.

31 Determine Where to Insert (Cont’d.)
ListNode *prev = NULL; ListNode *cur = head; while( (cur != NULL) && (newValue > cur -> value) ) { prev = cur; cur = cur -> next; } We now have a piece of code that will set prev to the place in the linked list where newValue should be inserted.

32 Create a New Node & Store the Data
Recall that the nodes in our list have been declared as struct ListNode { int value; ListNode *next; }; Consequently, we can create and initialize a new node as follows: ListNode *newNode; newNode = new ListNode; newNode -> value = newValue; newNode -> next = NULL;

33 Connect the New Node Into the List
newValue 50 head 12 27 38 53 prev newNode cur This is achieved by newNode -> next = cur; prev -> next = newNode; What happens if we try to insert at the end of the list?

34 Insert at the End of the List
newNode -> next = cur; prev -> next = newNode; What if we try to insert at the beginning of the list? newValue 60 head 12 27 53 prev cur newNode 38

35 Insert at the Beginning of the List
newNode -> next = cur; prev -> next = newNode; Since prev = NULL, prev -> next is an illegal reference! prev newValue 4 12 27 53 38 newNode head cur

36 Insert at the Beginning of the List (Cont’d.)
if( prev != NULL ) { newNode -> next = cur; prev -> next = newNode; } else { newNode -> next = head; head = newNode; } prev newValue 4 12 27 53 38 newNode cur head

37 Insert into an Empty List
What happens if the list is empty to begin with? if( head = = NULL ) { head = new ListNode; head -> value = newValue; head -> next = NULL; }

38 Insert: Putting it All Together
if( head = = NULL ) { head = new ListNode; head -> value = newValue; head -> next = NULL; } else // search for place to insert { ListNode *prev = NULL; ListNode *cur = head; while( (cur != NULL) && (newValue > cur -> value) ) { prev = cur; cur = cur -> next; } // create a new node ListNode *newNode; newNode = new ListNode; newNode -> value = newValue; // connect it into the list if( prev != NULL ) { newNode -> next = cur; prev -> next = newNode; } else { newNode -> next = head; head = newNode; } }

39 ADT SortedList Operation
How do we turn this code into an operation on an ADT SortedList ? First, define the public, member-function declaration: void insert( ItemType newValue, bool &success ); should insert newValue into a SortedList at the proper place. Success is true if insertion is successful, otherwise false. Next, modify the preceding code to set success appropriately handle duplicates appropriately Finally, include the member-function declaration and definition in the following:

40 Class Definition for the ADT SortedList
typedef int ItemType; // items in SortedList are int’s class SortedList { public: // declarations of public member functions private: struct ListNode ItemType value; ListNode *next; }; ListNode *head;

41 Displaying the SortedList Data
void SortedList::print( ) { for( ListNode *cur = head; cur != NULL; cur = cur -> next ) cout << cur -> value << endl; }

42 Delete from a Sorted, Linked List
Steps: 1) Locate the node to be deleted. 2) Disconnect the node from the linked list. 3) Make the node available for reuse.

43 Locate the Node to be Deleted
Suppose that we would like to delete the node containing 38 from the following, sorted linked list. 12 27 38 53 head targetValue 38

44 Locate the Node to be Deleted (Cont’d.)
ListNode *prev = NULL; ListNode *cur = head; while( (cur != NULL) && (targetValue != cur -> value) ) { prev = cur; cur = cur -> next; } What is the value of prev if targetValue is at the head of the list? What is the value of cur if targetValue is not found? targetValue 38 head 12 27 53 prev cur

45 Disconnect the Node from the List
if( cur != NULL ) { if( prev != NULL ) prev -> next = cur -> next; else head = cur -> next; cur -> next = NULL; } targetValue 38 head 12 53 prev cur 27 Note: cur points to the node that was disconnected from the list.

46 Make the Node Available for Reuse
delete cur; // de-allocates the node pointed to by cur, not cur cur = NULL; Although the node pointed to by cur has been returned to the system for reuse, it’s a good idea to set its next pointer and cur to NULL, so that at next use, they are not unintentionally pointing to a valid node. targetValue 38 head 12 53 prev 27 cur

47 ADT SortedList Operation
How do we turn the preceding code into an operation on an ADT SortedList ? First, provide the public, member-function declaration: void remove( ItemType targetValue, bool &success ); should remove targetValue from a SortedList. Success is true if insertion is successful, otherwise false. (Note: since delete is a reserved word, we call this function remove.) Next, modify the preceding code to set success appropriately. Finally, include the member-function declaration for remove( ) in the SortedList class declaration, followed by it’s definition.

48 SortedList Constructor & Destructor
SortedList::SortedList( ) : head( NULL ) { } // default constructor SortedList::~SortedList( ) // de-allocate all the nodes { // in the SortedList while( head != NULL ) { ListNode *cur; cur = head -> next; delete head; // de-allocates the node pointed to by head head = cur; }

49 SortedList Copy Constructor
Whenever a C++ program passes an ADT to a function by value, returns an ADT as the value of a function, or uses an ADT to initialize an object, a copy constructor is invoked implicitly to make a new copy of the ADT. If you don’t provide one, the compiler will generate a copy constructor that copies only the data members of the ADT, instead of the complete structure of the ADT (shallow copy).

50 SortedList Copy Constructor (Cont’d.)
if( oSortedList.head = = NULL ) head = NULL; else { head = new ListNode; head -> value = oSortedList.head -> value; ListNode *pnew = head; ListNode *porig = oSortedList.head -> next; 53 oSortedList.head 12 head pnew 27 38 porig

51 SortedList Copy Constructor (Cont’d.)
while( *porig != NULL) { pnew -> next = new ListNode; pnew = pnew -> next; pnew -> value = porig -> value; porig = porig -> next; } pnew -> next = NULL; oSortedList.head 12 27 38 53 12 27 head pnew porig

52 Copy Constructor: Putting it All Together
SortedList::SortedList( const SortedList &oSortedList ) { if( oSortedList.head = = NULL ) head = NULL; else head = new ListNode; head -> value = oSortedList.head -> value; ListNode *pnew = head; ListNode *porig = oSortedList.head -> next; while( *porig != NULL ) { pnew -> next = new ListNode; pnew = pnew -> next; pnew -> value = porig -> value; porig = porig -> next; } pnew -> next = NULL;

53 Arrays vs. Linked Lists

54 Saving a Linked List to a File
Pointers are memory addresses that could be different each time a program is run. Consequently, they represent nothing useful from one run to the next. If you wish to save a linked list to a file, it is sufficient to write the data portion of each node to the file, then recreate the linked list when the file is read in.

55 Saving a Linked List to a File (Cont’d.)
void SortedList::saveList( char *filename ) { ofstream outfile( filename, ios::binary ); // open outfile for // binary output for( ListNode *cur = head; cur != NULL; cur = cur -> next ) outfile << cur -> value << endl; outfile.close( ); }

56 Restoring a Linked List from a File
void SortedList::restoreList( char *filename ) { ifstream infile( filename, ios::binary ); // open infile for // binary input ItemType newValue; boolean Success; head = NULL; while( infile >> newValue ) insert( newValue, Success ); }

57 Restoring a Linked List (Cont’d.)
The restoreList( ) function on the previous slide calls public member function insert( ) to find the appropriate place to insert newValue into a SortedList and insert it there. The restore2List( ) function on the next slide takes advantage of the fact that the SortedList was saved to a file in sorted order.

58 Restoring a Linked List (Cont’d.)
void SortedList::restore2List( char *filename ) { ifstream infile( filename, ios::binary ); // open infile for binary // input ItemType newValue; boolean Success; if( infile >> newValue ) // add first element to SortedList // add rest of elements to SortedList }

59 Restoring a Linked List (Cont’d.)
// add first element to SortedList head = new ListNode; head -> value = newValue; head -> next = NULL; ListNode *tail = head; tail head 4 newValue

60 Restoring a Linked List (Cont’d.)
// add rest of elements to SortedList while( infile >> newValue ) { tail -> next = new ListNode; tail = tail -> next; tail -> value = newValue; tail -> next = NULL; } 4 head newValue 6 tail

61 Circular Linked Lists Basic idea: Let the last node in a linked list point back to the first node. Typical use: Server with multiple clients, such as a time-shared computer. The server (computer) processes requests, in turn, from each client (terminal or workstation). When all clients have been served, the server begins again at the beginning of the list of clients. This way of processing requests is sometimes called, “Round Robin.”

62 Circular Linked Lists (Cont’d.)
Benefit: Since every node has a predecessor and a successor and no node contains NULL, list processing (e.g. insertion/deletion) can have fewer special cases. Problem: Without a NULL pointer, how do we know when we are at the end of the list? head 2 4 6

63 Circular Linked Lists (Cont’d.)
Solution: Make the external pointer point to the last node, instead of the first. Now we have easy access to the first and last nodes: tail points to last node tail -> next points to first node 2 4 6 tail

64 Dummy-Headed Linked Lists
Basic idea: Put an empty (“dummy”) node before the first node. Benefit: Since every non-empty node has a predecessor, this is another strategy for reducing the number of special cases required for list processing. head dummy head node 2 4 6 prev cur

65 Dummy-Headed Linked Lists (Cont’d.)
Since the data field in the dummy head node is unused, some people put other information in this field, e.g. length of the list, largest or smallest element, etc. CAUTION: If you do this, what you store must be clearly documented and be of the same data type as the other data elements. (Otherwise, handling the dummy head node will be a special case.) head dummy head node 2 4 6

66 Doubly Linked Lists Basic idea: Every node contains a pointer to the next and previous nodes in the list. Benefit: prev pointer is no longer needed.

67 Doubly Linked List Insertion
Suppose that we wish to insert 34 before the node pointed to by cur. newValue 34 cur 55 21 13 pred next

68 Doubly Linked List Insertion (Cont’d.)
ListNode *newNode = new ListNode; newNode -> value = newValue; newNode -> next = cur; newNode -> pred = cur -> pred; (newNode -> next) -> pred = newNode; (newNode -> pred) -> next = newNode; newValue 34 55 21 13 cur newNode 34

69 Doubly Linked List Deletion
Suppose now that we would like to delete the node containing 34 from the list. (cur -> pred) -> next = cur -> next; (cur -> next) -> pred = cur -> pred; 21 34 55 13 cur

70 Doubly Linked List Deletion (Cont’d.)
(cur -> pred) -> next = cur -> next; (cur -> next) -> pred = cur -> pred; cur -> pred = NULL; cur -> next = NULL; delete cur; cur = NULL; 13 21 34 55 cur

71 Doubly Linked Lists (Cont’d.)
Doubly linked lists are often implemented with a dummy head node to reduce the number of special cases required for list processing. If we use a circular doubly linked list with a dummy head node, then no special cases are needed for insertion and deletion. (The preceding code works in all cases.) However, since each node in a doubly linked lists stores a pointer to the previous node, doubly linked lists require more memory than singly linked lists. This could be as much as 50% more memory if the list is storing a list of integers.

72 Circular, Doubly-Linked List with a Dummy Head Node
How do we find the end of the list? ( cur = = head -> prev ) One of the biggest advantages of a doubly linked list is the ability to traverse the list in both directions. 13 21 55 dummy head node head cur

73 Maintaining an Inventory
Read this “case study” in Chapter 4 of your text, Walls & Mirrors. This is a very good illustration of how to capture the significant aspects of a “real life” problem, break in into smaller sub-problems, and apply the concepts of this chapter in deciding upon an appropriate implementation.


Download ppt "(Walls & Mirrors - Beginning of Chapter 4)"

Similar presentations


Ads by Google