Forum: Compiler & IDEs for loop, wird wie oft durchlaufen?


von Michi (Gast)


Lesenswert?

Ansich eine ganz simple sache:

for(uint8_t i = 0 ; i < 255 ; i++){

send_uart('X');

}

Wieviele zeichen werden gesendet?

Ich könnte schwören ich empfange 255 Zeichen.

Wie muss die Schleife aussehen um 256 zeichen zu Empfangen?

von Bernhard R. (barnyhh)


Lesenswert?

Michi schrieb:
> Ansich eine ganz simple sache:
>
> for(uint8_t i = 0 ; i < 255 ; i++){
>
> send_uart('X');
>
> }
>
> Wieviele zeichen werden gesendet?
>
> Ich könnte schwören ich empfange 255 Zeichen.

Die Mathematik stimmt: 255 Schleifendurchläufe!

Für 256 Durchläufe:

for (uint16_t i = 0 ; i < 256 ; i++)   {
   send_uart('X');
}

Bernhard

von Andreas B. (andreas_b77)


Lesenswert?

255 Durchläufe ist richtig. Für 256 Durchläufe muss die Bedingung halt 
"i <= 255" heißen.

Zählen ab 0 muss man als Programmierer halt intus haben.

Edit: Äh passt wegen uint8_t nicht, da wird die Schleife nie beendet. 
Entweder nicht auf uint8_t beschränken, oder die Schleife umbauen:
1
uint8_t i = 0;
2
3
while (1) {
4
    send_uart('X');
5
    if (i == 255) break;
6
    i++;
7
}

von Floh (Gast)


Lesenswert?

Andreas B. schrieb:
> Für 256 Durchläufe muss die Bedingung halt
> "i <= 255" heißen.

Aber nur mit passendem Datentyp. Bei einem uint8_t ist <= 255 immer 
erfüllt, das ist der Haken an der Geschichte. :-)

von Gerhard K. (Gast)


Lesenswert?

Michi schrieb:

> Ansich eine ganz simple sache:
>
> for(uint8_t i = 0 ; i < 255 ; i++){
>
> send_uart('X');
>
> }

oder du initialisierst mit 255. Da es sich ja um eine uint8_t handelt 
kommt nach 255 -> 0 und somit hast du 256 Durchläufe.

for(uint8_t i = 255 ; i < 255 ; i++){
  send_uart('X');
}

von Stefan E. (sternst)


Lesenswert?

Gerhard K. schrieb:
> oder du initialisierst mit 255. Da es sich ja um eine uint8_t handelt
> kommt nach 255 -> 0 und somit hast du 256 Durchläufe.
>
> for(uint8_t i = 255 ; i < 255 ; i++){
>   send_uart('X');
> }

Nein, die Schleife hat genau 0 Durchläufe.

von Gerhard K. (Gast)


Lesenswert?

Sorry, das geht ja auch nicht, da läuft die Schleife ja nie los.

von Marcus B. (raketenfred)


Lesenswert?

Bernhard R. schrieb:
> for (uint16_t i = 0 ; i < 256 ; i++)   {
>    send_uart('X');
> }

ich frage mich, warum muss man trotz dieser einfachen und für mich guten 
Lösung, noch so komische Konstrukte bauen?!

Die Konstrukte reduzieren doch nur die Lesbarkeit und führen zu Fehlern 
beim Programmieren ?!

von Mark B. (markbrandis)


Lesenswert?

Vielleicht ist die Zielhardware ein kleiner 8-Bit-Controller mit sehr 
knappem Speicher? Wenn ein Byte ausreicht, nimmt man keine zwei.

von Bernhard R. (barnyhh)


Lesenswert?

Marcus B. schrieb:
> ich frage mich, warum muss man trotz dieser einfachen und für mich guten
> Lösung, noch so komische Konstrukte bauen?!

DANKE!
Das tat mir sehr gut.

Mark Brandis schrieb:
> Vielleicht ist die Zielhardware ein kleiner 8-Bit-Controller mit sehr
> knappem Speicher? Wenn ein Byte ausreicht, nimmt man keine zwei.

Das ist die typische Frickler-Lösung. Diese Art "Lösung" führt sehr 
schnell zu unwartbaren Systemen - in einer professionellen Umgebung 
nahezu tödlich.

Auch und gerade bei Software gilt der Grundsatz "Erst richtig machen und 
dann ganz ganz vielleicht optimieren!"

Einen schönen Sonntag noch!
Bernhard

von Michi (Gast)


Lesenswert?

Ich möchte hier in ein At45DB flash rein schreiben, er ist auf 256 
Bytes/Page gestellt. Und ich bekomme da je Page auch Tatsächlich 256 
Bytes rein. (wer hätte das gedacht :-)   ) aber beim Auslesen nur 255 
zurück was ärgerlich ist :-)

von MWS (Gast)


Lesenswert?

Michi schrieb:
> aber beim Auslesen nur 255
> zurück was ärgerlich ist :-)

"for" ist hier in Kombination mit einem 8-Bit Zähler ungeeignet, das 
hier würde gehen:
1
uint8_t i = 256; // i => 1 && i <= 256
2
  do {
3
     // ...
4
     i--;
5
     } while (i);

von was muss hier bloss rein? (Gast)


Lesenswert?

>uint8_t i = 256;
Janeisklar...

von MWS (Gast)


Lesenswert?

was muss hier bloss rein? schrieb:
>>uint8_t i = 256;
> Janeisklar...

Hatte den Kommentar warum das so funktioniert wieder gelöscht, dachte 
mir die Antworten werden interessanter :D
Versuch's nochmal.

von was muss hier bloss rein? (Gast)


Lesenswert?

Verflixt. Das funktioniert tatsächlich. Nur ist die Zuweisung trotzdem 
irreführend, da kann man auch 0 statt 256 schreiben (und gleich die 
Compilerwarnung verhindern).

Sehr nett...

von MWS (Gast)


Lesenswert?

was muss hier bloss rein? schrieb:
> Nur ist die Zuweisung trotzdem irreführend,

Nur ein bisserl ;-)

von Holger (Gast)


Lesenswert?

Aber guter Stil ist das nicht wirklich. Wer da nur flüchtig drauf schaut 
und sich denkt ... hmm.. jetzt soll die Schleife aber 257 mal laufen und 
das dann statt 256 hinschreibt wird wohl ein Problem bekommen.

Wartbarer Code ist jedenfalls anders.

von Schuhplattler Sepp, Oberammergau (Gast)


Lesenswert?

for(uint8_t i = 0 ; i != 255 ; i++){

send_uart('X');

}
send_uart('X');

von Klaus W. (mfgkw)


Lesenswert?

256 Durchläufe bekommt man mit einer uint8_t auch so hin, ohne den 
Schleifenrumpf kopieren zu müssen:
1
  uint8_t    i = 0;
2
  do
3
  {
4
    send_uart('X');
5
    ++i;
6
  }
7
  while( i!=0 );

von 900ss (900ss)


Lesenswert?

Michi schrieb:
> for(uint8_t i = 0 ; i < 255 ; i++){
>
> send_uart('X');
>
> }

> Wie muss die Schleife aussehen um 256 zeichen zu Empfangen?

Mit der Originalschleife leicht modifiziert:
1
for(uint8_t i = 0 ; i <= 255 ; i++){
2
3
  send_uart('X');
4
5
}

von Stefan E. (sternst)


Lesenswert?

900ss D. schrieb:
> Michi schrieb:
>> for(uint8_t i = 0 ; i < 255 ; i++){
>>
>> send_uart('X');
>>
>> }
>
>> Wie muss die Schleife aussehen um 256 zeichen zu Empfangen?
>
> Mit der Originalschleife leicht modifiziert:
1
for(uint8_t i = 0 ; i <= 255 ; i++){
2
3
  send_uart('X');
4
5
}

Das ist eine Endlosschleife.

von was muss hier bloss rein? (Gast)


Lesenswert?

900ss D. schrieb:
> Mit der Originalschleife leicht modifiziert:
>
1
> for(uint8_t i = 0 ; i <= 255 ; i++){
2
> 
3
>   send_uart('X');
4
> 
5
> }
6
>

Da sagt mein GCC
>main.c|9|warning: comparison is always true due to limited range of data type|

von 900ss (900ss)


Lesenswert?

was muss hier bloss rein? schrieb:
> Da sagt mein GCC
>>main.c|9|warning: comparison is always true due to limited range of data type|

Garantiert nicht :-)

von Stefan E. (sternst)


Lesenswert?

900ss D. schrieb:
> was muss hier bloss rein? schrieb:
>> Da sagt mein GCC
>>>main.c|9|warning: comparison is always true due to limited range of data type|
>
> Garantiert nicht :-)

Garantiert doch. Ein uint8_t ist immer <=255.

von 900ss (900ss)


Lesenswert?

Ja ja ja... :-)

Das geht natürlich nicht was ich da oben
Beitrag "Re: for loop, wird wie oft durchlaufen?"
gepostet habe.
Das kommt wenn man mal eben schnell....

von MWS (Gast)


Lesenswert?

Holger schrieb:
> Wer da nur flüchtig drauf schaut
> und sich denkt ... hmm.. jetzt soll die Schleife aber 257 mal laufen und
> das dann statt 256 hinschreibt wird wohl ein Problem bekommen.

Wer dabei so flüchtig schaut, daß er selbst den Kommentar übersieht:
1
uint8_t i = 256; // i => 1 && i <= 256
ist mit weniger anspruchsvollen Tätigkeiten sicher besser bedient.

von Holger (Gast)


Lesenswert?

@MWS:
Genau, und wer für so eine triviale Aufgabenstellung Code schreibt, der 
eines Kommentares bedarf...

von Karl H. (kbuchegg)


Lesenswert?

MWS schrieb:
> Holger schrieb:
>> Wer da nur flüchtig drauf schaut
>> und sich denkt ... hmm.. jetzt soll die Schleife aber 257 mal laufen und
>> das dann statt 256 hinschreibt wird wohl ein Problem bekommen.
>
> Wer dabei so flüchtig schaut, daß er selbst den Kommentar übersieht:
>
1
uint8_t i = 256; // i => 1 && i <= 256
> ist mit weniger anspruchsvollen Tätigkeiten sicher besser bedient.

Um ehrlich zu sein:
Bei dem Kommentar hab ich mich als erstes gefragt: Was will mir dir 
Dichter sagen?
Oder in der Kurzform: Hä?

von MWS (Gast)


Lesenswert?

Holger schrieb:
> Genau, und wer für so eine triviale Aufgabenstellung Code schreibt, der
> eines Kommentares bedarf...

Jetzt hab' ich mir den Thread doch nochmal durchgesehen, um auch Deine 
Vorschläge zur "trivialen Aufgabenstellung" zu finden. Gab nur keine.

Mein Kommentar war für die Anfänger hier gedacht, einem durchschnittlich 
begabten C-Programmierer traue ich auf jedem Fall zu dieses 
Codeschnipselchen ohne Kommentar zu verstehen.

Wenn Dir das aber zu kompliziert ist, ich erkläre es Dir gerne ;D

von MWS (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Bei dem Kommentar hab ich mich als erstes gefragt: Was will mir dir
> Dichter sagen?
> Oder in der Kurzform: Hä?

Karl Heinz, das ist aber nun wirklich nicht schwer, eine 
Gültigkeitsbereich für i, größer/gleich 1 und kleiner/gleich 256. Was 
soll denn da nicht zu verstehen sein ?

von Klaus W. (mfgkw)


Lesenswert?

Dann bin ich auch eher für weniger anspruchsvolle Tätigkeiten geeignet.
Selbst bei mehrmaligem Lesen verstehe ich nicht, was der Kommentar soll.

Verstanden hätte ich noch:
// 0 ... 255

von 900ss (900ss)


Lesenswert?

Klaus Wachtler schrieb:
> Dann bin ich auch eher für weniger anspruchsvolle Tätigkeiten geeignet.

Nach meinem Patzer oben halte ich mich da lieber raus ;-)

