C言語

【C言語】第5章第12回:関数テンプレートの基礎(C++との比較)

汎用的な関数を設計する際、C++では関数テンプレートが利用できますが、C言語では別の方法が必要です。この章では、C言語での汎用的な関数設計方法を学び、C++の関数テンプレートとの違いを比較します。

1. 関数テンプレートとは?

1.1 C++の関数テンプレート

関数テンプレートは、異なる型に対応した汎用的な関数を定義する仕組みです。以下はその例です:

// C++の例
#include <iostream>
using namespace std;

template <typename T>
T add(T a, T b) {
    return a + b;
}

int main() {
    cout << "Int addition: " << add(2, 3) << endl;
    cout << "Double addition: " << add(2.5, 3.5) << endl;
    return 0;
}

1.2 C言語での制約

C言語にはテンプレート機能がありません。そのため、以下のような手法で汎用性を実現します:

  • マクロを使用する
  • void *型とキャストを使用する

2. C言語での汎用的な関数設計

2.1 マクロを使用した汎用関数

例:異なる型の加算を実現するマクロ

#include <stdio.h>

// マクロで汎用関数を実現
#define ADD(a, b) ((a) + (b))

int main() {
    printf("Int addition: %d\n", ADD(2, 3));
    printf("Double addition: %.2f\n", ADD(2.5, 3.5));
    return 0;
}

解説:

  • マクロを使用して汎用的な加算操作を実現しています。
  • 型チェックが行われないため、意図しない型の組み合わせには注意が必要です。

2.2 void *型を使用した汎用関数

例:ポインタを使用して異なる型の加算を実現

#include <stdio.h>

void add(void *result, void *a, void *b, char type) {
    if (type == 'i') {
        *(int *)result = *(int *)a + *(int *)b;
    } else if (type == 'd') {
        *(double *)result = *(double *)a + *(double *)b;
    }
}

int main() {
    int a = 5, b = 3, intResult;
    double x = 2.5, y = 3.5, doubleResult;

    add(&intResult, &a, &b, 'i');
    printf("Int addition: %d\n", intResult);

    add(&doubleResult, &x, &y, 'd');
    printf("Double addition: %.2f\n", doubleResult);

    return 0;
}

解説:

  • void *を使用して、任意の型のポインタを受け取ります。
  • 引数typeで型を指定し、処理を分岐させます。

3. C++との比較

特性C++関数テンプレートC言語の疑似テンプレート
型安全性高い(コンパイル時チェックあり)低い(実行時チェックまたは無チェック)
柔軟性高い中程度
実装の複雑さ比較的簡単やや複雑

4. 練習問題

以下の課題に挑戦して、C言語での汎用的な関数設計を実践してください。

  1. マクロを使用して、整数の最大値を返す汎用関数を作成してください。
  2. void *型を使用して、2つの値の大小を比較する汎用関数を作成してください。
  3. マクロと_Genericを組み合わせて、型ごとに異なる操作を実行する関数を実装してください。

5. 練習問題の解答と解説

問1の解答

#include <stdio.h>

// マクロを使用した最大値関数
#define MAX(a, b) ((a) > (b) ? (a) : (b))

int main() {
    printf("Max of 3 and 5: %d\n", MAX(3, 5));
    printf("Max of 2.5 and 3.5: %.2f\n", MAX(2.5, 3.5));
    return 0;
}

解説:

  • MAXマクロは、引数の大小を比較して大きい方を返します。

6. まとめ

C言語では関数テンプレートの機能を直接使用できませんが、マクロやポインタを駆使して汎用的な関数を実現できます。次回は、インライン関数の使い方について学びます。