Можете ли вы назначить один экземпляр структуры другому, например так:
struct Test t1;
struct Test t2;
t2 = t1;
Я видел, как это работает для простых структур, но это работает для сложных структур?
Как компилятор знает, как копировать элементы данных в зависимости от их типа, т.е. различать int
строку и?
Да, назначение поддерживается для структур. Однако есть проблемы:
Теперь указатели обеих структур указывают на один и тот же блок памяти - компилятор не копирует указанные данные. Сейчас трудно понять, какой экземпляр структуры владеет данными. Вот почему C ++ изобрел концепцию определяемых пользователем операторов присваивания - вы можете написать специальный код для обработки этого случая.
источник
struct
себе четко скопированы.Сначала посмотрите на этот пример:
Код C для простой программы на C приведен ниже
Эквивалентный код ASM для foo_assign ()
Как вы можете видеть, что назначение просто заменяется инструкцией «mov» в сборке, оператор присваивания просто означает перемещение данных из одной ячейки памяти в другую ячейку памяти. Назначение будет делать это только для непосредственных членов структур и не сможет скопировать, если в структуре есть сложные типы данных. Здесь COMPLEX означает, что вы не можете иметь массив указателей, указывающих на списки.
Массив символов в структуре сам по себе не будет работать на большинстве компиляторов, потому что присваивание просто попытается скопировать, даже не глядя на тип данных сложного типа.
источник
Это простая копия, как и вы
memcpy()
(с некоторыми компиляторами, которые действительно вызываютmemcpy()
этот код). В Си нет «строки», только указатели на кучу символов. Если ваша исходная структура содержит такой указатель, то копируется указатель, а не сами символы.источник
memcpy
, см. Здесь: godbolt.org/z/nPxqWc - Но теперь, если я передаю идентичные указателиa
иb
, и*a = *b
преобразуется вmemcpy
неопределенное поведение, потому что дляmemcpy
«Области памяти не должны перекрываться». (цитата из справочной страницы). Так что компилятор неверен в использованииmemcpy
или я ошибаюсь при написании такого назначения?Вы имели в виду «Комплекс», как в комплексном числе с действительными и мнимыми частями? Это кажется маловероятным, поэтому, если нет, вам придется привести пример, поскольку «сложный» не означает ничего конкретного с точки зрения языка Си.
Вы получите прямую копию структуры памяти; это то, что вы хотите, зависит от структуры. Например, если структура содержит указатель, обе копии будут указывать на одни и те же данные. Это может или не может быть то, что вы хотите; это зависит от дизайна вашей программы.
Чтобы выполнить «умную» копию (или «глубокую» копию), вам потребуется реализовать функцию для выполнения копирования. Этого может быть очень трудно достичь, если сама структура содержит указатели и структуры, которые также содержат указатели и, возможно, указатели на такие структуры (возможно, это то, что вы подразумеваете под «сложным»), и его трудно поддерживать. Простое решение заключается в использовании C ++ и реализации конструкторов копирования и операторов присваивания для каждой структуры или класса, тогда каждый из них становится ответственным за свою собственную семантику копирования, вы можете использовать синтаксис присваивания и его легче поддерживать.
источник