von MWS (Gast)


Lesenswert?

Klaus Wachtler schrieb:
> Selbst bei mehrmaligem Lesen verstehe ich nicht, was der Kommentar soll.

Jetzt war ich der Überzeugung, daß ein C-Programmierer so etwas auflösen 
kann, wenn's der C-Kompiler selbst auch kann. Möglicherweise habe ich 
das überschätzt.

> Verstanden hätte ich noch:
> // 0 ... 255

Aber gerne.
1
uint8_t i = 256; // 1 ... 256
Besser ?

War aber 'ne Denksportaufgabe, eine Zuweisung von 256 an eine 
vorzeichenlose 8bit-Variable war natürlich zuerst einmal geeignet 
Widerspruch zu erzeugen, dann evtl. drüber nachzudenken. Und mit einem 
bisserl Nachdenken ist zumindest meiner Einschätzung nach der Kommentar 
kein Problem. Aber das ist wohl Ansichtssache.

von Klaus W. (mfgkw)


Lesenswert?

Auch mit diesem Kommentar (egal in welcher deiner beiden Versionen) kann 
ich nicht so recht nachvollziehen, wieso man eine uint8_t mit 256 
vergewaltigen muß.

Einen Kommentar, der das erklärt, fände ich sinnvoll. Wenn es denn 
wirkllich einen guten Grund dafür gibt.

von Karl H. (kbuchegg)


Lesenswert?

MWS schrieb:
> Klaus Wachtler schrieb:
>> Selbst bei mehrmaligem Lesen verstehe ich nicht, was der Kommentar soll.
>
> Jetzt war ich der Überzeugung, daß ein C-Programmierer so etwas auflösen
> kann, wenn's der C-Kompiler selbst auch kann.

Nein, nein.
Mit dem Code hab ich keine Schwierigkeiten, das ist nicht das Problem.

>> Verstanden hätte ich noch:
>> // 0 ... 255

geht mir auch so. Wobei ich diesen Gültigkeitsbereich weggelassen hätte. 
Viel lieber wär mir ein kleiner Kommentar gewesen, der mir kurz und 
knackig erzählt, dass der Code absichtlich einen Unterlauf von 0 auf 255 
im ersten Durchlauf provoziert. Wenn schon ein Kommentar angebracht 
erscheint.

von Karl H. (kbuchegg)


Lesenswert?

Ich nehm alles zurück:

Ich hab jetzt verstanden was du mit dem Kommentar aussagen wolltest.

In Langform heißt der:

Bitte hier die Anzahl der gewünschten Wiederholgen eintragen. Die Anzahl 
darf zwischen 1 und 256 (jeweils inklusive) betragen.

von MWS (Gast)


Lesenswert?

Klaus Wachtler schrieb:
> Auch mit diesem Kommentar (egal in welcher deiner beiden Versionen) kann
> ich nicht so recht nachvollziehen, wieso man eine uint8_t mit 256
> vergewaltigen muß.
> Einen Kommentar, der das erklärt, fände ich sinnvoll. Wenn es denn
> wirkllich einen guten Grund dafür gibt.

Nun, wenn der Kommentar alles mundklein vorkaut, wo sollte da dann die 
Aufgabe sein ?

von Klaus W. (mfgkw)


Lesenswert?

Fan von IOCCC?

