Forum: PC-Programmierung Funktion mit variabler Anzahl an Parameter 16 Bit


von CBeginner (Gast)


Lesenswert?

Hallo. Ich möchte eine Funktion mit variabler Anzahl von 
Übergabeparametern definieren:
1
uint8_t function(uint8_t number, ...)
2
{
3
   uint8_t i=  0;
4
   uint8_t current_element = 0;
5
   va_list zeiger;  
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
   return 0;
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)?

: Bearbeitet durch User
von CBeginner (Gast)


Lesenswert?

Sorry. Mein Fehler. Habe "uint8_t current_element" geschrieben, statt 
"uint16_t current_element".

von Klaus W. (mfgkw)


Lesenswert?

Wie kommst du darauf, daß int 8 Bit hätte und long int 16?

von Klaus W. (mfgkw)


Lesenswert?

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...

von (prx) A. K. (prx)


Lesenswert?

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?

: Bearbeitet durch User
von (prx) A. K. (prx)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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)

: Bearbeitet durch User
von CBeginner (Gast)


Lesenswert?

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.
1
/* va_start example */
2
#include <stdio.h>      /* printf */
3
#include <stdarg.h>     /* va_list, va_start, va_arg, va_end */
4
5
void PrintFloats (int n, int konstante, ...)
6
{
7
  int i;
8
  int val;
9
  printf ("Printing floats:");
10
  va_list vl;
11
  va_start(vl,konstante);
12
  
13
  for (i=0;i<n;i++)
14
  {
15
    val=va_arg(vl,double);
16
    printf (" [%d]",val);
17
  }
18
  va_end(vl);
19
  printf ("\n");
20
}
21
22
int main ()
23
{
24
  PrintFloats (3,99,1,2,3);
25
  return 0;
26
}
Ich erwarte die Ausgabe: "Printing floats: 1,2,3".  Korrekt?

: Bearbeitet durch User
von Klaus W. (mfgkw)


Lesenswert?

ja, va_start bekommt immer das letzte bekannte Argument vor den ...

von Karl H. (kbuchegg)


Lesenswert?

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
1
  PrintFloats (3,99,1,2,3);
werden nicht magisch double, nur weil du hier
1
    val=va_arg(vl,double);
sie als solche abholst.

: Bearbeitet durch User
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
Noch kein Account? Hier anmelden.