Array übergeben

Gast #284083
Lesenswert?
• ▲
▼
Hallo, ich würde gerne ein Array mithilfe von Pointern aus der
"test.c" in die "main.c übergeben.
---- test.c --
uint8_t test(uint8_t id[],uint8_t *RET[])
{
  sp[0]=1;
  sp[1]=2;
  sp[2]=3;
  sp[3]=4;
  sp[4]=5;
  for (int i=0;i<5;i++){  *RET++ = sp[i];}
}
----
---- main.c --
int main(void
{
#include "test.h"

......
  uint8_t ret[5];
  test(&gSensorIDs[0][0][0],&ret);
  for (int i=0;i<5;i++){uart_puti(ret[i*2]);uart_puts_P("..");}
}
----
Mein Problem ist: Er schreibt in jedes zweite Feld ret[1],ret[3]...
eine "0" und ich verstehe nicht wieso. Mit ret[i*2] ist es zwar kein
Problem, aber trotzdem würd ich gern wissen woran es liegt!!!

Lg michi
Moderator Persönliche Seite #284084
Lesenswert?
• ▲
▼
Daran, dass du das Kapitel über pointer & arrays im K&R nicht
verstanden hast.
1
uint8_t test(uint8_t id[],uint8_t *RET)
2
{
3
  sp[0]=1;
4
  sp[1]=2;
5
  sp[2]=3;
6
  sp[3]=4;
7
  sp[4]=5;
8
  for (int i=0;i<5;i++){  *RET++ = sp[i];}
9
}
10
...
11
int main(void
12
{
13
#include "test.h"
14

15
......
16
  uint8_t ret[5];
17
  test(&gSensorIDs[0][0][0],ret);
18
  for (int i=0;i<5;i++){uart_puti(ret[i]);uart_puts_P("..");}
19
}

Ich denke, dass "id" auch noch flasch ist, aber da fehlen die
Randinfos.

#include innerhalb einer Funktion ist normalerweise eher schlechter
Stil.
Gast #284085
Lesenswert?
• ▲
▼
for (int i=0;i<5;i++){uart_puti(ret[i*2]);uart_puts_P("..");}
}
----

> Mein Problem ist: Er schreibt in jedes zweite Feld
> ret[1],ret[3]...eine "0" und ich verstehe nicht wieso.

Eigentlich schreibst du in jedes zweite Feld gar nichts rein, d.h. es
steht nachher noch immer das drin, was zufällig vorher an dieser
Adresse stand. Nach dem Reset dürften das Nullen sein.

> Mit ret[i*2] ist es zwar kein Problem,

Doch, denn du hast ein Array aus 5 Elementen, also eines, auf das nur
mit Index 0 bis 4 zugegriffen werden darf. Dein Index geht aber bis 8.
Also schreibst du über das Ende des Arrays hinaus.

> aber trotzdem würd ich gern wissen woran es liegt!!!

Eben gerade an dem i*2. Wieso multiplizierst du überhaupt mit 2?
#284086
Lesenswert?
• ▲
▼
uint8_t test(uint8_t id[],uint8_t *RET[])
{
  ... *RET++ ...
}

Rhetorische Frage: was macht der ++
Um wieviel erhoeht er?

Nun da RET zuallererst mal ein Pointer auf Pointer ist,
erhoeht er um sizeof( uint8_t *).
Das moeschtest Du aber nicht, du moechtest um
sizeof( uint8_t ) erhoehen, da du ja an das naechste
Array Element ran kommen willst.
Da aber auf deinem System anscheinend
  sizeof( uint8_t*) == 2 * sizeof( uint8_t )
ist, beschreibst du nur jedes 2-te Array Element
(und hast einen klassischen Fall von: 'hinter ein
Array schreiben' und damit undefiniertes Verhalten)

Die Frage ist doch: Warum ueberhaupt dieser Mambo-Zambo
mit Pointer auf Array?
Du duerfte ein bekannter Denkfehler vorliegen: Arrays
werden naemlich sowieso immer per Pointer uebergeben.
Auch dann, wenn Du schreibst

  void foo( int A[] )

Das ist naemlich nichts anders als eine andere (unsaegliche)
Schreibweise fuer

  void foo( int * A )

oder in anderen Worten: Wenn einer Funktion ein Array
uebergeben wird, dann kann diese Funktion immer die
originalen Werte beim Aufrufer aendern. Das ist nun mal
so, Arrays verhalten sich hier anders als normale Variablen.
Andersrum ist es in C gar nicht moeglich: Es ist nicht moeglich
ein Array an eine Funktion zu uebergeben, sodass diese Funktion
eben nicht im originalen Array rumpfuschen kann.
Gast #284090
Lesenswert?
• ▲
▼
Der kleine Unterschied zwischen

<datentyp> array[<elements>];
 und
<datentype> pointer;

'array' ist der NAME einer Ansammlung von <datentyp> Elementen.
&array[5] kann zur Compilierzeit ausgewertet indem auf die Adresse des
ersten Elements 5 * sizeof(<datentype>) addiert wird.

'pointer' ist der Name einer VARIABLEN welche auf die Adresse einer
Ansammlung von <datentyp> Elementen zeigt.
&pointer[5] muss während des Programmablaufes ausgerechnet werden indem
der Inhalt der Variblen 'pointer' geladen wird und auf diesen Wert
(der zur Compilierzeit berechnete) Offset von 5 * sizeof(<datentype>)
addiert wird.

Der Wert von 'array' kann niemals verändert werden.
pointer = array; ist zulässig, array = pointer; aber nicht.

Im einem Programm steht also die Zeichenfolge 'array' für die Adresse
des Elements mit dem Offset 0 ( == &array[0] ), der Compiler 'ersetzt'
den Text 'array' durch eine Adresse.
Dagegen greift 'pointer' auf den eine Variable zu, der Compiler  Was
immer wieder verwirrt ist, dass man im Quelltext die gleichen
Operatoren verwenden kann.
Gast #284091
Lesenswert?
• ▲
▼
Letztlich will Dein Programm also wie folgt aussehen:

uint8_t test(uint8_t id[],uint8_t *RET)
{
  sp[0]=1;
  sp[1]=2;
  sp[2]=3;
  sp[3]=4;
  sp[4]=5;
  for (int i=0;i<5;i++)
  {
    *RET++ = sp[i];
  }
}
----
---- main.c --
#include "test.h"

int main(void)
{
......
  uint8_t ret[5];
  test(&gSensorIDs[0][0][0],ret);
  for (int i=0; i<5; i++)
  {
    uart_puti(ret[i]);
    uart_puts_P("..");}
  }
}

Es wurde eigentlich nur das [] im Kopf von Test entfernt, sowie beim
Aufruf der Adressoperator.
Wobei die Geschichte mit gSensorIDs weiterhin unheimlich aussieht.

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