Pointer auf pointer auf...



  • Wir lernen gerade C zu programmieren (auf Linux Ubuntu). DIe Grundkonzepte ähnen C++ aber trotzdem ist mir vieles neu.
    Habe ein Beispiel gegeben bei der wir das Code analysieren sollen und Fehler beheben müssen damit es kompilierbar wird.
    Habe vieles schon ausgebessert aber bei folgendem Codestück komme ich nicht weiter, genauer gesagt die Funktion PrintStrArr:

    int TestFuncPtr()
    
    {   
    
       char* unsorted[] = {(char*)"Hello", (char*)"Martha", (char*)"Anton", (char*)"Berta"};   
    
       void (*func) (char arr[]) = PrintLength;
    
       PrintHeader("Test Function Pointers");
    
       qsort(unsorted,4,sizeof(char*),comp);
    
       PrintStrArr(unsorted,4);
    
       CallFuncPointer(PrintBackward,unsorted);
    
       CallFuncPointer(func,unsorted);   
    
       return 0;
    
    }
    
    void PrintStrArr(char const * const * const arr, unsigned const len)
    
    {
    
       size_t i=0;
    
       for (;i<len;i++)
    
       {
    
          printf("%s\n",arr[i]);
    
       }
    
    }
    

    Als Fehlercode erhalte ich folgendes:

    Test.c: In function ‘TestFuncPtr’:
    Test.c:238:4: warning: passing argument 1 of ‘PrintStrArr’ from incompatible pointer type [enabled by default]
    In file included from Test.c:9:0:
    Print.h:8:6: note: expected ‘const char * const* const’ but argument is of type ‘char **’

    Nun was soll das sein: char const * const * const arr
    Arr ist ein konstanter Pointer auf einen konstanten... waaas? 😕 😃

    oder das:
    char* unsorted[] = {(char*)"Hello" ... -> ein normales array von char pointer, aber was tu ich da mit dem hello?

    ich schätze mal die lösung wäre iwo was zu casten, aber dafür bräuchte ich eure hilfe 🙂

    mfg
    acnut



  • ACnut schrieb:

    ich schätze mal die lösung wäre iwo was zu casten, aber dafür bräuchte ich eure hilfe 🙂

    Falsch geschätzt.
    Sich irgendwo irgendwas zusammenzucasten ist niemals die richtige Lösung. Nicht nur in C nicht.
    Zeiger-Casts sind Unsinn. Vergiß den (leider) oft vorkommenden Schrott, den du irgendwo aufgeschnappt hast.
    Casts (Zeiger-Casts immer, sonstige Casts meistens) zu benutzen bedeutet, den Kontrollmechanismus des Compilers bewusst auszuhebeln nach dem Motto "ich sage dem Compiler etwas, und weiß genau was ich tue; (weil ich vorher bei Datendesign gesündigt habe versuche ich jetzt, noch halbwegs irgendwas zu retten)". Dies ist insbesondere bei Anfängern nie gegeben.

    Mit (char*)"Hello" usw. beispielsweise sagst du dem Compiler, das ist ein Zeiger auf einen änderbaren Speicherbereich (char*), d.h. der Compiler wird hier nicht mehr warnen; Stringliterale sind aber hinsichtlich Änderungen ihrer Elemente UB. Der Compiler kann hier warnen, falls du korrekt "const char*" deklariert hast und anschließend trotzdem an den Elementen rumänderst. Er kann es nicht, wenn du das const wegcastest.

    const char* unsorted[] = {"Hello", "Martha", "Anton", "Berta"};
    

    sollte hier die Lösung sein, das ist doch gar nicht so schwierig.



  • du hast zwar Recht, allerdings "musste" ich trotzdem bei dieser funktion casten.

    int TestFuncPtr()
    
    {   
    
       const char* unsorted[] = {"Hello", "Martha", "Anton", "Berta"};
    
       void (*func) (char arr[]) = PrintLength;
    
       PrintHeader("Test Function Pointers");
    
       qsort(unsorted,4,sizeof(char*),comp);
       PrintStrArr(unsorted,4);
    
       /*auf char** casten*/
       CallFuncPointer(PrintBackward,(char**)unsorted);
       /*auf char** casten*/
       CallFuncPointer(func,(char**)unsorted);
    
       return 0;
    }
    

    was ich immer noch nicht verdtehe ist, dass ich immer noch keine deutsche Übersetzung für diese Zeile habe

    char const * const * const arr, unsigned const len
    

    letztes Jahr haben wir in C++ gelernt Pointercodes von rechts nach links zu lesen, aber ich komm nur auf unlogische Sätze



  • ACnut schrieb:

    was ich immer noch nicht verdtehe ist, dass ich immer noch keine deutsche Übersetzung für diese Zeile habe

    char const * const * const arr, unsigned const len
    

    letztes Jahr haben wir in C++ gelernt Pointercodes von rechts nach links zu lesen, aber ich komm nur auf unlogische Sätze

    arr ist ein konstanter zeiger auf einen konstanten zeiger auf einen constenten char.
    len könnte vielleicht ein constanter unsigned int werden, wenn da kein komma stünde, sondern ein semikolon.



  • ACnut schrieb:

    du hast zwar Recht, allerdings "musste" ich trotzdem bei dieser funktion casten.

    Hoffe, Du weißt, was passiert, wenn man stringliterale beschreibt.

    char* str=(char*)"hallo";//och, wen juckt schon der const-mist?
    str[0]='b';//autsch, selber schuld
    

  • Mod

    C kennt keine impliziten Multi-level-Zeigerkonvertierungen, ein Cast ist also an dieser Stelle erforderlich.



  • volkard schrieb:

    ACnut schrieb:

    du hast zwar Recht, allerdings "musste" ich trotzdem bei dieser funktion casten.

    Hoffe, Du weißt, was passiert, wenn man stringliterale beschreibt.

    char* str=(char*)"hallo";//och, wen juckt schon der const-mist?
    str[0]='b';//autsch, selber schuld
    

    mit const darf ich es halt nicht ändern, aber wieso autsch wenn man kein const macht?

    camper schrieb:

    C kennt keine impliziten Multi-level-Zeigerkonvertierungen, ein Cast ist also an dieser Stelle erforderlich.

    worauf ist das jetzt bezogen und was sind Multilevel -Zeiger?


Anmelden zum Antworten