Konvertierung uint8 *pData to uint16 * pData

Gast #6938069
Lesenswert?

Hallo und guten Tag,

ich habe folgendes Problem. In einer Funktion wird ein Wert als Referenz 
übergeben. Dieser Wert ist vom Type uint8. Nun soll außerhalb der Wert 
in ein uint16 gecastet werden.
1
void test(uint8* data, uint8* output);
2

3
Verwendung der Funktion:
4

5
uint16 output;
6
test(&dataBlock, (uint8*)&output);

Die Variable output muss uint16 sein. Was müsste ich genau tun damit der 
Wert in output steht?
#6938079
Lesenswert?

1
uint16_t output;
2
uint8_t tempVal;
3
test(&dataBlock, &tempVal);
4
output = tempVal;

Alles andere ist nicht portabel. Siehe auch Little Endian vs. Big 
Endian.

Der Code vom OP würde für little Endian funktionieren, wenn vorher 
output auf 0(Null) gesetzt wird.

IIRC sind aber einige µC Compiler auf Big Endian eingestellt.
Gast #6938110
Lesenswert?

Leon schrieb:
> In einer Funktion wird ein Wert als Referenz
> übergeben.

Das ist eine Pointer Übergabe, keine Referenz.

Referenzen wurden mit/in C++ eingeführt, gerade auch weil man sich mit 
Pointern schnell mal eben eine Frikadelle ans Knie nageln kann.

Mir stellen sich da Fragen!

Warum werden hier Pointer und keine Values verwendet?
Vielleicht soll der Wert, in der Funktion, geändert werden?
Und schon hat man die Frikadelle am Knie, wenn man eine 8 Bit Variable 
mit einem 16Bit Wert überschreibt.
Gast #6938134
Lesenswert?

Leon schrieb:
> Es soll keine weitere Variable angelegt werden.
Gibt es einen Grund dafür?

Leon schrieb:
> Ich würde gerne die "uint16 output" benutzen.
Dann bau die Funktion um.

Was ist ist eine "gute" Funktion?

1. Sie bekommt ihre Werte über Parameter.
2. Sie gibt ihre Ergebnisse per return zurück.
3. Sie verhält sich bei  gleichen Parametern immer gleich.
4. Sie hat keine Seiteneffekte.

Deine Funktion verstößt so schon gegen 3 und 4.
Gut, in C gehts wohl nicht immer ohne Pointer...

Aber der Typedreher ist eine Frikadelle


Ohne Kontext, sehe ich keine Möglichkeit das ordentlich zu lösen.
Gast #6938486
Lesenswert?

Leon schrieb:
> ich habe folgendes Problem.

Nö, du hast 2 ganz andere Probleme:

1. Du verstehst nicht, was du schreibst
2. Du castest zuviel.

Die Übergabe eines Funktionsarguments kann entweder als Wert oder als 
Referenz erfolgen. In C ist letzteres eben ein Zeiger auf diejenige 
Variable, die das Argument sein soll (ist in Pascal eigentlich genau so, 
bloß sieht man da den Zeiger nicht).

Die aufgerufene Funktion bestimmt dabei den Typ. Casten an dieser Stelle 
ist schlichtweg ein Fehler. Aus diesem Grunde gibt es in C die 
Headerdateien, wo drinsteht, welche Art von Argument(en) die betreffende 
Funktion haben will und was sie als Ergebnis zurückliefert.

W.S.
Gast #6938531
Lesenswert?

>> Die Übergabe eines Funktionsarguments kann entweder als Wert oder als
>> Referenz erfolgen.
>
> Und das ist grob falsch. C kennt nur Übergabe als Wert. Man kann einen
> Pointer übergeben (als Wert!!!) als Workaround für die fehlende Übergabe
> per Referenz.

Ist es nicht.  In C-Lingo ist eine Referenz auf ein Objekt dessen 
Addresse resp. ein Pointer auf es.  Da kannst du noch so auf den Boden 
stampfen und meckern, dass das nicht der C++-Definition einer Referenz 
entspricht ...
Gast #6938624
Lesenswert?

Cyblord -. schrieb:
> Ja was nun? Ist die Referenz die Adresse oder der Pointer?

Bei einem Pointer spricht man ja auch von Dereferenzierung.
Der Pointer ist somit eine Referenz auf die Variable, Funktion, oder was 
auch immer. Pointer zu sein, ist seine Natur, Referenz zu sein, eine 
Eigenschaft.

Erst  mit C++ ist man gezwungen konkreter zu formulieren, denn da gibt 
es einen semantischen Unterschied. Auch hier ist eine Referenz immer 
noch eine Adresse oder Pointer, aber nur im Hintergrund, nicht mit der 
Präsenz, wie in C.

Aber davon ab, in C++ würde man da sicherlich keine Pointer übergeben, 
sondern Referenzen bevorzugen. Zudem nicht casten oder einen Type Wrap 
drum rum basteln, sondern die Funktion überladen, auch gerne mehrfach.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren