C Pointers: Solutions
7
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
Chap Ch apte terr 7
254
C Po Poin inte ters rs:: So Solu luti tion onss
Self-Review Exercises 7.1
7.2
Answer each of the following: a) A point pointer er variab variable le conta contains ins as its value the of anoth another er varia variable. ble. AN S: address. b) The thre threee values that can be used to initia initialize lize a pointer pointer are , or a(n) . AN S: 0, NULL, an address. c) The only intege integerr that can be assign assigned ed to a point pointer er is . AN S: 0.
,
State whether the following are true true or or false false . If the answer is false is false , explain why. a) Th Thee addr address ess op oper erat ator or (&) can be applied only to constants, to expressions and to variables declared with the storage-class register. AN S: False. The address operator can be applied only to variables. The address operator cannot be applied to variables declared with storage class register. b) A pointer pointer tha thatt is dec declar lared ed to be void can be dereferenced. AN S: False. A pointer to void cannot be dereferenced, because there is no way to know exactly how many bytes of memory to dereference. c) Pointer Pointerss of different different types types may not be assigne assigned d to one another another without without a cast cast operation. operation. AN S: False. Pointers of type void can be assigned pointers of other types, and pointers of type void can be assigned to pointers of other types.
Answer each of the following. Assume that single-precision floating-point numbers are stored in 4 bytes, and that the starting address of the array is at location 1002500 in memory. Each part of the exercise should use the results of previous parts where appropriate. a) De Defin finee an an arr array ay of ty type pe float called numbers with 10 elements, and initialize the elements to the values 0.0, 1.1, 2.2, …, 9.9. Assume the symbolic constant SIZE has been defined as 10. 7.3
float numbers[ SIZE ] = { 0.0 0.0, , 1.1 1.1, , 2.2 2.2, , 3.3 3.3, , 4.4 4.4, , 5.5 5.5, , 6.6 6.6, , 7.7 7.7, , 8.8 8.8, , 9.9 }; b) De Defi fine ne a poi point nter er,, nPtr, that points to an object of type float. AN S: float *nPtr; c) Pri Print nt the the ele elemen ments ts of of array array numbers using array subscript notation. Use a for statement AN S:
and assume the integer control variable i has been defined. Print each number with 1 position of precision to the right of the decimal point. AN S:
for ( i = 0; i < SIZE SIZE; ; i++ ) printf( "%.1f ", numbers[ i ] );
d) Give two separate separate statement statementss that assign assign the starting starting address address of array array numbers to the pointer variable nPtr. AN S:
nPtr = numbers; nPtr = &numbers[ 0 ];
e) Pr Print int th thee eleme element ntss of arr array ay numbers using pointer/offset notation with the pointer nPtr. AN S:
for ( i = 0; i < SIZE SIZE; ; i++ ) printf( "%.1f ", " , *( nPtr + i ) );
f) Print Print th thee elem elemen ents ts of ar arra ray y numbers using pointer/offset notation with the array name as the pointer. for ( i = 0; i < SIZE SIZE; ; i++ ) printf( "%.1f ", " , *( numbers + i ) ); Print Pri nt the ele element mentss of of arra array y numbers by subscripting
AN S:
g)
AN S:
pointer nPtr.
for ( i = 0; i < SIZE SIZE; ; i++ ) printf( "%.1f ", nPtr[ i ] );
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
Self-Review Exercises
255
h) Refer Refer to to eleme element nt 4 of arra array y numbers using array subscript notation, pointer/offset notation with the array name as the pointer, pointer subscript notation with nPtr and pointer/offset notation with nPtr. AN S:
numbers[ 4 ] *( numbers + 4 ) nPtr[ 4 ] *( nPtr + 4 )
i) Ass Assuming th that nPtr points to the beginning of array numbers, what address is referenced by nPtr + 8? What value is stored at that location? AN S: The address is 1002500 + 8 * 4 = 1002532. The value is 8.8. j) Assuming that nPtr points to nu numb mber ers[ s[ 5 ], what address is referenced by nPtr –= 4. What is the value stored at that location? AN S: The address of numbers[ 5 ] is 1002500 + 5 * 4 = 1002520. The address of nPtr -= 4 is 1002520 - 4 * 4 = 1002504. The value at that location is 1.1. For each of the following, write a statement that performs the indicated task. Assume that floating-point variables number1 and number2 are defined and that number1 is initialized to 7.3. a) De Defi fine ne th the vari variab able le fPtr to be a pointer to an object of type float. 7.4
AN S:
float *fPtr;
b) Ass Assign ign the the addr address ess of of varia variable ble number1 to pointer variable fPtr. AN S:
fPtr = &number1;
c) Prin Printt the the value value of the the objec objectt point pointed ed to by by fPtr. printf( "The value of *fPtr is %f\n" , *fPtr ); Assign Assig n the value of the the object object pointe pointed d to by fPtr to variable number2.
AN S:
d)
AN S:
number2 = *fPtr;
e) Pr Prin intt the the va valu luee of of number2. AN S:
printf( "The value of number2 is %f\n" , number2 );
f) Pr Prin intt the the ad addr dres esss of of number1. Use the %p conversion specifier. AN S:
printf( "The address of number1 is %p\n" , &number1 );
g) Print Print the the add addres resss stor stored ed in fPtr. Use the %p conversion specifier. Is the value printed the same as the address of number1? AN S:
printf( "The address stored in fptr is %p\n" , fPtr );
Yes, the value is the same. same. 7.5
Do each of the following: a) Write the funct function ion header header for a functio function n called called exchange that takes two pointers to floating-point numbers x and y as parameters and does not return a value. AN S:
void exchange( float *x, float *y )
b) Write the the function function protot prototype ype for the function function in part part (a). (a). AN S:
void exchange( float *x, float *y );
c) Write Write the func functio tion n header header for for a functio function n called called evaluate that returns an integer and that takes as parameters integer x and a pointer to function poly. Function poly takes an integer parameter and returns an integer. i nteger. AN S:
int evaluate( int x, int (*poly)( int ) )
d) Write the the function function protot prototype ype for the function function in part part (c). (c). AN S:
7.6
int evaluate( int x, int (*poly)( int ) );
Find the error in each of the following program segments. Assume int *zPtr; /* zPtr will reference array z */ int *aPtr = NULL; void *sPtr = NULL; int number, i;
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
Chap Ch apte terr 7
256
C Po Poin inte ters rs:: So Solu luti tion onss
int z[ 5 ] = { 1, 2, 3, 4, 5 }; zPtr = z;
a)
++zptr;
AN S:
b)
Error: zPtr has not been initialized. Correction: Initialize zPtr with zPtr = z; before performing the pointer arithmetic.
/* use pointer to get first value of array; assume zPtr is initialized */ number = zPtr;
AN S:
c)
Error: The pointer is not dereferenced. Correction: Change the statement to number = *zPtr;
/* assign array element 2 (the value 3) to number; assume zPtr is initialized */ number = *zPtr[ 2 ];
AN S:
d)
Error: zPtr[ 2 ] is not a pointer and should not be dereferenced. Correction: Change *zPtr[ 2 ] to zPtr[ 2 ].
/* print entire array z; assume zPtr is initialized */ for ( i = 0; i <= 5; i++ ) printf( "%d ", " , zPtr[ i ] );
AN S:
e)
Error: Referring to an array element outside the array bounds with pointer subscripting. Correction: Change the operator <= in the for condition to <.
/* assign the value pointed to by sPtr to number */ number = *sPtr;
AN S:
f)
Error: Dereferencing a void pointer. Correction: In order to dereference the pointer, it must first be cast to an integer pointer. Change the statement to number = *( ( int * ) sPtr );
++z;
AN S:
Error: Trying to modify an array name with pointer arithmetic. Correction: Use a pointer variable instead of the array name to accomplish pointer arithmetic, or subscript the array name to refer to a specific e lement.
Exercises 7.7
Answer each of the following: a) The operator opera tor retur returns ns the locati location on in memor memoryy wher wheree its opera operand nd is store stored. d. AN S: address ( &). b) The operator opera tor retur returns ns the value of the objec objectt to which its opera operand nd point points. s. AN S: indirection (*). c) To simulate simulate call-by-ref call-by-reference erence when when passing passing a nonarray variable variable to to a function, function, it is necessary to pass the of the variable to the function. AN S: address.
7.8
State whether the following are true true or or false false . If false false , explain why. a) Two pointers pointers that that point to to different different arrays arrays cannot cannot be compared compared meaningfully meaningfully.. AN S: True. It is not possible to know where these arrays will be stored in advance. b) Becaus Becausee the name of an array is a pointer pointer to the first element element of the the array, array array names names may be manipulated in precisely the same manner as pointers. AN S: False. Array names cannot be modified to point to another location in memory.
Answer each of the following. Assume that that unsigned integers are are stored in 2 bytes and that the starting address of the array is at location 1002500 in memory. 7.9
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
Exercises
257
a) Defin Definee an an arr array ay of ty type pe unsigned int called values with five elements, and initialize the elements to the even integers from 2 to 10. Assume the symbolic constant SIZE has been defined as 5. unsigned int values[ SIZE ] = { 2, 4, 6, 8, 10 }; Defi De fine ne a poi point nter er vPtr that points to an object of type unsigned int.
AN S:
b)
AN S:
unsigned int *vPtr;
c) Print Print th thee elem elemen ents ts of of arra array y values using array subscript notation. Use a for statement and assume integer control variable i has been defined. AN S:
for ( i = 0; i < SIZE SIZE; ; i++ ) printf( “%d ”, ”, values[ i ] );
d) Give two separat separatee statements statements that that assign assign the starting starting address address of array array values to pointer variable vPtr. AN S:
1) vPtr = values; 2) vPtr = &values[ 0 ];
e) Pr Print int th thee elem elemen ents ts of of arra array y values using pointer/offset notation. AN S:
for
( i = 0; i < SIZE SIZE; ; i++ ) printf( “%d” “%d”, , *( vPtr + i ) );
f) Print Print th thee eleme element ntss of of arr array ay values using pointer/offset notation with the array name as the pointer. AN S:
for
( i = 0; i < SIZE SIZE; ; i++ ) printf( “%d” “%d”, , *( values + i ) );
g) Pri Print nt the ele element mentss of of arra array y values by subscripting the pointer to the array. AN S:
for
( i = 0; i < SIZE SIZE; ; i++ ) printf( “%d” “%d”, , vPtr[ i ] );
h) Refe Referr to to ele eleme ment nt 5 of array values using array subscript notation, pointer/offset notation with the array name as the pointer, pointer subscript notation, and pointer/offset notation. AN S:
values[ 4 ], *( values + 4 ), vPtr[ 4 ], *( vPtr + 4 ).
i) Wh What at add addre ress ss is is refer referen ence ced d by vPtr + 3? What value is stored at that location? AN S:
1002506; 8.
j) Assuming vPtr points to va valu lue es[ 4 ], what address is referenced by vPtr value is stored at that location? AN S:
-= 4.
What
1002500; 2.
For each of the following, write a single si ngle statement that performs the indicated task. Assume that long integer variables value1 and value2 have been defined and that value1 has been initialized to 200000. a) De Defi fine ne th the vari variab able le lPtr to be a pointer to an object of type long. 7.10
AN S:
long *lPtr;
b) Ass Assign ign the the addr address ess of of varia variable ble value1 to pointer variable lPtr. AN S:
lPtr = &value1;
c) Prin Printt the the value value of the the objec objectt point pointed ed to by by lPtr. AN S:
printf( “%ld\n” “%ld\n”, , *lPtr );
d) Assig Assign n the value of the the object object pointe pointed d to by lPtr to variable value2. AN S:
value2 = *lPtr;
e) Pr Prin intt the the va valu luee of of value2. AN S:
printf( “%ld\n” “%ld\n”, , value2 ); f) Pr Prin intt the the ad addr dres esss of of value1. AN S: printf( “%p\n” “%p\n”, , &value1 );
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
258
Chapter 7
C Pointers: Solutions
g) Print the address stored in lPtr. Is the value printed the same as the address of value1? AN S:
7.11
printf( “%p\n”, lPtr); /* The value is the same */
Do each of the following: a) Write the function header for function zero, which takes a long integer array parameter bigIntegers and does not return a value. AN S:
void zero( long int *bigIntegers )
b) Write the function prototype for the function in part a. AN S:
void zero( long int *bigIntegers );
c) Write the function header for function add1AndSum, which takes an integer array parameter oneTooSmall and returns an integer. AN S:
int add1AndSum( int *oneTooSmall )
d) Write the function prototype for the function described in part c. AN S:
int add1AndSum( int *oneTooSmall );
Note: Exercise 7.12 through Exercise 7.15 are reasonably challenging. Once you have done these problems, you ought to be able to implement most popular card games easily. (Card Shuffling and Dealing) Modify the program in Fig. 7.24 so that the card-dealing function deals a five-card poker hand. Then write the following additional functions: a) Determine if the hand contains a pair. b) Determine if the hand contains two pairs. c) Determine if the hand contains three of a kind (e.g., three jacks). d) Determine if the hand contains four of a kind (e.g., four aces). e) Determine if the hand contains a flush (i.e., all five cards of the same suit). f) Determine if the hand contains a straight (i.e., five cards of consecutive face values). 7.12
AN S:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
/* Exercise 7.12 Solution */ #include #include #include /* function prototypes */ void shuffle( int deck[][ 13 ] ); void deal(int deck[][ 13 ], int hand[][ 2 ], char *suit[], char *face[] ); void pair( int hand[][ 2 ], char *suit[], char *face[] ); void threeOfKind( int hand[][ 2 ], char *suit[], char *face[] ); void fourOfKind( int hand[][ 2 ], char *suit[], char *face[] ); void straightHand( int hand[][ 2 ], char *suit[], char *face[] ); void flushHand( int hand[][ 2 ], char *suit[], char *face[] ); int main() { char *suit[ 4 ] = { "Hearts", "Diamonds", "Clubs", "Spades" }; char *face[ 13 ] = { "Ace", "Deuce", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Jack", "Queen", "King" }; int deck[ 4 ][ 13 ]; /* represents deck of cards */ int hand[ 5 ][ 2 ]; /* represents hand */ int row, column; /* loop counters */ /* loop through rows of deck */ for ( row = 0; row <= 3; row++ ) {
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
Exercises
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
259
/* loop through columns of deck for current row */ for ( column = 0; column <= 12; column++ ) { deck[ row ][ column ] = 0; /* initialize slot of deck to 0 */ } /* end inner for */ } /* end outer for */ srand( time( NULL ) ); /* seed random number generator */ /* shuffle the deck and deal a 5-card hand */ shuffle( deck ); deal( deck, hand, suit, face ); /* determine the hand's poker value */ pair( hand, suit, face ); threeOfKind( hand, suit, face ); fourOfKind( hand, suit, face ); straightHand( hand, suit, face ); flushHand( hand, suit, face ); return 0; /* indicate successful termination */ } /* end function main */ /* shuffles the deck */ void shuffle( int deck[][ 13 ] ) { int row; /* represents suit value of card */ int column; /* represents face value of card */ int card; /* loop counter */ /* for each of the 52 cards, choose a slot of the deck randomly */ for ( card = 1; card <= 52; card++ ) { do /* choose a new random location until unoccupied slot is found */ { row = rand() % 4; /* randomly select the row */ column = rand() % 13; /* randomly select the column */ } while( deck[ row ][ column ] != 0 ); /* end do...while */ /* place card number in chosen slot of deck */ deck[ row ][ column ] = card; } /* end for */ } /* end function shuffle */ /* deals a poker hand */ void deal( int deck[][ 13 ], int hand[][ 2 ], char *suit[], char *face[] ) { int r = 0; /* counter for position in the hand */ int card, row, column; /* loop counters */ printf( "The hand is:\n" );
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
260
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
Chapter 7
C Pointers: Solutions
/* loop to distrubute the cards */ for ( card = 1; card < 6; card++ ) for ( row = 0; row <= 3; row++ ) for ( column = 0; column <= 12; column++ ) if ( deck[ row ][ column ] == card ) { hand[ r ][ 0 ] = row; hand[ r ][ 1 ] = column; printf( "%5s of %-8s\n", face[ column ], suit[ row ] ); ++r; } /* end if */ printf( "\n" ); } /* end function deal */ /* determines if there are any pairs in the hand */ void pair( int hand[][ 2 ], char *suit[], char *face[] ) { /* counter that records how many cards of each rank are in the hand */ int counter[ 13 ] = { 0 }; int r, p; /* loop counters */ /* record how many cards of each rank are in the hand */ for ( r = 0; r < 5; r++ ) counter[ hand[ r ][ 1 ] ]++; /* print result if there is a pair */ for ( p = 0; p < 13; p++ ) if ( counter[ p ] == 2 ) printf( "The hand contains a pair of %ss.\n", face[ p ] ); } /* end function pair */ /* determines if there is a three of a kind in the hand */ void threeOfKind( int hand[][ 2 ], char *suit[], char *face[] ) { /* counter that records how many cards of each rank are in the hand */ int counter[ 13 ] = { 0 }; int r, t; /* loop counters */ /* record how many cards of each rank are in the hand */ for ( r = 0; r < 5; r++ ) counter[ hand[ r ][ 1 ] ]++; /* print result if there is a three of a kind */ for ( t = 0; t < 13; t++ ) if ( counter[ t ] == 3 ) printf( "The hand contains three %ss.\n", face[ t ] ); } /* end function threeOfKind */
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
Exercises
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
261
/* determines if there is a four of a kind in the hand */ void fourOfKind( int hand[][ 2 ], char *suit[], char *face[] ) { /* counter that records how many cards of each rank are in the hand */ int counter[ 13 ] = { 0 }; int r, k; /* loop counters */ /* record how many cards of each rank are in the hand */ for ( r = 0; r < 5; r++ ) counter[ hand[ r ][ 1 ] ]++; /* print result if there is a pair */ for ( k = 0; k < 13; k++ ) if ( counter[ k ] == 4 ) printf( "The hand contains four %ss.\n", face[ k ] ); } /* end function fourOfKind */ /* determines if there is a straight in the hand */ void straightHand( int hand[][ 2 ], char *suit[], char *face[] ) { int s[ 5 ] = { 0 }; /* array that holds a copy of hand */ int temp; /* temporary integer */ int r, pass, comp, j; /* loop counters */ /* copy column locations to sort */ for ( r = 0; r < 5; r++ ) s[ r ] = hand[ r ][ 1 ]; /* bubble sort column locations */ for ( pass = 1; pass < 5; pass++ ) for ( comp = 0; comp < 4; comp++ ) if ( s[ comp ] > s[ comp + 1 ] ) { temp = s[ comp ]; s[ comp ] = s[ comp + 1 ]; s[ comp + 1 ] = temp; } /* end if */ /* check if sorted columns are a straight */ if ( s[ 4 ] - 1 == s[ 3 ] && s[ 3 ] - 1 == s[ 2 ] && s[ 2 ] - 1 == s[ 1 ] && s[ 1 ] - 1 == s[ 0 ] ) { printf( "The hand contains a straight from %s to %s.\n", face[ s[ 0 ] ], face[ s[ 4 ] ] ); } /* end if */ } /* end function straightHand */ /* determines if there is a flush in the hand */ void flushHand( int hand[][ 2 ], char *suit[], char *face[] ) {
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
Chapter 7
262
190 191 192 193 194 195 196 197 198 199 200 201 202 203
C Pointers: Solutions
/* counter that records how many cards of each suit are in the hand */ int count[ 4 ] = { 0 }; int r, f; /* loop counters */ /* record how many cards of each suit are in the hand */ for ( r = 0; r < 5; r++ ) count[ hand[ r ][ 0 ] ]++; for ( f = 0; f < 4; f++ ) if ( count[ f ] == 5 ) printf( "The hand contains a flush of %ss.\n", suit[ f ] ); } /* end function flushHand */
The hand Deuce of King of Deuce of Deuce of Nine of
is: Diamonds Diamonds Hearts Clubs Spades
The hand contains three Deuces.
The hand Five of Eight of Five of Four of Four of
is: Hearts Diamonds Diamonds Clubs Spades
The hand contains a pair of Fours. The hand contains a pair of Fives.
(Project: Card Shuffling and Dealing) Use the functions developed in Exercise 7.12 to write a program that deals two five-card poker hands, evaluates each hand, and determines which is the better hand. 7.13
(Project: Card Shuffling and Dealing) Modify the program developed in Exercise 7.13 so that it can simulate the dealer. The dealer's five-card hand is dealt “face down” so the player cannot see it. The program should then evaluate the dealer’s hand, and based on the quality of the hand, the dealer should draw one, two or three more cards to replace the corresponding number of unneeded cards in the original hand. The program should then re-evaluate the dealer's hand. [ Caution: This is a difficult problem!] 7.14
(Project: Card Shuffling and Dealing) Modify the program developed in Exercise 7.14 so that it can handle the dealer’s hand automatically, but the player is allowed to decide which cards of the player's hand to replace. The program should then evaluate both hands and determine who wins. Now use this new program to play 20 games against the computer. Who wins more games, you or the computer? Have one of your friends play 20 games against the computer. Who wins more games? Based on the results of these games, make appropriate modifications to refine your poker playing program (this, too, is a difficult problem). Play 20 more games. Does your modified program play a better game? 7.15
(Card Shuffling and Dealing Modification) In the card shuffling and dealing program of Fig. 7.24, we intentionally used an inefficient shuffling algorithm that introduced the possibility of 7.16
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
Exercises
263
indefinite postponement. In this problem, you’ll create a high-performance shuffling algorithm that avoids indefinite postponement. Modify the program of Fig. 7.24 as follows. Begin by initializing the deck array as shown in Fig. 7.29. Modify the shuffle function to loop row-by-row and column-by-column through the array, touching every element once. Each element should be swapped with a randomly selected element of the array. Unshuffled deck array
0 1 2 3
0
1
2
3
4
5
6
7
8
9
10
11
12
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
Fig. 7.29 | Unshuffled deck array. Sample shuffled deck array
0
1
2
3
4
5
6
7
8
9
10
11
12
0
19
40
27
25
36
46
10
34
35
41
18
2
44
1
13
28
14
16
21
30
8
11
31
17
24
7
1
2
12
33
15
42
43
23
45
3
29
32
4
47
26
3
50
38
52
39
48
51
9
5
37
49
22
6
20
Fig. 7.30 | Sample shuffled deck array. Print the resulting array to determine if the deck is satisfactorily shuffled (as in Fig. 7.30, for example). You may want your program to call the shuffle function several times to ensure a satisfactory shuffle. Note that although the approach in this problem improves the shuffling algorithm, the dealing algorithm still requires searching the deck array for card 1, then card 2, then card 3, and so on. Worse yet, even after the dealing algorithm locates and deals the card, the algorithm continues searching through the remainder of the deck. Modify the program of Fig. 7.24 so that once a card is dealt, no further attempts are made to match that card number, and the program immediately proceeds with dealing the next card. In Chapter 10, we develop a dealing algorithm that requires only one operation per card. AN S:
1 2 3 4 5
/* Exercise 7.16 Solution */ #include #include #include
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
264
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
Chapter 7
C Pointers: Solutions
/* function prototypes */ void shuffle( int workDeck[][ 13 ] ); void deal( int workDeck[][ 13 ], char *workFace[], char *workSuit[] ); int main() { int card = 1; int row; int column; int deck[ 4 ][ 13 ];
/* /* /* /*
card counter */ loop counter */ loop counter */ array of cards */
/* define arrays of card suits and faces */ char *suit[ 4 ] = { "Hearts", "Diamonds", "Clubs", "Spades"}; char *face[ 13 ] = { "Ace", "Deuce", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Jack", "Queen", "King" }; srand( time( NULL ) ); /* initialize deck */ for ( row = 0; row <= 3; row++ ) { for ( column = 0; column <= 12; column++ ) { deck[ row ][ column ] = card++; } /* end for */ } /* end for */ shuffle( deck ); deal( deck, face, suit ); return 0; /* indicate successful termination */ } /* end main */ /* introduce another way to shuffle */ void shuffle( int workDeck[][ 13 ] ) { int temp; /* temporary holder */ int row; /* loop counter */ int column; /* loop counter */ int randRow; /* random suit */ int randColumn; /* random face */ /* run through the loop and touch every element once */ for ( row = 0; row <= 3; row++ ) { for ( column = 0; column <= 12; column++ ) { /* generate a random card */ randRow = rand() % 4; randColumn = rand() % 13; /* swap random card with current card */ temp = workDeck[ row ][ column ]; workDeck[ row ][ column ] = workDeck[ randRow ][ randColumn ];
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
Exercises
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
265
workDeck[ randRow ][ randColumn ] = temp; } /* end for */ } /* end for */ } /* end function shuffle */ /* deal the cards */ void deal( int workDeck2[][ 13 { int card; /* card counter int row; /* loop counter int column; /* loop counter
], char *workFace[], char *workSuit[] ) */ */ */
/* loop through and print the cards */ for ( card = 1; card <= 52; card++ ) { /* loop through rows */ for ( row = 0; row <= 3; row++ ) { /* loop through columns */ for ( column = 0; column <= 12; column++ ) { /* if current card equals card, then deal */ if ( workDeck2[ row ][ column ] == card ) { printf("%5s of %-8s", workFace[ column ], workSuit[ row ]); card % 2 == 0 ? putchar( '\n' ) : putchar( '\t' ); break; /* break loop */ } /* end if */ } /* end for */ } /* end for */ } /* end for */ } /* end function deal */
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
Chapter 7
266
Eight Five Eight Deuce Seven Four Six Ten Four Jack Deuce Three Nine King Five Four King Deuce Ace Eight Nine Three Queen Queen Five Jack
of of of of of of of of of of of of of of of of of of of of of of of of of of
Spades Hearts Diamonds Hearts Clubs Clubs Spades Hearts Diamonds Diamonds Spades Hearts Hearts Spades Spades Spades Diamonds Clubs Diamonds Hearts Clubs Clubs Hearts Diamonds Clubs Spades
C Pointers: Solutions
Ace Ace Queen Seven Six Ace Ten King Four Three Queen Six Nine Seven Seven Ten Nine Jack Ten Six Five Deuce King Jack Three Eight
of of of of of of of of of of of of of of of of of of of of of of of of of of
Spades Hearts Spades Hearts Hearts Clubs Diamonds Hearts Hearts Diamonds Clubs Clubs Diamonds Diamonds Spades Spades Spades Hearts Clubs Diamonds Diamonds Diamonds Clubs Clubs Spades Clubs
(Simulation: The Tortoise and the Hare) In this problem, you’ll recreate one of the truly great moments in history, namely the classic race of the tortoise and the hare. You’ll use random number generation to develop a simulation of this memorable event. Our contenders begin the race at “square 1” of 70 squares. Each square represents a possible position along the race course. The finish line is at square 70. The first contender to reach or pass square 70 is rewarded with a pail of fresh carrots and lettuce. The course weaves its way up the side of a slippery mountain, so occasionally the contenders lose ground. There is a clock that ticks once per second. With each tick of the clock, your program should adjust the position of the animals according to the rules of Fig. 7.31. Use variables to keep track of the positions of the animals (i.e., position numbers are 1–70). Start each animal at position 1 (i.e., the “starting gate”). If an animal slips left before square 1, move the animal back to square 1. Generate the percentages in the preceding table by producing a random integer, i, in the range 1 ≤ i ≤ 10. For the tortoise, perform a “fast plod” when 1 ≤ i ≤ 5, a “slip” when 6 ≤ i ≤ 7, or a “slow plod” when 8 ≤ i ≤ 10. Use a similar technique to move the hare. 7.17
Animal
Move type
Percentage of the time
Actual move
Tortoise
Fast plod Slip Slow plod
50% 20% 30%
3 squares to the right 6 squares to the left 1 square to the right
Fig. 7.31 | Tortoise and hare rules for adjusting positions.
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
Exercises
Animal
Move type
Percentage of the time
Actual move
Hare
Sleep Big hop Big slip Small hop Small slip
20% 20% 10% 30% 20%
No move at all 9 squares to the right 12 squares to the left 1 square to the right 2 squares to the left
267
Fig. 7.31 | Tortoise and hare rules for adjusting positions. Begin the race by printing BANG !!!!! AND THEY'RE OFF !!!!!
Then, for each tick of the clock (i.e., each repetition of a loop), print a 70-position line showing the letter T in the position of the tortoise and the letter H in the position of the hare. Occasionally, the contenders will land on the same square. In this case, the tortoise bites the hare and your program should print OUCH!!! beginning at that position. All print positions other than the T, the H, or the OUCH!!! (in case of a tie) should be blank. After each line is printed, test if either animal has reached or passed square 70. If so, then print the winner and terminate the simulation. If the tortoise wins, print TORTOISE WINS!!! YAY!!! If the hare wins, print Hare wins. Yuch. If both animals win on the same tick of the clock, you may want to favor the turtle (the “underdog”), or you may want to print It's a tie. If neither animal wins, perform the loop again to simulate the next tick of the clock. When you are ready to run your program, assemble a group of fans to watch the race. You'll be amazed at how involved your audience gets! AN S:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
/* Exercise 7.17 Solution */ #include #include #include /* function prototypes */ void moveTortoise( int *turtlePtr ); void moveHare( int *rabbitPtr ); void printCurrentPositions( int *snapperPtr, int *bunnyPtr ); int main() { int tortoise = 1; /* tortoise current position */ int hare = 1; /* hare current position */ int timer = 0; /* time elapsed during race */ srand( time( NULL ) ); printf( "ON YOUR MARK, GET SET\n" ); printf( "BANG !!!!\n" ); printf( "AND THEY'RE OFF !!!!\n" );
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
268
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
Chapter 7
C Pointers: Solutions
/* loop through the events */ while ( tortoise != 70 && hare != 70 ) { moveTortoise( &tortoise ); moveHare( &hare ); printCurrentPositions( &tortoise, &hare ); ++timer; } /* end while */ /* determine the winner and print m essage */ if ( tortoise >= hare ) { printf( "\nTORTOISE WINS!!! YAY!!!\n" ); } /* end if */ else { printf( "Hare wins. Yuch.\n" ); } /* end else */ printf( "TIME ELAPSED = %d seconds\n", timer ); return 0; /* indicate successful termination */ } /* end main */ /* progress for the tortoise */ void moveTortoise( int *turtlePtr ) { int x; /* random number */ x = rand() % 10 + 1; /* generate random number from 1-10 */ /* determine progress */ if ( x >= 1 && x <= 5 ) { /* fast plod */ *turtlePtr += 3; } /* end if */ else if ( x == 6 || x == 7 ) { /* slip */ *turtlePtr -= 6; } /* end else if */ else { /* slow plod */ ++( *turtlePtr ); } /* end else */ /* check boundaries */ if ( *turtlePtr < 1 ) { *turtlePtr = 1; } /* end if */ if ( *turtlePtr > 70 ) { *turtlePtr = 70; } /* end if */ } /* end function moveTortoise */ /* progress for the hare */ void moveHare( int *rabbitPtr ) { int y; /* random number */
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
Exercises
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
y = rand() % 10 + 1; /* generate random number from 1-10 */ /* determine progress */ if ( y == 3 || y == 4 ) { /* big hop */ *rabbitPtr += 9; } /* end if */ else if ( y == 5 ) { /* big slip */ *rabbitPtr -= 12; } /* end else if */ else if ( y >= 6 && y <= 8 ) { /* small hop */ ++( *rabbitPtr ); } /* end else if */ else if ( y == 10 ) { /* small slip */ *rabbitPtr -= 2; } /* end else if */ /* check boundaries */ if ( *rabbitPtr < 1 ) { *rabbitPtr = 1; } /* end if */ if ( *rabbitPtr > 70 ) { *rabbitPtr = 70; } /* end if */ } /* end function moveHare */ /* display new position */ void printCurrentPositions( int *snapperPtr, int *bunnyPtr ) { int count; /* counter */ /* loop through race */ for ( count = 1; count <= 70; count++ ) /* print current leader */ if ( count == *snapperPtr && count == *bunnyPtr ) { printf( "OUCH!!!" ); } /* end if */ else if ( count == *bunnyPtr ) { printf( "H" ); } /* end else if */ else if ( count == *snapperPtr ) { printf( "T" ); } /* end else if */ else { printf( " " ); } /* end else */ printf( "\n" ); } /* end function printCurrentPositions */
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
269
270
Chapter 7
C Pointers: Solutions
ON YOUR MARK, GET SET BANG !!!! AND THEY'RE OFF !!!! H T H T T H H T H T H T H T H T H H H
T T T
H H
T T H
T H H
T T
H
T
H H
T T H
T H H H
T T T
H H
T T H H
T T H H
T T
H H
T T H
T H
T T
H H
T
H H
T T H H
T T
H
T H H H
T T T H H
T T H
H
T T
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
Exercises
H
T H H
271
T T
H
T
H H
T T H
T HT
TORTOISE WINS!!! YAY!!! TIME ELAPSED = 55 seconds
(Card Shuffling and Dealing Modification) Modify the card shuffling and dealing program of Fig. 7.24 so the shuffling and dealing operations are performed by the same function ( shuffleAndDeal). The function should contain one nested looping structure that is similar to function shuffle in Fig. 7.24. 7.18
AN S:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
/* Exercise 7.18 Solution */ #include #include #include /* function prototype */ void shuffleAndDeal( int workdeck[][ 13 ], char *workface[], char *worksuit[] ); int main() { /* define card suit array and card face array */ char *suit[ 4 ] = { "Hearts", "Diamonds", "Clubs", "Spades" }; char *face[ 13 ] = {"Ace","Deuce","Three","Four","Five","Six","Seven", "Eight", "Nine", "Ten", "Jack", "Queen", "King" }; int deck[ 4 ][ 13 ] = { 0 }; /* array of cards */ srand( time( NULL ) ); shuffleAndDeal( deck, face, suit ); return 0; /* indicate successful termination */ } /* end main */ /* integrate shuffling and dealing operation */ void shuffleAndDeal( int workdeck[][ 13 ], char *workface[], char *worksuit[] ) { int card; /* card loop counter */ int row; /* current suit */ int column; /* current face */
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
Chapter 7
272
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
/* loop through the deck of cards, shuffle and print */ for ( card = 1; card <= 52; card++ ) { /* choose random card until not equal to zero */ do { row = rand() % 4; column = rand() % 13; } while( workdeck[ row ][ column ] != 0 ); /* end do...while */ workdeck[ row ][ column ] = card; /* deal card */ printf( "%5s of %-8s", workface[ column ], worksuit[ row ] ); card % 2 == 0 ? printf( "\n" ) : printf( "\t" ); } /* end for */ } /* end function shuffleAndDeal */
Seven Six Three Jack Queen Four Six Three Seven Ten Queen Five Deuce Ace Five Deuce Nine King Seven Six Nine Three Four Ten Four Six
7.19 1 2 3
C Pointers: Solutions
of of of of of of of of of of of of of of of of of of of of of of of of of of
Spades Spades Clubs Diamonds Clubs Hearts Clubs Hearts Clubs Hearts Hearts Clubs Spades Clubs Spades Hearts Hearts Clubs Diamonds Hearts Spades Spades Diamonds Spades Clubs Diamonds
King King Three Jack Eight Deuce Eight Five Ace Five Eight Deuce Jack Nine Nine King Queen Four Ace Ten Queen Jack Ace Ten Eight Seven
of of of of of of of of of of of of of of of of of of of of of of of of of of
Diamonds Hearts Diamonds Spades Hearts Clubs Spades Hearts Hearts Diamonds Clubs Diamonds Hearts Diamonds Clubs Spades Spades Spades Diamonds Diamonds Diamonds Clubs Spades Clubs Diamonds Hearts
What does this program do?
/* ex07_19.c */ /* What does this program do? */ #include
4 5
void mystery1( char *s1, const char *s2 ); /* prototype */
6 7 8 9 10
int main( void ) { char string1[ 80 ]; /* create char array */ char string2[ 80 ]; /* create char array */
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
Exercises
11 12 13 14 15 16 17
printf( "Enter two strings: " ); scanf( "%s%s" , string1, string2 ); mystery1( string1, string2 ); printf("%s", string1 ); return 0; /* indicates successful termination */ } /* end main */
18 19 20 21 22 23 24
/* What does this function do? */ void mystery1( char *s1, const char *s2 ) { while ( *s1 != '\0' ) { s1++; } /* end while */
25 26 27 28 29
for ( ; *s1 = *s2; s1++, s2++ ) { ; /* empty statement */ } /* end for */ } /* end function mystery1 */ AN S:
Concatenates strings.
Enter two strings: string1 string2 string1string2
7.20 1 2 3
What does this program do?
/* ex07_20.c */ /* what does this program do? */ #include
4 5
int mystery2( const char *s ); /* prototype */
6 7 8 9
int main( void ) { char string[ 80 ]; /* create char array */
10 11 12 13 14 15
printf( "Enter a string: " ); scanf( "%s", string ); printf( "%d\n", mystery2( string ) ); return 0; /* indicates successful termination */ } /* end main */
16 17 18 19 20
/* What does this function do? */ int mystery2( const char *s ) { int x; /* counter */
21 22 23 24 25
/* loop through string */ for ( x = 0; *s != '\0'; s++ ) { x++; } /* end for */
26 27 28
return x; } /* end function mystery2 */
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
273
Chapter 7
274
AN S:
C Pointers: Solutions
Determines the length of a string.
Enter a string: string1 7
Find the error in each of the following program segments. If the error can be corrected, explain how. a) int *number; 7.21
printf( "%d\n", *number ); AN S:
b)
number
has not been assigned to point to a location in memory.
float *realPtr; long *integerPtr; integerPtr = realPtr;
AN S:
c)
A pointer cannot be assigned to a different type, other than
void *.
int * x, y; x = y;
AN S:
d)
There are two possible solutions. 1) The indirection operator ( *) is not distributive and would be required for y, which would result in a valid pointer assignment. 2) y as it is defined is a valid integer variable, and would require the address operator ( &) in the pointer assignment statement.
char s[] = "this is a character array" ; int count; for ( ; *s != '\0'; s++) printf( "%c ", *s );
AN S:
e)
s
should be defined as char *; a constant pointer cannot be moved.
short *numPtr, result; void *genericPtr = numPtr; result = *genericPtr + 7;
AN S:
f)
A void
*
pointer cannot be dereferenced.
float x = 19.34; float xPtr = &x; printf( "%f\n", xPtr );
AN S:
g)
is not defined as a pointer, so it should not be assigned the value of &x. Either define xPtr as a pointer and dereference it in the printf statement in the third line, or remove the & operator from x in the second line. xPtr
char *s; printf( "%s\n", s );
AN S:
s
has not been assigned a value; it does not point to anything.
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
Exercises
(Maze Traversal) The following grid is a double-subscripted array representation of a maze.
7.22 # # . # # # # # # # # #
# . . # . # . # . # . #
# . # # . # . . . # . #
275
# . . . . # # # . # . #
# # # # . . . . . # . #
# . . . # # # # . # . #
# . # . # . . . . . . #
# . # . # # # # . # # #
# . # . . . . . . # . #
# . # # # # # # # # . #
# . . . . . . . . . . #
# # # # . # # # # # # #
The # symbols represent the walls of the maze, and the periods ( .) represent squares in the possible paths through the maze. There is a simple algorithm for walking through a maze that guarantees finding the exit (assuming there is an exit). If there is not an exit, you will arrive at the starting location again. Place your right hand on the wall to your right and begin walking forward. Never remove your hand from the wall. If the maze turns to the right, you follow the wall to the right. As long as you do not remove your hand from the wall, eventually you will arrive at the exit of the maze. There may be a shorter path than the one you have taken, but you are guaranteed to get out of the maze. Write recursive function mazeTraverse to walk through the maze. The function should receive as arguments a 12-by-12 character array representing the maze and the starting location of the maze. As mazeTraverse attempts to locate the exit from the maze, it should place the character X in each square in the path. The function should display the maze after each move so the user can watch as the maze is solved. AN S:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
/* Exercise 7.22 Solution */ /* This solution assumes that there is only one */ /* entrance and one exit for a given maze, and */ /* these are the only two zeroes on the borders.*/ #include #include #define #define #define #define
DOWN RIGHT UP LEFT
0 1 2 3
/* /* /* /*
move move move move
down right up left
*/ */ */ */
#define X_START 2 /* starting X and Y coordinate for maze */ #define Y_START 0 /* function prototypes */ void mazeTraversal( char maze[ 12 ][ 12 ], int xCoord, int yCoord, int direction ); void printMaze( const char maze[][ 12 ] ); int validMove( const char maze[][ 12 ], int r, int c ); int coordsAreEdge( int x, int y ); int main() {
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
276
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
Chapter 7
C Pointers: Solutions
/* maze grid */ char maze[ 12 ][ 12 ] = { { '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1'}, { '1', '0', '0', '0', '1', '0', '0', '0', '0', '0', '0', '1'}, { '0', '0', '1', '0', '1', '0', '1', '1', '1', '1', '0', '1'}, { '1', '1', '1', '0', '1', '0', '0', '0', '0', '1', '0', '1'}, { '1', '0', '0', '0', '0', '1', '1', '1', '0', '1', '0', '0'}, { '1', '1', '1', '1', '0', '1', '0', '1', '0', '1', '0', '1'}, { '1', '0', '0', '1', '0', '1', '0', '1', '0', '1', '0', '1'}, { '1', '1', '0', '1', '0', '1', '0', '1', '0', '1', '0', '1'}, { '1', '0', '0', '0', '0', '0', '0', '0', '0', '1', '0', '1'}, { '1', '1', '1', '1', '1', '1', '0', '1', '1', '1', '0', '1'}, { '1', '0', '0', '0', '0', '0', '0', '1', '0', '0', '0', '1'}, { '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1' } }; mazeTraversal( maze, X_START, Y_START, RIGHT ); return 0; /* indicate successful termination */ } /* end main */ /* Assume that there is exactly 1 entrance and exactly 1 exit to the maze. */ void mazeTraversal( char maze[ 12 ][ 12 ], int xCoord, int yCoord, int direction ) { static int flag = 0; /* starting position flag */ maze[ xCoord ][ yCoord ] = 'X'; /* mark current point */ printMaze( maze ); /* if maze completed */ if ( coordsAreEdge( xCoord, yCoord ) && xCoord != X_START && yCoord != Y_START ) { printf( "\nMaze successfully exited!\n\n" ); return; } /* end if */ else if ( xCoord == X_START && yCoord == Y_START && flag == 1 ) { printf( "\nArrived back at the starting location.\n\n" ); return; } /* end else if */ else { /* make next move */ int move; /* next move */ int count; /* counter */ flag = 1; /* loop 4 times and find first valid move */ for ( move = direction, count = 0; count < 4; ++count, ++move, move %= 4 ) { /* choose valid move */ switch( move ) {
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
Exercises
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
277
case DOWN: /* move down */ /* if move is valid, call mazeTraversal */ if ( validMove( maze, xCoord + 1, yCoord ) ) { mazeTraversal( maze, xCoord + 1, yCoord, LEFT ); return; } /* end if */ break; /* exit switch */ case RIGHT: /* move right */ /* if move is valid, call mazeTraversal */ if ( validMove( maze, xCoord, yCoord + 1 ) ) { mazeTraversal( maze, xCoord, yCoord + 1, DOWN ); return; } /* end if */ break; /* exit switch */ case UP: /* move up */ /* if move is valid, call mazeTraversal */ if ( validMove( maze, xCoord - 1, yCoord ) ) { mazeTraversal( maze, xCoord - 1, yCoord, RIGHT ); return; } /* end if */ break; /* exit switch */ case LEFT: /* move left */ /* if move is valid, call mazeTraversal */ if ( validMove( maze, xCoord, yCoord - 1 ) ) { /*go left */ mazeTraversal( maze, xCoord, yCoord - 1, UP ); return; } /* end if */ break; /* exit switch */ } /* end switch */ } /* end for */ } /* end else */ } /* end function mazeTraversal */ /* validate move */ int validMove( const char maze[][ 12 ], int r, int c ) { return ( r >= 0 && r <= 11 && c >= 0 && c <= 11 && maze[ r ][ c ] != '1' ); } /* end function validMove */
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
278
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
Hit 1 1 1 X X X 1 1 1 X 1 1 1 X 1 1 1 X 1 1 1 X 1 1
Chapter 7
C Pointers: Solutions
/* function to check coordinates */ int coordsAreEdge( int x, int y ) { /* if coordinate is not valid if ( ( x == 0 || x == 11 ) && return 1; } /* end if */ else if ( ( y == 0 || y == 11 return 1; } /* end else if */ else { /* coordinate is valid return 0; } /* end else */
*/ ( y >= 0 && y <= 11 ) ) {
) && ( x >= 0 && x <= 11 ) ) {
*/
} /* end function coordsAreEdge */ /* print the current state of the maze */ void printMaze( const char maze[][ 12 ] ) { int x; /* row counter */ int y; /* column counter */ /* iterate through the maze */ for ( x = 0; x < 12; x++ ) { for ( y = 0; y < 12; y++ ) { printf( "%c ", maze[ x ][ y ] ); } /* end for */ printf( "\n" ); } /* end for */ printf( "\nHit return to see next move" ); getchar(); } /* end function printMaze */ return to 1 1 1 1 1 X X 1 X X 1 X 1 X 1 1 X 1 X X X X X 1 1 1 1 X 1 0 X 1 X 1 0 X 1 X 1 0 X X X X X 1 1 1 1 X X X X X X 1 1 1 1 1
see 1 1 X X 1 1 X X 1 X 1 X 1 X 1 X X X 1 1 1 0 1 1
next move 1 1 1 X X 1 1 0 1 1 0 1 1 0 0 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 0 0 1 1 1 1
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
Exercises
Hit 1 1 1 X X X 1 1 1 X 1 1 1 X 1 1 1 X 1 1 1 X 1 1
return to 1 1 1 1 1 X X 1 X X 1 X 1 X 1 1 X 1 X X X X X 1 1 1 1 X 1 0 X 1 X 1 0 X 1 X 1 0 X X X X X 1 1 1 1 X X X X X X 1 1 1 1 1
see 1 1 X X 1 1 X X 1 X 1 X 1 X 1 X X X 1 1 1 0 1 1
next move 1 1 1 X X 1 1 X 1 1 0 1 1 0 0 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 0 0 1 1 1 1
return to 1 1 1 1 1 X X 1 X X 1 X 1 X 1 1 X 1 X X X X X 1 1 1 1 X 1 0 X 1 X 1 0 X 1 X 1 0 X X X X X 1 1 1 1 X X X X X X 1 1 1 1 1
see 1 1 X X 1 1 X X 1 X 1 X 1 X 1 X X X 1 1 1 X 1 1
next move 1 1 1 X X 1 1 X 1 1 X 1 1 X X 1 X 1 1 X 1 1 X 1 1 X 1 1 X 1 X X 1 1 1 1
279
... Hit 1 1 1 X X X 1 1 1 X 1 1 1 X 1 1 1 X 1 1 1 X 1 1
Hit return to see next move Maze successfully exited!
(Generating Mazes Randomly) Write a function mazeGenerator that takes as an argument a double-subscripted 12-by-12 character array and randomly produces a maze. The function should also provide the starting and ending locations of the maze. Try your function mazeTraverse from Exercise 7.22 using several randomly generated mazes. 7.23
AN S:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/* Exercise 7.23 Solution */ #include #include #include #define #define #define #define #define
DOWN 0 /* move down */ RIGHT 1 /* move right */ UP 2 /* move up */ LEFT 3 /* move left */ POSSIBLE_ZEROS 100 /* maximum possible zeros */
/* function prototypes */ void mazeTraversal( char maze[ 12 ][ 12 ], const int xCoord, const int yCoord, int row, int col, int direction ); void mazeGenerator( char maze[][ 12 ], int *xPtr, int *yPtr ); void printMaze( const char maze[][ 12 ] ); int validMove( const char maze[][ 12 ], int r, int c ); int coordsAreEdge( int x, int y );
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
280
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
Chapter 7
C Pointers: Solutions
int main() { char maze[ 12 ][ 12 ]; /* maze grid */ int loop; /* row counter */ int loop2; /* column counter */ int xStart; /* starting x coordinate */ int yStart; /* starting y coordinate */ int x; /* current x coordinate */ int y; /* current y coordinate */ /* initialize maze grid to 1's */ for ( loop = 0; loop < 12; loop++ ) { for ( loop2 = 0; loop2 < 12; loop2++ ) { maze[ loop ][ loop2 ] = '1'; } /* end for */ } /* end for */ /* generate the maze */ mazeGenerator( maze, &xStart, &yStart ); x = xStart; /* starting row */ y = yStart; /* starting col */ mazeTraversal( maze, xStart, yStart, x, y, RIGHT ); return 0; /* indicate successful termination */ } /* end main */ /* Assume that there is exactly 1 entrance and exactly 1 exit to the maze. */ void mazeTraversal( char maze[ 12 ][ 12 ], const int xCoord, const int yCoord, int row, int col, int direction ) { static int flag = 0; /* starting position flag */ maze[ row ][ col ] = 'X'; /* insert X at current location */ printMaze( maze ); /* if maze completed */ if ( coordsAreEdge( row, col ) && row != xCoord && col != yCoord ) { printf( "\nMaze successfully exited!\n\n" ); return; } /* end if */ else if ( row == xCoord && col == yCoord && flag == 1 ) { printf( "\nArrived back at the starting location.\n\n" ); return; } /* end else if */ else { /* make next move */ int move; /* next move */ int count; /* counter */
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
Exercises
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
flag = 1; /* loop 4 times and find first valid move */ for ( move = direction, count = 0; count < 4; ++count, ++move, move %= 4 ) { /* choose valid move */ switch( move ) { case DOWN: /* move down */ /* if move is valid, call mazeTraversal */ if ( validMove( maze, row + 1, col ) ) { mazeTraversal( maze, xCoord, yCoord, row + 1, col, LEFT ); return; } /* end if */ break; /* exit switch */ case RIGHT: /* move right */ /* if move is valid, call mazeTraversal */ if ( validMove( maze, row, col + 1 ) ) { mazeTraversal( maze, xCoord, yCoord, row, col + 1, DOWN ); return; } /* end if */ break; /* exit switch */ case UP: /* move up */ /* if move is valid, call mazeTraversal */ if ( validMove( maze, row - 1, col ) ) { mazeTraversal( maze, xCoord, yCoord, row - 1, col, RIGHT ); return; } /* end if */ break; /* exit switch */ case LEFT: /* move left */ /* if move is valid, call mazeTraversal */ if ( validMove( maze, row, col - 1 ) ) { mazeTraversal( maze, xCoord, yCoord, row, col - 1, UP ); return; } /* end if */ break; /* exit switch */ } /* end switch */ } /* end for */
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
281
282
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
Chapter 7
C Pointers: Solutions
} /* end else */ } /* end function mazeTraversal */ /* validate move */ int validMove( const char maze[][ 12 ], int r, int c ) { return ( r >= 0 && r <= 11 && c >= 0 && c <= 11 && maze[ r ][ c ] != '1' ); } /* end function validMove */ /* check boundaries of coordinates */ int coordsAreEdge( int x, int y ) { /* if coordinates not if ( ( x == 0 || x == return 1; } /* end if */ else if ( ( y == 0 || return 1; } /* end else if */ else { /* coordinates return 0; } /* end else */
valid */ 11 ) && ( y >= 0 && y <= 11 ) ) {
y == 11 ) && ( x >= 0 && x <= 11 ) ) {
valid */
} /* end function coordsAreEdge */ /* print the maze */ void printMaze( const char maze[][ 12 ] ) { int x; /* row counter */ int y; /* column counter */ /* loop through maze grid */ for ( x = 0; x < 12; x++ ) { for ( y = 0; y < 12; y++ ) { printf( "%c ", maze[ x ][ y ] ); } /* end for */ printf( "\n" ); } /* end for */ printf( "\nHit return to see next move" ); getchar(); } /* end function printMaze */ /* random maze generator */ void mazeGenerator( char maze[][ 12 ], int *xPtr, int *yPtr ) { int a; /* random number */
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
Exercises
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235
int int int int int
x; y; entry; exit; loop;
/* /* /* /* /*
random number */ random number */ random entry */ random exit */ loop counter */
srand( time( NULL ) ); /* generate random entry and exit p ositions */ do { entry = rand() % 4; exit = rand() % 4; } while ( entry == exit ); /* end do...while */ /* Determine entry position while avoiding corners */ if ( entry == 0 ) { *xPtr = 1 + rand() % 10; *yPtr = 0; maze[ *xPtr ][ 0 ] = '0'; } /* end if */ else if ( entry == 1 ) { *xPtr = 0; *yPtr = 1 + rand() % 10; maze[ 0 ][ *yPtr ] = '0'; } /* end else if */ else if ( entry == 2 ) { *xPtr = 1 + rand() % 10; *yPtr = 11; maze[ *xPtr ][ 11 ] = '0'; } /* end else if */ else { *xPtr = 11; *yPtr = 1 + rand() % 10; maze[ 11 ][ *yPtr ] = '0'; } /* end else */ /* Determine exit location */ if ( exit == 0 ) { a = 1 + rand() % 10; maze[ a ][ 0 ] = '0'; } /* end if */ else if ( exit == 1 ) { a = 1 + rand() % 10; maze[ 0 ][ a ] = '0'; } /* end else if */ else if ( exit == 2 ) { a = 1 + rand() % 10; maze[ a ][ 11 ] = '0'; } /* end else if */ else { a = 1 + rand() % 10; maze[ 11 ][ a ] = '0'; } /* end else */
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
283
284
236 237 238 239 240 241 242 243
Chapter 7
C Pointers: Solutions
/* randomly add zeros to maze grid */ for ( loop = 1; loop < POSSIBLE_ZEROS; loop++ ) { x = 1 + rand() % 10; y = 1 + rand() % 10; maze[ x ][ y ] = '0'; } /* end for */ } /* end function mazeGenerator */
Hit 1 1 1 0 1 1 X X 1 X 1 X 1 1 1 1 1 X 1 1 1 1 1 1
return to 1 1 0 1 1 1 1 0 1 0 1 0 0 0 1 1 0 0 1 X X X 1 X X 1 X X X 1 X 1 X X X X X X X 1 X 0 0 X 1 X 0 1 X 1 X X X X X 1 1 1 1 1
see 1 1 1 X 1 1 X X 1 X 0 1 1 X 1 X X X X X 1 1 1 1
next move 1 1 1 X X 1 1 X 1 X X 1 X 1 1 X 1 1 X 1 1 1 0 1 X 1 1 1 0 1 0 0 1 1 1 1
Hit 1 1 1 0 1 1 X X 1 X 1 X 1 1 1 1 1 X 1 1 1 1 1 1
return to 1 1 0 1 1 1 1 0 1 0 1 0 0 0 1 1 0 0 1 X X X 1 X X 1 X X X 1 X 1 X X X X X X X 1 X 0 0 X 1 X 0 1 X 1 X X X X X 1 1 1 1 1
see 1 1 1 X 1 1 X X 1 X 0 1 1 X 1 X X X X X 1 1 1 1
next move 1 1 1 X X 1 1 X 1 X X 1 X 1 1 X 1 1 X 1 1 1 0 1 X 1 1 1 0 1 0 0 1 1 1 1
return to 1 1 X 1 1 1 1 X 1 0 1 0 X X 1 1 X X 1 X X X 1 X X 1 X X X 1 X 1 X X X X X X X 1 X 0 0 X 1 X 0 1 X 1 X X X X X 1 1 1 1 1
see 1 1 1 X 1 1 X X 1 X 0 1 1 X 1 X X X X X 1 1 1 1
next move 1 1 1 X X 1 1 X 1 X X 1 X 1 1 X 1 1 X 1 1 1 0 1 X 1 1 1 0 1 0 0 1 1 1 1
... Hit 1 1 1 0 1 1 X X 1 X 1 X 1 1 1 1 1 X 1 1 1 1 1 1
Hit return to see next move Maze successfully exited!
(Mazes of Any Size) Generalize functions mazeTraverse and Exercise 7.22 and Exercise 7.23 to process mazes of any width and height. 7.24
mazeGenerator
AN S:
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
of
Exercises
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
285
/* Exercise 7.24 Solution */ #include #include #include #define #define #define #define #define #define
ROW 10 COL 10 DOWN 0 RIGHT 1 UP 2 LEFT 3
/* /* /* /* /* /*
height */ width */ move down */ move right */ move up */ move left */
/* function prototypes */ void mazeTraversal( char maze[ ROW ][ COL ], const int xCoord, const int yCoord, int row, int col, int direction ); void mazeGenerator( char maze[][ COL ], int *xPtr, int *yPtr ); void printMaze( const char maze[][ COL ] ); int validMove( const char maze[][ COL ], int r, int c ); int coordsAreEdge( int x, int y ); int main() { char maze[ ROW ][ COL ]; /* maze grid */ int loop; /* row counter */ int loop2; /* column counter */ int xStart; /* starting x coordinate */ int yStart; /* starting y coordinate */ int x; /* current x coordinate */ int y; /* current y coordinate */ /* initialize maze grid to 1's */ for ( loop = 0; loop < ROW; loop++ ) { for ( loop2 = 0; loop2 < COL; loop2++ ) { maze[ loop ][ loop2 ] = '1'; } /* end for */ } /* end for */ /* generate the maze */ mazeGenerator( maze, &xStart, &yStart ); x = xStart; /* starting row */ y = yStart; /* starting col */ mazeTraversal( maze, xStart, yStart, x, y, RIGHT ); return 0; /* indicate successful termination */ } /* end main */ /* Assume that there is exactly 1 entrance and exactly 1 exit to the maze. */ void mazeTraversal( char maze[ ROW ][ COL ], const int xCoord, const int yCoord, int row, int col, int direction ) {
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
286
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
Chapter 7
C Pointers: Solutions
static int flag = 0; /* starting position flag */
maze[ row ][ col ] = 'X'; /* insert X at current location */ printMaze( maze ); /* if maze completed */ if ( coordsAreEdge( row, col ) && row != xCoord && col != yCoord ) { printf( "\nMaze successfully exited!\n\n" ); return; } /* end if */ else if ( row == xCoord && col == yCoord && flag == 1 ) { printf( "\nArrived back at the starting location.\n\n" ); return; } /* end else if */ else { /* make next move */ int move; /* next move */ int count; /* counter */ flag = 1; /* loop 4 times and find first valid move */ for ( move = direction, count = 0; count < 4; ++count, ++move, move %= 4 ) { /* choose valid move */ switch( move ) { case DOWN: /* move down */ /* if move is valid, call mazeTraversal */ if ( validMove( maze, row + 1, col ) ) { mazeTraversal( maze, xCoord, yCoord, row + 1, col, LEFT ); return; } /* end if */ break; /* exit switch */ case RIGHT: /* move right */ /* if move is valid, call mazeTraversal */ if ( validMove( maze, row, col + 1 ) ) { mazeTraversal( maze, xCoord, yCoord, row, col + 1, DOWN ); return; } /* end if */ break; /* exit switch */
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
Exercises
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
case UP: /* move up */ /* if move is valid, call mazeTraversal */ if ( validMove( maze, row - 1, col ) ) { mazeTraversal( maze, xCoord, yCoord, row - 1, col, RIGHT ); return; } /* end if */ break; /* exit switch */ case LEFT: /* move left */ /* if move is valid, call mazeTraversal */ if ( validMove( maze, row, col - 1 ) ) { mazeTraversal( maze, xCoord, yCoord, row, col - 1, UP ); return; } /* end if */ break; /* exit switch */ } /* end switch */ } /* end for */ } /* end else */ } /* end function mazeTraversal */ /* validate move */ int validMove( const char maze[][ COL ], int r, int c ) { return ( r >= 0 && r <= ROW - 1 && c >= 0 && c <= COL - 1 && maze[ r ][ c ] != '1' ); /* a valid move */ } /* end function validMove */ /* check boundaries of coordinates */ int coordsAreEdge( int x, int y ) { /* if coordinates not if ( ( x == 0 || x == return 1; } /* end if */ else if ( ( y == 0 || x <= ROW - 1 ) ) { return 1; } /* end else if */ else { /* coordinates return 0; } /* end else */
valid */ ROW - 1 ) && ( y >= 0 && y <= COL - 1 ) ) {
y == COL - 1 ) && ( x >= 0 &&
valid */
} /* end function coordsAreEdge */
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
287
288
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213
Chapter 7
C Pointers: Solutions
/* print the maze */ void printMaze( const char maze[][ COL ] ) { int x; /* row counter */ int y; /* column counter */ /* loop through maze grid */ for ( x = 0; x < ROW; x++ ) { for ( y = 0; y < COL; y++ ) { printf( "%c ", maze[ x ][ y ] ); } /* end for */ printf( "\n" ); } /* end for */ printf( "\nHit return to see next move" ); getchar(); } /* end function printMaze */ /* random maze generator */ void mazeGenerator( char maze[][ COL ], int *xPtr, int *yPtr ) { int a; /* random number */ int x; /* random number */ int y; /* random number */ int entry; /* random entry */ int exit; /* random exit */ int loop; /* loop counter */ srand( time( NULL ) ); /* generate random entry and exit p ositions */ do { entry = rand() % 4; exit = rand() % 4; } while ( entry == exit ); /* end do...while */ /* Determine entry position while if ( entry == 0 ) { *xPtr = 1 + rand() % ( ROW - 2 *yPtr = 0; maze[ *xPtr ][ *yPtr ] = '0'; } /* end if */ else if ( entry == 1 ) { *xPtr = 0; *yPtr = 1 + rand() % ( COL - 2 maze[ *xPtr ][ *yPtr ] = '0'; } /* end else if */ else if ( entry == 2 ) { *xPtr = 1 + rand() % ( ROW - 2 *yPtr = COL - 1; maze[ *xPtr ][ *yPtr ] = '0'; } /* end else if */
avoiding corners */ );
);
);
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
Exercises
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245
1 1 0 1 1 1 1 1 1 1
1 0 0 0 1 1 0 0 0 1
Hit 1 1 1 0 0 0 1 0 1 1 1 1 1 0 1 0 1 0 1 1
else { *xPtr *yPtr maze[ } /* end
= ROW - 1; = 1 + rand() % ( COL - 2 ); *xPtr ][ *yPtr ] = '0'; else */
/* Determine exit location */ if ( exit == 0 ) { a = 1 + rand() % ( ROW - 2 ); maze[ a ][ 0 ] = '0'; } /* end if */ else if ( exit == 1 ) { a = 1 + rand() % ( COL - 2 ); maze[ 0 ][ a ] = '0'; } /* end else if */ else if ( exit == 2 ) { a = 1 + rand() % ( ROW - 2 ); maze[ a ][ COL - 1 ] = '0'; } /* end else if */ else { a = 1 + rand() % ( COL - 2 ); maze[ ROW - 1 ][ a ] = '0'; } /* end else */ /* randomly add zeroes to maze grid */ for ( loop = 1; loop < ( ROW - 2 ) * ( COL - 2 ); loop++ ) { x = 1 + rand() % ( ROW - 2 ); y = 1 + rand() % ( COL - 2 ); maze[ x ][ y ] = '0'; } /* end for */ } /* end function mazeGenerator */ X 0 0 0 1 1 0 0 0 1
1 1 1 0 0 0 0 0 0 1
1 1 1 0 0 1 1 1 0 1
1 0 1 0 0 0 0 1 1 1
1 1 1 1 1 1 0 0 1 1
return to X 1 1 1 1 X 1 1 0 1 0 1 1 1 1 0 0 0 0 1 1 0 0 0 1 1 0 1 0 1 0 0 1 0 0 0 0 1 1 0 0 0 0 1 1 1 1 1 1 1
1 0 1 0 0 1 1 0 0 1
1 0 0 1 0 0 0 0 0 1
see 1 1 0 0 1 0 0 1 0 0 1 0 1 0 0 0 0 0 1 1
1 1 1 1 1 1 1 1 1 1 next move 1 1 1 1 1 1 1 1 1 1
...
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
289
290
Hit 1 1 1 X X X 1 0 1 1 1 1 1 0 1 0 1 0 1 1
Chapter 7
return to X 1 1 1 1 X 1 1 0 1 0 1 1 1 1 0 0 0 0 1 1 0 0 0 1 1 0 1 0 1 0 0 1 0 0 0 0 1 1 0 0 0 0 1 1 1 1 1 1 1
see 1 1 0 0 1 0 0 1 0 0 1 0 1 0 0 0 0 0 1 1
C Pointers: Solutions
next move 1 1 1 1 1 1 1 1 1 1
Hit return to see next move Maze successfully exited!
(Arrays of Pointers to Functions) Rewrite the program of Fig. 6.22 to use a menu-driven interface. The program should offer the user four options as follows: 7.25
Enter a choice: 0 Print the array of grades 1 Find the minimum grade 2 Find the maximum grade 3 Print the average on all tests for each student 4 End program
One restriction on using arrays of pointers to functions is that all the pointers must have the same type. The pointers must be to functions of the same return type that receive arguments of the same type. For this reason, the functions in Fig. 6.22 must be modified so that they each return the same type and take the same parameters. Modify functions minimum and maximum to print the minimum or maximum value and return nothing. For option 3, modify function average of Fig. 6.22 to output the average for each student (not a specific student). Function average should return nothing and take the same parameters as printArray, minimum and maximum. Store the pointers to the four functions in array processGrades and use the choice made by the user as the subscript into the array for calling each function. AN S:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/* Exercise 7.25 Solution */ #include #define STUDENTS 3 #define EXAMS 4 /* function prototypes */ void minimum( int grades[][ EXAMS ], void maximum( int grades[][ EXAMS ], void average( int grades[][ EXAMS ], void printArray( int grades[][ EXAMS void printMenu( void );
int pupils, int tests ); int pupils, int tests ); int pupils, int tests ); ], int pupils, int tests );
int main() {
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
Exercises
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
291
/* pointer to a function that takes as parameters a two-dimensional array and two integer values */ void ( *processGrades[ 4 ] )( int [][ EXAMS ], int, int ) = { printArray, minimum, maximum, average}; int choice = 0; /* menu choice */ /* array of student grades */ int studentGrades[ STUDENTS ][ EXAMS ] = { { 77, 68, 86, 73 }, { 96, 87, 89, 78 }, { 70, 90, 86, 81 } }; /* loop while user does not choose option 4 */ while ( choice != 4 ) { /* display menu and read user's choice */ do { printMenu(); scanf( "%d", &choice ); } while ( choice < 0 || choice > 4 ); /* end do...while */ /* pass choice into the array */ if ( choice != 4 ) { ( *processGrades[ choice ] )( studentGrades, STUDENTS, EXAMS ); } /* end if */ else { printf( "Program Ended.\n" ); } /* end else */ } /* end while */ return 0; /* indicate successful termination */ } /* end main */ /* search for the minimum value */ void minimum( int grades[][ EXAMS ], int pupils, int tests ) { int i; /* loop counter */ int j; /* loop counter */ int lowGrade = 100; /* set lowGrade to highest possible score * / /* loop through rows */ for ( i = 0; i <= pupils - 1; i++ ) { /* loop through columns */ for ( j = 0; j <= tests - 1; j++ ) { /* if current grade is lower than lowGrade */ if ( grades[ i ][ j ] < lowGrade ) { lowGrade = grades[ i ][ j ]; } /* end if */ } /* end for */ } /* end for */
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
292
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
Chapter 7
C Pointers: Solutions
printf( "\n\tThe lowest grade is %d\n", lowGrade ); } /* end function minimum */ /* search for maximum value */ void maximum( int grades[][ EXAMS ], int pupils, int tests ) { int i; /* loop counter */ int j; /* loop counter */ int highGrade = 0; /* set highGrade to lowest possible score * / /* loop through rows */ for ( i = 0; i <= pupils - 1; i++ ) { /* loop through columns */ for ( j = 0; j <= tests - 1; j++ ) { /* if current grade is higher than highGrade */ if ( grades[ i ][ j ] > highGrade ) { highGrade = grades[ i ][ j ]; } /* end if */ } /* end for */ } /* end for */ printf( "\n\tThe highest grade is %d\n", highGrade ); } /* end function maximum */ /* calculate average */ void average( int grades[][ EXAMS ], int pupils, int tests ) { int i; /* loop counter */ int j; /* loop counter */ int total; /* sum of all grades */ printf( "\n" ); /* loop through rows */ for ( i = 0; i <= pupils - 1; i++ ) { total = 0; /* loop through columns */ for ( j = 0; j <= tests - 1; j++ ) { total += grades[ i ][ j ]; } /* end for */ printf( "\tThe average for student %d is %. 1f\n", i + 1, ( double ) total / tests ); } /* end for */ } /* end function average */
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
Exercises
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
/* print the contents of the array */ void printArray( int grades[][ EXAMS ], int pupils, int tests ) { int i; /* loop counter */ int j; /* loop counter */ printf( "\n\t
[ 0 ]
[ 1 ]
[ 2 ]
[ 3 ]" );
/* loop through rows */ for ( i = 0; i <= pupils - 1; i++ ) { printf( "\n\tstudentGrades[ %d ] ", i ); /* loop through columns */ for ( j = 0; j <= tests - 1; j++ ) { printf( "%-7d", grades[ i ][ j ] ); } /* end for */ } /* end for */ printf( "\n" ); } /* end function printArray */ /* display the menu */ void printMenu( void ) { printf( "\n\tEnter a choice:\n" "\t 0 Print the array of grades\n" "\t 1 Find the minimum grade\n" "\t 2 Find the maximum grade\n" "\t 3 Print the average on all" " tests for each student\n" "\t 4 End program\n" "\t? " ); } /* end function printMenu */
Enter a choice: 0 Print the array of grades 1 Find the minimum grade 2 Find the maximum grade 3 Print the average on all tests for each student 4 End program ? 0 [ 0 ] studentGrades[ 0 ] 77 studentGrades[ 1 ] 96 studentGrades[ 2 ] 70
[ 1 ] 68 87 90
[ 2 ] 86 89 86
[ 3 ] 73 78 81
Enter a choice: 0 Print the array of grades 1 Find the minimum grade 2 Find the maximum grade 3 Print the average on all tests for each student 4 End program ? 1 The lowest grade is 68
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
293
294
Chapter 7
C Pointers: Solutions
Enter a choice: 0 Print the array of grades 1 Find the minimum grade 2 Find the maximum grade 3 Print the average on all tests for each student 4 End program ? 2 The highest grade is 96 Enter a choice: 0 Print the array of grades 1 Find the minimum grade 2 Find the maximum grade 3 Print the average on all tests for each student 4 End program ? 3 The average for student 1 is 76.0 The average for student 2 is 87.5 The average for student 3 is 81.8 Enter a choice: 0 Print the array of grades 1 Find the minimum grade 2 Find the maximum grade 3 Print the average on all tests for each student 4 End program ? 4 Program Ended.
7.26 1 2 3
What does this program do?
/* ex07_26.c */ /* What does this program do? */ #include
4 5
int mystery3( const char *s1, const char *s2 ); /* prototype */
6 7 8 9 10
int main( void ) { char string1[ 80 ]; /* create char array */ char string2[ 80 ]; /* create char array */
11 12 13 14 15 16
printf( "Enter two strings: " ); scanf( "%s%s", string1 , string2 ); printf( "The result is %d\n" , mystery3( string1, string2 ) ); return 0; /* indicates successful termination */ } /* end main */
17 18 19 20
int mystery3( const char *s1, const char *s2 ) { for ( ; *s1 != '\0' && *s2 != '\0'; s1++, s2++ ) {
21 22 23 24 25
if ( *s1 != *s2 ) { return 0; } /* end if */ } /* end for */
26 27 28
return 1; } /* end function mystery3 */
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
Special Section: Building Your Own Computer
AN S:
295
The program compares two strings, element by element, for equality.
Enter two strings: The result is 0
string1 string2
Enter two strings: The result is 1
string2 string2
Special Section: Building Your Own Computer In the next several problems, we take a temporary diversion away from the world of high-level language programming. We “peel open” a computer and look at its internal structure. We introduce machine-language programming and write several machine-language programs. To make this an especially valuable experience, we then build a computer (through the technique of software-based simulation) on which you can execute your machine-language programs! (Machine-Language Programming) Let’s create a computer we’ll call the Simpletron. As its name implies, it’s a simple machine, but as we’ll soon see, a powerful one as well. The Simpletron runs programs written in the only language it directly understands—that is, Simpletron Machine Language, or SML for short. The Simpletron contains an accumulator— a “special register” in which information is put before the Simpletron uses that information in calculations or examines it in various ways. All information in the Simpletron is handled in terms of words. A word is a signed four-digit decimal number such as +3364, -1293, +0007, -0001 and so on. The Simpletron is equipped with a 100 word memory, and these words are referenced by their location numbers 00, 01, …, 99. Before running an SML program, we must load or place the program into memory. The first instruction (or statement) of every SML program is always placed in location 00. Each instruction written in SML occupies one word of the Simpletron's memory (and hence instructions are signed four-digit decimal numbers). We assume that the sign of an SML instruction is always plus, but the sign of a data word may be either plus or minus. Each location in the Simpletron’s memory may contain either an instruction, a data value used by a program or an unused (and hence undefined) area of memory. The first two digits of each SML instruction are the operation code, which specifies the operation to be performed. SML operation codes are summarized in Fig. 7.32. 7.27
Operation code
Meaning
Input/output operations: #define READ 10
#define WRITE 11
Read a word from the terminal into a specific location in memory. Write a word from a specific location in memory to the terminal.
Load/store operations: #define LOAD 20
Load a word from a specific location in memory into the accumulator.
Fig. 7.32 | Simpletron Machine Language (SML) operation codes. (Part 1 of 2.)
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
296
Chapter 7
C Pointers: Solutions
Operation code
Meaning
Store a word from the accumulator into a specific location in memory.
#define STORE 21
Arithmetic operations: Add a word from a specific location in memory to the word in the accumulator (leave result in accumulator). Subtract a word from a specific location in memory from the word in the accumulator (leave result in accumulator). Divide a word from a specific location in memory into the word in the accumulator (leave result in accumulator). Multiply a word from a specific location in memory by the word in the accumulator (leave result in accumulator).
#define ADD 30
#define SUBTRACT 31
#define DIVIDE 32
#define MULTIPLY 33
Transfer of control operations: Branch to a specific location in memory. Branch to a specific location in memory if the accumulator is negative. Branch to a specific location in memory if the accumulator is zero. Halt—i.e., the program has completed its task.
#define BRANCH 40 #define BRANCHNEG 41
#define BRANCHZERO 42
#define HALT 43
Fig. 7.32 | Simpletron Machine Language (SML) operation codes. (Part 2 of 2.) The last two digits of an SML instruction are the operand, which is the address of the memory location containing the word to which the operation applies. Now let’s consider several simple SML programs. The following SML program reads two numbers from the keyboard, and computes and prints their sum. Example 1 Location
Number
Instruction
00
+1007
01
+1008
02
+2007
03
+3008
04
+2109
05
+1109
06
+4300
07
+0000
08
+0000
09
+0000
(Read A) (Read B) (Load A) (Add B) (Store C) (Write C) (Halt) (Variable A) (Variable B) (Result C)
The instruction +1007 reads the first number from the keyboard and places it into location 07 (which has been initialized to zero). Then +1008 reads the next number into location 08. The load instruction, +2007, puts the first number into the accumulator, and the add instruction, +3008, © 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
Special Section: Building Your Own Computer
297
adds the second number to the number in the accumulator. All SML arithmetic instructions leave their results in the accumulator. The store instruction, +2109, places the result back into memory location 09, from which the write instruction, +1109, takes the number and prints it (as a signed four-digit decimal number). The halt instruction, +4300, terminates execution. The following SML program reads two numbers from the keyboard, and determines and prints the larger value. Note the use of the instruction +4107 as a conditional transfer of control, much the same as C’s if statement. Example 2 Location
Number
Instruction
00
+1009
01
+1010
02
+2009
03
+3110
04
+4107
05
+1109
06
+4300
07
+1110
08
+4300
09
+0000
10
+0000
(Read A) (Read B) (Load A) (Subtract B) (Branch negative to 07) (Write A) (Halt) (Write B) (Halt) (Variable A) (Variable B)
Now write SML programs to accomplish each of the following tasks. a) Use a sentinel-controlled loop to read 10 positive integers and compute and print their sum. AN S:
00 01 02 03 04 05 06 07 08 09
+1009 +2009 +4106 +3008 +2108 +4000 +1108 +4300 +0000 +0000
(Read Value) (Load Value) (Branch negative to 06) (Add Sum) (Store Sum) (Branch 00) (Write Sum) (Halt) (Variable Sum) (Variable Value)
b) Use a counter-controlled loop to read seven numbers, some positive and some negative, and compute and print their average. AN S:
00 01 02 03 04 05 06 07 08 09 10 11 12
+2018 +3121 +4211 +2018 +3019 +2118 +1017 +2016 +3017 +2116 +4000 +2016 +3218
(Load Counter) (Subtract Termination) (Branch zero to 11) (Load Counter) (Add Increment) (Store Counter) (Read Value) (Load Sum) (Add Value) (Store Sum) (Branch 00) (Load Sum) (Divide Counter)
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
298
Chapter 7 13 14 15 16 17 18 19 20 21
C Pointers: Solutions
+2120 +1120 +4300 +0000 +0000 +0000 +0001 +0000 +0007
(Store Result) (Write Result) (Halt) (Variable Sum) (Variable Value) (Variable Counter) (Variable Increment) (Variable Result) (Variable Termination)
c) Read a series of numbers and determine and print the largest number. The first number read indicates how many numbers should be processed. AN S:
00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21
+1017 +2018 +3117 +4215 +2018 +3021 +2118 +1019 +2020 +3119 +4112 +4001 +2019 +2120 +4001 +1120 +4300 +0000 +0000 +0000 +0000 +0001
(Read Endvalue) (Load Counter) (Subtract Endvalue) (Branch zero to 15) (Load Counter) (Add Increment) (Store Counter) (Read Value) (Load Largest) (Subtract Value) (Branch negative to 12) (Branch 01) (Load Value) (Store Largest) (Branch 01) (Write Largest) (Halt) (Variable Endvalue) (Variable Counter) (Variable Value) (Variable Largest) (Variable Increment)
(A Computer Simulator) It may at first seem outrageous, but in this problem you’re going to build your own computer. No, you won’t be soldering components together. Rather, you’ll use the powerful technique of software-based simulation to create a software model of the Simpletron. You’ll not be disappointed. Your Simpletron simulator will turn the computer you’re using into a Simpletron, and you’ll actually be able to run, test and debug the SML programs you wrote in Exercise 7.27. When you run your Simpletron simulator, it should begin by printing: 7.28
*** *** *** *** *** *** ***
Welcome to Simpletron! *** Please enter your program one instruction (or data word) at a time. I will type the location number and a question mark (?). You then type the word for that location. Type the sentinel -99999 to stop entering your program. ***
*** *** *** *** ***
Simulate the memory of the Simpletron with a single-subscripted array memory that has 100 elements. Now assume that the simulator is running, and let’s examine the dialog as we enter the program of Example 2 of Exercise 7.27: 00 01 02 03 04 05 06 07 08 09 10
? ? ? ? ? ? ? ? ? ? ?
+1009 +1010 +2009 +3110 +4107 +1109 +4300 +1110 +4300 +0000 +0000
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
Special Section: Building Your Own Computer
299
11 ? -99999 *** Program loading completed *** *** Program execution begins ***
The SML program has now been placed (or loaded) into the array memory. Now the Simpletron executes the SML program. It begins with the instruction in location 00 and, continues sequentially, unless directed to some other part of the program by a transfer of control. Use the variable accumulator to represent the accumulator register. Use the variable instructionCounter to keep track of the location in memory that contains the instruction being performed. Use the variable operationCode to indicate the operation currently being performed—i.e., the left two digits of the instruction word. Use the variable operand to indicate the memory location on which the current instruction operates. Thus, operand is the rightmost two digits of the instruction currently being performed. Do not execute instructions directly from memory. Rather, transfer the next instruction to be performed from memory to a variable called instructionRegister. Then “pick off” the left two digits and place them in the variable operationCode, and “pick off” the right two digits and place them in operand. When Simpletron begins execution, the special registers are initialized as follows: accumulator instructionCounter instructionRegister operationCode operand
+0000 00 +0000 00 00
Now let’s “walk through” the execution of the first SML instruction, +1009 in memory location 00. This is called an instruction execution cycle. The instructionCounter tells us the location of the next instruction to be performed. We fetch the contents of that location from memory by using the C statement instructionRegister = memory[ instructionCounter ];
The operation code and the operand are extracted from the instruction register by the statements operationCode = instructionRegister / 100; operand = instructionRegister % 100;
Now the Simpletron must determine that the operation code is actually a read (versus a write , a load , and so on). A switch differentiates among the twelve operations of SML. In the switch statement, the behavior of various SML instructions is simulated as follows (we leave the others to the reader): read: scanf( "%d", &memory[ operand ] ); load: accumulator = memory[ operand ]; add: accumulator += memory[ operand ]; Various branch instructions: We'll discuss these shortly. halt: This instruction prints the message *** Simpletron execution terminated ***
then prints the name and contents of each register as well as the complete contents of memory. Such a printout is often called a computer dump. To help you program your dump function, a sam-
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
Chapter 7
300
C Pointers: Solutions
ple dump format is shown in Fig. 7.33. A dump after executing a Simpletron program would show the actual values of instructions and data values at the moment execution terminated. REGISTERS: accumulator instructionCounter instructionRegister operationCode operand
+0000 00 +0000 00 00
MEMORY: 0 10 20 30 40 50 60 70 80 90
0 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000
1 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000
2 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000
3 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000
4 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000
5 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000
6 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000
7 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000
8 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000
9 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000
Fig. 7.33 | Sample Simpletron dump format. Let’s proceed with the execution of our program’s first instruction, namely the +1009 in location 00. As we have indicated, the switch statement simulates this by performing the C statement scanf( "%d", &memory[ operand ] );
A question mark (?) should be displayed on the screen before the scanf is executed to prompt the user for input. The Simpletron waits for the user to type a value and then press the Return key . The value is then read into location 09. At this point, simulation of the first instruction is completed. All that remains is to prepare the Simpletron to execute the next instruction. Since the instruction just performed was not a transfer of control, we need merely increment the instruction counter register as follows: ++instructionCounter;
This completes the simulated execution of the first instruction. The entire process (i.e., the instruction execution cycle) begins anew with the fetch of the next instruction to be executed. Now let’s consider how the branching instructions—the transfers of control—are simulated. All we need to do is adjust the value in the instruction counter appropriately. Therefore, the unconditional branch instruction ( 40) is simulated within the switch as instructionCounter = operand;
The conditional “branch if accumulator is zero” instruction is simulated as if ( accumulator == 0 ) { instructionCounter = operand; }
At this point, you should implement your Simpletron simulator and run the SML programs you wrote in Exercise 7.27. You may embellish SML with additional features and provide for these in your simulator. Your simulator should check for various types of errors. During the program loading phase, for example, each number the user types into the Simpletron’s memory must be in the range -9999 to +9999. Your simulator should use a while loop to test that each number entered is in this range, and, if not, keep prompting the user to reenter the nu mber until the user enters a correct number.
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
Special Section: Building Your Own Computer
301
During the execution phase, your simulator should check for various serious errors, such as attempts to divide by zero, attempts to execute invalid o peration codes and accumulator overflows (i.e., arithmetic operations resulting in values larger than +9999 or smaller than -9999). Such serious errors are called fatal errors. When a fatal error is detected, your simulator should print an error message such as: *** Attempt to divide by zero *** *** Simpletron execution abnormally terminated ***
and should print a full computer dump in the format we have discussed previously. This will help the user locate the error in the program. AN S:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
/* Exercise 7.28 Solution */ #include /* define commands */ #define SIZE 100 #define SENTINEL -99999 #define TRUE 1 #define FALSE 0 #define READ 10 #define WRITE 11 #define LOAD 20 #define STORE 21 #define ADD 30 #define SUBTRACT 31 #define DIVIDE 32 #define MULTIPLY 33 #define BRANCH 40 #define BRANCHNEG 41 #define BRANCHZERO 42 #define HALT 43 /* function prototypes */ void load( int *loadMemory ); void execute( int *memory, int *acPtr, int *icPtr, int *irPtr, int *opCodePtr, int *opPtr ); void dump( int *memory, int accumulator, int instructionCounter, int instructionRegister, int operationCode, int operand ); int validWord( int word ); int main() { int memory[ SIZE ]; /* define memory array */ int ac = 0; /* accumulator */ int ic = 0; /* instruction counter */ int opCode = 0; /* operation code */ int op = 0; /* operand */ int ir = 0; /* instruction register */ int i; /* counter */
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
302
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
Chapter 7
C Pointers: Solutions
/* clear memory */ for ( i = 0; i < SIZE; i++ ) { memory[ i ] = 0; } /* end for */ load( memory ); execute( memory, &ac, &ic, &ir, &opCode, &op ) ; dump( memory, ac, ic, ir, opCode, op ); return 0; /* indicate successful termination */ } /* end main */ /* function loads instructions */ void load( int *loadMemory ) { long int instruction; /* current instruction */ int i = 0; /* indexing variable */ printf( "%s\n\n%s\n%s\n%s\n%s\n%s\n%s\n\n", "*** Welcome to Simpletron ***", "*** Please enter your program one instruction ***", "*** ( or data word ) at a time. I will type the ***", "*** location number and a question mark ( ? ). ***", "*** You then type the word for that location. ***", "*** Type the sentinel -99999 to s top entering ***", "*** your program. ***" ); printf( "00 ? " ); scanf( "%ld", &instruction ); /* read instruction */ /* while sentinel is not read from user */ while ( instruction != SENTINEL ) { /* test instruction for validity */ if ( !validWord( instruction ) ) { printf( "Number out of range. Please enter again.\n" ); } /* end if */ else { /* load instruction */ loadMemory[ i++ ] = instruction; } /* end else */ printf( "%02d ? ", i ); scanf( "%ld", &instruction ); } /* end while */ } /* end function load */ /* carry out the commands */ void execute( int *memory, int *acPtr, int *icPtr, int *irPtr, int *opCodePtr, int *opPtr ) { int fatal = FALSE; /* fatal error flag */ int temp; /* temporary holding space */
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
Special Section: Building Your Own Computer
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
303
printf( "\n************START SIMPLETRON E XECUTION************\n\n" ); /* separate operation code and operand */ *irPtr = memory[ *icPtr ]; *opCodePtr = *irPtr / 100; *opPtr = *irPtr % 100; /* loop while command is not HALT or fatal */ while ( *opCodePtr != HALT && !fatal ) { /* determine appropriate action */ switch ( *opCodePtr ) { /* read data into location in memory */ case READ: printf( "Enter an integer: " ); scanf( "%d", &temp ); /* check for validity */ while ( !validWord( temp ) ) { printf( "Number out of range. Please enter again: " ); scanf( "%d", &temp ); } /* end while */ memory[ *opPtr ] = temp; /* write to memory */ ++( *icPtr ); break; /* exit switch */ /* write data from memory to screen */ case WRITE: printf( "Contents of %02d: %d\n", *opPtr, memory[ *opPtr ] ); ++( *icPtr ); break; /* exit switch */ /* load data from memory into accumulator */ case LOAD: *acPtr = memory[ *opPtr ]; ++( *icPtr ); break; /* exit switch */ /* store data from accumulator into memory */ case STORE: memory[ *opPtr ] = *acPtr; ++( *icPtr ); break; /* exit switch */ /* add data from memory to data in accumulator */ case ADD: temp = *acPtr + memory[ *opPtr ]; /* check validity */ if ( !validWord( temp ) ) { printf( "*** FATAL ERROR: Accumulator overflow ***\n" ); printf( "*** Simpletron execution " );
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
304
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
Chapter 7
C Pointers: Solutions
printf( "abnormally terminated ***\n" ); fatal = TRUE; } /* end if */ else { *acPtr = temp; ++( *icPtr ); } /* end else */ break; /* exit switch */ /* subtract data in memory from data in accumulator */ case SUBTRACT: temp = *acPtr - memory[ *opPtr ]; /* check validity */ if ( !validWord( temp ) ) { printf( "*** FATAL ERROR: Accumulator overflow ***\n" ); printf( "*** Simpletron execution " ); printf( "abnormally terminated ***\n" ); fatal = TRUE; } /* end if */ else { *acPtr = temp; ++( *icPtr ); } /* end else */ break; /* exit switch */ /* divide data in memory into data in accumulator */ case DIVIDE: /* check for divide by zero error */ if ( memory[ *opPtr ] == 0 ) { printf("*** FATAL ERROR: Attempt to divide by zero ***\n"); printf( "*** Simpletron execution " ); printf( "abnormally terminated ***\n" ); fatal = TRUE; } /* end if */ else { *acPtr /= memory[ *opPtr ]; ++( *icPtr ); } /* end else */ break; /* exit switch */ /* multiply data in memory by data in accumulator */ case MULTIPLY: temp = *acPtr * memory[ *opPtr ]; /* check validity */ if ( !validWord( temp ) ) { printf( "*** FATAL ERROR: Accumulator overflow ***\n" ); printf( "*** Simpletron execution " ); printf( "abnormally terminated ***\n" );
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
Special Section: Building Your Own Computer
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256
305
fatal = TRUE; } /* end if */ else { *acPtr = temp; ++( *icPtr ); } /* end else */ break; /* exit switch */ /* branch to specific location in m emory */ case BRANCH: *icPtr = *opPtr; break; /* exit switch */ /* branch to location in memory if accumulator is negative */ case BRANCHNEG: /* if accumulator is negative */ if ( *acPtr < 0 ) { *icPtr = *opPtr; } /* end if */ else { ++( *icPtr ); } /* end else */ break; /* exit switch */ /* branch to location in memory if accumulator is zero */ case BRANCHZERO: /* if accumulator is zero */ if ( *acPtr == 0 ) { *icPtr = *opPtr; } /* end if */ else { ++( *icPtr ); } /* end else */ break; /* exit switch */ default: printf( "*** FATAL ERROR: Invalid opcode detected ***\n" ); printf( "*** Simpletron execution " ); printf( "abnormally terminated ***\n" ); fatal = TRUE; break; /* exit switch */ } /* end switch */ /* separate next operation code and operand */ *irPtr = memory[ *icPtr ]; *opCodePtr = *irPtr / 100; *opPtr = *irPtr % 100; } /* end while */
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
306
257 258 259 260 261 262 263 264 265 266 267
Chapter 7
C Pointers: Solutions
printf( "\n*************END SIMPLETRON EX ECUTION*************\n" ); } /* end function execute */ /* print out name and content of each register and memory */ void dump( int *memory, int accumulator, int instructionCounter, int instructionRegister, int operationCode, int operand ) { int i; /* counter */
printf("\n%s\n%-23s%+05d\n%-23s%5.2d\n%-23s%+05d\n%-23s%5.2d\n%23s%5.2d", "REGISTERS:", "accumulator", accumulator, "instructioncounter", 268 269 instructionCounter, "instructionregister", instructionRegister, "operationcode", operationCode, "operand", operand ); 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298
printf( "\n\nMEMORY:\n
" );
/* print column headers */ for ( i = 0; i <= 9; i++ ) { printf( "%5d ", i ); } /* end for */ /* print row headers and memory contents */ for ( i = 0; i < SIZE; i++ ) { /* print in increments of 10 */ if ( i % 10 == 0 ) { printf( "\n%2d ", i ); } /* end if */ printf( "%+05d ", memory[ i ] ); } /* end for */ printf( "\n" ); } /* end function dump */ /* function tests validity of word */ int validWord( int word ) { return word >= -9999 && word <= 9999; } /* end function validWord */
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
Special Section: Building Your Own Computer
***
Welcome to Simpletron
*** *** *** *** *** *** 00 01 02 03 04 05 06 07 08 09 10
307
***
Please enter your program one instruction *** ( or data word ) at a time. I will type the *** location number and a question mark ( ? ). *** You then type the word for that location. *** Type the sentinel -99999 to stop entering *** your program. ***
? ? ? ? ? ? ? ? ? ? ?
1007 1008 2007 3008 2109 1109 4300 0000 0000 0000 -99999
************START SIMPLETRON EXECUTION************ Enter an integer: 23 Enter an integer: 17 Contents of 09: 40 *************END SIMPLETRON EXECUTION************* REGISTERS: accumulator instructioncounter instructionregister operationcode operand
+0040 06 +4300 43 00
MEMORY: 0 10 20 30 40 50 60 70 80 90
0 +1007 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000
1 +1008 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000
2 +2007 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000
3 +3008 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000
4 +2109 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000
5 +1109 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000
6 +4300 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000
7 +0023 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000
8 +0017 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000
9 +0040 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000
( Modifications to the Simpletron Simulator ) In Exercise 7.28, you wrote a software simulation of a computer that executes programs written in Simpletron Machine Language (SML). In this exercise, we propose several modifications and enhancements to the Simpletron Simulator. In Exercises 12.26 and 12.27, we propose building a compiler that converts programs written in a high-level programming language (a variation of BASIC) to Simpletron Machine Language. Some of the following modifications and enhancements may be required to execute the programs produced by the compiler. a) Extend the Simpletron Simulator’s memory to contain 1000 memory locations to enable the Simpletron to handle larger programs. b) Allow the simulator to perform remainder calculations. This requires an additional Simpletron Machine Language instruction. c) Allow the simulator to perform exponentiation calculations. This requires an additional Simpletron Machine Language instruction. 7.29
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.
308
Chapter 7
C Pointers: Solutions
d) Modify the simulator to use hexadecimal values rather than integer values to represent Simpletron Machine Language instructions. e) Modify the simulator to allow output of a newline. This requires an additional Simpletron Machine Language instruction. f) Modify the simulator to process floating-point values in addition to integer values. g) Modify the simulator to handle string input. [Hint: Each Simpletron word can be divided into two groups, each holding a two-digit integer. Each two-digit integer represents the ASCII decimal equivalent of a character. Add a machine-language instruction that will input a string and store the string beginning at a specific Simpletron memory location. The first half of the word at that location will be a count of the number of characters in the string (i.e., the length of the string). Each succeeding half word contains one ASCII character expressed as two decimal digits. The machine-language instruction converts each character into its ASCII equivalent and assigns it to a half word.] h) Modify the simulator to handle output of strings stored in the format of part (g). [ Hint: Add a machine-language instruction that prints a string beginning at a specified Simpletron memory location. The first half of the word at that location is the length of the string in characters. Each succeeding half word contains one ASCII character expressed as two decimal digits. The machine-language instruction checks the length and prints the string by translating each two-digit number into its equivalent character.]
Array of Function Pointer Exercises (Calculating Circle Circumference, Circle Area or Sphere Volume Using Function Pointers) Using the techniques you learned in Fig. 7.28, create a text-based, menu-driven program that allows the user to choose whether to calculate the circumference of a circle, the area of a circle or the volume of a sphere. The program should then input a radius from the user, perform the appropriate calculation and display the result. Use an array of function pointers in which each pointer represents a function that returns void and receives a double parameter. The corresponding functions should each display messages indicating which calculation was performed, the value of the radius and the result of the calculation. AN S: See the solution in the file Circle.c with this chapter’s exercise solutions. 7.30
(Calculator Using Function Pointers) Using the techniques you learned in Fig. 7.28, create a text-based, menu-driven program that allows the user to choose whether to add, subtract, multiply or divide two numbers. The program should then input two double values from the user, perform the appropriate calculation and display the result. Use an array of function pointers in which each pointer represents a function that returns void and receives two double parameters. The corresponding functions should each display messages indicating which calculation was performed, the values of the parameters and the result of the calculation. AN S: See the solution in the file Calculator.c with this chapter’s exercise solutions. 7.31
Making a Difference (Polling) The Internet and the web are enabling more people to ne twork, join a cause, voice opinions, and so on. The U.S. presidential candidates in 2008 used the Internet intensively to get out their messages and raise money for their campaigns. In this e xercise, you’ll write a simple polling program that allows users to rate five social-consciousness issues from 1 (least important) to 10 (most important). Pick five causes that are important to you (e.g., political issues, global environmental issues). Use a one-dimensional array topics (of type char *) to store the five causes. To summarize the survey responses, use a 5-row, 10-column two-dimensional array responses (of type int), each row corresponding to an element in the topics array. When the program runs, it should 7.32
© 2010 Pearson Education, Inc., Upper Saddle River, NJ. All Rights Reserved.