Hallo, ich weiss nicht warum, aber heute habe ich mich gefragt, wie macht man eigentlich eine unbestimmte Parameterübergabe (Anzahl der Parameter und Typ) ähnlich wie bei bei printf? D.h. wie kann ich folgendes realisieren: Aufrufmöglichkeit 1: int Dezimalzahl = 10; float Floatzahl = 1.0; Unterprogramm("Dezimalzahl = %d, Floatzahl = %f", Dezimalzahl, Floatzahl); Aufrufmöglichkeit 2: uint8 Bytezahl = 'h'; Unterprogramm("Bytezahl = %c", Bytezahl); In dem Fall weiss ich bei der Programmierung des Unterprogrammes(...) vorher nicht genau, wieviele Parameter vorhanden sind, und von welchem Typ sie sind. Bei den ganzen Einführungen in C bin ich nicht in endlicher Zeit auf eine Lösung gestoßen. Ein eigenes C Buch möchte ich mangels konkretem Ziel nicht beschaffen. Im Forum gab es sicherlich schon mal eine Lösung zu dieser Frage, eine Lösung konnte ich aber nicht finden. Vielen Dank. Heiko.
Dazu gibt es Unterstützungsfunktionen in varargs.h
1 | /* Returns the average of a variable list of integers. */
|
2 | int average(int first, ...) |
3 | {
|
4 | int count = 0, sum = 0, i = first; |
5 | va_list marker; |
6 | |
7 | va_start(marker, first); /* Initialize variable arguments. */ |
8 | while (i != -1) |
9 | {
|
10 | sum += i; |
11 | count++; |
12 | i = va_arg(marker, int); |
13 | }
|
14 | va_end(marker); /* Reset variable arguments. */ |
15 | return(sum ? (sum / count) : 0); |
16 | }
|
17 | |
18 | // Aufruf, letztes Argument wird durch -1 gekennzeichnet
|
19 | |
20 | average(2, 3, 4, -1); |
Ein Problem hierbei ist, daß die Anzahl der übergebenen Argumente nicht bestimmbar ist. Also muss entweder als eigener Parameter deren Anzahl, etwas woraus deren Anzahl bestimmt werden kann oder wie im Beispiel eine eindeutige Ende-Kennung als letzter Parameter übergeben werden. "Etwas woraus deren Anzahl bestimmt werden kann" ist beispielsweise der Formatstring, der printf/scanf übergeben wird.
Danke für die Info, dann werde ich demnächst mal damit spielen. Vielleicht braucht man sowas ja mal kurzfristig in einem Bastel-Projekt. Gruß, Heiko.
Für printf() wäre noch anzumerken, dass es eine Form gibt (vprintf() & Co.), bei denen das va_arg direkt weitergereicht werden kann. Damit kann die Parameterliste unbestimmter Länge weitergeleitet werden, ohne dass man genau wissen muss, welche und wie viele Parameter es genau waren.
1 | #include <avr/io.h> |
2 | |
3 | #include <stdint.h> |
4 | #include <stdio.h> |
5 | #include <stdarg.h> |
6 | |
7 | void
|
8 | myprint(uint8_t leds, const char *fmt, ...) |
9 | {
|
10 | va_list ap; |
11 | |
12 | PORTB = leds; |
13 | |
14 | va_start(ap, fmt); |
15 | (void)vprintf(fmt, ap); |
16 | va_end(ap); |
17 | }
|
(Ja, bitte <stdarg.h> benutzen, nicht <varargs.h>. Das ist ein alter Name.)
> Vielleicht braucht man sowas ja mal kurzfristig in einem > Bastel-Projekt. Eher nicht. Um sowas sollte man einen grossen Bogen machen. Wenn irgendwie möglich lieber nach einer Alternative suchen. Die gibt es. Zb. dadurch dass alle Argumente, so sie denn vom gleichen Typ sind, in ein einfaches Array gesteckt werden. Array + Größe des Arrays an die Funktion übergeben, fertig. Die Anzahl der Fehler die enstanden sind, weil bei printf bzw. scanf die tatsächlichen Argument nicht mit den Angaben im Format-String übereinstimmten, sind Legion.
> Um sowas sollte man einen grossen Bogen machen. Es gibt noch einen zweiten Grund, warum man das vermeiden will: die Parameter der variablen Liste werden immer über den Stack übergeben. Normalerweise kann der AVR-GCC aber bis zu 18 Bytes an Parametern in Registern übergeben.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.