16Bit Wert aus 8Bit Array

OP #4761637
Frage: da ja ein Feld in einem Array bloß auf eine Speicheradresse 
zeigt. Kann man den beim Auslesen mit einem 2 Byte großen Wert 
"weiterlesen"? Also wie folgt:

1
uint16_t u_value    = 0x1337;
2
uint8_t  c_array[5] = {0x13,0x37,0x15,0x16,0x17}; 
3

4

5
if(c_array[0] == u_value)
6
{
7
    //true
8
}
9
else
10
{ 
11
    //false
12
}

Was passiert in diesem Fall bei einer Zuweisung?

1
uint16_t u_value    = 0x1337;
2
uint8_t  c_array[5] = {0x00,0x00,0x00,0x00,0x00}; 
3

4
c_array[0] = u_value;
Gast
Rene K. schrieb:

> Frage: da ja ein Feld in einem Array bloß auf eine Speicheradresse
> zeigt. Kann man den beim Auslesen mit einem 2 Byte großen Wert
> "weiterlesen"?

Nein, nicht ohne Weiteres.

> if(c_array[0] == u_value)

Wird immer "false" sein.

> Was passiert in diesem Fall bei einer Zuweisung?

u_value wird nach uint8_t gecastet, unter Bitverlust, und dann 
zugewiesen. Also die untersten 8 Bits, wenn ich das richtig sehe.

Man kann da auch nichts mit Pointercasting reißen, weil das Aliasing 
wäre und nach C-Standard nicht definiert. Allenfalls mit ner Union wäre 
da was zu machen.
OP
Alles klar, danke :-D Naja, bevor da ich da mit Unions "rumspiele" 
(Wobei da auch das Problem der Zuweisung ja weiterhin besteht) - 
Bitschubse (TM) ich mir dann halt einfach [0]..[1] in eine uint16 
zusammen und vergleiche das so oder Bitreiße (TM) es dann wieder zu 
einzelnen Bytes auseinander. :-)

Danke für deine Aufklärung.



EDIT:

Dennis H. schrieb:
> if((uint16_t)(c_array[0] | c_array[0+1]<<8 ) == u_value) {
>
> ....

Ja genau so :-D
OP
Nop schrieb:
> Das geht auch, allerdings solltest Du Dir dann Gedanken über korrekte
> Endianess machen.

Das Projekt ist nur für eine Architektur gedacht. Kann ich 
vernachlässigen. Aber danke für den Hinweis.

EDIT:

Nen Union (wo das ich eigentlich nicht nutzen will) dafür sähe dann so 
aus oder:
1
typedef union
2
{
3
     uint8_t c_array[5];
4

5
     uint16_t u_First16 : 2;
6
     uint16_t u_Secon16 : 2;
7
     uint8_t  u_Lastone : 1;
8
} un_value;
9

10

11
// Kann ich das Union auch "offen" lassen? Oder gibt das Speicherprobleme?
12

13
typedef union
14
{
15
     uint8_t c_array[5];
16
     uint16_t u_First16 : 2;
17

18
} un_value;
Gast
Etwa so:
1
struct uintwise {
2
  uint16_t uint_0;
3
  uint16_t uint_1;
4
  uint8_t trailbyte;
5
};
6

7
typedef union {
8
  struct uintwise uints;
9
  uint8_t c_array[5];
10
} T_ENTRY_5_BYTES;
Gast
im Embedded-Bereich sollte man sich für den direktn Zugriff mit anderer 
Bitbreite entsprechende Routinen bereithalten. Verschiedene Arten sind 
möglich, ich gebe mal Beispiele für den 16-Bit-Zugriff (Word). 
Entscheide Dich  für eine Art, die in Deinem Projekt am sinnvollsten ist 
und implementiere sie dann für alle benötigten Breiten als Inline oder 
als #define
1
/* direkter Zugriff auf angegebene Adresse */
2
uint16 word_access1(void *p) 
3
{
4
    return *((uint16 *)p);
5
}
6
/* mit offs = 0: Byte 0,1; offs=1: Byte 2,3 */
7
uint16 word_access2(void *p, int offs)
8
{
9
    return *(((uint16 *)p)+offs);
10
}
11
/* angabe der Variable im Makro, nicht die Adresse! */
12
#define word_access3(a) (*(((uint16 *)&(a)))
13

14
/* in Deinem Beispiel */
15
uint16_t u_value    = 0x1337;
16
uint8_t  c_array[5] = {0x13,0x37,0x15,0x16,0x17}; 
17

18
if(u_value == word_access1(c_array))     ..
19
if(u_value == word_access1(&c_array[0])) ..
20
if(u_value == word_access2(c_array, 0)   ..
21
if(u_value == word_access3(c_array[0])   ..

Mit dem Makro kannst Du an der Adresse mit 16 Bit lesen und schreiben!
1
word_access3(c_array[0]) = 0xdead; /* ueberschreibt c_array[0] und [1] */

Wenn Du es nicht willst, caste auf (const uint16 *).
Gast
Rene K. schrieb:
> Dennis H. schrieb:
>> if((uint16_t)(c_array[0] | c_array[0+1]<<8 ) == u_value) {
>>
>> ....
>
> Ja genau so :-D

wobei der cast nicht notwenig ist. es wird immer mit 16bit gerechnet.
1
if((c_array[0] | c_array[0+1]<<8 ) == u_value) {
Gast
union {
uint_8 i8[2];
uint_16 i16;
} buffer;

buffer.i8[0] = c_array[0];
buffer.i8[1] = c_array[1];

if(buffer.i16 == u_value)
{
    //true
}
else
{
    //false
}

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 10 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.