230 likes | 344 Views
ECE230 Lectures Series. Array, Pointer and Reference ( IV ). Ying Wu Electrical & Computer Engineering Northwestern University yingwu@ece.northwestern.edu. We’ve got a lot of stuff!. Regular variables and references Pointers Array Function
E N D
ECE230 Lectures Series Array, Pointer and Reference ( IV ) Ying Wu Electrical & Computer Engineering Northwestern University yingwu@ece.northwestern.edu
We’ve got a lot of stuff! • Regular variables and references • Pointers • Array • Function • Any combination of these leads to a new stuff! • Pointer + function passing pointers to a function • Ref. + function passing references to a function • Array + function passing an array to a function • Pointer + array ?? • Array + array ?? • Pointer + pointer ??
What to learn today? • 2D array (or matrix) • Array of pointers
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 array has a fixed size, but strings can be of any size suit[0] ’H’ ’e’ ’a’ ’r’ ’t’ ’s’ ’\0’ ’D’ ’i’ ’a’ ’m’ ’o’ ’n’ ’d’ ’s’ ’\0’ suit[1] ’C’ ’l’ ’u’ ’b’ ’s’ ’\0’ suit[2] ’S’ ’p’ ’a’ ’d’ ’e’ ’s’ ’\0’ suit[3]
Column 0 Column 1 Column 2 Column 3 a[ 0 ][ 0 ] a[ 0 ][ 1 ] a[ 0 ][ 2 ] a[ 0 ][ 3 ] Row 0 a[ 1 ][ 0 ] a[ 1 ][ 1 ] a[ 1 ][ 2 ] a[ 1 ][ 3 ] Row 1 a[ 2 ][ 0 ] a[ 2 ][ 1 ] a[ 2 ][ 2 ] a[ 2 ][ 3 ] Row 2 Column subscript Array name Row subscript 1 0 3 4 1 2 3 4 Multiple-Subscripted Arrays • Multiple subscripts - tables with rows, columns • Like matrices: specify row, then column. • Initialize int b[ 2 ][ 2 ] = { { 1, 2 }, { 3, 4 } }; • Initializers grouped by row in braces int b[ 2 ][ 2 ] = { { 1 }, { 3, 4 } }; • How to reference an element • b[row][col], e.g., b[0][1]
Multiple-Subscripted Arrays • How is a 2D array stored in memory? • int a[4][3]; • Row-first order • a is an array of pointers, *a[4], • **a = ? a + 1 = ? • a[0] + 1 = ? • *(a[0] + 1) = ? • Initialization int b[2][2] = {(1,2},{3,4}}; int b[2][2] = {1,2,3,4}; Int b[2][2] = {0}; • How to pass a 2-D array to a function? • int myfun(int a[][3], int row, int col); • Why? a[0][0] a[0][1] a a[0][2] a[1][0] a[0] a[1][1] a[1] a[1][2] a[2] a[2][0] a[3] a[2][1] a[2][2] a[3][0] a[3][1] a[3][2]
1 // Fig. 4.23: fig04_23.cpp 2 // Double-subscripted array example Each row is a particular student, each column is the grades on the exam. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 using std::ios; 8 9 #include <iomanip> 10 11 using std::setw; 12 using std::setiosflags; 13 using std::setprecision; 14 15 const int students = 3; // number of students 16 const int exams = 4; // number of exams 17 18 int minimum( int [][ exams ], int, int ); 19 int maximum( int [][ exams ], int, int ); 20 double average( int [], int ); 21 void printArray( int [][ exams ], int, int ); 22 23 int main() 24 { 25 int studentGrades[ students ][ exams ] = 26 { { 77, 68, 86, 73 }, 27 { 96, 87, 89, 78 }, 28 { 70, 90, 86, 81 } }; 29 30 cout << "The array is:\n"; 31 printArray( studentGrades, students, exams ); 32 cout << "\n\nLowest grade: " 33 << minimum( studentGrades, students, exams ) 1. Initialize variables 1.1 Define functions to take double scripted arrays 1.2 Initialize studentgrades[][] 2. Call functions minimum, maximum, and average
34 << "\nHighest grade: " 35 << maximum( studentGrades, students, exams ) << '\n'; 36 37 for ( int person = 0; person < students; person++ ) 38 cout << "The average grade for student " << person << " is " 39 << setiosflags( ios::fixed | ios::showpoint ) 40 << setprecision( 2 ) 41 << average( studentGrades[ person ], exams ) << endl; 42 43 return 0; 44 } 45 46 // Find the minimum grade 47 int minimum( int grades[][ exams ], int pupils, int tests ) 48 { 49 int lowGrade = 100; 50 51 for ( int i = 0; i < pupils; i++ ) 52 53 for ( int j = 0; j < tests; j++ ) 54 55 if ( grades[ i ][ j ] < lowGrade ) 56 lowGrade = grades[ i ][ j ]; 57 58 return lowGrade; 59 } 60 61 // Find the maximum grade 62 int maximum( int grades[][ exams ], int pupils, int tests ) 63 { 64 int highGrade = 0; 65 66 for ( int i = 0; i < pupils; i++ ) 2. Call functions minimum, maximum, and average 3. Define functions
67 68 for ( int j = 0; j < tests; j++ ) 69 70 if ( grades[ i ][ j ] > highGrade ) 71 highGrade = grades[ i ][ j ]; 72 73 return highGrade; 74 } 75 76 // Determine the average grade for a particular student 77 double average( int setOfGrades[], int tests ) 78 { 79 int total = 0; 80 81 for ( int i = 0; i < tests; i++ ) 82 total += setOfGrades[ i ]; 83 84 returnstatic_cast< double >( total ) / tests; 85 } 86 87 // Print the array 88 void printArray( int grades[][ exams ], int pupils, int tests ) 89 { 90 cout << " [0] [1] [2] [3]"; 91 92 for ( int i = 0; i < pupils; i++ ) { 93 cout << "\nstudentGrades[" << i << "] "; 94 95 for ( int j = 0; j < tests; j++ ) 96 cout << setiosflags( ios::left ) << setw( 5 ) 97 << grades[ i ][ j ]; 98 } 99 } 3. Define functions
The array is: [0] [1] [2] [3] studentGrades[0] 77 68 86 73 studentGrades[1] 96 87 89 78 studentGrades[2] 70 90 86 81 Lowest grade: 68 Highest grade: 96 The average grade for student 0 is 76.00 The average grade for student 1 is 87.50 The average grade for student 2 is 81.75 Program Output
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 array has a fixed size, but strings can be of any size suit[0] ’H’ ’e’ ’a’ ’r’ ’t’ ’s’ ’\0’ ’D’ ’i’ ’a’ ’m’ ’o’ ’n’ ’d’ ’s’ ’\0’ suit[1] ’C’ ’l’ ’u’ ’b’ ’s’ ’\0’ suit[2] ’S’ ’p’ ’a’ ’d’ ’e’ ’s’ ’\0’ suit[3]
Ace Two Three Four Five Six Seven Eight Nine Ten Jack Queen King 0 1 2 3 4 5 6 7 8 9 10 11 12 0 Hearts 1 Diamonds 2 Clubs 3 Spades King Clubs Card Shuffling/Dealing Simulation • Card shuffling program • Use an array of pointers to strings, to store suit names • Use a double scripted array (suit by value) • Place 1-52 into the array to specify the order in which the cards are dealt deck[2][12] represents the King of Clubs
Card Shuffling/Dealing Simulation Third refinement • Pseudocode for shuffling and dealingsimulation • 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 First refinement Second refinement • Initialize the suit array • Initialize the face array • Initialize the deck array • Shuffle the deck • Deal 52 cards • For each of the 52 cards • Place card number in randomly selected unoccupied slot of deck • For each of the 52 cards • Find card number in deck array and print face and suit of card • For each slot of the deck array • If slot contains card number Print the face and suit of the card Note: This design is bad. WHY? Can you do better?
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 ); 33 1. Initialize suit and face arrays 1.1 Initialize deck array 2. Call function shuffle 2.1 Call function deal
34 return 0; The numbers 1-52 are randomly placed into the deck array. 35 } 36 Searches deck for the card number, then prints the face and suit. 37 void shuffle( int wDeck[][ 13 ] ) 38 { 39 int row, column; 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 { 54 for ( int card = 1; card <= 52; card++ ) 55 56 for ( int row = 0; row <= 3; row++ ) 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' ); 66 } Note: This is not an efficient design! Why? Can you do better? 3. Define functions
Six of Clubs Seven of Diamonds Ace of Spades Ace of Diamonds Ace of Hearts Queen of Diamonds Queen of Clubs Seven of Hearts Ten of Hearts Deuce of Clubs Ten of Spades Three of Spades Ten of Diamonds Four of Spades Four of Diamonds Ten of Clubs Six of Diamonds Six of Spades Eight of Hearts Three of Diamonds Nine of Hearts Three of Hearts Deuce of Spades Six of Hearts Five of Clubs Eight of Clubs Deuce of Diamonds Eight of Spades Five of Spades King of Clubs King of Diamonds Jack of Spades Deuce of Hearts Queen of Hearts Ace of Clubs King of Spades Three of Clubs King of Hearts Nine of Clubs Nine of Spades Four of Hearts Queen of Spades Eight of Diamonds Nine of Diamonds Jack of Diamonds Seven of Clubs Five of Hearts Five of Diamonds Four of Clubs Jack of Hearts Jack of Clubs Seven of Spades Program Output
Name Database • Task: to create a name database, in which each entry is a name of a variable, e.g., “var_1”, “a”, … • How to search an entry given a name?
A Toy Example bool Search(const char*, int&); char *g_nameDB[4]; void main() { g_nameDB[0] = “a”; g_nameDB[1] = “var_1”; g_nameDB[2] = “xyz”; g_nameDB[4] = “temp”; char query[100]; cin.getline(query,100); int ind; if(Search(query, ind)){ cout << “Found “ << g_nameDB[ind]); else cout << “was not found!” << endl; } bool Search(const char* q, int& index) { bool isFound = false; for(int k=0;k<4;k++){ if( !strcmp(g_nameDB[k], q)){ index = k; isFound = true; break; } } return isFound; }
Question to think about? • To create a Variable DB • To hold the names/values of variables • Given the name of a variable, search the DB to find the corresponding value?
Real stuff: VarDB #define SIZE_DB 100 double gVarDB_Value[SIZE_DB]; char* gVarDB_Name[SIZE_DB]; int gVarDB_Size; // the size of the DB // Initialize the system variable DB void VarDB_Init(); // set name to one in the DB bool VarDB_SetVarName(const int& index, const char* name); // search variable according to its name bool VarDB_Search(const char* name, int& index); // create a new varible given a name bool VarDB_CreateANewVar(const char*name, int& index); // dump the DB void VarDB_Dump();
void VarDB_Init() { // the first one is reserved for "ans" gVarDB_Size = 1; for(int i=0; i<SIZE_DB; i++){ gVarDB_Value[i] = 0.0; gVarDB_Name[i] = NULL; } VarDB_SetVarName(0,"ans"); } bool VarDB_SetVarName(const int& index, const char* name) { assert(index < gVarDB_Size); bool code = true; if(gVarDB_Name[index]!=NULL){ if(strlen(gVarDB_Name[index])!=0) { delete [] gVarDB_Name[index]; } } gVarDB_Name[index] = new char [strlen(name) + 1]; if(gVarDB_Name[index]){ strcpy(gVarDB_Name[index], name); } else code = false; return code; }
bool VarDB_Search(const char* name, int& index) { bool code = false; for(int i=0; i<gVarDB_Size; i++){ if(!strcmp(gVarDB_Name[i], name)){ index = i; code = true; break; } } return code; } bool VarDB_CreateANewVar(const char*name, int& index) { bool code = false; if(gVarDB_Size < SIZE_DB){ gVarDB_Size ++; VarDB_SetVarName(gVarDB_Size-1,name); gVarDB_Value[gVarDB_Size-1] = 0.0; index = gVarDB_Size -1; code = true; } return code; }
void VarDB_Dump() { cout.setf(ios::left, ios::adjustfield); for(int i=0; i<gVarDB_Size; i++){ cout << " " << setw(20) << gVarDB_Name[i] << setw(15) << gVarDB_Value[i] << endl; } }