Die if-Anweisung mit Laufzeitwerten in C
Wir haben bisher nur Literale aus if-Ausdrücke verwendet. Tatsächlich ist aber jeder Ausdruck mit einem der drei Datentypen »int«, »double« oder »char *« als if-Ausdruck zulässig. Diese Lektion soll diese Möglichkeiten aufzeigen.
Beispiele
● Konstanten als if-Ausdrücke
Wir zeigen ein Beispiel zur if-Anweisung, in dem Konstanten als if-Ausdrücke verwendet werden.
main.c
#include <stdio.h>
int main( void )
{ { int const c = 0; if( c )printf( "1\n" ); }
{ int const c = -2; if( c )printf( "2\n" ); }}transcript
2
Der erste if-Ausdruck ist »0«, weswegen der Text »1« nicht ausgegeben wird.
Der zweite if-Ausdruck ist »-2«, weswegen der Text »2« ausgegeben wird. (Die innere Anweisung einer if-Anweisung wird immer dann ausgeführt, wenn der if-Ausdruck nicht gleich »0« ist.)
● Variablen als if-Ausdrücke
Wir zeigen ein Beispiel zur if-Anweisung, in dem eine Variable als if-Ausdruck verwendet wird.
main.c
#include <stdio.h>
int main( void )
{ int v = 9;
if( v )printf( "A\n" );
v = 0;
if( v )printf( "B\n" ); }transcript
A
Da die Variable nur bei der ersten if-Anweisung ungleich Null ist, wird nur ein »A« ausgegeben.
● Parameter als if-Ausdrücke
Wir zeigen ein Beispiel zur if-Anweisung, in dem ein Parameter als if-Ausdruck verwendet wird.
main.c
#include <stdio.h>
void f( int const p )
{ if( p )printf( "%d\n", p + 19 ); }int main( void )
{ f( -14 );
f( 0 ); }transcript
5
Da der Parameter nur bei der ersten if-Anweisung ungleich Null ist, wird nur »5« ausgegeben.
● Operatorausdrücke als if-Ausdrücke
Wir zeigen ein Beispiel zur if-Anweisung, in dem ein Operatorausdruck als if-Ausdruck verwendet wird.
main.c
#include <stdio.h>
void f( int const p )
{ if( p - 2 )printf( "%d\n", p ); }int main( void )
{ f( 0 );
f( 1 );
f( 2 );
f( 3 ); }stdout
0
1
3
● Offensichtliche Laufzeitwerte als Steuerungswerte
In dem folgenden Programm ergibt sich als Wert des if-Ausdrucks »0« oder »1« mit ungefähr gleicher Wahrscheinlichkeit. Dadurch werden mehrere Zeilen ausgegeben, die in praktisch unvorhersehbarer Weise manchmal ein »x« enthalten und manchmal nicht.
main.c
#include <stdio.h>
#include <stdlib.h>void f()
{ printf( ":" );
if( rand() /( RAND_MAX / 2 ))printf( "x" );
printf( "\n" ); }int main( void )
{ f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); }stdout
:
:x
:
:x
:x
:
:
:x
:x
:x
● Darstellung der Auswertungen mit Aufrufen als if-Ausdrücke
Das folgende Beispiel zeigt wie Auswertung, die jeweils die Werte »false«, »true« und »3« ergeben, bei der Auswertung der Ausdrücke »vfalse()«, »vtrue()« beziehungsweise »v3()« durch eine Ausgabe ihres Wertes dargestellt werden und so die Abläufe der Ausführung der beiden if-Anweisungen nachvollziehbar machen.
Der Leser sollte an Hand des Quelltextes genau nachvollziehen, wie die Ausgaben zustandekommen, um die if-Anweisung von C zu verstehen.
main.c
#include <stdio.h>
int vnull(){ puts( "Null" ); return 0; }
int vtrue(){ puts( "wahr" ); return 4; }int v2(){ puts( "2" ); return 2; }
int v3(){ puts( "3" ); return 3; }int main( void )
{ if( vnull() )v2();
if( vtrue() )v3(); }transcript
Null
wahr
3
● Kombination der if-Anweisung mit einem Prädikat
Die Funktion »check« soll nur etwas ausgeben, wenn ein Zeichen ein Buchstabe ist.
Hierzu wird die mit dem Prädikat »isalpha« gebildete Aussage »isalpha( c )« als Ausdruck der if-Anweisung verwendet.
Dieses Prädikat ergibt einen Wert ungleich »0« genau dann, wenn »c« die Kennzahl eines Buchstabens ist.
Die innere Anweisung einer if-Anweisung wird genau dann ausgeführt, wenn der Wert ihres Ausdrucks ungleich »0« ist.
Aus den beiden letzten Aussagen folgt, daß die printf-Anweisung genau dann ausgeführt wird, wenn »c« die Kennzahl eines Buchstabens ist.
main.c
#include <stdio.h>
#include <ctype.h> /* isalpha */void check( int const c )
{ if( isalpha( c ))printf( "'%c' ist ein Buchstabe.\n", c ); }int main( void )
{ check( 64 );
check( 65 ); }transcript
'A' ist ein Buchstabe.
Bei den Rückgabewerten von »isalpha« geht es nur darum, ob diese gleich »0« sind, der genaue Wert ist unwichtig.
Bei dem Ausdruck der if-Anweisung geht es ebenfalls nur darum, ob dieser den Wert »0« ergibt, der genaue Wert ist unwichtig.
Damit passen Prädikate wie »isalpha« genau zur if-Anweisung!
Man kann den Wert »0« oft auch als Darstellung des Wahrheitswertes „falsch“ ansehen, während jeder andere Wert den Wahrheitswert „wahr“ darstellt.
Damit kann man sagen, daß das Prädikat »isalpha« genau dann eine Darstellung des Wertes „wahr“ ergibt, wenn der Wert des Arguments die Kennzahl eines Buchstabens ist, und daß die innere Anweisung einer if-Anweisung genau dann ausgeführt wird, wenn die Auswertung ihres Ausdrucks eine Darstellung des Wertes „wahr“ (also einen Wert ungleich »0«) ergibt .
Übungen
? Übungsfrage
Ein Aufruf der Funktion »printf« gibt in der Regel die Anzahl der von ihm ausgegebenen Zeichen zurück. Welche Ausgabe erzeugt demnach das folgende Programm?
main.c
#include <stdio.h>
int main( void )
{ if( printf( "A" ))printf( "B\n" );
if( printf( "" ))printf( "C\n" ); }
Übungsaufgaben
/ Bedingte Ausgabe
Schreiben Sie eine Definition einer Funktion, die den Text »nicht Zwei« ausgibt, wenn sie nicht mit der Zahl »2« aufgerufen wurde, und sonst gar nichts macht.
Ersetzen Sie hierzu die Ellipse »…« des folgenden Musters durch einen geeigneten Text.
- Muster
- void f( void ){ if( … )printf( "nicht Zwei\n" ); }
/ Bedingte Ausgabe (1) *
Schreiben Sie eine Definition einer Funktion, die den Text »Eins« ausgibt, wenn sie mit der Zahl »1« aufgerufen wurde, und sonst nichts macht.
Ersetzen Sie hierzu die Ellipse »…« des folgenden Musters durch einen geeigneten Text.
- Muster
- void f( void ){ if( … )printf( "Eine\n" ); }
/ Bedingte Ausgabe (2) *
Schreiben Sie eine Definition einer Funktion, die den Text »Zwei« ausgibt, wenn sie mit der Zahl »2« aufgerufen wurde, und sonst gar nichts macht.
/ Kontrollierte Rekursion *
Schreiben Sie eine Definition einer Funktion, die von einer ihr als Argument übergebenen positiven int-Zahl an alle kleineren Zahlen bis hin zu der Zahl 0 ausgibt.
Hinweis: Programmieren Sie diese Funktion folgendermaßen: Geben Sie innerhalb dieser Funktion zuerst den Argumentwert aus. Falls dieser größer als 0 war, rufen Sie die Funktion alsdann mit dem um Eins verminderten Argumentwert auf. (Die Funktion soll sich in diesem Fall also selber aufrufen.)
Struktogramme *
Das folgende Struktogramm (gemäß DIN 66261 nach Nassi und Shneiderman ACM SIGPLAN Notices 8, August 1973) zeigt die Darstellung der folgenden C -Anweisung als Struktogramm.
- C -Anweisung
if( n )printf( "*" );
- Struktogramm
.-----------------------------------------.
|'-. .-'|
| '-. .-' |
| '-. n .-' |
| '-. .-' |
| nicht 0 '-. .-' 0 |
| '-. .-' |
|------------------'-.-'------------------|
| Ausgabe "*" | |
'-----------------------------------------'- Struktogramm (vereinfachte Form)
.-----------------------------------------.
| n ? |
| nicht 0 | 0 |
|--------------------|--------------------|
| Ausgabe "*" | |
'-----------------------------------------'