Почему всю структуру нельзя сравнивать в C, но все же ее можно скопировать? - PullRequest
11 голосов
/ 26 июня 2011

Почему всю структуру нельзя сравнивать в С, но ее можно скопировать? Другими словами, почему сравнение в приведенной ниже программе не работает? Строка не печатается.

#include <stdio.h>
#include <string.h>

int main(void)
{

    struct emp
    {
        char n[20];
        int age;
        };

    struct emp e1={"David",23};
    struct emp e2=e1;
    if(e2 == e1)
    {
        printf("The structures are equal");
    }
    return(0);
}

Ответы [ 6 ]

15 голосов
/ 26 июня 2011

Вы можете использовать memcmp ().В общем, это не очень хорошая идея, структуры имеют тенденцию иметь байты заполнения между полями.Заполнение используется для выравнивания поля.Ваша структура не имеет, но это случайно.Это заполнение может иметь любое значение, поэтому memcmp () перестает работать, потому что он видит все байты, а не только те, которые находятся в полях.

Более того, в структуре есть строка C.Он может содержать любые байты после нулевого терминатора.Использование strcmp () в строках вернет 0, но memcmp () снова не удастся, потому что он видит все байты.Указатели были бы еще одним режимом отказа.

Сравнение одного поля за раз.

4 голосов
/ 26 июня 2011
Элементы

struct обычно выровнены по некоторой границе, и когда вы инициализируете struct (особенно один в стеке), все в байтах, пропущенных выравниванием, будет неинициализировано. Более того, содержимое n после конца инициализатора константы не инициализируется. struct сравнение определяется как s1 == s2, выполняющее memcmp(&s1, &s2, sizeof s1), тогда как struct инициализация может копировать пропущенные байты или не копировать их. Если вы хотите надежно сравнить struct s, вам следует явно сравнить их элементы.

1 голос
/ 26 июня 2011

Он не печатает строку.

Но он даже не компилируется:

error: invalid operands to binary == (have ‘struct emp’ and ‘struct emp’)
0 голосов
/ 14 июля 2015

Но если вы передадите свое значение в строку, оно будет работать?

void Comparethisvalue(emp a, emp b) 
{
    if(a.n.tostring()+a.age.tostring() == b.n.tostring()+b.age.tostring())
      return true; 
}

в коде вы можете позвонить

if(Comparethisvalue(e1, e2))
{
  //do something
}

Или вы можете сделать это неявно:

void Comparethisvalue(emp a, emp b) 
{
  if(a.n == b.n && a.age == b.age)
    return true; 
}
0 голосов
/ 27 июня 2011

просто идея, приведёт ли его к типу типа void *, а затем сравнивать работу?Я думал что-то вроде

 struct emp e1 = { "David",23 };
 struct emp e2 = e1;
 if (*((void*)&e1) == *((void*)&e2))
 {
   /* pure evil? I think not :3*/
 }
0 голосов
/ 26 июня 2011

Помимо других правильных вещей, которые были сказаны, помните, что «сравнение», как правило, не является тривиальным действием: оно просто для «примитивных» базовых типов. Сложным типам (в данном случае структурам) потребуется перегрузка ==, но у C такой концепции нет.

Чтобы сравнить два «объекта» (структуры), вы должны написать свою собственную функцию, которая знает, как их сравнивать, например, int compare_emp(const struct emp *, const struct emp *); или аналогичный.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...