C - Logische Verknüpfungen

Hallo,
hab da mal wieder eine Frage zu C.

Also es geht um ein Programm, dass die Tage eines Monates ausgeben soll. Hier ist es mal
Code:
#include <stdio.h>

main()
{
	int jahr,monat,tage;
	printf("\n\tKalender\n");
	printf("\nBitte Jahr eingeben: ");
	scanf("%i",&jahr);
	printf("\nBItte Monat eingeben: ");
	scanf("%i",&monat);
	if (monat>=1 && monat <=12 && jahr > 1582)
	{
		switch (monat)
		{
			case 2:
				if (!((jahr%100)%4) && (jahr%100) || !(jahr%400))
					tage=29;
				else
					tage=28;
				break;
				case 2*2:
				case 6:
				case 9: case 11:
					tage=30;
					break;
				default:
					tage=31;
		}
		printf("\n%i hat der Monat %i %i Tage",jahr,monat,tage);
	}
	else
		printf("\nFalsche Datumsangabe!");
	return 0;
}
Soweit ist alles klar, einzig allein diese Zeile
Code:
if (!((jahr%100)%4) && (jahr%100) || !(jahr%400))
macht mir Probleme. In meinem Buch steht dazu folgende Erklärung:
Code:
Dies ist die Bedingung für ein Schaltjahr. Die Formulierung nutzt aus, dass C den
 Wert 0 als falsch und alles andere als wahr interpretiert. Wenn sich also die letzten zwei 
Stellen der Jahreszahl (jahr%100) durch 4 teilen läßt (!((jahr%100)%4)) UND das Jahr sich 
nicht durch 100 teilen läßt (jahr%100) ODER es durch 400 teilbar ist (!jahr%400)), dann 
wird die Bedingung wahr.
Soweit so klar. Nur, was machen die "!" jeweils vor den Klammern? Soweit ich es gelernt hab, ist dass das logische nicht, also der Wahrheitsgehalt wird umgedreht. Wenn ich jetzt z.B. für jahr 2008 einsetze, kommt ja dann
Code:
(!((2008%100)%4) && (2008%100) || !(2008%400))
(!(true)) && false || (!(false)) 
false && false || true
false && true
false
raus, die Bedigung ist also falsch. Jetzt versteht ich nicht, warum das als richtig durchgeht und tage=29 angezeigt wird und nicht die else Bedingung?! Oder ist meine Auflösung der if Funktion falsch? Irgendwo muss ich ja da ein "Denkfehler" haben.
Danke schon mal für eure Hilfe,
Gruß casio
 
Original von casio
Code:
if (!((jahr%100)%4) && (jahr%100) || !(jahr%400))
macht mir Probleme. In meinem Buch steht dazu folgende Erklärung:
Code:
Dies ist die Bedingung für ein Schaltjahr. Die Formulierung nutzt aus, dass C den
 Wert 0 als falsch und alles andere als wahr interpretiert. Wenn sich also die letzten zwei 
Stellen der Jahreszahl (jahr%100) durch 4 teilen läßt (!((jahr%100)%4)) UND das Jahr sich 
nicht durch 100 teilen läßt (jahr%100) ODER es durch 400 teilbar ist (!jahr%400)), dann 
wird die Bedingung wahr.
Soweit so klar. Nur, was machen die "!" jeweils vor den Klammern? Soweit ich es gelernt hab, ist dass das logische nicht, also der Wahrheitsgehalt wird umgedreht. Wenn ich jetzt z.B. für jahr 2008 einsetze, kommt ja dann
Code:
(!((2008%100)%4) && (2008%100) || !(2008%400))
(!(true)) && false || (!(false)) 
false && false || true
false && true
false
raus, die Bedigung ist also falsch. Jetzt versteht ich nicht, warum das als richtig durchgeht und tage=29 angezeigt wird und nicht die else Bedingung?! Oder ist meine Auflösung der if Funktion falsch? Irgendwo muss ich ja da ein "Denkfehler" haben.
Danke schon mal für eure Hilfe,
Gruß casio

Weil du nicht so arbeitest wie der Rechner. Normalerweise sollte man solche Ausdrücke auch immer Klammern um keinen Fehler zu erhalten.

Code:
((!((2008%100)%4) && (2008%100)) || (!(2008%400)))
((!(true)) && false) || ((!(false))) 
(false && false) || (true)
(false) || (true)
true

so macht es der rechner, deshalb kommt das richtige Ergebnis zu stande. Hoffe es war verständlich.
 
Original von lookshe
Code:
((!((2008%100)%4) && (2008%100)) || (!(2008%400)))
((!(true)) && false) || ((!(false))) 
(false && false) || (true)
(false) || (true)
true

so macht es der rechner, deshalb kommt das richtige Ergebnis zu stande. Hoffe es war verständlich.
Hier noch der Grund warum das Programm die if Anweisung so auflöst: der && Operator hat eine höhere Priorität als der || Operator und wird deswegen zuerst aufgelöst.
Eine Übersicht über die Prioritäten der Operatoren in C findet man hier: http://www.galileo-press.de/openbook/c_von_a_bis_z/c_030Anhang_000.htm
 
Aha. Ok. Ich dachte, weil || die schwächste Bindung ist, wird es zuerst abgearbeitet. Aber ein paar Seiten vorher wirds bei mir erklärt, dass es deshalb zuerst abgearbeitet wird. Danke für die schnelle Hilfe.
Übrigens, ein super Forum hier!
 
Zurück
Oben