270 likes | 387 Views
CS 108 Computing Fundamentals April 24, 2014. Next Three Classes and Exam 4. Introduce linked lists Introduce C++ Hints to prep for CS 240 over the break. Pointers/Addresses as "Return Values". We have routinely passed pointers to functions
E N D
CS 108 Computing Fundamentals April 24, 2014
Next Three Classes and Exam 4 • Introduce linked lists • Introduce C++ • Hints to prep for CS 240 over the break
Pointers/Addresses as "Return Values" • We have routinely passed pointers to functions • We can also write functions that return pointers • We may want to return the location of an answer instead of the value of the answer • Example: suppose we want to send two integer pointers to a function and return the pointer of the larger integer • Let’s develop a prototype for this function called max( )
Pointers/Addresses as "Return Values" • Most folks might develop the following as an initial prototype: int max (int * , int *) • This prototype returns a integer value not an integer pointer… let’s modify it
Pointers/Addresses as "Return Values" • Here’s the modification: int * max (int * , int *) • This function returns the location of the maximum value • Let’s develop the declaration:
Pointers/Addresses as "Return Values" • Given this prototype: int * max (int * , int *) • The declaration is: int * max (int * in_a , int * in_b) { if ( *in_a > *in_b ) return (in_a) ; else return (in_b) ; }
Pointers/Addresses as "Return Values" • Here’s the call for max( ) (assuming answer is declared as a pointer variable of the proper data type): answer = max ( &first, &second) • That means that we need the following variables declared: int * answer , first , second ; • Let’s put it all together
Pointers/Addresses as "Return Values" #include <stdio.h> // 1.c int * max ( int * , int * ) ; int main ( void ) { int * answer = NULL , first = 6 , second = 10 ; answer = max ( &first, &second ) ; printf("\n\n The larger integer value is: %d \n\n\n", * answer ); return (0) ; } int * max ( int * in_a , int * in_b ) { if ( * in_a > * in_b ) return (in_a) ; else return (in_b) ; }
Pointers/Addresses as "Return Values" • Let’s take a look at the addresses and values of our variable/pointers/parameters/arguments
#include <stdio.h> // 2.c int * max ( int * , int * ) ; int main ( void ) { int * answer = NULL , first = 6 , second = 10 ; printf("\n\n\n \t ANSWER \t\t FIRST \t\tSECOND ") ; printf("\n\n main addresses: \t %p \t%p \t %p", &answer, &first, &second); printf("\n\n main values: \t\t %p \t\t\t%d \t\t%d", answer, first, second); answer = max ( &first, &second) ; printf("\n\n The larger integer value is: %d\n\n\n\n", *answer); printf("\n\n\n \t ANSWER \t\t FIRST \t\t SECOND ") ; printf("\n\n main addresses: \t %p \t%p \t %p", &answer, &first, &second); printf("\n\n main values: \t\t %p \t%d \t \t%d", answer, first, second); printf("\n\n\n"); return (0) ; } // Continued on next slide
// Continued from previous slide int * max (int * in_a , int * in_b) { if ( *in_a > *in_b ) { printf("\n\n\n IN_A \t\t\t IN_B") ; printf("\n\n max addresses: \t %p \t %p ", &in_a, &in_b ); printf("\n\n max values: \t\t %p \t %p ", in_a , in_b ); return (in_a) ; } else { printf("\n\n\n IN_A \t\t\t IN_B") ; printf("\n\n max addresses: \t %p \t %p ", &in_a, &in_b ); printf("\n\n max values: \t\t %p \t %p ", in_a , in_b ); return (in_b) ; } }
Linked Lists (an introduction 1) • Many data structures (arrays, structures, and arrays of structures) are very useful but they have some limitations. • Many problems require "records" to be maintained in a certain order (think about directories or ordered lists of any kind) • Directories and ordered lists are dynamic beasts… they are updated often (many insertions and deletions… fewer changes of existing info) • An array of structures isn’t very efficient for maintaining lists (insertions and deletion require lots of overhead, arrays are fixed and pre-specified in size)
Linked Lists (an introduction 2) • Linked lists to the rescue • A linked list is an efficient method of maintaining an ordered, dynamic list (no need to constantly reorder and revise the complete list) • A linked list is a set of instances of a structure in which each instance of the structure contains at least one structure element that holds the address of the next ordered member in the list • Each record contains the address of the next record • Almost like "forward breadcrumbs" (used to find the next record/destination in memory • "Chalk talk"
Linked Lists (an introduction 3) • Each instance of a structure in a linked list has the same format and functionality except the last record… we replace the address of the pointer in the last record with a NULL • NULL acts as a flag the indicates the last record in the list has been processed • NULL marks the end of the list, but we need a way to identify the beginning of the list • We need a pointer that stores the address of the first record in the list • We know the beginning of the list, each element has the address of the next element, and we can determine the end of the list when we see it
Linked Lists (an introduction 4) • Link list factoids • We establish the beginning of the list by assigning the address of the first structure instance to a "beginning pointer" • Each and every member or node of the linked list (AKA structure instance) is assigned the address of the next member or node of the list • We can determine the end of the list when we see it (we find a NULL instead of the next member's/node's address)
Linked Lists… Pre-Prequel (1) • What makes this a Pre-Prequel? • The pointer points to a variable, not another structure instance • Syntax of a structure definition for a linked list: struct structure_name { data_type name_of_element_1 ; data_type name_of_element_2 ; . . . data_type name_of_element_n ; appropriate_data_type * name_of_pointer ; } ;
Linked Lists… Pre-Prequel (2) • Example a structure definition for a linked list: struct student { char first_name[20] ; char last_name[20] ; char ssn[9] ; int * student_ptr ; } ;
Linked Lists… Pre-Prequel (3) • Syntax for creating an instance of a defined structure: struct structure_name instance_name ; • Example of creating an instance of a defined structure : struct student student_1 ; • student_1 is a variable name that is an instance of the student structure
Linked Lists… Pre-Prequel (4) • The program on the next slide demonstrates the use of a structure with a pointer • Linked lists are just an extension of this simple use of a pointer • Note in the program: the structure member operator ( . ) has a higher precedence than the indirection operator ( * ) • Take a close look at the last printf( ) call
#include <stdio.h> // 3.c #include<string.h> typedef struct student { char first_name[20]; char last_name[20]; char ssn[10]; int *student_ptr ; } student ; int main (void) { student student_1; int birdhouse = 357 ; strcpy(student_1.first_name, "Chris"); strcpy(student_1.last_name, "Urban"); strcpy(student_1.ssn, "111223333"); student_1.student_ptr = &birdhouse; printf("\n\nLast name: %s", student_1.last_name); printf("\nSSN: %s \n\n\n", student_1.ssn); printf("\nAddress of birdhouse: %p", &birdhouse); printf("\nAddress that student_1.student_ptr holds: %p", student_1.student_ptr); printf("\nstudent_1.student_ptr points to the value: %d \n\n\n", * student_1.student_ptr); return (0) ; }
Linked List… Prequel (5) • Let’s extend the simple program on the previous slide to a program that creates a linked list but this is a static linked list (there's no dynamic memory allocation… that's what makes this a Prequel) struct student { char first_name[20]; char last_name[20]; char ssn[9]; struct student * next_address ; } ; struct student * first ; struct student st_1 {"Adam", "Applejack", "111111111"}; struct student st_2 {"Cathy", "Compari", "222222222"}; struct student st_3 {"Maddy", "Mead", "333333333"}; struct student st_4 {"Sam", "Saranac", "444444444"}; first = &st_1; st_1.next_address = &st_2; st_2.next_address = &st_3; st_3.next_address = &st_4; st_4.next_address = NULL;
Linked List… Prequel (6) printf("\n\n %s%s %s%s ", first->last_name , st_1.next_address->last_name , st_2.next_address->last_name , st_3.next_address->last_name) ;
#include <stdio.h> //4.c #include<string.h> struct student { char first_name[20]; char last_name[20]; char ssn[9]; struct student *next_address ; } ; int main (void) { struct student *first ; struct student st_1 = {"Adam", "Applejack", "111111111"}; struct student st_2 = {"Cathy", "Compari", "222222222"}; struct student st_3 = {"Maddy", "Mead", "333333333"}; struct student st_4 = {"Sam", "Saranac", "444444444"}; first = &st_1; st_1.next_address = &st_2; st_2.next_address = &st_3; st_3.next_address = &st_4; st_4.next_address = NULL; printf("\n\n %s%s%s%s \n\n", first->last_name , st_1.next_address->last_name , st_2.next_address->last_name , st_3.next_address->last_name) ; return (0) ; } This is a "static" incarnation of a linked list… this isn't optimal because we defined and named the four structures (st_1 though st_4) at compile time. Additionally, the printing isn't too elegant.
#include <stdio.h> //5.c #include<string.h> struct student { char first_name[20]; char last_name[20]; char ssn[9]; struct student *next_address ; } ; int main (void) { struct student *first ; struct student st_1 = {"Adam", "Applejack", "111111111"}; struct student st_2 = {"Cathy", "Compari", "222222222"}; struct student st_3 = {"Maddy", "Mead", "333333333"}; struct student st_4 = {"Sam", "Saranac", "444444444"}; first = &st_1; st_1.next_address = &st_2; st_2.next_address = &st_3; st_3.next_address = &st_4; st_4.next_address = NULL; printf("\n\n %s%s%s%s \n\n", first->last_name , st_1.next_address->last_name , (*st_2.next_address).last_name , // st_2.next_address->last_name st_3.next_address->last_name) ; return (0) ; }
#include <stdio.h> //6.c #include<string.h> struct student { char first_name[20]; char last_name[20]; char ssn[9]; struct student *next_address ; } ; int main (void) { struct student *first ; struct student *tracker ; struct student st_1 = {"Adam", "Applejack", "111111111"}; struct student st_2 = {"Cathy", "Compari", "222222222"}; struct student st_3 = {"Maddy", "Mead", "333333333"}; struct student st_4 = {"Sam", "Saranac", "444444444"}; first = &st_1; st_1.next_address = &st_2; st_2.next_address = &st_3; st_3.next_address = &st_4; st_4.next_address = NULL; tracker = first ; printf("\n\n") ; while (tracker != NULL) { printf(" %s ", tracker->last_name); tracker = tracker -> next_address; } printf("\n\n") ; return (0) ; } A little more elegant way of printing
#include <stdio.h> //7.c use of a function and looping to accomplish printing #include<string.h> struct student { char first_name[20]; char last_name[20]; char ssn[9]; struct student *next_address ; } ; void show_it ( struct student * ) ; int main (void) { struct student *first ; struct student st_1 = {"Adam", "Applejack", "111111111"}; struct student st_2 = {"Cathy", "Compari", "222222222"}; struct student st_3 = {"Maddy", "Mead", "333333333"}; struct student st_4 = {"Sam", "Saranac", "444444444"}; first = &st_1; st_1.next_address = &st_2; st_2.next_address = &st_3; st_3.next_address = &st_4; st_4.next_address = NULL; show_it ( first ) ; return (0); } // continued on next slide
void show_it ( struct student *in ) { while (in != NULL) { printf("\n %s%s \n\n", in->first_name, in->last_name); in = in->next_address; } return ; }