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

void function(void *i, void *j);

struct mystruct {
    int a;
    int b;
} ;

int main()
{

    int a = 50;

    struct mystruct s ;
    s.a = 100;
    s.b = 200;
    function(&a, &s);


}


void function(void *i, void *j)
{
    printf("Integer is %d\n", *i);
    printf("Struct member 1 is %d\n", j->a);
    printf("Struct member 2 is %d\n", j->b);


}

上記の私のコード。コンパイル時に次のエラーが発生し、それらを修正するために何をする必要があるかを理解しています。

voidstartest.c: In function function:
voidstartest.c:27: warning: dereferencing  void *  pointer
voidstartest.c:27: error: invalid use of void expression
voidstartest.c:28: warning: dereferencing  void *  pointer
voidstartest.c:28: error: request for member  a  in something not a structure or union
voidstartest.c:29: warning: dereferencing  void *  pointer
voidstartest.c:29: error: request for member  b  in something not a structure or union

エラーを修正するために必要なことは次のとおりです。

printf("Integer is %d\n", *(int*)i);

printf("Struct member 1 is %d\n", ((struct mystruct *)j)->a);

printf("Struct member 2 is %d\n", ((struct mystruct *)j)->b);

質問:

  1. 上記の方法でエラーを修正する必要がある場合、関数に送信するポインターのタイプを事前に知っておく必要があるということではないでしょうか? これは非常に厳しい要件だと思います。ではない?

  2. 一部のライブラリ関数には、(qsort のように) void * などの正式な引数があります。実際のデータ (それが指している) で動作するように逆参照できるように、実装はどのようにしてポインターの正しい型を知ることができますか?

4

4 に答える 4

5
  1. はい。つまり、型にとらわれない方法で関数を作成することはできないため、設計を再考する必要があります。1 つを使用する場合void*、通常はテンプレート関数を記述し、型を認識して基本的な操作を行う関数への関数ポインターをユーザーに要求します。

  2. それらの実装はそうではありません。また、上で説明したのと同じ方法で、関数ポインターまたはサイズ パラメーターを要求します。

于 2013-05-16T15:26:04.370 に答える