The document discusses a case study on card shuffling and dealing simulation using arrays and pointers in C programming. It details the pseudocode and implementation of functions for shuffling and dealing cards, as well as the concept of function pointers for sorting algorithms. Additionally, it covers memory allocation types, emphasizing static and dynamic memory management in programming.
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0 ratings0% found this document useful (0 votes)
2 views
CHTP5e_07-Pointers 4
The document discusses a case study on card shuffling and dealing simulation using arrays and pointers in C programming. It details the pseudocode and implementation of functions for shuffling and dealing cards, as well as the concept of function pointers for sorting algorithms. Additionally, it covers memory allocation types, emphasizing static and dynamic memory management in programming.
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 31
1
7.11 Case Study: Card Shuffling and
Dealing Simulation Card shuffling program • Use array of pointers to strings • Use double subscripted array (suit, face) • The numbers 1-52 go into the array - Representing the order in which the cards are dealt 2
Performance Tip
• Sometimes an algorithm that emerges in a
“natural” way can contain subtle performance problems, such as indefinite postponement
• Seek algorithms that avoid indefinite
postponement. 3
Double-subscripted array representation of a deck of cards.
Element positions (row, col) = represent the card Element value = represent the order of the card 4
7.11 Case Study: Card Shuffling and
Dealing Simulation Pseudocode – Top level: Shuffle and deal 52 cards – First refinement: Initialize the suit array Initialize the face array Initialize the deck array Shuffle the deck Deal 52 cards 5
7.11 Case Study: Card Shuffling and
Dealing Simulation – Second refinement - Convert shuffle the deck to For each of the 52 cards Place card number in randomly selected unoccupied slot of deck - Convert deal 52 cards to For each of the 52 cards Find card number in deck array and print face and suit of card 6
7.11 Case Study: Card Shuffling and
Dealing Simulation – Third refinement - Convert shuffle the deck to Choose slot of deck randomly While chosen slot of deck has been previously chosen Choose slot of deck randomly Place card number in chosen slot of deck - Convert deal 52 cards to For each slot of the deck array If slot contains card number Print the face and suit of the card 1 /* Fig. 7.24: fig07_24.c 7 2 Card shuffling dealing program */ 3 #include <stdio.h> 4 #include <stdlib.h> 5 #include <time.h> 6 7 /* prototypes */ 8 void shuffle( int wDeck[][ 13 ] ); 9 void deal( const int wDeck[][ 13 ], const char *wFace[], 10 const char *wSuit[] ); 11 12 int main( void ) 13 { 14 /* initialize suit array */ 15 const char *suit[ 4 ] = { "Hearts", "Diamonds", "Clubs", "Spades" }; 16 17 /* initialize face array */ 18 const char *face[ 13 ] = suit and face arrays are 19 { "Ace", "Deuce", "Three", "Four", arrays of pointers 20 "Five", "Six", "Seven", "Eight", 21 "Nine", "Ten", "Jack", "Queen", "King" }; 22 23 /* initialize deck array */ 24 int deck[ 4 ][ 13 ] = { 0 }; 25 26 srand( time( 0 ) ); /* seed random-number generator */ 27 28 shuffle( deck ); 29 deal( deck, face, suit ); 30 31 return 0; /* indicates successful termination */ 32 33 } /* end main */ 34 35 /* shuffle cards in deck */ 36 void shuffle( int wDeck[][ 13 ] ) 37 { 38 int row; /* row number */ 39 int column; /* column number */ 40 int card; /* counter */ 41 42 /* for each of the 52 cards, choose slot of deck randomly */ 43 for ( card = 1; card <= 52; card++ ) { 44 45 /* choose new random location until unoccupied slot found */ 46 do { do…while loop selects a 47 row = rand() % 4; 48 column = rand() % 13; random spot for each card 49 } while( wDeck[ row ][ column ] != 0 ); /* end do...while */ 50 51 /* place card number in chosen slot of deck */ 9 52 wDeck[ row ][ column ] = card; 53 } /* end for */ 54 55 } /* end function shuffle */ 56 57 /* deal cards in deck */ 58 void deal( const int wDeck[][ 13 ], const char *wFace[], 59 const char *wSuit[] ) 60 { 61 int card; /* card counter */ 62 int row; /* row counter */ 63 int column; /* column counter */ 64 65 /* deal each of the 52 cards */ 66 for ( card = 1; card <= 52; card++ ) { 67 /* loop through rows of wDeck */ 68 69 for ( row = 0; row <= 3; row++ ) { 70 71 /* loop through columns of wDeck for current row */ 72 for ( column = 0; column <= 12; column++ ) { 73 10 74 /* if slot contains current card, display card */ 75 if ( wDeck[ row ][ column ] == card ) { 76 printf( "%5s of %-8s%c", wFace[ column ], wSuit[ row ], 77 card % 2 == 0 ? '\n' : '\t' ); 78 } /* end if */ 79 80 } /* end for */ 81 82 } /* end for */ 83 84 } /* end for */ 85 86 } /* end function deal */ 11 Nine of Hearts Five of Clubs Queen of Spades Three of Spades Queen of Hearts Ace of Clubs King of Hearts Six of Spades Jack of Diamonds Five of Spades Seven of Hearts King of Clubs Three of Clubs Eight of Hearts Three of Diamonds Four of Diamonds Queen of Diamonds Five of Diamonds Six of Diamonds Five of Hearts Ace of Spades Six of Hearts Nine of Diamonds Queen of Clubs Eight of Spades Nine of Clubs Deuce of Clubs Six of Clubs Deuce of Spades Jack of Clubs Four of Clubs Eight of Clubs Four of Spades Seven of Spades Seven of Diamonds Seven of Clubs King of Spades Ten of Diamonds Jack of Hearts Ace of Hearts Jack of Spades Ten of Clubs Eight of Diamonds Deuce of Diamonds Ace of Diamonds Nine of Spades Four of Hearts Deuce of Hearts King of Diamonds Ten of Spades Three of Hearts Ten of Hearts 12
7.12 Pointers to Functions
Pointer to function • Contains address of function • Similar to how array name is address of first element • Function name is starting address of code that defines function Function pointers can be • Passed to functions • Stored in arrays • Assigned to other function pointers 13
7.12 Pointers to Functions
Example: bubblesort – Function bubble takes a function pointer - bubble calls this helper function - this determines ascending or descending sorting – The argument in bubblesort for the function pointer: int ( *compare )( int a, int b ) tells bubblesort to expect a pointer to a function that takes two ints and returns an int – If the parentheses were left out: int *compare( int a, int b ) - Defines a function that receives two integers and returns a pointer to a int 1 /* Fig. 7.26: fig07_26.c 14 2 Multipurpose sorting program using function pointers */ 3 #include <stdio.h> 4 #define SIZE 10 5 6 /* prototypes */ 7 void bubble( int work[], const int size, int (*compare)( int a, int b ) ); 8 int ascending( int a, int b ); 9 int descending( int a, int b ); 10 bubble function takes a function 11 int main( void ) pointer as an argument 12 { 13 int order; /* 1 for ascending order or 2 for descending order */ 14 int counter; /* counter */ 15 16 /* initialize array a */ 17 int a[ SIZE ] = { 2, 6, 4, 8, 10, 12, 89, 68, 45, 37 }; 18 19 printf( "Enter 1 to sort in ascending order,\n" 20 "Enter 2 to sort in descending order: " ); 21 scanf( "%d", &order ); 22 23 printf( "\nData items in original order\n" ); 24 25 /* output original array */ 26 for ( counter = 0; counter < SIZE; counter++ ) { 27 printf( "%5d", a[ counter ] ); 28 } /* end for */ 29 30 /* sort array in ascending order; pass function ascending as an 15 31 argument to specify ascending sorting order */ 32 if ( order == 1 ) { 33 bubble( a, SIZE, ascending ); 34 printf( "\nData items in ascending order\n" ); 35 } /* end if */ 36 else { /* pass function descending */ 37 bubble( a, SIZE, descending ); 38 printf( "\nData items in descending order\n" ); 39 } /* end else */ 40 depending on the user’s choice, the bubble 41 /* output sorted array */ function uses either the ascending or 42 for ( counter = 0; counter < SIZE; counter++ ) { descending function to sort the array 43 printf( "%5d", a[ counter ] ); 44 } /* end for */ 45 46 printf( "\n" ); 47 48 return 0; /* indicates successful termination */ 49 50 } /* end main */ 51 52 /* multipurpose bubble sort; parameter compare is a pointer to 16 53 the comparison function that determines sorting order */ 54 void bubble( int work[], const int size, int (*compare)( int a, int b ) ) 55 { 56 int pass; /* pass counter */ 57 int count; /* comparison counter */ 58 59 void swap( int *element1Ptr, int *element2ptr ); /* prototype */ 60 61 /* loop to control passes */ 62 for ( pass = 1; pass < size; pass++ ) { 63 64 /* loop to control number of comparisons per pass */ 65 for ( count = 0; count < size - 1; count++ ) { 66 67 /* if adjacent elements are out of order, swap them */ 68 if ( (*compare)( work[ count ], work[ count + 1 ] ) ) { 69 swap( &work[ count ], &work[ count + 1 ] ); 70 } /* end if */ 71 72 } /* end for */ Note that what the program considers 73 “out of order” is dependent on the 74 } /* end for */ function pointer that was passed to 75 the bubble function 76 } /* end function bubble */ 77 78 /* swap values at memory locations to which element1Ptr and 17 79 element2Ptr point */ 80 void swap( int *element1Ptr, int *element2Ptr ) 81 { 82 int hold; /* temporary holding variable */ 83 84 hold = *element1Ptr; 85 *element1Ptr = *element2Ptr; 86 *element2Ptr = hold; 87 } /* end function swap */ 88 89 /* determine whether elements are out of order for an ascending 90 order sort */ 91 int ascending( int a, int b ) Passing the bubble function ascending 92 { will point the program here 93 return b < a; /* swap if b is less than a */ 94 95 } /* end function ascending */ 96 97 /* determine whether elements are out of order for a descending 98 order sort */ 99 int descending( int a, int b ) 100 { Passing the bubble function descending 101 return b > a; /* swap if b is greater than a */ will point the program here 102 103 } /* end function descending */ 18 Enter 1 to sort in ascending order, Enter 2 to sort in descending order: 1
Data items in original order
2 6 4 8 10 12 89 68 45 37 Data items in ascending order 2 4 6 8 10 12 37 45 68 89
Enter 1 to sort in ascending order,
Enter 2 to sort in descending order: 2
Data items in original order
2 6 4 8 10 12 89 68 45 37 Data items in descending order 89 68 45 37 12 10 8 6 4 2 1 /* Fig. 7.28: fig07_28.c 19 2 Demonstrating an array of pointers to functions */ 3 #include <stdio.h> 4 5 /* prototypes */ 6 void function1( int a ); 7 void function2( int b ); 8 void function3( int c ); 9 10 int main( void ) 11 { 12 /* initialize array of 3 pointers to functions that each take an 13 int argument and return void */ 14 void (*f[ 3 ])( int ) = { function1, function2, function3 }; 15 16 int choice; /* variable to hold user's choice */ Array of pointers to functions 17 18 printf( "Enter a number between 0 and 2, 3 to end: " ); 19 scanf( "%d", &choice ); 20 21 /* process user's choice */ 20 22 while ( choice >= 0 && choice < 3 ) { 23 24 /* invoke function at location choice in array f and pass 25 choice as an argument */ 26 (*f[ choice ])( choice ); 27 Function called is dependent on user’s choice 28 printf( "Enter a number between 0 and 2, 3 to end: "); 29 scanf( "%d", &choice ); 30 } /* end while */ 31 32 printf( "Program execution completed.\n" ); 33 34 return 0; /* indicates successful termination */ 35 36 } /* end main */ 37 38 void function1( int a ) 39 { 40 printf( "You entered %d so function1 was called\n\n", a ); 41 } /* end function1 */ 42 43 void function2( int b ) 44 { 45 printf( "You entered %d so function2 was called\n\n", b ); 46 } /* end function2 */ 47 21 48 void function3( int c ) 49 { 50 printf( "You entered %d so function3 was called\n\n", c ); 51 } /* end function3 */
Enter a number between 0 and 2, 3 to end: 0
You entered 0 so function1 was called
Enter a number between 0 and 2, 3 to end: 1
You entered 1 so function2 was called
Enter a number between 0 and 2, 3 to end: 2
You entered 2 so function3 was called
Enter a number between 0 and 2, 3 to end: 3
Program execution completed. Memory Allocation There are essentially two types of memory allocation Static – Done by the compiler automatically (implicitly). Global variables or objects -- memory is allocated at the start of the program, and freed when program exits; alive throughout program execution Can be access anywhere in the program. Local variables (inside a routine) – memory is allocated when the routine starts and freed when the routine returns. A local variable cannot be accessed from another routine. Allocation and free are done implicitly. No need to explicitly manage memory is nice (easy to work with), but has limitations! Memory Allocation There are essentially two types of memory allocation Wouldn’t it be nice to be able to have an array whose size can be adjusted depending on needs. Dynamic memory allocation deals with this situation.
Dynamic – Done explicitly by programmer.
Programmer explicitly requests the system to allocate memory and return starting address of memory allocated. This address can be used by the programmer to access the allocated memory. When done using memory, it must be explicitly freed. Memory Allocation
• Although C language inherently does not has any
technique to allocated memory dynamically, there are 4 library functions under "stdlib.h" for dynamic memory allocation.
Function Use of Function
Allocates requested size of bytes and returns a
malloc() pointer first byte of allocated space Allocates space for an array elements, initializes calloc() to zero and then returns a pointer to memory free() Deallocate the previously allocated space realloc() Change the size of previously allocated space Memory Allocation • malloc() • The name malloc stands for "memory allocation". The function malloc() reserves a block of memory of specified size and return a pointer of type void which can be casted into pointer of any form. • Syntax of malloc() ptr=(cast-type*)malloc(byte-size) • Here, ptr is pointer of cast-type. The malloc() function returns a pointer to an area of memory with size of byte size. If the space is insufficient, allocation fails and returns NULL pointer. ptr=(int*)malloc(100*sizeof(int)); Memory Allocation • calloc() • The name calloc stands for "contiguous allocation". The only difference between malloc() and calloc() is that, malloc() allocates single block of memory whereas calloc() allocates multiple blocks of memory each of same size and sets all bytes to zero. • Syntax of calloc() ptr=(cast-type*)calloc(n,element-size); • This statement will allocate contiguous space in memory for an array of n elements. For example: ptr=(float*)calloc(25,sizeof(float)); • This statement allocates contiguous space in memory for an array of 25 elements each of size of float, i.e, 4 bytes. Memory Allocation • free() • Dynamically allocated memory with either calloc() or malloc() does not get return on its own. The programmer must use free() explicitly to release space. • syntax of free() free(ptr); • This statement cause the space in memory pointer by ptr to be deallocated. Examples 1 of calloc() and malloc() Examples 2 of calloc() and malloc() Memory Allocation • realloc() • If the previously allocated memory is insufficient or more than sufficient. Then, you can change memory size previously allocated using realloc(). • Syntax of realloc() realloc(ptr,newsize); • Here, ptr is reallocated with size of newsize. realloc()