<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Grammatik Funtionen Taschenrechner]]></title><description><![CDATA[<p>Hi Leute,<br />
Der erste Beitrag und direkt ein Problem :)........</p>
<p>Ich lerne seit einigen Monaten C++ mit einem Buch.</p>
<p>Nun programmieren wir gerade einen Taschenrechner.</p>
<p>Er soll die Eingaben des Benutzers in Token zerlegen und somit &quot;vorrausschauen&quot; können ob noch ein * oder ein / folgt.<br />
Denn er beherrscht ja keine Punkt-vor-Strich Rechnung.<br />
Er würde z.b. bei 5+2*2 , 20 herraus bekommen, obwohl das richtige Ergebnis ja 9 lautet.</p>
<p>Die Grammatik lautet folgendermassen:</p>
<p>Ausdruck:<br />
Term<br />
Ausdruck &quot;+&quot; Term<br />
Ausdruck &quot;-&quot; Term</p>
<p>Term:<br />
Faktor<br />
Term &quot;*&quot; Faktor<br />
Term &quot;/&quot; Faktor<br />
Term &quot;%&quot; Faktor</p>
<p>Faktor:<br />
Zahl<br />
&quot;(&quot; Ausdruck &quot;)&quot;</p>
<p>Zahl:<br />
Gleitkommaliteral</p>
<p>Der Code sieht folgender maßen aus:<br />
(Die Funktionen heißen anders: expression()=Ausdruk, Term()=Term,<br />
primary()=Faktor)</p>
<pre><code>#include &quot;std_lib_facilities.h&quot;

//------------------------------------------------------------------------------

class Token {
public:
    char kind;        // welche Kategorie von Token
    double value;     // für Zahlen: ein Wert 
    Token(char ch)    // erstelle ein Token aus einem char
        :kind(ch), value(0) { }    
    Token(char ch, double val)     // erstelle ein Token aus einem char und einem double
        :kind(ch), value(val) { }
};

//------------------------------------------------------------------------------

Token get_token()    // lies ein Token aus cin
{
    char ch;
    cin &gt;&gt; ch;    // beachten Sie, dass &gt;&gt; Whitespace-Zeichen wie 
                  // Leerzeichen, Zeilenumbruch, Tabulatorzeichen, etc. überspringt

    switch (ch) {
 //noch kein   case ';':    // für &quot;Ausgeben&quot;
 //noch kein   case 'q':    // für &quot;Verlassen&quot;
    case '(': case ')': case '+': case '-': case '*': case '/': 
        return Token(ch);        // jedes Zeichen repräsentiert sich selbst 
    case '.':
    case '0': case '1': case '2': case '3': case '4':
    case '5': case '6': case '7': case '8': case '9':
        {    
            cin.putback(ch);         // lege die Ziffer zurück in den Eingabestream
            double val;
            cin &gt;&gt; val;              // lies eine Gleitkommazahl 
            return Token('8',val);   // '8' repräsentiert &quot;eine Zahl&quot;
        }
    default:
        error(&quot;Ungueltiges Token&quot;);
    }
}

//------------------------------------------------------------------------------

double expression();  // liest einen Ausdruck ein und wertet ihn aus

//------------------------------------------------------------------------------

double term();        // liest einen Token ein und wertet ihn aus

//------------------------------------------------------------------------------

double primary()     // liest einen Faktor ein und wertet ihn aus
{
    Token t = get_token();
    switch (t.kind) {
    case '(':    // behandle'(' Ausdruck ')'
        {    
            double d = expression();
            t = get_token();
            if (t.kind != ')') error(&quot;')' erwartet&quot;);
            return d;
        }
    case '8':            // wir verwenden '8' zur Repräsentation einer Zahl
        return t.value;  // liefere den Wert der Zahl zurück
    default:
        error(&quot;Faktor erwartet&quot;);
    }
}
//------------------------------------------------------------------------------

int main()
try {
    while (cin)
        cout &lt;&lt; expression() &lt;&lt; '\n';
    keep_window_open();
}
catch (exception&amp; e) {
    cerr &lt;&lt; e.what() &lt;&lt; endl;
    keep_window_open();
    return 1;
}
catch (...) {
    cerr &lt;&lt; &quot;Ausnahme\n&quot;;
    keep_window_open();
    return 2;
}

//------------------------------------------------------------------------------

double expression()
{
    double left = term();      // liest einen Token ein und wertet ihn aus
    Token t = get_token();     // hole das nächste Tolen
    while(true) {    
        switch(t.kind) {
        case '+':
            left += term();    // werte Term aus und addiere
            t = get_token();
            break;
        case '-':
            left -= term();    // werte Term aus und subtrahiere
            t = get_token();
            break;
        default:
            return left;       // keine weiteren + oder –; Antwort zurückliefern
        }
    }
}

//------------------------------------------------------------------------------

double term()
{
    double left = primary();
    Token t = get_token();     // hole das nächste Tolen

    while(true) {
        switch (t.kind) {
        case '*':
            left *= primary();
            t = get_token();
            break;
        case '/':
            {    
                double d = primary();
                if (d == 0) error(&quot;Division durch null&quot;);
                left /= d; 
                t = get_token();
                break;
            }
        default: 
            return left;
        }
    }
}

//------------------------------------------------------------------------------
</code></pre>
<p>Das eigentliche Problem:</p>
<p>Immer der erste Befehl in den Funktionen expression(), term() und primary()<br />
lässt mich rätseln...........</p>
<p>Er lautet:</p>
<p>double left = term(); // liest einen Token ein und wertet ihn aus</p>
<p>Wie ist das zu verstehen?</p>
<p>Wird hier die doublevariable left mit term() initialisiert?<br />
Welcher wert wird von left an term() übergeben und woher kommt er?<br />
Übergibt left zum Beispiel den Wert '2', was macht dann term() damit bzw. was sendet term() zurück?</p>
<p>Ich hoffe ihr könnt mir etwas weiter helfen.</p>
<p>Mfg Golfi1812</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/286271/grammatik-funtionen-taschenrechner</link><generator>RSS for Node</generator><lastBuildDate>Thu, 20 Aug 2026 23:10:26 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/286271.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 06 May 2011 18:47:41 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Grammatik Funtionen Taschenrechner on Fri, 06 May 2011 18:47:41 GMT]]></title><description><![CDATA[<p>Hi Leute,<br />
Der erste Beitrag und direkt ein Problem :)........</p>
<p>Ich lerne seit einigen Monaten C++ mit einem Buch.</p>
<p>Nun programmieren wir gerade einen Taschenrechner.</p>
<p>Er soll die Eingaben des Benutzers in Token zerlegen und somit &quot;vorrausschauen&quot; können ob noch ein * oder ein / folgt.<br />
Denn er beherrscht ja keine Punkt-vor-Strich Rechnung.<br />
Er würde z.b. bei 5+2*2 , 20 herraus bekommen, obwohl das richtige Ergebnis ja 9 lautet.</p>
<p>Die Grammatik lautet folgendermassen:</p>
<p>Ausdruck:<br />
Term<br />
Ausdruck &quot;+&quot; Term<br />
Ausdruck &quot;-&quot; Term</p>
<p>Term:<br />
Faktor<br />
Term &quot;*&quot; Faktor<br />
Term &quot;/&quot; Faktor<br />
Term &quot;%&quot; Faktor</p>
<p>Faktor:<br />
Zahl<br />
&quot;(&quot; Ausdruck &quot;)&quot;</p>
<p>Zahl:<br />
Gleitkommaliteral</p>
<p>Der Code sieht folgender maßen aus:<br />
(Die Funktionen heißen anders: expression()=Ausdruk, Term()=Term,<br />
primary()=Faktor)</p>
<pre><code>#include &quot;std_lib_facilities.h&quot;

//------------------------------------------------------------------------------

class Token {
public:
    char kind;        // welche Kategorie von Token
    double value;     // für Zahlen: ein Wert 
    Token(char ch)    // erstelle ein Token aus einem char
        :kind(ch), value(0) { }    
    Token(char ch, double val)     // erstelle ein Token aus einem char und einem double
        :kind(ch), value(val) { }
};

//------------------------------------------------------------------------------

Token get_token()    // lies ein Token aus cin
{
    char ch;
    cin &gt;&gt; ch;    // beachten Sie, dass &gt;&gt; Whitespace-Zeichen wie 
                  // Leerzeichen, Zeilenumbruch, Tabulatorzeichen, etc. überspringt

    switch (ch) {
 //noch kein   case ';':    // für &quot;Ausgeben&quot;
 //noch kein   case 'q':    // für &quot;Verlassen&quot;
    case '(': case ')': case '+': case '-': case '*': case '/': 
        return Token(ch);        // jedes Zeichen repräsentiert sich selbst 
    case '.':
    case '0': case '1': case '2': case '3': case '4':
    case '5': case '6': case '7': case '8': case '9':
        {    
            cin.putback(ch);         // lege die Ziffer zurück in den Eingabestream
            double val;
            cin &gt;&gt; val;              // lies eine Gleitkommazahl 
            return Token('8',val);   // '8' repräsentiert &quot;eine Zahl&quot;
        }
    default:
        error(&quot;Ungueltiges Token&quot;);
    }
}

//------------------------------------------------------------------------------

double expression();  // liest einen Ausdruck ein und wertet ihn aus

//------------------------------------------------------------------------------

double term();        // liest einen Token ein und wertet ihn aus

//------------------------------------------------------------------------------

double primary()     // liest einen Faktor ein und wertet ihn aus
{
    Token t = get_token();
    switch (t.kind) {
    case '(':    // behandle'(' Ausdruck ')'
        {    
            double d = expression();
            t = get_token();
            if (t.kind != ')') error(&quot;')' erwartet&quot;);
            return d;
        }
    case '8':            // wir verwenden '8' zur Repräsentation einer Zahl
        return t.value;  // liefere den Wert der Zahl zurück
    default:
        error(&quot;Faktor erwartet&quot;);
    }
}
//------------------------------------------------------------------------------

int main()
try {
    while (cin)
        cout &lt;&lt; expression() &lt;&lt; '\n';
    keep_window_open();
}
catch (exception&amp; e) {
    cerr &lt;&lt; e.what() &lt;&lt; endl;
    keep_window_open();
    return 1;
}
catch (...) {
    cerr &lt;&lt; &quot;Ausnahme\n&quot;;
    keep_window_open();
    return 2;
}

//------------------------------------------------------------------------------

double expression()
{
    double left = term();      // liest einen Token ein und wertet ihn aus
    Token t = get_token();     // hole das nächste Tolen
    while(true) {    
        switch(t.kind) {
        case '+':
            left += term();    // werte Term aus und addiere
            t = get_token();
            break;
        case '-':
            left -= term();    // werte Term aus und subtrahiere
            t = get_token();
            break;
        default:
            return left;       // keine weiteren + oder –; Antwort zurückliefern
        }
    }
}

//------------------------------------------------------------------------------

double term()
{
    double left = primary();
    Token t = get_token();     // hole das nächste Tolen

    while(true) {
        switch (t.kind) {
        case '*':
            left *= primary();
            t = get_token();
            break;
        case '/':
            {    
                double d = primary();
                if (d == 0) error(&quot;Division durch null&quot;);
                left /= d; 
                t = get_token();
                break;
            }
        default: 
            return left;
        }
    }
}

//------------------------------------------------------------------------------
</code></pre>
<p>Das eigentliche Problem:</p>
<p>Immer der erste Befehl in den Funktionen expression(), term() und primary()<br />
lässt mich rätseln...........</p>
<p>Er lautet:</p>
<p>double left = term(); // liest einen Token ein und wertet ihn aus</p>
<p>Wie ist das zu verstehen?</p>
<p>Wird hier die doublevariable left mit term() initialisiert?<br />
Welcher wert wird von left an term() übergeben und woher kommt er?<br />
Übergibt left zum Beispiel den Wert '2', was macht dann term() damit bzw. was sendet term() zurück?</p>
<p>Ich hoffe ihr könnt mir etwas weiter helfen.</p>
<p>Mfg Golfi1812</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2059721</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2059721</guid><dc:creator><![CDATA[Golfi1812]]></dc:creator><pubDate>Fri, 06 May 2011 18:47:41 GMT</pubDate></item><item><title><![CDATA[Reply to Grammatik Funtionen Taschenrechner on Fri, 06 May 2011 18:54:55 GMT]]></title><description><![CDATA[<p>Diese Anweisung holt sich jeweils den ersten Summanden bzw. Faktor der Kette, indem es die jeweilige Funktion für die niederrangigeren Ausdrücke aufruft (expression() ruft term() auf, dieses wiederum primary(), das wiederum per get_token() eine Zahl oder Klammer aus der Eingabe rausholt).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2059727</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2059727</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Fri, 06 May 2011 18:54:55 GMT</pubDate></item><item><title><![CDATA[Reply to Grammatik Funtionen Taschenrechner on Fri, 06 May 2011 19:15:32 GMT]]></title><description><![CDATA[<p>Vielen Dank,</p>
<p>Doch eine Frage bleibt:</p>
<p>Woher nimmt double left seinen Wert?<br />
Es muss ja einen Wert an term() liefern ,damit tern() ihn auswerten kann.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2059736</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2059736</guid><dc:creator><![CDATA[Golfi1812]]></dc:creator><pubDate>Fri, 06 May 2011 19:15:32 GMT</pubDate></item><item><title><![CDATA[Reply to Grammatik Funtionen Taschenrechner on Fri, 06 May 2011 19:20:31 GMT]]></title><description><![CDATA[<p>Der holt es von <code>primary()</code> - und primary() bekommt den Wert entweder von <code>get_token()</code> (wenn die nächste Eingabe eine Zahl ist - get_token() holt den Wert aus der Eingabe) oder rekursiv von <code>expression()</code> (die die nächste Eingabe eine Klammer ist).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2059739</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2059739</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Fri, 06 May 2011 19:20:31 GMT</pubDate></item><item><title><![CDATA[Reply to Grammatik Funtionen Taschenrechner on Fri, 06 May 2011 19:42:00 GMT]]></title><description><![CDATA[<p>Okay verstehe,</p>
<p>Aber die double variable left ist nicht Global, also gibt es insgesamt 2 davon in diesem Programm in expression() und in term()?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2059750</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2059750</guid><dc:creator><![CDATA[Golfi1812]]></dc:creator><pubDate>Fri, 06 May 2011 19:42:00 GMT</pubDate></item><item><title><![CDATA[Reply to Grammatik Funtionen Taschenrechner on Fri, 06 May 2011 19:55:23 GMT]]></title><description><![CDATA[<p>Richtig erkannt - genauso hast du drei verschiedene Variablen namens t in deinen Funktionen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2059756</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2059756</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Fri, 06 May 2011 19:55:23 GMT</pubDate></item><item><title><![CDATA[Reply to Grammatik Funtionen Taschenrechner on Fri, 06 May 2011 19:58:30 GMT]]></title><description><![CDATA[<p>Okay Vielen Dank für deine schnelle Hilfe!<br />
Echt super vor 1 Stunde angemeldet und innerhalb kurzer Zeit ein eher komplexes Problem gelöst Super! So bin ich das nicht gewöhnt!</p>
<p>Ich werde nochmal den Code ausdrucken und mit handschriftlichen Kommentaren versehen um alles genau nachvollziehen zu können.</p>
<p>Vielen Dank <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f44d.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--thumbs_up"
      title=":+1:"
      alt="👍"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2059759</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2059759</guid><dc:creator><![CDATA[Golfi1812]]></dc:creator><pubDate>Fri, 06 May 2011 19:58:30 GMT</pubDate></item><item><title><![CDATA[Reply to Grammatik Funtionen Taschenrechner on Fri, 06 May 2011 20:01:17 GMT]]></title><description><![CDATA[<p>Dazu gibt es einen schönen Artikel im Magazin, wo ein solcher Taschenrechner entwickelt wird, der immer weitere Funktionen erhält: <a href="http://www.c-plusplus.net/forum/268247" rel="nofollow">http://www.c-plusplus.net/forum/268247</a></p>
<p>Sollte also deine Frage absolut beantworten und dir vielleicht sogar noch mehr Wissen zum Thema beibringen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2059761</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2059761</guid><dc:creator><![CDATA[Tippgeber]]></dc:creator><pubDate>Fri, 06 May 2011 20:01:17 GMT</pubDate></item><item><title><![CDATA[Reply to Grammatik Funtionen Taschenrechner on Sat, 07 May 2011 14:51:22 GMT]]></title><description><![CDATA[<p>Ich habe nochmal eine Frage:</p>
<p>Das ganze beginnt in der Funktion primary():</p>
<pre><code>double primary()     // liest einen Faktor ein und wertet ihn aus
{
    Token t = get_token();
    switch (t.kind) {
    case '(':    // behandle'(' Ausdruck ')'
        {    
            double d = expression();
            t = get_token();
            if (t.kind != ')') error(&quot;')' erwartet&quot;);
            return d;
        }
    case '8':            // wir verwenden '8' zur Repräsentation einer Zahl
        return t.value;  // liefere den Wert der Zahl zurück
    default:
        error(&quot;Faktor erwartet&quot;);
    }
}
</code></pre>
<p>Hier wird ja in Zeile 4 eine switchanwesiung begonnen.<br />
Wenn das Token ein '(' ist, muss ja der Grammatik nach nach einem Ausdruck gesucht werden [Grammatikregel = '(' Ausdruck ')'].</p>
<p>So wird dann in Zeile 7 eine doublevariable namens d mit expression() initialisiert. So weit so gut.</p>
<p>Hier wird expression() aufgerufen, expression() ruft dann wiederrum term() auf ,das wiederum primary() und primary beginnt den Kresilauf von neuem.</p>
<p>Das Programm würde also in einer Endlosschleife immer wieder die Funktionen nacheinander aufrufen. Das ist doch Unsinn! Habe ich etwa einen Denkfehler?</p>
<p>Mfg Golfi1812 <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f615.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--confused_face"
      title=":confused:"
      alt="😕"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2060047</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2060047</guid><dc:creator><![CDATA[Golfi1812]]></dc:creator><pubDate>Sat, 07 May 2011 14:51:22 GMT</pubDate></item><item><title><![CDATA[Reply to Grammatik Funtionen Taschenrechner on Sat, 07 May 2011 15:00:58 GMT]]></title><description><![CDATA[<p>Golfi1812 schrieb:</p>
<blockquote>
<p>Das Programm würde also in einer Endlosschleife immer wieder die Funktionen nacheinander aufrufen. Das ist doch Unsinn! Habe ich etwa einen Denkfehler?</p>
</blockquote>
<p>Dein Denkfehler liegt in der Funktionsweise der get_token() Funktion - diese liest und verschluckt jedes Mal einen Teil der Eingabe. Das heißt, wenn du das nächste Mal (drei Rekursionsstufen tiefer) wieder in der primary() ankommst, erhältst du andere Eingabedaten und kommst so möglicherweise in den <code>case '8':</code> Zweig.</p>
<p>Worüber ich mir gerade Gedanken mache: Die term() und expression() brechen mit ihrer Arbeit ab, wenn das nächste eingelesene Token nicht passt. Dann sieht die jeweils aufrufende Funktion aber nicht, welches Zeichen hinter dem verarbeiteten Teil der Eingabe stand.</p>
<p>PS: Ich schließe mich mal der Aussage von Tipgeber an - lies den Magazin-Artikel.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2060052</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2060052</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Sat, 07 May 2011 15:00:58 GMT</pubDate></item></channel></rss>