C-Liste / Problem mit Verkettung mittels Pointer



  • Hallo liebes Forum,

    Ich möchte in C eine Liste von "Transitionen" erzeugen, in der mittels Prozedur "findLast" (s.u.) das erste Listenelement != NULL gefunden werden soll (sofern vorhanden).

    Beim Compilieren erhalte ich jedoch stets die Meldung

    pointer.c:18: error: request for member `next' in something not a structure or union

    wobei Zeile 18 die folgende der Prozedur "findLast" ist:

    kaese = &(*kaese->next);
    

    [Den u.a. Code habe ich auf das Wesentliche gekürzt, darum sollte man sich über Sinn oder Unsinn des Programmfragmentes keine Gedanken machen.]

    Warum kann der Pointer "kaese" nicht auf das "next"-Listenelement zeigen??

    Für eine Lösung wäre ich super dankbar! 🕶

    #include <stdlib.h>
    
    typedef struct {
      char* state1;
      char* label;
      char* state2;
    } TRANSITION;
    
    typedef struct {
      TRANSITION transition;
      struct TRANSITIONSLIST* next;
    } TRANSITIONSLIST;
    
    void findLast (TRANSITIONSLIST** kaese) {
      while(*kaese != NULL) {
        kaese = &(*kaese->next); /* Geht nicht?! */
      }
    }
    
    int main (int argc, char* argv[]) {
    
      TRANSITIONSLIST* kaese = NULL;
      findLast(&kaese);
      return 0;
    }
    


  • zuviel *&
    geht einfacher, event noch mal entsprechende dokus lesen

    (ich geh davon aus das du dich in dem von dir weggekuerztem teil darum kuemmerst das next mit NULL initialisiert wird)

    void findLast (TRANSITIONSLIST * kaese) {
    while(kaese != NULL) {
    kaese = kaese->next;
    }
    }

    aufruf:

    TRANSITIONSLIST * kaese = NULL;
    findLast(kaese);



  • Hallo daHa,

    Erstmal danke für die schnelle Antwort!!

    Mit den verkürzten & bzw * Symbolen klappt es, aber dann habe ich insbesondere bei dem ersten Listen-Element ein Call-By-Value statt Call-By-Reference.

    Angenommen, ich möchte in der Prozedur "findLast" das erste Listenelement setzen, also schreibend auf die Liste zugreifen (nicht schön, aber ist eben nur ein Beispiel). Dann brauche ich die Referenz auf das erste Zeigerelement.

    Wie sieht die Lösung aus, wenn der Prozedurkopf gleich bleiben soll?

    Ich hoffe, mein etwas erweitertes Beispiel (Adressen hier als "Hack") macht mein Problem klarer:

    #include <stdlib.h>
    
    typedef struct {
      char* state1;
      char* label;
      char* state2;
    } TRANSITION;
    
    typedef struct {
      TRANSITION transition;
      struct TRANSITIONSLIST* next;
    } TRANSITIONSLIST;
    
    /* Call-By-Value (klappt, aber ist nicht das, was ich haben will) */
    
    void findLast_cbv (TRANSITIONSLIST* kaese) {
    
      while(kaese != NULL) {
        kaese = (TRANSITIONSLIST*)(kaese -> next);
      }
    
      kaese = (TRANSITIONSLIST*)1; /* Aenderung nur lokale Variable */
    }
    
    /* Call-By-Reference (das, was ich eigentlich haben moechte) */
    
    void findLast_cbr (TRANSITIONSLIST** kaese) {
    
    /* Warum geht das hier nicht?! Erzeugt:
       error: request for member `next' in something not a structure or union
    
      while(*kaese != NULL) {
        *kaese = (TRANSITIONSLIST*)(*kaese -> next);
      }
    */
    
      *kaese = (TRANSITIONSLIST*)1; /* Aenderung glokale Variable */
    }
    
    int main (int argc, char* argv[]) {
    
      TRANSITIONSLIST* kaese = NULL;
      findLast_cbv(kaese);
      printf("%d\n",kaese); /* Ausgabe 0 */
    
      findLast_cbr(&kaese);
      printf("%d\n",kaese); /* Ausgabe 1 */
    
      return 0;
    }
    


  • void findLast_cbv (TRANSITIONSLIST* kaese) {

    ist nicht call by value, das ist call by reference. es wird nur die adresse übergeben, nicht das objekt.

    sowas

    int **a;

    ist nen pointer auf nen pointer. kann sinnvoll sein, aber in deinem fall nicht nötig.

    wenn du "echtes" by reference im c++ stil haben willst, kannst du auch

    void findLast_cbv (TRANSITIONSLIST& kaese) {

    schreiben. verhält sich in deinem fall dann aber gleich.



  • mal nen beispiel, wie verkettung funktioniert.

    #include <iostream>
    
    struct Node
    {
     int payload;
     Node *next;
    }
    
    void findLast(Node *node) // call by reference
    {
     while(node != 0)
      node = node->next;
    }
    
    int main()
    {
     Node c; c.payload = 3; c.next = 0;
     Node b; b.payload = 2; b.next = &c;
     Node a; a.payload = 1; a.next = &b;
    
     Node t = a;
     findLast(&t);
    
     std::cout << "last node's payload = " << t.payload << std::endl;
    
     return 0;
    }
    


  • Flachkoepper, bitte arbeite noch mal ein oder zwei tutorials durch

    und versuch dir selbst den unterschied von folgendem zu erklaehren

    void foo( int x ) ;
    void foo( int & x ) ;
    void foo( int * x ) ;

    und

    int x = 1;

    int a = x;
    int & b = x ;
    int * c = &x;

    und probier nach ein bissl herum, so ala

    *c = 5;

    b = 7;

    usw

    und schau dir jedesmal die werte an

    ich denke das sollte dann einige fragen klaehren


Anmelden zum Antworten