3 Beispielprogramme zur Einführung


Beispielprogramm 1: 1. einfaches Programm
Beispielprogramm 2: 2. einfaches Programm
Beispielprogramm 3: while-Schleife
Beispielprogramm 4: for-Schleife
Beispielprogramm 5: Preprozessor-Makros
Beispielprogramm 6: Einfache Ein- und Ausgabe
Beispielprogramm 7: Eingabezeichen zählen mit while-Schleife
Beispielprogramm 8: Eingabezeichen zählen mit for-Schleife
Beispielprogramm 9: Eingabezeilen zählen
Beispielprogramm 10: Eingabezeilen, -worte und -zeichen zählen
Beispielprogramm 11: Ziffern, Zwischenräume und sonstige Zeichen zählen
Beispielprogramm 12: Die Funktion x^n
Beispielprogramm 13: Float-Eingaben und Bereichsprüfung
Beispielprogramm 14: Funktionsparameter und Zeiger
Beispielprogramm 15: String rueckwaerts ausgeben
Beispielprogramm 16: String rueckwaerts ausgeben mit Rekursion
Beispielprogramm 17: Kommandozeilenparameter


Beispielprogramm p3-1.c


  /*
   *      p3-1.c
   *      Beispielprogramm 1, Abschnitt 3
   */

  void main(void)
  {
    printf("Viel Spass mit C !\n");

  } /* main() */

Erläuterungen zu diesem Programm:

- alle Angaben zwischen /* und */ werden als Kommentar behandelt

- Kommentar kann überall im Quellencode stehen wo auch ein Leerzeichen, Tabulatorzeichen oder Zeilentrennzeichen stehen darf, sinnvollerweise schreibt man ihn aber an das Ende einer Zeile und/oder verwendet Kommentarzeilen

- C-Programme bestehen aus Funktionen, diese sind an den dem Funktionsnamen folgenden runden Klammern zu erkennen

- Funktion main() muß immer vorhanden sein

- sie wird meist am Anfang des Quellencodes plaziert

- die geschweiften Klammern umschließen den Funktionskörper wie z.B. BEGIN und END in PASCAL

- das Ende des Quellencodes muß nicht explizit angegeben werden

- in C gibt es nur Funktionen, keine CALLs

- printf ist eine Funktion zur formatierten Ausgabe auf den Bildschirm (bzw. die Standardausgabe)

- sie hat hier die Stringkonstante "Viel Spass mit C !\n" als Parameter

- die Zeichenkombination \n steht für das Zeilenendezeichen

