# 1 CS 162 Introduction to Computer Science Chapter 8 Pointers Herbert G. Mayer, PSU Status 11/20/2014.

## Presentation on theme: "1 CS 162 Introduction to Computer Science Chapter 8 Pointers Herbert G. Mayer, PSU Status 11/20/2014."— Presentation transcript:

1 CS 162 Introduction to Computer Science Chapter 8 Pointers Herbert G. Mayer, PSU Status 11/20/2014

2 Syllabus Simple int Pointers Simple int Pointers Forward References Forward References Linked List of char Elements Linked List of char Elements

3 Simple int Pointers Define various pointers to integer e.g.: int * p; Define various pointers to integer e.g.: int * p; Set some pointers to the address of int array elements Set some pointers to the address of int array elements And set a pointer simply to an array, in C and C++ array operations are not possible, and an array name simply refers to the address of the ac tualarray object And set a pointer simply to an array, in C and C++ array operations are not possible, and an array name simply refers to the address of the ac tualarray object Print pointers –i.e. machine addresses--, also the objects pointed to, and the differences of 2 distinct pointers, both counting up and down Print pointers –i.e. machine addresses--, also the objects pointed to, and the differences of 2 distinct pointers, both counting up and down Note that “difference of 2 pointers” means, the distance between 2 machine addresses, i.e. this is very low-level machine architecture detail, one of the unique features of C and C++ Note that “difference of 2 pointers” means, the distance between 2 machine addresses, i.e. this is very low-level machine architecture detail, one of the unique features of C and C++

4 Implement int Pointers #include #include int prime[] = { 0, 1, 2, 3, 5, 7, 11, 13 }; int prime[] = { 0, 1, 2, 3, 5, 7, 11, 13 }; int *p = & prime[ 2 ]; int *p = & prime[ 2 ]; int *q = & prime[ 4 ]; int *q = & prime[ 4 ]; int *r = prime; int *r = prime; int main() int main() { // main { // main cout << "*p = prime[2] = 2 = " << *p << endl; cout << "*p = prime[2] = 2 = " << *p << endl; cout << "*q = prime[4] = 5 = " << *q << endl; cout << "*q = prime[4] = 5 = " << *q << endl; cout << "*r = prime[0] = 0 = " << *r << endl; cout << "*r = prime[0] = 0 = " << *r << endl; printf( "p = %d\n", p ); printf( "p = %d\n", p ); printf( "q = %d\n", q ); printf( "q = %d\n", q ); printf( "r = %d\n", r ); printf( "r = %d\n", r ); printf( "r+1 = %d\n", r+1 ); printf( "r+1 = %d\n", r+1 ); printf( "*(r+1) = %d\n", *(r+1) ); printf( "*(r+1) = %d\n", *(r+1) ); printf( "p-q = %d\n", p-q ); printf( "p-q = %d\n", p-q ); printf( "q-p = %d\n", q-p ); printf( "q-p = %d\n", q-p ); return 0; } // end main } // end main

5 Output for int Pointers *p = prime[2] = 2 = 2 *q = prime[4] = 5 = 5 *r = prime[0] = 0 = 0 p = 137160 q = 137168 r = 137152 r+1 = 137156 *(r+1) = 1 p-q = -2 q-p = 2

6 Output for int Pointers As expected, p points to prime[ 2 ], and q to prime[ 4 ] As expected, p points to prime[ 2 ], and q to prime[ 4 ] Also expected, actual output on a real machine, is the order of the 3 pointers values themselves: r is set to point to the whole array prime[], which is the address of prime[ 0 ], which is 8 bytes before prime[ 2 ] Also expected, actual output on a real machine, is the order of the 3 pointers values themselves: r is set to point to the whole array prime[], which is the address of prime[ 0 ], which is 8 bytes before prime[ 2 ] Interesting that the value “r+1”, which is “the next address after r” is 4 larger than that of r, i.e. 4 bytes further in the address range Interesting that the value “r+1”, which is “the next address after r” is 4 larger than that of r, i.e. 4 bytes further in the address range And the absolute value of p-q is 2, not 8. The byte offset would be 8, but the types or p and q are “pointer to int”, then the next or previous element is indeed + -1; here the delta is 2, the indices are 2 and 4 And the absolute value of p-q is 2, not 8. The byte offset would be 8, but the types or p and q are “pointer to int”, then the next or previous element is indeed + -1; here the delta is 2, the indices are 2 and 4

8 Forward References Tress and graphs etc. typically use pointers to elements of types that have not yet been declared Tress and graphs etc. typically use pointers to elements of types that have not yet been declared This is, because the type of such pointers is self- referential, i.e. the type of objects being pointed to includes such pointers themselves This is, because the type of such pointers is self- referential, i.e. the type of objects being pointed to includes such pointers themselves Sounds like a “chicken and egg” problem, matter of fact it is Sounds like a “chicken and egg” problem, matter of fact it is Hence C++ has suitable struct methods to resolve Hence C++ has suitable struct methods to resolve One allows a forward reference, only for pointer types, pointer sizes are always known! One allows a forward reference, only for pointer types, pointer sizes are always known! The other method uses part of the struct type under definition The other method uses part of the struct type under definition

9 Forward Reference for Pointer // define incomplete since “forward” ref’ed ptr // sicne struct node_tp is unknown at this point // typedef struct node_tp * node_ptr_tp;// forward ref // Now OK to define objects of node_ptr_tp // Size is known to compiler: is size of pointer // node_ptr_tp root = NULL;// root of new tree // and now resolve the forward-referenced type typedef struct node_tp// being defined {// the struct charc;// track alpha intcount;// how many alphas? node_ptr_tpleft;// left subtree node_ptr_tpright;// right subtree } node_struct_tp;// new struct type

10 Forward Reference, Reuse struct // struct needs 2 pointers to self, its own type typedef struct node_tp // being defined { // the struct char c; // track alpha int count; // how many alphas? struct node_tp* left; // left subtree struct node_tp* right; // right subtree } node_struct_tp; // new struct type // one way to define pointers to this struct type: node_struct_tp* root1 = NULL; // OK // another way to define pointers to this struct type: typedef node_struct_tp * node_ptr_tp;// new ptr type node_ptr_tp root2 = NULL; // also OK // and a third way: struct node_tp * root3 = NULL; // OK, not good!

11 Implement Linked char List via Pointers // possible solution 1 #include #include typedef struct ll_tp// element of linked list of chars { char c;// actual data struct ll_tp * next;// link to next, if any } ll_type;// symbolic type name typedef ll_type * ll_ptr_type; ll_ptr_type ll = 0;// global pointer to linked list

12 Implement Linked char List via Pointers // possible solution 2 #include #include typedef struct ll_tp * ll_ptr_type;// forward ref’ed typedef struct ll_tp// being defined {// ll of chars char c; char c; ll_ptr_type next;// being used ll_ptr_type next;// being used } ll_type;// new struct type ll_ptr_type ll = NULL;

13 Build Linked char List via Pointers // allocate new node: call malloc() // change global ll void build_ll( ll_ptr_type ll_pin, char c ) { // build_ll ll_ptr_type temp = ll_ptr_type temp = (ll_ptr_type)malloc( sizeof( ll_type ) ); (ll_ptr_type)malloc( sizeof( ll_type ) ); if( temp ) { if( temp ) { temp->next = ll_pin; temp->next = ll_pin; temp->c = c; temp->c = c; ll = temp; ll = temp; }else{ }else{ printf( " no heap space in build_ll()\n" ); printf( " no heap space in build_ll()\n" ); } //end if } //end if } // end build_ll // uses global l void init() { // init char c; char c; while ( ( ( c = getchar() ) != '\$' ) && while ( ( ( c = getchar() ) != '\$' ) && ( c != EOF ) ) { ( c != EOF ) ) { build_ll( ll, c ); build_ll( ll, c ); } // end while } // end while } // end init

14 Linked List print() and main() // new: recursion! void print( ll_ptr_type ll ) { // print if ( ll ) { print( ll->next );// prints last element first printf( "%c ", ll->c ); } // end if } // end print int main() { // main printf( "enter string of characters end with \$:" ); printf( "enter string of characters end with \$:" ); init(); init(); print( ll ); print( ll ); return 0; return 0; } //end main

15 Output for Linked char List Void function print() is passed the global pointer to link elements Void function print() is passed the global pointer to link elements If not null, the current element is not yet printed, but the next ll->next is processed first! If not null, the current element is not yet printed, but the next ll->next is processed first! Once the last link element is reached, and next is NULL, the actual char in field ->c is printed Once the last link element is reached, and next is NULL, the actual char in field ->c is printed Overall the list of chars is printed in the reverse order stored, which is the original order entered in the list! Overall the list of chars is printed in the reverse order stored, which is the original order entered in the list!

Download ppt "1 CS 162 Introduction to Computer Science Chapter 8 Pointers Herbert G. Mayer, PSU Status 11/20/2014."

Similar presentations