Zeiger - Verständnisproblem



  • Hallo,
    ich habe folgenden Code für eine Vergleichsfunktion:

    int compare(const  void * lhs,const  void * rhs )
    {
      char * left  = *((char **) lhs);
      char * right = *((char **) rhs);
    
      printf("0)%p\n",lhs);
      printf("1)%p\n",(char *)lhs);
      printf("2)%p\n",*(char **)lhs);
      printf("3)%p\n",(char **)lhs);
      printf("4)%i\n",*(char *)lhs);
    
      return strcmp( left, right );
    }
    

    Nun verstehe ich nicht, was in den printf-Funktionen passiert.

    1. gibt den void-Pointer aus
    2. wandelt 0) in einen char-Pointer um, daher gilt 1)==0)
    3. der char-Pointer wird dereferenziert, ergebnis ist ein Integer

    Was passiert bei 2) und 3)? Kann mir jemand auf die Sprünge helfen?
    Und warum benötige ich diese komplizierte Konstruktion für den Vergleich mittels strcmp?

    Vielen Dank! 🙂



    1. aus lhs wird ein Zeiger auf einen Zeiger auf char gemacht und dann dereferenziert -> Zeiger auf char.
    2. aus lhs wird ein Doppelzeiger gemacht.

    Durch das casten wird der Wert der Zeiger nicht geändert.

    Das ganze brauchst du, wenn du strcmp für qsort nutzen willst da du bei qsort *char[] soertierst.



  • Genau, so habe ich mir das auch gedacht.
    Wenn ich aber bei 2) einen Zeiger auf char habe und bei 1) genauso, warum sind die Werte dann verschieden? Warum hebt sich die Dereferenzierung des Doppelzeigers nicht auf, warum gilt also nicht (char *)lhs == *(char **)lhs ?



  • Beim Dereferenzieren hebt sich nichts auf.
    (char*)lhs heißt, dass nicht lhs interpretiert wird, sondern der Speicherbereich auf den lhs zeigt als Zeigerwert interpretiert wird. Dereferenzierung bedeutet also das Auswerten der Daten für die der Zeiger einen Verweis darstellt, also das Ausnutzen des eigentlichen Sinn und Zwecks eines Zeigers.



  • Weil der Dereferenzierungsoperator (*) auf den Inhalt an der Stelle zugreift, auf die der Zeiger verweist.

    Und in diesem Fall ändert sich ja nichts an dem Wert des Zeigers selbst, sondern nur wie dun ihn interpretierst.



  • Danke, hab's verstanden :). 👍



  • 0), 1) und 3) sind ja lediglich andere Interpretierungen des Datentyps und bei 4) wird der Zeiger einfach dereferenziert.
    Aber 2) versteh ich nicht so ganz, also *(char**)
    Nach meiner Kenntnis muesste der Zeiger dann einfach als Zeiger auf char interpretiert werden (zuerst Zeiger auf Zeiger von char und dann dereferenziert zu Zeiger auf char - also muesste 2) doch dasselbe sein wie &lhs - aber das scheint falsch zu sein.

    P.S. Ich bin nicht der urspruengliche Threadstarter, ich hoffe das ist in Ordnung.



  • Da kommt schon ein char* raus, aber ...
    durch den Dereferenzierungsoperator (der * vor der Klammer) wird auf den Inhalt der Adresse zugegriffen, auf die der Zeiger verweist.

    lhs zeigt also auf eine Speicherstelle, in der ein Zeiger (auf char) steht.
    Den Wert von diesem Zeiger bekommst du bei 2)

    Da kannst du nichts "Kürzen".


Anmelden zum Antworten