Weisen Sie in C eine Struktur einer anderen zu

Lesezeit: 5 Minuten

Benutzeravatar von shreyasva
schreyasva

Können Sie eine Instanz einer Struktur einer anderen zuweisen, etwa so:

struct Test t1;
struct Test t2;
t2 = t1;

Ich habe gesehen, dass es für einfache Strukturen funktioniert, aber funktioniert es für komplexe Strukturen?
Woher weiß der Compiler, wie er Datenelemente abhängig von ihrem Typ kopiert, dh zwischen an unterscheidet int und Schnur?

Ja, wenn die Struktur vom gleichen Typ ist. Betrachten Sie es als eine Speicherkopie.

  • Denken Sie daran, dass es keine tiefe Kopie gibt, auf den Speicher verwiesen wird nicht kopiert.

    – Georg Scholly

    20. Februar 2010 um 13:43 Uhr


  • Parallelität ist auch hier ein Thema.

    – Tim Post

    20. Februar 2010 um 13:47 Uhr

  • @Tim Concurrency ist nicht mehr ein Problem als für die Zuweisung der eingebauten Typen wie Ganzzahlen und Doubles – die Zuweisung ist auch für diese keine atomare Operation.

    anon

    20. Februar 2010 um 13:58 Uhr

  • OK, wenn eine Kopie erstellt wurde, kann ich den Speicher später mit free() freigeben?

    – Betliste

    9. Mai 2012 um 10:26 Uhr

  • @Betlista Sie können den Speicher nicht mit free() freigeben, da es sich um automatische Variablen handelt: en.wikipedia.org/wiki/Automatic_variable

    – Joshdoe

    19. Juni 2012 um 16:32 Uhr

Ja, die Zuweisung wird für Strukturen unterstützt. Allerdings gibt es Probleme:

struct S {
   char * p;
};

struct S s1, s2;
s1.p = malloc(100);
s2 = s1;

Jetzt zeigen die Zeiger beider Strukturen auf denselben Speicherblock – der Compiler kopiert die Daten, auf die gezeigt wird, nicht. Es ist jetzt schwierig zu wissen, welcher Strukturinstanz die Daten gehören. Aus diesem Grund hat C++ das Konzept der benutzerdefinierbaren Zuweisungsoperatoren erfunden – Sie können spezifischen Code schreiben, um diesen Fall zu handhaben.

  • Ich habe es erhöht, weil ich durch das Lesen den Fehler / die Auslassung in meiner eigenen Antwort erkannt habe.

    – Clifford

    20. Februar 2010 um 14:50 Uhr

  • +1 für die Feststellung, dass eigentlich kein Kopieren stattfindet.

    – Tom Duckering

    20. Februar 2010 um 14:52 Uhr

  • Warum wurde dies als Spam markiert? Hat jemand die Kontrolle über seine Maus verloren?

    – Georg Fritzsche

    20. Februar 2010 um 19:58 Uhr

  • @gf Und anscheinend auch so beleidigend!

    anon

    20. Februar 2010 um 20:17 Uhr

  • @rahmanisback Die Antwort von Anon zu diesem Thema ist recht eindeutig: “Der Compiler kopiert die wies auf Daten”. Die Daten der struct selbst ist eindeutig kopiert.

    – Tobias

    11. Juli 2017 um 15:40 Uhr


Benutzeravatar von Arun Kaushal
Arun Kauschal

Schauen Sie sich zuerst dieses Beispiel an:

Der C-Code für ein einfaches C-Programm ist unten angegeben

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

Der äquivalente ASM-Code für foo_assign() ist

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    

Wie Sie sehen können, wird eine Zuweisung einfach durch eine “mov”-Anweisung in Assembler ersetzt, der Zuweisungsoperator bedeutet einfach, Daten von einem Speicherplatz zu einem anderen Speicherplatz zu verschieben. Die Zuweisung tut dies nur für unmittelbare Mitglieder einer Struktur und kann nicht kopiert werden, wenn Sie komplexe Datentypen in einer Struktur haben. Hier bedeutet KOMPLEX, dass Sie kein Array von Zeigern haben können, die auf Listen zeigen.

