MENU

コードリファクタリング 定数化編

前回修正したコードは以下になる。

初期コード

#include <stdio.h>

int main(void) {
    char inputCharactors[1000];
    char outputCharactor;
    int i = 0;
    int modeFlag;
    
        printf("暗号作成の時は0を\n暗号解読のときは1を\n終了するときは2を入力してください:");
        scanf("%d",&modeFlag);
    
        if (modeFlag == 0 || modeFlag == 1) {
            if (modeFlag == 0)
                printf("暗号化させたい文を入力してください\n");
            else
                printf("解読させたい文を入力してください\n");

            scanf("%s",inputCharactors);
        
            while (inputCharactors[i] != '\0') {
                if (inputCharactors[i] >= 65 && inputCharactors[i] <= 77)
                    outputCharactor = inputCharactors[i] + 13;
                else if (inputCharactors[i] >= 78 && inputCharactors[i] <= 90)
                    outputCharactor = inputCharactors[i] - 13;
                else if (inputCharactors[i] >= 97 && inputCharactors[i] <= 109)
                    outputCharactor = inputCharactors[i] + 13;
                else if (inputCharactors[i] >= 110 && inputCharactors[i] <= 122)
                    outputCharactor = inputCharactors[i] - 13;
                else outputCharactor = inputCharactors[i];
                printf("%c", outputCharactor);
                i++;
            }
            i = 0;
        }
        else if (modeFlag == 2)
            return 0;
        else
            printf("正しい数字を入力してください(怒)");

        printf("\n");
}

変数名が意味を表すようになったため、多少の可読性向上が見られた。しかし、まだパッと見で理解しにくい部分が多いだろう。

今回は、表題にある通り「定数化」について考えていく。

目次

定数化について

まずは先ほどのプログラムを一部抜粋する。

                if (inputCharactors[i] >= 65 && inputCharactors[i] <= 77)
                    outputCharactor = inputCharactors[i] + 13;
                else if (inputCharactors[i] >= 78 && inputCharactors[i] <= 90)
                    outputCharactor = inputCharactors[i] - 13;
                else if (inputCharactors[i] >= 97 && inputCharactors[i] <= 109)
                    outputCharactor = inputCharactors[i] + 13;
                else if (inputCharactors[i] >= 110 && inputCharactors[i] <= 122)
                    outputCharactor = inputCharactors[i] - 13;

この処理の意図がすぐに理解できる人は、かなりのプログラミング経験者だと思う。この処理は、1文字ずつチェックし、以下のロジックを適用している。

  • A〜Mの文字であれば+13してN〜Zに変換
  • N〜Zの文字であれば-13してA〜Mに変換

このコードが分かりにくい理由は、「マジックナンバー(意味のある数値がプログラム内に直接記述されていること)」を使用しているからだ。


マジックナンバーの問題点

マジックナンバーを使うと、コードの可読性が下がるだけでなく、将来的な改修が困難になる。たとえば、「小文字は変換対象から除外する」という仕様変更を求められた場合、どの部分を修正すればよいのか判断しにくくなるだろう。

そこで、意味のある数値を定数化する。

修正後コード

#include <stdio.h>

const int SMALL_A = 97;
const int SMALL_M = 109;
const int SMALL_N = 110;
const int SMALL_Z = 122;
const int LARGE_A = 65;
const int LARGE_M = 77;
const int LARGE_N = 78;
const int LARGE_Z = 90;
const int ENCRYPT_NUMBER = 13;

enum ModeFlag {
    ENCRYPT = 0,
    DECRYPT = 1,
    EXIT = 2
};

int main(void) {
    char inputCharactors[1000];
    char outputCharactor;
    int i = 0;
    int modeFlag;
    
        printf("暗号作成の時は0を\n暗号解読のときは1を\n終了するときは2を入力してください:");
        scanf("%d",&modeFlag);
    
        if (modeFlag == ENCRYPT || modeFlag == DECRYPT) {
            if (modeFlag == ENCRYPT)
                printf("暗号化させたい文を入力してください\n");
            else
                printf("解読させたい文を入力してください\n");

            scanf("%s",inputCharactors);
        
            while (inputCharactors[i] != '\0') {
                if (inputCharactors[i] >= LARGE_A && inputCharactors[i] <= LARGE_M)
                    outputCharactor = inputCharactors[i] + ENCRYPT_NUMBER;
                else if (inputCharactors[i] >= LARGE_N && inputCharactors[i] <= LARGE_Z)
                    outputCharactor = inputCharactors[i] - ENCRYPT_NUMBER;
                else if (inputCharactors[i] >= SMALL_A && inputCharactors[i] <= SMALL_M)
                    outputCharactor = inputCharactors[i] + ENCRYPT_NUMBER;
                else if (inputCharactors[i] >= SMALL_N && inputCharactors[i] <= SMALL_Z)
                    outputCharactor = inputCharactors[i] - ENCRYPT_NUMBER;
                else outputCharactor = inputCharactors[i];
                printf("%c", outputCharactor);
                i++;
            }
            i = 0;
        }
        else if (modeFlag == EXIT)
            return 0;
        else
            printf("正しい数字を入力してください(怒)");

        printf("\n");
}

この修正により、以下の改善が実現された。

  1. 文字コードを表す数値を定数化し、どの範囲の文字に+13または-13するのかが分かりやすくなった。
  2. 暗号化・解読のモードをenumで定義し、モードの判別が容易になった。

結果として、可読性が向上し、将来的な仕様変更にも対応しやすくなったと思う。

プログラム上のマジックナンバーを定数化しよう。

さて、次回はどのようにリファクタしようかな。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次