Kopieren Sie Struct zu Struct in C

Lesezeit: 5 Minuten

Benutzeravatar von Christian
Christian

Ich möchte eine identische Struktur in eine andere kopieren und später als Vergleich zur ersten verwenden. Die Sache ist, dass mein Compiler mich warnt, wenn ich so etwas mache! Soll ich es anders machen oder mache ich das falsch:

In Header-Datei:

extern struct RTCclk
{
uint8_t second;
uint8_t minute;
uint8_t hour;
uint8_t mday;
uint8_t month;
uint8_t year;
}
RTCclk;

In C-Datei:

struct RTCclk RTCclk;
struct RTCclk RTCclkBuffert;

void FunctionDO(void)
{
   ... // Some Code
   /* Copy first struct values into the second one */
   memcpy(&RTCclk, &RTCclkBuffert, sizeof RTCclk);
}

  • Welche Warnung gibt der Compiler aus?

    – Nick Shaw

    3. Februar 2012 um 10:39 Uhr

  • PS – sollte nicht die Größe des Anrufs sein sizeof(RTCclk)nicht sizeof TRCclk?

    – Nick Shaw

    3. Februar 2012 um 10:40 Uhr


  • Nur eine Warnung [2054] verdächtige Zeigerkonvertierung, sollte ich stattdessen memset oder memmove verwenden?

    – Christian

    3. Februar 2012 um 10:43 Uhr

  • @NickShaw: Die Klammern sind redundant, wie in i = (2)+(4);. Ich mag sie nicht; einige andere Leute tun.

    – pmg

    3. Februar 2012 um 10:44 Uhr

  • Der einzige Hinweis, den ich finden kann, ist “Warnung [2054] Verdächtige Zeigerkonvertierung” bezieht sich auf die Microchip-Compiler für PICs. Auf ihre Speicherzuordnungen kann auf unterschiedliche Weise zugegriffen werden, und sie können durch Dinge wie Banking beeinflusst werden, daher sollten Sie überprüfen, was die Signatur von memcpy() ist und wo sich Ihre Variablen befinden vom Linker platziert.Vielleicht ist die Verwendung der Strukturzuweisung wie beantwortet die sicherste Wahl.

    – Blechmann

    3. Februar 2012 um 10:56 Uhr

Für einfache Strukturen können Sie entweder verwenden memcpy wie Sie es tun, oder weisen Sie einfach von einem zum anderen zu:

RTCclk = RTCclkBuffert;

Der Compiler erstellt Code, um die Struktur für Sie zu kopieren.


Ein wichtiger Hinweis zum Kopieren: Es ist eine flache Kopie, genau wie bei memcpy. Das heißt, wenn Sie zB eine Struktur haben, die Zeiger enthält, werden nur die eigentlichen Zeiger kopiert und nicht das, worauf sie zeigen. Nach dem Kopieren haben Sie also zwei Zeiger, die auf denselben Speicher zeigen.

  • funktioniert es auch, wenn ich Arrays in struct habe? wie: struct example{ int myThings[10000]; Charaktername[100]; int-ID; };

    – M4rk

    7. Januar 2014 um 16:35 Uhr

  • Wie mache ich dann eine tiefe Kopie?

    – Benutzer

    27. März 2015 um 6:17 Uhr

  • @User Wenn die Struktur keine Zeiger enthält und enthaltene Strukturen keine Zeiger usw., dann ist das erledigt. Wenn es irgendwo Zeiger gibt, müssen Sie neuen Speicher zuweisen und mit zB kopieren memcpy.

    – Irgendein Programmierer-Typ

    27. März 2015 um 6:19 Uhr

  • Ja, es ist eine verkettete Liste. Also memcpy einfach das erste Element in der verknüpften Liste?

    – Benutzer

    27. März 2015 um 6:21 Uhr

  • @User Wenn Sie eine Liste kopieren möchten, ist es am einfachsten, eine Liste komplett neu zu erstellen. Schleife über die vorhandene Liste und rufe ihre Daten ab, dann füge sie der neuen Liste hinzu.

    – Irgendein Programmierer-Typ

    27. März 2015 um 6:24 Uhr

Benutzeravatar von Graham Borland
Graham Borland

Dein Code ist richtig. Sie können das eine auch direkt dem anderen zuweisen (siehe Antwort von Joachim Pileborg).

