4

次の構造体があるとします。

struct A{
    int a;
} a;

struct B{
    A a;
    int b;
} b;

タイプかどうか、またはbタイプかどうかを確認する方法は?BbA

4

6 に答える 6

12

どちらかを指すとすると、実行時に意味しますvoid *か?残念ながら、これは不可能です。Cには、実行時型情報メカニズムはありません。

于 2012-06-05T20:16:21.217 に答える
3

コンパイル時:

#define WARN_IF_DIFFERENT_STRUCT_TYPE_1(T, o) do { \
    T temp = (o);                                  \
    (void) temp;                                   \
} while (0)

例:

struct B b;
/* will warn if b is not of struct A type */
WARN_IF_DIFFERENT_STRUCT_TYPE_1(struct A, b);  

typeofGNU 拡張機能を使用してマクロ パラメーターとして渡される 2 つのオブジェクト:

#define WARN_IF_DIFFERENT_STRUCT_TYPE_2(o1, o2) do { \
    typeof(o1) temp = (o2);                          \
    (void) temp;                                     \
} while (0)   

例:

struct A a;
struct B b;
/* will warn if a and b are not the same struct type */
WARN_IF_DIFFERENT_STRUCT_TYPE_2(a, b);  
于 2012-06-05T20:57:29.190 に答える
0

いいえ。実行時にvtableを使用して型の関連付けを維持する C++ とは異なり、C には実行時の型チェックの方法がありません。

考えられる回避策は、型識別子を構造体の最初の要素として割り当てることです。

struct A {
    int type;
    int a;
} a; a.type = 'A';

struct B {
    int type;
    A a;
    int b;
} b; b.type = 'B';

// Now, given a (void*) pointer `ptr`, of either `A` or `B`...
if ( *(int*)ptr == 'A')
{
    // ...
}
elseif ( *(int*)ptr == 'B')
{
    // ...
}
于 2012-06-05T20:20:37.110 に答える
0

いいえ、C に関する限り、データは単なるビット列です。データをどのように使用および解釈するかは、プログラマ次第です。

charこれは、 a が文字、正の数または負の数 (またはそれ以外のもの) を表す方法と同じです。コンテキストと、プログラマによる使用方法によって異なります。

于 2012-06-05T20:18:30.850 に答える
0

独自の型チェック メカニズムを作成する場合は、型フィールドに入力するマクロを作成することをお勧めします。

typedef struct A {
   void *type;
   int a; 
} A;

このマクロは、文字列化を使用して、型情報で各構造を初期化します。

 #define InitializeType(ptr, type) \
      ((ptr)->type == (void *)(#type ## __FILE__ ##))
 #define IsType(ptr, type)      \
      ((ptr)!=NULL && (ptr)->type != (void *)(#type ## __FILE__ ##))

タイプ フィールドには、構造体の名前とそれが配置されているファイルを含む文字列が入力されます。複数のソース ファイルで同じ名前の 2 つの構造体を持つことはできますが、同じ名前の 2 つの構造体を持つことはできません。同じソース ファイル、したがって、型が初期化されたソース ファイルの名前を含める理由。その後、次のように使用します。

 A alpha;
 InitializeType(&alpha, A);
 IsType(&alpha, A);

ただし、注意点がいくつかあります。文字列プーリングコンパイラフラグを使用する必要があり、構造体を「クラス」にカプセル化して、型チェックと初期化がプライベート構造体を含むソースファイルにローカライズされるようにする必要があります。各構造体。

于 2012-07-23T04:50:56.267 に答える
-2

ハッキングできますか?本当に必要で、構造体が 2 つしかない場合。

struct A{
    int a;
    int identifer = 0;
} a;

struct B{
    A a;
    int b;
    int identifer = 1;
} b;

そして、あなたのコードが次のようになることができれば

if object->identifer == 0 
     bla bla bla
于 2012-06-05T20:19:53.430 に答える