Forum: Mikrocontroller und Digitale Elektronik if abfragen in Schleife packen funktioniert nicht!


von schleifen-noob (Gast)


Lesenswert?

warum funktioniert mein Programm nicht mehr so wie vorher wenn ich meine 
abfragen versuche in eine Schleife zu packen??? Wo liegt mein Fehler?
Erstmal das eigenliche Programm:
1
if(!P3_5)
2
    {
3
    while(!P3_5);                     
4
    if(spielfeld[0][0]==0){
5
    spielfeld[0][0]=1;           
6
      x=0;
7
    y=0;}
8
    else if(spielfeld[0][1]==0){
9
    spielfeld[0][1]=1;
10
    x=0;
11
    y=1;}                              
12
      else if(spielfeld[0][2]==0){
13
    spielfeld[0][2]=1;
14
    x=0;
15
    y=2;}    
16
    else if(spielfeld[0][3]==0){
17
    spielfeld[0][3]=1;
18
    x=0;
19
    y=3;}
20
    else if(spielfeld[0][4]==0){
21
    spielfeld[0][4]=1;
22
    x=0;
23
    y=4;}        
24
    else if(spielfeld[0][5]==0){
25
    spielfeld[0][5]=1;
26
    x=0;
27
    y=3;}
28
    else if(spielfeld[0][6]==0){
29
    spielfeld[0][6]=1;
30
    x=0;
31
    y=3;}        
32
    for(k=10000;k=0;k--);                     
33
    pruef=1;                            
34
    }                               
35
  if(!P3_4)
36
    {
37
    while(!P3_4);                     
38
    if(spielfeld[1][0]==0){
39
    spielfeld[1][0]=1;           
40
      x=1;
41
    y=0;}
42
    else if(spielfeld[1][1]==0){
43
    spielfeld[1][1]=1;
44
    x=1;
45
    y=1;}                              
46
      else if(spielfeld[1][2]==0){
47
    spielfeld[1][2]=1;
48
    x=0;
49
    y=2;}    
50
    else if(spielfeld[1][3]==0){
51
    spielfeld[1][3]=1;
52
    x=0;
53
    y=3;}
54
    else if(spielfeld[1][4]==0){
55
    spielfeld[1][4]=1;
56
    x=1;
57
    y=4;}        
58
    else if(spielfeld[1][5]==0){
59
    spielfeld[1][5]=1;
60
    x=0;
61
    y=5;}
62
    else if(spielfeld[1][6]==0){
63
    spielfeld[1][6]=1;
64
    x=0;
65
    y=6;}        
66
    for(k=10000;k=0;k--);                     
67
    pruef=1;                            
68
    }                       
69
  if(!P3_3)
70
    {
71
    while(!P3_3);                     
72
    if(spielfeld[2][0]==0){
73
    spielfeld[2][0]=1;           
74
      x=2;
75
    y=0;}
76
    else if(spielfeld[2][1]==0){
77
    spielfeld[2][1]=1;
78
    x=2;
79
    y=1;}                              
80
      else if(spielfeld[2][2]==0){
81
    spielfeld[2][2]=1;
82
    x=2;
83
    y=2;}    
84
    else if(spielfeld[2][3]==0){
85
    spielfeld[2][3]=1;
86
    x=2;
87
    y=3;}
88
    else if(spielfeld[2][4]==0){
89
    spielfeld[2][4]=1;
90
    x=2;
91
    y=4;}        
92
    else if(spielfeld[2][5]==0){
93
    spielfeld[2][5]=1;
94
    x=2;
95
    y=5;}
96
    else if(spielfeld[2][6]==0){
97
    spielfeld[2][6]=1;
98
    x=2;
99
    y=6;}        
100
    for(k=10000;k=0;k--);                     
101
    pruef=1;                            
102
    }                       
103
    if(!P3_2)
