Pointer in C



  • Hallo zusammen

    Ich habe wieder einmal eine Frage zu den Pointern.

    Ich denke ich habe die Pointer schon etwas besser verstanden, aber in diesem Video zB

    https://www.youtube.com/watch?v=JTttg85xsbo&t=14

    bei 7:48

    erstellt er eine Pointer int *p und weist diesem die Adresse von int a zu.
    Dann erstellt er einen Pointer char *p0.

    Jetzt verstehe ich nicht, warum er beim Casten p0=(char*)p ausführt.
    p0 muss doch nun eine Adresse zugewiesen werden und kein Wert.

    Sprich also

    a=1025 zB an Adresse 200
    p=&a --> p ist dann 200, zB an Adresse 500

    Wenn ich doch nun
    p0 = (char*) p setze, erhalte ich doch p=1, weil char und nicht die Adresse..
    Bei ihm funktionierts aber.
    Wo habe ich den Denkfehler?

    Ich wäre um Hilfe dankbar.

    Edit: Oder muss ich das so verstehen:
    Weil der * innerhalb der Klammern steht, teile ich dem Compiler mit, dass ich auf einen char Pointer zeigen möchte und weise ihm p zu, wodurch dann der Compiler weiss, dass er nur ein Byte ab der Adresse 200 lesen muss, wenn ich deferenziere?



  • Ja,

    p0=(char*)p;
    

    bedeutet, daß dem Zeiger p0 der Zeiger p zugewiesen wird. Weil diese aber nicht direkt kompatibel sind, muß noch ein sog. cast durchgeführt werden, der den Zeigerwert von p zu einem "Zeiger auf char" macht.
    Und erst durch die Dereferenzierung, also *p0 bzw. *p, wird auf den Zeigerinhalt zugegriffen.



  • char* ist die Bezeichnung für den Typ Zeiger auf char

    Mit dem Cast zeigst du dem Compiler, dass du weißt, dass die Typen (char* und int*) nicht zueinander passen, du aber trotzdem diese Operation möchtest. Dann meckert der Compiler nicht.

    Dass der Compiler nur ein Byte holen muss, weiß er dadurch, dass p0 vom Typ char* ist

    Bei p0 = (char) p;* werden Zeiger kopiert (je nach System so 2 bis 8 Byte)

    Deine Edit Erklärung würde eher für

    char c;
    
    c= *(char*)p;
    

    passen



  • Vielen Dank für die Inputs.

    Ich habe das Video gesehen zu den structures.
    https://www.youtube.com/watch?v=Ranc3VvjI88&index=42&list=PLVlQHNRLflP8IGz6OXwlV_lgHgc72aXlh

    bei 11:16 geht es um den Access mittels Punkt

    Nun

    ich habe bei einem Programm definiert

    typedef struct{
        uint8 start;
        d_t id;
        uint16 länge;
    
    } xxx_t;
    

    dann habe ich versucht im main mittels

    xxx_t var;
    
    var.start = 0x0000;
    var.id = 0x01;
    var.länge = 3;
    

    die Werte zuzuweisen. Ich habe jedoch die Fehlermeldung bekommen, dass ich irgendetwas mit union definieren müsste und habe es dann folglich auf v->start ändern müssen. Dann hat es funktioniert.

    Wieso also gibt er im Video an, dass der Accessor der Punkt ist und nicht der Pfeiloperator?
    Oder was habe ich falsch gemacht?

    Grüsse



  • Hallo,

    es wäre sinnvoll gewesen, die Fehlermeldung zu zitieren. Oder den Code, der nicht funktioniert.

    Ich habe jedoch die Fehlermeldung bekommen, dass ich irgendetwas mit union definieren müsste und habe es dann folglich auf v->start ändern müssen

    Das ergibt überhaupt keinen Sinn, auf union-Members wird genauso zugegriffen wie auf struct-Members, der -> Operator wird benutzt, wenn man einen Zeiger auf eine Struktur (oder Union) vorliegen hat.



  • Bashar schrieb:

    wenn man einen Zeiger auf eine Struktur (oder Union) vorliegen hat.

    Danke das wars. 😋
    Ich habe jetzt nochmals genau geschaut und siehe da.
    Ich habe doch *var definiert gehabt und nicht var.

    xxx_t* var;
    
    var.start = 0x00;
    var.id = 0x01;
    var.länge = 3;
    

    Wenn man seinen eigenen Code nicht mehr versteht, sollte man denke ich aufhören zu programmieren.. 🙄



  • Das ist richtig. Höre lieber auf.
    Du hast Zeiger nicht verstanden, d.h. du hast C nicht verstanden.
    Du hast einen Zeiger definiert, der auf undefinierten Speicher zeigt, das ist Unfug und UB.



  • Wutz schrieb:

    Das ist richtig. Höre lieber auf.
    Du heißt Zeiger nicht verstanden, d.h. du hast C nicht verstanden.
    Du hast einen Zeiger definiert, der auf undefinierten Speicher zeigt, das ist Unfug und UB.

    und du kannst mit Deutsch aufhören. 😉
    Aber ich bin auf dem besten Weg. 😉

    wieso zeigt dieser auf undefinierten Speicher?
    was heisst UB?

    Ich habe noch folgende Frage zu den Erklärungen bei
    http://www.wachtler.de/ck/8_7_struct_union.html

    Der Pointer in der Funktionsübergabe zeigt doch auf den struct.
    Warum schreibt er (*p).name anstatt p->name?
    Ist doch ein Pointer, der darauf zeigt und keine gewöhnliche Variable.

    typedef struct
    {
      char                name[30];
      char                beruf[20];
      union manta_oder_iq miq;
    }
    person_t;
    
    void lese_person( person_t *p )
    {
      printf( "Bitte den Namen eingeben: " );
      scanf( "%s", (*p).name );
      printf( "Bitte den Beruf eingeben: " );
      scanf( "%s", (*p).beruf );
      if( strcmp( (*p).name, "Manni" ) )
      {
        printf( "Bitte den Intelligenzquotienten:  " );
        scanf( "%d", &((*p).miq.iq) );
      }
      else
      {
        printf( "Bitte die Hoechstgeschwindigkeit: " );
        scanf( "%f", &((*p).miq.geschwindigkeit) );
      }
    }
    


  • buell schrieb:

    wieso zeigt dieser auf undefinierten Speicher?
    was heisst UB?

    Wohin zeigt er denn sonst? UB = undefined behavior

    Der Pointer in der Funktionsübergabe zeigt doch auf den struct.
    Warum schreibt er (*p).name anstatt p->name?

    Wieso meinst du denn, dass das erste nicht funktionieren sollte? Wenn p auf die Struktur zeigt, dann ist *p doch eine Struktur, also kann man mit . darauf zugreifen. (BTW die -> Schreibweise ist nur eine Abkürzung für die andere.)



  • buell schrieb:

    Aber ich bin auf dem besten Weg. 😉

    wieso zeigt dieser auf undefinierten Speicher?
    was heisst UB?

    Bist du nicht.
    Das Problem mit euch Anfängern ist durchweg, dass ihr nach flüchtiger Lektüre zweifelhafter Quellen glaubt, C verstanden zu haben.
    Und bei dir kommt noch Unkenntnis von Basisvokabular hinzu.
    Nimm lieber Basic oder Java, das kommt deiner Lernweise besser entgegen.



  • [quote="Bashar"]

    buell schrieb:

    wieso zeigt dieser auf undefinierten Speicher?
    was heisst UB?

    Wohin zeigt er denn sonst? UB = undefined behavior

    Ich habe keine Ahnung.
    Was müsste ich denn anders machen, damit der Speicher definiert ist?
    Auf die Schnelle hätte ich gesagt, ich müsste es ändern zu

    struct Paket{ 
        uint8 start; 
        d_t id; 
        uint16 länge; 
    
    };
    
    struct Paket var; 
    
    var.start = 0x00; 
    var.id = 0x01; 
    var.länge = 3;
    

    Ausserdem müsste doch bei dem gezeigten Beispiel hier http://www.wachtler.de/ck/8_7_struct_union.html der Speicher auch undefiniert sein. Ich sehe mit seinem typedef struct leider keinen Unterschied zu meinem..



  • buell schrieb:

    Was müsste ich denn anders machen, damit der Speicher definiert ist?

    Zum Beispiel den Zeiger auf ein passendes Objekt zeigen lassen. Oder dynamische Allokation mit malloc/free.

    Auf die Schnelle hätte ich gesagt, ich müsste es ändern zu

    Naja, ohne Zeiger hast du das Problem natürlich nicht.

    Ausserdem müsste doch bei dem gezeigten Beispiel hier http://www.wachtler.de/ck/8_7_struct_union.html der Speicher auch undefiniert sein.

    Warum, kannst du nicht sagen, worauf der Zeiger dort zeigt?



  • Bashar schrieb:

    buell schrieb:

    Was müsste ich denn anders machen, damit der Speicher definiert ist?

    Zum Beispiel den Zeiger auf ein passendes Objekt zeigen lassen.

    Mein Pointer zeigt doch auf die DAtenstruktur.
    Mit struct Paket* var; wurde Speicher alloziiert.

    struct Paket{ 
        uint8 start; 
        d_t id; 
        uint16 länge; 
    
    }; 
    
    struct Paket* var; 
    
    var->start = 0x00; 
    var->id = 0x01; 
    var->länge = 3;
    


  • buell schrieb:

    Mein Pointer zeigt doch auf die DAtenstruktur.

    Aber wo liegt diese DAtenstruktur?
    Wohin verweist der Pointer.

    buell schrieb:

    Mit struct Paket* var; wurde Speicher alloziiert.

    Aber nur für den Pointer. Und diesem Pointer hast du noch keinen Wert (Adresse) zugewiesen.



  • DirkB schrieb:

    buell schrieb:

    Mein Pointer zeigt doch auf die DAtenstruktur.

    Aber wo liegt diese DAtenstruktur?
    Wohin verweist der Pointer.

    buell schrieb:

    Mit struct Paket* var; wurde Speicher alloziiert.

    Aber nur für den Pointer. Und diesem Pointer hast du noch keinen Wert (Adresse) zugewiesen.

    Ja das könnte der gute Mann im Video ruhig auch mal erwähnen zu den structures mit Pointern 😡

    Naja, ich habe nun eine bessere Seite gefunden, als ich nach memory allocation for structures gesucht habe.
    Gestossen bin ich auf folgende Seite und muss sagen, dass diese so ziemlich gut ist.

    https://www.programiz.com/c-programming/c-structures-pointers

    Damit müsste nun Wutz auch zufrieden sein, denn diese scheint nicht so dubios zu sein.
    Was haltet ihr davon, denn ich werde mich nun daran halten und weiter üben.
    Mir gefällt auch, dass vor den Erklärungen erstmal ein Bild gezeigt wird.

    Damit folgt für mein Programm die Lösung:

    struct Paket{ 
        uint8 start; 
        d_t id; 
        uint16 länge; 
    
    }; 
    
    struct Paket *ptr, var;
    ptr = &var;
    
    oder
    mit n Werte die zuvor eingegeben werden durch den User 
    
    ptr = (struct Paket*) malloc(n * sizeof(struct Paket));
    
    if(ptr == Null)
    {
    printf("Out of Memory Error\n");
    }
    else
    {
    printf("Enter Paket data:");
    }
    
    var->start = 0x00; 
    var->id = 0x01; 
    var->länge = 3;
    


  • buell schrieb:

    Ja das könnte der gute Mann im Video ruhig auch mal erwähnen zu den structures mit Pointern 😡

    Das gilt ganz Allgemein für Pointer.
    Also wurde es hoffentlich schon vorher erklärt.

    buell schrieb:

    Gestossen bin ich auf folgende Seite und muss sagen, dass diese so ziemlich gut ist.

    Das kannst du mit deinem Wissen noch nicht beurteilen.

    buell schrieb:

    Damit müsste nun Wutz auch zufrieden sein, denn diese scheint nicht so dubios zu sein.

    Die Hoffnung stirbt zuletzt, aber sie stirbt.

    buell schrieb:

    Damit folgt für mein Programm die Lösung:

    struct Paket{ 
        uint8 start; 
        d_t id; 
        uint16 länge; 
      
    }; 
      
    struct Paket *ptr, var;
    ptr = &var;
    
    oder
    mit n Werte die zuvor eingegeben werden durch den User 
    
    ptr = (struct Paket*) malloc(n * sizeof(struct Paket));
    
    if(ptr == Null)
    {
    printf("Out of Memory Error\n");
    }
    else
    {
    printf("Enter Paket data:");
    }
      
    var->start = 0x00; 
    var->id = 0x01; 
    var->länge = 3;
    

    Der Cast bei malloc ist in C nicht nötig und verdeckt Fehler (fehlende Deklaration von malloc)
    Du überprüfst zwar, ob malloc erfolgreich war, greifst aber im Fehlerfall troztdem auf den Speicher zu.



  • DirkB schrieb:

    buell schrieb:

    Ja das könnte der gute Mann im Video ruhig auch mal erwähnen zu den structures mit Pointern 😡

    Das gilt ganz Allgemein für Pointer.
    Also wurde es hoffentlich schon vorher erklärt.

    buell schrieb:

    Gestossen bin ich auf folgende Seite und muss sagen, dass diese so ziemlich gut ist.

    Das kannst du mit deinem Wissen noch nicht beurteilen.

    buell schrieb:

    Damit müsste nun Wutz auch zufrieden sein, denn diese scheint nicht so dubios zu sein.

    Die Hoffnung stirbt zuletzt, aber sie stirbt.

    buell schrieb:

    if(ptr == Null)
    {
    printf("Out of Memory Error\n");
    }
    else
    {
    printf("Enter Paket data:");
    }

    var->start = 0x00;
    var->id = 0x01;
    var->länge = 3;
    [/code]

    Der Cast bei malloc ist in C nicht nötig und verdeckt Fehler (fehlende Deklaration von malloc)
    Du überprüfst zwar, ob malloc erfolgreich war, greifst aber im Fehlerfall troztdem auf den Speicher zu.

    Ok die geschweifte Klammer von else müsste nach den Zuweisungen kommen und zuvor noch falls notwendig die Werte per scanf einlesen.

    Was für eine Quelle könnt ihr denn empfehlen, wenn nicht der Link von mir für den Anfang?
    Die ist doch gut für Anfänger..



  • void* malloc(size_t size);  //Deklaration
    
    ptr = (struct Paket*) malloc(n * sizeof(struct Paket));
    
    if(ptr == Null)
    {
    printf("Out of Memory Error\n");
    }
    else
    {
    printf("Enter Paket data:");
    
    var->start = 0x00; 
    var->id = 0x01; 
    var->länge = 3;
    }
    

    Der Cast bei malloc ist in C nicht nötig und verdeckt Fehler (fehlende Deklaration von malloc)

    Hallo Dirk
    nochmals, die malloc-Funktion gibt doch so ein void* (generic Pointer) zurück und der Pointer ist vom Typ struct Paket
    Also muss ich schon casten. Warum in C nicht? Verstehe ich jetzt nicht. 😕



  • In C ist jeder Zeiger ohne Cast von und nach void* konvertierbar.



  • Ja das ist mir schon klar, wenn ich einen int habe muss ich auuch nicht auf einen int casten..
    genauso für void* auf void* und string auf string, was auch immer.

    Kapier ich immer noch nicht, was ihr meint.

    ich habe void* (malloc) und brauch struct Paket (Pointer)
    also folgt Casting
    😕


Anmelden zum Antworten