# taschenrechner erweitern



## michelr (18. Juni 2004)

Hallo,
habe bisher einen ganz simplen taschenrechner mit den 4 grundrechenarten (+, -, *, /) programmiert (s.Quellcode). Ich lese einfach 2 Zahlen ein frage den operator ab und gebe das ergebnis aus. Bis hier war das auch für mich als anfänger noch ganz einfach.


```
using namespace std;

int main()
{
int eingabe1;
int eingabe2;
int ergebnis;

char rechenzeichen;
cout<<"Taschenrechner"<<endl;
cout<<"Geben Sie die 1.Zahl ein : ";
cin>>eingabe1;
cout<<"Geben Sie die gewünschte Rechenoperation an (+ - * /): ";
cin>>rechenzeichen;
cout<<"Geben Sie die 2.Zahl ein: ";
cin>>eingabe2;

if (rechenzeichen=='+')
{
ergebnis=eingabe1+eingabe2;
}
else if(rechenzeichen=='-')
{
ergebnis=eingabe1-eingabe2;
}
else if(rechenzeichen=='*')
{
ergebnis=eingabe1*eingabe2;
}
else
{
ergebnis=eingabe1/eingabe2;
}
cout<<"Ergebnis: "<<ergebnis;
return ergebnis;
}
```

Jetzt habe ich die Aufgabe meinen Taschenrechner folgenderm. zu erweitern:
Der Benutzer soll die Möglichkeit haben z.B. folgendes einzugeben: "2+2*5"
Das Programm soll nun einfach die eingegebene Zeile von links nach rechts lesen und das ergebnis ausgeben. In diesem Fall also 20. Rechenregeln wie punkt vor strich oder klammern müssen nicht berücksichtigt werden. 
Ich soll also eine Funktion schreiben die eine Textzeile als Parameter hat.  Das Ergebnis soll in der Funktion zurückgegeben werden. Ich hoffe ich habe euch mein Problem verständlich gemacht und mir kann jemand weiterhelfen. Ich fürchte ich muss hier mit einem String als Parameter arbeiten.
Leider habe ich im Umgang mit strings noch sehr sehr wenig Erfahrung. Für eure Hilfe wäre ich sehr dankbar.


----------



## abcd_hallo (18. Juni 2004)

Hier, hab dir mal schnell eine geschrieben, aber denke dran, dass das mathematisch nicht korrekt ist


```
int rechne (char *param)
{
	int erg, i, k=0;
	char szHilf[5];
	char* operanten;
	int operantenAnz=0;
	int* werte;
	int werteAnz = 0;

	operanten = (char *) malloc (sizeof(char));
	werte = (int *) malloc (sizeof(int));


	//String zerlegen
	for (i=0; i<strlen(param); i++)
	{
		if (param[i] >= 48 && param[i] <= 57)
		{
			//es ist eine Zahl
			szHilf[k] = param[i];
			k++;
			
			if (param[i+1] < 48 || param[i+1] > 57)
			{
				//Zahl ist fertig
				szHilf[k] = '\0';
				k=0;
				werte = (int *) realloc (werte, (werteAnz+1)*sizeof(int));
				sscanf(szHilf, "%d", &werte[werteAnz]);
				werteAnz++;
			}
		}
		else if (param[i] == '+' || param[i] =='-' || param[i] =='*' || param[i] =='/')
		{
			//Operation gefunden
			operanten = (char *) realloc (operanten, (operantenAnz+1)*sizeof(char));
			operanten[operantenAnz] = param[i];
			operantenAnz++;
		}
	}

	//Ausrechnen

	erg = werte[0];

	for (i=1; i<werteAnz; i++)
	{
		switch (operanten[i-1])
		{
		case '+':
			erg = erg + werte[i];
			break;
		case '-':
			erg = erg - werte[i];
			break;
		case '*':
			erg = erg * werte[i];
			break;
		case '/':
			erg = erg / werte[i];
			break;
		}
	}

	free (werte);
	free (operanten);

	return erg;
}
```


----------



## Gawayn (18. Juni 2004)

Hm, also ich glaube, so toll ist das nicht, fertigen Code zu präsentieren. Es hilft mehr, gemeinsam einen Lösungsansatz auszuarbeiten. Die Arbeit von anderen erledigen zu lassen, ist nur Faulheit. Und ich glaube, das war in diesem Thread auch gar nicht gefragt.

Gawayn


----------



## js-mueller (18. Juni 2004)

