Download - Array, Pointer and Reference ( IV )
Array, Pointer and Reference ( IV )
Ying Wu Electrical & Computer Engineering
Northwestern [email protected]
ECE230 Lectures Series
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 stringschar *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[3]
suit[2]
suit[1]
suit[0] ’H’ ’e’ ’a’ ’r’ ’t’ ’s’ ’\0’
’D’ ’i’ ’a’ ’m’ ’o’ ’n’ ’d’ ’s’ ’\0’
’C’ ’l’ ’u’ ’b’ ’s’ ’\0’
’S’ ’p’ ’a’ ’d’ ’e’ ’s’ ’\0’
Multiple-Subscripted Arrays• Multiple subscripts - tables with rows, columns
– Like matrices: specify row, then column.
• Initializeint b[ 2 ][ 2 ] = { { 1, 2 }, { 3, 4 } };
– Initializers grouped by row in bracesint b[ 2 ][ 2 ] = { { 1 }, { 3, 4 } };
• How to reference an element – b[row][col], e.g., b[0][1]
Row 0
Row 1
Row 2
Column 0 Column 1 Column 2 Column 3a[ 0 ][ 0 ]
a[ 1 ][ 0 ]
a[ 2 ][ 0 ]
a[ 0 ][ 1 ]
a[ 1 ][ 1 ]
a[ 2 ][ 1 ]
a[ 0 ][ 2 ]
a[ 1 ][ 2 ]
a[ 2 ][ 2 ]
a[ 0 ][ 3 ]
a[ 1 ][ 3 ]
a[ 2 ][ 3 ]
Row subscript
Array name
Column subscript
1 2
3 4
1 0
3 4
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[0][2]
a[1][0]
a[2][0]
a[1][2]
a[1][1]
a[2][2]
a[2][1]
a[3][2]
a[3][1]
a[3][0]
a[0]
a[1]
a[2]
a[3]
a
1. Initialize variables
1.1 Define functions to take double scripted
arrays
1.2 Initialize studentgrades[][]
2. Call functions minimum, maximum,
and average
1 // Fig. 4.23: fig04_23.cpp2 // Double-subscripted array example3 #include <iostream>45 using std::cout;6 using std::endl;7 using std::ios;89 #include <iomanip>1011 using std::setw;12 using std::setiosflags;13 using std::setprecision;1415 const int students = 3; // number of students16 const int exams = 4; // number of exams1718 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 );2223 int main()24 {25 int studentGrades[ students ][ exams ] = 26 { { 77, 68, 86, 73 },27 { 96, 87, 89, 78 },28 { 70, 90, 86, 81 } };2930 cout << "The array is:\n";31 printArray( studentGrades, students, exams );32 cout << "\n\nLowest grade: "33 << minimum( studentGrades, students, exams )
Each row is a particular student, each column is the grades on the exam.
2. Call functions minimum,
maximum, and average
3. Define functions
34 << "\nHighest grade: "35 << maximum( studentGrades, students, exams ) << '\n';3637 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;4243 return 0;44 }4546 // Find the minimum grade47 int minimum( int grades[][ exams ], int pupils, int tests )48 {49 int lowGrade = 100;5051 for ( int i = 0; i < pupils; i++ )5253 for ( int j = 0; j < tests; j++ )5455 if ( grades[ i ][ j ] < lowGrade )56 lowGrade = grades[ i ][ j ];5758 return lowGrade;59 }6061 // Find the maximum grade62 int maximum( int grades[][ exams ], int pupils, int tests )63 {64 int highGrade = 0;6566 for ( int i = 0; i < pupils; i++ )
6768 for ( int j = 0; j < tests; j++ )6970 if ( grades[ i ][ j ] > highGrade )71 highGrade = grades[ i ][ j ];7273 return highGrade;74 }7576 // Determine the average grade for a particular student77 double average( int setOfGrades[], int tests )78 {79 int total = 0;8081 for ( int i = 0; i < tests; i++ )82 total += setOfGrades[ i ];8384 return static_cast< double >( total ) / tests;85 }8687 // Print the array88 void printArray( int grades[][ exams ], int pupils, int tests ) 89 {90 cout << " [0] [1] [2] [3]";9192 for ( int i = 0; i < pupils; i++ ) {93 cout << "\nstudentGrades[" << i << "] ";9495 for ( int j = 0; j < tests; j++ )96 cout << setiosflags( ios::left ) << setw( 5 ) 97 << grades[ i ][ j ];98 }99 }
3. Define functions
Program Output
The array is: [0] [1] [2] [3]studentGrades[0] 77 68 86 73studentGrades[1] 96 87 89 78studentGrades[2] 70 90 86 81 Lowest grade: 68Highest grade: 96The average grade for student 0 is 76.00The average grade for student 1 is 87.50The average grade for student 2 is 81.75
Arrays of Pointers• Arrays can contain pointers
– Commonly used to store an array of stringschar *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[3]
suit[2]
suit[1]
suit[0] ’H’ ’e’ ’a’ ’r’ ’t’ ’s’ ’\0’
’D’ ’i’ ’a’ ’m’ ’o’ ’n’ ’d’ ’s’ ’\0’
’C’ ’l’ ’u’ ’b’ ’s’ ’\0’
’S’ ’p’ ’a’ ’d’ ’e’ ’s’ ’\0’
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
Hearts
Diamonds
Clubs
Spades
0
1
2
3
Ace Two Three Four Five Six Seven Eight Nine Ten Jack Queen King0 1 2 3 4 5 6 7 8 9 10 11 12
Clubs King
Card Shuffling/Dealing Simulation
• Pseudocode for shuffling and dealingsimulation
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
Choose slot of deck randomly
While chosen slot of deck has been previously chosen
Choose slot of deck randomlyPlace card number in chosen slot of deck
For each slot of the deck array
If slot contains card number Print the face and suit of the card
Second refinement
Third refinement
First refinement
Initialize the suit array
Initialize the face array
Initialize the deck array
Shuffle the deck
Deal 52 cards
Note: This design is bad. WHY? Can you do better?
1. Initialize suit and face arrays
1.1 Initialize deck array
2. Call function shuffle
2.1 Call function deal
1 // Fig. 5.24: fig05_24.cpp2 // Card shuffling dealing program3 #include <iostream>45 using std::cout;6 using std::ios;78 #include <iomanip>910 using std::setw;11 using std::setiosflags;1213 #include <cstdlib>14 #include <ctime>1516 void shuffle( int [][ 13 ] );17 void deal( const int [][ 13 ], const char *[], const char *[] );1819 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 };2829 srand( time( 0 ) );3031 shuffle( deck );32 deal( deck, face, suit );33
34 return 0;35 }3637 void shuffle( int wDeck[][ 13 ] )38 {39 int row, column;4041 for ( int card = 1; card <= 52; card++ ) {42 do {43 row = rand() % 4;44 column = rand() % 13;45 } while( wDeck[ row ][ column ] != 0 );4647 wDeck[ row ][ column ] = card;48 }49 }5051 void deal( const int wDeck[][ 13 ], const char *wFace[],52 const char *wSuit[] )53 {54 for ( int card = 1; card <= 52; card++ )5556 for ( int row = 0; row <= 3; row++ )5758 for ( int column = 0; column <= 12; column++ )5960 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 }
3. Define functions
The numbers 1-52 are randomly placed into the deck array.
Searches deck for the card number, then prints the face and suit.
Note: This is not an efficient design! Why? Can you do better?
Program Output
Six of Clubs Seven of Diamonds Ace of Spades Ace of Diamonds Ace of Hearts Queen of DiamondsQueen 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 SpadesEight of Hearts Three of Diamonds Nine of Hearts Three of HeartsDeuce of Spades Six of Hearts Five of Clubs Eight of ClubsDeuce of Diamonds Eight of Spades Five of Spades King of Clubs King of Diamonds Jack of SpadesDeuce of Hearts Queen of Hearts Ace of Clubs King of SpadesThree of Clubs King of Hearts Nine of Clubs Nine of Spades Four of Hearts Queen of SpadesEight 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
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 Examplebool 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 100double gVarDB_Value[SIZE_DB];char* gVarDB_Name[SIZE_DB];int gVarDB_Size; // the size of the DB
// Initialize the system variable DBvoid VarDB_Init();
// set name to one in the DBbool VarDB_SetVarName(const int& index, const char* name);
// search variable according to its namebool VarDB_Search(const char* name, int& index);
// create a new varible given a namebool VarDB_CreateANewVar(const char*name, int& index);
// dump the DBvoid 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;
}
}