Typumwandlung bei Struckturen



  • Hallo zusammen

    Wenn man eine Struktur "a" in eine Struktur "b" umwandeln
    will geht das überhaupt ohne Zeiger?

    also in der Form:

    struct a
    {
    	int a_Element_1;
    	int a_Element_2;
    	//int a_Element_3;
    };
    
    struct b
    {
    	int b_Element_1;
    	int b_Element_2;
    };
    
    struct b variable_b;
    struct a variable_a;
    
    variable_b = (struct b) variable_a;
    

    oder müssen zuerst Zeiger auf diese Strukturen gesetzt werden und dann in der
    oberen Form gecastet werden??
    Wie muss man sich eigendlich so eine Typumwandlung von Strukturen vorstellen?
    Wie werden die Elemente umgewandelt?
    Bei float zu int oder umgekehrt ist das ja recht einfach nach zu vollziehen.

    3.14 zu 3
    3 zu 3.00

    usw.



  • Es sind 2 unterschiedliche Typen die nichts miteinander zu tun haben.

    Schreib dir doch ne Funktion, die diese 'Umwandlung' vornimmt - sprich: die die Elemente kopiert.



  • Danke für die schnelle Antwort!

    Das bedeutet also das eine solche Umwandlung wie oben absolut nicht geht?
    Aber mit Zeigern sollte es gehen wie hier:
    Beispiel:

    //erwartet als zweiten Parameter einen Zeiger auf "sockaddr":
    //weiter unten beim Funktionsaufruf wird aber ein Zeiger auf "sockaddr_in" über
    //geben aber vorher umgewandelt in den Typ "sockaddr"
    int connect(int sockfd, struct sockaddr *serv_addr, int addrlen);
    
    //Ausgangspunkte sind zwei Struckturen:
    
    //Strucktur "sockaddr"
    struct sockaddr 
    {
    sa_family_t     sa_family;
    char            sa_data[14];
    };
    
    //struktur "sockaddr_in"
    struct sockaddr_in 
    {
    sa_family_t     sin_family;
    unsigned short  int sin_port;
    struct in_addr  sin_addr;
    unsigned char   pad[8];
    }
    
    //Hier die übergabe, wobei serv_addr ein Zeiger auf "sockaddr_in" ist
    connect(sockfd, (sockaddr *) &serv_addr, sizeof(sockaddr))
    

    Nur was passiert bei der übergabe bzw. Umwandlung dieser Strukturen??

    Das mit der Funktion ist ein gute Idee nur nützt sie mir in diesem Fall leider
    nichts.



  • OK, möglich ist es - ist aber nicht ganz unproblematisch.

    Denn eine struct kann padding Byte beinhalten - so dass zwischen den einzelnen Elementen sinnlose Bytes stehen, so kann die CPU effektiver die struct verarbeiten.

    Nun müssen diese Padding Bytes nicht immer gleich sein - so dass die beiden structs vielleicht identische Elemente besitzen, allerdings trotzdem andere Padding Bytes.

    Mit Compilerschalter kann man das umgehen (Padding Bytes abschalten) - und dann kann man auch memcpy() verwenden um die eine struct in die Andere zu kopieren.

    Selbiges Problem haben die Zeiger - wenn es Padding Bytes gibt, wird der Code fehlschlagen. Mir gefällt aus diesem Grund auch das Design der connect() Funktion nicht...



  • Nun ich will ja nicht erreichen das die beiden Struckturen gleich sind,
    sondern nur dass ich der funktion connect(...)eine andere Strucktur durch
    Typumwandlung übergeben kann.

    Was ich nun komisch finde ist das eine Solche Umwandlung geht obwohl die Struckturen ganz andere Elemente bzw Daten beinhalten.



  • Toady schrieb:

    Was ich nun komisch finde ist das eine Solche Umwandlung geht obwohl die Struckturen ganz andere Elemente bzw Daten beinhalten.

    Casts in C sind brute force casts. Wenn du ihm sagst: dieser Apfel ist eine Birne - dann glaubt er dir das.

    Aber es kann zu Problemen kommen:

    struct Apfel
    {
      char name[10];
      int form;
    };
    
    struct Birne
    {
      char name[10];
      double umfang;
    };
    
    void print(Apfel* p)
    {
      printf("%s\n", p->name); //vermutlich OK
      printf("%d\n", p->form); //vermutlich BUMM
    }
    
    int main(void)
    {
      struct Birne b;
      strcpy(b.name, "Hallo");
      b.umfang=3.1415;
      print((Apfel*)&b);
      return 0;
    }
    


  • meinst du mit BUMM seg fault?? wird in diesem fall wohl nicht vorkommen, da ein int kleiner als ein double ist und somit der zugriff weiterhin innerhalb der struktur erfolgt... ansonsten hast du natürlich recht. es kann also auch sonst zu unerwartetem verhalten kommen... da ist halt C++ doch schöner, wo ich einfach nur den zuweisungsoperator überladen muss bzw. "andere_struktur & operator()" implementieren kann 🙂



  • Danke für die schnellen Antworten hat mir geholfen! 🙂


Anmelden zum Antworten