C言語 演習問題 第4回 『関数』

C言語 の演習問題を解いてみましょう。今回は関数について扱います。
問題文で提示された要件を満たすプログラムを作成してみて下さい。

この記事はシリーズ記事です。全シリーズはこちらからご覧になれます。

(C言語の基礎、操作方法等の記事⼀覧は こちら

目次

第1問

①3つの引数を受け取り、その中で一番大きな数値を戻り値として返す関数「max」を作成してください。関数名と引数は以下としてください。
・int max(int x, int y, int z)

②作成した①のmax関数を利用しましょう。main関数内で任意の3つの数値を入力し、入力した値をmax関数を用いて最大値を求めて画面に出力して下さい。

◆回答例◆
#include <stdio.h>

int max(int x, int y, int z)
{
    if (x >= y && x >= z) // xがyおよびz以上なら
    {
        return x; // xを返す
    }
    else if (y >= x && y >= z) // yがxおよびz以上なら
    {
        return y; // yを返す
    }
    else // それ以外の場合は
    {
        return z; // zを返す
    }
}

int main(void)
{
    int nums[3];
    int i;
    char labels[][4] = { "1st", "2nd", "3rd" };
    for (i = 0; i < 3; i++)
    {
        printf("Input %s data: ", labels[i]);
        scanf("%d", &nums[i]);
    }
    printf("Max value: %d", max(nums[0], nums[1], nums[2]));
    return 0;
}

第2問

呼び出すたびに、呼び出された回数を画面に表示する関数「call_counter」を作成してください。
出来上がったcall_counter関数をmain関数内で複数回呼び出し、call_counterの呼び出し回数表示が変化する事を確認してください。
ただし、グローバル変数は使わず、回数の管理はcall_counter関数の中で行うものとします。

◆回答例◆
#include <stdio.h>

void call_counter(void)
{
    static int call_cnt = 0;
    call_cnt++;
    printf("この関数は %d回 呼び出されました。\n", call_cnt);
}

int main(void)
{
    int i;
    for (i = 0; i < 10; i++) {
        call_counter();
    }
    return 0;
}

第3問

べき乗(2の3乗、5の2乗など)を計算する関数を作成しましょう。基数(かけられる数)と指数(肩に乗る数)を引数として、べき乗を計算するpower関数を定義してください。その後、main関数で任意の入力(基数と指数)を行って、power関数を呼び出して結果を画面表示してください。入力する値は整数としますが、負数(マイナス)も含むものとします。(負のべき乗が可能なプログラムにして下さい、の意)

◆回答例◆
#include <stdio.h>
double power(int base, int exp)
{
    if (exp == 0)
    {
        return 1; //0乗は1になる
    }
    else if (exp > 0) //正のべき乗
    {
        return base * power(base, exp - 1);
    }
    else //負のべき乗
    {
        return power(base, exp + 1) / base;
    }
}
int main(void)
{
    int x, y;
    printf("基数: ");
    scanf("%d", &x);
    printf("指数: ");
    scanf("%d", &y);
    printf("%d ^ %d = %f", x, y, power(x, y));
    return 0;
}

power関数内で、power関数を再度呼び出している点に着目してください。指数の数だけpower関数が呼び出されます。

第4問

配列と、配列の要素数を引数として受け取って中央値を返す関数「calculate_median」を作成しましょう。作成出来たら、main関数から配列と要素数を渡して中央値を画面表示してください。
calculate_median関数の関数名と引数は以下としてください。
・int calculate_median(int arr[], int n)

※中央値: あるデータの集合のちょうど真ん中の順位のデータのこと。
たとえば配列が{30,40,100}のとき、中央値は40になる。
{30,40,50,100}の場合は40と50の平均値45が中央値になる。

※(任意)下記の配列を利用して頂いてもかまいません。

    int arr[] = { 45, 78, 12, 90, 32, 67, 5, 23, 88, 42, 99, 55 };
    int length = 12;
◆回答例◆
#include <stdio.h>

// プロトタイプ宣言
void bubble_sort(int arr[], int n);
double calculate_median(int arr[], int n);

int main(void)
{
    int arr[] = { 45, 78, 12, 90, 32, 67, 5, 23, 88, 42, 99, 55 };
    int length = 12;
    int median;
    median = calculate_median(arr, length); // 中央値計算
    printf("中央値: %d\n", median);
    return 0;
}

void bubble_sort(int arr[], int n) // バブルソート関数
{
    int tmp;
    for (int i = 0; i < n - 1; i++) {
        for (int j = 0; j < n - i - 1; j++) {
            if (arr[j] > arr[j + 1]) {
                tmp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = tmp;
            }
        }
    }
}

double calculate_median(int arr[], int n) // 中央値計算関数
{
    bubble_sort(arr, n);  // 配列をバブルソート
    if (n % 2 == 1) {     // 奇数の場合は真ん中の値を返す
        return arr[n / 2];
    }
    else {                // 偶数の場合は中央の2つの値の平均を返す
        return (arr[n / 2 - 1] + arr[n / 2]) / 2;
    }
}

第5問

第4問のコードを修正して、中央値だけでなく平均、分散、標準偏差の値も算出可能にして下さい。
平均: 配列のすべての要素の合計を配列の要素数で割る。
分散: 各要素と平均値との差の二乗の平均。
標準偏差: 分散の平方根。

・平方根の計算には、下記の関数を使用して下さい。

#include <math.h>
sqrt(num)
◆回答例◆
#include <stdio.h>
#include <math.h>

// プロトタイプ宣言
void bubble_sort(int arr[], int n);
double calculate_median(int arr[], int n);
double calculate_mean(int arr[], int n);
double calculate_variance(int arr[], int n, double mean);
double calculate_standard_deviation(double variance);

int main(void)
{
    int arr[] = { 45, 78, 12, 90, 32, 67, 5, 23, 88, 42, 99, 55 };
    int lenge = sizeof(arr) / sizeof(arr[0]);  // 配列の要素数を計算
    double median, mean, variance, std_dev;
    median = calculate_median(arr, lenge);    // 中央値計算
    mean = calculate_mean(arr, lenge);     // 平均計算
    variance = calculate_variance(arr, lenge, mean);     // 分散計算
    std_dev = calculate_standard_deviation(variance);    // 標準偏差計算

    printf("中央値: %.2f\n", median);
    printf("平均: %.2f\n", mean);
    printf("分散: %.2f\n", variance);
    printf("標準偏差: %.2f\n", std_dev);

    return 0;
}

// バブルソート関数
void bubble_sort(int arr[], int n)
{
    int tmp;
    for (int i = 0; i < n - 1; i++) {
        for (int j = 0; j < n - i - 1; j++) {
            if (arr[j] > arr[j + 1]) {
                tmp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = tmp;
            }
        }
    }
}

double calculate_median(int arr[], int n) // 中央値計算関数
{
    bubble_sort(arr, n);  // 配列をバブルソート
    if (n % 2 == 1) {     // 奇数の場合は真ん中の値を返す
        return arr[n / 2];
    }
    else {                // 偶数の場合は中央の2つの値の平均を返す
        return (arr[n / 2 - 1] + arr[n / 2]) / 2.0;  // 2.0で割ることで小数を保持
    }
}
double calculate_mean(int arr[], int n) // 平均計算関数
{
    double sum = 0;
    for (int i = 0; i < n; i++) {
        sum += arr[i];
    }
    return sum / n;
}
double calculate_variance(int arr[], int n, double mean) // 分散計算関数
{
    double sum_squared_diff = 0;
    for (int i = 0; i < n; i++) {
        sum_squared_diff += (arr[i] - mean) * (arr[i] - mean);
    }
    return sum_squared_diff / n;
}
double calculate_standard_deviation(double variance) // 標準偏差計算関数
{
    return sqrt(variance);
}

第6問

2500以下の整数の素因数分解を行って画面に表示するプログラムを作成してください。
50以下の素数は事前に配列で与えられているものとします。下記のprimes[]を使用して下さい。

int primes[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47};
◆回答例1◆
#include <stdio.h>
#define NUMBER_OF_PRIMES 15

int primes[] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47 }; 

