我有两种数据结构:
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]处数据结构内的所有值。
有没有一种简短的方法可以做到这一点,还是我必须遍历每个成员并单独进行比较?
由于
答案 0 :(得分: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. */
}
答案 1 :(得分: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;
}
}
实际上并不是那么多代码,当然你可以将循环封装在一个交叉比较两个EVENTS
数组的 n 第一个插槽的函数中。
答案 2 :(得分: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
。大多数现代编译器都会这样做,但例外情况仍可能发生。