[C] Unerwünschter Nebeneffekt bei Ausgabe

weiß nicht,

also void main() geht garnicht,
kommt auf den Scheduler an, da kannste manchmal blöd auf die Fresse fligen ;)
Bei Win wohl weniger aber sonst mhh würd ich's lassen

Hehe stimmt, aber warum einfach wenns auch kompliziert geht
ich leb nach dem Motto,
K.I. künstlicher Irrsinn, den muss nur ich verstehen, dadurch werd ich unersetzbar... :)
warum Klartext schreiben wenn ich Bits schubsen kann *g da mach ich dir aus nem Z nen A mit einem Befehl *g

ich merks schon, wieder zuviel getrunken... gute nacht

gruß
 
So hier der neue Code (Sry hätte Ihn früher nochmal einstellen sollen :D):

Code:
/* 
MathematiX by Atomique 2011
Programm zur Berechnung verschiedener mathematischer Problemstellungen
*/

// Einbinden der Laufzeitbibliotheken
#include <stdio.h>		
#include <stdlib.h>

// Deklaration von Variablen und Konstanten
#define Version 1.00

int main();
void menue_01();
void programmende();


// Quellcode / Funktionen etc
int main()
{	
	int me_in=0;	

	do
	{
		System("cls");
		menue_01();			
		scanf("%d",&me_in);
		fflush(stdin);
		switch(me_in)
		{
		case 1:	printf("1\n");		//Hier werden noch Funktionen etc eingefügt wenn ich sie geschrieben habe
			break;
		case 2:	printf("2\n");
			break;
		case 3:	printf("3\n");
			break;
		case 9:	printf("9\n");
			break;
		case 0: programmende();
			break;
		default: printf("Falscheingabe\n\n");	// Wenn Case 1-9 (Es soll noch mehr als 1,2,3,9,0 geben) / 0 nicht auftreten 
												// Dann "Falscheingabe"
		}
		
	}
	while(me_in=!0);		// Wenn 0 eingegeben --> Schleife verlassen und weiter in MAIN()


	return 0;
}


void menue_01() // Diese Funktion dient zur grafischen Ausgabe des Menüs in der Konsole
{
	printf("Willkommen in MathematiX Version %.2lf, was wollen Sie tun?\n", Version);
	printf("<1> Rechnen (Normaler Taschenrechner)\n");
	printf("<2> Flaechenberechnung einer geom. Figur\n"); 
	printf("<3> Volumenbrechnung eines Objektes\n");
	printf("<9> About MathematiX Version %.2lf.\n", Version);
	printf("<0> Programm beenden. \n[Randnotiz: Es folgen weitere Funktionen ;) ]\n");
	


	return 0;
}

void programmende()	// Funktion soll Programmende mit Bestätigung ausführen. Fehlereingabe mit inbegriffen.
{
	char input;
	printf("Programm wird beendet. Fortfahren mit < J >, Abbrechen mit < N >.\n");
	do
	{
	input=getchar();
	}
	while(getchar()!='\n');	// Eliminierung des Return wertes '\n' 
	fflush(stdin);
	if(input == 'j','n')	// wenn input 'j' oder 'n' entspricht dann Kontrolle ob 'j'
	{
		if(input=='j')		// wenn input == 'j' dann Programmende und Ausgabe
		{
			printf("Programm beendet. Vielen Dank f\x81r das benutzen von MathematiX Version %.2lf\n", Version);
			exit(0);		//	Programm beenden
		}
		else				// ansonsten Programm fortsetzen und Ausgabe 
		{
			printf("Programm wird fortgesetzt.\n\n");
			return 0;
		}

	}
	else		// wenn nicht 'j' / 'n' dann Falscheingabe und Aufruf der Funktion programmende.
	{
		printf("Falscheingabe, Bitte wiederholen:\n");
		programmende();
	}
	return 0;
}

