[ATmega32] Verlassen der Schleife verlässt alle Schleifen

Gast #1007942
Ich versteh nicht warum, aber sobald er die innerste while Schleife 
durchlaufen hat, verlässt er automatisch alle anderen Schleifen auch. 
Als wäre irgendwo ein riesen break; versteckt. Die vorherige wird aber 
noch bis zum Ende durchlaufen. Also in der for () wird PORTC noch auf 0 
geschalten, und die 1. while Schleife noch 1x X erhöht. Aber er 
durchläuft while kein weiteres mal. Ich versteh nicht, warum nicht 
wieder normal die vorherigen Schleifen weiterlaufen, sondern beendet 
werden. gcc meldet keine Fehler und übertragen kann ich es normal.

Der Code dient jetzt nur zum Testen einiger 7-Segmentanzeigen. Im code[] 
Array sind die verschiedenen Segmentcodes gespeichert.
Es soll:
- eine Zahl anzeigen (while1)
- die innereste while 20x durchlaufen lassen
- in der 1. while die nächste Zahl anzeigen
- wieder innerste while, usw.
- das ganze 2x; dafür die for()

i, x und y sind deklariert als int.
1
for (i=0; i<2;i++) {
2

3

4
char code[] = {0xF9, 0x88, 0xB5, 0x9D, 0xCC, 0x5D, 0x7D, 0x89, 0xFD, 0xDD, 0x00, 0x3D, 0x23, 0x37, 0x6B, 0x79, 0x63, 0x69, 0x7D};
5
while (x < strlen(code)) {
6
PORTC = code[x];
7
while (y < 20) { // läuft korrekt durch
8
PORTD = 0x20;
9
_delay_ms(5);
10
PORTD = 0x40;
11
_delay_ms(5);
12
PORTD = 0x10;
13
_delay_ms(5);
14
PORTD = 0x80;
15
_delay_ms(5);
16
PORTD = 0x08;
17
_delay_ms(5);
18
y++;
19
  }
20
x++; // wird beim verlassen der 2. while() 1x ausgeführt und verlässt dann while()
21
 }
22
PORTC = 0x00; // wird genauso 1x ausgeführt und verlässt die for()
23
}
Gast #1007946
Alle 3 Zählvariablen sind am Anfang als 0 deklariert.

int i = 0;
int x = 0;
int y = 0;

Und solange sie kleiner als die Schleifenprüfung sind, müsste es ja 
immer laufen.
Gast #1007962
Wie wäre es denn erstmal mit einer ordentlichen Formatierung des Codes?
Einrückungen
1
for (i=0; i<2;i++)
2
{
3
  char code[] = { 0xF9, 0x88, 0xB5, 0x9D, 0xCC, 0x5D, 0x7D, 0x89,
4
                  0xFD, 0xDD, 0x00, 0x3D, 0x23, 0x37, 0x6B, 0x79,
5
                  0x63, 0x69, 0x7D };
6
  while ( x < strlen(code) )
7
  {
8
    PORTC = code[x];
9
    while (y < 20)
10
    { // läuft korrekt durch
11
      PORTD = 0x20;
12
      _delay_ms(5);
13
      PORTD = 0x40;
14
      _delay_ms(5);
15
      PORTD = 0x10;
16
      _delay_ms(5);
17
      PORTD = 0x80;
18
      _delay_ms(5);
19
      PORTD = 0x08;
20
      _delay_ms(5);
21
      y++;
22
    }
23
    x++; // wird beim verlassen der 2. while() 
24
         // 1x ausgeführt und verlässt dann while()
25
  }
26
  PORTC = 0x00; // wird genauso 1x ausgeführt und verlässt die for()
27
}
Gast #1007976
Das Problem ist dass, wie Skua gesagt hat, die Variablen der inneren 
Schleifen einmal hochlaufen und dann auf ihrem Wert der Größe als die 
Bedingung der While Schleife ist Hängenbleiben. Die for Schleife läuft 
zwar Ordnungsgemäß durch aber nach dem ersten Durchlauf werden ja die 
beiden while Schleifen nicht mehr ausgeführt. du musst es also so 
machen:

for()
{
  while(x)
  {
   while(y)
     {
     }
  y=0;
  }
x=0;
}
Gast #1007999
Zusätzlich ist nicht definiert was die Funktion strlen(code) 
zurückliefert.

strlen sucht nach einem 0x00 als Endekennung eines Strings.
Dies ist im char[] nicht definiert und was nach dem Array kommt kann 
niemand sagen.

In diesem Fall wäre es besser mit sizeof() zu arbeiten, da dies der 
Compiler schon zur Compilierung auflösen kann und nicht zur Laufzeit
bei jedem Schleifendurchlauf berechnet werden muss.

Ich mache sowas gerne in folgender Form:

while (x < (sizeof(code) / sizeof(char))) {

Das kann der Compiler komplett auflösen und wenn sich z.B.
Datentypen ändern (nicht in diesem Fall, aber wenn statt char Strukturen 
vorhanden sind) muss keine Anpassung gemacht werden.
#1008010
JensM wrote:
> Zusätzlich ist nicht definiert was die Funktion strlen(code)
> zurückliefert.
>
> strlen sucht nach einem 0x00 als Endekennung eines Strings.
> Dies ist im char[] nicht definiert und was nach dem Array kommt kann
> niemand sagen.
>
ist doch definiert:
1
  char code[] = { 0xF9, 0x88, 0xB5, 0x9D, 0xCC, 0x5D, 0x7D, 0x89,
2
                  0xFD, 0xDD, 0x00, <-----!!!
> In diesem Fall wäre es besser mit sizeof() zu arbeiten, da dies der
> Compiler schon zur Compilierung auflösen kann und nicht zur Laufzeit
> bei jedem Schleifendurchlauf berechnet werden muss.
>
> Ich mache sowas gerne in folgender Form:
>
> while (x < (sizeof(code) / sizeof(char))) {
>
> Das kann der Compiler komplett auflösen und wenn sich z.B.
> Datentypen ändern (nicht in diesem Fall, aber wenn statt char Strukturen
> vorhanden sind) muss keine Anpassung gemacht werden.

aber ansonsten hast Du vollkommen recht, zumal bei der 0x00 mitten im 
String dieser nicht vollständig abgearbeitet wird...

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 18 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.