[C++] Strings bei Parameterübergabe

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • [C++] Strings bei Parameterübergabe

    Hallo,

    Ich habe folgendes Problem bzw. folgende Frage:

    Wieso kann man Char-Arrys (strings) in Funktionsheader mit "Zeiger" bezeichnen?

    Beispiel, wie ich dies meine hier:

    Quellcode

    1. #include <iostream>
    2. using namespace std;
    3. void Test1(char *a, char b[]) // 1. Argument: Wieso ein "*a". Dies zeigt doch, dass es sich um einen Zeiger handelt. 2. Argument: Eindeutig - eine Char-Arry.
    4. {
    5. cout<<a<<endl;
    6. cout<<b<<endl;
    7. cout<<" ----- Werte ausgegeben ----- \n";
    8. }
    9. void Test2(char *a) // Hier ein "echter" Zeiger. Der Wert ist vorer 'a' und dann 'b'.
    10. {
    11. *a = 'b';
    12. cout<<"Adresse:"<<&a<<" Wert:"<<*a<<" Ohne Adresszeichen oder Stern:"<<a<<endl;
    13. cout<<" ----- Wert ausgegeben ----- \n";
    14. }
    15. int main()
    16. {
    17. Test1("Dies ist ein Test","Dies ebenfalls"); // Gleich Strings eintragen
    18. char Str[3]; // 1. Variante
    19. Str[0] = 'a';
    20. Str[1] = 'b';
    21. char Str2[3] = "cd"; // 2. Variante
    22. Test1(Str,Str2); // Strings in Char-Arrys
    23. ///////////////////////////////////////////////////////////////////////
    24. char x = 'a';
    25. cout<<"Vor der Funktion:"<<x<<endl; // 'a'
    26. Test2(&x); // Adresse übergeben
    27. cout<<"Nach der Funktion:"<<x<<endl; // 'b' - Zeiger tat seine Arbeit.
    28. cin.get();
    29. }
    Alles anzeigen


    Ausgabe:

    Dies ist ein Test
    Dies ebenfalls
    ---- Werte ausgegeben ----
    ab
    cd
    ---- Werte ausgegeben ----
    Vor der Funktion: a
    Adresse: 0x27fee0 Wert:b Ohne Addresszeichen oder Stern:bcd
    ---- Wert ausgegeben ----
    Nach der Funktion:b


    Ich hoffe mir kann jemand die Augen öffnen :Very Happy:

    // EDIT:

    Ich hab es nun rausbekommen bzw so erklärt bekommen (für alle Interessenten oder Leute die mich korrigieren wollen xP):
    Man kann Arrys nicht so "übergeben". Man müsste alles einzeln kopieren. Daher wird per Zeiger auf den Speicher, wo sich alle Elemente befinden, verwiesen. Man benötigt jedoch kein & bzw. kann dies "normal" angebenen, da die Arbeit abgenommen wird.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von KornChief ()

  • Man muss es nicht kopieren. Es ist immer die Frage, was man damit machen will.
    char* bezeichnet einen Zeiger auf einen char, nicht zwangsläufig ein Array!
    Beispiel:

    Quellcode

    1. void foo(char* bar)
    2. {
    3. // Hier kann bar entweder ein einzelner char sein, oder ein array.
    4. // Wenn es nur ein einzelnes zeichen ist, dann gibt das hier einen crash.
    5. char a = bar[4];
    6. }
    7. // Beispiel eines Crashs:
    8. int main()
    9. {
    10. char foobar = 'A';
    11. // Zeigerübergabe eines einzelnen Zeichens. in foo gibts dann eine Null-Pointer-Exception bzw sigsegv.
    12. foo(&foobar);
    13. }
    Alles anzeigen

    Dazu gibts 2 Lösungen:
    1.) Größe mit angeben.

    Quellcode

    1. void foo(char* bar, unsigned int size)
    2. {
    3. // Sicher, wenn man bei der Übergabe keinen Fehler macht.
    4. char last = bar[size];
    5. }

    2.) std::string verwenden

    Quellcode

    1. void foo(std::string bar)
    2. {
    3. // Auch das letzte zeichen
    4. char last = bar[bar.length()];
    5. }


    Das mit dem & scheinst Du allerdings nicht verstanden zu haben.
    Das & notiert in C++ eine Referenz. So wie ich das oben mit std::string gemacht habe, übergebe ich eine Kopie von bar. Sprich, das originale Objekt bleibt unverändert.
    Wenn ich eine Referenz übergebe, dann kann ich das Objekt verändern und auch das Original-Objekt wird verändert.
    Beispiel:

    Quellcode

    1. #include <iostream>
    2. void foo(std::string& bar)
    3. {
    4. bar += "World";
    5. }
    6. int main()
    7. {
    8. std::string hello = "Hello ";
    9. foo(hello);
    10. std::cout << hello << std::endl;
    11. }
    Alles anzeigen

    Die Ausgabe dieses Programmes ist "Hello World" weil foo den string hello ändert über die Referenz.
    Deswegen sollte man auch, wenn man Fehler vermeiden will, IMMER const angeben bei der Übergabe wenn man ein Objekt nicht verändern möchte und eine Kopie nicht in Frage kommt, weil das Objekt sehr groß ist.:

    Quellcode

    1. void foo ( const std::string& bar )
    2. {
    3. bar += "Hello"; // Compiler-Fehler!
    4. }

    Jetzt wird zwar auch eine Referenz übergeben, die schneller erzeugt wird als eine Kopie, aber das Objekt kann nicht verändert werden (ausser über gefährliche const-casts).
    Das gleiche gilt übrigens auch bei Zeigern. Bei referenzen genauso wie bei Zeigern ist nicht garantiert, dass das Objekt dahinter auf ein gültiges Objekt im Speicher zeigt.
    Hoffe Du hast das verstanden.
    rya.
    Sometimes it pays to stay in bed in Monday, rather than spending the rest of the week debugging Monday's code. ~Dan Salomon

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von superuser ()