voodoo44:
Danke dir, es kommen aber noch cases dazu. Ich habe vor 1-9 und 0 zu verwenden und 0 möchte ich als Programmende benutzten :> --> das System("Cls"); amcht mir meine Konsole "sauber" bevor das Programm weiter macht oder?

soyd:
Ist es so okay? Oder habe ich es richtig verstanden, dass ich das return 0; noch weg nehmen muss wo ich void hab? Wäre ja eigentlich Sinnvoll oder?


Danke für die Hilfe :)
gute Nacht soyd :)

Gruß Atomique (werde jetzt auch ins Bett gehen und erst Morgen früh wieder antworten :))

Edit:

Das mit dem \x84 --> Damit kann man Ä Ö Ü und so weiter angeben!

ä: \x84
ö: \x94
ü: \x81

Sind hexadezimalzahlen, ja :)
 
Zuletzt bearbeitet:
system("cls"); ist unportierbar und der system()-Aufruf ist sowieso jederzeit zu vermeiden.
Tu es nicht.
 
kann nicht schlafen, Freundin schnarcht...

void sind Funktionen ohne Rückgabe, return ist überflüssig wie sinnlos ;)

das mit den ä Ö Ü 's test ich morgen mal, hab hier nur nen Ipad...
mit scanf(%c,...) sollte das eigentlich klappen
immer diese Umlaute... soviele normale Buchtaben, in Groß und klein aber alle wollen sie Ä's Ü's :p versteh ich nicht ;) bin hauptsächlcih mit µC und embedded Linux unterwegs und hab glaub noch nie nen ä abgefragt
vielleicht weil die so nah an ENTER liegen? =) hab meine eigenen "Taster"
anstatt fflush würd ich eher sowas benutzen:
#define FLUSHIN(c) while ((c = getc() != EOF && c != '\n')

oder als Funktion:

int stdinFlush(FILE *fp)
{
int c = 0;
while((c = getc(fp)) != EOF && c != '\n')
{
continue;
}
return EOF == c;
}

dann ist der Input leer, fflush kuck ich mal morgen daheim an... da gabs irgendwas...

gruß
 
Zuletzt bearbeitet:
Ich danke dir für die Mühe :D Und hoffe, dass du es gestern Abend noch ins Bett geschafft hast ^^ Oder eben nur auf die Couch :( ^^ - ich hab bis jetzt eigentlich immer nur fflush(stdin) von meinem prof reingeprügelt bekommen ^^ Sonst nichts anderes.. hm ^^ Ich hab es nochmal abgeändert, das System("Cls") raus und die returns raus wo nen void war.. nun werde ich mal weiter machen :>

gruß Atomique

Ps.: wenn ich weitere Fragen hab zu meinem Programm, darf ich das dann hier posten in diesem Thread oder soll ich nen neuen Thread auf machen?
 
Okay ich werd es so machen :) es dann etwas verallgemeinern etc :) Dankeschön ^^

*geht jetzt weiter programmieren* :D
Ergänzung ()

Eine Frage aber noch zur Case-Abfrage:

Kann ich nur einen Wert als Case angeben oder kann ich sie auch mit logischen Operatoren vergleichen?

Also

switch(variable)
{
case 1 && 'a': anweisung;
break;

usw....


}
 
&& also in der Bedeutung von 'und' geht gar nicht, da ja die variable nicht beide Werte gleichzeitig beinhalten kann. Du meinst wahrscheinlich || (oder). Das geht per 'fall thru'
Code:
switch(variable)
{
  case 'a':
  case 'b': anweisung;
  break;
  ...
}
Fehlt ein break, wird einfach die Programmausführung beim nächsten case fortgesetzt.
 
Ja ich meine Oder eigentlich :D Und ist nicht sinnvoll :> - Wollte es halt so machen:
(am bsp des Taschenrechners)
Wenn Benutzer '1' eingibt oder '+' dann soll er Addition() aufrufen usw.

