|
Diese FAQ bezieht sich in ihrer Gänze auf den inzwischen nicht mehr aktuellen ISO-C Standard 9899:1990, vielfach auch als C90 bezeichnet. Der seit Dezember 1999 existierende neue ISO 9899:1999 Standard (oder auch C99) wird nicht berücksichtigt.
Frage 8.1: Welcher Typ wird am besten für boolesche Werte verwendet? Warum gibt es dafür keinen eigenen Typ? Sollte "#define" oder "enum" für TRUE und FALSE benutzt werden? Antwort: C stellt keinen Standardtyp zur Verfügung, weil diese Entscheidung für die eine oder die andere Variante dem Programmierer überlassen werden soll, da sie den Bedarf an Speicherplatz und/oder das Laufzeitverhalten beeinflußt (die Wahl 'int' mag schneller sein, dafür kann char evtl. Speicherplatz sparen). Die Entscheidung für '#define' oder 'enum' ist willkürlich und nicht sonderlich interessant (s.a. 9.1). Jede Entscheidung für #define TRUE 1 #define YES 1 #define FALSE 0 #define NO 0 enum bool {false,true}; enum bool {no,yes}; ist gleich gut, solange sie innerhalb des Programms/Projekts konsequent durchgehalten wird. (Möglicherweise ist 'enum' vorzuziehen, wenn der verwendete Debugger die Werte dann symbolisch anzeigen kann). Einige Programmierer bevorzugen Varianten wie #define TRUE (1==1) #define FALSE (!TRUE) oder basteln Hilfsmakros wie #define Istrue(e) ((e) != 0). Das bringt keinen Vorteil irgendeiner Art. (s.a. 8.2 sowie 1.6). Frage 8.2: Ist '#define TRUE 1' nicht gefährlich, da jeder von 0 verschiedene Wert in C als 'true' interpretiert wird? Was geschieht, wenn einer der eingebauten Vergleichsoperatoren etwas anderes als 1 zurück gibt? Antwort: Es stimmt zwar, dass jeder von 0 verschiedene Wert in C als 'true' akzeptiert wird, aber dies bezieht sich nur auf die Eingabe, d.h. auf die Stellen, an denen boolesche Werte erwartet werden. Wenn ein boolescher Wert von einem eingebauten Operator erzeugt wird, ist es definitiv 0 oder 1. Deshalb funktioniert der Test if (( a==b ) == TRUE) genau dann, wenn TRUE dem Wert 1 entspricht, hat aber offensichtlich keinen weiteren Sinn. Allgemein sind ausdrückliche Tests auf TRUE oder FALSE nicht sinnvoll, da einige Bibliotheksfunktionen (namentlich isupper, isalpha, etc.) im Erfolgsfall einen von 0 verschiedenen Wert zurückgeben, der nicht unbedingt 1 ist. (Außerdem, wenn 'if((a==b)==TRUE)' eine Verbesserung gegenüber 'if(a==b)' ist, warum sollte man dies nicht noch durch 'if(((a==b)==TRUE)==TRUE)' weiter verbessern?) Eine gute Faustregel sagt, dass TRUE, FALSE (oder ähnliches) nur für Wertzuweisungen an boolesche Variablen oder als Rückgabewerte für boolesche Funktionen, niemals aber in Vergleichen verwendet werden sollten. Die Präprozessormakros TRUE und FALSE sollen die Lesbarkeit des Quelltexts steigern, nicht aber als Sicherheitsleine für eine evtl. Änderung der zugrundeliegenden Werte dienen (s.a. 1.7 und 1.9). References: K&R I Sec. 2.7 p. 41; K&R II Sec. 2.6 p. 42, Sec. A7.4.7 p. 204, Sec. A7.9 p. 206; ANSI Secs. 3.3.3.3, 3.3.8, 3.3.9, 3.3.13, 3.3.14, 3.3.15, 3.6.4.1, 3.6.5; Achilles and the Tortoise.
© 1997-2004 Jochen Schoof (joscho@bigfoot.de) Diese Version wurde am 14. März 2004 erzeugt. Sie wird zukünftig nicht weiter gepflegt. |