Wenn Sie später die beiden Strukturen vergleichen, müssen Sie darauf achten, die Strukturen auf lange Sicht zu vergleichen, ein Mitglied nach dem anderen, anstatt sie zu verwenden memcmp; siehe Wie vergleicht man Strukturen auf Gleichheit in C?

  • Also sollte ich dann so etwas tun: dowhile ( RTCclk.second != RTCclkBuffert.second || RTCclk.minute != RTCclkBuffert.minute || RTCclk.hour != RTCclkBuffert.hour || RTCclk.mday != RTCclkBuffert.mday) ;

    – Christian

    3. Februar 2012 um 12:09 Uhr

  • Ja. Obwohl es vielleicht besser wäre, den Vergleich in eine Funktion zu packen.

    – Graham Borland

    3. Februar 2012 um 12:12 Uhr

Kopieren Sie die Struktur in c, Sie müssen nur die Werte wie folgt zuweisen:

struct RTCclk RTCclk1;
struct RTCclk RTCclkBuffert;

RTCclk1.second=3;
RTCclk1.minute=4;
RTCclk1.hour=5;

RTCclkBuffert=RTCclk1;

jetzt hat RTCclkBuffert.hour den Wert 5,

RTCclkBuffert.minute hat den Wert 4

RTCclkBuffert.second hat den Wert 3

Auch ein gutes Beispiel…..

struct point{int x,y;};
typedef struct point point_t;
typedef struct
{
    struct point ne,se,sw,nw;
}rect_t;
rect_t temp;


int main()
{
//rotate
    RotateRect(&temp);
    return 0;
}

void RotateRect(rect_t *givenRect)
{
    point_t temp_point;
    /*Copy struct data from struct to struct within a struct*/
    temp_point = givenRect->sw;
    givenRect->sw = givenRect->se;
    givenRect->se = givenRect->ne;
    givenRect->ne = givenRect->nw;
    givenRect->nw = temp_point;
}

Dein memcpy Code ist richtig.

Meine Vermutung ist, dass Ihnen ein Include von string.h fehlt. Der Compiler geht also von einem falschen Prototyp aus memcpy und damit die Warnung.

Wie auch immer, Sie sollten die Strukturen der Einfachheit halber zuweisen (wie Joachim Pileborg darauf hingewiesen hat).

  • memcpy für Strukturen sagt “Ich weiß nicht, dass die Sprache, die ich verwende, Strukturzuweisungen unterstützt”. Der einzige Grund, memcpy jemals zwischen zwei Strukturen identischen Typs zu verwenden, besteht darin, dass Sie aus irgendeinem Grund sicherstellen müssen, dass die Strukturauffüllung genau beibehalten wird.

    – Kas

    13. Februar 2016 um 19:42 Uhr

Dans Benutzeravatar
Dan

memcpy erwartet, dass die ersten beiden Argumente void* sind.

Versuchen:
memcpy( (void*)&RTCclk, (void*)&RTCclkBuffert, sizeof(RTCclk) );

PS, obwohl nicht notwendig, schreibt die Konvention die Klammern für die Größe des Operators vor. Sie können in C mit einer Menge davonkommen, die den Code unmöglich zu warten macht, also ist das Befolgen von Konventionen das Kennzeichen eines guten (beschäftigungsfähigen) C-Programmierers.

  • memcpy für Strukturen sagt “Ich weiß nicht, dass die Sprache, die ich verwende, Strukturzuweisungen unterstützt”. Der einzige Grund, memcpy jemals zwischen zwei Strukturen identischen Typs zu verwenden, besteht darin, dass Sie aus irgendeinem Grund sicherstellen müssen, dass die Strukturauffüllung genau beibehalten wird.

    – Kas

    13. Februar 2016 um 19:42 Uhr

Benutzeravatar von Alpha
Alpha

Ich denke, Sie sollten die Zeiger auf (void *) setzen, um die Warnungen loszuwerden.

memcpy((void *)&RTCclk, (void *)&RTCclkBuffert, sizeof RTCclk);

Sie können auch sizeof ohne Klammern verwenden, Sie können dies mit Variablen verwenden, aber wenn RTCclk als Array definiert wurde, gibt sizeof von die volle Größe des Arrays zurück. Wenn Sie sizeof mit Typ verwenden, sollten Sie mit Klammern verwenden.

sizeof(struct RTCclk)

1418970cookie-checkKopieren Sie Struct zu Struct in C

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

Privacy policy