Funktionswertübergabe / Funktion nach main wird nicht beachtet und übersprungen.



  • Hi
    ich schreibe ein Programm, der den Namen einliest und dann an eine Funktion übergibt. Diese soll dann meinen eingegebenen Namen mit dem Text ""Hello name this is your first Visual C++ program ...Congratulations!" ausgeben...

    Joa beim kompilieren wird die selbstgeschriebene Funktion einfach übersprungen und beim Funktionsaufruf in main kommt eine Fehlermeldung: "Bezeichner nicht gefunden". Bin echt ratlos, hatte mir c++ anders vorgestellt ..irgendwie mehr c# like. Danke für Hilfe.

    Hier der Code:

    #include <stdio.h>
    #include <iostream>
    #include <string>
    using std::string;
    using namespace std;
    
    int main()
    {
    
    	std::cout << "Bitte Name eingeben:" << std::endl;
    	string name;
    	std::cin >> name;
    	printhello(name);
    
    	return 0;
    }
    
    int printhello(string name)
    {
    	std::cout << "Hello" << name <<"this is your first Visual C++ program ...Congratulations!" << std::endl;
    	return 0;
    }
    


  • Wenn du eine Funktion aufrufen möchtest, muss sie zu diesem Zeitpunkt bereits deklariert (nicht unbedingt definiert) sein. Deklarieren heißt, dem Compiler die Schnitstellt mitzuteilen, in deinem Fall

    int printhello(string name);
    

    Bei der Definition wird dann die konkrete Implementierung vorgenommen, das machst du ja auch schon:

    int printhello(string name)
    {
        std::cout << "Hello" << name <<"this is your first Visual C++ program ...Congratulations!" << std::endl;
        return 0;
    }
    

    Eine Definition ist bei Funktionen übrigens auch eine Deklaration. DU hast also 2 Möglichkeiten: Entweder du definierst die Funktion über der Definition von main oder du lässt die Definition wo sie ist und schreibst nur die Deklaration vor main.

    Noch ein paar andere Anmerkungen zu deinem Programm:

    1. Wieso bindest du stdio.h ein? Du verwendest nirgendwo Funktionen daraus. Außerdem würde man in C++ cstdio und nicht stdio.h nehmen, weil es ein C-Header ist und die C++-Versionen (mit Namespace std, siehe unten) durch weglassen des .h und voranstellen von c gebildet werden.

    2. Weißt du, was ein Namensraum ist? Es sieht nämlich nicht so aus. Du schreibst einerseits using std::string, was dazu führt, dass du danach string benutzen kannst, ohne den Namensraum std explizit anzugeben. Danach benutzt du using namespace std was dazu führt, dass alle Bezeichner aus dem Namensraum std ohne Angabe des Namensraums verwendet werden können. Trotzdem qualifizierst du im weiteren Programm cout und cin mit std.

    3. Weißt du, wie eine Funktionsdeklaration funktioniert und wofür das int vor deinen Funktionen ist? Das bedeutet, dass ein Integer zurückgegeben wird. Bei main ist das nach dem C++ Standard nötig, aber bei printhello ist es zum Beispiel unnötig, das heißt, du könntest einfach schreiben

    void printhello(string name)
    {
        std::cout << "Hello" << name <<"this is your first Visual C++ program ...Congratulations!" << std::endl;
    }
    

    und dir dann auch das return 0 sparen.

    1. strings sind (relativ) aufwändig zu kopieren. Deshalb würde man sie normalerweise per (const) Referenz übergeben, um sich das Kopieren zu sparen. Das geht so:
    void printhello(const string &name)
    {
           std::cout << "Hello" << name <<"this is your first Visual C++ program ...Congratulations!" << std::endl;
    }
    

    Dabei ist das const wichtig, um anzuzeigen, dass die Funktion das durch die Referenz übergebene Objekt nicht ändern kann. Nur dadurch kann man die Funktion dann auch mit Konstanten und Literalen aufrufen.

    Das war vielleicht alles ein bisschen viel und wirft sicher wieder viele neue Fragen auf, aber frag einfach!

    Felix



  • Hi,

    bei C++ "liest" der Compiler den Quellcode ganz normal von links nach rechts und dann von oben nach unten ... und wenn er auf etwas stößt, von dem er gar nicht einordnen kann, was es sein soll (Bezeichner für einen Typen oder eine Funktion oder eine Variable oder ...), dann beschwert er sich eben.

    Tobi85 schrieb:

    ...Bin echt ratlos, hatte mir c++ anders vorgestellt ..irgendwie mehr c# like...

    Ist das in C# denn anders ?
    (ist eine echte frage, weil ich C# nicht kenne)

    Gruß,

    Simon2.



  • Simon2 schrieb:

    Ist das in C# denn anders ?
    (ist eine echte frage, weil ich C# nicht kenne)

    Ja, das ist es.
    Forwärtsdekl. gibts nicht in c#.
    Ein inkluden auf Source File Eben auch nicht, nur auf Assembly (=.NET DLL) Ebene (->"Assembly wid referenziert").

    Simon



  • Hi Felix

    Erstmal danke für deine tolle Hilfe:)
    Du scheinst dich ja echt sehr gut mit c++ auszukennen.
    habe das alles mal so übernommen wie du es mir geschrieben hast. Funktioniert gut, nur wenn ich nun meinen Namen eingebe, dann wird der Text einfach nicht ausgegeben mit dem "this is your first Visual C++ program" usw... und das meinte ich damit das er einfach die Funktion gar nicht erkennt... die hat gar keine daseinsberechtigung wahrscheinlich^^

    zu deinen fragen:
    zu 1) das rührt wahrscheinlich noch von c her^^ hatte im 2. Semester c und dort wurde das immer so eingebunden. Habe gemeint bei c++ nun auch mit .h.

    zu 2) Nein weiss nicht genau was ein Namensraum ist. Hab das alles mal includet weil ich vorher string nicht verwenden konnte.. und in meinem tollen Übungsblatt steht das die Funktion string zurückliefern soll... (du hast mir geschrieben der vorangehende datentyp bestimmt immer den rückgabewert, also müsste es ja dann

    string printhello(string name);
    

    heissen oder?
    Ich habe nicht drauf geachtet das ich ja dann das std:: weglassen kann.

    zu 3) die funktion soll string zurückgeben. Das mit dem int vor printhello hab ich gemacht, weil in meinem Übungsblatt steht ich soll eine Funktion schreibent. Und mit void wäre es ja dann eine Prozedur oder? Weil ja dann kein Rückgabewert mehr da ist. Aber ich hatte das genauso wie du vorhin schon geschrieben mit dem void, weil ich mir dachte das ist ja sinnlos mit dem return 0.

    zu 4) das hab ich nun mal einfach so übernommen, wenn du sagst das es dann besser ist.

    DANKE.
    Nur hab ich nun immernoch das Problem das er den Text dann nach Eingabe des Namens nicht anzeigt =/.....



  • theta schrieb:

    Simon2 schrieb:

    Ist das in C# denn anders ?
    (ist eine echte frage, weil ich C# nicht kenne)

    Ja, das ist es.
    Forwärtsdekl. gibts nicht in c#.
    Ein inkluden auf Source File Eben auch nicht, nur auf Assembly (=.NET DLL) Ebene (->"Assembly wid referenziert").

    Simon

    Jo genau das wollt ich auch schreiben 🙂



  • theta schrieb:

    Simon2 schrieb:

    Ist das in C# denn anders ?
    (ist eine echte frage, weil ich C# nicht kenne)

    Ja, das ist es.
    Forwärtsdekl. gibts nicht in c#.
    Ein inkluden auf Source File Eben auch nicht, nur auf Assembly (=.NET DLL) Ebene (->"Assembly wid referenziert").

    Simon

    Ahaaaa !
    OK - also eher wie bei Java.

    Danke,

    Simon2.



  • Lass mich raten: Das Fenster öffnet sich, du gibst was ein und das Fenster, böse wie es ist, schließt sich wieder. Richtig?

    Nun, wenn das der Fall ist: Er gibt den Text aus, da das Programm aber zuende ist, wird das Fenster geschlossen bevor du das bemerkst. In der FAQ steht was dazu.



  • Tobi85 schrieb:

    zu 2) Nein weiss nicht genau was ein Namensraum ist. Hab das alles mal includet weil ich vorher string nicht verwenden konnte.. und in meinem tollen Übungsblatt steht das die Funktion string zurückliefern soll... (du hast mir geschrieben der vorangehende datentyp bestimmt immer den rückgabewert, also müsste es ja dann

    string printhello(string name);
    

    heissen oder?
    Ich habe nicht drauf geachtet das ich ja dann das std:: weglassen kann.

    Es kommt nicht direkt auf den Rückgabewert an. Wenn du nirgends ein using schreibst, musst du schon klar machen, dass sich die Klasse string im Namensraum std befindet, und zwar mit std::string .

    Tobi85 schrieb:

    zu 3) die funktion soll string zurückgeben. Das mit dem int vor printhello hab ich gemacht, weil in meinem Übungsblatt steht ich soll eine Funktion schreibent. Und mit void wäre es ja dann eine Prozedur oder? Weil ja dann kein Rückgabewert mehr da ist.

    In C++ gibt es keine Prozeduren, alles sind Funktionen, unabhängig vom Rückgabewert.

    Tobi85 schrieb:

    zu 4) das hab ich nun mal einfach so übernommen, wenn du sagst das es dann besser ist.

    Naja, wenn du immer schön fleissig C++ lernst, wirst du schon noch zu Referenzen vorstossen, und dann solltest du auch die ganze Thematik kennen lernen... 😉

    Tobi85 schrieb:

    Nur hab ich nun immernoch das Problem das er den Text dann nach Eingabe des Namens nicht anzeigt =/.....

    Was heisst "nicht anzeigt"? Schliesst sich die Konsole? Bleibt sie offen, aber es passiert nichts?


Anmelden zum Antworten