// 2500以下の整数をmで受け取って素因数分解した結果を表示する関数
void factorize_primes(int m)
{
    int i, pow;
    printf("%d = ", m);
    for (int i = 0; i < NUMBER_OF_PRIMES; i++)
    {
        pow = 0;                   // 指数を0で初期化
        while (m % primes[i] == 0) // 素数で割り切れる間は実行を繰り返す
        {
            m /= primes[i];
            pow++;
        }
        switch (pow)
        {
        case 0: // 指数が0なら何もしない
            break;
        case 1: // 指数が1なら「p * 」と表示
            printf("%d * ", primes[i]);
            break;
        default: // 指数が2以上なら「(p ^ pow) * 」と表示
            printf("(%d ^ %d) * ", primes[i], pow);
            break;
        }
    }
    if (m > 1)
    {
        printf("%d\n", m);
    }
    else
    {
        printf("\b\b\n");
    }

    return;
}

int main(void)
{
    int num;
    printf("Input a number: ");
    scanf("%d", &num);

    factorize_primes(num);

    return 0;
}

◆回答例2◆
#include <stdio.h>

void factorize_primes(int m) {
    int i, pow;
    printf("%d = ", m);
    if (m == 1) {
        printf("1\n");
        return;
    } else if (m == 0) {
        printf("0\n");
        return;
    } else {
        for (int i = 2; i <= m; i++) {
            pow = 0;
            while (m % i == 0) {
                m /= i;
                pow++;
            }
            switch (pow) {
                case 0:
                    break;
                case 1:
                    printf("%d", i);
                    break;
                default:
                    printf("(%d ^ %d)", i, pow);
                    break;
            }
            if (m > 1 && pow != 0) {
                printf(" * ");
            } else if (m == 1) {
                break;
            }
        }
        printf("\n");
    }
}

int main(void) {
    int num;
    printf("Input a number: ");
    scanf("%d", &num);

    factorize_primes(num);

    return 0;
}

プログラミングは、練習と経験が鍵となります。ぜひ問題に挑戦し続けてください。別の記事で、より複雑な課題にも取り組みスキルをさらに磨いていきましょう。

この記事はシリーズ記事です。全シリーズはこちらからご覧になれます。

(Visited 47 times, 1 visits today)
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

目次