Frage zu den Zeigern



  • Hi,

    ich sitze gerade an dem OpenBook von Galileocomputing "C von A bis Z" und habe zwei Fragen zu folgendem Beispiel:

    /* ptr13.c */
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define MAX 255
    
    char *eingabe(char *str) {
       char input[MAX];
    
       printf("Bitte \"%s\" eingeben: ",str);
       fgets(input, MAX, stdin);
       return strtok(input, "\n");
    }
    
    int main(void) {
       char *ptr;
    
       ptr = eingabe("Vorname");
       printf("Hallo %s\n", ptr);
       ptr = eingabe("Nachname");
       printf("%s, interssanter Nachname\n", ptr);
       return EXIT_SUCCESS;
    }
    

    1. Wieso ist die Funktion "*eingabe" ein Zeiger und welchen Sinn macht das?
    2. Ein Kapitel zuvor wurde in dem Buch erwähnt, dass ein Zeiger !NUR! eine Adresse, einer Variable, als Wert haben kann/darf. Nur wieso darf er hier plötzlich einen String als Wert haben?

    Ich freue mich über jeden Versuch mir die Antworten, auf meine Fragen, näher zu bringen 😃 und bedanke mich jetz schon Mal ganz lieb im Voraus.

    LG
    RisH

    EDIT:
    Tut mir echt Leid, doch habe erst jetzt gesehen, dass ich ausversehen im C++ Unterforum gelandet bin. Könnte ein Mod den Beitrag bitte verschieben?
    Aber die Syntax ist ja eigentlich die gleiche.



  • die Funktion ist kein Zeiger 🙂

    char* func1_name() {return ' ';} 
    char * func2_name() {return ' ';}
    char *func2_name() {return ' ';}
    

    Das ist eine Funktion die einen char-pointer zurückliefert 😉

    Programmintern werden char* so interpretiert ... er 'pointet' auf den Start des arrays und (bei Ausgabe zB) werden alle Zeichen bis zum ersten '\0' ausgegeben. Der Pointer zeigt trotzdem nur auf die erste Stelle was du merkst wenn du zB

    char text[4] = "123\0"; // geht das? C ist lange her
    cout << text << endl;   // sollte '123\0' ausgeben
    cout << text+1 << endl; // sollte '23\0' ausgeben
    cout << text+2 << endl; // sollte '3\0' ausgeben
    cout << text+3 << endl; // sollte '\0' ausgeben
    cout << text+4 << endl; // krawumm
    

    Und das char* braucht immer ein Zeichen '\0' am Ende, wenn du also 6 Zeichen speichern willst, immer 7 allokieren und das letzte mit '\0' füllen ... sonst kanns irgendwann krachen.



  • padreigh schrieb:

    char text[4] = "123\0"; // geht das? C ist lange her
    

    Klar, geht. Die terminierende Null ergibt sich bei Literalen allerdings automatisch und muss somit nicht von dir von Hand in den String geschrieben werden. Das gleiche Ergebnis bekommst du also auch so:

    char text[4] = "123";
    
    //oder so:
    
    char text[]="123";  //die Länge des char-Arrays ergibt sich durch die Initialisierung
    

    padreigh schrieb:

    cout << text << endl;   // sollte '123\0' ausgeben
    

    Hier wird "123" ausgegeben, die Null stellt nur das Ende des Strings dar und wird nicht ausgegeben (abgesehen davon, dass 0 sowieso nicht druckbar ist).



  • RisH schrieb:

    char *eingabe(char *str) {
       char input[MAX];
    
       printf("Bitte \"%s\" eingeben: ",str);
       fgets(input, MAX, stdin);
       return strtok(input, "\n");
    }
    

    Wenn das so wirklich da drin steht, würde ich mir an deiner Stelle schleunigst ein besseres Buch besorgen - der Code, so wie er da steht, erzeugt undefiniertes Verhalten (die Funktion gibt verdeckt einen Zeiger auf eine lokale Variable zurück). Wenn das bei dir funktioniert, ist das reiner Zufall, und wenn der Autor das so geschrieben hat, hat er von C nicht genug Ahnung, um ein Buch darüber zu schreiben - das ist ein böser Anfängerfehler.



  • Ist ja nicht das erste Mal das Jürgen Wolf sich selbst als Laie outet. Traurig nur das so jemand Bücher schreibt von denen er nur bedingt Ahnung hat.

    Bitte bitte bitte egal was die Amazon Rezensionen sagen: kauft kein Buch von Jürgen Wolf wenn ihr wirklich ernsthaft C oder C++ lernen wollt. Ihr bekommt einfach verzerrte Grundlagen beigebracht die hinterher nur schwer wieder weg zu bekommen sind.

    Die guten Rezensionen kommen von Leuten die gar nicht wissen was an dem Buch falsch ist und nur den lockeren Schreibstil toll finden und dann erst Jahre später merken das die viel falsch verstanden haben.

    Traurig das der Verlag da mitmacht und ihn noch weite Grundlagenbücher schreiben lässt, das ist schon grob fahrlässing.



  • Wenn man nur das new-line am Ende des Strings entfernen will, geht das sicher auch etwas performanter, als strtok aufzurufen.

    strtok(input, "\n");
    

    besser wäre imho sowas:

    input[strlen(input) - 1] = 0;
    


  • Das ändert aber auch nichts daran, dass er danach nicht einfach input aus der Funktion zurückgeben kann - input wird ungültig, sobald die Funktion verlassen wird.

    Was Jürgen Wolf und Galileo Press angeht - naja, ein renommierter Fachverlag wird Galileo Press mit solchen Autoren jedenfalls nicht. Vielleicht hat man sich auf das Markt+Technik-Konzept eingeschossen, Bücher von Deppen an Deppen zu verkaufen. Geld ist auf die Weise ja zu machen.


Anmelden zum Antworten