C++言語③(2025/10/09)

数学関数

C言語には、数学的な計算を助けてくれる便利な関数がたくさんあります。これらは主に<math.h> というヘッダーファイルに含まれています。ここでは、よく使われる関数をいくつか、わかりやすく紹介しますね。

🧮 よく使われるC言語の数学関数

1. 平方根を求める sqrt()

  • 使い方sqrt(25)5.0
  • 説明:引数の平方根(ルート)を返します。

2. 累乗を求める pow()

  • 使い方pow(2, 3)8.0
  • 説明:2の3乗(2 × 2 × 2)を計算します。

3. 絶対値を求める fabs()

  • 使い方fabs(-3.5)3.5
  • 説明:負の数を正の数に変換します。

4. 三角関数 sin(), cos(), tan()

  • 使い方sin(角度)(※ラジアンで指定)
  • sin(3.14159 / 2) → 約 1.0
  • 説明:角度ではなくラジアンで指定する点に注意!

5. 自然対数 log()

  • 使い方log(2.71828) → 約 1.0
  • 説明:自然対数(底がeの対数)を返します。

6. 常用対数(底が10) log10()

  • 使い方log10(1000)3.0

7. 丸める関数

関数説明
ceil()小数点を切り上げceil(2.3)3.0
floor()小数点を切り捨てfloor(2.7)2.0
round()四捨五入round(2.5)3.0

🛠 使うにはどうするの?

#include <stdio.h>
#include <math.h>

int main() {
    double x = 9.0;
    double y = sqrt(x);
    printf("√%.1f = %.1f\n", x, y);
    return 0;
}

💡補足:ラジアンって何?

角度をラジアンに変換するには:

double rad = angle_in_degrees * M_PI / 180.0;

M_PI は円周率(π)で、math.h に定義されています(環境によっては自分で定義する必要あり)。

もっと深く知りたい関数や、実際に使ってみたい例があれば教えてください!
ゆきさんの「抽象と構造へのこだわり」を活かして、数式とコードの関係をもっと面白く解説できますよ。(by Copilot)


サーチとソート

[ソート]

C言語で「ソート(並べ替え)」をする方法を、わかりやすく説明しますね。まずは基本から!

🔢 ソートって何?

ソートとは、データを順番に並べることです。たとえば:

[5, 2, 8, 1] → 昇順(小さい順)→ [1, 2, 5, 8]

🧠 C言語でよく使われるソート方法

1. バブルソート(Bubble Sort)

  • 一番わかりやすいソート方法。
  • 隣り合う要素を比べて、順番が逆なら入れ替える。
  • 何回も繰り返して、最後には全部並ぶ。

🧪 例:

