你如何比较结构的两个实例在标准C平等?
Answer 1:
C提供无语言设施来做到这一点 - 你必须做你自己,并通过成员的每个结构成员进行比较。
Answer 2:
你可能会使用memcmp(&a, &b, sizeof(struct foo))
但它可能不会在所有情况下工作。 编译器可以添加对齐缓冲器空间的结构,并且在位于在缓冲空间的存储器位置中的值是不保证任何特定值。
但是,如果你使用calloc
或memset
使用之前的结构的全尺寸,你可以做一个浅层比较memcmp
(如果您的结构中包含指针,它只会如果地址指针都指向是相同的匹配)。
Answer 3:
如果你这样做了很多,我建议写两个结构比较的功能。 这样,如果你改变你只需要改变结构比较在同一个地方。
至于如何做到这一点....你需要每一个元素单独比较
Answer 4:
不能使用memcmp比较平等结构,由于在结构领域之间的潜在随机填充字符。
// bad
memcmp(&struct1, &struct2, sizeof(struct1));
上面会失败这样的结构:
typedef struct Foo {
char a;
/* padding */
double d;
/* padding */
char e;
/* padding */
int f;
} Foo ;
你必须使用成员两比较是安全的。
Answer 5:
请注意,您可以使用memcmp()对非静态钢结构制品,而不必担心填充,只要你不初始化所有成员(一次)。 这是由C90定义:
http://www.pixelbeat.org/programming/gcc/auto_init.html
Answer 6:
@格雷格是正确的,必须在一般情况下写明确的比较函数。
它可以使用memcmp
如果:
- 该结构不包含那些可能浮点领域
NaN
。 - 该结构包含无边框(使用
-Wpadded
铿锵检查本)或结构被明确初始化所用memset
在初始化。 - 没有成员类型(如Windows
BOOL
),其具有不同的但等效的值。
除非你是编程的嵌入式系统(或写,可能对他们使用的库),我就不会担心一些极端案例中的C标准。 近远与指针的区别不任何32位或64位设备上存在。 没有非嵌入式系统,我知道有多个NULL
指针。
另一种选择是自动生成的平等功能。 如果你躺在你的结构定义了一个简单的方法,可以用简单的文本处理来处理简单的结构定义。 您可以使用libclang对于一般情况 - 因为它使用相同的前端,铛,它正确地处理所有的情况(除非错误)。
我还没有看到这样的代码生成库。 然而,这似乎比较简单。
然而,它也是这样产生的平等功能会经常做错误的事情,在应用层面的情况。 例如,应在2层UNICODE_STRING
在Windows结构进行浅或深相比?
Answer 7:
这要看你问的问题是:
- 这些是两个结构相同的对象?
- 他们有相同的值?
要看看他们是同一个对象,比较指针指向两个结构是否相等。 如果您想了解一般的,如果它们具有相同的价值,你必须做深刻的对比。 这涉及到所有成员进行比较。 如果成员是指向其他结构需要递归到这些结构了。
在特殊情况下的结构不包含指针,你可以做一个memcmp执行包含在每个数据的逐位比较,而不需要知道数据的含义。
确保你知道什么是“等于”是指每个成员 - 这是显而易见的整数,但更微妙的,当涉及到浮点值或用户定义类型。
Answer 8:
memcmp
不比较结构, memcmp
比较二进制文件,总有垃圾的结构,因此它永远是假的比较。
通过元素其安全比较元素,不会失败。
Answer 9:
如果结构只包含原语,或者如果你有兴趣在严格的平等,那么你可以做这样的事情:
int my_struct_cmp(const struct my_struct * lhs, const struct my_struct * rhs) { return memcmp(lhs, rsh, sizeof(struct my_struct)); }
但是,如果你的结构包含指向其他结构或联合,那么你将需要编写一个基元比较正常的功能,使对其他结构适当的比较调用。
请注意,但是,你应该使用memset的(一,的sizeof(结构my_struct),1),以零出结构的内存范围内的ADT初始化的一部分。
Answer 10:
如果两个变量的结构是initialied用calloc或者正在memset的设定为0,所以你可以用memcmp比较你2层结构和没有关于结构垃圾担心,这将让你赢得时间
Answer 11:
该标准的示例使用Microsoft Visual Studio中的#pragma包编译器扩展,以确保成员都挤满尽可能紧的结构:
#include <string.h>
#pragma pack(push, 1)
struct s {
char c;
int i;
char buffer[13];
};
#pragma pack(pop)
void compare(const struct s *left, const struct s *right) {
if (0 == memcmp(left, right, sizeof(struct s))) {
/* ... */
}
}