Назначить одну структуру другому в C

Можно ли назначить один экземпляр структуры другому, например:

struct Test t1;
struct Test t2;
t2 = t1;

Я видел, как он работает для простых структур, bu работает он для сложных структур?
Как компилятор знает, как копировать элементы данных в зависимости от их типа, т.е. Проводить различие между int и строкой?

Ответ 1

Да, если структура одного типа. Подумайте, что это копия памяти.

Ответ 2

Да, назначение поддерживается для структур. Однако есть проблемы:

struct S {
   char * p;
};

struct S s1, s2;
s1.p = malloc(100);
s2 = s1;

Теперь указатели обеих структур указывают на один и тот же блок памяти - компилятор не копирует указанные данные. Теперь трудно понять, какой экземпляр структуры принадлежит данным. Вот почему С++ изобрел концепцию определяемых пользователем операторов присваивания - вы можете написать конкретный код для обработки этого случая.

Ответ 3

Сначала Посмотрите на этот пример:

Код C для простой программы на C приведен ниже

struct Foo {
    char a;
    int b;
    double c;
    } foo1,foo2;

void foo_assign(void)
{
    foo1 = foo2;
}
int main(/*char *argv[],int argc*/)
{
    foo_assign();
return 0;
}

Эквивалентный код ASM для foo_assign() -

00401050 <_foo_assign>:
  401050:   55                      push   %ebp
  401051:   89 e5                   mov    %esp,%ebp
  401053:   a1 20 20 40 00          mov    0x402020,%eax
  401058:   a3 30 20 40 00          mov    %eax,0x402030
  40105d:   a1 24 20 40 00          mov    0x402024,%eax
  401062:   a3 34 20 40 00          mov    %eax,0x402034
  401067:   a1 28 20 40 00          mov    0x402028,%eax
  40106c:   a3 38 20 40 00          mov    %eax,0x402038
  401071:   a1 2c 20 40 00          mov    0x40202c,%eax
  401076:   a3 3c 20 40 00          mov    %eax,0x40203c
  40107b:   5d                      pop    %ebp
  40107c:   c3                      ret    

Как вы можете видеть, что присваивание просто заменяется инструкцией "mov" в сборке, оператор присваивания просто означает перенос данных из одной ячейки памяти в другую ячейку памяти. Назначение будет выполняться только для непосредственных членов структур и не будет копироваться, если у вас есть сложные типы данных в структуре. Здесь COMPLEX означает, что вы не можете иметь массив указателей, указывая на списки.

Массив символов внутри структуры сам по себе не будет работать на большинстве компиляторов, потому что назначение просто пытается копировать, даже если тип данных не имеет сложного типа.

Ответ 4

Это простая копия, как и с memcpy() (действительно, некоторые компиляторы действительно вызывают вызов для memcpy() для этого кода). В C нет "строки", только указатели на кучу символов. Если ваша исходная структура содержит такой указатель, то указатель копируется, а не сами символы.

Ответ 5

Вы имели в виду "Комплекс", как в сложном числе с реальными и мнимыми частями? Это кажется маловероятным, так что если бы вы не стали приводить пример, поскольку "сложный" означает ничего специфического с точки зрения языка C.

Вы получите прямую копию копии памяти; независимо от того, что вы хотите, зависит от структуры. Например, если структура содержит указатель, обе копии указывают на одни и те же данные. Это может быть или не быть тем, чего вы хотите; это зависит от вашего дизайна программы.

Чтобы выполнить "умную" копию (или "глубокую" копию), вам нужно будет реализовать функцию для выполнения копии. Это может быть очень трудно достичь, если сама структура содержит указатели и структуры, которые также содержат указатели, и, возможно, указатели на такие структуры (возможно, что вы подразумеваете под "сложным" ), и ее трудно поддерживать. Простым решением является использование С++ и реализация конструкторов копирования и операторов присваивания для каждой структуры или класса, тогда каждый из них станет ответственным за свою собственную семантику копирования, вы можете использовать синтаксис присваивания, и его легче поддерживать.