関数ベースのモジュール化プログラミング演習
本演習では、C言語における再利用可能な関数の設計・実装を主眼に、数学的アルゴリズムの実装と構造化されたプログラム構成を学ぶ。各課題は独立した機能単位(モジュール)として実装され、引数渡し、戻り値の取り扱い、条件検証などの基本概念を実践的に理解する。
1. 三角形面積の計算(ヘロンの公式)
三辺の長さから三角形の面積を求める関数 computeTriangleArea を実装する。入力値が三角形成立条件(任意の2辺の和 > 残り1辺)を満たすかを事前に検証し、不正な入力に対してはエラーメッセージを出力する。
#include <stdio.h>
#include <math.h>
double computeTriangleArea(double sideA, double sideB, double sideC) {
double semiPerimeter = (sideA + sideB + sideC) / 2.0;
double squaredArea = semiPerimeter *
(semiPerimeter - sideA) *
(semiPerimeter - sideB) *
(semiPerimeter - sideC);
return sqrt(squaredArea);
}
int main() {
double a, b, c;
printf("3辺の長さを入力してください(スペース区切り): ");
if (scanf("%lf %lf %lf", &a, &b, &c) != 3) {
printf("入力エラー\n");
return 1;
}
if (a + b > c && a + c > b && b + c > a) {
printf("面積: %.3f\n", computeTriangleArea(a, b, c));
} else {
printf("無効な三角形です\n");
}
return 0;
}2. 階乗の逐次計算(非再帰・静的ローカル変数活用)
階乗を逐次生成する関数 nextFactorial を定義。静的変数を用いて前回の計算結果を保持し、呼び出し毎に次の整数の階乗値を返す。この手法は累積的な計算処理に適している。
#include <stdio.h>
long nextFactorial(int current) {
static long result = 1;
result *= current;
return result;
}
int main() {
const int LIMIT = 6;
printf("1〜%d の階乗:\n", LIMIT);
for (int i = 1; i <= LIMIT; ++i) {
printf("%d! = %ld\n", i, nextFactorial(i));
}
return 0;
}3. 最大公約数の算出(ユークリッドの互除法)
2つの整数の最大公約数(GCD)をユークリッドの互除法で求める関数 calculateGCD を実装。負の値やゼロへの対応を含め、堅牢な入力処理を行う。
#include <stdio.h>
#include <stdlib.h>
int calculateGCD(int x, int y) {
x = abs(x); y = abs(y);
while (y != 0) {
int remainder = x % y;
x = y;
y = remainder;
}
return x;
}
int main() {
int num1, num2;
printf("2つの整数を入力: ");
if (scanf("%d %d", &num1, &num2) == 2) {
printf("GCD(%d, %d) = %d\n", num1, num2, calculateGCD(num1, num2));
}
return 0;
}4. パターン描画(高さ指定のピラミッド)
指定された高さ n の星号ピラミッドを出力する関数 drawPyramid を作成。各行の先頭空白数と星号数を正確に制御し、整列された出力を実現する。
#include <stdio.h>
void drawPyramid(int height) {
for (int row = 1; row <= height; ++row) {
// 空白
for (int space = 0; space < height - row; ++space) {
putchar(' ');
}
// 星号
for (int star = 0; star < 2 * row - 1; ++star) {
putchar('*');
}
putchar('\n');
}
}
int main() {
int n;
printf("ピラミッドの高さを入力: ");
if (scanf("%d", &n) == 1 && n > 0) {
drawPyramid(n);
}
return 0;
}5. 友愛数ペアの探索(500未満)
友愛数(amicable numbers)とは、2つの異なる正の整数で、それぞれの「真の約数の和」が他方と等しくなる組のこと。関数 sumOfProperDivisors を用いて500未満の全友愛数ペアを列挙する。
#include <stdio.h>
int sumOfProperDivisors(int n) {
if (n <= 1) return 0;
int total = 1;
for (int f = 2; f * f <= n; ++f) {
if (n % f == 0) {
total += f;
if (f != n / f) total += n / f;
}
}
return total;
}
int main() {
const int UPPER_BOUND = 500;
printf("500未満の友愛数ペア:\n");
for (int a = 2; a < UPPER_BOUND; ++a) {
int b = sumOfProperDivisors(a);
if (b > a && b < UPPER_BOUND && sumOfProperDivisors(b) == a) {
printf("(%d, %d)\n", a, b);
}
}
return 0;
}