Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
Vorwort
Vorwort des Gutachters
1 Einstieg in C
2 Das erste Programm
3 Grundlagen
4 Formatierte Ein-/Ausgabe mit »scanf()« und »printf()«
5 Basisdatentypen
6 Operatoren
7 Typumwandlung
8 Kontrollstrukturen
9 Funktionen
10 Präprozessor-Direktiven
11 Arrays
12 Zeiger (Pointer)
13 Kommandozeilenargumente
14 Dynamische Speicherverwaltung
15 Strukturen
16 Ein-/Ausgabe-Funktionen
17 Attribute von Dateien und das Arbeiten mit Verzeichnissen (nicht ANSI C)
18 Arbeiten mit variabel langen Argumentlisten – <stdarg.h>
19 Zeitroutinen
20 Weitere Headerdateien und ihre Funktionen (ANSI C)
21 Dynamische Datenstrukturen
22 Algorithmen
23 CGI mit C
24 MySQL und C
25 Netzwerkprogrammierung und Cross–Plattform-Entwicklung
26 Paralleles Rechnen
27 Sicheres Programmieren
28 Wie geht’s jetzt weiter?
A Operatoren
B Die C-Standard-Bibliothek
Stichwort

Buch bestellen
Ihre Meinung?

Spacer
<< zurück
C von A bis Z von Jürgen Wolf
Das umfassende Handbuch
Buch: C von A bis Z

C von A bis Z
3., aktualisierte und erweiterte Auflage, geb., mit CD und Referenzkarte
1.190 S., 39,90 Euro
Rheinwerk Computing
ISBN 978-3-8362-1411-7
Pfeil 18 Arbeiten mit variabel langen Argumentlisten – <stdarg.h>
Pfeil 18.1 Makros in <stdarg.h> – »va_list«, »va_arg«, »va_start« und »va_end«
Pfeil 18.2 Die Argumentliste am Anfang oder Ende kennzeichnen
Pfeil 18.3 »vprintf()«, »vsprintf()«, »vfsprintf()« und »vsnsprintf()«
Pfeil 18.4 Variadic Makros – __VA_ARGS__


Rheinwerk Computing - Zum Seitenanfang

18.2 Die Argumentliste am Anfang oder Ende kennzeichnen topZur vorigen Überschrift

Diese vier Makros werden Sie jetzt anwenden. Es soll eine Funktion geschrieben werden, die eine variable Anzahl von Argumenten erhält. Die Argumente (Ganzzahlen) werden dabei alle zu einer Summe addiert. Hier sehen Sie das Listing:

/* vargs1.c */
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

int add(int zahlen, ...) {
   va_list zeiger;
   int zahl;

   va_start(zeiger,zahlen);
   do {
      zahl = va_arg(zeiger,int);
      zahlen += zahl;
   } while(zahl != 0);

   va_end(zeiger);
   return zahlen;
}

int main(void) {
   int erg;

   printf("%d\n",add(11,12,13,0));
   printf("%d\n",add(99,66,33,22,11,0));
   erg = add(10, 13, 11, 0) + add(9, 8, 11, 0);
   printf("%d\n",erg);
   return EXIT_SUCCESS;
}

Der Aufruf der Funktion erfolgt mit:

printf("%d\n",add(11,12,13,0));

Hier wird die Funktion add() mit den Argumenten 11, 12, 13 und 0 aufgerufen. Die Zahl 0 am Ende stellt die Abbruchbedingung dar. Zunächst wird der Argumentzeiger angelegt, mit dem die Liste der optionalen Argumente durchlaufen wird:

va_list zeiger;

Der Argumentzeiger erhält jetzt mithilfe des Makros va_start() die Position des ersten optionalen Arguments:

va_start(zeiger,zahlen);

Ohne diesen Aufruf wäre kein Zugriff auf die weiteren optionalen Argumente möglich. Man könnte auch sagen, der Datentyp zeiger verweist auf die Anfangsadresse der ersten Zahl in der Argumentliste. Anschließend wird in der do while-Schleife der Wert zurückgeliefert, auf den der Argumentzeiger gerade verweist.

zahl=va_arg(zeiger,int);

In diesem Beispiel ist dies die Zahl 12. Diese Zahl wird zu dem ersten Wert von zahlen (11) addiert. Außerdem wird nach dem Aufruf von va_arg() der Argumentzeiger auf das nachfolgende Argument gesetzt.

Ist die Bedingung der Schleife wahr (zahl != 0), fährt das Programm mit zahl=va_arg(zeiger,int), genauer gesagt dem nächsten Wert (13), fort und addiert diesen wieder mit zahlen. Beim nächsten Durchgang ist die while-Bedingung unwahr (zahl==0), und die Liste wird beendet mit:

va_end(zeiger);

Anhand des ersten Funktionsaufrufs können Sie sich dies grafisch so vorstellen:

Abbildung 18.1 Zugriff einzelner Werte bei einer variablen Argumentliste

Jetzt soll das Programm so umgeschrieben werden, dass mit einer bestimmten Anzahl von Argumenten gearbeitet wird:

/* vargs2.c */
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

void print_zahlen(int anzahl, ...) {
   va_list zeiger;
   int zahl;
   int i;

   printf("Es werden %d Zahlen ausgegeben\n",anzahl);
   va_start(zeiger,anzahl);
   for(i = 1; i <= anzahl; i++) {
      zahl=va_arg(zeiger,int);
      printf("%d\t",zahl);
   }
   printf("\n");
   va_end(zeiger);
}

int main(void) {
   print_zahlen(4,3,2,4,7);
   print_zahlen(6,11,22,33,44,55,66);
   return EXIT_SUCCESS;
}

Das Programm ist ähnlich aufgebaut wie im Beispiel zuvor, nur dass hier als Abbruchbedingung das erste Argument verwendet wurde. In dem Funktionsaufruf

print_zahlen(6, 11, 22, 33, 44, 55, 66);

wird durch das erste Argument gekennzeichnet, dass die Funktion mit 6 Argumenten vom Typ int aufgerufen wird. Dies ist auch die Abbruchbedingung für die for-Schleife in der Funktion print_zahlen().

Diese Makros sind natürlich noch deutlich vielseitiger, als Beispiel sei die Funktion strcat() zum Anhängen eines Strings an einen anderen genannt. Häufig würden Sie sicherlich gern mehrere Strings auf einmal an einen anderen hängen. Dabei mussten Sie bislang immer mehrere strcat()-Aufrufe ausführen. Mit dem eben gezeigten Beispiel kann dies jetzt in einem Schritt realisiert werden:

strxcat(3, string, string1, string2);

Hiermit werden die beiden Strings string1 und string2 an den String string gehängt. Die Anzahl der Strings wird am Anfang der Argumentliste gekennzeichnet. Hierzu das Listing:

/* strxcat.c */
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#define MAX 50

void strxcat(int n_strings, ...) {
   va_list zeiger;
   char *quelle, *ziel, *p;

   va_start(zeiger,n_strings);
   /* nun auf den Zielstring */
   ziel = va_arg(zeiger,char *);
   p = ziel;
   /* am Ende vom Zielstring */
   ziel+=strlen(ziel);
   if( (ziel-p) > MAX) {
      printf("!!!Maximale Anzahl an Zeichen ueberschritten!!!\n");
      return;
   }
   while(--n_strings > 0) {
      /* Quelle einlesen */
      quelle = va_arg(zeiger, char *);
      /* jetzt Zeichen für Zeichen an ziel */
      while(*quelle) {
         *ziel++ = *quelle++;
         if( (ziel-p) > MAX) {
            printf("!Maximale Anzahl an Zeichen ueberschritten!\n");
            exit(EXIT_FAILURE);
         }
      }
   }
   *ziel = '\0';
}

int main(void) {
   char string[MAX] = "Test : ";
   char string2[] = " Und";

   strxcat(3, string, "hallo " , "welt");
   printf("%s\n",string);

   strxcat(5, string, string2, " noch", " ein", " Test");
   printf("%s\n",string);

   /*Und nun ein Fehler mit Absicht*/
   strxcat(4, string , " Ueberlauf", " von", " MAX");
   printf("%s\n",string);
   return EXIT_SUCCESS;
}

Abbildung 18.2 Mehrere Strings auf einmal aneinanderhängen

Hier wurde auch eine Sicherung eingebaut, um sich vor sogenannten Pufferüberläufen zu schützen.



Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen. >> Zum Feedback-Formular
<< zurück
  
  Zum Katalog
Zum Katalog: C von A bis Z

 C von A bis Z
Jetzt bestellen


 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchtipps
Zum Katalog: C/C++






 C/C++


Zum Katalog: Einstieg in C






 Einstieg in C


Zum Katalog: Schrödinger programmiert C++






 Schrödinger
 programmiert C++


Zum Katalog: C++ Handbuch






 C++ Handbuch


Zum Katalog: IT-Handbuch für Fachinformatiker






 IT-Handbuch für
 Fachinformatiker


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo




Copyright © Rheinwerk Verlag GmbH 2009
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


[Rheinwerk Computing]

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de