前回修正したコードは以下になる。
初期コード
#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;
これを見て理解できたら相当プログラミングができる人だと思う。
処理内容を解説すると、Char型の1文字を見てA~Mなら+13してN~Zに、N~Zなら-13してA~Mにする(小文字も同等)というロジックである。
なぜこの処理が分かりにくいか、それはいわゆる「マジックナンバー」を使用しているからである。
マジックナンバー
マジックナンバーとは意味のある値だが、プログラム上にベタ書きで書いている数値のことである。
将来的にこのプログラムの改修が必要になったときマジックナンバーがあることによって、
この数値の意味を正しく理解し、適切な改修を行うことが困難になる。
例えば小文字は変換対象としない改修を入れてくれと言われて、パッと下2つの条件文を消せばいいということには気付けないだろう。
ここで、意味のある数値を定数化してみる。
修正後コード
#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");
}
特定の文字コードを表す数値、暗号化する際に使用する数値、プログラムの最初に入力するモードを定数化した。
文字コードを定数化することにより、A~Mを+13し、N~Zを-13していることが非常に分かりやすくなっている。
また、モードを表していた数値もどの数値がどのモードかが分かりやすくなっているはずだ。
プログラム上のマジックナンバーを定数化しよう。
さて、次回はどのようにリファクタしようかな。