Mich würde das auch mal interessiere. Wie man an sowas rangeht. Der fertige code sieht mir jetzt nen bissle komplex aus, wäre cool wenn du das näher erklären könntest


----------



## Thomas Darimont (18. Juni 2004)

Hallo!

Damit dein Taschenrechner auch etwas komplexere Auswertungen durchführen kann wie etwa Klammerung beachten, Punkt-vor-Strich etc. solltest du dir vielleicht mal ein tutorial dazu anschauen, wie man einen Parser baut, der mathematische Ausdrücke auswerten kann. 

Google mal nach: mathematical expression parser

hier: http://www.programmersheaven.com/zone3/cat414/
findest du ein paar Beispiele zu dem Thema.

Gruß Tom


----------



## michelr (20. Juni 2004)

Hallo,
danke erst einmal für die hilfe auch wenn ich es eigentlich gar nicht so genau haben wollte. Aber das programm funktioniert. 
Jetzt würde ich aber auch gerne manches nachvollziehen können. Ich bin nämlich noch Anfänger und würde mich daher freuen wenn man zu dem code beispiel etwas mehr kommentar anfügen könnte ? 
was macht eigentlich "malloc" bzw. "realloc"  
In den if-schleifen arbeitest du immer mit den werten 48 und 57  Warum bzw. hat das ne bestimmte Bedeutung (Ascii-code) oder so 
Kann sein das meine Fragen sich blöd anhören aber solch ein komplexer code ist für mich als anfänger halt teilweise schwer zu verstehen 
Für Kommentare wäre ich sehr dankbar.


----------



## Kachelator (20. Juni 2004)

Zu malloc:  Klick 
Hast du keine Dokumentation? Probier's im Netz zum Beispiel mit MSDN (s.o.).

48 und 57 usw. sind ASCII-Werte für die Ziffernzeichen 0 und 9. Sinnvoller wäre es im Code gewesen, stattdessen '0' bzw. '9'  (also 0 und 9 als char) zu schreiben.


----------



## Dudadida (20. Juni 2004)

Noch was erläuternd dazu michelr, in C/C++ ist ein char eine stinknormale Zahl mit 8bit Umfang. Ist es in anderen Programmiersprachen auch, aber da wird meistens anders getan. Deswegen kannst du mit einer char Variablen auch ganz normal rechnen aber ihr auch wie Kachelator vorgeschlagen hat, Werte mit den ' zuweisen. Der Compiler macht dann aus bspw. '0' den entsprechenden Zahlwert (48).


----------



## michelr (23. Juni 2004)

ich habe mitlerweile in einem buch nachgelesen das "malloc" und "free" eigentlich c-syntax ist und "new" und "delete" der entsprechende gegenpart in C++ wäre. Ich wollte in dem Quellcode dann malloc durch new und free durch delete ersetzen, jedoch ohne Erfolg. Kann mir jemand sagen was ich das beachten muss.was ist eigentlich der gegenpart zu realloc in c++. realloc wurde in meinem buch gar nicht erklärt. gibt es eigentlich auch eine doku wie die msdn library irgendwo in deutsch ? Fragen über Fragen. Ich hoffe mir kann jemand weiterhelfen  vielen dank schon mal im voraus


----------



## squeaker (23. Juni 2004)

malloc/free ist für unstrukturierte Speicherblöcke. Man sagt einfach wieviel Speicher man will und bekommt einen pointer drauf. Darin kann man sich nach lust und laune austoben.

new/delete ist für Klassen - die es erst für C++ gibt, da erst C++ Objektorientiert ist. Mit new holt man sich den Speicher für eine Klasse. Bei der Klasse wird auch gleich der Konstruktor ausgeführt und entsprechende benötigte Initialisierungen getätigt. Als Rückgabewert erhält man einen Zeiger auf die Klasse, den man dann auch verwenden kann/muss um Methoden aufzurufen usw. delete ist die Gegenoperation und ruft den Destruktor wieder auf bevor es den Speicher wieder an das OS zurückgibt.

Deshalb kann das blose ersetzen von malloc/free durch new/delete nicht funktionieren.


----------



## Gawayn (23. Juni 2004)

Du kannst in der Tat malloc durch new ersetzen. Das geht z.B. so:

```
int *p = new int ;
int *m = (int*)malloc( sizeof( int ) ) ;
```
Diese beiden Anweisungen sind äquivalent. Wie du siehst, ist die new-Syntax erstens weitaus einfacher und zweitens weit weniger fehleranfällig als die malloc-Syntax.