- C kennt keine Zeilenstruktur (Ausnahme: innerhalb von Zeichenketten oder #define-Anweisungen)

- Anweisungen sind mit ; zu beenden


Beispielprogramm p3-2.c


  /*
   *      p3-2.c
   *      Beispielprogramm 2, Abschnitt 3
   */
   
  void main(void)
  {
    printf("Viel");
    printf(" Spass");
    printf(" mit");
    printf(" C !");
    printf("\n");

  } /* main() */

Erläuterungen zu diesem Programm:

- gleiche Wirkung wie Programm p3-1.c aber anderes Programm

- kein explizites Zeilenendezeichen, daher Verkettung der Ausgabe

- das Zeichen \ wirkt als Fluchtsymbol, es dient zur Darstellung von Sonderzeichen:


  \n    =  Zeilensprung (Linefeed)
  \r    =  Wagenrücklauf (Carriage Return)
  \t    =  Tabulatorzeichen
  \b    =  Backspacezeichen
  \"    =  das Zeichen "
  \\    =  das Zeichen \


Beispielprogramm p3-3.c


  /*
   *      p3-3.c
   *      Beispielprogramm 3, Abschnitt 3
   *      Umwandlung von Fahrenheit in Celsius 
   *      fuer f = 0, 20, ..., 300
   */

  void main(void)
  {
    int lower, upper, step;
    float fahr, celsius;

    lower = 0;      /* untere Grenze der Temperaturtabelle */
    upper = 300;    /* obere Grenze */
    step = 20;      /* Schrittweite */
    fahr = lower;

    while (fahr <= upper) {
      celsius = (5.0/9.0) * (fahr-32.0);
      printf("%4.0f %6.1f\n", fahr, celsius);    
      fahr = fahr + step;                       
    }     

  } /* main() */

Erläuterungen zu diesem Programm:

- in C müssen alle Variablen vor ihrer Verwendung vereinbart werden

- Vereinbarungen müssen am Anfang eines Blocks vor der ersten Anweisung stehen

- man unterscheidet Deklarationen und Definitionen

- C kennt folgende elementaren Datentypen


  char          einzelnes Zeichen (Character)
  int           Integerzahlen
  float         Gleitkommazahlen
  double        Gleitkommazahl mit doppelter Genauigkeit

- zur Qualifizierung dienen dann noch die Zusätze:


  short         kleine Integerzahl
  long          große Integerzahl
  unsigned      ohne Vorzeichen
  signed        mit Vorzeichen (Weglasswert)

- die Zeilen :


  lower = 0;
  upper = 300;
  fahr  = lower;

stellen Zuweisungen dar, dabei wird im 3.Fall eine Typwandlung von int nach float durchgeführt

- Die Schleife


  while (Bedingung) {

    Anweisungen

  }

ist eine von mehreren in C realisierten Kontrollstrukturen, die Anweisungen in den geschweiften Klammern werden nur ausgeführt, wenn der Ausdruck in der Klammer nach while wahr ist

- hängt nur eine einzige Anweisung von der while Bedingung ab, so kann man die geschweiften Klammern auch weglassen:


  while (i < j)
    i = 2 * j;

- in C gilt generell die Konvention:

gleich 0 := FALSE (FALSCH)

ungleich 0 := TRUE (WAHR)

- die Formulierung 5.0/9.0 gegenüber 5/9 ist notwendig, da wegen der sonst verwendeten Ganzzahlarithmetik 5/9=0 gilt

- dagegen kann man die Zahl 32 als 32 oder 32.0 schreiben, weil C die Verwendung gemischter Typen in Ausdrücken erlaubt; zum Zwecke der besseren internen Dokumentation sollte man in unserem Falle aber 32.0 verwenden (Gleitkommazahlen)

- printf kann mehr als einen Parameter haben und gleichzeitig die Ausgabe formatieren:


  printf("%4.0f  %6.1f\n", fahr, celsius);

bedeutet:

gibt die Variable fahr im Gleitkommaformat mit insgesamt 4 Stellen ohne Nachkommastellen aus, füge ein Leerzeichen (Blank) ein, gib dann die Variable celsius im Gleitkommaformat mit insgesamt 6 Stellen und einer Nachkommastelle aus und schließe die Ausgabe mit einem Zeilenendezeichen ab

- printf kennt noch andere Umwandlungsformate:


  %c            ein einzelnes Zeichen
  %d            Integerzahl
  %f            Gleitkommazahl
  %o            Oktaldarstellung
  %s            Zeichenkette
  %x            Hexadezimaldarstellung
  %%            das %-Zeichen selbst ausgeben


Beispielprogramm p3-4.c


  /*
   *      p3-4.c
   *      Beispielprogramm 4, Abschnitt 3
   *      Umwandlung von Fahrenheit in Celsius 
   *      fuer f = 0, 20, ..., 300
   *      Wie Beispiel 3 aber mit for-Schleife
   */

  void main(void)
  {
    int fahr;
    
    for (fahr=0; fahr <= 300; fahr=fahr+20) {
      printf("%4.0d %6.1f\n", fahr, (5.0/9.0)*(fahr-32));
    }
  
  } /* main() */

Erläuterungen zu diesem Programm:

- dieses Programm liefert das gleiche Ergebnis, wie das vorige Beispiel, aber es sieht ganz anders aus

- fahr ist jetzt eine Integerzahl, dies dient nur der Demonstration der %d Umwandlung

- printf akzeptiert auch Ausdrücke für die auszugebenden Parameter

- die for Schleife ist eine weitere in C mögliche Kontrollstruktur, sie hat die Form:


  for (Initialisierung; Bedingung; Reinitialisierung) {
  
    Anweisungen
    
  }            


Beispielprogramm p3-5.c


  /*
   *      p3-5.c
   *      Beispielprogramm 5, Abschnitt 3
   *      Umwandlung von Fahrenheit in Celsius 
   *      fuer f = 0, 20, ..., 300
   *      Wie Beispiel 4 aber mit Konstanten
   */

  #define LOWER 0         /* untere Grenze der Tabelle */
  #define UPPER 300       /* obere Grenze der Tabelle */
  #define STEP 20         /* Schrittweite */

  void main(void)
  {
    int fahr;
  
    for (fahr=LOWER; fahr<=UPPER; fahr=fahr+STEP)
      printf ("%4.0d %6.1f\n", fahr, (5.0/9.0)*(fahr-32));

  } /* main() */

Erläuterungen zu diesem Programm:

- die Verwendung von symbolischen Konstanten garantiert eine einfache Änderungsmöglichkeit

- symbolische Konstanten werden üblicherweise zur einfacheren Identifizierung in Großbuchstaben geschrieben

- C unterscheidet zwischen Groß- und Kleinschreibung

- nach #define Zeilen steht kein Semikolon, da #define einen Textersatz (also auch mit evtl. Semikolon) bewirkt

- das # muß in der 1. Spalte stehen

- der C-Präprozessor verarbeitet diejenigen Anweisungen, bei denen ein # in der ersten Spalte steht (in unserem Falle hier ist diese Verarbeitung ein Textersatz)


Beispielprogramm p3-6.c


  /*
   *      p3-6.c
   *      Beispielprogramm 6, Abschnitt 3
   *      Ein Kopierprogramm
   */

  #include <stdio.h>              /* enthaelt wichtige Konstanten */

  void main(void)
  {
    int c;          

    c = getchar();
    while (c != EOF) {
      putchar(c);
      c = getchar();
    }

  } /* main() */

Erläuterungen zu diesem Programm:

- #include bewirkt das Einfügen von Quellencode aus einer anderen Datei

- die Hauptanwendung liegt im Einfügen von sogenannten Header-Dateien, die üblicherweise zu jedem C-Bibliothekssystem dazugehören

- eine solche Headerdatei hat die Dateinamenergänzung .h und enthält Symbole und Vereinbarungen, die bei bestimmten Anwendungen (z.B. Ein-/Ausgabe, Dateiverarbeitung) immer wieder gebraucht werden

- die spitzen Klammern um den Dateinamen bewirken, daß zunächst das "INCLUDE"-Verzeichnis (bei UNIX Systemen meist /usr/include) und erst dann das Arbeitsverzeichnis nach der angegebenen Datei durchsucht wird

- auf verschiedenen Rechnern kann EOF 0 oder -1 sein, daher die Definition von EOF in einer Headerdatei

- c ist als int deklariert, um den Wert EOF abfragen zu können

- getchar ist eine Funktion aus der Funktionsbibliothek, die 1 Zeichen von der Konsole (stdin) einliest

- putchar gibt 1 Zeichen auf die Konsole (stdout) aus

- != bedeutet ungleich

- nach der while Bedingung sind 2 Anweisungen mittels geschweifter Klammern zu einem Block zusammengefaßt

- man hätte das Programm auch noch kompakter so formulieren können


  while ((c = getchar()) != EOF)
    putchar(c);

- die Klammerung ist sehr wichtig sonst wird c der Wert des Vergleiches von getchar() mit EOF und nicht das gelesene Zeichen zugewiesen


Beispielprogramm p3-7.c


  /*
   *      p3-7.c
   *      Beispielprogramm 7, Abschnitt 3
   *      Programm zum Zaehlen von Eingabezeichen
   */

  #include <stdio.h>

  void main(void)
  {
    long nc;          

    nc = 0;
    while (getchar() != EOF)
      ++nc;
    printf("%ld\n", nc);

  } /* main() */

Erläuterungen zu diesem Programm:

- ++nc ist eine Inkrementoperation für die Variable nc, analog ist --nc eine Dekrementoperation

- ++nc und nc++ sind beide möglich, unterscheiden sich aber

- ++nc heißt erst inkrementieren, dann Wert von nc verwenden

- nc++ heißt erst Wert von nc verwenden, dann inkrementieren

- die Formatangabe %ld ist notwendig, da nc ein Long-Integerwert ist


Beispielprogramm p3-8.c

 
  /*
   *      p3-8.c
   *      Beispielprogramm 8, Abschnitt 3
   *      Programm zum Zaehlen von Eingabezeichen
   *      Wie Beispiel 7, aber mit for-Schleife
   *      und anderem Datentyp fuer den Zaehler
   */

  #include <stdio.h>

  void main(void)
  {
    double nc;          
  
    for (nc=0; getchar() != EOF; ++nc)
      ;
    printf("%.0f\n", nc);
  
  } /* main() */

Erläuterungen zu diesem Programm:

- die for-Schleife in diesem Fall hat keine abhängige Anweisung, daher das einzelne Semikolon in einer neuen Zeile (wichtig zur Dokumentation)

- die Formatangabe %.0f bewirkt die Ausgabe eine doppelt genauen Gleitpunktzahl ohne Nachkommastellen


Beispielprogramm p3-9.c


  /*
   *      p3-9.c
   *      Beispielprogramm 9, Abschnitt 3
   *      Programm zum Zaehlen von Eingabezeilen
   */

  #include <stdio.h>

  void main(void)
  {
    int c, nl;
 
    nl = 0;
    while ((c = getchar()) != EOF)        /* Klammern sind wichtig! */
      if (c == '\n')
	++nl;
    printf("%d\n", nl);

  } /* main() */

Erläuterungen zu diesem Programm:

- hier sehen wir eine if Kontrollstruktur, wobei die Bedingung wie bei while in Klammern gesetzt wird

- die if Kontrollstruktur sieht so aus:


  if (Bedingung) {

    Anweisungen

  }
  else if (Bedingung) {
  
    Anweisungen
    
  }
  else {

    Anweisungen
      
  }

- die else if- und else-Zweige sind optional

- == bedeutet identisch

- '\n' ist eine Zeichenkonstante, deswegen in Hochkommas eingeschlossen


Beispielprogramm p3-10.c


  /*
   *      p3-10.c
   *      Beispielprogramm 10, Abschnitt 3
   *      Eingabezeilen, -worte und -zeichen zaehlen
   */

  #include <stdio.h>

  #define YES 1
  #define NO 0

  void main(void)
  {
    int c, nl, nw, nc, inword;

    inword = NO;
    nl = nw = nc = 0;
  
    while ((c = getchar()) != EOF) {
      ++nc;
      if (c == '\n')
	++nl;
      if (c == ' ' || c == '\n' || c == '\t')
	inword = NO;
      else if (inword == NO) {
	inword = YES;
	++nw;
      }
    }
  
    printf("%d %d %d\n", nl, nw, nc);

  } /* main() */

Erläuterungen zu diesem Programm:

- verbundene Anweisungen wie nl=nw=nc=0; werden von rechts nach links abgearbeitet, sie sollten nach Möglichkeit vermieden werden

- || ist der (logische) ODER-Operator

- && ist der (logische) UND-Operator

- Ausdrücke mit logischen Operatoren werden von links nach rechts bewertet und dann abgebrochen, wenn das Ergebnis feststeht (also der erste Teilausdruck ungleich 0 (bei ODER) oder gleich 0 (bei UND) ist


Beispielprogramm p3-11.c


  /*
   *      p3-11.c
   *      Beispielprogramm 11, Abschnitt 3
   *      Ziffern, Zwischenraeume und andere Zeichen zaehlen
   */

  #include <stdio.h>

  void main(void)
  {
    int c, i, nwhite, nother;
    int ndigit[10];
  
    nwhite = nother = 0;
  
    for (i=0; i<10; ++i)
      ndigit[i]=0;
    
    while ((c = getchar()) != EOF)
      if (c >= '0' && c <= '9')
	++ndigit[c-'0'];
      else if (c == ' ' || c == '\n' || c == '\t')
	++nwhite;
      else
	++nother;
      
    printf("Zahlen =");
    for (i=0; i<10; ++i)
      printf(" %d", ndigit[i]);
    printf("\n\"White Space\" = %d, andere = %d\n", nwhite, nother);

  } /* main() */

Erläuterungen zu diesem Programm:

- Vektoren (Felder) werden durch Anhängen von eckigen Klammern an den Variablennamen definiert

- die Feldindizes laufen von 0 bis N-1, sie werden nicht abgeprüft

- das Beispielprogramm gilt nur für Zeichencodes mit lückenlosem Aufeinanderfolgen von Ziffern (sowohl in EBCDIC als auch in ASCII erfüllt)

- char wird intern in int gewandelt, deshalb ist der Ausdruck


  c - '0'

so einfach möglich

- Verkettungen von if und else sollte man so schreiben:


  if            oder    if
  else if               else
			  if
  else                    else


Beispielprogramm p3-12.c


  /*
   *      p3-12.c
   *      Beispielprogramm 12, Abschnitt 3
   *      die Funktion X hoch N
   */

  void main(void)
  {
    int i;
  
    for (i=0; i<=10; ++i)
      printf("%d %d %d\n",i, power(2,i), power(-3,i));

  } /* main() */

  int power(int x, int n)         /* x hoch n, n>0 */
  {
    int i, p;

    p = 1;
    for (i=1; i<=n; ++i)
      p = p * x;
    return(p);

  } /* power() */

Erläuterungen zu diesem Programm:

- hier haben wir zum ersten Mal eine "richtige" Funktion

- eine Funktion hat immer die Form:


  Typ Name(Parameterliste)
  {

    Vereinbarungen

    Anweisungen

    return Funktionswert

  }

- die Parameternamen sind nur lokal bekannt

- die Parameterwerte sind durch die Funktion nur lokal nicht aber mit Wirkung für die aufrufende Funktion veränderbar

- die return Anweisung bewirkt einen Rücksprung mit der Übergabe des Funktionswertes, die Klammern um den Funktionswert sind syntaktisch nicht notwendig, aber üblich

- fehlt return, dann erfolgt der Rücksprung nach der letzten schließenden geschweiften Klammer, der Funktionswert ist dann unbestimmt


Beispielprogramm p3-13.c


  /*
   *      p3-13.c
   *      Beispielprogramm 13, Abschnitt 3
   *      Wie Beispiel 3, aber mit Einlesen der 
   *      Grenzen und der Schrittwerte
   */

  #include <stdio.h>
  
  void main(void)
  {
    int i;
    int lower, upper, step;
    float fahr, celsius;
  
    i = 0;
    while (i != 2) {
      printf("Bitte die Grenzen fuer die Berechnung in \
      der Form \"untere - obere\" angeben\n");
      i = scanf("%d - %d", &lower, &upper);
      if (i != 2 || upper <= lower) {
	printf("\n Falsche Eingabe \07\n");
	i = 0;
      }
    }
    
    i = 0;
    while (i != 1) {
      printf("Bitte die Schrittweite eingeben: ");
      i = scanf("%d", &step);
      if (i != 1 || step <= 0) {
	printf("\n Falsche Eingabe \07\n");
	i = 0;
      }
    }

    fahr = lower;
    while (fahr <= upper) {
      celsius = (5.0/9.0) * (fahr-32.0);
      printf("%4.0f %6.1f\n", fahr, celsius);
      fahr = fahr + step;
    }
  
  } /* main() */

Erläuterungen zu diesem Programm:

- wir haben hier das gleiche Programm wie in Beispiel p3-3.c, allerdings werden hier einige Daten interaktiv eingelesen

- das Einlesen wird von der Funktion scanf bewerkstelligt

- sie hat die gleiche Formatsteuerung wie printf

- die Parameter müssen aber Adressen sein (Warum?)

- & ist der Adressoperator, Ergebnis ist die Adresse des Objekts

- Funktionswert von scanf ist die Anzahl erfolgreich eingelesener Parameter

- alle Angaben in den Anführungsstrichen von scanf, die nicht zu Formatangaben gehören, müssen genauso eingegeben werden

- Strings dürfen über das Zeilenende hinausgehen, wenn unmittelbar vor dem Zeilenende ein \ steht

- \" gibt " aus

- \07 gibt das ASCII-Zeichen mit dem Oktalcode 07 (=BELL) aus


Beispielprogramm p3-14.c


  /*
   *      p3-14.c
   *      Beispielprogramm 14, Abschnitt 3
   *      Eingabefunktion mit Parametern
   */

  #include <stdio.h>
  
  void proc(int, int *);          /* Prototyp */

  void main(void)
  {
    int n, m;
    int *mp;

    n = 11;                       /* Initialwerte */
    m = 22;
    mp = &m;                      /* mp = Adresse m */
  
    printf("main: n=%06d m=%06d mp=%p (&m=%p)\n\n", n, m, mp, &m);
    proc(n, &m);
    printf("main: n=%06d m=%06d mp=%p (&m=%p)\n", n, m, mp, &m);

  } /* main() */

  void proc(int n, int *m)
  {
    printf("proc: n=%06d m=%06d mp=%p (&m=%p)\n", n, *m, m, &m);
    printf("      Eingabe n? ");
    (void) scanf("%d", &n);
    printf("      Eingabe m? ");
    (void) scanf("%d", m);
    printf("proc: n=%06d m=%06d mp=%p (&m=%p)\n\n", n, *m, m, &m);

  } /* proc() */

Erläuterungen zu diesem Programm:

- Prototyp type function (parameter, ...) gibt dem Compiler die Möglichkeit die korrekte Nutzung einer Funktion und ihrer Parameter (Typ!) zur Compilezeit zu prüfen

- Zeigervariable (Pointer) int *mp Zeiger auf eine Variable vom Typ Integer, Zeigervariable enthält die Adresse

- Prozedurdeklaration mit aktuellen Parametern (Typ und Name): Parameter n call by value, Parameter m call by reference

- Wert von n sichtbar nur lokal in Prozedur, nicht in aufrufendem Block main(), Wert von *m sichtbar auch in aufrufendem Block in m:


  main: n=000011 m=000022 mp=effffb68 (&m=effffb68)

  proc: n=000011 m=000022 mp=effffb68 (&m=effffb48)
	Eingabe n? 22
	Eingabe m? 33
  proc: n=000022 m=000033 mp=effffb68 (&m=effffb48)

  main: n=000011 m=000033 mp=effffb68 (&m=effffb68)

- Damit 2 Wege in Funktionen Variable zu verändern: Rückgabewerte von Funktionen und Adress- bzw. Pointerparameter


Beispielprogramm p3-15.c


  /*
   *      p3-15.c
   *      Beispielprogramm 15, Abschnitt 3
   *      String rueckwaerts ausgeben 
   *      mit for-Schleife
   */

  #include <stdio.h>

  void main(void)
  {
    char s[256];          /* String mit Laenge 256 Zeichen */
    int i;
  
    s[0] = '\0';
    printf("Bitte String eingeben: ");
    gets(s);
  
    if (s[0]) {
      for (i = strlen(s) - 1; i >= 0; i--) {
	putchar(s[i]);
      }
      putchar('\n');
    }
    else {
      printf("Sorry, Eingabe war leer.\n");
    }  

  } /* main() */

Erläuterungen zu diesem Programm:

- In C ist ein String ein Feld/Vektor von Zeichen, also kein eigener Datentyp

- Strings werden mit dem Zeichen ASCII-NUL '\0' terminiert, die maximale Stringlänge ist daher die Feldlänge - 1

- Keinerlei Prüfung auf Stringlänge und Zulässigkeit, daher ist gets() unzuverlässig und kann Programmfehler durch Überlauf verursachen, wenn die Eingabe zu lang ist

- Wie bei Feldern üblich läuft auch bei Strings der Feldindex von 0 an


Beispielprogramm p3-16.c


  /*
   *      p3-16.c
   *      Beispielprogramm 16, Abschnitt 3
   *      String rueckwaerts ausgeben
   *      mit Rekursion
   */

  #include <stdio.h>

  void putrevc(char *s);  /* Prototyp */

  void main(void)
  {
    char s[256];          /* String mit Laenge 256 Zeichen */
  
    s[0] = '\0';
    printf("Bitte String eingeben: ");
    gets(s);
  
    putrevc(s);

  } /* main() */

  void putrevc(char *s)
  {
  #ifdef  DEBUG
    static int n = 0;
  
    printf("putrevc(%03d) [%s]\n", ++n, s);
  #endif 
 
    if(*s && *(s+1))
      putrevc(s+1);  
  #ifdef  DEBUG  
    else
      printf("putrevc(%03d) [%s] [0x%02x] [0x%02x] Abbruch\n", 
	      n, s, *s, *(s+1));
    printf("putrevc(%03d) [%s] [%c]\n", n, s, *s);
  #else
    putchar(*s);
  #endif  /* DEBUG */  

  } /* putrevc() */

Erläuterungen zu diesem Programm:

- Bedingte Übersetzung durch das Preprozessor-Makro DEBUG. Der Programmcode zwischen #ifdef DEBUG und #endif bzw. zwischen #ifdef DEBUG und #else wird nur dann an den C-Compiler eingespeist, wenn das Makro/die Konstante DEBUG zur Übersetzungszeit definiert ist. Das kann auch in der Kommandozeile geschehen:


  $ cc -DDEBUG -o p3-16 p3-16.c

- Entsprechend wird der Programmcode zwischen #else und #endif nur erzeugt, wenn DEBUG undefiniert ist

- Die Deklaration einer Variablen in einem Block (z.B. einer Funktion) als static bedeutet, daß die Variable ihren Wert über die ganze Lebensdauer des Programms erhält, d.h. auch dann, wenn ein Block inaktiv ist.

- Gleichbehandlung von Zeiger- und Feldvariablen, daher startet der Feldindex auch mit 0. Die Parameterübergabe erfolgt by reference, also mit Adresse, nicht by value, also mit dem Wert/Inhalt des Feldes

- Der Zeiger *s ist damit ein Zeiger auf ein Zeichen, auf das die Zeigervariable s gerade verweist. Damit ist auch Pointerarithmetik möglich

- Rekursion bedeutet, daß sich eine Funktion/Prozedur solange immer wieder selbst aufruft bis eine Abbruchbedingung erfüllt ist:


  Bitte String eingeben: hallo
  putrevc(001) [hallo]
  putrevc(002) [allo]
  putrevc(003) [llo]
  putrevc(004) [lo]
  putrevc(005) [o]
  putrevc(005) [o] [0x6f] [0x00] Abbruch
  putrevc(005) [o] [o]
  putrevc(005) [lo] [l]
  putrevc(005) [llo] [l]
  putrevc(005) [allo] [a]
  putrevc(005) [hallo] [h]


Beispielprogramm p3-17.c


  /*
   *      p3-17.c
   *      Beispielprogramm 17, Abschnitt 3
   *      Kommandozeilenparameter
   */

  #include <stdio.h>

  void main(int argc, char *argv[])
  {
    int n;
  
    printf("Parameterzahl:\t%d\n", argc);
    for (n = 0; n < argc; n++)
      printf("Parameter %2d:\t%s\n", n, argv[n]);
  
  } /* main() */

Erläuterungen zu diesem Programm:

- Das C-Laufzeitsystem gibt jedem Programm die Anzahl der Programmparameter in argc und die Parameter in argv als Feld von Strings mit

- Der Index für den Parametervektor startet wie üblich mit 0. Der erste Kommandozeilenparameter argv[0] enthält den Programmnamen


  $ p3-17
  Parameterzahl:  1
  Parameter  0:   p3-17  
  
  $ /home/fd3001/clabor/p3-17
  Parameterzahl:  1
  Parameter  0:   /home/fd3001/clabor/p3-17  
  
  $ p3-17 -option1 -option2 parameter1 parameter2 parameter3
  Parameterzahl:  5
  Parameter  0:   p3-17  
  Parameter  1:   -option1  
  Parameter  2:   -option2  
  Parameter  3:   parameter1  
  Parameter  4:   parameter2  
  Parameter  5:   parameter3


zurück zum Inhaltsverzeichnis

 

11. November 1999, Peter Klingebiel, DVZ