1 C++ Programming I Lecture 9 MIS160 Instructor – Larry Langellier 2000 Deitel & Associates, Inc. All rights reserved. 2 Lecture 9 – Pointers and Strings Outline 5.8 5.9 5.10 5.12 5.13 The Relationship Between Pointers and Arrays Arrays of Pointers Case Study: A Card Shuffling and Dealing Simulation Introduction to Character and String Processing 5.12.1 Fundamentals of Characters and Strings 5.12.2 String Manipulation Functions of the String-handling Library Thinking About Objects: Interactions Among Objects 2000 Deitel & Associates, Inc. All rights reserved. 3 The Relationship Between Pointers and Arrays • Arrays and pointers closely related – Array name like constant pointer – Pointers can do array subscripting operations – Having declared an array b[ 5 ] and a pointer bPtr • bPtr is equal to b bptr == b • bptr is equal to the address of the first element of b bptr == &b[ 0 ] 2000 Deitel & Associates, Inc. All rights reserved. 4 Pointers and Arrays • Array elements can be accessed using pointer notation also • Example – ptrnote.cpp • *(intarray + j) is equivalent to intarray[j] • Adding a value to a pointer causes it to move that many elements forward, not that many address locations • In the case of an integer, adding 1 would move you 2 bytes forward; for a double, adding 1 would move you 8 bytes forward 2000 Deitel & Associates, Inc. All rights reserved. 5 Pointer Constants and Pointer Variables • You may not use the increment operator to step through array addresses – the starting address of the array is a constant • Although you can’t increment the address, you can increment a pointer that holds the address • Example – ptrinc.cpp • The pointer variable can be incremented and used to traverse the array 2000 Deitel & Associates, Inc. All rights reserved. 6 The Relationship Between Pointers and Arrays • Accessing array elements with pointers – Element b[ n ] can be accessed by *( bPtr + n ) • Called pointer/offset notation – Array itself can use pointer arithmetic. • b[ 3 ] same as *(b + 3) – Pointers can be subscripted (pointer/subscript notation) • bPtr[ 3 ] same as b[ 3 ] 2000 Deitel & Associates, Inc. All rights reserved. 7 Arrays of Pointers • Arrays can contain pointers – Commonly used to store an array of strings char *suit[ 4 ] = {"Hearts", "Diamonds", "Clubs", "Spades" }; – Each element of suit is a pointer to a char * (a string) – The strings are not in the array, only pointers to the strings are in the array suit[0] ’H’ ’e’ ’a’ ’r’ ’t’ ’s’ ’\0’ suit[1] ’D’ ’i’ ’a’ ’m’ ’o’ ’n’ ’d’ suit[2] ’C’ ’l’ ’u’ ’b’ ’s’ ’\0’ suit[3] ’S’ ’p’ ’a’ ’d’ ’e’ ’s’ ’s’ ’\0’ ’\0’ – suit array has a fixed size, but strings can be of any size • Example – ptrtostr.cpp 2000 Deitel & Associates, Inc. All rights reserved. 8 Case Study: A Card Shuffling and Dealing Simulation • Card shuffling program – Use an array of pointers to strings, to store suit names – Use a double scripted array (suit by value) Ace 0 Hearts 0 Diamonds 1 Clubs 2 Spades 3 Two 1 2 Three Four Five Six Seven Eight Nine Ten Jack Queen King 3 4 5 6 7 8 9 10 11 12 deck[2][12] represents the King of Clubs Clubs King – Place 1-52 into the array to specify the order in which the cards are dealt 2000 Deitel & Associates, Inc. All rights reserved. 9 Case Study: A Card Shuffling and Dealing Simulation • Pseudocode for shuffling and dealing simulation First refinement Initialize the suit array Initialize the face array Initialize the deck array Second refinement For each of the 52 cards Place card number in randomly selected unoccupied slot of deck Third refinement Choose slot of deck randomly While chosen slot of deck has been previously chosen Choose slot of deck randomly Place card number in chosen slot of deck Shuffle the deck For each of the 52 cards Deal 52 cards Find card number in deck array and print face and suit of card 2000 Deitel & Associates, Inc. All rights reserved. For each slot of the deck array If slot contains card number Print the face and suit of the card 1 // Fig. 5.24: fig05_24.cpp 2 // Card shuffling dealing program 3 #include <iostream> 4 5 using std::cout; 6 using std::ios; 7 8 #include <iomanip> 9 10 using std::setw; 11 using std::setiosflags; 12 13 #include <cstdlib> 14 #include <ctime> 15 16 void shuffle( int [][ 13 ] ); 17 void deal( const int [][ 13 ], const char *[], const char *[] ); 18 19 int main() 20 { 21 const char *suit[ 4 ] = 22 { "Hearts", "Diamonds", "Clubs", "Spades" }; 23 const char *face[ 13 ] = 24 { "Ace", "Deuce", "Three", "Four", 25 "Five", "Six", "Seven", "Eight", 26 "Nine", "Ten", "Jack", "Queen", "King" }; 27 int deck[ 4 ][ 13 ] = { 0 }; 28 29 srand( time( 0 ) ); 30 31 shuffle( deck ); 32 deal( deck, face, suit ); 2000 Deitel & Associates, Inc. All rights reserved. 33 Outline 1. Initialize suit and face arrays 1.1 Initialize deck array 2. Call function shuffle 2.1 Call function deal 34 return 0; 35 } 36 37 void shuffle( int wDeck[][ 13 ] ) The numbers 1-52 are 3. Define functions 38 { randomly placed into the 39 int row, column; deck array. 40 41 for ( int card = 1; card <= 52; card++ ) { 42 do { 43 row = rand() % 4; 44 column = rand() % 13; 45 } while( wDeck[ row ][ column ] != 0 ); 46 47 wDeck[ row ][ column ] = card; 48 } 49 } 50 51 void deal( const int wDeck[][ 13 ], const char *wFace[], 52 const char *wSuit[] ) 53 { Searches deck for the 54 for ( int card = 1; card <= 52; card++ ) card number, then prints 55 56 for ( int row = 0; row <= 3; row++ ) the face and suit. 57 58 for ( int column = 0; column <= 12; column++ ) 59 60 if ( wDeck[ row ][ column ] == card ) 61 cout << setw( 5 ) << setiosflags( ios::right ) 62 << wFace[ column ] << " of " 63 << setw( 8 ) << setiosflags( ios::left ) 64 << wSuit[ row ] 65 << ( card % 2 == 0 ? '\n' : '\t' ); 2000 Deitel & Associates, Inc. All rights reserved. 66 } Outline Six of Clubs Ace of Spades Ace of Hearts Queen of Clubs Ten of Hearts Ten of Spades Ten of Diamonds Four of Diamonds Six of Diamonds Eight of Hearts Nine of Hearts Deuce of Spades Five of Clubs Deuce of Diamonds Five of Spades King of Diamonds Deuce of Hearts Ace of Clubs Three of Clubs Nine of Clubs Four of Hearts Eight of Diamonds Jack of Diamonds Five of Hearts Four of Clubs Jack of Clubs Seven of Diamonds Ace of Diamonds Queen of Diamonds Seven of Hearts Deuce of Clubs Three of Spades Four of Spades Ten of Clubs Six of Spades Three of Diamonds Three of Hearts Six of Hearts Eight of Clubs Eight of Spades King of Clubs Jack of Spades Queen of Hearts King of Spades King of Hearts Nine of Spades Queen of Spades Nine of Diamonds Seven of Clubs Five of Diamonds Jack of Hearts Seven of Spades 2000 Deitel & Associates, Inc. All rights reserved. Outline Program Output 13 Function Pointers • Pointers to functions – Contain the address of the function – Similar to how an array name is the address of its first element – Function name is starting address of code that defines function • Function pointers can be – Passed to functions – Stored in arrays – Assigned to other function pointers 2000 Deitel & Associates, Inc. All rights reserved. 14 Function Pointers • Example: bubblesort – Function bubble takes a function pointer • The function determines whether the the array is sorted into ascending or descending sorting – The argument in bubble for the function pointer bool ( *compare )( int, int ) tells bubble to expect a pointer to a function that takes two ints and returns a bool – If the parentheses were left out bool *compare( int, int ) would declare a function that receives two integers and returns a pointer to a bool 2000 Deitel & Associates, Inc. All rights reserved. 1 // Fig. 5.26: fig05_26.cpp 2 // Multipurpose sorting program using function pointers 3 #include <iostream> 4 5 using std::cout; 1. Initialize array 6 using std::cin; 7 using std::endl; 8 Notice the function pointer 2. Prompt for 9 #include <iomanip> ascending or parameter. 10 descending sorting 11 using std::setw; 12 13 void bubble( int [], const int, bool (*)( int, int ) ); 2.1 Put appropriate 14 bool ascending( int, int ); function pointer into 15 bool descending( int, int ); bubblesort 16 17 int main() 18 { 2.2 Call bubble 19 const int arraySize = 10; 20 int order, 21 counter, 3. Print results 22 a[ arraySize ] = { 2, 6, 4, 8, 10, 12, 89, 68, 45, 37 }; 23 24 cout << "Enter 1 to sort in ascending order,\n" 25 << "Enter 2 to sort in descending order: "; 26 cin >> order; 27 cout << "\nData items in original order\n"; 28 29 for ( counter = 0; counter < arraySize; counter++ ) 30 cout << setw( 4 ) << a[ counter ]; 31 32 if ( order == 1 ) { 33 bubble( a, arraySize, ascending ); 2000 Deitel & Associates, Inc. Allitems rights reserved. 34 cout << "\nData in ascending order\n"; Outline 35 } 36 else { 37 bubble( a, arraySize, descending ); 38 cout << "\nData items in descending order\n"; 39 } 3.1 Define functions 40 41 for ( counter = 0; counter < arraySize; counter++ ) 42 cout << setw( 4 ) << a[ counter ]; 43 44 cout << endl; ascending and 45 return 0; descending return true or 46 } 47 false. bubble calls swap if 48 void bubble( int work[], const int size, the function call returns true. 49 bool (*compare)( int, int ) ) 50 { 51 void swap( int * const, int * const ); // prototype 52 53 for ( int pass = 1; pass < size; pass++ ) Notice how function pointers 54 are called using the 55 for ( int count = 0; count < size - 1; count++ ) dereferencing operator. The * 56 57 if ( (*compare)( work[ count ], work[ count + 1 ] ) ) is not required, but emphasizes 58 swap( &work[ count ], &work[ count + 1 ] ); that compare is a function 59 } pointer and not a function. 60 61 void swap( int * const element1Ptr, int * const element2Ptr ) 62 { 63 int temp; 64 65 temp = *element1Ptr; 66 *element1Ptr = *element2Ptr; 67 *element2Ptr = temp; 2000 68 } Deitel & Associates, Inc. All rights reserved. Outline 69 Outline 70 bool ascending( int a, int b ) 71 { 72 return b < a; // swap if b is less than a 3.1 Define functions 73 } 74 75 bool descending( int a, int b ) 76 { 77 return b > a; // swap if b is greater than a 78 } Enter 1 to sort in ascending order, Enter 2 to sort in descending order: 1 Data items in original order 2 6 4 8 10 12 89 68 Data items in ascending order 2 4 6 8 10 12 37 45 Program output 45 37 68 89 Enter 1 to sort in ascending order, Enter 2 to sort in descending order: 2 Data items in original order 2 6 4 8 10 12 89 68 Data items in descending order 89 68 45 37 12 10 8 6 45 37 4 2 2000 Deitel & Associates, Inc. All rights reserved. 18 Fundamentals of Characters and Strings • Character constant – Integer value of a character – Single quotes – 'z' is the integer value of z, which is 122 • String – Series of characters treated as one unit – Can include letters, digits, special characters +, -, * ... – String literal (string constants) • Enclosed in double quotes, for example: "I like C++" – Array of characters, ends with null character '\0' – Strings are constant pointers (like arrays) • Value of string is the address of its first character 2000 Deitel & Associates, Inc. All rights reserved. 19 Fundamentals of Characters and Strings • String assignment – Character array: char color[] = "blue"; • Creates 5 element char array, color, (last element is '\0') – variable of type char * char *colorPtr = "blue"; • Creates a pointer to string “blue”, colorPtr, and stores it in memory • Avoiding Buffer Overflow – Use setw( ) to limit the number of characters cin will accept – one less than the width – Example – safetyin.cpp • String Constants – You can initialize a string variable to a constant value when you define it char str[] = “Halloween is coming!!!”; 2000 Deitel & Associates, Inc. All rights reserved. 20 Just Do It! Write a program that uses random-number generation to create sentences. The program should use four arrays of pointers to char called article, noun, verb and preposition. The program should create a sentence by selecting a word at random from each array in the following order: article, noun, verb, preposition, article and noun. As it word is picked, it should be concatenated to the previous words in an array that is large enough to hold the entire sentence. The words should be separated by spaces. When the final sentence is output it should start with a capital letter and end with a period. The program should generate 20 such sentences. The arrays should contain: article: noun: verb: preps: “the”, “a”, “one”, “some”, “any” “boy”, “girl”, “dog”, “town”, “car” “drove”, “jumped”, “ran”, “walked”, “skipped” “to”, “from”, “over”, “under”, “on” 2000 Deitel & Associates, Inc. All rights reserved. 21 Sample Solution #include <iostream> #include <cstdlib> #include <ctime> #include <cstring> #include <cctype> using namespace std; const int SIZE = 100; int main() { const char article[][10] = { "the", "a", "one", "some", "any" }, noun[][10] = { "boy", "girl", "dog", "town", "car" }, verb[][10] = { "drove", "jumped", "ran", "walked", "skipped" }, preposition[][10] = { "to", "from", "over", "under", "on" }; char sentence[ SIZE ] = ""; 2000 Deitel & Associates, Inc. All rights reserved. 22 Sample Solution (cont.) for ( int i = 1; i <= 20; ++i ) { strcat( sentence, article[ rand() % 5 ] ); strcat( sentence, " " ); strcat( sentence, noun[ rand() % 5 ] ); strcat( sentence, " " ); strcat( sentence, verb[ rand() % 5 ] ); strcat( sentence, " " ); strcat( sentence, preposition[ rand() % 5 ] ); strcat( sentence, " " ); strcat( sentence, article[ rand() % 5 ] ); strcat( sentence, " " ); strcat( sentence, noun[ rand() % 5 ] ); cout << static_cast< char > ( toupper( sentence[ 0 ] ) ) << &sentence[ 1 ] << ".\n"; sentence[ 0 ] = '\0'; } cout << endl; return 0; } 2000 Deitel & Associates, Inc. All rights reserved. 23 Fundamentals of Characters and Strings • Reading strings – Assign input to character array word[ 20 ] cin >> word • Reads characters until whitespace or EOF • String could exceed array size cin >> setw( 20 ) >> word; • Reads 19 characters (space reserved for '\0') • cin.getline – Reads a line of text – Using cin.getline cin.getline( array, size, delimiter character); 2000 Deitel & Associates, Inc. All rights reserved. 24 Fundamentals of Characters and Strings • cin.getline – Copies input into specified array until either • One less than the size is reached • The delimiter character is input – Example char sentence[ 80 ]; cin.getline( sentence, 80, '\n' ); 2000 Deitel & Associates, Inc. All rights reserved. 25 Copying Strings • The Hard Way – character by character – Use a loop copying character by character from one array to the other – Example – strcopy1.cpp – Library Function – strlen( ) • The Easy Way – using the strcpy( ) function – The standard string library (cstring) provides a function that will copy the contents of one string variable into another – strcpy( ) strcpy(str2, str1); – Example – strcopy2.cpp 2000 Deitel & Associates, Inc. All rights reserved. 26 String Manipulation Functions of the Stringhandling Library • String handling library <cstring> provides functions to – – – – Manipulate strings Compare strings Search strings Tokenize strings (separate them into logical pieces) • ASCII character code – Strings are compared using their character codes – Easy to make comparisons (greater than, less than, equal to) • Tokenizing – Breaking strings into tokens, separated by user-specified characters – Tokens are usually logical units, such as words (separated by spaces) – "This is my string" has 4 word tokens (separated by spaces) 2000 Deitel & Associates, Inc. All rights reserved. 27 String Manipulation Functions of the String-handling Library char *strcpy( char *s1, const char *s2 ); Copies the string s2 into the character array s1. The value of s1 is returned. char *strncpy( char *s1, const char *s2, size_t n ); Copies at most n characters of the string s2 into the character array s1. The value of s1 is returned. char *strcat( char *s1, const char *s2 ); Appends the string s2 to the string s1. The first character of s2 overwrites the terminating null character of s1. The value of s1 is returned. char *strncat( char *s1, const char *s2, size_t n ); Appends at most n characters of string s2 to string s1. The first character of s2 overwrites the terminating null character of s1. The value of s1 is returned. int strcmp( const char *s1, const char *s2 ); Compares the string s1 with the string s2. The function returns a value of zero, less than zero or greater than zero if s1 is equal to, less than or greater than s2, respectively. 2000 Deitel & Associates, Inc. All rights reserved. 28 String Manipulation Functions of the String-handling Library (III) int strncmp( const char *s1, const char *s2, size_t n ); Compares up to n characters of the string s1 with the string s2. The function returns zero, less than zero or greater than zero if s1 is equal to, less than or greater than s2, respectively. char *strtok( char *s1, const char *s2 ); A sequence of calls to strtok breaks string s1 into “tokens”—logical pieces such as words in a line of text—delimited by characters contained in string s2. The first call contains s1 as the first argument, and subsequent calls to continue tokenizing the same string contain NULL as the first argument. A pointer to the current token is returned by each call. If there are no more tokens when the function is called, NULL is returned. size_t strlen( const char *s ); Determines the length of string s. The number of characters preceding the terminating null character is returned. 2000 Deitel & Associates, Inc. All rights reserved. 29 Strings as Part of Other Types • Arrays of Strings – Strings are Arrays and we can have Arrays of Arrays (multidimensional), therefor we can have Arrays of Strings – Example – straray.cpp – Accessing an individual String star[j] – not star[j][i] • Strings as Data Members – Strings can be a Data Member for a struct – Example – strpart.cpp 2000 Deitel & Associates, Inc. All rights reserved. 30 Just Do It! Write a program that encodes English language words into pig Latin. Pig Latin is a form of coded language often used from amusement. To translate an English word into a pig Latin word, place the first letter of the English word at the end of the English word and add the letters “ay”. Thus the word “jump” becomes “umpjay”. Assume that all words have two or more letters You should have a function called printLatinWord() to display the word. Feel free to use any string functions you find useful… 2000 Deitel & Associates, Inc. All rights reserved. 31 Sample Solution #include <iostream> #include <cstring> using namespace std; const int SIZE = 80; void printLatinWord( char word[] ) { int i; int len = strlen( word ); for (i = 1; i < len; ++i ) cout << word[i]; cout << word[0] << "ay"; } 2000 Deitel & Associates, Inc. All rights reserved. 32 Sample Solution (cont.) int main() { char word[ SIZE ]; cout << "Enter a word:\n"; cin.getline( word, SIZE ); cout << "\nThe word in Pig Latin is:\n"; printLatinWord( word ); cout << endl; return 0; } 2000 Deitel & Associates, Inc. All rights reserved. 33 Thinking (some more) About Objects • This chapter – Last OOD assignment before we begin study of OOP in Chapter 6 – Focus on object collaboration • End of section – List of Internet and WWW UML resources (look in text) – Bibliography of UML resources (look in text) • Chapter 6 – Begin coding simulator • Chapters 7, 9 – Required to complete simulator 2000 Deitel & Associates, Inc. All rights reserved. 34 Collaborations • Collaboration - interaction between objects 1. Object of one class 2. Sends message 3. Received by object of another class – Message invokes operation of second class – In Chapter 4, we determined many operations • Now, we focus on the messages that invoke them • Next slide – List of verb phrases that correspond to operations • Some phrases removed from complete list of all verbs – Remaining phrases are collaborations 2000 Deitel & Associates, Inc. All rights reserved. 35 Collaborations (II) Cla ss Verb p hra ses Elevator resets the elevator button, sounds the elevator bell, signals its arrival to a floor, opens its door, closes its door Clock Scheduler ticks every second tells a person to step onto a floor, verifies that a floor is unoccupied Person presses floor button, presses elevator button, enters elevator, exits elevator Floor resets floor button, turns off light, turns on light FloorButton summons elevator ElevatorButton signals elevator to prepare to leave Door (opening of door) signals person to exit elevator, (opening of door) signals person to enter elevator Bell Light Building increments the time, gets the time, provides the time to the scheduler, provides the time to the elevator 2000 Deitel & Associates, Inc. All rights reserved. 36 Creating Collaborations • Creating Collaborations – Examine list of verbs – "resets elevator button" in class Elevator – To do this: • Elevator object sends resetButton message to ElevatorButton object • This invokes resetButton operation • Next slide – List of all collaborations that can be taken from our table of verb phrases 2000 Deitel & Associates, Inc. All rights reserved. 37 Creating Collaborations (II) An o b jec t o f c la ss Send s the m essa g e To a n o b jec t o f c la ss Elevator resetButton ringBell elevatorArrived openDoor closeDoor ElevatorButton Bell Floor Door Door Scheduler stepOntoFloor isOccupied Person pressButton pressButton passengerEnters passengerExits personArrives Floor resetButton turnOff turnOn Person Floor FloorButton ElevatorButton Elevator Elevator Floor FloorButton Light Light FloorButton summonElevator Elevator ElevatorButton prepareToLeave Door exitElevator enterElevator Elevator Person Person tick getTime processTime processTime Clock Clock Scheduler Elevator Clock Bell Light Building 2000 Deitel & Associates, Inc. All rights reserved. 38 Collaboration Diagrams • Collaboration diagrams – Model interaction of objects – Focus on which objects participate in interactions – Similar to sequence diagrams, but sequence diagrams focus on when interactions occur • Format – Rectangle - represents object, has name inside – Solid lines - connect collaborating objects • Message passed along direction shown by arrows • Name of message by arrow – Sequence of messages - numerical ordering of messages 2000 Deitel & Associates, Inc. All rights reserved. 39 4.2: Door sends message to waitingperson 3: Elevator 4: Elevator notifies opensfloor doorofenterElevator arrival 5.4 Collaboration Diagrams 4.1: Door 4.2.1 sends passengerEnters exitElevator message to passenger 3.1: Floor resets its button 1: Elevator resets button passengerExits 3.2:4.1.1 Floor (This turns sequence on its light ensures that a person exits before another enters) 2: Elevator rings bell : FloorButton : Light 3.1: resetButton( ) 3.2: turnOn( ) : Floor 3: elevatorArrived( ) 4.2.1: passengerEnters( ) waitingPassenger : Person 4.1.1: passengerExits( ) : Elevator passenger : Person 1: resetButton( ) 2: ringBell( ) : Bell : ElevatorButton 4: openDoor( ) 4.2: enterElevator( ) 4.1: exitElevator( ) : Door 2000 Deitel & Associates, Inc. All rights reserved. 40 Summary • Reasonably complete listing of classes – Chapter 6 - implement large portion of simulator – Chapter 7 - implement complete, working simulator – Chapter 9 - discuss inheritance • Summary of object-oriented design process 0. Analysis phase - meet with clients, gather information • Create use cases to describe how users interact with system • In this example, began with problem statement (no analysis phase) 1. Classes - locate classes by listing nouns in problem statement • Eliminate nouns that are attributes of classes, and nouns that are not part of the system • Create a diagram that models classes and associations 2000 Deitel & Associates, Inc. All rights reserved. 41 Summary • Summary of OOD process (continued) 2. Attributes - extract attributes by listing words that describe classes 3. Dynamic Nature - create statechart diagrams to learn how classes change over time 4. Operations - examine verbs associated with each class • Extract operations • Use activity diagrams to model details of operations 5. Collaborations - examine interactions between objects • Use sequence and collaboration diagrams • Add attributes and operations as needed • Design – We are probably missing a few pieces – This will become apparent as we implement the simulator in Chapter 6 2000 Deitel & Associates, Inc. All rights reserved.