Gast
#2894548
Hallo, ich will eine long Variable in ein char Array umwandeln, sodass ich die 4 Bytes der long Variable einzeln verwenden kann und bin überfragt(Anfänger).Ich hoffe ihr könnt mir helfen. Danke
|
Anzeige
|
Long in char Array umwandeln
Gast
#2894548
Hallo, ich will eine long Variable in ein char Array umwandeln, sodass ich die 4 Bytes der long Variable einzeln verwenden kann und bin überfragt(Anfänger).Ich hoffe ihr könnt mir helfen. Danke
Gast
#2894569
Das wäre die Big-Endian-Reihenfolge. Wenn es andersrum sein soll, entsprechend die Positionen bzw. Shifts tauschen.
Gast
#2894581
union convert
{
char mychar[4];
long mylong
} c;
unsigned char bitte. Für Bytes niemals char verwenden! Bei char überlässt du es dem Compiler, ob da ein Vorzeichen angenommen werden soll oder nicht. Das ist aber nicht das, was man bei Bytes haben will. Bei Bytes gibt es kein Vorzeichen. Daher: sag das auch deinem Compiler und überlasse es nicht dem Zufall bzw. dem Compilerhersteller ob das so ist oder nicht. Das unsigned kostet dich nichts, kann dich aber vor schwer zu findenden Fehlern bewahren, wenn der Compiler Default eben nicht unsigned ist.
Gast
#2894607
Ah ja, genau danach hatte ich gesucht. Vielen Dank für die schnellen Antworten.
Gast
#2894648
Empfehlen würde ich dir auch den Datentyp uint8_t zu verwenden, unsigned char müsste nach Standard zwar sowieso sizeof(unsigned char) == 1 ergeben, aber so bist du immer auf der sicheren Seite. Dieses Type-Punning ist inspecified Behavior in C. Johann L. schrieb: > Dieses Type-Punning ist inspecified Behavior in C. Ist es nicht. Nur weil das im Standard als undefiniert beschrieben wird, heisst das noch lange nicht, dass das Verhalten irgendwie zufällig oder nicht reproduzierbar ist. Sondern nur, dass dieser Fall jeder Compiler handhaben kann wie er will (eher sein Entwickler). Der Normalfall ist, dass überschüssige Bits einfach abgeschnitten werden. Bsp.:
Zur Sicherheit das Handbuch fragen oder einfach ausprobieren. Es ist unspecified, nicht implementation defined. "Ausprobieren" ist übrigens n tolls Design Pattern...
Gast
#2896137
be stucki schrieb: > Johann L. schrieb: >> Dieses Type-Punning ist inspecified Behavior in C. > > Ist es nicht. Nur weil das im Standard als undefiniert beschrieben wird, > heisst das noch lange nicht, dass das Verhalten irgendwie zufällig oder > nicht reproduzierbar ist. Sondern nur, dass dieser Fall jeder Compiler > handhaben kann wie er will (eher sein Entwickler). Undefiniertes Verhalten heißt auch, daß er es gar nicht explizit handhaben muß, so daß eben das rauskommt, was sich aus irgendwelchen anderen Umständen ergibt, auch wenn das sich je nach Compiler-Parametern, Optimierung oder anderen Dingen unterschiedlich verhält. Der Compiler-Bauer muß sich schlicht überhaupt nicht drum kümmern und nicht mal drüber nachdenken, was denn in dem Fall passiert. Johann L. schrieb: > Es ist unspecified, nicht implementation defined. Immerhin darf man aber jedes Objekt in ein Array aus unsigned char gleicher Größe per memcpy kopieren, also so:
Das dürfte aus ISO-C-Sicht die sauberste Variante sein und beim gcc auch nicht langsamer oder umständlicher als irgendwelche union-Verrenkungen oder Pointer-Castereien.
Gast
#2896140
Rolf Magnus schrieb: > char b[sizeof a]; Hmrpf, muß natürlich unsigned char statt char heißen.
Gast
#2896162
Rolf Magnus schrieb: > Immerhin darf man aber jedes Objekt in ein Array aus unsigned char > gleicher Größe per memcpy kopieren, also so: > long a = 1234567; > char b[sizeof a]; > > memcpy(b, a, sizeof a); > > Das dürfte aus ISO-C-Sicht die sauberste Variante sein und beim gcc auch > nicht langsamer oder umständlicher als irgendwelche union-Verrenkungen > oder Pointer-Castereien. Wenn man tatsächlich eine Kopie braucht, kann man das natürlich machen. Wenn es nur darum geht, auf einzelne Bytes zuzugreifen, erreicht man mit den "Union-Verrenkungen oder Pointer-Castereien" aber das Gleiche ohne die Daten kopieren zu müssen. Das Problem ist nur (sowohl bei memcpy, Unions und Pointercasting), dass der Code nicht portabel ist, da auf anderer Hardware die Byte-Reihenfolge anders sein kann. Beim Shiften ist die Semantik dagegen unabhängig von der Bytereihenfolge, und bei einem klugen Compiler nicht langsamer als die anderen Methoden.
Gast
#2896215
Streng genommen müsste man die Bits auf der linken Seite auch noch ausmaskieren, weil ja nicht garantiert ist, dass ein char 8 Bit breit ist:
Das sollte dann wirklich koscher sein. Wenn man es öfters braucht, kann man es ja in ein Macro verpacken.
Gast
#2896340
xfr schrieb: > Wenn man tatsächlich eine Kopie braucht, kann man das natürlich machen. > Wenn es nur darum geht, auf einzelne Bytes zuzugreifen, erreicht man mit > den "Union-Verrenkungen oder Pointer-Castereien" aber das Gleiche ohne > die Daten kopieren zu müssen. Bei der Union mußt du auch kopieren, es sei denn, du verpackst gleich den ursprünglichen long in die Union rein. Ggf. mußt du da sogar zweimal kopieren, nämlich einmal den long in die union, dann das Ergebnis wieder raus in das Ziel-Array. > Das Problem ist nur (sowohl bei memcpy, Unions und Pointercasting), dass > der Code nicht portabel ist, da auf anderer Hardware die > Byte-Reihenfolge anders sein kann. Beim Shiften ist die Semantik dagegen > unabhängig von der Bytereihenfolge, und bei einem klugen Compiler nicht > langsamer als die anderen Methoden. Allerdings ist auch das Rechtsschieben von negativen Werten, wie sie ein long ja haben kann, nicht portabel. Rolf Magnus schrieb: > Allerdings ist auch das Rechtsschieben von negativen Werten, wie sie ein > long ja haben kann, nicht portabel. Also long erst in einen unsigned long casten, dann schieben ;-) Ich werfe diesen Vorschlag noch ins Feuer:
Dann kann man mit b[0] bis b[3] auf die 4 Bytes lesend zugreifen. Allerdings hat man hier weder eine Kopie noch ist diese Lösung Endian-fest, dafür aber ist sie wohl die schnellste Lösung ;-) Antwort schreibenBitte melde dich an, um einen Beitrag zu schreiben. |
Anzeige
|