Присвоить одной структуры в другую в C

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

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

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

5 ответов


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


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

struct S {
   char * p;
};

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

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


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

код 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 " в сборке, оператор назначения просто означает перемещение данных из одного места памяти в другое место памяти. Назначение будет делать это только для непосредственных участников структуры и не удастся скопировать, когда у вас есть сложные типы данных в структуре. Здесь комплекс означает ,что вы не можете иметь массив указателей, указывающих на списки.

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


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


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

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

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