錯誤與斷言

首先聲明:這些內容主要是面向C語言的初學者,尤其是正在學習C語言的學生。

    在《C語言字符型數據(一)》中,我們對文本文件中的內容進行了簡單的加密處理。程序如下所示:

#include "stdio.h"

int main()

{

   char ch;

   freopen("original.txt","r",stdin) ; //輸入輸出被分別重定向到兩個文件。

   freopen("result.txt","w",stdout);

   ch=getchar();

   while(ch!=EOF)    //EOF指文件的末尾

   {

        if(ch>='A'&&ch<='Z'||ch>='a'&&ch<='z')

        {

            ch=ch+3;

            if(ch>'z'||(ch>'Z'&&ch<='Z'+3))

                 ch= ch-26;

        }               

        printf("%c",ch);

        ch = getchar();

   }

   return 0;

}

    有一個學生在練習上述程序時,誤將while(ch!=EOF) 寫成了while(ch=!EOF),程序編譯通過,運行後,result.txt文件中什麼結果都沒有。花了很長時間才最終發現了這個錯誤。其實很多初學者都曾犯過類似的錯誤。比如,在寫if語句的條件時,也很容易將if(ch!=EOF)寫成if(ch=!EOF),或者本來是判斷是否相等if(ch==’a’),結果寫成了if(ch=’a’)。對初學者而言,最大的困難是這類錯誤並沒有語法問題,從而很難查找,這也是C語言靈活性的一個體現。下面我們先分析錯誤的原因,再給出解決方法。

錯誤分析:

    while後面的括號中可以是任何表達式,表達式首先被求值,然後判斷該值的真假,C語言判斷真假的規則是:零是假,非零的值都爲真。當寫成ch=!EOF時,這實際上是一個賦值表達式,因爲感嘆號現在是邏輯運算符“非”,它的優先級高於賦值“=”,所以ch=!EOF等價於ch=!EOF)。EOF是一個常量,等於-1(非零爲真),所以!EOF的值爲假,注意邏輯表達式求值後的真假是用10來表示的,因此!EOF的值爲0ch也被賦值爲0,表達式ch=!EOF的值等於ch的值,也爲0。因此,while後面的條件恆爲假,循環體一次都沒有執行。這就是爲什麼result.txt文件中什麼結果都沒有。

解決方法:

    1.有牛人曾經給出過一個解決方案:在寫while或者if後面的條件時,把常量寫在左面,變量寫在右邊。這樣寫的好處是,當寫錯運算符時,編譯會報錯。比如上面的例子,建議寫成while(EOF!= ch),這樣寫並不影響判斷,但如果誤寫爲while(EOF=!ch),編譯時會報錯,因爲EOF是一個常量,常量是不能被賦值的。這樣就很容易糾正錯誤。

    2.適當加入斷言來防止錯誤的發生。比如上面的程序中,如果while循環正常結束的話,ch應該等於EOF,因此我們可以斷言循環結束後ch等於EOF。加了斷言的程序如下所示:

#include "stdio.h"

#include"assert.h"

int main()

{

    char ch;

    freopen("original.txt","r",stdin);

    freopen("result.txt","w",stdout);

    ch=getchar();

    while(ch!=EOF)    //當這個表達式寫成while(ch=!EOF),運行時後面的assert會檢測到問題。

    {

         if(ch>='A'&&ch<='Z'||ch>='a'&&ch<='z')

         {

              ch=ch+3;

              if(ch>'z'||(ch>'Z'&&ch<='Z'+3))

                   ch = ch-26;

          }               

          printf("%c",ch);

          ch = getchar();

     }

     assert(c==EOF);  //正常情況下,循環結束時,c==EOF,斷言是正確的。當while後面的表達式寫錯時,循環

                      //一次都沒有執行,這時c!=EOF ,因此斷言會報錯。

     return 0;

}


    初學者可以自己上機去試試上面的程序,看斷言報錯的結果是怎樣的。

發佈了40 篇原創文章 · 獲贊 119 · 訪問量 16萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章