Assigner une structure à une autre dans C

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, ça marche 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 un int et une chaîne?

Oui si la structure est du même type. Pensez-le comme une copie de mémoire.

Oui, l’affectation est prise en charge pour les structures. Cependant, il y a des problèmes:

 struct S { char * p; }; struct S s1, s2; s1.p = malloc(100); s2 = s1; 

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 structure possède les données. C’est pourquoi C ++ a inventé le concept d’opérateur d’affectation définissable par l’utilisateur – vous pouvez écrire un code spécifique pour gérer ce cas.

Regardez d’abord cet exemple:

Le code C pour un programme simple C est donné ci-dessous

 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; } 

Le code ASM équivalent pour foo_assign () est

 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 

Comme vous pouvez le voir, une affectation est simplement remplacée par une instruction “mov” dans l’assemblage, l’opérateur d’assignation signifie simplement déplacer des données d’un emplacement de mémoire vers un autre emplacement de mémoire. L’affectation ne le fera que pour les membres immédiats d’une structure et ne parviendra pas à copier lorsque vous avez des types de données complexes dans une structure. Ici, COMPLEXE signifie que vous ne pouvez pas avoir un tableau de pointeurs, pointant vers des listes.

Un tableau de caractères dans une structure ne fonctionnera pas sur la plupart des compilateurs, car l’assignation essaiera simplement de copier sans même regarder le type de données comme étant de type complexe.

C’est une copie simple, comme vous le feriez avec memcpy() (en effet, certains compilateurs produisent 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, le pointeur est copié, pas les caractères eux-mêmes.

Vouliez-vous dire “complexe” en 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; que ce soit ce que vous voulez dépend de la structure. Par exemple, si la structure contient un pointeur, les deux copies indiqueront les mêmes données. Cela peut être ou ne pas être ce que vous voulez; c’est à 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 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 la gérer plus facilement.