von MWS (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> geht mir auch so. Wobei ich diesen Gültigkeitsbereich weggelassen hätte.
> Viel lieber wär mir ein kleiner Kommentar gewesen, der mir kurz und
> knackig erzählt, dass der Code absichtlich einen Unterlauf von 0 auf 255
> im ersten Durchlauf provoziert.

Ich wollte daß die Leute selbst drauf kommen, deshalb konnte ich das 
nicht ausführlichst breittreten, wollte aber dennoch einen Hinweis 
geben, damit niemand auf die Idee kommt das Ding mit 0 oder 512 zu 
füttern.

Genau hätte mein Kommentar lauten müssen:
"Wird in diesem Code die Variable mit 0 oder 256 (woraus der Compiler o 
macht) initialisiert, so resultieren daraus 256 Schleifendurchläufe. 
Werte zwischen 1 und 255 führen zu 1 bis 255 Durchläufen."

Wär' doch langweilig gewesen :)

von MWS (Gast)


Lesenswert?

Klaus Wachtler schrieb:
> Fan von IOCCC?

Nein, finde ich zwar höchst interessant was da so ausgebrütet wird, aber 
das Einzige was an meinem Code wirklich zu kritisierbar ist, wäre die 
Übergabe eines zu großen Wertes an eine zu kleine Variable.

Den Hintergrund dazu habe ich bereits genannt.

Dein Code ein paar Posts unter meinem sieht im Übrigen genauso aus, nur 
mit dem Unterschied daß bei meinem Code in i die gewünschte Anzahl 
Schleifendurchläufe stehen darf, und ich das while kürzer gehalten hab', 
anstatt von:

Klaus Wachtler schrieb:
> while( i!=0 );

Ist alles zulässig, Codeobfuscating kannst Du mir deswegen hier nicht 
vorwerfen. :D

von Klaus W. (mfgkw)


Lesenswert?

MWS schrieb:
> Ist alles zulässig, Codeobfuscating kannst Du mir deswegen hier nicht
> vorwerfen. :D

Nein, das will ich ja auch gar nicht.
Das einzige, was ich sagen wollte, ist: wenn man schon einen Kommentar 
spendiert, dann doch warum man willkürlich und bewusst den Wertebereich 
überschreitet.

von Random .. (thorstendb) Benutzerseite


Lesenswert?

Klaus Wachtler schrieb:
>> Ist alles zulässig, Codeobfuscating kannst Du mir deswegen hier nicht
>> vorwerfen. :D
1
uint8_t i=0;
2
do{
3
  send_uart('X');
4
} while( ++i );

:-)

von Klaus W. (mfgkw)


Lesenswert?

Random ... schrieb:
> Klaus Wachtler schrieb:
>>> Ist alles zulässig, Codeobfuscating kannst Du mir deswegen hier nicht
>>> vorwerfen. :D

Das war gar nicht von mir ...

Random ... schrieb:
> uint8_t i=0;
> do{
>   send_uart('X');
> } while( ++i );

Das war von mir, bezog sich aber auf die Ausgangsfrage (wie man mit 
einer uint8_t 256 Durchläufe hinbekommt), und nicht auf die Diskussion, 
welche Kommentare sinnvoll sind.

Abgesehen davon halte ich sowieso nichts davon, im Regelfall Datentypen 
derart überzustrapazieren (von wenigen Ausnahmen abgesehen).

von stru_aus (Gast)


Lesenswert?

256 mal?

for(uint8_t i = 0 ; i < 128 ; i++){
send_uart('X');
send_uart('X');
}

:D

von MWS (Gast)


Lesenswert?

Klaus Wachtler schrieb:
> Random ... schrieb:
>> uint8_t i=0;
>> do{
>>   send_uart('X');
>> } while( ++i );
>
> Das war von mir, bezog sich aber

Nein, das war nicht von Dir, dieser Code war von Random.

Das hier war von Dir:

Klaus Wachtler schrieb:
> 256 Durchläufe bekommt man mit einer uint8_t auch so hin, ohne den
> Schleifenrumpf kopieren zu müssen:  uint8_t    i = 0;
>   do
>   {
>     send_uart('X');
>     ++i;
>   }
>   while( i!=0 );

Sehr confuscating :D

von Michi (Gast)


Lesenswert?

uuuh, da hab ich ja was los getreten.
Vielen Dank für die ganzen Antworten

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
Noch kein Account? Hier anmelden.