Parameterübergaben



  • Hallo,

    Ich habe eine Frage zum Verständnis. In C++ bei Parameterübergaben vom Typ Pointer, einer Funktion, zb. int *fromlen, gibt mann soweit ich es verstanden habe die Dereferenzierte Variable also &variable an. Bei anderen Funktionen wiederrum, zb. bei strlen() wird auch ein *const char str verlangt. Dort gibt mann jedoch einfach die Variable ohne &-Operator an. Meine frage, gibt es dabei irgendeinen Konsens den mann befolgen kann? Mich verwirrt nämlich diese Pointer thematik.

    Und wenn ich eine Variable auf (typ 😉 caste, wie wird aus ihr ein Pointer, im technischen Sinn?



  • Einfache Antwort: Das musst du nicht wissen. Vegiß zeiger erstmal und lerne andere Dinge, du brauchst sie sowieso eher selten... Kümmere dich um Zeiger irgendwann später.

    Schwere Antwort: Pointer ist kein Typ. Pointer ist ein Pointer. Verlangt eine Funktion einen Zeiger, dann übergibst du ihr die Adresse einer Variablen, logisch. Das ist immer so und das ist demnach natürlich auch bei strlen() so.



  • Ein Array ist im Prinzip nichts anderes als ein Zeiger auf das erste Element, die Länge musst du selbst nachhalten.

    Daraus ergibt sich, dass Arrays implizit zu Zeigern konvertierbar sind.

    char str[] = "Hallo Welt";  // Array
    const char * str2 = "Hallo Welt"; // Der String ist ein konstantes Array, und darauf hast du einen Zeiger
    
    auto l1 = strlen(str); // implizit castbar, weil dasselbe
    auto l2 = strlen(str2); // ist ja schon der gleiche Datentyp
    


  • Ein Array ist also ein Pointer, mit mehreren Elementen auf die er zeigen kann?

    Ich hätte noch eine Frage:
    Besteht das nullterminierte Zeichen aus "\0" -> also aus 2 Zeichen am Ende des Strings oder ist es eigentlich nur eine "0".

    Ich habe nämlich ein Code der einen char mit "0" terminiert, anstatt mit "\0". "\0" gibt hier nämlich einen Fehler: Einen Typ von const char * kann keiner Entität vom Typ char zugewiesen werden

    char buffer[100];
    
    	//Daten ausgeben
    	if(nbytes > 0){
    		buffer[nbytes] = 0;
    


  • Skym0sh0 schrieb:

    Ein Array ist im Prinzip nichts anderes als ein Zeiger auf das erste Element, die Länge musst du selbst nachhalten.

    Quatsch solchen Nonsens irgendwelchen Anfängern hier vorzusetzen.



  • blubb schrieb:

    Ein Array ist also ein Pointer, mit mehreren Elementen auf die er zeigen kann?

    Nein.



  • blubb schrieb:

    Ich habe nämlich ein Code der einen char mit "0" terminiert, anstatt mit "\0". "\0" gibt hier nämlich einen Fehler: Einen Typ von const char * kann keiner Entität vom Typ char zugewiesen werden

    char buffer[100];
    
    	//Daten ausgeben
    	if(nbytes > 0){
    		buffer[nbytes] = 0;
    

    Nicht "\0". Das sind zwei Zeichen '\0' und '\0' nochmal als Terminierung. Richtig ist nur '\0'.



  • kann mal jemand klare Worte sprechen,ich bin verwirrter als vorher 😕

    Und wieso funktioniert das buffer[stringende] = 0; wenn das nullterminierende Zeichen ein"\0" sein muss?



  • Nein, verdammt nochmal nicht "\0".
    Es gibt Stringliterale. Diese beginnen und enden mit ". Solche Literale sind Werte im Arbeitsspeicher, die fest kodiert sind. Um sie an Funktionen zu übergeben brauchst du einen const char* (Pointer).
    Bei int Werten ist das anders. Die sind direkt in einer Variablen gespeichert.
    Um das eine Funktion zu übergeben, musst du nur die Variable übergeben, in diesem Fall hat sie den Typen int.
    Du kannst auch die Adresse übergeben, dann kann ein und dieselbe Variable in einer Funktion verändert werden. Da der Typ int und kein int-Pointer ist, brauchst du den Adressoperator & um die Adresse zu übergeben.
    Dann gibt es noch chars. Ein char speichert ein Zeichen, eingeschlossen in '. Intern werden die Zeichen in den Zeichenliteralen nach der ASCII-Tabelle in Zahlen umgewandelt. Aus '\0' wird 0. So weit so gut.
    Es gibt noch char-Arrays. Diese sind eigentlich genauso wie int-Arrays:

    int  int_arr [] = {1,2,3,4,5};
    char char_arr[] = {'a', 'b', 'c', 'd'};
    

    Um Arrays an Funktionen zu übergeben, übergibt man einen Pointer auf die Anfangsadresse und die Länge, damit die Funktion weiß, wie groß das Array ist.
    Da ein Array automatisch in ein Pointer auf das erste Element konvertiert werden kann, braucht man keinen besonderen Operator.

    void foo(int *arr, int size)
    ...
    int arr[] = {...};
    foo(arr, size_von_arr);
    

    Nun hat man sich jedoch einen Trick bei char-Arrays überlegt, die als String dienen sollen. Damit man nicht manuell zählen muss, hat man sich ein Zeichen überlegt, was das Ende markiert '\0' bzw 0 als Zahl. Funktionen, die nun ein char-Array brauchen, übergibt man nur die Anfangsadresse, die Funktion arbeitet dann so lange, bis sie auf ein '\0' trifft.

    void string_foo(char *arr)
    {
       for (int i = 0; arr[i] /* oder ausgeschrieben: arr[i] != '\0' (oder eben 0)*/; ++i)
        cout << arr[i];
    }
    

    Bei String Literalen (wir erinnern uns, das Zeug zwischen "), wird die '\0' bzw 0 automatisch angefügt. Dein "\0" besteht in Wirklichkeit also aus zwei Zeichen: Dem eigentlichen String, bestehend aus '\0' und dem automatisch angefügten Terminierer '\0'.
    Und weil folgendes bei längeren Strings ziemlich umständlich aussieht, gibt es einen Trick:
    Anstatt:

    char arr[] = {'T', 'e', 'x', 't', '\0'};
    

    Kann man auch einfach schreiben:

    char arr[] = "Text";
    

Log in to reply