Pouvez-vous affecter une instance d'une structure à une autre, comme ceci:
struct Test t1;
struct Test t2;
t2 = t1;
Je l'ai vu fonctionner pour des structures simples, mais est-ce que cela fonctionne pour des structures complexes?
Comment le compilateur sait-il copier des éléments de données en fonction de leur type, c'est-à-dire en différenciant une int
et une chaîne?
Oui, l'affectation est prise en charge pour les structures. Cependant, il y a des problèmes:
Maintenant, les pointeurs des deux structures pointent vers le même bloc de mémoire - le compilateur ne copie pas les données pointées. Il est maintenant difficile de savoir quelle instance de struct possède les données. C'est pourquoi C ++ a inventé le concept d'opérateurs d'affectation définissables par l'utilisateur - vous pouvez écrire du code spécifique pour gérer ce cas.
la source
struct
lui-même sont clairement copiées.Regardez d'abord cet exemple:
Le code C pour un programme C simple est donné ci-dessous
Le code ASM équivalent pour foo_assign () est
Comme vous pouvez voir qu'une affectation est simplement remplacée par une instruction "mov" dans l'assemblage, l'opérateur d'affectation signifie simplement déplacer des données d'un emplacement mémoire à un autre emplacement mémoire. L'affectation ne le fera que pour les membres immédiats d'une structure et échouera à la copie lorsque vous avez des types de données complexes dans une structure. Ici, COMPLEX signifie que vous ne pouvez pas avoir de tableau de pointeurs, pointant vers des listes.
Un tableau de caractères dans une structure ne fonctionnera pas lui-même sur la plupart des compilateurs, car l'affectation essaiera simplement de copier sans même regarder le type de données comme étant de type complexe.
la source
Ceci est une simple copie, comme vous le feriez avec
memcpy()
(en effet, certains compilateurs produisent en fait un appel àmemcpy()
pour ce code). Il n'y a pas de "chaîne" en C, seulement des pointeurs vers un groupe de caractères. Si votre structure source contient un tel pointeur, alors le pointeur est copié, pas les caractères eux-mêmes.la source
memcpy
, voir ici: godbolt.org/z/nPxqWc - Mais maintenant, si je passe des pointeurs identiquesa
etb
, et*a = *b
est traduit en unmemcpy
comportement indéfini, car pourmemcpy
"Les zones de mémoire ne doivent pas se chevaucher." (citant la page de manuel). Le compilateur a-t-il tort d'utilisermemcpy
ou ai-je tort d'écrire une telle affectation?Vouliez-vous dire "Complexe" comme un nombre complexe avec des parties réelles et imaginaires? Cela semble peu probable, donc sinon vous devrez donner un exemple puisque «complexe» ne signifie rien de spécifique en termes de langage C.
Vous obtiendrez une copie mémoire directe de la structure; si c'est ce que vous voulez dépend de la structure. Par exemple, si la structure contient un pointeur, les deux copies pointeront vers les mêmes données. Cela peut ou non être ce que vous voulez; cela dépend de la conception de votre programme.
Pour effectuer une copie «intelligente» (ou une copie «profonde»), vous devrez implémenter une fonction pour effectuer la copie. Cela peut être très difficile à réaliser si la structure elle-même contient des pointeurs et des structures qui contiennent également des pointeurs, et peut-être des pointeurs vers de telles structures (c'est peut-être ce que vous entendez par «complexe»), et c'est difficile à maintenir. La solution simple consiste à utiliser C ++ et à implémenter des constructeurs de copie et des opérateurs d'affectation pour chaque structure ou classe, puis chacun devient responsable de sa propre sémantique de copie, vous pouvez utiliser la syntaxe d'affectation et elle est plus facile à gérer.
la source