--> dh dann nach deiner Methode:

Code:
char variable;
switch(variable)
{
   case '1':
   case '+': Addition();
      break;

   case '2':
   case '-': Subtraktion();
      break;

   default: printf("Falscheingabe");
}

Oder?

Edit: Sry muss mir angewöhnen alles in einen CodeBlock zu setzen :D
 
@voodoo44

jeder Funktionskopf belegt Speicher ;)
Speicherplatz ist Geld
Geld hab ich keins
also muss ich irgendwo sparen :p

aufm HeimPc wohl egal...


gruß
 
Hey CB,
ich bin mit meinem Taschenrechner noch auf weitere Probleme gestoßen, vielleicht könnt ihr mir ja weiter helfen! (Und mir vllcht noch sagen wie man das Thema vom Thread ändert ^^)

Zum Programm:

Ich habe eine Funktion eingebaut die den Durchschnitt berechnen soll. Um Parameterübergabe von Funktionen zu üben, habe ich diese in 2 Funktionen unterteilt (Auch wenn das vielleicht mit einer Funktion besser geht^^) . Einmal in average_input() und in average(). In der Funktion Average_input() soll der User die folgenden Werte eingeben:

- Von wie vielen Werten soll der Durchschnitt berechnet werden (Max 50)
- Die Werte von denen der Durchschnitt berechnet werden soll

--> Diese Werte wollte ich mit einem Array verarbeiten.

Hier ersteinmal der Code:

Code:
void average_input()	// Funktion soll Durchschnitt berechnen (Im Array)
{

	int i=0;
	int k=0; // Variable um Wert bei Ausgabe richtig anzugeben. Dient eig. nur zur Optik nicht zur Funktionalität.
	int elemente=0;
	int avg[50];
	float avg_ret=0;		// In diese Variable kommt der Rückgabewert der Funktion average()
	printf("Bitte geben Sie die Anzahl der Elemente ein,\n aus denen Sie den Durchschnitt errechnen wollen (Maximal 50 Werte zul\x84ssig)\n");
	scanf("%d", &i);
	elemente=i;		// Endbedingung für For-Schleife / Elemente im Array.
	if(i<=50)
	{
		for(i=0; i<elemente; i++)
		{
			k=i+1;
			printf("Bitte %d. Wert eingeben:", k);	// Var k: Richtige Ausgabe des "Wertes" in der For-Schleife
			scanf("%d", &avg[i]);
		}
		avg_ret=average(avg, 50);
		printf("Durchschnitt:%.2f \n", avg_ret);
	}
	else
	{
		printf("Bitte kleineren Wert eingeben!");
	}


}

float average(int avg[], int elemente)	// Funktion gemacht um Wertübergabe von Funktionen zu üben.
{
	int i;
	int gesamt=0;
	for(i=0; i<elemente; i++)
	{
		gesamt=gesamt+avg[i];
	}
	return((float)gesamt / elemente);		
}

Nun hatte ich dazu mehrere Fragen:

1. Was bedeutet "return((float)gesamt / elemente);" (Klar es ist der Rückgabewert der berechneten Variablen aber ich lerne gerade aus einem Buch und komme nicht darauf was es mit dem float auf sich hat, bzw. warum man das dort hinschreibt.)

2. Wenn ich das Programm ausführe kommen nur komische Durchschnittswerte zu stande. Darf ich überhaupt sagen, dass das Array 50 Plätze hat und ich aber nur 5 (Benutzereingabe) benutze? Ich komme nicht darauf wieso da so ein Ergebnis raus kommt.

3. Habt ihr Verbesserungsvorschläge wie ihr das Programm angehen würdet (Wenn möglich mit Parameter-Rückgabe^^ - geht aber auch ohne wenn es total Sinnfrei / nicht Empfehlenswert ist.)

EDIT: Nachträglich (sorry, vergessen) die Ausgabe als Screen (Unten im Anhang)



Ich danke euch schon einmal für die Hilfe! :)

Gruß Atomique


Achja und für die Leute die es interessiert was aus meinem Programm geworden ist bis jetzt :D (Speziell an diejenigen die mir schonmal hier geholfen haben):

Code:
/* 
MathematiX by Atomique 2011
Programm zur Berechnung verschiedener mathematischer Problemstellungen
*/

// Einbinden der Laufzeitbibliotheken
#include <stdio.h>		
#include <stdlib.h>

// Deklaration von Variablen und Konstanten
#define Version 1.00

int main();
void menue_01();
void programmende();
void calculate();
void addition();
void subtraktion();
void multiplikation();
void division();
void average_input();
float average();

// Quellcode / Funktionen etc
int main()
{	
	int me_in=0;	

	do
	{
		menue_01();			
		scanf("%d",&me_in);
		fflush(stdin);
		switch(me_in)
		{
		case 1:	calculate();		//Hier werden noch Funktionen etc eingefügt wenn ich sie geschrieben habe
			break;
		case 2:	printf("2\n");
			break;
		case 3:	printf("3\n");
			break;
		case 9:	printf("9\n");
			break;
		case 0: programmende();
			break;
		default: printf("Falscheingabe\n\n");	// Wenn Case 1-9 (Es soll noch mehr als 1,2,3,9,0 geben) / 0 nicht auftreten 
												// Dann "Falscheingabe"
		}
		
	}
	while(me_in=!0);		// Wenn 0 eingegeben --> Schleife verlassen und weiter in MAIN()


	return 0;
}


void menue_01() // Diese Funktion dient zur grafischen Ausgabe des Menüs in der Konsole
{
	printf("Willkommen in MathematiX Version %.2lf, was wollen Sie tun?\n", Version);
	printf("<1> Rechnen (Normaler Taschenrechner)\n");
	printf("<2> Flaechenberechnung einer geom. Figur\n"); 
	printf("<3> Volumenbrechnung eines Objektes\n");
	printf("<9> About MathematiX Version %.2lf.\n", Version);
	printf("<0> Programm beenden. \n[Randnotiz: Es folgen weitere Funktionen ;) ]\n");
}

void menue_calc()
{
	printf("Calculator:\n\n");
	printf("Welche Rechenart? Zahl oder Operator eingeben:\n");
	printf("< 1 / +\t> Addition\n");
	printf("< 2 / -\t> Subtraktion\n");
	printf("< 3 / *\t> Multiplikation\n");
	printf("< 4 / /\t> Division\n");
	printf("< 5 / #\t> Durchschnitt\n");

}

void programmende()	// Funktion soll Programmende mit Bestätigung ausführen. Fehlereingabe mit inbegriffen.
{
	char input;
	printf("Programm wird beendet. Fortfahren mit < J >, Abbrechen mit < N >.\n");
	do
	{
	input=getchar();
	}
	while(getchar()!='\n');	// Eliminierung des Return wertes '\n' 
	fflush(stdin);
	if(input == 'j','n')	// wenn input 'j' oder 'n' entspricht dann Kontrolle ob 'j'
	{
		if(input=='j')		// wenn input == 'j' dann Programmende und Ausgabe
		{
			printf("Programm beendet. Vielen Dank f\x81r das benutzen von MathematiX Version %.2lf\n", Version);
			exit(0);		//	Programm beenden
		}
		else				// ansonsten Programm fortsetzen und Ausgabe 
		{
			printf("Programm wird fortgesetzt.\n\n");
		}

	}
	else		// wenn nicht 'j' / 'n' dann Falscheingabe und Aufruf der Funktion programmende.
	{
		printf("Falscheingabe, Bitte wiederholen:\n");
		programmende();
	}
}

