13

関数が引数として void ポインターを取るとします。たとえば、int func(void *p);
p が指している型をどのように判断または推測できますか?

4

4 に答える 4

27

一般的には、できません。場合によっては、p が何を指すかが保証されている場合は、そのアドレス以降の内容を見ればわかる場合があります。通常、関数は、単に渡す場合を除いて、渡されたものを認識している必要があります。

C のデータと関数の引数は、ひとまとめにしたビットの集まりです。これらのビットの一部を使用してビットが何であるかを伝えない限り、それを識別する一貫した方法はありません。

于 2010-04-09T02:58:06.010 に答える
8

確かにできます、そしてそれも簡単です。それはCです、あなたが望むことを何でもします、あなたがそれを望む方法です。

型システムを作成します。渡したすべてのものを構造体に入れ、最初の1バイトまたは2バイトをマジックナンバーにして、構造体にマジックナンバー以外に何が含まれているかを判断します。

「型変数」を作成/取得/設定/破棄する関数をいくつか作成します。

実行時に新しいタイプを追加および登録するために、他のいくつかの関数を作成します。

構造体を読みやすく型キャストしやすくするために、いくつかの定義を作成します。

あなたがそれを知る前に、あなたはあなたのプロジェクトに使用できる素晴らしいプロプライエタリ型システムを持っているでしょう、そしてそれはあなたがそれを作ったのであなたが望むものと必要なものを常に正確に行います。

あなたは夢中になって、それをシステムのような完全なオブジェクト指向に成長させることができます。または、自分で作業を保存して、すでに夢中になっている他のすべての人の作業を使用してください-http://en.wikipedia.org/wiki/GObject

于 2010-04-09T03:43:56.397 に答える
6

簡単な答え - できません。

Cでは、提供しない限り実行時間情報はありませんが、printf(3)ファミリを見て、フォーマット仕様と実際の引数の型が一致しないと、いかに簡単に足を踏み入れることができるかを確認してください。

型システムはあなたの友達です。これを使って。

于 2010-04-09T03:24:02.067 に答える
0

私は同様の問題に直面し、プログラミング言語プロジェクトの命令セットを書かなければならないことに気づきました。関数を列挙して for ループで実行できるように関数へのポインターの配列を持っていたため (オンライン ヘルプや構文など)、この問題に遭遇しました。例えば:

struct List_Str  *(*InstructionSet[])(struct List_Str *ContextPrefix,struct List_Str *ContextSuffix)=
{

  AAVF,Add,AddEmotions,AddEmoDebug,AddScope,...

};

これで、struct List_Str * タイプの代わりに char * を使用して同じことを簡単に行うことができ、snprintf、atoi、atof、およびその他の変換関数を使用して、すべてのデータを文字列形式に変換できます。あなたがする場合:

man isalpha

これは、ctype.h 内の多くの関数を示しており、文字列内に保持されているデータの型を判断する方法のアイデアを提供します。

すべての型を「stringy」形式に折りたたむと、非常に柔軟で規則性が高くなりますが、データを文字列から整数、浮動小数点数などに自動的に変換するのは困難ですが、ルーチンがライブラリ化されると実り多いものになります。

バイナリ データを保持する場合は、文字列を使用できません。これは、バイナリ データ内に 0 文字が含まれる可能性があり、これにより strlen 関数が混乱するためです。さらに、スコープを離れると malloc された長さがわからないため、データの前に参照解除されたデータの長さを char * の最初の数バイトに格納することをお勧めします。

最後に、データを void * に保存することはお勧めしません。あいまいすぎます。char * を使用することをお勧めします。これはもう少し具体的で、void * に含まれるすべてのものを含めることができ、怪しいものがあればコンパイラが事前に通知してくれるからです。

于 2013-05-22T22:41:53.980 に答える