PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Frage zu for-Schleife



jagdfalke
28.11.2005, 21:30
Hi,
sagem wir mal ich will eine Schleife von x nach y schreiben. Ich weiß aber nicht, ob x größer oder kleiner als y ist. Gibts ne einfache Möglichkeit das so zu schreiben, dass ich nicht immer ne if-Abfrage machen muss um herauszufinden ob x inkrementiert oder dekrementiert werden muss???



int i=0;
for(i=x; i<=y; ??) {
/* ... */
}


In Bascom ging das indem man hinter "STEP" ne Variable gehängt hat, die -1 bzw +1 enthielt. Gibts sowas ähnliches auch in C?

mfg
jagdfalke

linux_80
28.11.2005, 23:39
Wenn man nicht weiss welcher Wert grösser ist, kann man die Abfrage in der Mitte nur auf != abfragen, sonst läuft die Schleife evtl. länger als vorgesehen.
Ansonsten könnte man schon hinten schreiben i=i+step, und step auf -1 setzen.
Evtl. gehts auch so:

for(i = x; i != y; i+= (x<y ? 1: -1))

jagdfalke
29.11.2005, 08:43
danke, das mit dem != hätte ich eigentlich auch rausfinden müssen aber "i+= (x<y ? 1: -1)" !? Kannst du mal erklären was der da macht?

mfg
jagdfalke

PicNick
29.11.2005, 09:59
Das ist "if else " ohne "if else"
i += (x<y ? 1: -1)
if (x < y) i += 1; else i -= 1;


EDIT: Noch was: Das macht er bei jeder schleife, also high-performance ist das nicht

jagdfalke
29.11.2005, 17:39
Also schreibe ich das einmal vor die Schleife und in die Schleife dann i+=i. So müsste es dann gehen. Danke.

askazo
29.11.2005, 18:16
Geht auch einfacher:


for(i=0; i<(abs(x-y)); i++)

askazo

jagdfalke
29.11.2005, 19:41
hä? Wenn ich i von 0 an laufen lassen soll und dann die Servoposition gleich i setzt kommt doch bewegungstechnisch nur Shice raus. Dann springt der immer auf 0 und dann zur Differenz.

askazo
30.11.2005, 09:23
Ach so, wenn Du in der Schleife die Werte von x bzw. y brauchst, geht das so natürlich nicht.
Wußte ja nicht, dass es für ne Servoansteuerung ist....

Dann ist die Lösung von Linux schon ok.

Also schreibe ich das einmal vor die Schleife und in die Schleife dann i+=i. So müsste es dann gehen.
Das wäre allerdings Blödsinn.
i wird ja schon in der Schleifendeklaration (kann man das so nennen?) inkrementiert bzw. dekrementiert....

askazo

jagdfalke
30.11.2005, 12:02
Also ich glaube wir reden etwas aneinander vorbei:


int move_elbow_to(int dest_pos) {
int step = 0;
if(elbow_pos > dest_pos) { step=-1; }
if(elbow_pos < dest_pos) { step=1; }
if(step == 0) { return 1; }

int i=0;
for(i=elbow_pos; i!=dest_pos; i += step) {
move(3, i);
}
elbow_pos = i;
return 0;
}

So hab ich mir das gedacht. So gehts jedenfalls. Kann man den Code noch optimieren?

mfg
jagdfalke

PicNick
30.11.2005, 12:29
Du kannst ein bißchen sparen:


int move_elbow_to(int dest_pos)
{
int step = 1;
if(elbow_pos > dest_pos) step=-1;
while (elbow_pos !=dest_pos)
{
elbow_pos += step;
move(3, elbow_pos);
}
return 0;
}

DU nimmst einfach +1 an, nur wenn < angesagt ist, mußt du das noch ändern.
Auf pos == dest fragt ja eh' schon die while-schleife ab, brauchst du nicht extra nochmal "iffen"

"i" ist überflüssig.

der erste move wäre mit der alten position --> also sinnlos

daher bleibt für ein "for" nix über, also while

der step VOR dem move

btw:
Du solltest "step" gleich definieren wie elbow_pos, also nicht unbedingt "int", wenn vielleicht pos nur ein char ist

Nicht berücksichtigt, was es mit dem Return-value auf sich hat, sonst kann man das auch noch schmeissen

PicNick
30.11.2005, 12:37
Ach ja, noch was: Der Kollege fetzt bei dieser Lösung den Ellenbogen auf "dest", so schnell er nur kann. Das ist für das gesamte Gerät möglicherweise nicht so gut.
Eigentlich solltest du das mit timer in festen Abständen machen

Betrifft aber dein gesamtkonzept, d.h. ich kann das nicht beurteilen

linux_80
30.11.2005, 12:40
Also ich hätte jetzt gemeint, keine Globalen Variablen in der Schleife, denn diese werden meist im SRAM gehalten, und müssen zum bearbeiten erst von dort gelesen und danach wieder geschrieben werden.
Daher könnte es evtl. schneller sein, wenn man vorher in eine lokale variable kopiert, mit dieser in der Schleife arbeitet, und erst am Ende wieder ein die Globale zurück ?!

PicNick
30.11.2005, 12:44
Das ist z.T. nicht unrichtig, aber das frißt der GCC+Optimizer sowieso, den muß man eher prügeln, damit er überhaupt was in den SRAM schreibt (volatile)

Andererseits kommt ein Servo mit dieser Schleife sowieso nicht mit. Extra tunen müßt' man garnicht.

Weil ich heut' grad' so besonders gescheit bin:
Bei global hat er eine Chance, mit einen wert direkt ins ein Register zu lesen, bei lokalen Variable MUSS er indirekt laden

jagdfalke
30.11.2005, 12:48
Ja das wollte ich gerader posten. Selbst wenn ich kein delay einbaue gehts viel langsamer als wenn ich einfach direkt den Endwert übergebe.
Ok, dann hätte ich/wir den ersten Schritt schonmal geschafft. Dann gehts auf zum multithreading (anderer thread).

mfg
jagdfalke