Ein Array von Zeichen innerhalb einer Struktur funktioniert selbst auf den meisten Compilern nicht, da die Zuweisung einfach versucht, zu kopieren, ohne den Datentyp auch nur als komplexen Typ zu betrachten.

  • Können Sie erläutern, unter welchen Bedingungen es fehlschlagen würde, da es bei mir immer zu funktionieren scheint

    – AlphaGoku

    23. November 2017 um 10:36 Uhr

  • Dies wurde aus dem einzigen Grund erhöht, dass diese Antwort einfach unglaublich lehrreich ist. Vielen Dank!

    – Wilhelm Martens

    13. Februar 2021 um 13:07 Uhr

Dies ist eine einfache Kopie, genau wie Sie es tun würden memcpy() (in der Tat erzeugen einige Compiler tatsächlich einen Aufruf an memcpy() für diesen Code). Es gibt keinen “String” in C, nur Zeiger auf ein paar Zeichen. Wenn Ihre Quellstruktur einen solchen Zeiger enthält, wird der Zeiger kopiert, nicht die Zeichen selbst.

Benutzeravatar von Clifford
Clifford

Meinten Sie “komplex” wie in komplexen Zahlen mit Real- und Imaginärteil? Dies erscheint unwahrscheinlich, wenn nicht, müssten Sie ein Beispiel geben, da “komplex” in Bezug auf die C-Sprache nichts Besonderes bedeutet.

Sie erhalten eine direkte Speicherkopie der Struktur; ob man das will, hängt von der Struktur ab. Wenn die Struktur beispielsweise einen Zeiger enthält, zeigen beide Kopien auf dieselben Daten. Dies kann oder kann nicht das sein, was Sie wollen; das liegt an Ihrem Programmdesign.

Um eine „intelligente“ Kopie (oder eine „tiefe“ Kopie) durchzuführen, müssen Sie eine Funktion implementieren, um die Kopie durchzuführen. Dies kann sehr schwierig zu erreichen sein, wenn die Struktur selbst Zeiger und Strukturen enthält, die ebenfalls Zeiger enthalten, und möglicherweise Zeiger auf solche Strukturen (vielleicht meinen Sie das mit „komplex“), und es ist schwer zu warten. Die einfache Lösung besteht darin, C++ zu verwenden und Kopierkonstruktoren und Zuweisungsoperatoren für jede Struktur oder Klasse zu implementieren, dann wird jede für ihre eigene Kopiersemantik verantwortlich, Sie können Zuweisungssyntax verwenden, und sie ist einfacher zu verwalten.

Benutzeravatar von Dean P
Dekan P

Ja, Sie können eine Instanz einer Struktur einer anderen zuweisen, indem Sie eine einfache Zuweisungsanweisung verwenden.

  • Im Fall von Nicht-Zeigern oder Nicht-Zeigern, die Strukturmitglieder enthalten, bedeutet Zuweisung Kopieren.

  • Im Fall von Zeigerstrukturmitgliedern bedeutet Zuweisung, dass der Zeiger auf die gleiche Adresse wie der andere Zeiger zeigt.

Lassen Sie uns das aus erster Hand sehen:

#include <stdio.h>

struct Test{
    int foo;
    char *bar;
};

int main(){
    struct Test t1;
    struct Test t2;
    t1.foo = 1;
    t1.bar = malloc(100 * sizeof(char));
    strcpy(t1.bar, "t1 bar value");
    t2.foo = 2;
    t2.bar = malloc(100 * sizeof(char));
    strcpy(t2.bar, "t2 bar value");
    printf("t2 foo and bar before copy: %d %s\n", t2.foo, t2.bar);
    t2 = t1;// <---- ASSIGNMENT
    printf("t2 foo and bar after copy: %d %s\n", t2.foo, t2.bar);
    //The following 3 lines of code demonstrate that foo is deep copied and bar is shallow copied
    strcpy(t1.bar, "t1 bar value changed");
    t1.foo = 3;
    printf("t2 foo and bar after t1 is altered: %d %s\n", t2.foo, t2.bar);
    return 0;
}

1424970cookie-checkWeisen Sie in C eine Struktur einer anderen zu

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy