1. ホーム
  2. c

[解決済み] void*の意味と使い方を教えてください。

2022-04-21 16:24:42

質問

今日、他の人のコードを読んでいたら、次のようなものがありました。 void *func(void* i); これは何ですか? void* ここでは、関数名と変数型にそれぞれ意味があるのでしょうか?

また、このようなポインターは、どのような場合に、どのように使うのでしょうか。

どのように解決するのですか?

へのポインタ void は一般的なポインタ型です。 A void * は、明示的にキャストすることなく他の任意のポインタ型に変換することができます。 を参照解除することはできません。 void * ポインタの演算を行うには、まずこれを完全なデータ型へのポインタに変換する必要があります。

void * は、同じコード内で異なるポインタ型を扱えるようにする必要がある場合によく使われます。 よく例に出されるのが、ライブラリ関数の qsort :

void qsort(void *base, size_t nmemb, size_t size, 
           int (*compar)(const void *, const void *));

base は配列のアドレスです。 nmemb は配列の要素数です。 size は各要素のサイズ、そして compar は配列の 2 つの要素を比較する関数へのポインタです. このように呼び出される。

int iArr[10];
double dArr[30];
long lArr[50];
...
qsort(iArr, sizeof iArr/sizeof iArr[0], sizeof iArr[0], compareInt);
qsort(dArr, sizeof dArr/sizeof dArr[0], sizeof dArr[0], compareDouble);
qsort(lArr, sizeof lArr/sizeof lArr[0], sizeof lArr[0], compareLong);

配列の表現 iArr , dArr および lArr は関数呼び出しの際に暗黙のうちに配列型からポインタ型に変換され、それぞれは"ポインタから int / double / long へのポインタ。 void "です。

比較関数は次のようなものになる。

int compareInt(const void *lhs, const void *rhs)
{
  const int *x = lhs;  // convert void * to int * by assignment
  const int *y = rhs;

  if (*x > *y) return 1;
  if (*x == *y) return 0;
  return -1;
}

を受け入れることで void * , qsort は、あらゆる型の配列を扱うことができます。

を使うことのデメリットは void * は、型の安全性を窓から対向車線に投げ出すことになります。 間違った比較ルーチンの使用からあなたを守るものは何もないのです。

qsort(dArr, sizeof dArr/sizeof dArr[0], sizeof dArr[0], compareInt);

compareInt は、その引数が以下の場所を指していることを期待しています。 int を使用していますが、実際には double s. コンパイル時にこの問題を発見する方法はありません。