104
    {
105
    while(!P3_2);                     
106
    if(spielfeld[3][0]==0){
107
    spielfeld[3][0]=1;           
108
      x=3;
109
    y=0;}
110
    else if(spielfeld[3][1]==0){
111
    spielfeld[3][1]=1;
112
    x=3;
113
    y=1;}                              
114
      else if(spielfeld[3][2]==0){
115
    spielfeld[3][2]=1;
116
    x=3;
117
    y=2;}    
118
    else if(spielfeld[3][3]==0){
119
    spielfeld[3][3]=1;
120
    x=3;
121
    y=3;}
122
    else if(spielfeld[3][4]==0){
123
    spielfeld[3][4]=1;
124
    x=3;
125
    y=4;}        
126
    else if(spielfeld[3][5]==0){
127
    spielfeld[3][5]=1;
128
    x=3;
129
    y=5;}
130
    else if(spielfeld[3][6]==0){
131
    spielfeld[3][6]=1;
132
    x=3;
133
    y=6;}        
134
    for(k=10000;k=0;k--);                     
135
    pruef=1;                            
136
    }                       
137
    if(!P3_1)
138
    {
139
    while(!P3_1);                     
140
    if(spielfeld[4][0]==0){
141
    spielfeld[4][0]=1;           
142
      x=4;
143
    y=0;}
144
    else if(spielfeld[4][1]==0){
145
    spielfeld[4][1]=1;
146
    x=4;
147
    y=1;}                              
148
      else if(spielfeld[4][2]==0){
149
    spielfeld[4][2]=1;
150
    x=4;
151
    y=2;}    
152
    else if(spielfeld[4][3]==0){
153
    spielfeld[4][3]=1;
154
    x=4;
155
    y=3;}
156
    else if(spielfeld[4][4]==0){
157
    spielfeld[4][4]=1;
158
    x=4;
159
    y=4;}        
160
    else if(spielfeld[4][5]==0){
161
    spielfeld[4][5]=1;
162
    x=4;
163
    y=5;}
164
    else if(spielfeld[4][6]==0){
165
    spielfeld[4][6]=1;
166
    x=4;
167
    y=6;}        
168
    for(k=10000;k=0;k--);                     
169
    pruef=1;                            
170
    }                       
171
    if(!P3_0)
172
    {
173
    while(!P3_0);                     
174
    if(spielfeld[5][0]==0){
175
    spielfeld[5][0]=1;           
176
      x=5;
177
    y=0;}
178
    else if(spielfeld[5][1]==0){
179
    spielfeld[5][1]=1;
180
    x=5;
181
    y=1;}                              
182
      else if(spielfeld[5][2]==0){
183
    spielfeld[5][2]=1;
184
    x=5;
185
    y=2;}    
186
    else if(spielfeld[5][3]==0){
187
    spielfeld[5][3]=1;
188
    x=5;
189
    y=3;}
190
    else if(spielfeld[5][4]==0){
191
    spielfeld[5][4]=1;
192
    x=5;
193
    y=4;}        
194
    else if(spielfeld[5][5]==0){
195
    spielfeld[5][5]=1;
196
    x=5;
197
    y=5;}
198
    else if(spielfeld[5][6]==0){
199
    spielfeld[5][6]=1;
200
    x=5;
201
    y=6;}        
202
    for(k=10000;k=0;k--);                     
203
    pruef=1;                            
204
    }

Und hier der versuch es in eine Schleife zu packen:
1
 for(a=0;a<=5;a++){
2
       if(P3&portpin[a]){
3
      while(P3&portpin[a])
4
      for(c=0;c<=6;c++){
5
        if(spielfeld[a][c]==0){
6
          spielfeld[a][c]=1;
7
          x=a;
8
          y=c;
9
        }
10
        else ;
11
        
12
      }
13
      for(k=10000;k=0;k--);
14
      pruef=1;
15
     }
16
  }
hier noch Portpin
1
unsigned char portpin[6]={0xDF,0xEF,0xF7,0xFB,0xFD,0xFE};

von Sheeva P. (sheevaplug)


Lesenswert?

Hallo schleifen-noob,

ich möchte Dir wirklich nicht zu Nahe treten, möchte Dir jedoch dringend 
empfehlen, daß Du Dir einen sauberen Codingstil angewöhnst. Dann behälst 
Du den Überblick und verwirrst Dich nicht selbst.

Natürlich kann man geschweifte Klammern oft weglassen, wenn der Block 
nur aus einer Anweisung besteht. Aber prinzipiell ist das mMn. kein 
guter Stil, weil es den Code schwer lesbar macht -- insbesondere dann, 
wenn man den Code obendrein nicht sauber einrückt. Außerdem erschwert 
das Weglassen der Klammern die Entwicklung selbst, denn beispielsweise 
das hier:
1
if(dings == 4) bums = 5; test = bums;
 macht wahrscheinlich nicht das Gewünschte. Man könnte zwar statt des 
ersten Semikolons hier ein Komma verwenden, aber... ganz genau, bäh.

Weiterhin möchtest Du wohl über das zweidimensionale Array "spielfeld" 
iterieren und die Indizes herausfinden, bei denen das Spielfeld "0" ist. 
Das kannst Du mit zwei direkt ineinander geschachtelten For-Schleifen 
machen:
1
#define MAXLEN_SPIELFELD_X 10
2
#define MAXLEN_SPIELFELD_Y 10
3
4
5
int i, k, x, y;
6
for(i = 0; i < MAXLEN_SPIELFELD_X; i++) {
7
    for(k = 0; k < MAXLEN_SPIELFELD_Y; k++) {
8
        if(spielfeld[i][k] == 0) {
9
            spielfeld[i][k] = 1;
10
            x = i;
11
            y = k;
12
        }
13
    }
14
}

Etwas eleganter ist, das Ganze in eine Funktion zu packen:
1
#define MAXLEN_SPIELFELD_X 10
2
#define MAXLEN_SPIELFELD_Y 10
3
4
// Neuen Datentyp mit Int-Feldern x und y anlegen
5
typedef struct { int x; int y; } coords;
6
7
coords suche(int spielfeld[][]);    // Prototyp
8
9
coords suche(int spielfeld[][]) {   // Implementierung
10
    int i, k;
11
    coords rv;
12
    for(i = 0; i < MAXLEN_SPIELFELD_X; i++) {
13
        for(k = 0; k < MAXLEN_SPIELFELD_Y; k++) {
14
            if(spielfeld[i][k] == 0) {
15
                spielfeld[i][k] = 1;
16
                rv.x = i;
17
                rv.y = k;
18
                break;
19
            }
20
        }
21
    }
22
    return rv;
23
}

Durch die Zeile
1
break;
 wird immer nur das erste Vorkommen von spielfeld[i][k] == 0 gefunden. 
Wenn Du diese Zeile auskommentierst, dann wird immer nur das letzte 
Vorkommen gefunden, alle anderen spielfeld[][] werden dann aber auf 1 
zurückgesetzt.

HTH und beste Grüße,
Sheeva

von schleifen-noob (Gast)


Lesenswert?

jetz fehlen aber noch die tasterabfragen, ich will mit dem programm 
bezwecken dass ich in einem array durch tastendruck spaltenweise stein 
auf sein setzen kann, das hat auch alles funktioniert, nur möchte ich 
das was ich jetz in if abfragen geschrieben habe, in schleifen packen, 
also das ganze um einiges an text verkürzen, der übersichtlichkeit 
halber

also es fehlen in der schleife noch die tasterabfragen
1
if(P3&portpin[a])

von Karl H. (kbuchegg)


Lesenswert?

schleifen-noob schrieb:
>
> also es fehlen in der schleife noch die tasterabfragen
>
>
1
> if(P3&portpin[a])
2
>

Ja, dann mach.
Aber so wie ddu das oben hast, ist es einfach nur grauslich, 
unübersichtlich, unwartbar und fehleranfällig.

Codblöcke zu duplizieren bei deinen nur Zahlen angepasst werden müssen, 
sind praktisch immer ein Zeichen dafür, dass der Einsatz einer oder 
mehrerer Schleifen angebracht ist.

Bei dir würde sich zusätzlich noch der Einsatz einer Funktion anbieten, 
deren einzige Aufgabe darin besteht, die Position in einer SPalte zu 
suchen (mit einer Schleife) auf der eine Spielmarke zu liegen kommt. 
Denn das ist ja wohl die ursprüngliche Absicht in diesem Code (zumindest 
was ich im drüberscrollen so gesehen habe)
Und schon werden aus deinen 100 Zeilen Code eine Handvoll Codezeilen, 
die leicht auf eine Bilschirmseite passen.

Das soll dir auch deutlich machen, wie wichti es ist, sein 
Handwerkszeug, die Programmiersprache, zu lernen, zu verstehen und zu 
wissen welche Möglichkeiten es gibt.

von schleifen-noob (Gast)


Lesenswert?

ich versteh nicht was ich so grottenmäßig falsch mache, wie soll ich den 
das hinbekommen wenn ich nicht weiß wies geht?
mein programm hat doch funktioniert, und ich weiß nicht was ich noch 
besser machen könnte, auf jeden fall weiß ich nicht warum mein zweites 
programm nicht die funktion des ersten programms hat. ich will doch nur 
wissen wies richtig heißt, ich komm nicht drauf
bitte!!!

von Eddy C. (chrisi)


Lesenswert?

Deine Portabfrage ist nicht korrekt, weil Du mit Deinem Array genau das 
gefragte Pin "weg-undest". So könnte es eher funktionieren:

1
unsigned char portmask = 0x20;
2
for(a=0; a<=5; a++, portmask >>= 1)
3
{
4
  if ((P3 & portmask) == 0)
5
  {
6
    while ((P3 & portmask) == 0)
7
      ;
8
    for (c=0; c<=6; c++)
9
    {
10
      if (spielfeld[a][c] == 0)
11
      {
12
        spielfeld[a][c]=1;
13
        x=a;
14
        y=c;
15
        break;
16
      }
17
    }
18
    for(k=10000;k=0;k--)
19
      ;
20
    pruef = 1;
21
  }
22
}

von Eddy C. (chrisi)


Lesenswert?

6 x 7... hm .... Vier gewinnt, sag's doch gleich ;-)

von schleifen-noob (Gast)


Lesenswert?

ja es ist vier-gewint, es funktioniert auch so ziemlich alles, eben bis 
auf das ich die if abfragen nicht in schleifen bekommen, und mir keil 
sonst sag
das der code für die unregistrierte version zu groß ist -.-

von Karl H. (kbuchegg)


Lesenswert?

schleifen-noob schrieb:

> besser machen könnte, auf jeden fall weiß ich nicht warum mein zweites
> programm nicht die funktion des ersten programms hat.

Überleg mal, ob hier
1
       if(P3&portpin[a]){
2
      while(P3&portpin[a])
3
      for(c=0;c<=6;c++){

die while-Schleife dieselbe Funktion hat, wie in deiner 'langen' 
Version.

von ??? (Gast)


Lesenswert?

Sowas

Eddy Current schrieb:
>
1
>     for(k=10000;k=0;k--)
2
>       ;
3
4
>

ist Murks (und außerdem falsch).

von schleifen-noob (Gast)


Lesenswert?

+

Karl Heinz Buchegger schrieb:
> Überleg mal, ob hier
>        if(P3&portpin[a]){
>       while(P3&portpin[a])
>       for(c=0;c<=6;c++){
>
> die while-Schleife dieselbe Funktion hat, wie in deiner 'langen'
> Version.

also eingentlich sollte die while schleife ja solage warten bis der 
taster wieder losgelassen  wird

??? schrieb:
> Sowas
>
> Eddy Current schrieb:
>>>     for(k=10000;k=0;k--)
>>       ;
>
>>
> ist Murks (und außerdem falsch).
>
>
die schleife solte eingenlich zum entprellen dienen

von Karl H. (kbuchegg)


Lesenswert?

schleifen-noob schrieb:
> +
>
> Karl Heinz Buchegger schrieb:
>> Überleg mal, ob hier
>>        if(P3&portpin[a]){
>>       while(P3&portpin[a])
>>       for(c=0;c<=6;c++){
>>
>> die while-Schleife dieselbe Funktion hat, wie in deiner 'langen'
>> Version.
>
> also eingentlich sollte die while schleife ja solage warten bis der
> taster wieder losgelassen  wird

S C H A U   D I R   A N    W E L C H E   A N W E I S U N G

J E W E I L S    V O M     W H I L E     A B H Ä N G T    !




Im Original hattes du (umformatiert)
1
    while( !P3_5 )
2
      ;
3
4
    if( spielfeld[0][0] == 0 ) {
5
      ...

hier hast du
1
    while( P3 & portpin[a] )
2
      for( c = 0; c <= 6; c++ ) {
3
        ...

einen noch schlagenderen Beweis für die Wichtgkeit einer ordentliche 
Codeformatierung gibt es eigentlich nicht mehr.

von schleifen-noob (Gast)


Lesenswert?

Achso...
Entschuldige, ja ich weiß bei meiner formatierung blickt man nichts mehr 
durch -.-

von Karl H. (kbuchegg)


Lesenswert?

Code sauber einrücken!
Nicht einfach alles knirsch an knirsch schreiben!
Eine Leerzeile da und dort, mit der man den Begin eines neuen
Abschnittes anzeigt

... das alles sind Dinge, die einem helfen nicht den Überblick im Code
zu verlieren.

In C gibt es die 'leere' Anweisung, die nichts tut.
Du hast sie zb hier
1
   while(!P3_5);
oder hier
1
    for(k=10000;k=0;k--);
oder hier
1
        else ;
benutzt.

Gewöhn dir an, dass du pro Zeile nur 1 Anweisung schreibst. In Fällen in
denen etwas aus mehreren Anweisungen zusammengesetzt wird, wie zb
Schleifen, Abfragen kommen die einzelnen Anweisungen auf eine eigene
Zeile.

ALso nicht

   if( Bedinung )  Anweisung;

sondern

   if( Bedingung )
     Anweisung;

wobei die Anweisung eingerückt wird. (Der ; ist Teil der Anweisung und
nicht etwa Teil des Gesamtkonstruktes)

Konsequenterweise sollten deine Beispiele daher lauten
1
   while(!P3_5)
2
     ;
bzw
1
    for( k = 10000; k == 0; k-- )
2
      ;
oder hier
1
        else
2
          ;
um anzuzeigen, dass es sich eben um die leere Anweisung handelt und
nicht etwa um einen unabsichtlich ans Zeilende geschriebenen ;


Hier
1
    for(k=10000;k=0;k--);
ist der mittlere Ausdruck falsch. Du hast eine Zuweisung geschrieben und
keine Abfrage

So
1
    for( k = 10000; k = 0; k-- )
2
      ;
stehen die Chancen besser, das du das erkennst. Aber auch dann ist das
noch falsch. Denn der mitlere Ausdruck in einer for-Schleife ist die
Bedingung die zutreffen muss, damit die Schleife wiederholt wird. WEnn
du aber k auf 10000 setzt, dann ist die Bedingung, dass k gleich 0 sein
muss, nicht zutreffend. Die Schleife wird nicht wiederholt, bzw. gar
nicht erst ausgeführt.

So
1
    for( k = 10000; k > 0; k-- )
2
      ;
wird sie ausgeführt.

von Karl H. (kbuchegg)


Lesenswert?

schleifen-noob schrieb:
> Achso...
> Entschuldige, ja ich weiß bei meiner formatierung blickt man nichts mehr
> durch -.-

Dann ändere etwas daran!

Solange du nicht selbst erkennst, dass du dir mit derartigen 
Nicht-Formatierungen selbst ins Knie schiesst, wirst du immer wieder von 
derartigen unnötigen Fehlern verfolgt.

von coder (Gast)


Lesenswert?

Leere for-Schleifen sind auch nicht geschickt. Wenn er nämlich anfängt, 
Compiler-Optimierungen zu verwenden, könnten leere Schleifen 
wegoptimiert werden, wenn die Zählvariable nicht volatile deklariert 
ist. Dann lieber delay_cycles, delay_ms oder was auch immer.  Ansonsten 
hat Herr Buchegger alles gesagt.

von Philipp (Gast)


Lesenswert?

1
for( k = 10000; k = 0; k-- )
2
      ;

Was Herr Buchegger noch vergessen hat:
k = 0 ist hier eine Zuweisung.
Bei einem Vergleich muss es k == 0 heißen.

von Karl H. (kbuchegg)


Lesenswert?

Philipp schrieb:
>
1
> for( k = 10000; k = 0; k-- )
2
>       ;
3
>
>
> Was Herr Buchegger noch vergessen hat:
> k = 0 ist hier eine Zuweisung.
> Bei einem Vergleich muss es k == 0 heißen.

Lies den Abschnitt (und die Zeilen davor) noch mal genauer :-)

von ??? (Gast)


Lesenswert?

Philipp schrieb:
>
1
> for( k = 10000; k = 0; k-- )
2
>       ;
3
>
>
> Was Herr Buchegger noch vergessen hat:
> k = 0 ist hier eine Zuweisung.
> Bei einem Vergleich muss es k == 0 heißen.

Genau, ist im konkreten Fall genauso falsch wie = 0. Mensch Leute!

Lösung:

Karl Heinz Buchegger schrieb
> So
>
1
>     for( k = 10000; k > 0; k-- )
2
>       ;
3
>
> wird sie ausgeführt.

von Philipp (Gast)


Lesenswert?

Okay, hab ich übersehen...
hast ja auch wirklich eine ganze menge geschrieben :)

von Philipp (Gast)


Lesenswert?

???:
>Genau, ist im konkreten Fall genauso falsch wie = 0. Mensch Leute!

ich sagte ja nicht, das k == 0 in seinem Fall richtig ist, ich sagte nur 
das ein vergleich so aussehen muss. ;)

von ??? (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Konsequenterweise sollten deine Beispiele daher lauten
> ...
>
1
>         else
2
>           ;
3
>
> um anzuzeigen, dass es sich eben um die leere Anweisung handelt und
> nicht etwa um einen unabsichtlich ans Zeilende geschriebenen ;


Gerade bei längeren if-else-else if-Konstrukten sind geschweifte 
Klammern kein Luxus.

Schlecht:
1
if(foo)
2
  do();
3
else if (bar)
4
  do_also();
5
/* a lot more else if */
6
else ;

Besser:
1
if(foo)
2
  do();
3
else if (bar)
4
  do_also();
5
/* a lot more else if */
6
else 
7
  ;

IMHO am besten weil die Absicht des Programmierers am deutlichsten ist:
1
if(foo)
2
  do();
3
else if (bar)
4
  do_also();
5
/* a lot more else if */
6
else
7
{
8
  ; /* Hier könnte ein nützliches Kommentar stehen, z.B. die Antwort auf die Frage "Warum gibts hier keine Anweisungen?" */
9
}
"else;" ist ja eigentlich überflüssig, wenn man es schreibt gibt es 
einen guten Grund welcher dann auch klar erkennbar sein sollte!

Einfache Warteschleifen schreibe ich allerdings in einer Zeile:
1
while(PIN_B&(1<<42));

Philipp schrieb:
> ???:
>>Genau, ist im konkreten Fall genauso falsch wie = 0. Mensch Leute!
>
> ich sagte ja nicht, das k == 0 in seinem Fall richtig ist, ich sagte nur
> das ein vergleich so aussehen muss. ;)
Erbsenzähler! ;-) Ne im Ernst, du hast Recht aber bei Anfängern sollte 
man solche unklaren Hinweise besser vermeiden.

von schleifen-noob (Gast)


Lesenswert?

schleifen-noob schrieb im Beitrag #2268522:
>>Was Herr Buchegger noch vergessen hat:
>
> Ich finde das nicht so schlimm. Die falsche Zeile stammt schließlich von
> mir. Umso bewundernswerter ist, dass Herr Buchegger anscheinend sein
> ganzes Leben lang nichts besseres zu tun hatte als C Programme zu
> schreiben und zu debuggen und sich auf jeden verfügbaren Quellcode
> stürzt, um ihn zu verbessern. Hut ab!
>
>
>     Beitrag melden | Bearbeiten | Löschen |

 das kommt übrigens auch nicht von mir, da hat mir jemand den namen 
geklaut

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.