web-dev-qa-db-fra.com

Assigne une structure à une autre en C

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?

133
shreyasva

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

137
fabrizioM

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.

127
anon

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.

23
Arun Kaushal

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.

15
Thomas Pornin

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.

6
Clifford