PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : ein Int-Array einer Funktion



oderlachs
16.02.2014, 15:30
Hallo ,
ich suche mal wieder Hilfe oder Anregung.
ich habe vor 3 Messwerte(MW) in einem Intarray MW[] beim Funktionsaufruf zu speichern und dieses Array als Return zurück zu bekommen, es geht nicht. Was mache ich falsch:


int mess()
{
int MW[3];
MW[0] = analogRead(IR_RFL_V) ;
MW[1] = analogRead(IR_RFL_L) ;
MW[2] = analogRead(IR_RFL_R) ;
return MW[];
}



Hier der Aufruf im Programm:


void loop()
{....
IR_RFL_I[] = mess();
....
}

IR_RFL_I ist so definiert:

int IR_FL_I[3];

Ich finde nicht den Fehler, warum es nicht zu kompilieren geht....

Gruss Gerhard

Peter(TOO)
16.02.2014, 21:54
Hallo Gerhard,

1. int MW[3]; ist eine automatische lokale Variable und wird auf den Stack abgelegt wenn die Funktion aufgerufen wird.
Wenn die Funktion mit return beendet wird, wird aber er Stack wieder abgeräumt, inklusive der Variablen MW.
Abhilfe:
entweder
a) static int MW[3];
b) MW als globale Variable deklarieren
c) Die Funktion mess() so schreiben, dass das Array als Zeiger auf das Array übergeben wird. Dann muss der Speicherplat für MW im AUfrufenden Teil deklariert werden.

2. Die Funktion soll einen int zurückgeben.
MW[] ist aber ein Zeiger auf eine Array aus int.
MW[] entspricht &MW[0]
Du müsstest also
int *mess()
schreiben, dann sollte das Compilieren gehen, aber das zurückgelieferte Array kann dann irgendwelche Random Werte enthalten. Es kann dann manchmal die gewünschten Werte enthalten und, wenn z.B. ein Interrupt auftritt, nur noch irgendwelchen Schrott.

MfG Peter(TOO)

Sisor
16.02.2014, 22:33
oder so:


...
int MW[3];//globales Variablenfeld
...
void updateMW(){
MW[0] = analogRead(IR_RFL_V) ;
MW[1] = analogRead(IR_RFL_L) ;
MW[2] = analogRead(IR_RFL_R) ;
}
...
void loop() {
....
updateMW();
....
}

Peter(TOO)
17.02.2014, 01:06
Hallo,
Ist zwar die einfachste, aber leider auch unschönste Variante:

- Seiteneffekte sind nun mal unschön:
In einem grösseren Projekt, wird schnell übersehen, dass update() die globale Variable verändert.
Jeder darf sich ausmalen, was man da an Zeit zur Fehlersuche aufwenden kann, besonders wenn ein Fremder etwas am Code ändern muss.

- unflexibel
Am flexibelsten ist die Variante bei welcher das Array über einen Zeiger übergeben wird.
Man kann beliebig viele Messwerte abspeichern. Zudem ist es auch egal, ob man die Messwerte Global. lokal oder auf dem Heap ablegen will, update muss dazu nicht verändert werden.

MfG Peter(TOO)

oderlachs
17.02.2014, 08:29
Ich habe es auch so erst ein mal gelöst..:
void mess()
{

IR_FL_I[0] = analogRead(IR_RFL_V);
IR_FL_I[1] = analogRead(IR_RFL_L);
IR_FL_I[2] = analogRead(IR_RFL_R);

}

int IR_FL_I[3] ist in meiner Lib zum Projekt global deklariert...

praktische Erfahrungen habe ich noch nicht damit..muss noch was löten, montieren...usw..

Danke für Eure Hilfe..
ich werde berichten wie ich weiter komme...

Gerhard

Hier mein bisheriger CODE (http://robot.oderlachs.de/zumo/zumo_laby_wand.zip) zum Projekt

Wsk8
17.02.2014, 10:17
void mess(int *arr) {
arr[0] = analogRead(IR_RFL_V) ;
arr[1] = analogRead(IR_RFL_L) ;
arr[2] = analogRead(IR_RFL_R) ;
}

void loop()
{....
mess(MW);
....
}

Sollte in deinem Fall die beste Lösung sein. Globale Variablen sollte man wenn möglich vermeiden.
Funktion ist natürlich nicht sicher, da keine Überprüfung des Arrays stattfindet.

mfg

shedepe
17.02.2014, 11:46
Die Ideale Variante währe (so wird das auch von den C Standard Funktionen gemacht):



int * mess(int *arr, int length)
{
//Array befüllen und dabei length beachten
return arr;
}

Sisor
17.02.2014, 16:28
Wir programmieren hier für einem Arduino. Da sind globale Variablen einfach praktisch.
Wer schon mal größere objektoorientierte Programme geschrieben hat, weiß das das Gefahren birgt.
Je größer ein Arduino Sketch, desto unübersichtlicher. Die Probleme fangen an, wenn man nicht mehr weiß, wie groß z.B. ein Variablenfeld ist und über die Feldgrenzen hinweg schreibt oder ließt. Oder wenn sich ein zweiter Programmierer über den Code hermacht.

Aber für einfachere Sketches finde ich es durchaus empfehlenswert mit globalen Variablen zu arbeiten.
Wenn man seinen Code anständig kommentiert, und sprechende Namen vergibt, ist es für mich ok.
Es ist halt auch die schnellste Variante, da die Variablen global erhalten bleiben und keine Parameter übergeben werden.

Da hat halt jeder hat seinen eigenen Stil.

shedepe
17.02.2014, 18:40
Globale Variablen würde ich nicht als eigenen Stil sondern als sehr schlechte Angewohnheit bezeichen, besonders wenn die Alternative kaum Mehraufwand bedeutet.
Also Regel würde ich mal sagen: so lokal wie möglich, so global wie nötig. Also wenn ich eine Variable nur in einer Funktion brauche, dann deklare ich die auch nur dort, usw.

Wsk8
17.02.2014, 20:17
Globale Variablen würde ich nicht als eigenen Stil sondern als sehr schlechte Angewohnheit bezeichen, besonders wenn die Alternative kaum Mehraufwand bedeutet.
Also Regel würde ich mal sagen: so lokal wie möglich, so global wie nötig. Also wenn ich eine Variable nur in einer Funktion brauche, dann deklare ich die auch nur dort, usw.
^this

mfg

Sisor
17.02.2014, 20:20
Ich sehe einen Arduino Sketch so:


void loop()
{
...
}

ist etwa das gleiche wie:


while(1)
{
...
}

Wenn nun Variablen in der Loop- (oder While-) Schleife gebraucht werden, deklariere ich sie außerhalb. Innerhalb würde bedeuten, dass sie in jedem neuen Durchlauf weggeschmissen und neu erstellt werden müssen (Stack). In diesem Fall entscheide ich mich also ganz bewußt für diese Vorgehensweise, nicht aus schlechter Gewohnheit.

Im Allgemeinen stimme ich aber shedepe in allen Punkten zu.

Wsk8
17.02.2014, 20:23
27549

mfg

Sisor
17.02.2014, 21:00
Touché! :p

shedepe
17.02.2014, 22:50
Außerdem würde ich den Fall des Arduinos nur halb gelten lassen. Letztendlich ist es ja nichts anderes als eine while(1) Schleife im Hintergrund bei der ständig die Funktion loop() aufgerufen wird. Es kommt eher selten vor, dass man solche Programmierkonstrukte hat die man nicht selber beeinflussen kann. Sonst könnte man auch der Funktion loop die passenden Argumente übergeben oder sich die Funktion gleich sparen.