程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> C語言初學者代碼中的常見錯誤與瑕疵(7)

C語言初學者代碼中的常見錯誤與瑕疵(7)

編輯:關於C語言

矩形的個數     在一個3*2的矩形中,可以找到6個1*1的矩形,4個2*1的矩形3個1*2的矩形,2個2*2的矩形,2個3*1的矩形和1個3*2的矩形,總共18個矩形。給出A,B,計算可以從中找到多少個矩形     輸入:   本題有多組輸入數據(<10000),你必須處理到EOF為止     輸入2個整數A,B(1<=A,B<=1000)     輸出:     輸出找到的矩形數。     樣例:   輸入:   1 2  3 2     輸出:  3  18    原代碼-1: 復制代碼 #include <stdio.h> int rectangle(int x,int y) {     int i,j,sum,temp;       for(i=1,sum=0,temp=0;i<=x;i++)     {         for(j=1;j<=y;j++)         {             temp = (x-i+1)*(y-j+1);             sum += temp;         }     }       return sum; }   int main() {     long int A[1000],B[1000],i;     int rectangle(int x,int y);     //printf("input A&B and end with 0\n");       for(i=0;i<1000;i++)     {         scanf("%d",&A[i]);                  if (A[i]==0)         {             break;         }           scanf("%d",&B[i]);     }       for(i=0;A[i]!=0;i++)     {         printf("%d\n",rectangle(A[i],B[i]));     }       return 0; } 復制代碼  評析:    寫完之後這位小朋友坦率地承認:   露珠不知道如何以EOF結尾..只好用0了...哪位指點下..      我告訴他,   沒必要用數組  while( scanf("%d%d", &A,&B)!=EOF )  {       //計算輸出矩形個數  }   於是他很快給出了新代碼:    原代碼-2: 復制代碼 #include <stdio.h> int rectangle(int x,int y) {     int i,j,sum,temp;       for(i=1,sum=0,temp=0;i<=x;i++)     {         for(j=1;j<=y;j++)         {             temp = (x-i+1)*(y-j+1);             sum += temp;         }     }       return sum; }   int main() {     long int A,B;     int rectangle(int x,int y);     printf("input A&B and end with EOF\n");       while(scanf("%d%d",&A,&B)!= EOF)     {         printf("%d\n",rectangle(A,B));     }       return 0; } 復制代碼 評析:   這次好多了。不過他又有了新的困惑:   我修改成這樣之後,比如我先輸入 2 3 跳出來 18,輸入eof 就一直跳 18 停止不了了...  總之就是一直跳最後一次出來的結果 ..   看來他不清楚EOF是怎麼回事,還以為是在鍵盤上鍵入eof三個字符呢。     我告訴他:   EOF不是三個字符  而是一個符號常量  如果你用的是WIN系統  在行首輸入Control-Z試試     實際上EOF是在stdio.h中定義的一個宏,通常是這樣的    #define    EOF    (-1)   不過C語言並沒說EOF一定為-1。     在鍵盤上是沒有這個EOF的,但在輸入流中遇到特殊的字符,scanf()函數的返回值可以是EOF。那麼,這句話究竟是什麼意思呢?     通常scanf()的返回值是一個非負整數。比如   int i; scanf("%d", &i ) ;   如果你在鍵盤上鍵入的是123(1、2、3與%d相匹配),scanf("%d", &i )的值就為1,因為為1個變量賦了值;如果你在鍵盤上鍵的是abc(a與%d不匹配),scanf("%d", &i )的值就為0,因為scanf無法把"a"視為十進制整數(%d),也無法對它進行轉換,更無法為變量 i 賦值,也就是說scanf這種情況下沒有為任何變量賦值,所以返回值為0。如果scanf()在輸入流中遇到的是某個特殊的字符(具體是哪個字符與環境有關),則返回值為EOF。     另外我告訴他:   把函數類型聲明  int rectangle(int x,int y);  寫在main()函數之內很傻 (應該把函數類型聲明)寫在函數外面   另外那個temp多余   temp賦值為零就更多余   (因為可以直接)   sum += (x-i+1)*(y-j+1);         就這樣,他再次進行了修改:   原代碼-3 復制代碼 #include <stdio.h> int rectangle(int x,int y) {     int i,j,sum,temp;       for(i=1,sum=0;i<=x;i++)     {         for(j=1;j<=y;j++)         {             sum += (x-i+1)*(y-j+1);;         }     }       return sum; }   int rectangle(int x,int y); int main() {     long int A,B;     printf("input A&B and end with EOF\n");       while(scanf("%d%d",&A,&B)!= EOF)     {         printf("%d\n",rectangle(A,B));     }       return 0; } 復制代碼  評析:    現在毛病少多了,不過還是有一些。     首先, rectangle()函數定義的位置不妥,寫在main()定義的後面為好。     其次,數據類型有問題,這個問題比較嚴重。        long int A,B;   這裡絕對沒有必要把A、B定義為long類型,int類型足矣。由於不當地把A、B定義成了long類型,所以代碼中的   scanf("%d%d",&A,&B) 和   rectangle(A,B) 這兩次調用都是錯的。雖然沒有產生錯誤的結果(估計在那個系統中long和int類型大小一樣),但其實是瞎貓碰到死耗子,僥幸而已。     此外的兩處小瑕疵就是rectangle()函數定義中的temp變量忘記刪除了,循環體內刪除語句時不干淨,有一“;”也忘記刪除了。     再有就是    sum += (x-i+1)*(y-j+1);    這個算法我沒看懂,不知道是否正確。   重構:   其實原來代碼已經改得差不多了,只剩下少許小錯和瑕疵。我在這裡只說一下我的算法:     我的算法是,窮舉出兩個點(P1,P2)的所有組合情況,只要P1可以是某個矩形的左上角,P2可以是某個矩形的右下角(P1_X<P2_X,P1_Y<P2_Y),則構成了一個矩形。   復制代碼  1 /*  2 矩形的個數   3 在一個3*2的矩形中,可以找到6個1*1的矩形,4個2*1的矩形3個1*2的矩形,  4 2個2*2的矩形,2個3*1的矩形和1個3*2的矩形,總共18個矩形。   5 給出A,B,計算可以從中找到多少個矩形。   6   7 輸入:   8 本題有多組輸入數據(<10000),你必須處理到EOF為止   9 輸入2個整數A,B(1<=A,B<=1000)  10  11 輸出:  12 輸出找到的矩形數。  13  14 樣例: 15  16 輸入:  17 1 2  18 3 2  19  20 輸出:  21 3  22 18 23  24 作者:薛非 25 出處:http://www.cnblogs.com/pmer/   “C語言初學者代碼中的常見錯誤與瑕疵”系列博文  26  27 */ 28  29 #include <stdio.h> 30  31 int count( int , int );  32  33 int main( void ) 34 { 35   int A , B ; 36    37   while ( printf( "輸入2個整數A,B(1<=A,B<=1000)" ), 38           scanf( "%d%d" , &A , &B )!= EOF     39         ) 40   { 41      printf( "%d\n" , count( A , B ) ); 42   } 43    44   return 0; 45 } 46  47 int count( int A , int B ) 48 { 49    int x1 , y1 ;//第一個點的坐標  50    int x2 , y2 ;//第二個點的坐標 51    int num = 0 ; 52     53    for ( x1 = 0 ; x1 <= B ; x1 ++ ) 54       for ( y1 = 0 ; y1 <= A ; y1 ++ )//窮舉第一個點的各種可能  55          for ( x2 = 0 ; x2 <= B ; x2 ++ ) 56             for ( y2 = 0 ; y2 <= A ; y2 ++ )//窮舉第二個點的各種可能  57             { 58                if ( x1 < x2 && y1 < y2 ) 59                   num ++ ; 60             } 61  62    return num ; 63 }

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved