Programmende < C/C++ < Programmiersprachen < Praxis < Informatik < Vorhilfe
|
Status: |
(Frage) beantwortet | Datum: | 22:47 Do 03.01.2013 | Autor: | pina7 |
Aufgabe | Schreiben Sie ein Programm mit einer Funktion checksum, welche die Quersumme (Summe der Ziffern) einer eingelesenen ganzen Zahl berechnet. Welchen Rückgabewert sollte diese Funktion haben? Das Programm soll diesen dann ausgeben. Von 456 beträgt die Quersumme z.B. 4+5+6 = 15. Das Programm soll so oft wiederholt werden, bis der Benutzer den Wert 0 eingibt. |
Hallo.
Mein Quellcode lautet:
#include "stdafx.h"
#include <iostream>
#define _USE_MATH_DEFINES
#include <math.h>
using namespace std;
int checksum(int eingabe)
{
int quersumme;
cout << endl << "Bitte eine ganze Zahl eingeben. (maximal 4 Stellen)" << endl << endl;
cin >> eingabe;
quersumme = ((eingabe % 10) + ((eingabe/10) % 10) + ((eingabe/100) % 10) + (eingabe/1000));
cout << endl << endl << "Die Quersumme lautet: " << quersumme << endl << endl;
return quersumme;
}
int _tmain(int argc, _TCHAR* argv[])
{
int eingabe = 0;
do
{
checksum(eingabe);
}while (eingabe != 0);
system("pause");
return 0;
}
Ich verstehe nicht, warum die Berechnung der Quersumme nur einmal durchgeführt wird, obwohl eingabe ungleich null ist. Ich bitte um eine Antwort, die mir meinen Fehler aufzeigt.
Danke vielmals!
(Frage nirgendwo anders gestellt)
|
|
|
|
Hallo pina,
sag mal in Klartext oder Pseudocode, was Du in den letzten 7 Zeilen (ab dem letzten "do") von Deinem Programm willst. Was meinst Du, was es da tut?
Grüße
reverend
PS: Ich ignoriere Leerzeilen in Programmen und Ziffern am Ende von Benutzernamen.
|
|
|
|
|
Hallo!
Wenn du es exakt so machen willst, wie es da steht, liegt dein Problem in der Übergabe der Variablen eingabe.
Wenn du checksum(eingabe) aufrufst, bekommt die Funktion checksum eine KOPIE der Variablen eingabe. Sobald die Funktion beendet ist, hat die Variable in der main() wieder ihren ursprünglichen Wert, und der ist 0.
Am einfachsten kannst du das lösen, indem du die Funktion als
int checksum(int &eingabe)
definierst, dann arbeitet sie mit dem Original. Das ist nicht sehr gebräuchlich, weil man dann dem Funktionsaufruf in der main() nicht ansieht, ob jetzt mit einer Kopie oder dem Original gearbeitet wird. Außerdem ist das C++, und nicht C.
Statt dessen nimmt man lieber Zeiger, dazu findest du erstmal hier was:
http://de.wikibooks.org/wiki/C-Programmierung:_Zeiger#Unterschied_zwischen_Call_by_Value_und_Call_by_Reference
Andererseits berechnet deine Funktion die Quersumme und gibt sie zurück. Dann könntest du die für den Test nehmen.
Aber:
Du hast die Ein- und Ausgabe (cin/cout) mit in die Funktion gepackt. Man möchte Code aber gerne wiederverwertbar schreiben, d.h. es sollte möglich sein, deine Funktion später in einem ganz anderen Programm wieder zum Berechnen der Quersumme benutzen zu können. Dann bräuchte man aber eher eine Funktion, die eine Zahl (eingabe) frißt und ein Ergebnis (quersumme) zurück gibt. Das cin/cout sollte daher NICHT in die Funktion rein, sondern in die main. Dann hast du auch dein Problem nicht.
Und noch ein Problem des Programms: Was ist mit Zahlen mit mehr als 3 Stellen? Ich schlage eine while-Schleife vor, in der jeder Summand einzeln berechnet wird, indem eingabe immer wieder durch 10 geteilt wird. Wie lautet da die Abbruch-Bedingung?
|
|
|
|
|
Status: |
(Frage) beantwortet | Datum: | 12:50 Fr 04.01.2013 | Autor: | pina7 |
Also ganz vielen Dank, jetzt habe ich genau das, was ich wollte bzw. was die Aufgabe verlangt.
#include "stdafx.h"
#include <iostream>
#define _USE_MATH_DEFINES
#include <math.h>
using namespace std;
int checksum(int eingabe)
{
int quersumme = 0;
do
{
quersumme = quersumme + (eingabe % 10);
eingabe = eingabe/10;
}while (eingabe > 0);
return quersumme;
}
int _tmain(int argc, _TCHAR* argv[])
{
int eingabe;
do
{
cout << endl << "Bitte eine ganze Zahl eingeben. Programmende bei Eingabe von Null." << endl << endl;
cin >> eingabe;
cout << endl << endl << "Die Quersumme lautet: " << checksum(eingabe) << endl << endl;
}while (eingabe != 0);
system("pause");
return 0;
}
Jedoch kommt es zu einer Endlosschleife bei Eingabe von Zahlen mit mehr als 10 Stellen. Warum?
Vielen Dank!
|
|
|
|
|
Hallo!
Der höchste Wert, den ein INT von 4 Byte länge darstellen kann, ist etwa 2.100.000.000 und das sind 10 Stellen. Das heißt, mit so großen Zahlen stößt du an die Grenzen der Variablen.
Was ganz stupide passiert ist, daß die Variable "überfüllt" wird und danach irgendeinen komischen Wert enthält, der aber in sie rein passt. Davon könnte man zwar ne Quersumme berechnen, die wäre aber falsch, und man würde es nicht merken.
Deshalb gibt es Konventionen, in denen eine Variable neben Zahlen auch noch die Zustände infinity (INF) und not-a-number (NAN) annehmen kann. Ersteres bedeutet, daß der Zahlenwert zu groß für die Variable war, letzteres entsteht beispielsweise bei Division durch 0.
Mit solchen Werten läßt sich natürlich nicht rechnen, INF/10 ist immernoch INF.
Ich denke, das wird dein Problem sein. Wenn du den Wert von eingabe per cout ausgibst, wirst du vermutlich sehen, daß da INF steht.
Du kannst dein Programm noch etwas aufbohren, indem du statt INT den Datentypen UNSIGNED LONG LONG nimmst, der geht wenigstens bis 18.446.744.073.709.551.615 und hat damit 19 volle Stellen.
Ich kann dir leider nicht sagen, wie du ermittelst, ob eine Variable "INF" ist, das hängt vom Compiler ab, und du verwendest da was anderes als ich.
|
|
|
|