1 / 46

Engineering Problem Solving With C++ An Object Based Approach

Engineering Problem Solving With C++ An Object Based Approach. Chapter 9 Pointers and Creating Data Structures. Pointer Basics. A pointer is a variable that holds the memory address of another object

yukio
Download Presentation

Engineering Problem Solving With C++ An Object Based Approach

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Engineering Problem Solving With C++An Object Based Approach Chapter 9 Pointers and Creating Data Structures

  2. Pointer Basics • A pointer is a variable that holds the memory address of another object • If a variable p contains the address of another variable q, then p is said to point to q • If q is a variable at location 100 in memory, then p would have the value 100 (q’s address)

  3. Address Of Operator • The & operator is called the addressof operator. • The operator & in front of any variable produces the address of that variable. • Example: int x=75; cout << "x is " << x; cout << "\nthe addres of x is " << &x; 0x7fff8164 x 75 x is 75 the address of x is 0x7fff8164

  4. How to declare a pointer variable • pointer variables are declared using the indirection operator*, more commonly called the dereferencing operator. • general form - • type *variable_name, *variable_name; • type* variable_name; • when declaring more than one pointer variable, the * must precede each variable.

  5. Example int *iPtr; double* dPtr; • the variable iPtr is declared to be of type pointer to int • the variable dPtr is declared to be of type pointer to double • neither variable in this example has been initialized • declaring a pointer creates a variable capable of holding an address

  6. Example int *iPtr, i=6;char* s, str = "example";double *dPtr, d=1.25; iPtr s dPtr i str d 6 "example" 1.25

  7. NULL pointer • there is a literal value that can be assigned to any pointer • the literal value is NULL or 0 • in this context it is known as the nulladdressand does not point to anything which can be referenced. • trying to dereference the null address, results in a terminal error

  8. Example int *iPtr=0; char *s=NULL; //predefined constant in iostream.h double *dPtr=NULL; NULL iPtr s dPtr NULL NULL

  9. x xp ip Assigning values to a pointer • the assignment operator (=) is defined for pointers • the right operand of the assignment operator can be any expression that evaluates to the same type as the left Example: int x, *xp, *ip; xp = &x; ip = xp;

  10. The Base Type • In the declaration int *p; // the base type of p is int double *q; // the base type of q is double • Base type determines the size of an object to which the pointer is assumed to be pointing • The size of p and q are the same ( 4 bytes**), but p points to 4 bytes** and q points to 8 bytes** **compiler dependent

  11. Base Type continued • A pointers base type determines how the contents of the memory location pointed to by the pointer will be interpreted • The declaration: int *p; declares p to be a pointer to int. What ever p points to will be interpreted as an int, whether or not it actually is an int • Base type also affects pointer arithmetic

  12. Pointer Arithmetic • Four arithmetic operations are supported • +, -, ++, -- • only integers may be used in these operations • Arithmetic is performed relative to the base type • When applied to pointers, ++ means increment pointer to point to nextobject Example: p++; • if p is defined as int *p, p will be incremented by 4 • if p is defined as double *p, p will be incremented by 8

  13. Example int *p; cout << "size of char is " << sizeof(char) << endl; cout << "size of int is " << sizeof(int) << endl; cout << "size of double is " << sizeof(double) << endl; cout << "size of float is " << sizeof(float) << endl; cout << "the size of p is " << sizeof(p) << endl; Output: size of char is 1 size of int is 4 size of double is 8 size of float is 4 the size of p is 4

  14. Practice! (Use the information from previous slide) int q=6; int *iPtr = &q; cout << "iPtr is " << iPtr << endl; cout << "*iPtr is " << *iPtr << endl; cout << "++*iPtr, is " << ++*iPtr << endl; cout << "q is " << q << endl; cout << "iPtr is " << iPtr << endl; cout << "*iPtr++ is " << *iPtr++ << endl; cout << "iPtr is " << iPtr << endl; cout << "q is " << q << endl; If the first line of output is iPtr is 0x7fff2f14 what is the remaining output?

  15. Result of Practice iPtr is 0x7fff2f14 *iPtr is 6 ++*iPtr is 7 q is 7 iPtr is 0x7fff2f14 *iPtr++ is 7 iPtr is 0x7fff2f18 q is 7

  16. Comparing Pointers • You may compare pointers using relational operators • Common comparisons are: • check for null pointer (p == NULL) • Note: since NULL evaluates as false, and any other pointer evaluates as true, checking for a null pointer can be done as (!p) • check if two pointers are pointing to the same object (p == q) • Note: (*p == *q) means they are pointing to equivalent, but not necessarily the same data.

  17. Pointers and Arrays • The name of an array is the address of the first element (i.e. a pointer to the first element) • Arrays and pointers may often be used interchangeably Example int num[4] = {1,2,3,4}, *p; p = num; //same as p = &num[0]; cout << *p<<endl; p++; cout << *p; 1 2

  18. More Pointers and Arrays • You can also index a pointer using array notation Example: char myString[] = "This is a string"; char *str; str = myString; for(int i =0; str[i]; i++) //look for null cout << str[i]; What does this segment print? This is a string

  19. Arrays and Pointers • The name of an array is a pointer to the first element. However, the array name is not a pointer variable. It is a constantpointer that always points to the first element of the array and its value can not be changed. • Also when an array is declared, space for all elements in the array is allocated, however when a pointer variable is declared only space sufficient to hold an address is allocated

  20. 0xfff4c252 myString T h i s i s a s t r i n g \0 strPtr 0xfff4c252 Practice! What does this print? char myString[ ] = "This is a string"; char *strPtr; strPtr = myString; cout << *myString << endl; cout<<myString << endl; cout << *(myString + 1) << endl; strPtr++; cout << *++strPtr << endl; myString++; //not legal T This is a string h i

  21. Arrays of Pointers • You may define arrays of pointers like any other data type in C++ int num=8; //declare an array of 10 pointers to int int *iPtrs[10]; //first element is assigned a value iPtrs[0] = &num; //output the value of num cout << *iPtrs[0];

  22. Arrays of Type char pointers • char *words[ ] ; //array of pointers to char int main(int argc, char *argv[ ]) { for(int I =1; I<argc; I++) cout << argv[I] << endl; //ouput Ith string } output all arguments, not the command a.out filename1 filename2 filename3 (argc is 4)

  23. Passing Pointers As Parameters • Pointers may be passed either "by value" or "by reference". • In either case, the pointer can be used to modify the object to which it is pointing. • Only when passed by reference can the pointer argument be modified.

  24. Common Pointer Problems • Using uninitialized pointers int *iPtr; *iPtr = 100; iPtr has not been initialized. The value 100 will be assigned to some memory location. Which one determines the error. • Failing to reset a pointer after altering it’s value • Incorrect/unintended syntax

  25. Practice! • #include <iostream> • using namespace std; • int main() • { char *aString = "What happens here?"; • int len=0; • while(*aString++ != '\0') • len++; • cout << len << ": " << aString; • return 0; • } • Does this compile? If not, why? • If it does, what is the output? Why? Yes 18:

  26. Stack Heap Global data Program code Dynamic Allocation Using new and delete • Storage for data is allocated as needed from the free memory area known as the heap (or the freestore). • Run-time stack • Local variables • Formal parameters • Managed by the compiler • Heap • Dynamic storage • Managed by storage allocator

  27. Dynamic Memory Allocation • Dynamically allocated memory is determined at runtime • It allows a program to create as many or as few variables as required, offering greater flexibility • Dynamic allocation is often used to support data structures such as stacks, queues, linked lists and binary trees. • Dynamic memory is finite • Dynamically allocated memory may be freed during execution

  28. Operator new • Replaces malloc() used in C • Creates a new dynamic variable of the specified type • Returns a pointer to the new variable • If allocation fails, new terminates the program (or returns NULL on older compilers)

  29. Example int *iPtr; iPtr = new int; // 4 bytes are allocated // iPtr points to new integer // variable double *dPtr; dPtr = new double[20]; // dPtr points to the first // double in anarray // of 20 doubles (160 bytes // allocated)

  30. new - continued • If your compiler returns NULL when new fails, it is a good idea to check after each request. int *p; p = new int; //if assertion is false, program ends and error //message is issued assert(p != NULL); • assert is defined in cassert

  31. Initializing Dynamically Allocated Memory • To initialize a dynamically allocated variable, specify the initial value inside parentheses after the type name. • Example: int *ptr; ptr = new int(100); //new variable pointed to //by ptr has a value of 100

  32. iPtr jPtr ? ? ? ? ? ? dptr Practice: int main() { int *iPtr, *jPtr, i; iPtr = new int; jPtr = new int(3); double *dPtr; dPtr = new double[6]; *iPtr = 7; //SKETCH MEMORY cout << *iPtr << ',' << *jPtr << endl; for(i=0; i<6; i++) dPtr[i] = 5; for(i=0; i<6; i++) cout << (*dPtr)++ << ' '; cout << endl; for(i=0; i<6; i++) cout << dPtr[i] << ' '; return 0; //OUTPUT? } 7 3 OUTPUT 7 , 3 5 6 7 8 9 10 11 5 5 5 5 5

  33. constModifier with pointers const int *cPtr, *cPtr2; int n=3; cPtr = new int (10); cPtr2 = &n; //can not modify what is pointed to by //cPtr or cPtr2

  34. Operatordelete • Replaces free() function used in C • The delete operator frees memory produced by new • Using delete to attempt to free any other type of address will produce problems • While delete uses a pointer variable, it does not destroy the pointer variable, it only frees the storage to which the variable is pointing.

  35. 100 delete Example int *ptr; ptr = new int (100); cout << *ptr; //see if it worked delete ptr; //free the memory value of ptr is now undefined

  36. Example of dynamically allocated arrays double *dptr; const int size = 10; dptr = new double[size]; //allocate 10 doubles for(int I=0; I<size; I++) //read values into array cin >> dptr[I]; fun1(dptr, size); // pass array to fun1 delete [] dptr; //free all 10 elements prototype for fun1: void fun1(double*, int);

  37. Example using delete int *iPtr, *jPtr; iPtr = new int(2); jPtr = new int(3); cout << *iPtr << ',' << *jPtr << endl; delete iPtr; delete jPtr; cout << *iPtr << ',' << *jPtr << endl; int *dPtr; dPtr = new int(5); cout << iPtr << ',' << jPtr << endl; cout << *iPtr << ',' << *jPtr << endl; cout << dPtr << endl; What would you expect from this code?

  38. Data Structures • Dynamic memory allocation is used to implement data structures such as • stacks • queues • linked lists

  39. Stacks • Last-In-First_Out (LIFO) • Many processes exhibit this behavior • control when computing function calls • compiler design (language parsing) • cafeteria tray stacks

  40. Implementing Stacks • Stacks can be implemented using an array • concern with exceeding bounds of the array • Linked structures are a more natural way stack 5 7 7 NULL • Allocate newmemory each time a value is added to the stack

  41. Stack operations • Create Stack • Stack points to NULL • Empty • returns true if stack is empty • Push • Insert a value into the head of the list (top of the stack) • Top • Return the value of the head (top) of the stack • Pop • Remove element from top of stack

  42. Example • Create • Push 2 • Push 4 • Pop • Top • Stack Stack 2 Stack 4 2 Stack 2

  43. Queues • First-In-First_Out (FIFO) • Many processes exhibit queuing behavior • Waiting lines of people • Job requests • Requests for computer resources

  44. Implementing Queues • Queues require both a head (front) and a tail (rear) pointer • Values are added to the tail • Values are retrieved from the head 5 7 8 head tail

  45. Queue operations • Create queue • Creates an empty queue by setting head and rear to NULL • Empty • Returns true if the queue is empty, and false otherwise • InsertTail • Inserts a new item to the rear of the queue • DeleteHead • Deletes the node at the front of the queue

  46. Example • Create • InsertTail 2 • InsertTail 4 • DeleteHead • Head Head 2 2 Head Tail 4 Tail Head Tail 4

More Related