C Programm gibt immer 0 aus.

datalukas

Captain
Registriert
Dez. 2009
Beiträge
3.628
Hallo liebe Community,

habe hier ein Problem: Ich wollte zur Übung ein Programm erstellen, dass mir den Blutalkoholgehalt grob ausrechnet. Allerdings gibt es immer aus.

Du hast 0 Promille im Blut

Code:
#include "stdafx.h"

int main ()
{
	char Geschlecht;
	int Gewicht, Volproz_Getraenk, Menge_Getraenk, Verteilungsfaktor, Blutalkoholgehalt;
	printf("\t\tPromillerechner\n");
	printf("Welches Geschlecht (m/w)? ");
	scanf("%c", &Geschlecht);
	if (Geschlecht == 'm')
	{
		Verteilungsfaktor = 0,69;
	}
	else if (Geschlecht == 'w')
	{
		Verteilungsfaktor = 0,575;
	}
	else
	{
		printf("Ungültige Angabe...\n");
	}
	printf("Wie viel wiegst du (in kg)? ");
	scanf("%d", &Gewicht);
	printf("Wie hoch ist der Alokoholgehalt des Getränks in Volumenprozent? ");
	scanf("%d", &Volproz_Getraenk);
	printf("Wie viel hast du getrunken (in ml)? ");
	scanf("%d", &Menge_Getraenk);
	Blutalkoholgehalt = 0,01* Volproz_Getraenk * Menge_Getraenk / Gewicht * Verteilungsfaktor;
	printf("Du hast %d Promille im Blut", Blutalkoholgehalt);
	return 0;
}

Dass hier von Dichte 1 bei Alkohol ausgegangen wird, ist zweitrangig, ist ja auch nur grob.
Habe mal zum Test Zeile 28 so gemacht:
Code:
(0,01* Volproz_Getraenk * Menge_Getraenk) / (Gewicht * Verteilungsfaktor)
Das Programm wird erstellt, bricht am Ende aber mit der Fehlermeldung
Unbehandelte Ausnahme bei 0x770115de in BAG.exe: 0x00000000: Der Vorgang wurde erfolgreich beendet.
ab. BAG ist der Name des Projekts.
Ich hoffe, mir kann bei diesem Problem jemand helfen
Gruß
Datalukas


PS: Das Programm wurde mit VCpp erstellt, deswegen auch dieser Header, oder hängt es wonöglich damit zusammen?
 
Du rechnest mit Integer-Werten ^^ Integer verwendet man nur für Ganze Zahlen :)

Double oder float wäre da besser ;)
 
Int sollten Ganzzahlen sein, heißt wenn du ein Wert von 0,99 bekommst, schnippelt int den Wert ab und du bekommst 0 ausgegeben.
Bin mir gerade unsicher, bin kein C-profi, aber float müsste als Datentyp besser geeignet sein.
 
Sorry falscher Film!

float ist natürlich korrekt, nur double wäre schon überdimensioniert :/
 
Zuletzt bearbeitet:
Nicht? Wie nimmt dann der Verteilungsfaktor einen anderen Wert als 0 an? Und dann steht er auch noch in einer Division.
 
Dass das überhaupt kompiliert, bestätigt nur meine Meinung, dass die C-Compiler alle bescheuert sind.
 
Zumindest ist sowas ein Grund, warum ich C keinem Anfänger empfehlen würde, besonders keinem autodidaktischen. Mit reinem C hatte ich noch nicht das Vergnügen, aber die Fehlermeldungen in C++ fand ich immer abenteuerlich und wenig hilfreich. Hier überrascht mich schon, dass Gleitkommazahlen mit , geschrieben werden dürfen.

@antred: Sowas ist mir auch noch nicht untergekommen. Man lernt nie aus. :D
 
Zuletzt bearbeitet:
Mike Lowrey schrieb:
Sorry falscher Film!

float ist natürlich korrekt, nur double wäre schon überdimensioniert :/

An double is gar nix überdimensioniert. Wenn du glaubst, mit float wärst du schneller unterwegs als mit double, täuscht du dich (oftmals). Die Hardware des Durchschnitts-PCs ist heute für Operationen auf doubles optimiert. Wenn du mit floats hantierst, wird das System die eigentliche Berechnung häufig im double-Format ausführen. Das heißt, dein float wird erst zu einem double aufgeblasen, dann wird die Berechung im double-Format gemacht und anschließend das Resultat wieder auf float zurückkonvertiert.
Ergänzung ()

Tumbleweed schrieb:
Hier überrascht mich schon, dass Gleitkommazahlen mit , geschrieben werden dürfen.

Dürfen sie nicht.

Code:
int Verteilungsfaktor;
Verteilungsfaktor = 0,67;

Das ist keine Zuweisung von 0.67 an die Variable Verteilungsfaktor. Stattdessen werden hier 2 Expressions mit dem Komma-Operator verknüpft. Die erste Expression (0) wird ausgewertet, dann die zweite (67). Das Ergebnis der zweiten wird dann der Variablen Verteilungsfaktor zugewiesen.
 
Da werden Kommas anstatt Punkte als Dezimaltrennzeichen verwendet. Das macht was komplett anderes, weil C tatsächlich einen Komma-Operator kennt. Der verwirft alles, was vor dem Komma steht und wertet den Ausdruck dahinter aus. D.h. nach
int Verteilungsfaktor = 0,575;
hat "Verteilungsfaktor" den Wert 575.

Edit: das vor dem Komma wird auch ausgewertet, aber nur der möglichen Nebeneffekte wegen. Und warum das Programm abstürzt, weiß ich auch nicht. ;)
 
printf("Wie hoch ist der Alokoholgehalt des Getränks in Volumenprozent? ");

Hat der Autor hier probeweise schon mal ein paar Gläser runtergeschüttet? ;)
Ergänzung ()

character schrieb:
Dass das überhaupt kompiliert, bestätigt nur meine Meinung, dass die C-Compiler alle bescheuert sind.

Der Compiler ist nicht bescheuert. Der tut genau das, was der Programmierer ihm sagt. Das Program ist syntaktisch völlig korrekt, auch wenn es semantisch natürlich Blödsinn ist. Ein ganz besonders intelligenter Compiler hätte hier bestenfalls an einigen Stellen Warnungen ausgeben können ("Diese Stelle schaut komisch aus. Ist das wirklich, was du willst?").
 
Eine Warnung ist das Mindeste, was man bei sowas heutzutage erwarten können sollte. Leider ist das ganze C-Ökosystem nicht nur alt, sondern auch altmodisch. Man muss sich nur mal die Diskussionen dazu auf diversen Mailing-Listen anschauen.

Letztendlich finde ich C daher für Anfänger ungeeignet. Natürlich kann man auch damit anfangen, das geht schon irgendwie. Aber es gibt deutlich sinnvollere Alternativen um sich sowohl Grundlagen als auch wichtige SE-Konzepte anzueignen, ohne dass man so "hilflos" rumeiern muss.
 
character schrieb:
Eine Warnung ist das Mindeste, was man bei sowas heutzutage erwarten können sollte.
Es ist syntaktisch korrekter Code, da muss keine Warnung hin. Woher will der Compiler wissen, ob dies nicht wirklich mit Absicht so gemacht wurde? Vielleicht mag einer diesen Stil und er macht es dauerhaft. Soll dieser nun von Warnungen bombardiert werden oder wie?
character schrieb:
Leider ist das ganze C-Ökosystem nicht nur alt, sondern auch altmodisch. Man muss sich nur mal die Diskussionen dazu auf diversen Mailing-Listen anschauen.
Und trotzdem wird es sehr oft verwendet, einfach weil es gut ist.
 
Vielen Dank. Bin noch ein Anfänger, deswegen dieser blöde Fehler.
Ich meinte auch mal wo gelesen zu haben, dass int 5 Nachkommastellen speichern kann, habe mich aber offenbar getäuscht.
Jetzt funktioniert es aber immer noch nicht richtig. Es kommt:

Du hast 1.#INF00 Promille im Blut.

Hier noch mal der Code, habe sicherheitshalber alles mit double gemacht.

Code:
#include "stdafx.h"