void calculate()
{
	char input_calc;

	do
	{
		menue_calc();
		do
		{
		input_calc=getchar();
				
		}
		while(getchar()!='\n');
		switch(input_calc)
		{
			case '+':					// case-auswahl durch fall thru --> bsp.: wenn + oder 1 eingegeben wird, addition();
			case '1':	addition();
				break;
			case '-':
			case '2':	subtraktion();
				break;
			case '*':
			case '3':	multiplikation();
				break;
			case '/':
			case '4':	division();
				break;
			case '#':
			case '5':	average_input();
				break;
			case '0': printf("Calculator beendet.\n");
				break;
			default: printf("Falscheingabe\n");
		}
	}
	while(input_calc!='0');
}

void addition()
{
	int ad_ergebnis;
	int ad_zahl1;
	int ad_zahl2;

	printf("Addition:\n");


	printf("Bitte Zahl 1 eingeben:\n");
	scanf("%d", &ad_zahl1);

	printf("Bitte Zahl 2 eingeben:\n");
	scanf("%d", &ad_zahl2);

	ad_ergebnis=ad_zahl1+ad_zahl2;
	
	printf("Ihr Ergebnis lautet: %d\n\n", ad_ergebnis);
}
void subtraktion()
{
	int su_ergebnis;
	int su_zahl1;
	int su_zahl2;

	printf("Subtraktion:\n");


	printf("Bitte Zahl 1 eingeben:\n");
	scanf("%d", &su_zahl1);

	printf("Bitte Zahl 2 eingeben:\n");
	scanf("%d", &su_zahl2);

	su_ergebnis=su_zahl1-su_zahl2;
	
	printf("Ihr Ergebnis lautet: %d\n\n", su_ergebnis);
}

void multiplikation()
{
	int mu_ergebnis;
	int mu_zahl1;
	int mu_zahl2;

	printf("Multiplikation:\n");


	printf("Bitte Zahl 1 eingeben:\n");
	scanf("%d", &mu_zahl1);

	printf("Bitte Zahl 2 eingeben:\n");
	scanf("%d", &mu_zahl2);

	mu_ergebnis=mu_zahl1-mu_zahl2;
	
	printf("Ihr Ergebnis lautet: %d\n\n", mu_ergebnis);
}
void division()
{
	int di_ergebnis;
	int di_zahl1;
	int di_zahl2;

	printf("Division:\n");


	printf("Bitte Zahl 1 eingeben:\n");
	scanf("%d", &di_zahl1);

	printf("Bitte Zahl 2 eingeben:\n");
	scanf("%d", &di_zahl2);

	di_ergebnis=di_zahl1-di_zahl2;
	
	printf("Ihr Ergebnis lautet: %d\n\n", di_ergebnis);
}
void average_input()	// Funktion soll Durchschnitt berechnen (Im Array)
{

	int i=0;
	int k=0; // Variable um Wert bei Ausgabe richtig anzugeben. Dient eig. nur zur Optik nicht zur Funktionalität.
	int elemente=0;
	int avg[50];
	float avg_ret=0;		// In diese Variable kommt der Rückgabewert der Funktion average()
	printf("Bitte geben Sie die Anzahl der Elemente ein,\n aus denen Sie den Durchschnitt errechnen wollen (Maximal 50 Werte zul\x84ssig)\n");
	scanf("%d", &i);
	elemente=i;		// Endbedingung für For-Schleife / Elemente im Array.
	if(i<=50)
	{
		for(i=0; i<elemente; i++)
		{
			k=i+1;
			printf("Bitte %d. Wert eingeben:", k);	// Var k: Richtige Ausgabe des "Wertes" in der For-Schleife
			scanf("%d", &avg[i]);
		}
		avg_ret=average(avg, 50);
		printf("Durchschnitt:%.2f \n", avg_ret);
	}
	else
	{
		printf("Bitte kleineren Wert eingeben!");
	}


}

float average(int avg[], int elemente)	// Funktion gemacht um Wertübergabe von Funktionen zu üben.
{
	int i;
	int gesamt=0;
	for(i=0; i<elemente; i++)
	{
		gesamt=gesamt+avg[i];
	}
	return((float)gesamt / elemente);		
}
 

Anhänge

  • konsolenausgabe.JPG
    konsolenausgabe.JPG
    55 KB · Aufrufe: 141
Zuletzt bearbeitet:
Atomique schrieb:
Nun hatte ich dazu mehrere Fragen:

1. Was bedeutet "return((float)gesamt / elemente);" (Klar es ist der Rückgabewert der berechneten Variablen aber ich lerne gerade aus einem Buch und komme nicht darauf was es mit dem float auf sich hat, bzw. warum man das dort hinschreibt.)
Das bedeutet, dass der Typ von gesamt in float umgewandelt wird.

2. Wenn ich das Programm ausführe kommen nur komische Durchschnittswerte zu stande. Darf ich überhaupt sagen, dass das Array 50 Plätze hat und ich aber nur 5 (Benutzereingabe) benutze? Ich komme nicht darauf wieso da so ein Ergebnis raus kommt.
Das Ergebnis kommt heraus, weil du den uninitialisierten Teil des Arrays mit in die Berechnung einziehst.
Wenn du nur 5 Werte gegeben bekommst, bleiben 45 Einträge des Arrays auf zufälligen Werten, von denen
der Durchschnitt mitberechnet wird.

3. Habt ihr Verbesserungsvorschläge wie ihr das Programm angehen würdet (Wenn möglich mit Parameter-Rückgabe^^ - geht aber auch ohne wenn es total Sinnfrei / nicht Empfehlenswert ist.)
Prüfe auf Integer overflow.
 
Vielleicht schaust du dir mal rein informativ das Thema "Listen" an. Das würde deinen Rechner sicher um einiges praktischer machen :)
 
Hey CB :) Sry das ich jetzt erst antworte, hatte sich nicht vorher ergeben :)

voodoo44: Danke dir, werde ich machen. Bin in meinem Buch gerade bei Strukturen angelangt und Listen ist direkt danach glaube ich :)

asdfman:

Das bedeutet, dass der Typ von gesamt in float umgewandelt wird.

Danke :) Das ist dann eine Explizite Typenumwandlung oder? (Hätte ich eigentlich auch selber drauf kommen können oO)

Das Ergebnis kommt heraus, weil du den uninitialisierten Teil des Arrays mit in die Berechnung einziehst.
Wenn du nur 5 Werte gegeben bekommst, bleiben 45 Einträge des Arrays auf zufälligen Werten, von denen
der Durchschnitt mitberechnet wird.

Ich hab herrausgefunden woran es lag! Es ist egal wieviele Werte frei bleiben anscheinend! - Ich habe bloß als Parameter den Wert 50 übergeben! Deswegen hatte ich immer 50 darin stehen :D

Code:
Davor:   avg_ret=average(avg, 50);
Danach: avg_ret=average(avg, elemente);

Prüfe auf Integer overflow.
Wie meinst du das? Wie teste ich das? Was ist das? Und wie kann mir sowas passieren?


Gruß Atomique :) Danke :)
 
Danke für den Link :) Ich melde mich jetzt grad nochmal ^^ hab da ne kleine Frage.. Hab mal Pointer etc durchgenommen.. was passiert wenn ich:
++(*xPtr); (Inkrementieren in der Postfix Schreibweise)
schreibe?

Also was passiert wenn ich einen solchen Befehl in meinem Programm habe?

Gruß Atomique
 
Der Pointer wird erst dereferenziert und dann der Wert, der an der referenzierten Adresse steht, inkrementiert.
 
das heißt, dass der wert aufgesucht wird praktisch und dann addiert mit 1 .. was passiert bei: (*xPtr)++;? da gibt es doch einen unterschied oder?
 

Ähnliche Themen

Zurück
Oben