あなたが求めていることを正確に行うことはできません-incrementのような演算子は特定のタイプで動作する必要があります。したがって、次のようなことができます。
enum type {
TYPE_CHAR,
TYPE_INT,
TYPE_FLOAT
};
void incr(enum type t, void *vp)
{
switch (t) {
case TYPE_CHAR:
(*(char *)vp)++;
break;
case TYPE_INT:
(*(int *)vp)++;
break;
case TYPE_FLOAT:
(*(float *)vp)++;
break;
}
}
次に、次のように呼びます。
int i=5;
float f=5.6f;
char c='a';
incr(TYPE_INT, &i);
incr(TYPE_FLOAT, &f);
incr(TYPE_CHAR, &c);
もちろん、これは、個別incr_int()
の関数incr_float()
を定義するだけでは実際には何も得られません。incr_char()
これは、の目的ではありませんvoid *
。
の目的はvoid *
、作成しているアルゴリズムがオブジェクトの実際のタイプを気にしない場合に実現されます。qsort()
良い例は、次のように宣言されている標準のソート関数です。
void qsort(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *));
これは、任意のタイプのオブジェクトの配列を並べ替えるために使用できます。呼び出し元は、2つのオブジェクトを比較できる比較関数を提供する必要があります。
あなたの関数swap()
とsort()
関数の両方がこのカテゴリに分類されます。 swap()
さらに簡単です-アルゴリズムは、オブジェクトを交換するためにオブジェクトのサイズ以外のことを知る必要はありません。
void swap(void *a, void *b, size_t size)
{
unsigned char *ap = a;
unsigned char *bp = b;
size_t i;
for (i = 0; i < size; i++) {
unsigned char tmp = ap[i];
ap[i] = bp[i];
bp[i] = tmp;
}
}
これで、任意の配列が与えられた場合、その配列内の2つのアイテムを交換できます。
int ai[];
double ad[];
swap(&ai[x], &ai[y], sizeof(int));
swap(&di[x], &di[y], sizeof(double));