Forum: Mikrocontroller und Digitale Elektronik Konvertierung uint8 *pData to uint16 * pData


von Leon (Gast)


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?

von Jim M. (turboj)


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.

von A. S. (Gast)


Lesenswert?

Leon schrieb:
> Was müsste ich genau tun damit der Wert in output steht?

Eine lokale variable uint8, damit die Funktion aufrufen und später auf 
output zuweisen.

Alternativ: uint8 zurückgeben statt ptr.

von Peter D. (peda)


Lesenswert?

Leon schrieb:
> Nun soll außerhalb der Wert
> in ein uint16 gecastet werden.

Warum soll es das?
Mach doch einfach eine Zuweisung.
1
*dst_16 = *src_8;
Dadurch wird das High-Byte vorzeichenrichtig erweitert.

von EAF (Gast)


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.

von Leon (Gast)


Lesenswert?

Es soll keine weitere Variable angelegt werden.
Ich würde gerne die "uint16 output" benutzen.

von Leon (Gast)


Lesenswert?

1
test(&dataBlock, &output);

Error:
argument of type "uint16 *" is incompatible with parameter of type 
"uint8 *"

von Peter D. (peda)


Lesenswert?

Leon schrieb:
> Es soll keine weitere Variable angelegt werden.

Die Compiler sind heutzutage nicht mehr völlig dumm. Kurzlebige 
Variablen werden oft in Registern gehalten.

von Cyblord -. (cyblord)


Lesenswert?

Leon schrieb:
> Es soll keine weitere Variable angelegt werden.
> Ich würde gerne die "uint16 output" benutzen.

Kosten Variablen bei dir pro Stück? Es werden dann Variablen angelegt 
wenn es sinnvoll ist.

von EAF (Gast)


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.

von EAF (Gast)


Lesenswert?

Leon schrieb:
> Error:
> argument of type "uint16 *" is incompatible with parameter of type
> "uint8 *"
So ist es.
Und das ist auch vollkommen berechtigt.

Ein Cast macht die Sache nicht besser, nur weil es die Meldung 
vermeidet.

von Leon (Gast)


Lesenswert?

Ok. Hab nun eine weitere Variable angelegt.

von W.S. (Gast)


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.

von Cyblord -. (cyblord)


Lesenswert?

W.S. schrieb:
> 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.
Es bleibt aber Übergabe als Wert.
Gerade ein Anfänger muss das verstehen.

von foobar (Gast)


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

von Cyblord -. (cyblord)


Lesenswert?

foobar schrieb:
> In C-Lingo ist eine Referenz auf ein Objekt dessen
> Addresse resp. ein Pointer auf es.

Ja was nun? Ist die Referenz die Adresse oder der Pointer? Kann es sein 
dass deine C-Lingo nur von C-Mongos gesprochen wird?

von EAF (Gast)


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.

von Cyblord -. (cyblord)


Lesenswert?

EAF schrieb:
> 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.

Da kann ich mitgehen. Diese Definition ist wohltuend sinnvoll nach all 
dem Unsinn von W.S. und foobar.

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.