目次
モジュール化とファイル分割
前回までのコードはこちら。
前回のコード
#include <stdio.h>
const int SMALL_A = 97;
const int SMALL_Z = 122;
const int LARGE_A = 65;
const int LARGE_Z = 90;
const int ENCRYPT_NUMBER = 13;
const int ALPHABET_COUNT = 26;
enum ModeFlag {
ENCRYPT = 0,
DECRYPT = 1,
EXIT = 2
};
char encryptCore(char input, int baseCharactor){
return (input - baseCharactor + ENCRYPT_NUMBER) % ALPHABET_COUNT + baseCharactor;
}
char encrypt(char input) {
if ((input >= LARGE_A && input <= LARGE_Z)) {
return encryptCore(input, LARGE_A);
} else if ((input >= SMALL_A && input <= SMALL_Z)) {
return encryptCore(input, SMALL_A);
}
return input;
}
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') {
outputCharactor = encrypt(inputCharactors[i]);
printf("%c", outputCharactor);
i++;
}
i = 0;
}
else if (modeFlag == EXIT)
return 0;
else
printf("正しい数字を入力してください(怒)");
printf("\n");
}
前回は「処理の共通化」について解説し、暗号化処理を関数として切り出すことでコードの可読性と保守性を向上させた。
今回は、さらに一歩進んで「モジュール化とファイル分割」について考えていく。
モジュール化とファイル分割のメリット
現在のプログラムは、全ての処理が1つのファイルにまとめられている。
これは小規模なプログラムでは問題ないが、プログラムが大きくなるにつれて以下の問題が発生する。
- 可読性の低下: 1つのファイルが長くなると、どこに何が書かれているのか分かりにくくなる。
- 保守性の低下: 特定の機能を修正する際に、関連するコードを探すのが大変になる。
- 再利用性の欠如: 他のプロジェクトで同じ機能を使いたい場合、コードをコピーする必要があり、非効率的。
これらの問題を解決するために、プログラムを複数のファイルに分割し、モジュール化する。
ファイル分割の手順
今回は、以下のようにファイルを分割する。
- main.c: プログラムのエントリーポイント。ユーザーとのやり取りを行う。
- encrypt.h: 暗号化処理に関する関数の宣言を記載する。
- encrypt.c: 暗号化処理の実装を記載する。
1. encrypt.h
#ifndef ENCRYPT_H
#define ENCRYPT_H
char encrypt(char input);
#endif
2. encrypt.c
#include "encrypt.h"
const int SMALL_A = 97;
const int SMALL_Z = 122;
const int LARGE_A = 65;
const int LARGE_Z = 90;
const int ENCRYPT_NUMBER = 13;
const int ALPHABET_COUNT = 26;
static char encryptCore(char input, int baseCharactor) {
return (input - baseCharactor + ENCRYPT_NUMBER) % ALPHABET_COUNT + baseCharactor;
}
char encrypt(char input) {
if ((input >= LARGE_A && input <= LARGE_Z)) {
return encryptCore(input, LARGE_A);
} else if ((input >= SMALL_A && input <= SMALL_Z)) {
return encryptCore(input, SMALL_A);
}
return input;
}
3. main.c
#include <stdio.h>
#include "encrypt.h"
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') {
outputCharactor = encrypt(inputCharactors[i]);
printf("%c", outputCharactor);
i++;
}
i = 0;
}
else if (modeFlag == EXIT)
return 0;
else
printf("正しい数字を入力してください(怒)");
printf("\n");
}
まとめ
ファイル分割とモジュール化を行うことで、以下のメリットが得られる。
- 可読性の向上: 関連する処理が1つのファイルにまとまるため、コードの見通しが良くなる。
- 保守性の向上: 特定の機能を修正する際に、関連するファイルを探すだけで済む。
- 再利用性の向上: 他のプロジェクトで同じ機能を使いたい場合、ファイルごとコピーするだけで良い。
C言語以外への展開
Pythonでは、モジュール化を実現するために「モジュール」と「パッケージ」という概念があり、C#では、名前空間(namespace
)とクラスという概念があるように、多くの言語でこの考え方が利用されている。
これらの原則を守ることで、どの言語でも可読性が高く、保守しやすいコードを書けるようにしたい。