PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Rückgabewert aus einer Function



fredyxx
18.05.2016, 23:32
Hallo,

kann eine function einen Wert auch als Parameter an das Hauptprogramm zurückgeben, ohne das dieser Parameterwert global deklariert ist;
z.B durch die gleiche Stellung in der Parameterliste in Aufruf und function?

Wenn ja, wie geht das dann?

Gruß
fredyxx

RoboHolIC
18.05.2016, 23:41
Ja, indem man einen passenden (typbehafteten) Zeiger auf den Speicherort des fraglichen Parameters übergibt.

fredyxx
19.05.2016, 06:34
Ja, indem man einen passenden (typbehafteten) Zeiger auf den Speicherort des fraglichen Parameters übergibt.

Hallo, so klappt es mit dem 3. Parameter nicht! Wie wäre es richtig?



void setup() {

Serial.begin (250000); // diese Buadrate muss auch in der Konsole (Serieller Monitor) eingestellt sein
while (!Serial);

}

void loop() {


Serial.print ("lzahn2 = ");
Serial.println (lzahn2Prog (213.56994, 57.56108, float xyz)); // Druckt Ergebnis des UPs

delay(2000);

}


// **************************************Unterprogram m lzahn2Prog *******************************


float lzahn2Prog ( float x1, float y1, W4) {

float P0_P1 = sqrt(pow(x1, 2) + pow(y1, 2)); //Gerade P0-P1

float CosinusW4 = (114196.0 - pow(P0_P1, 2)) / 102960.0;
float W4 = acos(CosinusW4); // = W4 im Bogenmaß
float lzahn2 = sqrt( 21164.49 - cos (W4 + 0.09180432) * 20574.0 );



return lzahn2; // die Ausgabe erfolgt in mm

}



Gruß
fredyxx

Sisor
19.05.2016, 07:34
Zeigervariante

void setup() {
Serial.begin (250000); // diese Buadrate muss auch in der Konsole (Serieller Monitor) eingestellt sein
while (!Serial);
}

void loop() {
float xyz;
Serial.print ("lzahn2 = ");
Serial.println (lzahn2Prog (213.56994, 57.56108, &xyz )); // Druckt Ergebnis des UPs
Serial.println (xyz); // Druckt xyz
delay(2000);
}


// **************************************Unterprogram m lzahn2Prog *******************************


float lzahn2Prog ( float x1, float y1, float* W4) {
float P0_P1 = sqrt(pow(x1, 2) + pow(y1, 2)); //Gerade P0-P1

float CosinusW4 = (114196.0 - pow(P0_P1, 2)) / 102960.0;
*W4 = acos(CosinusW4); // = W4 im Bogenmaß
float lzahn2 = sqrt( 21164.49 - cos (*W4 + 0.09180432) * 20574.0 );

return lzahn2; // die Ausgabe erfolgt in mm
}

Referenzvariante
void setup() {
Serial.begin (250000); // diese Buadrate muss auch in der Konsole (Serieller Monitor) eingestellt sein
while (!Serial);
}

void loop() {
float xyz;
Serial.print ("lzahn2 = ");
Serial.println (lzahn2Prog (213.56994, 57.56108, xyz )); // Druckt Ergebnis des UPs
Serial.println (xyz); // Druckt xyz
delay(2000);
}


// **************************************Unterprogram m lzahn2Prog *******************************


float lzahn2Prog ( float x1, float y1, float& W4) {
float P0_P1 = sqrt(pow(x1, 2) + pow(y1, 2)); //Gerade P0-P1

float CosinusW4 = (114196.0 - pow(P0_P1, 2)) / 102960.0;
W4 = acos(CosinusW4); // = W4 im Bogenmaß
float lzahn2 = sqrt( 21164.49 - cos (W4 + 0.09180432) * 20574.0 );

return lzahn2; // die Ausgabe erfolgt in mm
}

fredyxx
19.05.2016, 08:54
PRIMA, danke

Gruß
fredyx

HaWe
19.05.2016, 11:20
hallo,
was mich ganz nebenbei etwas stutzig macht, ist dein
Serial.begin (250000);
das funktioniert?
üblich ist eher was in der Größenordnung bis max.
Serial.begin (115200);
was schon sehr schnell ist, aber es könnte sein, dass die Arduino IDE die 250000 automatisch auf default zurücksetzt.

---

zurück zum Topic:

es ist kein "schöner Programmierstil" und stört auch das Verstehen und Debuggen, wenn du sowohl als Rückgabewert als auch bei den Parametern eine Wert-Änderung durchführst.
(Abgesehen davon, dass mir unklar ist, wieso du überhaupt beide Werte (lzahn2Prog Rückgabewert und W4) in derselben Funktion berechnest bzw. änderst...)

"schöner", "üblicher" und "lesbarer" ist:
a) wenn nur 1 Wert zu ändern oder zurückzugeben: als Rückgabewert oder per Referenz (&) oder per Zeiger(*) bei den Parametern
b) wenn 1 Wert benötigt wird, um die richtige Ausführung zu kontrollieren, dann diesen als Funktions-error-Wert zurückgeben.
c) wenn mehrere Werte geändert werden, mit denen "gerechnet" wird, dann alle als Parameter, nicht den/die einen als Parameter und einen anderen als Funktionswert..

Sisor
19.05.2016, 21:35
Eingedampfte Variante:

float w4berechnen (float x1, float y1) {
return acos((114196.0 - x1*x1 + y1*y1) / 102960.0);
}

float lzahn2berechnen (float W4) {
return sqrt( 21164.49 - cos (W4 + 0.09180432) * 20574.0 );
}

void setup() {
Serial.begin (250000);
while (!Serial);
}

void loop() {
float x1 = 213.56994;
float y1 = 57.56108;
float w4 = w4berechnen(x1, y1);
float lzahn2 = lzahn2berechnen(w4);

Serial.print ("lzahn2 = ");
Serial.println (lzahn2 );
Serial.print ("w4 = ");
Serial.println (w4);
delay(2000);
}

HaWe
19.05.2016, 21:59
Wunderwunderschön :D


eingedampfte, sublimierte und obfuscierte Variante:




void loop() {
float x1 = 213.56994;
float y1 = 57.56108;
float lzahn2 = sqrt( 21164.49 - cos ( ( acos((114196.0 - x1*x1 + y1*y1) / 102960.0) ) + 0.09180432) * 20574.0 );
Serial.print ("lzahn2 = ");
Serial.println (lzahn2 );
delay(2000);
}


nein, Sisor's Variante ist wirklich schöner ;)

fredyxx
19.05.2016, 23:44
was mich ganz nebenbei etwas stutzig macht, ist dein
Serial.begin (250000);
das funktioniert?

Ja funktioniert


(Abgesehen davon, dass mir unklar ist, wieso du überhaupt beide Werte (lzahn2Prog Rückgabewert und W4) in derselben Funktion berechnest bzw. änderst...)

Es ging mir im Moment nur mal darum zu erfahren, ob und wie es denn geht.

Da das, was ihr oben seht nur ein sehr kleiner Teil von dem sein wird, was ich noch machen will, dachte ich mir, dass die Funktionen/ Unterprogramme doch einen gewissen Funktionsblock darstellen sollten, damit das Programm nachher noch einigermaßen übersichtlich ist und nicht aus lauter Funktionen mit nur einer Formel besteht. Da ich aber erst am Anfang stehe, stecke ich sowohl mit Konzept als auch mit den Programmierkenntnissen noch in den Kinderschuhen.
Am Ende soll das mal die Steuerung für ein Baggermodell mit 6 Motoren werden, das selbstständig verschiedene Programme abfahren soll.

Gruß
fredyxx

HaWe
20.05.2016, 09:44
Ja funktioniert


edit:

du hast recht, ich habe nachgesehen, es könnte tasächlich funktionieren, es wird "nur empfohlen", bestimmte Werte für die serielle Konsole (PC) bis max. 115200 zu verwenden: https://www.arduino.cc/en/Serial/Begin