<エラーコードとエラー処理>

 

 ユーザーに処理の選択をさせている関係上、各関数内で様々なエラーが生じる可能性があります。例えば、データがないのに演算する、データがないのにセーブする、指定されたファイルが見つからない、などです。

 

 エラーが生じた場合、ただプログラムを異常終了させるだけでは芸がありませんので、各関数が返すエラーコードに意味を持たせて、それに応じてmain関数内で適切なエラー処理をするようにするとよいでしょう。例えば、

 

#define NO_ERROR 0              /* NO_ERROR0 */

#define NO_DATA 1               /* NO_DATA1 */

#define SIZE_MISMATCH 2        /* SIZE_MISMATCH2 */

...

int main(void) {

         ...

         err = do_process();    /* do_process関数を呼び出し、返却値(エラーコード)をerrに格納 */

         ...

         if (err != NO_ERROR) {         /* エラーがあったら */

                 switch (err) {          /* エラーの種類で分岐してエラー処理 */

                 case NO_DATA: ...

                 case SIZE_MISMATCH:...

                 ...

                 }

         }

         ...

 

 今回の課題では必要ないと思われますが、関数からの返却値に複数の意味を同時に持たせることも可能です。

 

#define NO_ERROR 0              /* 00000000 */

#define NO_FILE 1               /* 00000001 */

#define NO_DATA 2               /* 00000010 */

#define SIZE_MISMATCH 4        /* 00000100 */

#define DIM_MISMATCH 8         /* 00001000 */

#define ALLOC_FAILURE 16       /* 00010000 */

...

typedef unsigned char ERROR;  /* 符号なしchar型をERROR型として型定義 */

...

int main(void) {

         ERROR err;

         ...

         err = some_function();

         /* some_funciton関数が返してきたエラーコードに従ってエラー処理 */

         if (err) {

                 if (err & NO_FILE) {

                          ...

                 }

                 if (err & NO_DATA) {

                          ...

                 }

                 if (err & SIZE_MISMATCH) {

                          ...

                 }

                 ...

         }

}

 

/* 関数some_functionの定義 */

/* 処理中に生じたエラーの情報を含むエラーコードを返す */

ERROR some_function(void) {

         ERROR err = NO_ERROR;          /* 返却(予定)値を0で初期化 */

         if (ファイルがなかったら)

                 err |= NO_FILE;         /* errNO_FILEの論理和(or)をerrに代入 */

         if (データがなかったら)

                 err |= NO_DATA;         /* errNO_DATAの論理和をerrに代入 */

         if (サイズが違ったら)

                 err |= SIZE_MISMATCH;  /* errSIZE_MISMATCHの論理和をerrに代入 */

 

         ...

         return err;              /* 呼び出し元にerrの値を返す */

}

 

 この例では、返却値の各ビットを各エラーのフラグとして使っています。演算子&や|は、二つの数のビットごとの論理演算をするものです。それをふまえて、上の例の動作を考えてみて下さい。

 

 

戻る