Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   [Ansi C] Long in Bytes aufteilen (https://www.delphipraxis.net/101189-%5Bansi-c%5D-long-bytes-aufteilen.html)

Newbie44 9. Okt 2007 17:14


[Ansi C] Long in Bytes aufteilen
 
Hallo,

ich habe folgende Long Variable: FFEEDDCC So steht die im Speicher. Ich möchte nun das ganze irgendwie in Bytes aufteilen und in einzelne Integer Variablen reinschieben, also das sowas rauskommt

Int1 = FF
Int2 = EE
Int3 = DD
Int4 = CC

Wie mache ich das? Ich komme nicht weiter und stehe auf dem Schlauch. Kann ich das Irgendwie maskieren? Die Bitverschiebung bringt nicht wirklich viel in diesem Fall.

Ich hoffe Ihr könnt mir helfen. Ich weiß, es ist zwar ein Delphi Forum, aber es gibt doch immer Ähnlichkeiten zwischen den Sprachen.

Gruß

Sebastian

SirThornberry 9. Okt 2007 17:20

Re: [Ansi C] Long in Bytes aufteilen
 
entweder mit einer Struktur oder mit BitShifting
Code:
unsinged int my_var = 0xFFEEDDCC;
int Int1 = (my_var >> 24) & 255;
int Int2 = (my_var >> 16) & 255;
int Int3 = (my_var >> 8) & 255;
int Int4 = (my_var >> 0) & 255;

Newbie44 9. Okt 2007 17:24

Re: [Ansi C] Long in Bytes aufteilen
 
Vielen dank für deine Schnell Hilfe. Nur eines musst du mir noch erklären, warum machst du noch mit & 255 eine UND verknüpfung? Das verstehe ich noch nicht so recht, daher wäre ich dir dankbar wenn du darauf nochmal näher eingehen könntest

danke

kolbaschedder 9. Okt 2007 17:24

Re: [Ansi C] Long in Bytes aufteilen
 
Hallo,

einen eigenen Typen anlegen.

Delphi-Quellcode:
type
  MyTyp = packed record
  case a:byte of
    1 : (dw : DWord;);
    2 : (b1,b2,b3,b4 : byte;);
  end;

var test : MyTyp;

begin
  test.dw := 23420784;
  int1 := test.b1;

//usw

Dax 9. Okt 2007 17:32

Re: [Ansi C] Long in Bytes aufteilen
 
Zitat:

Zitat von Newbie44
Vielen dank für deine Schnell Hilfe. Nur eines musst du mir noch erklären, warum machst du noch mit & 255 eine UND verknüpfung? Das verstehe ich noch nicht so recht, daher wäre ich dir dankbar wenn du darauf nochmal näher eingehen könntest

Damit auch wirklich nur ein Byte im int steht. FFEEDDCC >> 8 ergibt FFEEDD, FFEEDDCC >> 8 && FF ergibt DD, und DD ist dein gewünschtes Ergebnis.

Für unions wäre das (schätze ich, hab lange kein C angefasst) so:
Code:
typedef struct {
  union {
    unsigned int inval;
    byte b1, b2, b3, b4;
  }
} int_to_bytes

int_to_bytes convert;
convert.intavl = 0xFFEEDDCC;
// convert: intval = FFEEDDCC, b1 = FF, b2 = EE, b3 = DD, b4 = CC

Newbie44 9. Okt 2007 17:35

Re: [Ansi C] Long in Bytes aufteilen
 
achso, ich kann demnach die und-verknüfung dazu benutzen um bits auch auszuschalten? ich kannte bislang nur die oder verknüpfung, speziell bei diesem beispiel:

x = x << 8 | y

also sprich den Inhalt um 8 bytes nach links schieben und den Inhalt von y anhängen. ist ja toll was man mit der und Verknüpfung alles machen kann.

ist es eigentlich wahr, dass man mit byteoperationen das Programm schneller machen kann?

Dax 9. Okt 2007 17:37

Re: [Ansi C] Long in Bytes aufteilen
 
Zitat:

Zitat von Newbie44
ist es eigentlich wahr, dass man mit byteoperationen das Programm schneller machen kann?

Das ist so wahr, wie Birnen leuchten: es kommt immer auf den Kontext an. Wenn du viel mit Bits hantierst und vorher mit div/mod gearbeitet hast, wird es schneller, wenn du aber Mathematik betreibst, wirst du dich mit Bitoperationen nur in Sackgassen manövrieren.

OregonGhost 9. Okt 2007 18:22

Re: [Ansi C] Long in Bytes aufteilen
 
Je nachdem, was "steht so im Speicher" bedeutet, kann der Union-Ansatz unter Umständen verkehrte Ergebnisse liefern. Der Shift-Ansatz hingegen funktioniert auf jedem System korrekt, ist jedoch geringfügig langsamer. Sollte der Union-Ansatz korrekte Ergebnisse liefern, kommt als Alternative auch ein Cast in Frage:
Code:
uint8_t* bytes = reinterpret_cast<uint8_t*>(&input); // C++
bzw.
uint8_t* bytes = (uint8_t*)&input; /* C */
Wenn du zur Kompilierzeit die Byte-Reihenfolge im Speicher kennst, kannst du auch den Cast-Ansatz benutzen und dann je nachdem ob Big- oder LittleEndian das Array vorwärts oder rückwärts durchlaufen.

Noch ein Tipp zu dem Verodern mit 255: Irgendwann, besonders wenn du mehr oder weniger als 8 Bit benötigst, wirst du dich mit der 255 unter Umständen selbst ins Fleisch schneiden. Lieber gleich 0xFF, da wird auf den ersten Blick klar, was passiert. (Bei C sind die Chancen realistisch, dass dein Compiler Binärdarstellung beherrscht, das ist dann eventuell auch noch eine Alternative).

Zitat:

x = x << 8 | y
Ich kann mich dunkel daran erinnern, dass die Shift-Operatoren in C++ deshalb als Stream-Operatoren missbraucht werden, weil sie recht spät ausgewertet werden. Dein Ausdruck wäre also mit Klammern sicherer, und gerade bei diesen ganzen Schiebe- und Verund- und -oderungsoperationen kommt man so leicht durcheinander, dass man lieber ordentlich klammern sollte.

Newbie44 9. Okt 2007 18:59

Re: [Ansi C] Long in Bytes aufteilen
 
Hallo nochmal, ich hab jetzt meine Funktion fast fertig, ich möchte damit einfach etwas rumprobieren in C++. Die Frage vorhin bezog sich nur auf Ansi C, diese jetzt auf Cpp. Ich hab ein problem in der Funktion:

Code:
char * longtoip(const unsigned long zahl)
{
    char ** iptmp = new char * [4];
    int i, j;
    char * ret;
    ret = new char [10];
    cout<<"Die Laenge von ret ="<<strlen(ret);
    for (i = 0, j = 24; i < 4; i++, j -=8)
    {
        iptmp[i] = new char[4];
        ltoa(((zahl >> j) & 0xFF),iptmp[i],10);
        cout<<iptmp[i]<<endl;
        cout<<"Die Stringlänge von "<<i<<" ist: "<<strlen(iptmp[i])<<endl;
    }
  return ret;
}
Wenn ich die Länge von ret zurückgeben möchte bekomme ich immer 2410. Das ist so komisch, wie kommt der auf die 24 davor? Ist nur irgendwie nicht nachvollziehbar.

Wäre euch für erneute Hilfe dankbar.

Warum immer 24? Die einzige 24 die vorkommt ist in j. Ich weiß auch das in ret nur Rubbish als Wert vorhanden ist, darum gehts mir auch im moment nicht, ich verstehe nicht warum er mir die falsche länge von ret zurückliefert.

Gruß

Sebastian.

BTW hier der Ausdruck was immer kommt:

Zitat:

Bitte Zahl eingeben:
167772161
Die Laenge von ret =2410
Die Stringlõnge von 0 ist: 2
0
Die Stringlõnge von 1 ist: 1
0
Die Stringlõnge von 2 ist: 1
1
Die Stringlõnge von 3 ist: 1
*

OregonGhost 9. Okt 2007 19:11

Re: [Ansi C] Long in Bytes aufteilen
 
Die Länge eines nicht initialisierten Strings ist nicht definiert.

Du erzeugst einen String, in dem irgendetwas drin steht. strlen() wird jedoch bis zur ersten 0 wandern und die Bytes bis dahin zählen.
Edit: Oh, und was die 24 angeht: Diese 24 ist keine 24. Im Speicher hast du eine Binärrepräsentation, deine 24 hingegen ist dezimal. Also 2410 ist nicht dasselbe wie eine 24 und eine 10.

Davon abgesehen:
1. char* gehört nicht in C++-Programm. Benutze std::string. Dasselbe gilt für Funktionen wie ltoa oder strlen.
2. In einer Funktion Speicher zu reservieren und den Zeiger darauf zurückzugeben ist schon ein wenig böse. Eher solltest du (C-Style) den Puffer als Ausgabeparameter anlegen oder (C++-Style) entweder std::string oder eine eigene Klasse verwenden.
3. Du gibst den Speicher, den du in der Schleife reservierst, niemals frei.
4. Zwei Variablen im for-Kopf zu verwenden ist zwar möglich, aber schlechter Stil. Die Lektüre von ein wenig Scott Adams oder auch des guten alten C++-FAQ Lite sollte hier Abhilfe schaffen, oder Code Complete von Steve McConnell.


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:55 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz