Hallo Ich möchte innerhalb einer main Schleife eine Funktion A aufrufen und dieser 3 Werte übergeben, z.b. mit Schiebereglern. Wenn jetzt bei Funkion A alles geregelt ist möchte ich 3 Parameter einer Funktion B übergeben, mit den gleichen Schiebereglern. Wie schaffe ich es dass Funktion A sich die letzten Werte "merkt" ohne dass die Werte überschrieben werden? Wahrscheinlich ist es ganz einfach und ich stehe nur grade auf dem Schlauch. :-( Danke für Hinweise!
Leider ist deine Frage nicht klar. Wenn Funktion A durch ist, wird diese verlassen und danach Funktion B aufgerufen. Wie kommt Funktion A ist wieder ins Spiel?!
ein "static" vor die Variablen in A() schreiben.
Beide Funktionen werden dauernd aufgerufen! Durch einen Schalter z.B. könnte bestimmt werden für welche der Funktionen die Schieberegler grade gültig sind. Ein static löst das Problem nicht da ja die Schieberegler weiter betätigt werden.
Mir ist leider nicht klar, was es mit deinen Schiebereglern auf sich hat aber in C hast du drei Möglichkeiten: 1. Globale Variable
1 | int hugo = 42; |
2 | |
3 | void foo(void) { |
4 | hugo++; |
5 | }
|
6 | |
7 | void bar(void) { |
8 | hugo--; |
9 | }
|
10 | |
11 | int main(void) { |
12 | hugo = 0; |
13 | foo(); |
14 | bar(); |
15 | }
|
2. Pass by value
1 | void foo(int a) { |
2 | a++; |
3 | }
|
4 | |
5 | int main(void) { |
6 | int hugo; |
7 | hugo = 0; |
8 | foo(hugo); |
9 | // hugo is still zero
|
10 | }
|
3. Pass by reference
1 | void foo(int* a) { |
2 | *a++; |
3 | }
|
4 | |
5 | int main(void) { |
6 | int hugo; |
7 | hugo = 0; |
8 | foo(&hugo); |
9 | // hugo is now 1
|
10 | }
|
Also: 1) Frage die Schieberegler ab. 2) Schreibe die Werte der Schieberegler in Funktion A solange bis: 3) Funktion B aktiv ist.Dann führe Funktion A mit den letzten übergebenen Parametern weiter aus. 4) Schreibe demnach die Werte der Schieberegler in Funktion B solange bis: 5) Funktion C aktiv ist. Dann führe Funktion A mit seinen (gespeicherten?) Parametern aus und führe B mit den letzten übergebenen Parametern weiter aus. 6) Schreibe demnach die Werte der Schieberegler in Funktion C. ...usw..... 7) Fang von vorne an.
Attila C. schrieb: > Also: Vielleicht ist dein Ansatz nicht der Richtige. Ich habe das jetzt so verstanden: Auf Grund eines bestimmten Ereignisses (Zeit abgelaufen, 10 Durchläufe, ...) sollen die Eingabeparameter mit einer weiteren/ der nächsten Funktion verarbeitet werden. Da könnte man jeder Funktion zusätzlich ein Flag oder eine Statusvariable übergeben, welche(s) anzeigt, dass eine weitere Funktion aktiv ist und somit mit den letzten Werten weitergerechnet werden soll. 'static' ist hier trotzdem nötig.
Indem Du zu den 3 noch einen vierten Parameter mitgibst, ob die 3 für Funktion A oder B gelten. Alternativ die Parameter auf einen "Spezial-Wert" setzen. Z.B. -1 wenn sonst nur 0..100 gültig sind. Und lokale Spiegel der Variablen ("static"), damit die letzten Werte gültig bleiben.
1 | void FuncA(int X, int Y, int Z, int BoxChecked) |
2 | {
|
3 | static int p[3]; |
4 | |
5 | /* hier nur, wenn BoxChecked == 0, in B andersrum*/
|
6 | if(!BoxChecked) |
7 | {
|
8 | p[0]=X; |
9 | p[1]=Y; |
10 | p[2]=Z |
11 | }
|
12 | ... und hier nur noch p[0..2] verwenden |
13 | }
|
Hier mein Vorschlag ohne static. Hat den Vorteil, dass Du ggf. verschiedene Functionen wiederverwenden kannst, wenn dort eigentlich dasselbe passiert.
1 | typedef struct |
2 | {
|
3 | int p1; |
4 | int p2; |
5 | int p3; |
6 | } paramsTypeDef; |
7 | |
8 | enum actualFunctionEnum |
9 | {
|
10 | isFunctionA = 0, |
11 | isFunctionB, |
12 | isFunctionC, |
13 | isNoFunction, |
14 | }
|
15 | |
16 | |
17 | void functionA (paramsTypeDef *pSavedparameters, *pActualParameters, int saveMyParams) |
18 | {
|
19 | // do code of A
|
20 | |
21 | if (saveMyParams) |
22 | {
|
23 | memcpy (pSavedparameters, pActualParameters, sizeof(paramsTypeDef)); |
24 | }
|
25 | }
|
26 | |
27 | |
28 | void functionBC (paramsTypeDef *pSavedparameters, *pActualParameters, int saveMyParams) |
29 | {
|
30 | // do code of B and C
|
31 | |
32 | if (saveMyParams) |
33 | {
|
34 | memcpy (pSavedparameters, pActualParameters, sizeof(paramsTypeDef)); |
35 | }
|
36 | }
|
37 | |
38 | |
39 | void main() |
40 | {
|
41 | paramsTypeDef paramsA; |
42 | paramsTypeDef paramsB; |
43 | paramsTypeDef paramsC; |
44 | paramsTypeDef actualFaders; |
45 | actualFunctionTypeDef actualFunction = isFunctionA; |
46 | int saveParams; |
47 | |
48 | while(1) |
49 | {
|
50 | getfader(&actualFaders); |
51 | saveParams = shouldISaveParams(); |
52 | |
53 | switch (actualFunction) |
54 | {
|
55 | case isFunctionA: |
56 | functionA(¶msA, &actualFaders, saveParams); |
57 | if (saveParams) actualFunction = isFunctionB; |
58 | break; |
59 | |
60 | case isFunctionB: |
61 | functionB(¶mB, &actualFaders, saveParams); |
62 | if (saveParams) actualFunction = isFunctionC; |
63 | break; |
64 | |
65 | case isFunctionC: |
66 | functionC(¶msC, &actualFaders, saveParams); |
67 | if (saveParams) actualFunction = isNoFunction; |
68 | break; |
69 | |
70 | case isNoFunction: |
71 | if (saveParams) actualFunction = isFunctionA; |
72 | break; |
73 | |
74 | default:
|
75 | actualFunction = isFunctionA; // you should never get here! |
76 | break; |
77 | }
|
78 | } // end of while(1) |
79 | } // end of main() |
Ich würde ggf. noch das Ändern der Parameter und das Processing voneinandern trennen (nicht oben implementiert). Z.B.: void changeParams (paramsTypeDef *pSavedparameters, *pActualParameters, int saveMyParams) void processA/B/C(paramsTypeDef *pSavedparameters); Für das Ändern der Parameter brauchst Du dann nur eine Function, weil die bei A,B,C exakt dasselbe tut. Gruß, Stefan
Attila C. schrieb: > Ich möchte innerhalb einer main Schleife eine Funktion A aufrufen und > dieser 3 Werte übergeben, z.b. mit Schiebereglern. Dunkel der Sinn deiner Rede ist. Schieberegler sind kein Konzept der Programmiersprache C. Variablen hingegen sind es. Und Werte, die man an Funktionen übergibt, nennt man in C (und nicht nur da) üblicherweise Funktionsparameter. Ach ja: "main Schleifen" gibt es in C auch nicht. > Wenn jetzt bei Funkion A alles geregelt ist möchte ich 3 Parameter einer > Funktion B übergeben, mit den gleichen Schiebereglern. Wenn du zwei Funktionen mit den gleichen Parametern aufrufen willst, dann mach das doch einfach. > Wie schaffe ich es dass Funktion A sich die letzten Werte "merkt" ohne > dass die Werte überschrieben werden? Wenn Funktion A so definiert ist, daß sie drei Parameter erwartet, dann werden diese Parameter aus Sicht der Funktion immer überschrieben. Aber der Aufrufer der Funktion hat ja volle Kontrolle darüber, wie er die Funktion aufruft. Wenn er zweimal die gleichen Parameter verwenden will, dann kann er das selbstverständlich tun. > Wahrscheinlich ist es ganz einfach und ich stehe nur grade auf dem > Schlauch. :-( Davon ist auszugehen. So wie es sich mir darstellt, hast du noch nicht mal die Aufgabe verstanden.
Stefan K. schrieb: > Hier mein Vorschlag ohne static. Hat den Vorteil, dass Du ggf. > verschiedene Functionen wiederverwenden kannst, wenn dort eigentlich > dasselbe passiert. Ist das jetzt Satire, oder willst Du dem TO wirklich helfen? Und für uns, könntest Du nochmal den Vorteil beschreiben, den der NV-Speicher auf dem Stack gegenüber static hat?
Du mußt Dir zuerst mal ein Bedienkonzept überlegen. Also wie die Funktionen A,B,C ausgewählt werden und wann die Schieberegler übernommen werden sollen. Einfach so drauflos programmieren führt zu nichts. Auch könnte es das Verständnis wesentlich erhöhen, wenn Du sagst, was A,B,C konkret machen sollen. Abstrakte Fragestellungen helfen nur selten weiter, mit Gedankenlesen tun sich hier viele schwer.
Du solltest dir ein gutes C Buch besorgen und es durcharbeiten. Werte speichert man in Variablen. Funktionen dienen nur dazu irgendwas auszuführen, dazu brauchen sie oft Variablen und manipulieren sie, aber Funktionen "bewahren" im Allgemeinen keine Variablen auf.
Der Andere schrieb: > Funktionen dienen nur dazu irgendwas auszuführen, dazu brauchen sie oft > Variablen und manipulieren sie, aber Funktionen "bewahren" im > Allgemeinen keine Variablen auf. So ist es. In manchen Situationen vereinfachen lokale statische Variablen das Leben. Allerdings: Funktionen sollten ein reproduzierbares Verhalten zeigen. Also bei gleichen Parametern, immer das selbe Ergebnis bringen. Das macht sie leichter testbar und auch wiederverwendbar. Wenn sie lokale statische Variablen beinhalten, kann das bei unachtsamer Verwendung zu unerwünschten Seiteneffekten führen. Das wollen wir doch nicht! Oder? Einerseits ist das ein erlaubtes Sprachmittel, aber andererseits gilt auch der Spruch: "Wer einmal begriffen hat, wie ein Hammer funktioniert, für den sieht jedes Problem wie ein Nagel aus"
Achim S. schrieb: > Ist das jetzt Satire, oder willst Du dem TO wirklich helfen? Wenn ich das nicht ernst meinen würde, hätte ich mir wohl kaum die Mühe gemacht. > Und für uns, könntest Du nochmal den Vorteil beschreiben, den der > NV-Speicher auf dem Stack gegenüber static hat? * Bei static kannst Du die Werte nur innerhalb dieser Funktion benutzen. Meistens ist es aber sinnvoll, solche Parameter an mehreren Stellen verfügbar zu haben. Das kan static nicht leisten. * Bei static kann die Funktion nur einmal mit genau diesen Parametern verwendet werden. Wiederverwendbarkeit ist damit ausgeschlossen. Das Problem des TO sieht aber danach aus, dass seine Schieberegler auf genau dieselbe Weise in 3 Funktionen in unterschiedliche Parameter gesichert werden. Ob die Parameter A/B/C global oder in main() definiert werden, ist dagegen erstmal zweitrangig. In C++ liesse sich das Ganze übrigens noch deutlich eleganter lösen. Gruß, Stefan
:
Bearbeitet durch User
Erst mal an alle: Vielen Dank! Ralf G. Und Achim S. : Genau danach hatte ich gesucht! Danke! Stefan K. : Danke, aber die Werte müssen nicht weiter verändert werden. Axel Schwenke: Das ich eine Aufgabe die meinen eigenen Überlegungen entspringt nicht verstanden haben soll ist an Absurdität kaum zu überbieten! Peter Danneger: Ich habe den wahren Zweck der Anwendung nicht beschrieben um mich nicht dem allseits beliebten Bashing in diesem Forum auszusetzen. Dieser Thread wäre, wie leider so viele hier, komplett off-topic gegangen! Ansonsten ist es ,wie so oft, wie mit dem Schuhe-zubinden: Es ist gar nicht so einfach zu beschreiben. Der Andere: Die von Ralf und Achim vorgeschlagene Idee ist sicher nicht in einem C-Buch zu finden. Noch einmal vielen Dank!
@ Attila C. Mal noch ein später Hinweis: Arduino F. schrieb: > Allerdings: > Funktionen sollten ein reproduzierbares Verhalten zeigen. Also bei > gleichen Parametern, immer das selbe Ergebnis bringen. Auch ich würde die berechneten Werte außerhalb der Funktion speichern und die Funktion, wenn die Werte nicht verändert werden sollen, gar nicht erst aufrufen. Arduino F. schrieb: > Das macht sie leichter testbar und auch wiederverwendbar. Eventuell kann man dann Teile der Funktionen A, B, C, ... sogar noch zusammenfassen.
:
Bearbeitet durch User
Stefan K. schrieb: > memcpy (pSavedparameters, pActualParameters, sizeof(paramsTypeDef)); wieso nicht
1 | *pSavedParameters = *pActualParameters; |
?? Das reduziert (mindestens) eine Fehlerquelle und erlaubt dem Compiler, so zu optimieren, wie er das für richtig hält (wenn auch in vielen Fällen dasselbe rauskommt). Es ist schon sehr lange her, dass C keine struct-Zuweisungen k[a,o]nnte.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.