1

我有两个数据结构:

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

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

这些已经填满了。typeone 已被填充到 typeone[5] 和 typetwo 直到 typetwo[8]。

我只想比较 typeone 和 typetwo 的前六个,看看它们的所有成员是否相等。

有没有办法typeone[1] == typetwo[1] 基本上比较 [1] 处数据结构内的所有值。有没有一种简短的方法可以做到这一点,还是我必须遍历每个成员并分别比较?

谢谢

4

3 回答 3

3

这是一个comp.lang.c 常见问题解答。简而言之,不,C 不支持与==运算符进行结构比较(常见问题解答中的答案说明了为什么在一般情况下很难做到这一点的几个原因)。您必须编写自己的函数并逐个成员进行比较。正如所指出的,由于访问填充字节时未指定的行为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;
  }
}

它实际上并没有那么多代码,当然您可以将循环简单地封装在一个交叉比较两个数组的前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 位指令检索的字对齐位置,必须通过四个字节读取来挑选它,然后从这四个部分组装到目标寄存器中。因此,请考虑性能影响。

另外,检查您的编译器是否支持#pragma pack. 大多数现代编译器都会这样做,但仍然可能发生异常。

于 2012-12-18T12:52:28.377 回答