mikrocontroller.net

Forum: Compiler & IDEs Array übergeben


Autor: riegaz (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Daran, dass du das Kapitel über pointer & arrays im K&R nicht
verstanden hast.
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];}
}
...
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]);uart_puts_P("..");}
}

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

#include innerhalb einer Funktion ist normalerweise eher schlechter
Stil.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Karl heinz Buchegger (heinzi)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Μαtthias W. (matthias) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

wenn man das aber will könnte man das Array in eine Struktur packen und
schon..... Lassen wir das sonst verwirren wir riegaz noch vollständig
:-)

Matthias

Autor: riegaz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich bin schon verwirrt ;-)

sorry

Autor: Marian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du bist nicht alleine :)...ich bin auch immmer verwirrt, wenn es um C
geht.

Gretz Marian

Autor: Werner B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Christian Rötzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Siehe auch meinen zweiten Beitrag. ;-)

Autor: Christian Rötzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stimmt! Las' uns wieder über AVRDUDE diskutieren :-)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.