www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Arrays und Zeiger


Autor: etepetete (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Arbeite in C
auf Atmel AVR

Ich habe folgendes Problem.

4 int Arrays

nach einer Auswertung soll nunmindestens eines dieser 4 Arrays
umgearbeitet werden udn in ein neues Array geschoben werden.


der erste gedanke waren zeiger, Problem kann sein, das auch zwei dieser
Arrays hintereinanderkommen können.

Die ganzen Erklärungen die ich in den Büchern gefunden habe waren sehr
verwirrend, und mit schelchten Beispielen belget. kann mir da jemand
helfen?

Autor: inoffizieller WM-Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
[OT] In erster Linie hast du ein Problem damit, dein Problem in Worte zu
fassen.[/OT]

>Ich habe folgendes Problem.
>4 int Arrays
>nach einer Auswertung soll nunmindestens eines dieser 4 Arrays
>umgearbeitet werden udn in ein neues Array geschoben werden.

4 int Arrays sind kein Problem.
Wenn man von vornherein deren Grösse weiß, hat man eine
Abbruchbedingung (nämlich den grössten Index).
Selbst, wenn sich ein fünftes dazugesellt, sehe ich immer noch kein
Problem.

Autor: etepetete (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also nochmal hoffentlich besser erklärt.

Ich habe vier vordefinierte Arrays in unterschiedlichen Längen. ( es
sidn tatsächliche wesentlich mehr, aber ums übersichtlich zu halten
eben so )


Es folgen nun Bedienugnen nach denen das eine odere andere Array
genutzt werden soll.

Jetzt will ich das durch die Auswertung, die mir einen Zahlwert (INT )
gibt, das entsprechnde Array genutzt wird.

Ist das Ergebnis zB. 1 soll er Array 1 nutzen

Dieses Array wird anschließend weiterverarbeitet.


Das Problem ist der Teil wo Ergebnis zum Array zugeordnet werden muß.
Hoffe das ist so etwas verständlicher Erklärt

Autor: david reiher (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
nimm doch einfach 2dimensioanle arrays. wenn du weist wieviele arrays du
brauchst:

int *array[N]; // N ist anzahl der arrays

dann ihm programm mit malloc die 2 dimension reservieren

array[n]=(int *)malloc(m*sizeof(int)); //m  ist die anzahl an intergers
in dem array

david

Autor: inoffizieller WM-Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Haben die Arrays eine konstante Länge, oder ändert sich das je nach
Datenaufkommen?
Wenn du 4 Arrays hast, die alle unterschiedlíche Grössen haben, diese
Grösse aber zu jedem Zeitpunkt gleich ist, dann kannst du den
"Endpunkt" durch einen Zahlenwert feststellen.
Andere Methoden benutzen Endezeichen (z.B. "\0" bei Strings).
Das resultierende Feld kannst du entweder so bemessen, dass immer die
größtmögliche Anzahl an Werten dort hineingschrieben werden kann, oder
per "malloc" neu dimensioniert werden.

>Hoffe das ist so etwas verständlicher Erklärt
Naja...

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich versteh's immer noch nicht :(
Was ist jetzt das Problem? Du hast eine Funktion, die als Parameter ein
Array verlang und willst abhängig von diversen Bedingungen diese
Funktion mit unterschiedlichen Arrays aufrufen? Das Problem der
Zuordnung des Ergebnisses zum Array verstehe ich einfach nicht, was
meinst du damit?

Autor: Micha (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Keine Ahnung, ob das auch so auf dem MC funktioniert, aber
hier mal ein "aus der Huefte"-Loesungsvorschlag.

int array0[n_0], array1[n_1], array2[n_2], array3[n_3];
int *arrays[4];

// Startadresse der jeweiligen Arrays hinterlegen
arrays[0] = &(array0[0]);
arrays[1] = &(array1[0]);
arrays[2] = &(array2[0]);
arrays[3] = &(array3[0]);


Eigentlich muesste dann der Zugriff auf das i.-te Feld
des j.-ten Arrays mittels

arrays[i-1][j-1]

gelingen.

Ich hoffe, dass es noch nicht zu lange her ist, seit dem ich
das letzte Mal C programmiert habe.

   Micha

Autor: Micha (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mist, da hat sich schon mindestens ein Fehler eingeschlichen,
der Zugriff auf das i.-te Feld des j.-ten Arrays erfolgt mittels

value = arrays[j-1][i-1]

  Micha

Autor: etepetete (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
UHH mit Brett vorm Kopp... das mit den 2 D Array ... beinahe peinlich,
das zu übersehen g


Das mit dem Erklären ist immer so eine Sache :o) vor allem wenn man
gedanklich noch so vertieft da drinsteckt udn genau weiß, was man will
und versucht dann sowas knapp niederzuschreiben.

Danke

Autor: david reiher (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
^^ er will abhängig von bestimmten ereignissen mit unterschiedlichen
arrays arbeiten, weiß aber nicht wie er die arrays im programm
beispielsweise in abhängigkeit einer vareablen selectieren kann.

das geht entweder über ihren namen in verbindung mit zb einer
switch-case anweisung oder über ein array von array wie ich es schon
gepostet hab.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die einfachste (und sicherlich beste) Variante
ist es, wie bereits angesprochen, die eigentliche
Verarbeitung des Arrays in eine eigene Funktion
auszulagern und je nach Auswertebedingung die
Funktion mit je einem der vorhandenen Arrays
aufzurufen.
Im Grunde passiert hier dann unter der Decke
das, was man explizit auch mittels Zeiger
erreichen kann:

  int W1[4], W2[4],W3[4];
  int* pW;

  if( Bedingung1 )
    pW =  W1;
  else if( Bedingung2 )
    pW = W2;
  else
    pW = W3;

  pW[2] = 5;

Das Ganze ist ein klassisches Lehrstück über
den Zusammenhang von Arrays und Pointern.
Der Name eines Arrays alleine, also ohne
Indizierung, verhält sich so, als ob er ein
Pointer auf das erste Arrayelement wäre. Damit
sind die Zuweisungen alle legal: pW erhält
jeweils die Startadresse des ausgewählten Arrays
zugewiesen.
Warum geht aber die Indizierung weiter unten?
Nun, in C ist eine Arrayindizerung keineswegs
an Arrays gebunden. Ganz im Gegenteil: Array-
indizierungen werden vom Compiler zuallererst
in eine equivalente Pointerform überfhrt:

   a[b]  <==>   *(a+b)

und hier ligt das Gehemniss:
pW[2] wird zuallererst umgesetzt in *(pW+2)
und das ist eine völlig legaler Zugriff über
einen Pointer mit exakt definiertem Verhalten.

Autor: -daniel- (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
schlisse mich dem obengesagten zu
erweitere es um den wenig bekannte syntax

int i=2, a[]={1,2,3}, * p = &a[0];

a[i] == i[a] == *(p+i)

Autor: etepetete (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
kann ich eigentlich aus dem pW auch ein array machen??

################################
int W1[4], W2[4],W3[4];
  int* pW;

  if( Bedingung1 )
    pW =  W1;
  else if( Bedingung2 )
    pW = W2;
  else
    pW = W3;

  pW[2] = 5;
##############################
ginge also:
int* pW[]={W1,W2,W3};

und wie muß das auslesen aussehen?
will ich zum beispiel aus dem array 1 den 2. wert haben
test=&pW[1]?????

Ich habe es probiert, nur kommt dort Datenmüll bei auslesen raus.
Ich vermute irgendwo ist ein kleiner Fehler im Syntax... bzw mit den *
udn & komme ich ncoh nicht so zurecht..

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klar geht das.

Ist sogar eine beliebte Methode '2-dimensionale'
Arrays aufzubauen.

  pW[0][1];

liefert dir aus dem ersten Array den 2. ten Wert.

> bzw mit den * udn &

& kann bei der Abfrage des Wertes schon mal überhaupt
nicht vorkommen. & liefert die Adresse von irgendwas.
Die Adresse von der du den Wert holen willst hast du:
die steht im pW-Array. Wenn schon, dann brauchst du
die Umkehrung: einen Wert besorgen, von dem du die
Speicheradresse hast. Das macht *

pW ist ein Array von Pointern.
Mit pW[0]  wählst du also einen speziellen Pointer aus.
Nämlich den, der auf das erste Array zeigt.
Wenn du einen Pointer auf ein Array hast, dann kann man
mit   *( Ptr + i) den Wert des i-ten Array-Elements kriegen.
Ptr ist die Startadresse des Arrays, da wird dann noch i
hinzugezählt, wobei i vorher noch mit der richtigen Datentyp
Größe multipliziert wird, zb. bei einem int Array mit sizeof(int)
Damit ist man bei Pointerarithmetik davon befreit sich immer
um die Datentypen zu kümmern. Wenn Ptr auf int zeigt, dann liefert
Ptr + i den richtigen Offset, wenn Ptr auf double zeigt, dann
liefert Ptr + i ebenfalls den richtigen Offset.
Also: Ptr + i  ist damit bereits ein korrekter Pointer in den Speicher
von wo der Wert geholt werden soll. Dann lass uns mal den Wert
holen: *( Ptr + i)

so, jetzt setzen wir für Ptr nur noch unseren tatsaechlichen Pointer
ein, der da war pW[0].

Also muss es heissen *( pW[0] + i )
du wolltest das 2-te Element, also das mit dem Index 1:
*( pW[0] + 1 )

Nun geht die Sache aber weiter: Array Indizierung ist in C
so definiert, dass die Ausdrücke a[b] und *(a+b) völlig
gleichwertig sind.
Anstatt *(Ptr + i) kann man daher schreiben:  Ptr[i]
Weiderrum für Ptr eingesetzt:   pW[0][i]
und für i noch eine 1:   pW[0][1]

qed

Autor: Andreas Bombe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> int array0[n_0], array1[n_1], array2[n_2], array3[n_3];
> int *arrays[4];
>
> // Startadresse der jeweiligen Arrays hinterlegen
> arrays[0] = &(array0[0]);

Abgesehen davon, dass die Klammern nicht nötig wären, lässt sich das
auch weniger umständlich schreiben:

arrays[0] = array0;

Merke: &array[n] == array + n

Autor: etepetete (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Karl Heinz

Ich danke dir, für die echt gute erklärung. Damit schaffe ich es.
Vielen dank.. ist echt gut ausführlich und sogar warum das so ist, läßt
sich nachvollziehen.

vielen dank..  bin begeistert von der erklärung :o)

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.