Hallo. Ich möchte eine Funktion mit variabler Anzahl von
Übergabeparametern definieren:
1
uint8_tfunction(uint8_tnumber,...)
2
{
3
uint8_ti=0;
4
uint8_tcurrent_element=0;
5
va_listzeiger;
6
va_start(zeiger,number_of_bytes);
7
for(i=0;i<number_of_bytes;i++)
8
{
9
current_element=va_arg(zeiger,int);
10
fprintf("%d\n\r",current_element);
11
}
12
va_end(zeiger);
13
return0;
14
}
Mit 8 Bit Zahlen funktioniert die Funktion ( z.B. function(3,1,2,3);).
Mit 16 Bit Zahlen funktioniert sie nicht. Es gibt einen Überlauf ( z.B.
function(3,1,2,260);).: Angezeigt wird "1,2,4", also bei der Zahl 260 >
256 der Überlauf 4.
Ich habe nun versucht die Funktion auf 16-Bit zu erweitern, indem ich
die Zeile
current_element = va_arg(zeiger,int)
gegen die Zeile
current_element = va_arg(zeiger,long int) ausgetauscht habe.
Ich weiß nun nicht wie das intern läuft. Der Zeiger zeigt ja auf mein
erstes Element meines Stacks. Dieser ist ja stets 8 Bit breit. Eine
16-Bit Variable wird ja aufgeteilt auf zweimal acht bit. Nun die Frage:
Kann ich es überhaupt auf 16 Bit Zahlen erweitern?
Wenn das geht, kann der Funktionsaufruf auch wie folgt aussehen:
function(8BitInt, 16BitInt,8BitInt,8BitInt,8BitString)?
P.S.: es kann natürlich sein, ist aber unwahrscheinlich.
Genauer gesagt, kann das auf jedem System anders sein - du musst dir
klar sein, auf welchem System du arbeitest, bevor du von bestimmten
Bitlängen ausgehst.
Und dann viellleicht auch noch verraten, welches System du hast...
CBeginner schrieb:> Sorry. Mein Fehler. Habe "uint8_t current_element" geschrieben, statt> "uint16_t current_element".
Könntest du mal versuchen, einen Code zu zeigen, der grössere
Ähnlichkeit mit dem hat, wo das Problem auftritt? Es ergibt einfach
keinen Sinn, seitenlang irrelevante Fehler in Pseudocode zu suchen, der
nur entfernte Ähnlichkeit mit dem wirklichen Code hat. Das war nämlich
nicht dein einziger Fehler.
Da es in "PC Programmierung" steht: Darf man als Plattform einen PC
annehmen?
CBeginner schrieb:> Eine 16-Bit Variable wird ja aufgeteilt auf zweimal acht bit.
Wenn der Compiler ANSI lieb hat, dann ist das in diesem Kontext
garantiert nicht so. Denn Varargs werden mindestens als "int" übergeben,
da gibts keine kleineren Typen.
CBeginner schrieb:> uint8_t function(uint8_t number, ...)> va_start(zeiger,number_of_bytes);> for(i = 0; i < number_of_bytes; i++)
Kann es sein, dass du vollkommen missverstanden hast, was va_start für
eine Aufgabe hat und welche Bedeutung das 2-te Argument zu va_start
wirklich hat?
> Ich weiß nun nicht wie das intern läuft. Der Zeiger zeigt ja auf mein> erstes Element meines Stacks.
Mag sein. Was die va_list genau repräsentiert, interessiert eigentlich
nicht wirklich. Dazu gibt es ja va_start, damit man den Mechanismus
dahingehend informiert, welches das letzte benannte Argument in der
Argumentliste war, wo also mittels va_arg die nächsten Argumente
abgeholt werden sollen.
Vielleicht mal die Doku und ein Beispiel dazu studieren? Das dürfte
einiges klären.
http://www.cplusplus.com/reference/cstdarg/va_start/
(und das wiederholen der impliziten Konvertierungsregeln bei
Funktionsaufrufen, die bei variadischen Funktionen wirksam werden,
könnte auch nicht schaden. Sonst wird das nämlich nichts)
Die Funktion teste ich aber gerade auf dem PC.
Ich habe mir das Beispiel angeschaut. Funktioniert auch soweit. Nun eine
weitere Frage:
Angenommen ich habe eine Funktion: funktion(AnzahlVariablen, Konstante,
...).
Bezogen auf das im Link genannte Beispiel würde ich dann denken, dass
ich ich den Zeiger diesesmal auf "konstante" und nicht auf "n" setze.
(-> va_start(vl,konstante);) Das ist ja diesesmal meine gewünschte
Anfangsadresse.
CBeginner schrieb:> Ich erwarte die Ausgabe: "Printing floats: 1,2,3". Korrekt?
Nein, nicht korrekt.
Zumindest nicht so, wie du das erwartest.
Das hier
1
val=va_arg(vl,double);
passt mit dem hier
1
PrintFloats(3,99,1,2,3);
nicht zusammen.
Mehr Sorgfalt! Auch in der Zusammenstellung der Beispiele, über die du
Auskunft haben willst.
Mit variadischen Funktionen sind alle Sicherheitsmechanismen
ausgeschaltet. Aus den int hier