mikrocontroller.net

Forum: Compiler & IDEs for schleife mit uint8_t für 256 durchlaufe


Autor: Matthias Lipinsky (lippy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Leute,

Kurze Frage zur for Schleife in C.

for ( x=0; x<256; x++)
..

erzeugt ja 256, also 0..255 schleifendurchläufe.  Das ganze geht aber 
nur, wenn ich x als uint16_t deklariere. Wie kann ich das mit einem 
uint8_t erreichen?


Danke schonmal

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
do { ... } while (++x != 0);

Autor: Thomas B. (detritus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
x = 0;
do {
   //   irgendwas sinnvolles
   x++;
} while (x != 0);

P.S. zu langsam...

Autor: Gelegenheitsposter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Obiges ist ja schon fast richtig, aber immer noch off-by-one! Damit 
sollte es klappen:
uint8_t c = 0;
do{
  // please code here
}while ( ++c != 0);

Autor: Matthias Lipinsky (lippy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank.
Hätte ich auch selbst drauf kommen können....

@ Gelegenheitsposter (Gast)
Das konnte ich mir gradeso noch dazureimen ;-)

Autor: SoLaLa (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
versteh ich jetzt nicht... die Beispiele sind doch alle 3 korrekt, oder 
nicht?

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
SoLaLa wrote:
> versteh ich jetzt nicht... die Beispiele sind doch alle 3 korrekt, oder
> nicht?

Nein, mathematisch exakt sind sie alle falsch.

Wenn man x anfängt bei 0 zu zählen und immer nur erhöht, kann der Wert 
nie wieder 0 sein. Neuere Versionen von gcc erkennen das und optimieren 
entsprechend, falls nicht entsprechend beschaltert ist 
(-fno-strict-overflow).

gcc release notes state:
> For example, a loop like
>
>   for (i = 1; i > 0; i *= 2)
> 
> is presumably intended to continue looping until i overflows.
> With -fstrict-overflow, the compiler may assume that signed overflow
> will not occur, and transform this into an infinite loop.
> -fstrict-overflow is turned on by default at -O2...

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Georg johann Lay wrote:

>> versteh ich jetzt nicht... die Beispiele sind doch alle 3 korrekt, oder
>> nicht?

> Nein, mathematisch exakt sind sie alle falsch.

Es ging aber nicht um Mathematik, sondern um die Regeln der
Programmiersprache C.

Unser Mathe-Prof hatte mal erzählt, dass es einem seiner älteren
Kollegen damals völliges Unverständnis verursacht hat, in einem
FORTRAN-Programm die Zeile

I = I + 1

zu sehen.  Das ist nämlich mathematisch auch völliger Unsinn.
(Pascal hat das besser formuliert als i := i + 1.)

> Wenn man x anfängt bei 0 zu zählen und immer nur erhöht, kann der Wert
> nie wieder 0 sein.

Doch, nach den Regeln der Programmiersprache C schon.  Der OP hat
schließlich ausdrücklich von einem uint8_t geschrieben, und für
den (und nur für den) ist das Verhalten völlig exakt so definiert.

> Neuere Versionen von gcc erkennen das und optimieren
> entsprechend, falls nicht entsprechend beschaltert ist
> (-fno-strict-overflow).

Das bezieht sich nur auf signed overflow, der ist nämlich
implementation defined.  Für unsigned integer Typen sind die Regeln
eindeutig, dass der Überlauf vom jeweiligen Maximalwert nach 0
stillschweigend erfolgt.

Autor: Frank Link (franklink)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Matthias Lipinsky wrote:
> Hi Leute,
>
> Kurze Frage zur for Schleife in C.
>
> for ( x=0; x<256; x++)
> ..
>
> erzeugt ja 256, also 0..255 schleifendurchläufe.  Das ganze geht aber
> nur, wenn ich x als uint16_t deklariere. Wie kann ich das mit einem
> uint8_t erreichen?
>
>
> Danke schonmal

Hallo,
meine Vermutung, 256 passt nicht mehr in unit8_t von daher würde ich es 
mit

for ( x=0;x<=255;x++)

versuchen.

x nimmt in der ursprüngliche Schleife ja in jedem Fall den Wert 256 an.

Kann natürlich sein, dass ich vollkommen falsch liege.

Gruß
Frank

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Frank Link wrote:

> Kann natürlich sein, dass ich vollkommen falsch liege.

Du liegst vollkommen falsch.

Wenn x ein uint8_t ist, gibt es keinen Wert für x, der
die Bedingung  x <= 255 nicht erfüllen würde -> du hast eine
Endlosschleife.

Autor: Matthias Lipinsky (lippy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Kann natürlich sein, dass ich vollkommen falsch liege.
>for ( x=0;x<=255;x++)

Hm.. Solche "Versuche" habe ich vor meinem Posting hier auch schon 
gemacht:
for ( x=0;++x!=255;)
..
for ( x=0;x<255;++x)

Autor: Kai G. (runtimeterror)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mit einer reinen for-Schleife kann das gar nicht gehen, da diese 
kopfabweisend ist. Sie erlaubt nur 0 bis 255 Durchläufe. Eine 
fußabweisende Schleife erlaubt 1 bis 256 Durchläufe und ist deshalb auch 
vorgeschlagen worden.

Man könnte auch eine Schleife mit 255 Durchläufen verwenden und den 
wiederholten Ausdruck im Anschluss an die Schleife erneut einmal 
ausführen - bringt aber hier keinen Nutzen.

>>Nein, mathematisch exakt sind sie alle falsch.

>Es ging aber nicht um Mathematik, sondern um die Regeln der
>Programmiersprache C.

Selbst rein mathematisch betrachtet ist das korrekt (schließlich ist die 
Informatik nur eine Spezialisierung der Mathematik ;) ) - die Rechnungen 
erfolgen halt alle modulo 256.
Guckst du hier: 
http://de.wikipedia.org/wiki/Kongruenz_%28Zahlentheorie%29

Autor: Frank Link (franklink)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stimmt, wenn ich nochmal über meine Antwort nachdenke, komme ich zu der 
gleichen Erkenntnis.

Wie war das, "zuerst den Kopf einschalten und dann schreiben".

Danke, späte Erkenntnis ist auch eine Erkenntnis.

Gruß
Frank

Autor: Kai G. (runtimeterror)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Wie war das, "zuerst den Kopf einschalten und dann schreiben".

Macht nix - dafür war ja dein Disclaimer ;)

>Kann natürlich sein, dass ich vollkommen falsch liege.

Schönes Wochenende,
Kai

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.