Pouvez-vous assigner 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 fonctionne-t-il pour des structures complexes?
Comment le compilateur sait-il comment copier des éléments de données en fonction de leur type, c’est-à-dire différencier un int
et une chaîne?
Oui si la structure est du même type. Pensez-y 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 sur 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 est propriétaire des 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 C simple 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 constater, une affectation est simplement remplacée par une instruction "mov" dans Assembly, l'opérateur d'affectation signifie simplement le déplacement de 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 pourra pas être copiée lorsque vous aurez des types de données complexes dans une structure. Ici, COMPLEXE signifie que vous ne pouvez pas avoir un tableau de pointeurs pointant sur des listes.
Un tableau de caractères dans une structure ne fonctionnera pas en soi 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.
Ceci est une copie simple, comme vous le feriez avec memcpy()
(en fait, certains compilateurs génèrent un appel à memcpy()
pour ce code). Il n'y a pas de "chaîne" en C, seulement des pointeurs sur un groupe de caractères. Si votre structure source contient un tel pointeur, il est copié, pas les caractères eux-mêmes.
Voulez-vous dire "complexe" comme dans un nombre complexe avec des parties réelles et imaginaires? Cela semble peu probable, alors sinon, vous devriez donner un exemple, car "complexe" ne veut rien dire de particulier en termes de langage C.
Vous obtiendrez une copie directe en mémoire de la structure; Que ce soit ce que vous voulez ou non dépend de la structure. Par exemple, si la structure contient un pointeur, les deux copies pointeront sur les mêmes données. Cela peut être ou ne pas être ce que vous voulez; cela dépend de la conception de votre programme.
Pour effectuer une copie "intelligente" (ou une copie "en profondeur"), vous devez implémenter une fonction permettant d'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 qu'il est difficile à maintenir. La solution simple consiste à utiliser C++ et à implémenter des constructeurs de copie et des opérateurs d’assignation pour chaque structure ou classe. Chacune devient alors responsable de sa propre sémantique de copie, vous pouvez utiliser la syntaxe d’assignation et la maintenir plus facilement.