Hallo, ich habe ein Verständnis Problem.
In meinem Code habe ich eine Endlosschleife. Wenn ein bestimmter Zustand
eintritt, so soll die Schleife bis zum nächsten Schleifendurchlauf nicht
mehr betrachtet werden. Sowas mach man ja normal mit continue. Ist das
bei AVR while(1) in einer main anders?
Ich sende an mein Slave Daten, wenn ein CRC Fehler eintritt, so soll
halt wieder an den Anfang der while-Schleife. Wie gesagt normal macht
man dies mit continue, aber wenn ich das verwende, bleibt das programm
hängen. Ändere ich das in break, so läuft das Programm normal.
Aber das ist ja so dann ja garnicht richtig. Oder verstehe ich da was
falsch?
So sollte es richtig sein (hängt sich auf):
Hmm. Üblicherweise benötigst in einer Endlosschleife in main weder break
noch continue.
Es ist auch unklar woran Du merkst, das das Programm "hängen bleibt". An
und für sich gibt es das garnicht. Der uC führt immer irgendwas aus.
Ich sehe in Deinem Code nicht die Bedingung "CRC Fehler" reflektiert.
Deswegen deute ich das hier mal an.
1
intmain(void){
2
while(1){
3
if(rf12_data()){
4
//...
5
if(!CRC_Fehler){
6
mach_was_sinnvolles();
7
}
8
}
9
}
10
}
Damit wird der Code für den Erfolgsfall eben nur dann ausgeführt, wenn
alles OK ist, ansonsten einfach zum nächsten Schleifendurchlauf
übergegangen.
Insgesamt ist Deine Erklärung unklar und es scheint mir, das Du Dir über
den Ablauf in Kontrollstrukturen nicht klar bist. Wiegesagt ist continue
und break selten nötig. Ich selbst verwende break nur in switches und
habe in 30 Jahren noch nie ein continue gebraucht. (Abgesehen von etwas
komplizierten Fällen in Betriebssystemen). Vor allem möchte ich Dir
empfehlen das Kapitel hier
http://openbook.galileocomputing.de/c_von_a_bis_z/008_c_kontrollstrukturen_011.htm#mj23c58e4ac13db1b754398ebbb1825baf
mal durchzulesen.
ichdu schrieb:> Ändere ich das in break, so läuft das Programm normal.
In dienem Code sprigst du mit break aus der while(1)-Endlosschleife.
Danach kommt nichts mehr, also gibt es ein return aus main ins nirwana.
Das nirwana besteht beim WinAVR aus einer endlosschleife, ergo, der
Controller "hängt".
Da das aber anscheinend nicht passiert, sind alle weiteren Überlegungen
müssig, solange du nicht den vollständigen Code zeigst.
Ansonsten hat guru recht - continue braucht man in C noch seltener als
goto, sprich, nie.
Oliver
Oliver schrieb:> Ansonsten hat guru recht - continue braucht man in C noch seltener als> goto, sprich, nie.
Nö. Continue ist durchaus sehr sinnvoll. Selbst in einer Endlosschleife
kann es sinnvoll sein.
Oliver schrieb:> Ansonsten hat guru recht - continue braucht man in C noch seltener als> goto, sprich, nie.
Brr, da würd mir dann aber was fehlen ohne Continue.
Guru schrieb:> Hmm. Üblicherweise benötigst in einer Endlosschleife in main weder break> noch continue.Rufus Τ. Firefly schrieb:> Nö. Continue ist durchaus sehr sinnvoll. Selbst in einer Endlosschleife> kann es sinnvoll sein.Nico Sch. schrieb:> Brr, da würd mir dann aber was fehlen ohne Continue.
Nun denn, drei Programmierer, vier Meinungen ;)
Ich bleib bei meiner ;)
Oliver
Vieleicht sollte man verstehen was break und continue überhaupt macht.
ichdu weiß es wohl nicht, oliver wohl auch nicht so genau.
break springt aus einer Schleife raus egal of while for do ... while,
das heisst die Schleife (bzw. bei mehreren geschachtelten die innerste
Schleife) wird sofort verlassen. Das ist wie ein goto hinter das
Schleifenende
continue springt sofort wieder an den Anfang der Schleife, bei einer for
Schleife führt das dazu, daß die incrementbedingung ausgeführt wird. Das
ist genau dann sinnvoll, wenn ich den rest des codes in der Schleife
nicht mehr ausführen will.
Beispiel
do (hole nächste Zeile aus Konfigurationsdatei) {
if (ist Kommentar) continue;
verarbeite zeile
...
} (while nicht dateiende Konfigurationsdatei)
Oliver und jetzt erzähle nicht da könnte man if else benutzen, wenn du
mehrere Abbruchbedingungen für die Verarbeitung der aktuellen zeile hast
ist continue deutlich besser, eleganter, verständlicher.
U.R. Schmitt schrieb:> liver und jetzt erzähle nicht da könnte man if else benutzen, wenn du> mehrere Abbruchbedingungen für die Verarbeitung der aktuellen zeile hast> ist continue deutlich besser, eleganter, verständlicher.
und auch schneller und kleiner weil keine else Zweige ausgewertet werden
müssen.
U.R. Schmitt schrieb:> ichdu weiß es wohl nicht, oliver wohl auch nicht so genau.
Danke, ich weiß das schon sehr genau. Und bin in meinem Leben bisher
ohne continue ausgekonnen. Bei brak ist das anders, das nutze ich ab und
an 8ausserhaöb von switch).
U.R. Schmitt schrieb:> Oliver und jetzt erzähle nicht da könnte man if else benutzen,
Es gibt IMMER mehrere Wege nach Rom, und die wenigsten führen über
continue.
Oliver
Oliver schrieb:> Es gibt IMMER mehrere Wege nach Rom, und die wenigsten führen über> continue.
ROFL!
Eben, weil die meisten Wege nach Rom Umwege sind!
Es gibt in der Regel nur einen schnellsten und einen kürzesten aber
viele andere, aber du darfst gerne erst nach Frankreich fahren, dort die
Fähre nach Korsika nehmen und dort dann ne andere zum italienischen
Festland. dann ist es nicht mehr weit nach Rom, ist bestimmt ne schöne
Fahrt :-)
Merke: nur wer möglichst viele Wege kennt und bereit ist diese auch zu
benutzen hat eine größere Chanche den für das Projekt besten Weg zu
finden.
U.R. Schmitt schrieb:> Merke: nur wer möglichst viele Wege kennt und bereit ist diese auch zu> benutzen hat eine größere Chanche den für das Projekt besten Weg zu> finden.
Wobei man den besten Weg getrost nach der Ästhetik wählen kann. Der
compiler wird für mehrere verschieden hingeschriebene Bedingungen oft
genug den gleichen Code ausspucken.
Die Diskussion erinnert mich irgendwie an Donald E. Knuth's Aufsatz:
"Structured Programming with GOTOs".
Jörg Wunsch schrieb:> Wobei man den besten Weg getrost nach der Ästhetik wählen kann. Der> compiler wird für mehrere verschieden hingeschriebene Bedingungen oft> genug den gleichen Code ausspucken.
Das bezweifle ich zumindest für den Fall daß du eine Schleife mit einem
komplexeren Lnnenleben hast bei dem du sonst ein mehrfaches Abfragen
nach irgendwelchen Stati machen müsstest, wenn du kein continue benutzen
würdest.
Wobei man jetzt wieder sagen kann schlecht designt wenn der Code in der
Schleife so komplex ist ....
Egal, aber wenn man sagt ich brauche kein continue und kein break, dann
kann man genau so sagen, mir reicht ein do ... while, die while und for
Schleifen sind vollkommen unnötig, das kann ich alles mit do ... while
machen.
Jörg Wunsch schrieb:> Die Diskussion erinnert mich irgendwie an Donald E. Knuth's Aufsatz:> "Structured Programming with GOTOs".
den kenn ich jetzt leider nicht, aber das Dauerstreitthema goto sind
"schlecht" / "doch manchmal notwendig" zeigt auch daß Dogmen meistens
nicht zielführend sind.
ich habe Ablaufcode gesehen wo jeder Aufruf immer ein "if (rc==0) ..."
hatte, die hätten mit einem goto ERROR besser ausgesehen.
Egal wer nur ein Subset der Befehle nutzen will soll das gerne tun, wie
gesagt es gibt mehrere Wege...
U.R. Schmitt schrieb:> den kenn ich jetzt leider nicht, aber das Dauerstreitthema goto sind> "schlecht" / "doch manchmal notwendig" zeigt auch daß Dogmen meistens> nicht zielführend sind.
Die Diskussion ist so alt wie die Programmier-Menschheit, und wird auch
immer fortbestehen. Der oben genannte Artikel stammt von 1974, und ist
insofern sicherlich richtig, als daß in den nach diesem Zeitpunkt
entwickelten höheren Programmiersprachen (also eigentlich fast allen...)
Strukturen zum "verdeckten" Einsatz von goto enthalten sind, wie
setjmp/longjmp, try/catch, die doch sehr viel angenehmeres Programmieren
zulassen, als es mit einer Programmiersprache der "reinen Lehre" wie
Niclaos' Wirthschen Pascal oder Modula der Fall wäre.
Um aber wieder aufs Thema zurückzukommen:
Das der Code des Threadstartes nicht funktioniert, liegt weder an
continue noch an break.
Vielleicht meldet der sich ja nochmal mit dem vollständigen Code.
Oliver
Oliver schrieb:> Das der Code des Threadstartes nicht funktioniert, liegt weder an> continue noch an break.> Vielleicht meldet der sich ja nochmal mit dem vollständigen Code.
Da stimme ich dir zu, insofern nichts für ungut :-)
Wenn man wie der TO zur Fehlersuche einfach ein continue durch ein break
ersetzt, dann möchte ich hier mal Karl Heinz ziteren: "Er braucht
dringend ein C Buch". -und sollte natürlich auch lesen-
Ui. Da habe ich aber was angerichtet!
Es lag nicht in meiner Absicht Dogmen aufzustellen. Ich bin auch der
Meinung, dass meine Äusserungen:
" Üblicherweise benötigst in einer Endlosschleife in main weder break
noch continue."
und:
"Wiegesagt ist continue und break selten nötig."
nicht als Dogmen zu verstehen sind, die man relativieren muss.
Und mit:
"Ich selbst verwende break nur in switches und habe in 30 Jahren noch
nie ein continue gebraucht. (Abgesehen von etwas komplizierten Fällen in
Betriebssystemen)."
habe ich eingeräumt, dass auch ich Gründe kenne, break und continue
anzuwenden. (Klar. Bei Switch ist das trivial und man kommt nur mit
Gewalt drum herum).
Wenn ich mir die Beiträge so anschaue so scheint sich jeder der
Antwortenden zumindest grundsätzlich darüber klar zu sein, dass und wie
man ein continue vermeiden kann. Irgendwie kommt dann auch immer die
Ästhetik ins Spiel. Das aber sollte man ernst nehmen, denke ich, und
hier deswegen keine "Klarstellungen" anfügen. Das man über Geschmack
streiten kann, ob eine ausformulierte Bedingung mit ausformulierten
else-if Zweigen nun "schöner" ist, als ein continue, muss letztlich
jeder selbst entscheiden.
Warum schreibe ich das hier keine Klarstellungen nötig sind?
Nun, weil der TO ganz offensichtlich die Grundlagen nicht beherrscht und
erstmal überhaupt lernen muss wie while-Schleifen und insbesondere
unendliche while-Schleifen zu behandeln hat. Insofern waren meine
relativ formulierte Abweisung von continue und break, meine ich,
durchaus sinnvoll.
Mit den ganzen Gründen warum und wann continue sinnvoll ist, kann er
nach meiner Wahrnehmung garnichts anfangen.
Wenn der TO klare Gründe gebracht hätte warum er nun ein continue
verwenden will, zu erkennen gegeben hätte, das er den anderen Weg kennt
und nur einen Kommentar dazu gewünscht hätte, was davon zu halten sei,
das er continue anwendet, wäre das ein anderer Fall gewesen, den ich,
unter Umständen mit einem Vorbehalt, aber letztlich bejahend beantworten
hätte müssen.
Wenn er z.B. hätte darlegen können das die Abprüfung von
Alternativbedingungen notwendig sehr viel Zeit braucht und sein Programm
zeitkritisch ist, wäre ja gegen continue nichts zu sagen gewesen.
(Übrigens einer der Fälle z.B. in Betriebssystemen wo ich es auch
verwenden würde).
Naja. Es fehlt uns jedenfalls eine klare Erklärung des TO zu dem
Problem, denke ich und einiges an Grundlagenkenntnissen könnte er auch
noch nachlesen. Bei dem Satz "... so soll die Schleife bis zum nächsten
Schleifendurchlauf nicht mehr betrachtet werden." hat sich mir doch
irgendwie was innerlich verwunden. Der uC gibt sich doch keinen
"Betrachtungen" hin. :-)
Klaus Wachtler schrieb:> Schleifen verlässt man prinzipiell mit longjmp(), das ist> portabel und macht mehr Eindruck.
Ach was! Man lässt einen watchdog reset zuschlagen, und wenn man
sich noch irgendwie den vorherigen Zustand merken muss, dann organi-
siert man sich das über eine .noinit-Variable.
Alternativ: man patcht die Einsprungadresse für den nächsten Start
nach dem Reset in die Vektortabelle ... selbstmodifizierender Code,
war zu Z80-Zeiten gang und gäbe. :-))