PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Array und Zeiger



guenter1604
18.09.2010, 20:26
Hallo,

mein C-Umstieg macht Fortschritte, jedoch habe ich noch 1 Problem:

in einem Array

uint8_t Speed_array[8]={ 0,0,0,0,0,0,0,0} ;

bekomme ich 4 Wordvariablen angeliefert, jetzt setze ich Zeiger1 auf die Position 0:

uint8_t *Speed_left = &Speed_array[0];

und will jetzt die Wordvariable schreiben:

uint16_t x

x = *Speed_left

Was ist falsch?

Günter

Felix G
18.09.2010, 20:30
Warum verwendest du ein Array vom Typ uint8_t, wenn du darin eigentlich 16Bit Werte speichern möchtest?

guenter1604
18.09.2010, 20:34
weil die Werte byteweise über I2C reinkommen

Felix G
18.09.2010, 20:43
In diesem Fall könntest du sowas machen:

x = ((uint16_t*)Speed_array)[0]

Damit verwendest du das Array so, als wäre es ein uint16_t Array. So sparst dir den zusätzlichen Pointer, und du kannst 0,1,2,3 als Indizes verwenden (statt 0,2,4,6 wie bei der anderen Variante)


edit:
oder wie wär's damit...

uint8_t Speed_array[8];
uint16_t* Speed_array16 = (uint16_t*)Speed_array;

x = Speed_array16[0];Das macht im Endeffekt das gleiche, aber du musst nicht bei jedem Zugriff einen Typecast machen, sondern nur einmal.

guenter1604
18.09.2010, 20:54
Sieht toll aus, könntest du das bitte näher erklären, ich stehe auf dem Schlauch.

BurningWave
18.09.2010, 21:11
Im Wesentlichen ist Speed_array16 ein Zeiger, der auf das 1. Element von Speed_array zeigt. Hier wird das Array deklariert: uint8_t Speed_array[8];
und hier der Zeiger: uint16_t* Speed_array16 (Zeiger wegen dem *). Speed_array ohne Indexoperator ([]) ist ein Zeiger auf das 1. Element seiner Elemente. Dieser Zeiger wird in uint16_t gecastet und die Adresse dem Zeiger Speed_array16 zugewiesen. (uint16_t*) ist der Cast. Jetzt kannst du über x = Speed_array16[0]; auf den Speicherbereich, also die Elemente von Speed_array zugreifen ohne jedesmal zu casten.

Felix G
18.09.2010, 21:15
Naja, für den Compiler ist ein Array im Endeffekt auch nichts Anderes als ein "normaler" Pointer, nur daß in diesem Pointer eben die Basisadresse eines Arrays steht.
Umgekehrt bedeutet das, man kann den []-Operator mit jedem beliebigen Pointer verwenden, selbst dann wenn dieser eigentlich garkein Array ist (denn dem Compiler ists egal).


Nehmen wir an es gäbe den []-Operator nicht, wie würde man dann auf ein Element eines Arrays zugreifen?
Man müsste, ausgehend von der Basisadresse des Arrays und der Nummer des Elements eben die Adresse dieses Elements berechnen.

Bei 8-Bit Typen ist das sehr simpel, man muss nur die Basisadresse und die Nummer des Elements addieren, fertig ist die Adresse des Elements.

array[63] entspricht dann quasi *(array + 63)

Bei anderen Typen muss zusätzlich deren Größe berücksichtigt werden, also z.B. *(array + 63 * sizeof(uint16_t)) bei 16 Bit.



Der []-Operator sagt dem Compiler also nur, daß er - passend zum Typ des verwendeten Pointers - die Adresse eines bestimmten Elements berechnen soll.


In meinem Beispiel erzeuge ich einen uint16_t Pointer, und setze ihn auf die Basisadresse des vorhandenen uint8_t Arrays. Wenn ich dann mittels [] darauf zugreife, behandelt der Compiler diesen Pointer genauso wie ein uint16_t Array

guenter1604
18.09.2010, 21:20
uint8_t Speed_array[8]={ 0,0,0,0,0,0,0,0} ;
uint16_t* Speed_array16 = (uint16_t*)Speed_array;
uint16_t Speed_left;
uint16_t Speed_right;
Speed_left = Speed_array16[0];
Speed_right = Speed_array16[1];

leider kommen hier Compilierungsfehler, mache ich noch was falsch?

Felix G
18.09.2010, 21:25
Seltsam...
was genau gefällt dem Compiler nicht?

guenter1604
18.09.2010, 21:28
t.c:57: warning: data definition has no type or storage class
t.c:57: warning: type defaults to 'int' in declaration of 'Speed_left'
usw...

edit:
hier:
Speed_left = Speed_array16[0];

Felix G
18.09.2010, 21:37
Hmm, bei mir funktionierts problemlos...


blöde Frage, aber hast du an die stdint.h gedacht?

guenter1604
18.09.2010, 21:53
Mist!

Kaum macht mans richtig, schon funktionierts :D

Speed_left = Speed_array16[0];
sollte schon in der Schleife stehen und nicht im Deklarationsbereich

guenter1604
18.09.2010, 22:04
Danke für die Hilfe!

weitere Fortschritte hier:

http://www.gerold-online.de/cms/wheelie/mein-wheelie.html