wie cast uint8_t-array von 4 auf uint32_t in c
Ich versuche zu casten ein array von uint8_t auf ein array uint32_t, aber es scheint nicht zu funktionieren.
Kann einer mir helfen auf diese. Ich brauche, um uint8_t Werte uint32_t.
Ich kann dies mit der Verschiebung, aber ich denke, es gibt eine einfache Möglichkeit.
uint32_t *v4full;
v4full=( uint32_t *)v4;
while (*v4full) {
if (*v4full & 1)
printf("1");
else
printf("0");
*v4full >>= 1;
}
printf("\n");
- Können Sie zeigen den Bau des Quell-Arrays?
- sorry, habe ich korrigiert-Typ-Fehler. Quell-array-Konstruktion in4_pton(token,-1,&v4,-1,&c); dieser wandelt eine Zeichenkette in eine ip-Adresse und legen Sie es in der v4-array
- Okay. Nicht werfen die Zeiger in einer solchen Art und Weise das Programm denkt, es ist der Blick auf einen 32-bit-Wort. Wenn Sie brauchen, um die Arbeit mit int, iterate über die original-Vektor, der die 8-bit-bytes, und weisen Sie dann das byte auf eine einfache int variable; z.B., für (int n=0; n < 4; n++) { int i = (int)v4[n]; ...}, es sei denn, Sie wollen den gesamten Vektor als kombinierte 32-bit-Wort...
- Nur um zu klären: können wir denken, dass der
v4
alsuint8_t v4[4]
, und Sie wollen, dass Sie als ein einzelnes 32-bit-Zahl?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Angesichts der Notwendigkeit, uint8_t Werte uint32_t, und die Spezifikationen auf der in4_pton()...
Versuchen, diese mit einer möglichen Korrektur des byte-Reihenfolge:
Wenn v4full ist ein Zeiger, dann die Linie
Sollte einen Fehler auslösen, oder zumindest eine compiler-Warnung. Vielleicht haben Sie zu tun bedeuten
Wo ich davon ausgehen
v4
selbst ist ein Zeiger auf eineuint8
array. Ich weiß, ich bin Extrapolation aus unvollständiger Informationen verursacht wurden...BEARBEITEN da oben zu haben scheint, behandelt ein Tippfehler, lassen Sie uns versuchen Sie es erneut.
Den folgenden code-snippet funktioniert wie erwartet - und ich glaube, Sie wollen, dass Ihr code, um zu arbeiten. Bitte kommentieren Sie diese - wie ist dieser code nicht zu tun, was Sie wollen?
Ausgabe:
Hinweis - die Reihenfolge der bytes in der gedruckten Zahl ist es Umgekehrt - Sie bekommen
04030201
statt01020304
als Sie erwartet haben könnte /wollte. Dies ist, weil meine Maschine (x86-Architektur) ist little-endian. Wenn Sie sicherstellen möchten, dass die Reihenfolge der bytes ist die Art, wie Sie es wollen (in anderen Worten, das element [0] entspricht dem höchstwertigen byte) Sie sind besser dran mit @bvj-Lösung - schalten jedes der vier bytes in der richtigen position in Ihrem 32-bit-integer.Kann man übrigens sehen, diese frühere Antwort für einen sehr effizienten Weg, dies zu tun, wenn nötig (sagt der compiler zu verwenden errichtet in der Anweisung von der CPU).
allOfIt = (uint32_t*)v4
ist illegal unter dem c99-standard. Es kann einzuführen bugs in den code entweder in der Zukunft oder sogar in aktuellen Compilern auf höheren Optimierung.union
der beiden Arten? Das wäre ein paar mehr Zeilen code...Gibt es ein problem mit deinem Beispiel - eigentlich mit dem, was Sie versuchen zu tun, (da Sie nicht wollen, dass die Schichten).
Sehen, es ist eine wenig bekannte Tatsache, aber Sie sind nicht erlaubt zu wechseln-Zeiger-Typen in dieser Weise
speziell, code wie das ist illegal:
Der einzige Fall, wo dies legal ist, ist wenn
type2
istchar
(oderunsigned char
oderconst char
etc.), aber wenntype2
beliebiger anderer Typ (uint32_t
in deinem Beispiel) es ist gegen die Norm und einführen können Fehler in Ihrem code, wenn Sie kompilieren mit-O2
oder-O3
Optimierung.Nennt sich das "strict-aliasing-Regel", und es ermöglicht Compiler davon ausgehen, dass die Zeiger der verschiedenen Arten niemals zu entsprechenden Punkte im Memory - Speicher, so dass, wenn Sie ändern die Erinnerung an einen pointer, die den compiler nicht haben, um neu zu laden, alle anderen Zeiger.
Es ist schwer für Compiler, um Instanzen zu suchen, bricht diese Regel, es sei denn, Sie machen es schmerzlich klar, es. Zum Beispiel, wenn Sie den code ändern, um dies zu tun:
und kompilieren Sie mit
-O3 -Wall
(ich verwende gcc), erhalten Sie die Warnung:So kann man nicht vermeiden, mit den Verschiebungen.
Hinweis: es wird Arbeit am unteren Optimierung der Einstellungen, und es funktioniert auch in höheren Einstellungen, wenn Sie ändern Sie nie die info Zeiger auf die von
v4
undv4_full
. Es wird funktionieren, aber es ist noch ein bug, und immer noch "gegen die Regeln".Ist dies eine Lösung:
Einem anderen Problem, das macht dieser code nicht portabel ist, dass viele Architekturen erfordern eine
uint32_t
ausgerichtet werden auf einem vier-byte-Grenze, sondern ermöglichenuint8_t
zu haben, eine Adresse angeben. Der Aufruf dieses Codes auf einer falsch ausgerichteten array würde dann der schaltplanbearbeitung zu undefiniertem Verhalten wie z.B. Absturz des Programms mitSIGBUS
. Auf diesen Maschinen, ist die einzige Möglichkeit zum umwandeln eines beliebigenuint8_t[]
zu einemuint32_t[]
istmemcpy()
den Inhalt. (Wenn Sie dies tun, in einem vier-byte-Blöcken, sollte der compiler optimieren, um je nachdem, welcher einen nichtlinearen Last-oder zwei-Lasten-und-eines-shift ist effizienter auf Ihre Architektur.)Wenn Sie haben die Kontrolle über die Erklärung des source-array, können Sie
#include <stdalign.h>
und dann erklärenalignas(uint32_t) uint8_t bytes[]
. Die klassische Lösung ist, um zu erklären, sowohl das byte-array und die 32-bit-Werte als Mitglieder einerunion
- und type-pun zwischen Ihnen. Es ist auch sicher zu bedienen Zeiger eingeholtmalloc()
, denn diese sind garantiert passend ausgerichtet.Eine weitere Lösung:
Hier verwenden wir das Ergebnis der
in4_pton
Funktion (ip
) ohne zusätzliche Variablen und Gussteilen.user2714949
die Frage nach nutzen Ergebnisin4_pton
. Meine Antwort ist ein weiterer Ansatz, um diese Funktion zu nutzen, ohne zusätzliche Variablen und Gussteilen.