int main ()
{
	char Geschlecht;
	double Gewicht, Volproz_Getraenk, Menge_Getraenk, Verteilungsfaktor, Blutalkoholgehalt;
	printf("\t\tPromillerechner\n");
	printf("Welches Geschlecht (m/w)? ");
	scanf("%c", &Geschlecht);
	if (Geschlecht == 'm')
	{
		Verteilungsfaktor = 0,69;
	}
	else if (Geschlecht == 'w')
	{
		Verteilungsfaktor = 0,575;
	}
	else
	{
		printf("Ungültige Angabe...\n");
	}
	printf("Wie viel wiegst du (in kg)? ");
	scanf("%lf", &Gewicht);
	printf("Wie hoch ist der Alkoholgehalt des Getränks in Volumenprozent? ");
	scanf("%lf", &Volproz_Getraenk);
	printf("Wie viel hast du getrunken (in ml)? ");
	scanf("%lf", &Menge_Getraenk);
	Blutalkoholgehalt = (0.01* Volproz_Getraenk * Menge_Getraenk) / (Gewicht * Verteilungsfaktor);
	printf("Du hast %lf Promille im Blut", Blutalkoholgehalt);
	getchar();
	return 0;
}


Hat der Autor hier probeweise schon mal ein paar Gläser runtergeschüttet?

Ne, bin 15 und da ist das glaub ich nicht so gut, auch wenn es schon einige im meinem Alter machen.:D
Natürlich verbessert.

Zwei Fragen blieben aber noch:
1. getchar() funktioniert bei mir normalerweise, hier aber nicht. Ich meine damit, dass das Programm nicht gleich schließt (wurde mir in einem anderen Thread als Tipp gegeben). So muss ich es halt über die Kommandozeile aufrufen, wenn ich es sehen will.
2. Was kann ich machen, dass das Programm schließt, wenn die beiden if-Bedingungen nicht zutreffen, also bei else, wenn die Eingabe nicht korrekt ist?
 
Um nochmal das Problem im Code oben nach der ganzen Diskussion zusammenzufassen. Es dürfte an 2 Sachen liegen. Erstens werden in eigentlich allen mir bekannten Programmiersprachen Komma-Zahlen mit einem Punkt angegeben. Also statt "0,69" musst du "0.69" schreiben.
Zweitens ist der Datentyp Int nicht für deine Berechnungen geeignet. Da Int nur mit ganzen Zahlen arbeitet und bei Komma-Zahlen den Nachkomma-Anteil abschneidet. So wird aus 0.69 ganz schnell 0. Ein besser geeigneter Datentyp für alle Werte die Komma-Zahlen annehmen können ist double.
 
datalukas schrieb:
2. Was kann ich machen, dass das Programm schließt, wenn die beiden if-Bedingungen nicht zutreffen, also bei else, wenn die Eingabe nicht korrekt ist?

Du könntest mit printf() eine Fehlermeldung absetzen und dann mit

return 1;

die main()-Funktion und damit das Programm verlassen.


P.S. datalukas, du verwendest auch in deinem korregierten Programm immer noch Kommas statt Punkten in deinen Gleitkommazahlen.

Code:
if (Geschlecht == 'm')
{
Verteilungsfaktor = 0,69;
}
else if (Geschlecht == 'w')
{
Verteilungsfaktor = 0,575;
}
else
{
printf("Ungültige Angabe...\n");
}
 
Zuletzt bearbeitet:
Sorry für das Malheur, habe es unten gemacht, aber oben vergessen. Jetzt geht es auch.
 
Yuuri schrieb:
Es ist syntaktisch korrekter Code, da muss keine Warnung hin. Woher will der Compiler wissen, ob dies nicht wirklich mit Absicht so gemacht wurde?
Genau dafuer sind Warnungen aber da. Wenn die Syntax fehlerhaft ist, gibt es ja einen Fehler.

An sich hast du aber Recht: Das waere hier eher Aufgabe der IDE und nicht des Compilers.

Insofern benutzt der Threadersteller anscheinend keine oder eine nicht sehr hilfsbereite, eher schuechterne, ja geradezu introvertierte IDE. Jede Sprache hat diverse Pitfalls, die man damit umgehen kann (ich erinnere nur an Javas Stringvergleiche).
 
Zuletzt bearbeitet:
Zurück
Oben