Forum: PC-Programmierung Zuweisung zwischen unterschiedlichen Pointern


von hausmeister (Gast)


Lesenswert?

Moin,

habe da ein Problem. Ich habe ein Array uint8_t array[8] und eine 
Variable
uint64_t *var.
Nun möchte ich gern die 64 Bits des Arrays in der Variable haben. Es 
sollte doch eigentlich heißen var = (uint64_t)array ? Da meckert er 
aber. Schreibe ich var = (uint64_t*)array, verschwindet zwar die 
Fehlermeldung, aber funktionieren tuts immer noch nich :(

: Verschoben durch Admin
von Karl H. (kbuchegg)


Lesenswert?

hausmeister schrieb:

> Nun möchte ich gern die 64 Bits des Arrays in der Variable haben. Es
> sollte doch eigentlich heißen var = (uint64_t)array ?

No-
Warum sollte es das?

uint64_t   ist ein Datentyp, bei dem eine deratige Variable aus 64 Bit 
besteht.

> Nun möchte ich gern die 64 Bits des Arrays in der Variable haben
In welcher?
In 'var'.
Das kann nicht gehen. var ist eine Pointer Variable. Die speichert 
Speicheradressen, aber keine Werte.

> Da meckert er
> aber. Schreibe ich var = (uint64_t*)array,

Das ist aber etwas anderes.
Das hier sagt
Nimm die Adresse von array und jetzt tun wir mal so, also ob dieser 
Adresse die Adresse eines 64 Bit Datentyps wäre.

Und diese Adresse wird in var abgelegt. Die Adresse(!), nicht das worauf 
diese Adresse verweist.


> verschwindet zwar die
> Fehlermeldung, aber funktionieren tuts immer noch nich :(

'funktioniert nicht' ist keine sehr aussagekräftige Fehlermeldung.

"Hilfe, mein Auto funktioniert nicht"
"Doktor, es tut weh"
"Installateur, ich hab Wasser"

All das sind 'Fehlermeldungen' bzw. 'Hilferufe' mit denen der 
angesprochene nichts anfangen kann um damit am Problem zu arbeiten.

von Albert .. (albert-k)


Lesenswert?

Du kannst nicht einfach ein array aus 8 Einzelteilen in eine 64 bit 
Variable casten. Du musst über Schiebe und ODER Operationen deinen 64 
bit Wert aus den einzelnen zusammensetzen.

In etwa auf folgende Art und Weise (nicht kontrolliert)
1
for(i=0;7;i++){
2
*var=(*var)|(array[i]<<i*7);
3
}

von hausmeister (Gast)


Lesenswert?

Hallo Karl Heinz Buchegger,

ich bin der Meinung, dass ich mein Problem genau genug beschrieben habe. 
Als Hilfe wäre mir die eine Zuweisungszeile ("Nun möchte ich gern die 64 
Bits des Arrays in der Variable haben") genug. Solltest du jedoch nicht 
herauslesen können, worum es mir geht, dann frage ich mich, wie du es 
hier zum Mod geschafft hast.

Dein Posting mit deinen Belehrungen hilft weder mir noch Anderen weiter 
und verschwendet deine, meine und die Zeit der Anderen, die erst den 
ganzen Unsinn lesen müssen, bis sie zum Ergebnis kommen. Auch ist mir 
nicht klar, warum du mir erklärst, welchem Typ ein uint64_t entspricht. 
Danach habe ich nicht gefragt.

von hausmeister (Gast)


Lesenswert?

Um es noch einmal unmissverständlich auszudrücken:

In var möchte ich die Adresse vom ersten Bit des Array haben, also den 
Wert von array.

von Peter II (Gast)


Lesenswert?

hausmeister schrieb:
> In var möchte ich die Adresse vom ersten Bit des Array haben, also den
> Wert von array.

ein bit hat keine Adresse. Außerdem ist das ganze abhängig von der 
Platform. Litte Endian oder Big Endian.

von hausmeister (Gast)


Lesenswert?

Falls das so geht.. Wahrscheinl. nicht, denn das Array verliert seine 
Gültigkeit beim Verlassen der Funktion.. Ich teste mal den Vorschlag von 
Albert.

von Karl H. (kbuchegg)


Lesenswert?

hausmeister schrieb:

> Dein Posting mit deinen Belehrungen hilft weder mir noch Anderen weiter
> und verschwendet deine, meine und die Zeit der Anderen,

Da hast du recht.
Daher die Standardantwort:
Du brauchst ein C-Buch, das du dann auch studieren musst.
Warum soll ich mir die Mühe machen und dir etwas erklären, was du in 
jedem C-Buch ausführlichst finden kannst?

> warum du mir erklärst, welchem Typ ein uint64_t entspricht.
> Danach habe ich nicht gefragt.

Warum wirfst du dann die Dinge durcheinander, wenn du das eh alles 
weißt?

von hausmeister (Gast)


Lesenswert?

"ein bit hat keine Adresse."

Verzeihung, ich meinte natürlich Byte...

von hausmeister (Gast)


Lesenswert?

Karl Heinz Buchegger,

du hast Recht. Was machst du dann hier? Wofür gibt es das Forum? Beides 
wird nicht gebraucht, da es ja Bücher gibt... Warum überhaupt 
programmieren, wenn man doch auch am Strand liegen kann?!

Dein 2. Post hat wieder nichts zur Sache beigetragen. Wer hat dich zum 
Mod gemacht?

von Peter II (Gast)


Lesenswert?

hausmeister schrieb:

erklär uns doch mal wie man jemand weiter helfen soll, der nicht mal 
sagen kann WAS NICHT GEHT.

> verschwindet zwar die Fehlermeldung, aber funktionieren tuts
> immer noch nich

von hausmeister (Gast)


Lesenswert?

Und woher kommt deine falsche Annahme, dass ich alles weiß? Würde ich 
alles wissen, würde ich hier nicht fragen. Allerdings habe ich NICHT 
danach gefragt, was ein uint64_t ist!

Macht es dir eigentlich Spaß, den Oberlehrer raushängen zu lassen und 
nicht auf die Fragen einzugehen? Bisher habe ich die Leute hier im Forum 
als kompetent angesehen, nun kenn ich dich...

Und Peter: was verstehst du bei "Nun möchte ich gern die 64 Bits des 
Arrays in der Variable haben" nicht? Wenn ich dann schreibe, dass es 
nicht geht, dann wird das Ergebnis wohl sein, dass in der Variable (für 
die neunmalklugen hinter der Adresse, welche in var gespeichert ist) 
nicht die 64 Bit aus dem Array stehen. Desweiteren bin ich der Meinung, 
mit meinen Codebeispielen zum Ausdruck gebracht zu haben, wo meine 
Wissenslücken sind. Diese liegen NICHT in der Interpretation von *var 
oder var usw, sondern in dieser einen Zuweisung (falls es eine solche 
gibt)

In diesem Zusammenhang Danke an Albert, welcher als einziger verstanden 
hat, worum es mir geht. Und ich bin mir sicher, der Rest hat es auch 
verstanden, kommt aber vor lauter Arroganz nicht zum Punkt..

von Karl H. (kbuchegg)


Lesenswert?

Peter II schrieb:
> hausmeister schrieb:
>
> erklär uns doch mal wie man jemand weiter helfen soll, der nicht mal
> sagen kann WAS NICHT GEHT.

Hab ich ihn schon gefragt.
Er ist allerdings der Ansicht, das braucht er nicht kundzutun.

von beautiful guy (Gast)


Lesenswert?

@hausmeister kauf dir ein C Buch und gib ruhe!

von Karl H. (kbuchegg)


Lesenswert?

hausmeister schrieb:

> nicht die 64 Bit aus dem Array stehen. Desweiteren bin ich der Meinung,
> mit meinen Codebeispielen zum Ausdruck gebracht zu haben, wo meine
> Wissenslücken sind.

Nope.
Dein Problem kann auf mehrere Arten gelesen werden, wobei du es 
geschafft hast, mehrere mögliche Interpretationen komplett durcheinander 
zu werfen. Und das nicht ganz unbedeutende Detail, dass das Array in 
einer Funktion steckt, ist dann auch nicht ganz unwichtig, wenn man mit 
Adressen von Arrays um sich wirft.

Persönlich bin ich ja der Meinung, dass du eigentlich nach

   uint64_t var = *(uint64_t*)array;

suchst, aber um sicher zu gehen, fehlen da halt ein paar Angaben. 
Nachher hab ich dann wieder die schlechte Nachrede, nicht eine zum 
Problem passende Lösung geliefert zu haben, nur weil ich falsch geraten 
habe.

Aber du schreibst ja lieber ellenlange Beschimpfungen, anstatt endlich 
mal eine komplette Fehlerbeschriebung bzw. eine Beschriebung dessen was 
du eiegentlich wirklich bezwecken willst, zu liefern.

von hausmeister (Gast)


Lesenswert?

Ich wiederhole mich gern:

Ich habe ein Array uint8_t array[8] und eine Variable uint64_t *var.

Ich möchte gern, dass die in dem Array enthaltenen 64 Bit nach einer 
Anweisung bzw etwas Code an der Adresse stehen, auf die var verweist.

&var übergebe ich einer Funktion, in der Funktion wird das array gefüllt 
und nach Verlassen der Funktion möchte ich hinter var die 64 Bit 
wiederfinden.


PS: "Aber du schreibst ja lieber ellenlange Beschimpfungen.."

Hättest du deine Bemerkungen

"Hilfe, mein Auto funktioniert nicht"
"Doktor, es tut weh"
"Installateur, ich hab Wasser"

gelassen, wäre die Unterhaltung sicher anders verlaufen.

von Karl H. (kbuchegg)


Lesenswert?

hausmeister schrieb:

> Ich möchte gern, dass die in dem Array enthaltenen 64 Bit nach einer
> Anweisung bzw etwas Code an der Adresse stehen, auf die var verweist.

Aha.
Das ist jetzt Version 3, von dem was du möchtest

   *var = *(uint64_t*)array;

Aber bitte, wir können noch ewig so weiter tun und Sterne in dieser 
Anweisung verteilen bzw. rausnehmen.

> gelassen, wäre die Unterhaltung sicher anders verlaufen.

Ändert nichts daran, dass 'funktioniert nicht' keine vernünftige 
Fehlermeldung ist. Genausowenig wie die 3 Beispiele vernünftige Anfragen 
nach Hilfe beim jeweiligen Gegenüber sind. Wenn du das nicht verstehst, 
solltest du vielleicht mal etwas mehr in dich gehen und dich fragen 
warum andere Leute immer so schlecht erraten, was du eigentlich sagen 
willst aber nicht gesagt hast.

von hausmeister (Gast)


Lesenswert?

"Ändert nichts daran, dass 'funktioniert nicht' keine vernünftige
Fehlermeldung ist"

Wenn es eine Fehlermeldung gegeben hätte, hätte ich sie gepostet. Wie du 
ganz oben lesen kannst, habe ich das bereits geschrieben:
"Schreibe ich var = (uint64_t*)array, verschwindet zwar die 
Fehlermeldung, aber funktionieren tuts immer noch nich"

Das meine ich so wie ichs geschrieben habe: es kompiliert und wird ohne 
Probleme ausgeführt, nur ist eben das Ergebnis nicht so, wie ichs 
möchte. Aber ich glaube ich habe jetzt langsam erkannt, worauf du hinaus 
wolltest: Anstelle deiner abwertenden Kommentare hättest du einfach 
fragen können, wie das Verhalten meines Programmes ist. Da du dich 
leider so undeutlich ausgedrückt hast, konnte ich nur erraten, worum es 
dir ging.

Dennoch würde mich eins interessieren. Ausgangspunkt sind zwei 
Datenstrukturen mit eindeutiger Definition:

uint8_t array[8]
uint64_t *var

gewünschtes Ergebnis: Inhalt des Arrays soll über die Variable 
wiederzufinden sein.

Mein Versuch "var = (uint64_t)array" deutet es doch auch an, was ich 
will.

var enthält einen Zeiger, genauso wie array. Da array einen uint8_t und 
var einen uint64_t enthält, wollte ich eben noch casten.

Was genau versteht man nun daran nicht?

Anhand des Hinweises von Albert (er hat weder beidigt, noch sich über 
zuwenig Infos beschwert und dennoch sofort erkannt, worin mein Problem 
liegt.) habe ich übrigens die Lösung erarbeitet:

*val = (*val)|(uint64_t)temp[i]<<(56-(i*8));

Vielleicht kann ja nun ein Mod das ganze unnütze Gewäsch entfernen und 
den Thread auf die sinnvollen Informationen beschränken.

Merci an alle, die sich beteiligt haben, mir zu helfen!

von Ralf G. (ralg)


Lesenswert?

Was Karl Heinz aus dir die ganze Zeit herausholen will, ist: was du 
wirklich meinst!

hausmeister schrieb:
> gewünschtes Ergebnis: Inhalt des Arrays soll über die Variable
> wiederzufinden sein.

hausmeister schrieb:
> Nun möchte ich gern die 64 Bits des Arrays in der Variable haben.

Das sind zwei verschiedene Dinge!!

Für die obere, von dir zuletzt gepostete Variante, ist
1
var = (uint64_t*)array;
die korrekte Zuweisung!

von hausmeister (Gast)


Lesenswert?

BTW:

*val = *((uint64_t*)temp);

funktioniert auch.

Man setze val = var und temp = array, um auf meine oben genannten 
Deklarationen zu kommen.

von Peter II (Gast)


Lesenswert?

hausmeister schrieb:
> *val = *((uint64_t*)temp);

wobei hier nicht nicht Big/Little Endian berücksichtig wird.

hier schon

> *val = (*val)|(uint64_t)temp[i]<<(56-(i*8));

von hausmeister (Gast)


Lesenswert?

"Das sind zwei verschiedene Dinge!!"

Ok, man möge mir meinen ungenauen Wortlaut verzeihen. Eine gezielte 
Frage hätte hier sicherlich mehr geholfen, als Oberlehrermimik von einem 
Mod.

von Karl H. (kbuchegg)


Lesenswert?

hausmeister schrieb:

> Das meine ich so wie ichs geschrieben habe: es kompiliert und wird ohne
> Probleme ausgeführt, nur ist eben das Ergebnis nicht so, wie ichs
> möchte.

Oft ist es hilfreich, anhand eines konkreten Beispiels (mit realen 
Zahlen) zu zeigen
* was willst du eigentlich
* was passiert statt dessen


> Dennoch würde mich eins interessieren. Ausgangspunkt sind zwei
> Datenstrukturen mit eindeutiger Definition:
>
> uint8_t array[8]
> uint64_t *var
>
> gewünschtes Ergebnis: Inhalt des Arrays soll über die Variable
> wiederzufinden sein.
>
> Mein Versuch "var = (uint64_t)array" deutet es doch auch an, was ich
> will.

Eben nicht.
Es gibt unzählige Variationen, was man aus diesen Angaben machen kann.

> var enthält einen Zeiger, genauso wie array.

array ist KEIN Zeiger.
array kann in manchen Zusammenhängen wie einer benutzt werden. Aber er 
IST kein Zeiger.
Das ist ein wichtiger Unterschied!

> Da array einen uint8_t und
> var einen uint64_t enthält, wollte ich eben noch casten.

array enthält VIELE uint8_t. Aber die Nennung des Array-Names alleine, 
ohne Indizierung, liefert die Startadresse des Arrays.
(Das folgende stimmt jetzt nicht ganz, ist aber für die weitere 
Betrachtung unerheblich)
Diese Startadresse hat, wie alle Adressen, einen Pointer Datentyp.
Eine Adresse kann man nur in einer Pointer Variablen speichern. Dann 
wird dort aber die Adresse gespeichert, nicht das, was unter dieser 
Adresse im Speicher zu finden ist. Dazu müssen die Datentypen 
übereinstimmen.

Mal ohne Cast

  uint8_t array[8]
  uint64_t *var

  var = array;

welcher Datentyp steht links vom = ?
Das steht 'var' und 'var' hat den Datentyp uint64_t*
Welcher Datentyp steht rechts vom = ?
Da steht 'array'. 'array' hat den Datentyp uint8_t[], welcher in diesem
Kontext automatisch zu einem uint8_t* konvertiert wird.

Die Anweisung in Datentypen Form geschrieben, sieht also so aus.

   uint64_t* = uint8_t*;

und das passt nicht. Einen uint8_t-Pointer kann man nicht auf einen 
uint64_t-Pointer zuweisen.
Aber man kann den Compiler mit einem Cast ruhigstellen, indem man die 
Basistypen der Pointer anpasst. Aus dem uint8_t-Pointer muss ein 
uint64_t-Pointer werden. Wie schreibt sich das? Ganz normal in Pointer 
Syntax, so wie man eben den Datentyp eines Pointers schreibt.

  uint64_t* = (uint64_t*)uint8_t*;

jetzt, mit dem Cast, passen die Datentypen. Zurück zu den Variablen hatr 
man also

  var = (uint64_t*)array;

soweit so gut. Aber: Das hier speichert die Adresse von array in der 
Variablen var ab. Da ist kein Transfer von Datenbytes involviert.

D.h. DAS ist (anscheind) NICHT das, was du eigentlich willst.

> Vielleicht kann ja nun ein Mod das ganze unnütze Gewäsch entfernen und
> den Thread auf die sinnvollen Informationen beschränken.

Das einzig Sinnvolle in diesem Thread ist, das dein C zu schwach ist um 
die Unterschiede in dem was du schreibst zu erkennen und deine 
Ausdrucksweise zu sehr zu wünschen übrig lässt als das man aus deinem 
Geschreibsel eindeutig erraten kann, was du eigentlich wirklich machen 
willst.

von Ralf G. (ralg)


Lesenswert?

Karl Heinz Buchegger schrieb:
> var = (uint64_t*)array;
>
> soweit so gut. Aber: Das hier speichert die Adresse von array in der
> Variablen var ab. Da ist kein Transfer von Datenbytes involviert.
>
> D.h. DAS ist (anscheind) NICHT das, was du eigentlich willst.

wahrscheinlich doch:
hausmeister schrieb:
> Um es noch einmal unmissverständlich auszudrücken:
>
> In var möchte ich die Adresse vom ersten Bit des Array haben, also den
> Wert von array.

Allerdings:
hausmeister schrieb:
> Und Peter: was verstehst du bei "Nun möchte ich gern die 64 Bits des
> Arrays in der Variable haben" nicht?
Und hier noch anders:
hausmeister schrieb:
> Ich möchte gern, dass die in dem Array enthaltenen 64 Bit nach einer
> Anweisung bzw etwas Code an der Adresse stehen, auf die var verweist.

von Karl H. (kbuchegg)


Lesenswert?

Ralf G. schrieb:

>> D.h. DAS ist (anscheind) NICHT das, was du eigentlich willst.
>
> wahrscheinlich doch:

Vielleicht soll ja auch alle 3 Bedingungen simultan gelten.

Ich denke, es ist ihm gar nicht bewusst, dass er da 3 sich 
widersprechende Angaben gemacht hat, was er eigentlich will.
Er weiß nur, dass er vom Oberlehrer keine Belehrung will.

von Klaus W. (mfgkw)


Lesenswert?

hausmeister schrieb:
> Dein 2. Post hat wieder nichts zur Sache beigetragen. Wer hat dich zum
> Mod gemacht?

Manchmal frage ich mich, wie es manche überhaupt bis zum Hausmeister 
schaffen.

(Falls er es überhaupt soweit gebracht hat.)

von Uwe (de0508)


Lesenswert?

Hallo,

ich werfe man eine weiter Möglichkeit eine 64-Bit Variable in 8 Bit (1 
Byte) Häppchen an zu sprechen in den (Welt-)Raum.

UNiON
1
typedef union {
2
 uint64_t   o;        // Oktal Byte = 8*sizeof(Byte) = 8*8
3
 uint8_t    b[8];     // Index E {0,..,7}
4
} union_64bit_t;
5
6
union_64bit_t my_var;
7
8
// Zugriff
9
uint64_t u_64data = my_var.o;
10
uint8_t u_8data = my_var.b[0];

1
// Zugriff auf die Adresse
2
uint8_t * u_8data_pt = &my_var.b[0];

_

von Yalu X. (yalu) (Moderator)


Lesenswert?

Hier ist auch noch mein Senf zum Thema ;-)

hausmeister schrieb:
> habe ich übrigens die Lösung erarbeitet:
>
> *val = (*val)|(uint64_t)temp[i]<<(56-(i*8));

Freut mich, dass du die Lösung gefunden hast. Aber schau dir doch noch
einmal deine vorherigen Aussagen an, vielleicht merkst du dann, warum
keiner der Leute hier erraten hat, was du eigentlich wolltest:

hausmeister schrieb:
> Nun möchte ich gern die 64 Bits des Arrays in der Variable haben.

Nein. Du möchtest die 64 Bits da haben, wo die Variable hinzeigt.
In der Variable selbst haben die 64 Bits gar nicht Platz, wenn es sich
nicht gerade um ein 64-Bit-System handelt.

hausmeister schrieb:
> In var möchte ich die Adresse vom ersten Bit des Array haben,

Nein. Dass Bits keine Adresse haben, wurde ja schon geschrieben.

> also den Wert von array.

Nein. Der Wert von array (wenn man den Namen ohne sizeof-Operator in
einem Ausdruck verwendet) ist die Adresse des ersten Array-Elements
(genauer gesagt der Wert des Zeigers auf das erste Element). Den willst
und brauchst du aber nicht.

hausmeister schrieb:
> Verzeihung, ich meinte natürlich Byte...

Nein. Auch das wolltest du nicht (s.o.).

hausmeister schrieb:
> In diesem Zusammenhang Danke an Albert, welcher als einziger verstanden
> hat, worum es mir geht.

Ich glaube eher, er hat als einziger richtig geraten ;-)

hausmeister schrieb:
> Ich möchte gern, dass die in dem Array enthaltenen 64 Bit nach einer
> Anweisung bzw etwas Code an der Adresse stehen, auf die var verweist.

Jetzt erst kommt so langsam etwas Licht ins Dunkel.

hausmeister schrieb:
> Mein Versuch "var = (uint64_t)array" deutet es doch auch an, was ich
> will.
>
> var enthält einen Zeiger, genauso wie array. Da array einen uint8_t und
> var einen uint64_t enthält, wollte ich eben noch casten.
>
> Was genau versteht man nun daran nicht?

Diese Beschreibung legt nahe, dass du einen Zeiger und nicht den Inhalt,
auf den er zeigt, kopieren möchtest, also so etwas in der Art:

  var = (uint64_t *)array;

Aber auch das ist offensichtlich nicht das, was du wolltest.


Genereller Tipp: Genauso wie nicht jeder perfekt programmieren kann,
liegt es auch nicht jedem, ein Problem klar darzustellen. Wenn man
(vielleicht auch auf etwas saloppe Art) darauf hingewiesen wird, dass
die Problembeschreibung unvollständig ist, ist die korrekte Reaktion
eine ausführlichere Beschreibung und nicht

> ich bin der Meinung, dass ich mein Problem genau genug beschrieben habe.

Bei einem schwer zu beschreibenden Problem hilft es oft, ein paar
Hintergrundinformationen zu liefern. In diesem Fall: Wofür stehen die 8
Bytes im Array? Wo kommen sie her? Was wird anschließend mit der
Variable var gemacht?

Mit solchen Zusatzinformationen ist es auch bei einer unpräzisen
Problembeschreibung viel leichter zu verstehen, wo der Schuh drückt.

von Klaus W. (mfgkw)


Lesenswert?

> ich werfe man eine weiter Möglichkeit


Ja, auch eine Möglichkeit.

Aber ebenso wie alle anderen sinnvollen Aussagen hier schon tausendmal 
durchgekaut, wenn der OT mal danach suchen würde oder sich Grundlagen 
aneignen würde.
Und nein, dieses Forum ist nicht dazu da, Leuten alles nachzutragen, die 
zu doof sind ein Buch in die Hand zu nehmen.

Also Perlen vor die Säue geworfen.

von Dosmo (Gast)


Lesenswert?

hausmeister schrieb:
> Ich habe ein Array uint8_t array[8] und eine Variable uint64_t *var.
> Nun möchte ich gern die 64 Bits des Arrays in der Variable haben.

Bin ich eigentlich der Einzige, der sich wundert, daß man hausmeister in 
einem Pointer 64Bits speichern will?

Das müßte ja so aus sehen:
1
memcpy(&var, array, 8);

Hä???

von Klaus W. (mfgkw)


Lesenswert?

Auf einem Rechner mit 64-Bit-Zeigern geht das sogar :-)

Aber wundern tut mich hier eigentlich nichts.

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.