Macro anpassen



  • #define swap(t,x,y) { t_z; \
                     _z = x;\
                      y = _z; }
    
    main()
    {
       char x,y;
       x = 'a';
       y = 'b';
    
       printf("x = %c \t y = %c\n", x, y);
    
       swap(char, x, y);
    
       printf("x = %c \t y = %c\n", x, y);
    }
    

    Ich möchte dieses Programm auch für Variablen von nicht skalare Typen nutzen (struct, int und string).Wie müsste ich es modifizieren?



  • Wenn du es so anpasst, dass es funktioniert, dann geht das auch für int, struct, double und Pointer.

    Mit Arrays geht es nicht.

    Mit memswap ( https://github.com/qca/open-plc-utils/blob/master/tools/memswap.c ) würde auch das gehen.
    Da musst du aber unbedingt auf die identische Größe achten.



  • mit structs geht es doch

    struct test {int a; int b;};
    
        struct test s1 = {1,2};
        struct test s2 = {3,4};
        swap (struct test, s1, s2);
    


  • DirkB schrieb:

    Mit Arrays geht es nicht.

    mit arrays in struct sollte es gehen.



  • swapper schrieb:

    DirkB schrieb:

    Mit Arrays geht es nicht.

    mit arrays in struct sollte es gehen.

    Das ist dann eine struct und kein Array.



  • DirkB schrieb:

    swapper schrieb:

    DirkB schrieb:

    Mit Arrays geht es nicht.

    mit arrays in struct sollte es gehen.

    Das ist dann eine struct und kein Array.

    Gibt es in dem Fall also keine Möglichkeit alles abzudecken?



  • DirkB schrieb:

    swapper schrieb:

    DirkB schrieb:

    Mit Arrays geht es nicht.

    mit arrays in struct sollte es gehen.

    Das ist dann eine struct und kein Array.

    swap für arrays gleicher länge:

    #define swap2(t,x,y) { char _z[t]; \
                     memcpy(_z,&x,t);\
                     memcpy(&x,&y,t);\
                      memcpy(&y,_z,t); }
    
    int main()
    {
        char a[] = "erster";
        char b[] = "zweite";
        swap2 (sizeof(a), a, b);
        puts (a);
        puts (b);
    }
    


  • Joe1903 schrieb:

    Gibt es in dem Fall also keine Möglichkeit alles abzudecken?

    siehe mein post zuvor. sollte auch mit primitiven typen gehen. kannste beliebig erweitern.



  • Wenn du auf den Adressoperator verzichtest, dann würde das auch für Pointer gehen (die auf gleich Große Speicherbereiche zeigen).

    Der Aufruf mit dem sizeof geht dann aber nicht.



  • Joe1903 schrieb:

    Gibt es in dem Fall also keine Möglichkeit alles abzudecken?

    Mit dem memswap würde das gehen.
    Da übergibst du dann nicht den Typ sonder die Größe des Elements (im Zweifel das Ergebnis von sizeof)

    Arrays sind in C besonders.

    Du kannst dir ja mal den Quellcode der Funktion qsort anschauen. Die vertauscht auch Elemente beliebiger Größe.

    Gibt es einen Grund für dein Makro?



  • DirkB schrieb:

    Wenn du auf den Adressoperator verzichtest, dann würde das auch für Pointer gehen (die auf gleich Große Speicherbereiche zeigen).

    Der Aufruf mit dem sizeof geht dann aber nicht.

    man kann nicht alles haben. der adressoperator ist nötig um auch structs, doubles usw. zu swappen.



  • swapper schrieb:

    DirkB schrieb:

    Wenn du auf den Adressoperator verzichtest, dann würde das auch für Pointer gehen (die auf gleich Große Speicherbereiche zeigen).

    Der Aufruf mit dem sizeof geht dann aber nicht.

    man kann nicht alles haben. der adressoperator ist nötig um auch structs, doubles usw. zu swappen.

    Ah, OK.

    Ich dachte, das swap2 wäre speziell für Arrays, bzw. Speicherbereiche



  • Und für sowas:

    struct test {int m; char m_string[16+1];};



  • Joe1903 schrieb:

    Und für sowas:

    struct test {int m; char m_string[16+1];};

    Das ist eine struct .

    structs kann man mit = zuweisen, daher klappt das auch mit dem (korrigiertem) swap aus deinem Eröffnungspost.

    Nochmal:
    Dein swap ist falsch definiert, da fehlt noch was.



  • DirkB schrieb:

    Joe1903 schrieb:

    Und für sowas:

    struct test {int m; char m_string[16+1];};

    Das ist eine struct .

    structs kann man mit = zuweisen, daher klappt das auch mit dem (korrigiertem) swap aus deinem Eröffnungspost.

    Nochmal:
    Dein swap ist falsch definiert, da fehlt noch was.

    Welcher korrigierte swap?



  • Joe1903 schrieb:

    #define swap(t,x,y) { t_z; \
                     _z = x;\
                      y = _z; }
    

    Funktioniert nicht wie gewünscht.
    Das macht einfach ein y = x;
    x behält den ursprünglichen Wert, das ist dann kein swap.
    Das muss korrigiert werden.

    Zudem würde der Compiler den Ausdruck char_t; anmeckern.



  • hier mal ein swap für arrays unterschiedlicher länge.
    das kürzere array kann natürlich das längere array nicht vollständig aufnehmen. daher ist die sinnhaftigkeit solchen swappens fraglich.

    #define MAX(a,b) (((a)>(b))?(a):(b))
    
    #define swap3(x,y) { char _z[MAX(sizeof(x),sizeof(y))]; \
                     memcpy(_z,&x,sizeof(x));\
                     memcpy(&x,&y,sizeof(x));\
                      memcpy(&y,_z,sizeof(y)); }
    


  • swapper schrieb:

    hier mal ein swap für arrays unterschiedlicher länge.
    das kürzere array kann natürlich das längere array nicht vollständig aufnehmen. daher ist die sinnhaftigkeit solchen swappens fraglich.

    #define MAX(a,b) (((a)>(b))?(a):(b))
    
    #define swap3(x,y) { char _z[MAX(sizeof(x),sizeof(y))]; \
                     memcpy(_z,&x,sizeof(x));\
                     memcpy(&x,&y,sizeof(x));\
                      memcpy(&y,_z,sizeof(y)); }
    

    Würde das auch für sowas funktionieren
    struct test {int m; char m_string[16+1];};? Wie könnte ich speziell diesen Fall testen?



  • DirkB schrieb:

    Joe1903 schrieb:

    Und für sowas:

    struct test {int m; char m_string[16+1];};

    Das ist eine struct .

    structs kann man mit = zuweisen, daher klappt das auch mit dem (korrigiertem) swap aus deinem Eröffnungspost.

    Nochmal:
    Dein swap ist falsch definiert, da fehlt noch was.



  • Belli schrieb:

    DirkB schrieb:

    Joe1903 schrieb:

    Und für sowas:

    struct test {int m; char m_string[16+1];};

    Das ist eine struct .

    structs kann man mit = zuweisen, daher klappt das auch mit dem (korrigiertem) swap aus deinem Eröffnungspost.

    Nochmal:
    Dein swap ist falsch definiert, da fehlt noch was.

    Das ist es ja,ich weiss nicht wie es aussehen müsste.
    Kann mir jemand helfen?


Log in to reply