Gawayn


----------



## michelr (23. Juni 2004)

Hallo Gawayn,
danke für den Hinweis ! das hat mir echt weitergeholfen denn jetzt versteh ich wenigstens was an der Stelle des programms gemacht wird. ich habe jetzt malloc durch new und free durch delete ersetzt. 
Aber was ist jetzt noch mit dem realloc. Was ist hier der gegenpart in C++. 
Ich würde das auch gerne entsprechend ersetzen wenn möglich. Ich habe auch noch keinen genauen plan was realloc macht und eine leicht zu verstehende doku dazu habe ich auch nicht gefunden. Hier nochmal zur Übersicht der quellcode. 


```
char Textzeile[10];

int rechne (char *param)
{
	int erg;
	int i;
	int k=0;
	char szHilf[5];
   char* operanten;
	int operantenAnz=0;
	int *werte;
	int werteAnz=0;
	
	//operanten=(char *) malloc (sizeof(char));
	operanten= new char;  // new ersetzt malloc

	//werte = (int *) malloc (sizeof(int));
	werte = new int;   // new ersetzt malloc

	//String zerlegen
	for(i=0; i<strlen(param); i++)
	{
		if (param[i] >=48 && param[i] <=57)
		{
			//es ist eine Zahl
			szHilf[k]=param[i];
			k++;
			
			if (param[i+1] < 48 || param[i+1] > 57)
			{
			//Zahl ist fertig
				szHilf[k] = '\0';
				k=0;
				werte = (int *) realloc (werte, (werteAnz+1)*sizeof(int));
				sscanf(szHilf, "%d", &werte[werteAnz]);
				werteAnz++;
			}
		}
		else if (param[i] == '+' || param[i] == '-' || param[i] == '*' || param[i] == '/')
		{
		//Operation gefunden
			operanten = (char *) realloc(operanten, (operantenAnz+1)*sizeof(char));
			operanten[operantenAnz]=param[i];
			operantenAnz++;
		}
	}
	
	//Ausrechnen
	
	erg=werte[0];
	for(i=1;i<werteAnz;i++)
	{
		switch(operanten[i-1])
		{
		case '+':
				erg= erg + werte[i];
				break;
		case '-':
				erg= erg - werte[i];
				break;
		case '*':
				erg= erg * werte[i];
				break;
		case '/':
				erg= erg / werte[i];
				break;		
		}
	}
	//free (werte);
	delete (werte);      //delete ersetzt free
	//free (operanten);
	delete (operanten);  //delete ersetzt free
	
	return erg;
}

int main()
{
cout<<"Eingabe: ";
cin>>Textzeile;
cout<<endl<<"Das Ergebnis lautet: "<<  rechne(Textzeile);
}
```

Durch was kann ich realloc ersetzen ?


----------



## squeaker (23. Juni 2004)

Wer nicht Objektorientiert programmiert sollte auch eigentlich besser C als C++ verwenden (das ist zumindest meine bescheidene Meinung).


----------



## Gawayn (23. Juni 2004)

@squeaker: Das macht keinen Sinn. Warum soll jemand eine Syntax benutzen, die fehleranfällig ist, wenn C++ ja absichtlich eine bessere Syntax eingeführt hat, um genau diese Fehleranfälligkeit zu vermeiden. Und außerdem ist ein prozedural programmiertes Programm immer noch ein wunderschönes C++-Programm. Schließlich ist C++ keine objektorientierte Sprache (wie Java), sondern nur eine Sprache mit objektorientierten Fähigkeiten.

@michelr: realloc ändert die Größe eines vorher mit malloc reservierten Speicherbereichs. Wenn man also mit malloc z.B. 1024 Bytes reserviert hat und später auf einmal 2048 Bytes braucht, dann muss man nicht mit malloc einen neuen Bereich reservieren, dort alles hineinkopieren und dann mit free den alten Bereich freigeben, sondern man kann mit realloc einfach den alten Bereich vergrößern. Allerdings kenne ich aus dem Stehgreif keinen C++-Operator, der diese Funktion wahrnimmt.

Gawayn


----------



## squeaker (23. Juni 2004)

Da bin ich anderer Meinung. Aber ich kenne mich mit den Unterschieden zwischen C und C++ Syntax zu wenig aus um qualifiziert zu sein. Aber so simpel kann die C++ Syntax nicht sein wenn es noch keine Compiler gibt der sie vollständig implementiert.


----------

