1

2つのデータ構造があります。

typedef struct{
    int a;
    int b;
    int c;
}EVENTS;

EVENTS typeone[20];
EVENTS typetwo[20];

これらは埋められました。typeoneはtypeone[5]まで、typetwoはtypetwo[8]まで満たされています。

タイプ1とタイプ2の最初の6つを比較して、すべてのメンバーが等しいかどうかを確認したいと思います。

typeone[1] == typetwo[1] [1]のデータ構造内のすべての値を基本的に比較する方法はありますか。これを行う簡単な方法はありますか、それとも各メンバーをループして個別に比較する必要がありますか?

ありがとう

4

3 に答える 3

3

これはcomp.lang.c FAQです。一言で言えば、いいえ、C は演算子との構造体比較をサポートしていません==(FAQ の回答には、一般的なケースでこれが難しい理由についていくつかの理由が示されています)。独自の関数を作成し、メンバーごとに比較する必要があります。指摘されたように、パディング バイトにアクセスするときの動作が規定されていないため、保証された方法でmemcmp()はありません。

int eventsequal (const EVENTS *const a, const EVENTS *const b)
{
    if (a->a != b->a) return 0;
    if (a->b != b->b) return 0;
    if (a->c != b->c) return 0;
    return 1;
}

そして、あなたの例は次のようtypeone[1] == typetwo[1]になります

if (eventsequal (typeone + 1, typetwo + 1)) {
   /* They're equal. */
}
于 2012-12-18T12:34:35.867 に答える
2

パディングの問題を回避するには、フィールドを個別に比較する必要があります。これはそれほど恐ろしいことである必要はありません。

#include <stdbool.h>

bool EVENTS_equal(const EVENTS *e1, const EVENTS *e2)
{
  return e1->a == e2->a && e1->b == e2->b && e1->c == e2->c;
}

次にループします:

size_t i;
bool   equal = true;

for(i = 0; i < 6; ++i)
{
  if(!EVENTS_equal(typeone + i, typetwo + i))
  {
    equal = 0;
    break;
  }
}

それは実際にはそれほど多くのコードではなく、もちろん、2 つの配列の最初のn 個 のスロットを相互比較する関数でループを自明にカプセル化することもできます。EVENTS

于 2012-12-18T12:36:39.717 に答える
1
 typedef struct{
     int a;
     int b;
     int c;
 }EVENTS;

 #pragma pack(1)
     EVENTS typeone[20];
     EVENTS typetwo[20];
 #pragma pack()

 int equal(EVENTS* v1, EVENTS* v2)
 {
      return 0==memcmp(v1, v2, sizeof(*v1));
 }

#pragma pack(1). これにより、構造体にパディング バイトがないことが保証されます。この方法では、memcmp はパディング バイトを比較しようとせず、比較はフィールドごとの方法よりもはるかに高速ですが、この場合、パフォーマンスが悪影響を受ける可能性は低いですが、次のようにします。

     typedef struct{
         char a;
         long b;
     } somestruct;

 #pragma pack(1)
     somestruct foo;
 #pragma pack()

検索foo.bには、パディングされた構造体の場合よりもはるかに多くのマシン コードが必要になります。これは、単一の 32 ビット命令で検索できるワード アラインされた位置が失われるためです。これらの 4 つの部分からターゲット レジスタに組み立てられます。そのため、パフォーマンスへの影響を考慮してください。

また、コンパイラが をサポートしているかどうかも確認してください#pragma pack。最新のコンパイラのほとんどはそうしていますが、それでも例外が発生する可能性があります。

于 2012-12-18T12:52:28.377 に答える