Bad code analysis -- "we wrote the book C language (Second Edition)" 21 point pr

Recommended for you: Get network issues from WhatsUp Gold. Not end users.

  To examine the overall structure of the main ().

29. main()
30. {
31.    int numCards;
32.    int cards[52],playerPoints[2],dealerPoints[2],total[2];
33.    char ans;
34.    
35.    do 
36.    { 
37.       initCardsScreen(cards,playerPoints,dealerPoints,total, &numCards);
38.       dealerGetsCard(&numCards,cards, dealerPoints);
39.       printf("\n");
40.       playerGetsCard(&numCards,cards,playerPoints); 
41.       playerGetsCard(&numCards,cards,playerPoints);
42.       do
43.       {
44.          ans = getAns("Hit or stand (H/S)?");
45.          if ( ans == 'H' )
46.          { 
47.             playerGetsCard(&numCards,cards,playerPoints);
48.          }  
49.       }
50.       while( ans != 'S' );
51.       
52.       totalIt(playerPoints,total,PLAYER);
53.       do
54.       {
55.          dealerGetsCard(&numCards,cards,dealerPoints);
56.       }
57.       while (dealerPoints[ACEHIGH] <17 );
58.       
59.       totalIt(dealerPoints,total,DEALER);
60.       findWinner(total); 
61.       
62.       ans = getAns("\nPlay again(Y/N)?");  
63.    }
64.    while(ans=='Y');
65.    
66.    return 0;
67. }
68. 

   main()The DO-WHILE statement in the loop body function is the meaning of this

35.    do 
36.    { 
              /*21 point game*/
62.       ans = getAns("\nPlay again(Y/N)?");  /*Asked whether to continue*/
63.    }
64.    while ( ans == 'Y' ); 

   Compared with the following wording, both structures in the logic of the difference is very obvious

    do 
    { 
             /*21 point game*/
    }
    while(  getAns("\nPlay again(Y/N)?") == 'Y' );  /*Asked whether to continue*/

   The loop body to do two things, more precisely to do 1.5 things, because &ldquo asked whether to continue; ” not completely clean, kicked the door kicked in the door, do things sloppily. And the writing in the body of the loop only focus on one thing, this thing does not appear together with another thing, but in a different part of the DO-WHILE statement, there is a clear demarcation line.

  Even from this perspective, also not in favor of the original code using the ANS variable method.

  Neither should take different things (“ 21 point game ” and “ ask whether to continue ”) stir together, also should not have a thing (“ asked whether to continue ”) was divided into two parts separated in different parts of the DO-WHILE statement.

  Now back to the loop body, see the simulation process of 21 point game to complete the.  

37.       initCardsScreen(cards,playerPoints,dealerPoints,total, &numCards);

   The main purpose of this statement is the implementation of the program data initialization. The intuitive feeling is that the parameters of this function is too much, usually a sign of data structure design of failure.  

16. void initCardsScreen(int cards[52],int playerPoints[2],
17. int dealerPoints[2], int total[2], 
18. int *numCards);

   This function a type declaration written is not standard. [] within the 52,2,2,2 unnecessary, code alignment is also a problem. Should be:

 void initCardsScreen( int cards[] ,int playerPoints[] ,
       int dealerPoints[] , int total[] , 
                   int *numCards ) ;

   Similarly, the function definition in the corresponding

69. void initCardsScreen( int cards[52],int playerPoints[2],
70.                       int dealerPoints[2], int total[2], 
71.                       int *numCards )
72. {
73.    int sub,val = 1 ;
74.    char firstName[15];
75.    *numCards=52;
76.    
77.    for(sub=0;sub<=51;sub++)
78.    {
79.       val = (val == 14) ? 1 : val;
80.       cards[sub] = val;
81.       val++;  
82.    }
83.    
84.    for(sub=0;sub<=1;sub++)
85.    { 
86.       playerPoints[sub]=dealerPoints[sub]=total[sub]=0;
87.    }
88.    dispTitle();
89.    
90.    if (askedForName==0)
91.    { 
92.       printf("What is your first name?");
93.       scanf(" %s",firstName);
94.       askedForName=1;
95.       printf("Ok, %s,get ready for casino action!\n\n",firstName);
96.       getchar();
97.    }
98.    return;        
99. }

 In the function of the head, also should do similar amendments

 void initCardsScreen( int cards[],int playerPoints[],
                       int dealerPoints[], int total[], 
                       int *numCards )

   Because the parameter is not an array, [] within the content regardless of how much the compiler will be ignored. Writing is white to write, write it very?

  The name numCards for this parameter is very bad, it is a pointer, but even with the variable to which it points with the same name. This kind of writing code author lacks the basic programming knowledge.

  initCardsScreen()According to the authors describe the function code is array initialization said 52 cards (written in the 4 set of 1~13), screen and display the title. From the functional description is sufficient to establish that design of this function are very failure — — its function is too much. The function should only do one thing.

  In the function body 

75.    *numCards=52;

 A word, very make such a fuss about, because this is completely useless. As long as the main (in vivo) cycle in the DO-WHILE statement in a sentence 

numCards = 52 ;

 You can, by the function call for the variable numCards is initialized is simply not worth.

  Read here, is not difficult to find that in main () of these variables in the definition of the position is not right, these variables should be defined in the DO-WHILE statement.  

   do 
    { 
      int numCards = 52 ;
      int cards[52],playerPoints[2],dealerPoints[2],total[2];

          /*21 point game*/
    }
    while(  getAns("\nPlay again(Y/N)?") == 'Y' );  /*Asked whether to continue*/

   Variable definitions should as far as possible localization.  

77.    for(sub=0;sub<=51;sub++)
78.    {
79.       val = (val == 14) ? 1 : val;
80.       cards[sub] = val;
81.       val++;  
82.    }

   This way of writing very amateur, and the 51 is a Magic Number, and 14. A professional is written 

    for ( sub = 0 ; sub <52 ; sub++ )
    {
       cards [ sub ]  =  sub  %  13  +  1 ;
    }

   So Val this variable also is redundant.


84.    for(sub=0;sub<=1;sub++)
85.    { 
86.       playerPoints[sub]=dealerPoints[sub]=total[sub]=0;
87.    }

   “sub<=1”Writing is an amateur, professional staff is usually written as“ sub <2 ”.

  “playerPoints[sub]=dealerPoints[sub]=total[sub]=0;”This writing will usually be criticized, elegant demeanor programmers often write:  

  playerPoints[sub]
= dealerPoints[sub]
= total[sub]
= 0 ;

   Also should notice is, the individual elements of the array as the initialized to 0, actually also need not through function calls so complicated to realize, the most simple initialization methods in the main () in direct initialization:

    do 
    { 
      int numCards = 52 ;
      int cards[52] , 
            playerPoints[2] = { 0 } ,
            dealerPoints[2] = { 0 } ,
            total[2] = { 0 } ;

          /*21 point game*/
    }
    while( getAns("\nPlay again(Y/N)?") == 'Y' );  /*Asked whether to continue*/

   Conclusion a rare: variables defined position properly, will make the code very clumsy, will bring you a lot of trouble. It can also confirm that the initCardsScreen () over the function parameters, in fact the cards[] only need to initialize the array.  

88.    dispTitle();

   This line of code according to the author said is clear, but the function call initCardsScreen () this function is obviously a dislocation. From the definition of this function at

215. void dispTitle(void)
216. {
217.    int i = 0 ;
218.    while(i<25)
219.    { 
220.         printf("\n");
221.         i++; 
222.    }
223.    printf("\n\n*Step right up to the Blackjack tables*\n\n");
224.    return ;
225. }

   Its role is to output 25 newline characters, then the output string"\n\n*Step right up to the Blackjack tables*\n\n". Note that, at this time the cursor to the bottom left of the screen, while the real clear screen, the cursor is in the top left of the screen. So the author thinks himself wrote a “ the function of &rdquo than the function usually use more special, apparently just wishful thinking; an illusion, he wrote so “ ”, have to is not the function of the degree.

  If purely from the way of speaking, this function is written is also very poor. The following notation to clean more.  

void dispTitle( void )
{
   int i ;
   for( i = 0 ; i <25 ; i ++ )
   {
        putchar('\n');
   }
   puts("\n\n*Step right up to the Blackjack tables*\n");
}

   Now to initCardsScreen () function definition part.

90.    if (askedForName==0)
91.    { 
92.       printf("What is your first name?");
93.       scanf(" %s",firstName);
94.       askedForName=1;
95.       printf("Ok, %s,get ready for casino action!\n\n",firstName);
96.       getchar();
97.    }

   This code, a lot of problems. First of all, this code should not appear in the initCardsScreen () function is defined and initialized, because it never mind.

  Secondly, even if there is, should also like dispTitle () as abstract as a function as well.

  Third, now finally understand the author of code set askedForName the external variables of the intention, but the intention is stupid and clumsy. It should be arranged in main (in), generally written as follows

int main(void)
{
   char firstName[15];

   dispTitle();
   /*Here, read firstName*/

   do{
        /*21 point game*/
   }while( getAns("\nPlay again(Y/N)?") == 'Y' );  /*Asked whether to continue*/

   return 0;
}

   There is no need to clumsy and stupid to use external variables are dangerous, that writing is totally beginner level, in the book to other beginners as demonstration is extremely irresponsible behavior.

  See here some speechless … …, what can I say? I use words to describe, “ failure of failure”.

  Fourth, the authors claim 

96.       getchar();

 Causes the compiler warning, and readers to feel at ease and justified to ignore this warning (ignore compiler warning here). To tell you the truth, I have seen this as a separate call getchar () function without the use of the return value of the warning, but readers ignore warning is a misleading and instigation.

  Here if there is a warning, should be removed by the following method:

(void) getchar();

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download

Posted by Conrad at November 16, 2013 - 3:27 AM