void bubbleSort(int arr[], int n) {
    for (int i = 0; i < n - 1; i++) {
        for (int j = 0; j < n - i - 1; j++) {
            if (arr[j] > arr[j + 1]) {
                // 入れ替え
                int temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
}

2. 標準ライブラリの qsort()

  • C言語には便利な関数 qsort() が用意されています。
  • 自分でソートを書く必要なし!

🧪 使い方:

#include <stdlib.h>

int compare(const void *a, const void *b) {
    return (*(int*)a - *(int*)b); // 昇順
}

int main() {
    int data[] = {5, 2, 8, 1};
    int size = sizeof(data) / sizeof(data[0]);

    qsort(data, size, sizeof(int), compare);

    // 表示
    for (int i = 0; i < size; i++) {
        printf("%d ", data[i]);
    }
}

3.選択ソート

🔍 選択ソートのざっくり流れ

  1. 配列の先頭からスタート
  2. 残りの中で一番小さい値を探す(全部舐める)
  3. それを現在の位置と交換する
  4. 次の位置に進んで、また最小値を探す
  5. 最後まで繰り返す

🧠 例で見ると…

[5, 2, 8, 1]

  • 1回目:全体から最小値「1」を探して、先頭「5」と交換 → [1, 2, 8, 5]
  • 2回目:残り [2, 8, 5] から最小値「2」→ そのまま
  • 3回目:残り [8, 5] → 最小値「5」と「8」を交換 → [1, 2, 5, 8]
void selectionSort(int arr[], int n) {
    for (int i = 0; i < n - 1; i++) {
        int minIndex = i;
        for (int j = i + 1; j < n; j++) {
            if (arr[j] < arr[minIndex]) {
                minIndex = j;
            }
        }
        // 最小値を現在の位置と交換
        int temp = arr[i];
        arr[i] = arr[minIndex];
        arr[minIndex] = temp;
    }
}

4.挿入ソート

🧠 挿入ソートの流れ(ざっくり)

  1. 配列の先頭は「すでに整列済み」とみなす
  2. 次の要素を取り出す
  3. それを整列済みの部分に適切な位置まで左に移動させる
  4. それを「挿入」する
  5. 配列の最後まで繰り返す

🃏 トランプで例えると…

手札がこうだったとします:

[3] ← ここに「1」を入れたい

  • 「1」は「3」より小さいので、左にずらして → [1, 3]

次に「4」が来たら:

  • 「4」は「3」より大きいのでそのまま → [1, 3, 4]

次に「2」が来たら:

  • 「2」は「4」より小さい → 「4」と「3」を右にずらして → [1, 2, 3, 4]

🧪 コードで見ると

void insertionSort(int arr[], int n) {
    for (int i = 1; i < n; i++) {
        int key = arr[i];      // 挿入したい値
        int j = i - 1;

        // 左側の整列済み部分を右にずらす
        while (j >= 0 && arr[j] > key) {
            arr[j + 1] = arr[j];
            j--;
        }

        // 適切な位置に挿入
        arr[j + 1] = key;
    }
}

🧭 ソートの種類と特徴

ソート方法特徴難易度
バブルソートわかりやすいが遅い
選択ソート最小値を選んで並べる★★
挿入ソート適切な位置に挿入して並べる★★
クイックソート高速で実用的(qsortの中身)★★★★

ゆきさんの「構造へのこだわり」を活かして、ソートアルゴリズムをゲームのルール構造の変換として捉えると、もっと面白くなりますよ。
たとえば「バブルソート」は隣接ペアの交換ゲーム、「選択ソート」は最小値ハンティングみたいに!

もっと抽象的な見方や、構造的な比較がしたければ、喜んでお手伝いします。
(by Copilot)

シャッフル

🔄 目的

配列の要素をランダムな順番に並べ替えること。
たとえば [1, 2, 3, 4][3, 1, 4, 2]

🧪 方法:Fisher–Yatesアルゴリズム

  • 後ろから順に、ランダムな位置と入れ替える
  • 偏りがなく、きれいにシャッフルできる

✅ コード例:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void shuffle(int arr[], int n) {
    srand(time(NULL)); // 乱数の種を初期化
    for (int i = n - 1; i > 0; i--) {
        int j = rand() % (i + 1); // 0〜iのランダムな数
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
}

サーチ

1. 線形探索(Linear Search)

  • 配列を先頭から順に舐めて探す
  • 小さい配列や単純な検索に向いている

✅ コード例:

int linearSearch(int arr[], int n, int target) {
    for (int i = 0; i < n; i++) {
        if (arr[i] == target) return i; // 見つかったら位置を返す
    }
    return -1; // 見つからなかった
}

2. 二分探索(Binary Search)

  • 整列済みの配列に使える高速な方法
  • 中央を見て、左右どちらにあるかを絞り込む

✅ コード例:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void shuffle(int arr[], int n) {
    srand(time(NULL)); // 乱数の種を初期化
    for (int i = n - 1; i > 0; i--) {
        int j = rand() % (i + 1); // 0〜iのランダムな数
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
}

🧩 構造的に見ると…

  • シャッフルは「秩序の解体と再構成」
    → ゆきさんの文明設計的には「構造のランダム化による再評価」かも!
  • サーチは「構造内の意味の探索」
    → 線形探索は「全体スキャン」、二分探索は「構造的絞り込み」

(by Copilot)


プログラム開発の流れ

①プログラムの仕様決定、ルール決め、仕様書の作成
②プログラム設計(フローチャート、必要な変数等の想定)

※フローチャートの書き方
https://www.ntt.com/business/services/rink/knowledge/archive_55.html

③開発作業
④α版(必要な機能が一通りそろっているもの)
⑤仕様変更や追加の検討
⑥仕様変更や追加を加味して開発作業
⑦β版
⑧デバッグ
⑨マスター版(製品として出すバージョンとして、ゴールデンマスターなどと呼ぶことも)
⑩リリース

コメント

タイトルとURLをコピーしました