16Bit Wert aus 8Bit Array

OP #4761637
Lesenswert?
• ▲
▼
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 #4761642
Lesenswert?
• ▲
▼
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 #4761647
Lesenswert?
• ▲
▼
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 #4761651
Lesenswert?
• ▲
▼
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 #4761991
Lesenswert?
• ▲
▼
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 *).

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren