If Schleife Abbruchbedingung aus Variable einsetzen

Kann mir einer sagen wie ich die Abbruchbedingung von einer Variabel übergeben kann?

for (int i=0; i<10; i++)

Jetzt die 10 bei i<10

for (int i=0; i<maxWasauchimmer; i++)

Gerne auch mit Funktion:

for (int i=0; i<sizeof(werte); i++)

Also wenn ich jetzt

int abbruch = 25; schreibe

dann gehts so weiter

for (int i=0; i<abbruch; i++)

Ist das so richtig?

Jawoll, bei "abbruch = 25" zählt er dann in deinem Beispiel von 0...24
Weil 24 kleiner als 25 ist ..
Man kann auch schreiben for( int i = 0; i <= 25; i++ )
Dann geht die Schleife von 0..25

devrim:
Ist das so richtig?

Ja :slight_smile:

int anfang=0, ende=25;
for (int i=anfang; i<ende; i++)

Das kann innerhalb von Funktionen sinnvoll sein.

Puristen würden anstelle int eventuell byte nehmen. Das hängt vom Drumherum ab.

agmue:
Gerne auch mit Funktion:

for (int i=0; i<sizeof(werte); i++)

sizeof ist ein Operator, keine Funktion. Auch wenn er oft aussieht wie eine Funktion.
Es ist nötig den Ausdruck zu klammern, wenn er einen Typnamen angibt, bei Ausdrücken oder Variablennamen geht es auch ohne.

Puristen würden anstelle int eventuell byte nehmen. Das hängt vom Drumherum ab.

Ich glaube, mit dieser Aussage muss man ein wenig vorsichtig sein...

Eigentlich gehöre ich selbst auch zu diesen Puristen und setze gerne dort ein "Byte" ein, wo die Zahlenwerte definitiv im Bereich 0..255 liegen. Warum auch nicht? Alles kein Thema, auch bei For-Schleifen.

Ja, aber....

Und genau das hat mir letztens nämlich viel Zeit und Nerven gekostet: Im Höhenflug vieler Programmier-Erfolge habe ich dann auch mit Stolz geschwellter Brust ein "byte" genommen, um einen Zähler von X nach 0 herunterzuzählen... und habe mich gewundert, warum mein Programm zum Verrecken nicht funktionieren wollte. Oder was kann daran falsch sein, wenn ich schreibe:

for( byte k = 16; k >= 0; k--) {...}

Falsch ist an dieser Stelle definitiv die Verwendung von "byte"!

Denn wenn er bei 0 angekommen ist, macht er munter bei 255 weiter und decrementiert lustig bis ans Ende aller Tage - oder bis man ihm den Strom abdreht. Erst der Einsatz von "int" in Verbindung mit dem Decrement löste das Problem!

Warum das im Detail so ist, oder ob ich hier noch 'n Denkfehler mache, das kann ich nicht sagen. Was in PHP, Pascal (mit Downto...) oder Javascript wunderbar und ohne nachzudenken funktioniert - stellt mir hier beim Arduino manchmal schnell ein Beinchen...

Falsch ist an dieser Stelle definitiv die Verwendung von "byte"!

Nein!
Da hast du den falschen Schuldigen identifiziert.

Falsch ist die Verwendung von k >= 0
Wenn du bei 0 stoppen möchtest, hat das so k > 0 auszusehen.

Außerdem:
Es gibt ja auch noch Vorzeichen behaftete 8Bit Typen.

Wenn du bei 0 stoppen möchtest, hat das so k > 0 auszusehen.

Dann ist der letzte zurückgegebene Wert doch 1

Ich möchte aber bis 0 runterzählen. Und als mit Vorzeichen behaftete 8-Bit-Werte kann ich hier doch nur "char" nehmen, was aber auch wieder nur einen Wertbereich von -128...+127 hat? Da blieben dann Zählschleifen von z.B. 200...0 außen vor...

Es ist ja auch nur ein Problem bei 0 als Ziel. Eine Byte-Schleife von 200...5 oder 99..1 klappt ja, nur eben 0, das klappt so wie ich es analysiert habe nur bei Integer.

*Nachsatz, gerade noch mal getestet:
Sicherlich kann ich for( char k... ) nutzen, dann bleibt er tatsächlich bei 0 so wie ich es möchte. Aber nur halt von maximal +127 aus. Alles andere ist dann wieder Murks.

Auch interessant...

Das Problem mit 0 scheint bei allen "unsigned" Typen zu existieren. Das wird wohl daran liegen, wie es intern dann in Maschinen-Code umgesetzt wird. Solange ich Vorzeichen behaftete Typen nehme kann ich für for( ... k-- ) auch die 0 auswerten.

Unterstreicht aber wieder obige Aussage, dass man mit "Byte" in diesem Fall vorsichtig umgehen sollte.

RudiDL5:
Das Problem mit 0 scheint bei allen "unsigned" Typen zu existieren. Das wird wohl daran liegen, wie es intern dann in Maschinen-Code umgesetzt wird. Solange ich Vorzeichen behaftete Typen nehme kann ich für for( ... k-- ) auch die 0 auswerten.

Das ist natürlich Voodoo bzw Aberglaube.

Es gibt 'kein Problem mit der 0' bei unsigned, lediglich liefert der Vergleich >= 0 immer true.

Wenn du unsigned Variablen als Schleifenindex (mit 0) nutzen willst, könntest du

  • aufwärts zählen
  • innerhalb der Schleife mit Schleifenindex-1 arbeiten
  • do while benuten

Das ist natürlich Voodoo bzw Aberglaube.

Gleichgültig wie manche Spezialisten das bezeichnen mögen...

Tatsache ist und bleibt, dass ich in vielen anderen Hochsprachen und Assemblern nie über so etwas gestolpert bin. Wenn ich zig Jahre for( 100...0 ) perfekt ausgewertet bekommen habe, gehe ich erstmal davon, dass das hier genau so geht - was aber bei "unsigned" nicht der Fall zu sein scheint. Da muss man(n) sich halt nur dran gewöhnen und im Hinterkopf behalten. Ist ja auch kein größeres Problem.

Und warum soll ich hochzählen, wenn ich runterzählen will?? Oder muss?? Sicherlich führen mittels "while..." oder andere Konstruktionen viele Wege nach Rom - aber man beschreitet doch erst mal die Wege, die man gewohnt ist und die man liebgewonnen hat. Oder irre ich da?

Und wieder unterstreicht es obige Aussage, dass man in diesem speziellen Fall mit "byte" (was ja auch unsigned ist) etwas vorsichtig sein sollte.

Nimm int und alles ist wie gewohnt.

Wenn du unsigned Variablentypen benutzt und >=0 als Abbruchbedingung einsetzt,
kannst du dem Compiler oder der Sprachdefinition keinen Vorwurf machen.

Ich mache dem armen Compiler ja gar keinen Vorwurf :smiley: Man(n) muss sich nur halt an diverse Eigenheiten hier gewöhnen. Das ist alles - und in Zukunft beim Runterzählen "signed" Typen verwenden. Mehr wollte ich doch gar nicht sagen. :wink:

Das Problem mit 0 scheint bei allen "unsigned" Typen zu existieren

Ja klar, denn das Problem ist in deinem Kopf:
Ein unsigned ist definitionsgemäß nie < 0, und immer >= 0.

Du könntest, wenn deine Schleife wirklich 17 mal laufen muss und du unbedingt
for( byte k = 16; k >= 0; k--)    verwenden willst,
am Ende des Blocks den Abbruch einbauen.

for( byte k = 16;; k--) {
   ...
   if (k==0) break;
}

Das mit der if-Schleife hatten wir erst neulich :wink:

if (k==0) break;

So etwas schwebte mir auch vor.

Das mit der if-Schleife hatten wir erst neulich :wink:

Das stammt aber NICHT von mir... ich kenne den Link, hatte es mir aber verkniffen ihn einzusetzen
:smiley:

Hier zählt er mir in 20 er Schritten hoch.
Warum macht er dies? Ist das var nicht was eigenständiges?

int abbruch = 20;
int var = 0;

void loop()
{

 for (int i=0; i<abbruch; i++)
 var++;
 digitalWrite(2, HIGH);
 delay(1000);
 digitalWrite(2, LOW);
 delay(1000);
 lcd.setCursor(0,0);
 lcd.print("                     ");
 lcd.setCursor(0,0);
 lcd.print(var);

}

Weil deine For - Schleife falsch geklammert ist !

Du (d.h. dein Atmega) führt nur 25 x digitalWrite(2, HIGH); aus
Das i (der Schleifenzähler) ist nur in der for-Schleife bekannt,
daher geht das lcd.print(i) schief bzw. der Compiler meckert.
Also hinter die for-Schleife ein {
und nach dem lcd.print(i); eine } dann gehts.

Ich halte übrigens nicht viel von dieser "spät Deklariererei" in diesem fall in der For-schleife.
Das ist meines Erachtens viel zu fehleranfällig.
Was man braucht wird zu beginn einer Methode oder Funktion deklariert und basta.
Als in diesem Fall nach loop() { int i;

Ulli

Jetzt hast du während ich schreibe geändert, aber der Fehler bleibt im Prinzip der gleiche.

Ja ich lerne gerade noch. Das sind so ziemlich meine ersten Schritte.

Ich halte übrigens nicht viel von dieser "spät Deklariererei" in diesem fall in der For-schleife.
Das ist meines Erachtens viel zu fehleranfällig.

Och, da bin ich eher anders rum...
:wink:
Ich versuche Variablen möglichst weit lokal zu halten.
Gültigkeitsbereiche einengen.
Das ist meines Erachtens viel weniger fehleranfällig, als zu ausgedehnte Gültigkeitsbereiche.