Перенес это в ответ, так как он больше не подходит для комментариев.
Основная причина проблемы заключается в том, что если члены объединения имеют разные размеры, вам не гарантируется, что сравнение будет успешным, если записать в меньшие элементы, но затем сравнить более крупные элементы. Например, если вы записали в alph
член обоих объединений, но затем сравнили num
членов, один байт, содержащий alph
, будет сравниваться правильно, но даже если они равны, остальные байты в num
может отличаться, что приводит к «ложному неравному» результату. То же самое с записью num
членов и последующим сравнением real
членов.
Таким образом, чтобы избежать этой проблемы, вам нужно сначала сравнить два значения type
, и только если они совпадают, сравнить соответствующую пару членов объединения. Выбор элементов для сравнения проще всего выполнить с помощью переключателя.
node* findkey(list *l, union element key, int type)
{
node *i=list->head;
while(!i) {
// compare types first, assume no match if they differ
if(i->type != type) {
continue
}
switch (type)
{
case NUM:
if(i->data.num == key.num) {
return i;
}
break;
case STR:
...
case REAL:
...
case CHAR:
...
}
i=i->next;
}
return NULL;
}
Я добавлю примечание, что способ обработки case STR:
зависит от поведения, которое вы хотите. Если вы хотите, чтобы эти две строки совпадали, используйте strcmp()
, если вы хотите, чтобы они ссылались на одну и ту же строку, используйте ==
на двух указателях. Я подозреваю, что первый будет более полезным способом сделать что-то, но стоит отметить точное сравнение указателей. Несколько похоже на разницу между ==
и ===
в PHP.