C言語ユーザー定義関数の4つの実証済みパターン
C言語ユーザー定義関数の4つの実証済みパターン
数が素数かどうかをチェックするユーザー定義関数を4つの異なる方法で実装し、どのアプローチが最も明確で再利用性が高いかを学びます。
以下では、同じ論理タスクを異なる関数シグネチャで表現した4つの完全なプログラムを示します。すべての出力は同一ですが、設計選択が異なり、関数設計における重要なトレードオフを示しています。
例1: 引数なし、戻り値なし
#include <stdio.h>
void checkPrimeNumber();
int main() {
checkPrimeNumber(); // 引数は渡さない
return 0;
}
// 戻り値の型はvoidで値を返さない
void checkPrimeNumber() {
int n, i, flag = 0;
printf("正の整数を入力: ");
scanf("%d", &n);
for(i=2; i <= n/2; ++i) {
if(n%i == 0) {
flag = 1;
}
}
if (flag == 1)
printf("%d is not a prime number.", n);
else
printf("%d is a prime number.", n);
}
checkPrimeNumber()関数はユーザー入力の読み取り、素数判定、結果の出力をすべて担当します。戻り値の型がvoidのため、結果は副作用のみで伝達されます。
例2: 引数なし、だが戻り値あり
#include <stdio.h>
int getInteger();
int main() {
int n, i, flag = 0;
// 引数は渡さない
n = getInteger();
for(i=2; i<=n/2; ++i) {
if(n%i==0){
flag = 1;
break;
}
}
if (flag == 1)
printf("%d is not a prime number.", n);
else
printf("%d is a prime number.", n);
return 0;
}
// ユーザーが入力した整数を返す
int getInteger() {
int n;
printf("正の整数を入力: ");
scanf("%d", &n);
return n;
}
ここではgetInteger()が入力ルーチンをカプセル化し、値をmainに返します。mainが素数判定ロジックを処理します。この分離により入力ステップが異なる文脈で再利用可能になります。
例3: 引数あり、戻り値なし
#include <stdio.h>
void checkPrimeAndDisplay(int n);
int main() {
int n;
printf("正の整数を入力: ");
scanf("%d", &n);
// nを関数に渡す
checkPrimeAndDisplay(n);
return 0;
}
// 戻り値の型はvoidで値を返さない
void checkPrimeAndDisplay(int n) {
int i, flag = 0;
for(i=2; i <= n/2; ++i) {
if(n%i == 0){
flag = 1;
break;
}
}
if(flag == 1)
printf("%d is not a prime number.",n);
else
printf("%d is a prime number.", n);
}
このパターンでは、結果の表示責任がヘルパー関数に移っています。mainはシンプルになりますが、関数がアルゴリズムとI/Oを結合するため再利用性が低下します。
例4: 引数あり、かつ戻り値あり
#include <stdio.h>
int checkPrimeNumber(int n);
int main() {
int n, flag;
printf("正の整数を入力: ");
scanf("%d", &n);
// nをcheckPrimeNumber()関数に渡す
// 返された値をflag変数に代入
flag = checkPrimeNumber(n);
if(flag == 1)
printf("%d is not a prime number",n);
else
printf("%d is a prime number",n);
return 0;
}
// 関数からintが返される
int checkPrimeNumber(int n) {
int i;
for(i=2; i <= n/2; ++i) {
if(n%i == 0)
return 1;
}
return 0;
}
この設計ではアルゴリズムが分離され、シンプルなステータスフラグを返します。呼び出し元が結果の提示方法を決められるため、ライブラリや大規模アプリケーションへの統合で高い再利用性を発揮します。
最適なパターンの選択
すべての実装が同じ出力を生成しますが、最も保守しやすくテストしやすいアプローチは例4です:数値を引数として渡し、ブール風のフラグを返す。このパターンは単一責任の原則に従い、checkPrimeNumberをI/O依存なしでユニットテスト可能にし、より複雑なシステムへの統合を容易にします。
最終的に選択はプロジェクトのアーキテクチャに依存します。関数がユーザーと直接対話する必要があるなら例3で十分かもしれません。I/Oが別で処理されるライブラリコードやサービスでは、例4が最大の柔軟性を提供します。
C言語
- C#名前空間完全ガイド:構成、スコープ、ベストプラクティス
- C言語データ型完全解説:int、float、charなど
- C言語演算子完全ガイド:算術・関係・論理・ビット演算子
- C言語 標準ライブラリ関数: 実践ガイド
- C++変数とデータ型:int、double、char、string、boolを徹底解説
- C 言語ポインタ完全ガイド: 型、使い方、ベストプラクティス
- Cプログラミング入門:初心者向け包括チュートリアル
- C言語のデータ型完全ガイド:整数、浮動小数点、void型
- C言語の関数マスター:構造、宣言、ベストプラクティス
- C言語可変長引数のマスター:実践ガイド
- C#の変数:型、ストレージ、使い方を完全ガイド