Funktion mit variabler Argumentliste



  • anstatt so einen batzen zu schreiben benutz ich lieber va_list 😉 🙂


  • Administrator

    player424 schrieb:

    anstatt so einen batzen zu schreiben benutz ich lieber va_list 😉 🙂

    Schreibfaulheit kommt meistens auch zusammen mit Fehleranfälligkeit 😉

    Und ich würde ja sowieso zur Lösung raten, welche ich als erstes geschrieben habe. Das ist schliesslich nichts anderes als die Funktion selber, nur ein wenig erweitert, damit sie mit Iteratoren funktioniert. Dadurch hast du eine höhere Flexibilität.

    Grüssli



  • player424 schrieb:

    anstatt so einen batzen zu schreiben benutz ich lieber va_list 😉 🙂

    Es geht beim Programmieren aber nicht darum, mit möglichst wenig Code möglichst viel Kot zu produzieren...



  • Hallo zusammen,
    natürlich kann es sein, dass dieser Stil entweder nicht gut ist oder nicht gebräuchlich. In meinem Buch wird er jedoch behandelt und wenn ich das Kaptiel "Funktionen mit variabler Parameterliste" nicht interessant fände, dann würde ich mich wahrscheinlich auch nicht mehr damit beschäftigen.

    Vielen Dank für den vielen "Ersatzcode", doch möchte ich einmal mein Programm zum Laufen bekommen. Ich habe nämlich gelesen, dass die Standartfunktionen wie printf genauso mit diesen Makros funktionieren (und das soll was heißen)

    Ich bin auch blöd....jetzt habt ihr mir tausendmal gesagt, dass ich gleiche Typen einsetzten soll und ich vergesse den Rückgabewert zu ändern. Also das Programm sieht jetzt so aus:

    float Durchschnitt (float Anzahl,...)
    {
     va_list Argumente; 
     va_start (Argumente, Anzahl); float sum = 0.0;
    
     for (float i=0; i<Anzahl; i++)
     {
      sum += va_arg(Argumente,float);  
     }
     va_end(Argumente); 
     return sum/Anzahl;
    }
    
    void __fastcall TForm1::FormCreate(TObject *Sender)
    {
     cout << Durchschnitt(3,4.4,6.7,8.9);
    

    Der erste Parameter ist pflicht und gibt die Anzahl der Parameter an. Daher muss dieser doch eine ganze Zahl sein (so wirds auch in meinem Buch beschrieben). Ich kann schließlich nicht 3,4 Parameter haben.

    Dennoch funktioniert das Programm nicht. Es kommt nicht der Durchschnitt heraus, sondern die Zahl -35791394,6666667!! Keine Ahnung, was der Compiler da anstellt. Dies ist aber kein zufälliger Wert, d.h. er erscheint immer wieder!!

    Was mache ich noch falsch??
    Vielen Dank für eure Hilfe
    lg, freakC++

    PS: Nehmt es mir nicht Übel, dass ich dieses Programm zu Ende stellen möchte!!


  • Administrator

    freakC++ schrieb:

    Vielen Dank für den vielen "Ersatzcode", doch möchte ich einmal mein Programm zum Laufen bekommen. Ich habe nämlich gelesen, dass die Standartfunktionen wie printf genauso mit diesen Makros funktionieren (und das soll was heißen)

    printf ist eine C Funktion. In C hat man da kaum andere Möglichkeiten. In C++ ist die variable Argumentliste von printf einer der Gründe, wieso man printf nicht benutzt. Ausgaben & Eingaben werden in C++ über die Streams geregelt. Auf C Funktionen probiert man in C++ so oft wie möglich zu verzichten.

    freakC++ schrieb:

    Was mache ich noch falsch??

    Immer noch das gleiche. Du übergibst doubles und liest floats aus.

    4.3  // -> double
    4.3f // -> float
    

    Ändere einfach diese Zeile um:

    sum += va_arg(Argumente,float);
    

    zu:

    sum += va_arg(Argumente,double);
    

    Der Typ des Rückgabewerts und die Typen, welche du sonst in der Funktion benutzt sind scheiss egal. Du musst einfach aus der variablen Parameterliste doubles auslesen, wenn sich dort doubles befinden. Du musst immer den Typ auslesen, welcher sich dort drin befindet. Deshalb gibt man bei printf ja auch an, von welchem Typ der jeweilige Parameter ist, mit den Codes im String drin.

    Übringes, was benutzt du eigentlich für ein Buch?

    Grüssli



  • freakC++ schrieb:

    Hallo zusammen,
    natürlich kann es sein, dass dieser Stil entweder nicht gut ist oder nicht gebräuchlich.

    In C++ nicht gut und deshalb nicht gebräuchlich. Eines der wichtigsten Dinge in C++ ist die Typsicherheit und die Fähigeit des Compilers, diese durchzusetzen und damit schon zur Compielzeit eine große Menge an Fehlern abzufangen. va_args & Co setzen im Gegensatz dazu auf Pointergehüpfe und mehr oder weniger willkürliches Umhercasten von Pointern und Uminterpretieren von Speicherbereichen, weshalb wie oben schon gesagt wurde das alles auch nur für PODs definiert ist. Der Compiler kann dir dabei keine Unterstützung geben, muss für bare Münze nehmen was du ihm diktierst und produziert daraus irgendwelchen Code, der funktionieren kann oder auch nicht. Um wirklich sicher zu sein dass das was du getippt hast in jedem Fall auch tut was du erwartest, müsstest du streng genommen bei jedem Funktionsaufruf schauen ob du die einzelnen Argumente auch richtig interpretierst (z.B. der float/double-Fehler). Da könntest du es fast jedesmal von Hand hintippen.

    freakC++ schrieb:

    In meinem Buch wird er jedoch behandelt und wenn ich das Kaptiel "Funktionen mit variabler Parameterliste" nicht interessant fände, dann würde ich mich wahrscheinlich auch nicht mehr damit beschäftigen.

    Steht auf deinem Buch zufälligerweise "C/C++"? Falls ja, bist du gerade im C-Teil. Falls nicht: gibts am Anfang zu dem Abschnitt "variable Argumenteliste" einen fetten Disclaimer "möglchst nicht in C++ benutzen"? Falls auch das nicht zutrifft hat das Buch bestenfalls noch Heizwert, denn dann ist entweder das Buch oder der Kenntnisstand des Autors noch aus den Anfängen von C++ wo es eher als "C mit Klassen" benutzt wurde.



  • Hallo zusammen,
    also ich benutze das Buch "C++ Objektorientierte Programmierung" von Alexander Nieman und Stefan Heitsiek!
    Ich finde es recht kompliziert geschrieben, doch da ich schon ein paar Grundlagen habe (auch wenn es manchmal nicht
    so scheint), komm ich bis jetzt ganz gut damit klar! Jedoch wird auch andauernd

    void main (void)
    {
    ...
    }
    

    geschrieben, was auch nicht mehr den Standarts entspricht. Es handelt sich also um ein reines C++ Buch. Es ist die zweite Auflage
    und ist im Jahr 2008 erschienen (also noch neu).

    Ich habe mir vorgenommen, verschiedene Einsteigerbücher von verschiedenen Autoren durchzuarbeiten, um ein möglichst breit
    gefächertes Wissen abzubekommen. Nach diesem Buch wollte ich mir dann einen richtig schönen Wälzer anschaffen, der sich dann
    auch sehr viel tiefer eingeht (ich will ja nicht immer solch primitive Programme schreiben, sondern auch welche die jemandem
    etwas nützen)

    Ihr könnt euch das Buch ja mal anschauen:

    http://www.amazon.de/C-Objektorientierte-Programmierung-Alexander-Niemann/dp/3826673743

    Vielen Dank für eure Hilfe
    lg, freakC++



  • Hi,

    also ich bin doch ziemlich erstaunt, welche Lösungen hier angeboten werden ... immerhin ist doch gerade "Durchschnitt" eine Funktion, die locker mit einer Parameterliste mit
    a) variabler Länge aber
    b) festem Typ
    auskommt ... und für so etwas hat Gott doch den std::vector erfunden. (oder meinetwegen ein Array).

    Gruß,

    Simon2.


  • Administrator

    freakC++ schrieb:

    geschrieben, was auch nicht mehr den Standarts entspricht. Es handelt sich also um ein reines C++ Buch. Es ist die zweite Auflage
    und ist im Jahr 2008 erschienen (also noch neu).

    Ufff, dann schmeiss das Ding weg oder verwende es zum Anfeuern. Ich meine man muss nur diese zwei Rezensionen lesen:
    http://www.amazon.de/product-reviews/3826673743/ref=cm_cr_dp_hist_1/279-9692699-1433456?ie=UTF8&showViewpoints=0&filterBy=addOneStar

    Wer sein Buch überarbeitet und dann immer noch solch fatale Fehler drin hat, der hat einfach nichts mitbekommen, wie sich C++ entwickelt hat. Der ist noch auf einem uralten Stand. Wir empfehlen hier hauptsächlich die folgenden zwei:
    - C++ Primer
    - Thinking in C++ 1 & 2 (auch als gratis Download erhältlich)

    Gibt noch ein paar weitere in den FAQs.
    Falls du dich schon ein wenig auskennst, wäre die Lektüre von "Die C++ Programmiersprache" von Bjarne Stroustrup auch eine Überlegung wert.

    Simon2 schrieb:

    ... und für so etwas hat Gott doch den std::vector erfunden. (oder meinetwegen ein Array).

    Und deswegen habe ich die Lösung mit den Iteratoren vorgeschlagen, welche mit allen Containern, welche das Iteratoren-Konzept ünterstützen, auskommt.

    Grüssli



  • freakC++ schrieb:

    ich benutze das Buch "C++ Objektorientierte Programmierung" von Alexander Nieman und Stefan Heitsiek [...]
    andauernd

    void main (void)
    {
    ...
    }
    

    [...]
    reines C++ Buch. Es ist die zweite Auflage
    und ist im Jahr 2008 erschienen (also noch neu).

    😮 Ein 2008er Buch mit void main (void) - das war meines Wissens nichtmal in C90 legal.

    Ein ganz klarer Fall für den Schredder. Schmeiß das bloß weg! Wer weiß was für anderen Scheiß die einem verkaufen wollen, der nicht so ganz offensichtlich ist.

    Simon2 schrieb:

    und für so etwas hat Gott doch den std::vector erfunden. (oder meinetwegen ein Array).

    Oder ganz generisch Iterator-Ranges (wurden aber auch am Anfang schon vorgeschlagen)

    /edit: gna, war wieder einer schneller 🙄


Anmelden zum Antworten