[ATmega32] Verlassen der Schleife verlässt alle Schleifen

Gast #1007942
Lesenswert?

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 #1007962
Lesenswert?

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
Lesenswert?

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
Lesenswert?

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
Lesenswert?

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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren