Hallo zusammen,
kann mir jemand sagen für was ich die while(1) schleife in einem
C-Programm benötige?
mein erster gedanke war, dass dadurch der Programm Code immer wieder
wiederholt wird!
mein Klassenkamerad meinte aber, dass das C-Programm ein definiertes
Ende braucht, kann mir jemand helfen?
wäre sehr dankbar
@ Miriam (Gast)
>mein erster gedanke war, dass dadurch der Programm Code immer wieder>wiederholt wird!
In der Tat.
>mein Klassenkamerad meinte aber, dass das C-Programm ein definiertes>Ende braucht,
"This is the end, da da da, my only friend, the end . . ." ;-)
Eine Schleife ist das Eine, eine definiertes Ende eines C-Programms ein
anderes. While-Schleifen werden solange durchlaufen, wie die
Laufbedingung erfüllt ist, dann werden sie beendet. Ein C-Programm
enthält meist mehrere While Schleifen.
MFG
Falk
Stimmt beides.
Vor allem das mit dem definierten Ende ist bei manchen Compilern
scheinbar wichtig, denn sonst rennt dein Programm am Ende ohne die
while-Schleife einfach irgendwo ins Nirvana und dann macht die CPU nur
noch mist.
Miriam schrieb:> Hallo zusammen,>> kann mir jemand sagen für was ich die while(1) schleife in einem> C-Programm benötige?> mein erster gedanke war, dass dadurch der Programm Code immer wieder> wiederholt wird!
Ja.
> mein Klassenkamerad meinte aber, dass das C-Programm ein definiertes> Ende braucht, kann mir jemand helfen?
Die while-Schleife sorgt eher dafor, daß es gar kein Ende gibt. Beim PC
ist es ja kein Problem, wenn ein Programm zu Ende geht, aber was soll
ein µC dann machen? Also sorgt man durch die While-Schleife dafür, daß
es nie zum Ende kommt.
Das fragst du ausgerechnet im Mikrocontroller Forum?
Sie ein MC Programm läuft und läuft und läuft... bis man den Strom
wieder abstellt. Die meisten MC Programme haben ein while(1) in der
Hauptschleife.
Miriam schrieb:> mein Klassenkamerad meinte aber, dass das C-Programm ein definiertes> Ende braucht, kann mir jemand helfen?
Und was soll der µC dann machen?
Beim µC läuft der Prozessor bis zum Stromabschalten immer in einer
Schleife. Falls das Programm ein Ende hat, wird das also nie erreicht
und ist deswegen überflüssig. Das ist wie eine Einbahnstrahße, die in
einem Kreisverkehr endet.
Also mir fallen da 3 Verwendungszwecke für while(1) ein, wovon
eigentlich nur einer (1.) brauchbar ist, aber auch nur für
Microcontroller. C ist ja auch für PCs da und dort ist soeine Schleife
nicht ganz so sinnvoll, da, wie schon gesagt wurde, das Programm am PC
ja irgendwann auch aufhören soll.
1.
1
voidmain(){
2
//Config etc
3
while(1){
4
//Programm, dass immer wieder von vorne beginnt
5
}
6
}
2.
1
voidmain(){
2
//Config etc
3
4
// Programm
5
while(1);// Ende, soll nichts mehr nach einmaligen Durchlauf machen
6
}
3.
1
voidmain(){
2
// Config etc
3
while(1){
4
//Programm ...
5
if(Bedingung)break;// Wenn Bedingung erfüllt ist, wird die Schleife abgebrochen
6
//Programm ...
7
}
8
}
2. Macht wenig sinn, da halt das Programm was tun soll. Danach hängt er
da fest und ist nur durch ein neustart wieder benutzbar.
3. Macht auch relativ wenig Sinn, da man diese Bedingung ja auch in die
Klammern der While-Schleife machen kann. Höchstens wenn man zusätzlich
eine Bedingung hat und direkt nach dem Prüfen der Bedingung abbrechen
will, ohne dass die Schleife bis zum Ende durchläuft.
Rolf Magnus schrieb:> Miriam schrieb:>> Hallo zusammen,>>>> kann mir jemand sagen für was ich die while(1) schleife in einem>> C-Programm benötige?>> mein erster gedanke war, dass dadurch der Programm Code immer wieder>> wiederholt wird!>> Ja.>>> mein Klassenkamerad meinte aber, dass das C-Programm ein definiertes>> Ende braucht, kann mir jemand helfen?>> Die while-Schleife sorgt eher dafor, daß es gar kein Ende gibt. Beim PC> ist es ja kein Problem, wenn ein Programm zu Ende geht, aber was soll> ein µC dann machen? Also sorgt man durch die While-Schleife dafür, daß> es nie zum Ende kommt.
und dein Betriebssystem läuft nicht in ner while(1) schleifen? Den PC
stört das genauso sehr wie einen uC, dafür gibts sowohl bei PC
betriebssystemen den Leerlauftask und die whileschleife um den
Taskhandler, genauso wie bei (echtzeit-)betriebssystemen für uC.
bei windows ist es allerdings eher eine
while(!ich_will_den_benutzer_nerven_bool)-schleife
Miriam schrieb:> kann mir jemand sagen für was ich die while(1) schleife in einem> C-Programm benötige?
So etwas schreiben nur Programmierer, denen man zuvor mit Gewalt
eingeprügelt hat, daß das Verwenden von goto ihnen verboten ist.
Mumpitz. Für die Schleife in main() bei einem normalen uC-Programm finde
ich es besser und auch sauberer, eine Marke ("immerzu:") zu setzen und
dediziert zu dieser per goto zu springen. Maschinencodemäßig kommt es
wohl auf's gleiche raus, aber ein ehrliches goto ist besser als ein
mißbrauchtes while.
main(..)
{
initialisierungen...
immerzu:
dies und das tun, was grad ansteht
goto immerzu;
}
Ausdrücke wie while(1) braucht man nicht - es sei denn, man ist ein
grottenschlechter Programmierer, der es nicht schafft, in einer Schleife
die richtige Abbruchbedingung zu formulieren und deshalb etwa so sich
ausdrückt:
while(1) { if (abbruchbedingung) break; }
Bei einem uC ist es zumeist nicht sinnvoll, die Funktion main jemals zu
verlassen - es sei denn, man hat ein Betriebssystem drauf, zu dem dann
zurückgekehrt wird.
Es gibt noch ein anderes typisches Beispiel für den Einsatz einer
while{1}-Schleife:
Wenn auf Deinem uC ein Scheduler läuft, werden die einzelnen Tasks
üblicherweise (wenn nicht gar zwingend) in einer Endlosschleife
betrieben.
Diese Tasks laufen dann quasi-parallel (wenn sie nicht suspended sind).
Nur das Betriebssystem kann die Tasks wieder beenden. Und das
Betriebssystem ist auch die einzige Instanz, die (getriggert durch einen
Interrupt) den Prozi aus der einen Endlosschleife rausreissen und in die
eines anderen Tasks reinpflanzen kann. Gäbe ja ein heilloses
Durcheinander, wenn der Prozi "hinten" aus so einem Task "rauspurzeln"
würde... :-)
Michael Skropski schrieb:> 2.void main(){> //Config etc>> // Programm> while(1); // Ende, soll nichts mehr nach einmaligen Durchlauf machen> }
Diese Variante gibts aber auch und ist sogar Sinnvoll: Nämlich dann,
wenn nach dem eigentlichen Programmablauf nur noch auf Interrupts
reagiert wird.
Noch ein Kommentar bzgl. dem Äquivalent PC-Programm: auch eine Anwendung
unter Windows läuft architekturbedingt in einer Endlosschleife - in der
Abarbeitung der Message Queue. Der Abbruch und damit das Programmende
erfolgt auch nur durch eine dezidierte Mitteilung durch die API.
Dazu kommt es beim µC sinngemäß natürlich nie.
Das ganze mit while(1) zu konstruieren ist völlig legitim.
Finsbury schrieb:> Das ganze mit while(1) zu konstruieren ist völlig legitim.
Verbieten wird es die keiner, aber es ist absolut unüblich. Ich
programmiere seit 1992 unter Windows, und eine while(1) Schleife als
Hauptprogramm ist mir noch nie zwischen die Finger gekommen.
Abgesehen davon programmiert man Windows heute üblicherweise in C++, und
da kümmert man sich herzlich wenig um das Hauptprogramm, sondern
implementiert Methoden.
Das letzte mal, dass ich ein Programm durch einen
"Betriebssystem"-Aufruf beendet habe, war unter DOS:
1
mov ax, 4c00h
2
int 21h
:-D
Einzige mir bekannte Ausnahme:
Wenn man
1
raise(SIGABRT);
aufruft, wird das Programm beendet, ohne dass das return in WinMain()
erreicht wird, aber das sollte nur für die Behandlung von
Ausnahme-Fehlern verwendet werden.
Ach ja:
Endlosschleifen sehen so viel schicker aus:
Finsbury schrieb:> Der Abbruch und damit das Programmende> erfolgt auch nur durch eine dezidierte Mitteilung durch die API.
Lesen und verstehen auch schon seit '92?
"durch die" => "von der" wäre eindeutiger gewesen.
Gilt auch für:
"ist völlig" => "ist beim µC völlig"
Finsbury schrieb:> Lesen und verstehen auch schon seit '92?
Häme vor der Stellungnahme seit wann?
Hallo,
die ganze Diskussion ist völlig lächerlich, da überhaupt jeder Prozessor
in einer Endlosschleife läuft, wenn er nicht zum Schlafen gelegt wurde.
Was sollte er denn sonst tun?
Entweder, in den einfachsten Steuerungen, wartet der Prozessor endlos
auf Tastatureingaben oder Temperaturmessungen oder irgendwas, was
regelmässig geschieht und eine Aufgabe darstellt. In einem
Windowsprogramm (oder einem anderen ereignisgesteuerten System) läuft
endlos die Messagequeue, was etwa das Gleiche ist nur mit etwas mehr
möglichen Ereignissen. Und ein ausgewachsenes Betriebssystem läuft in
einer Endlosschleife im Scheduler, der den Tasks Rechenzeit zuweist (und
die laufen ihrerseits in einer Endlosschleife).
Auch die Frage, ob das als Programmierer erlaubt ist, ist geradezu
absurd - alle diese Endlosschleifen wurden von Programmierern
geschrieben, und in der Regel von denen der besseren Sorte. Die würden
sich über die Diskussion hier kranklachen.
Gruss Reinhard
Reinhard Kern schrieb:> die ganze Diskussion ist völlig lächerlich, ..
Die Eingangsfrage ist schon unlogisch, da sie Syntax ("braucht
definiertes Ende") und Semantik (was "while(1)" tut) in Beziehung
stellt.
> ..da überhaupt jeder Prozessor> in einer Endlosschleife läuft, wenn er nicht zum Schlafen gelegt wurde.> Was sollte er denn sonst tun?
Das bezweifelt hier keiner. Man stritt sich um Details, wie diese
Endlosschleife zu implementieren sei.
> Entweder, in den einfachsten Steuerungen, wartet der Prozessor endlos> auf Tastatureingaben oder Temperaturmessungen oder irgendwas, was> regelmässig geschieht und eine Aufgabe darstellt. In einem> Windowsprogramm (oder einem anderen ereignisgesteuerten System) läuft> endlos die Messagequeue, was etwa das Gleiche ist nur mit etwas mehr> möglichen Ereignissen. Und ein ausgewachsenes Betriebssystem läuft in> einer Endlosschleife im Scheduler, der den Tasks Rechenzeit zuweist (und> die laufen ihrerseits in einer Endlosschleife).
Wir scheinen unterschiedliche Vorstellungen von Endlosschleifen zu
haben. In meiner haben Endlosschleifen kein Abbruchkriterium, auch
keinen Ausstieg per break oder return. Programme, die beendet werden
können, also typischerweise solche, die in einem Betriebssystem
aufgerufen werden, haben eigentlich keine Endlosschleifen, zumindest
nicht absichtlich.
Meistens schreibt man also µC-Programme und Betriebssystem mit, und
User-Anwendungen ohne Endlosschleife.
Ein while(1) am Ende von main macht keinen Sinn. Schliesslich ist main
auch nur eine Funktion die von woanders aufgerufen wurde und sie kann
und darf natuerlich auch wieder verlassen werden.
Da spricht absolut nichts gegen! Dann laufen halt wieder die
Serviceroutinen des Compilers und die wissen schon was sie dann zu
machen haben. Bei mir sieht das z.B so aus:
[start.s]
! Wir sind fertig, also starten wir mal main.c
mov.l main_k,r0
jmp @r0
nop
loop: ! Fuer den Fall das main zurueckkehrt
bra loop
Ihr seht, es gibt da nochmal eine Endlosschleife. :-D
Ich nutze while(1) aber gelegentlich bei der Programmentwicklung wenn
ich will das mein Programm an einer definierten Stelle stehenbleibt. Die
Alternative waere natuerlich im Debugger einen Breakpoint zu setzen,
aber ein while(1) hat den Vorteil das dann die Interrupts noch laufen
und wenn man kurz vorher mit my_printf("Fehler XY") was ausgegeben hat
dann liegt das jetzt erst in der Fifo und wird dann noch im Hintergrund
vom IRQ ausgegeben.
Schlimmer als while(1) sind uebrigens diese Murksprogramme wo es sowas
gibt: while(i2c_sendflag ==TRUE); oder while(uart_tx.empty ==TRUE);
Das sind dann naemlich Programme die einmal im Monat stehen bleiben und
keiner weiss warum.
Olaf
Wo's so schön ins esotherische abgleitet:
Aus Gewohnheit nehme ich immer for(;;)
Meist fällt mir auch noch ein wundervoller Laufindex ein, zB 'i':
for( i=0;;i++);
goto ist ja absolut so etwas von out und böse. :-)))
Und während hier noch intensiv nach der einzigen wahren Wahrheit gesucht
wird, feiert man in Shenzhen mit einen halben Glas Apfelschorle das
zehnmillionste fertige Produkt.
Philipp Klostermann schrieb:> Programme, die beendet werden> können, also typischerweise solche, die in einem Betriebssystem> aufgerufen werden, haben eigentlich keine Endlosschleifen, zumindest> nicht absichtlich.
Dann kennst du offensichtlich Programme wie Windows nicht. Die
Messageloop hat kein Ende und ein Windowsprogramm kann sich auch
garnicht selbst beenden - es muss das System bitten "Bitte Bitte beende
mich!". Die Funktion dazu heisst PostQuitMessage.
Man kann natürlich durchaus Programme schreiben, ohne sowas zu wissen,
denn heute legt meistens eine IDE oder ein Framework die Messageschleife
an, einschliesslich des Austiegsmechanismus z.B. über den Standardknopf
mit dem X.
Gruss Reinhard
µC-Bastler schrieb:> Miriam schrieb:>> mein Klassenkamerad meinte aber, dass das C-Programm ein definiertes>> Ende braucht, kann mir jemand helfen?>> Und was soll der µC dann machen?
Trotzdem fordert der C-Standard ein definiertes Ende.
W.S. schrieb:> aschinencodemäßig kommt es> wohl auf's gleiche raus, aber ein ehrliches goto ist besser als ein> mißbrauchtes while.>> main(..)> {> initialisierungen...>> immerzu:>> dies und das tun, was grad ansteht>> goto immerzu;> }
Warum genau soll es besser sein?
Florian schrieb:> Bartli schrieb:>> Eben nicht. Man nimmt dazu ein goto. Jetzt habt ihr's doch eben gelernt.>> Mach die Tür bitte leise zu. Von außen.
Ich nehme an, du hast die hofentlich vorhandene Ironie übersehen.
Reinhard Kern schrieb:> Dann kennst du offensichtlich Programme wie Windows nicht. Die> Messageloop hat kein Ende und ein Windowsprogramm kann sich auch> garnicht selbst beenden - es muss das System bitten "Bitte Bitte beende> mich!". Die Funktion dazu heisst PostQuitMessage.
Du kennst Windows aber auch nicht, sonst würdest du nicht so einen
Unsinn schreiben. Ich poste hier mal ne Standard-Winmain:
int WINAPI WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{ MSG msg;
HACCEL hAccelTable;
if (!InitInstance (hInstance, nCmdShow)) return FALSE;
InitCommonControls();
hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_CETERMINAL);
while (GetMessage(&msg, NULL, 0, 0))
{ if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{ TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}
So. Die WinMain läuft solange in der Messageloop, bis GetMessage ne Null
liefert und quittiert dann den Dienst. Wer will, könnte natürlich nach
der Messageloop noch was anderes schreiben und das Programm eben nicht
beenden.
W.S.
ich weis ja nicht wie es bei anderen compilern, entwicklungsumgebungen
etc. ist, aber bei AVR Studio ist es so, das die main-Funktion eine
int-funktion sein muss und auch einen return wert haben muss, alles
andere lässt der compiler gar nicht durchgehen!
1
intmain(void)
2
{
3
while(1)
4
{
5
//tu was
6
}
7
return0;
8
}
Somit ist trotz endlosschleife ein definiertes ende vorhanden, es wird
nur nicht erreicht, was etwas anderes ist!
Es läuft ja nicht die main-funktion als endlosschleife,
1
while(1)
2
{
3
intmain();
4
}
(mir ist bewusst das dies syntaktisch völliger mist ist, soll aber den
unterschied verdeutlichen!)
sondern etwas innerhalb der main-funktion läuft als endlosschleife!
Kaj schrieb:> ich weis ja nicht wie es bei anderen compilern, entwicklungsumgebungen> etc. ist, aber bei AVR Studio ist es so, das die main-Funktion eine> int-funktion sein muss und auch einen return wert haben muss
Das ist auch richtig so. int main() ist C Standard. Vielleicht gibt es
neuere Standards, die etwas anderes zulassen, aber eigentlich ist alles
andere falsch. Auch mein Informatikprofessor kam immer mit void main()…
Ok, ich muss ergänzen: Meinen Nachforschungen zufolge, war void
main(void) mal erlaubt, ist es aber nicht mehr und alles außer int
main() ist nicht verboten, lässt dem Compiler aber frei, zu machen, was
er will. Das heißt, es gibt kein definiertes Verhalten.
W.S. schrieb:> So. Die WinMain läuft solange in der Messageloop, bis GetMessage ne Null> liefert und quittiert dann den Dienst.
Ja, aber das passiert eben nur, wenn das System das Programm beendet -
sonst liefert GetMessage immer <> Null.
Die Diskussion wie endlos eine Endlosschleife ist führt sowieso zu
nichts. Wir sind uns zweifellos einig, dass in 1 Mio Jahren keine dieser
Schleifen mehr läuft und dass es insofern keine echten Endlosschleifen
gibt. Andrerseits behaupte ich nach wie vor Recht zu haben damit, dass
ein laufender Prozessor immer irgendwas ausführt und nicht einfach
stehenbleibt, wie sich das manche vorstellen. Auch nach Ende der WinMain
hört der Prozessor nicht auf Befehle auszuführen. Das Programm kehrt nur
wie bei jedem Unterprogramm dahin zurück wo es aufgerufen wurde. Ein
Pc-Prozessor quittiert niemals den Dienst bis der Strom weg ist, und das
ist auch bei allen anderen Systemen von der Waschmaschine an so.
Gruss Reinhard
Es ging hier doch garnicht darum, ob main nun als int void oder sonstwas
deklariert wird.
Es ging um mißbrauchte Statements wie eben for(;;) oder while(1).
Es gibt von sowas sicher noch ne Menge Abarten. Warum machen das die
Leute? Es gibt Marken in C und es gibt das Statement goto. Für
Schleifen, von denen man von vornherein weiß, daß sie niemals verlassen
werden sollen und unendlich ohne Zähl-oder Abbruchkriterium durchlaufen
werden sollen, ist Marke: goto Marke genau der richtige Text.
Warum zieren sich hier die Leute wie die Zicke am Strick so sehr
dagegen?
Ich seh da nur den gesteigerten Willen zum Nebeneffekt oder das Ergebnis
einer Art Dressur. Jedenfalls ist verständnisvolles Nachdenken nicht mit
dabei. Ich frag deshalb mal provokativ:
Warum sollte man for(;;) oder while(1) benutzen?
Weil man zu doof ist, goto zu schreiben?
Oder weil man unbedingt danach noch ein return 0; hinschreiben möchte,
weil main ja int ist und der Compiler auf solche Formsachen dann doch
achtet, obwohl dem Schreiber klar ist, daß der dafür erzeugte Code
unerreichbar ist?
W.S.
W.S. schrieb:> Warum sollte man for(;;) oder while(1) benutzen?
Ganz einfach: weil eine Schleife, besonders so eine wichtige wie die
Hauptschleife eines Embedded-Programms, auch als solche erkennbar sein
sollte. Goto ist was für Write-Only-Programmierer, deren Hauptbestreben
darin besteht, dass niemand, ganz besonders nicht der Chef, den Code
verstehen kann. So sichert man vielleicht seinen eigenen Arbeitsplatz,
aber nicht eine wartbare Software. Am besten führt man dann noch mehrere
Gotos nacheinander und über Kreuz aus, damit niemand mehr so leicht die
Struktur der Software erkennen kann.
Gruss Reinhard
W.S. schrieb:
> unendlich ohne Zähl-oder Abbruchkriterium durchlaufen> werden sollen
in C sind es immer Laufbedingungen, keine Abbruchbedingungen! Riesen
unterschied!!!
while(1) hat eine ganz klare laufbedinung: Laufe, solange 1 wahr ist!
So, wo ist das jetzt ein missbrauchtes "statemant"?
das return 0; müsste ich ebenso bei einem goto schreiben, und hat nichts
mit der schleife zu tun! die anmerkung mit der main-funktion, war auch
auf die aussage mit dem definierten ende eines c-programmes bezogen!
Es kann jeder programmieren wie er will, aber wer goto benutzt hat das
konzept der strukturierten programmierung nicht verstanden!
goto führt, so wie schon seit ewigkeiten, zu "spaghettie-code", das ist
tatsache! Ein strukturiertes Programm und wartbarer code sehen anders
aus!
W.S. schrieb:> Es gibt von sowas sicher noch ne Menge Abarten. Warum machen das die> Leute? Es gibt Marken in C und es gibt das Statement goto. Für> Schleifen, von denen man von vornherein weiß, daß sie niemals verlassen> werden sollen und unendlich ohne Zähl-oder Abbruchkriterium durchlaufen> werden sollen, ist Marke: goto Marke genau der richtige Text.
Begründet hast du es immer noch nicht. Bei while (1){ sehe ich
wenigstens auf den ersten Blick, dass alles folgende In der
Endlosschleife läuft. Übrigens wurden schleifen ausgerechnet dafür
erfunden, um Dinge wiederholt auszuführen. Aber offenbar hast du eine
persönliche Abneiung gegen Schleifen. Ich nehme mal an, du ersetzt auch
alle anderen Schleifen durch gotos, um mal richtig den Rebellen zu
markieren?
W.S. schrieb:> Ich seh da nur den gesteigerten Willen zum Nebeneffekt oder das Ergebnis> einer Art Dressur. Jedenfalls ist verständnisvolles Nachdenken nicht mit> dabei. Ich frag deshalb mal provokativ:>> Warum sollte man for(;;) oder while(1) benutzen?
Nun, eventuell weil genau das der Sinn einer Schleife ist? Und weil es
übersichtlicher ist?
W.S. schrieb:> Oder weil man unbedingt danach noch ein return 0; hinschreiben möchte,> weil main ja int ist und der Compiler auf solche Formsachen dann doch> achtet, obwohl dem Schreiber klar ist, daß der dafür erzeugte Code> unerreichbar ist?
Ich würde ja gern sagen, dass es langsam echt lächerlich wird, aber das
ist es ja bereits. Dass der C-Standard (und damit jeder ordentliche
Compiler) verlangt, dass main() etwas zurückgibt, ist ziemlich
unabhängig davon, ob das Ende nun erreicht wird oder nicht, vor allem
aber davon, ob das erreichen des return-Statements nun durch eine
Schleife oder ein missbrauchtes goto verhindert wird.
Kaj schrieb:> goto führt, so wie schon seit ewigkeiten, zu "spaghettie-code", das ist> tatsache! Ein strukturiertes Programm und wartbarer code sehen anders> aus!
Man könnte sich ja noch Szenarien überlegen, in denen "goto" sinnvoll
ist. Aber wer Sprunganweisungen ganz Assembler-like für Schleifen nutzt,
hat echt den Knall nicht gehört und sollte sich mal überlegen, warum
heutige Programmiersprachen üblicherweisein aller Regel über Schleifen
verfügen.
Reinhard Kern schrieb:> Philipp Klostermann schrieb:>> Programme, die beendet werden>> können, also typischerweise solche, die in einem Betriebssystem>> aufgerufen werden, haben eigentlich keine Endlosschleifen, zumindest>> nicht absichtlich.>> Dann kennst du offensichtlich Programme wie Windows nicht.
:-D
Irgendwie hapert es hier auf mehreren Ebenen an den Begrifflichkeiten,
und so reden wir aneinander vorbei.
Also: Meinst Du nun Windows selbst oder Programme, die unter Windows
laufen? (Ich weiß, dass Windows auch ein "Programm" ist, aber dafür habe
ich ja die Einschränkung "die in einem Betriebssystem aufgerufen werden"
gemacht.
> Die> Messageloop hat kein Ende und ein Windowsprogramm kann sich auch> garnicht selbst beenden - es muss das System bitten "Bitte Bitte beende> mich!". Die Funktion dazu heisst PostQuitMessage.
<<The PostQuitMessage function posts a WM_QUIT message to the thread's
message queue and returns immediately; the function simply indicates to
the system that the thread is requesting to quit at some time in the
future.
When the thread retrieves the WM_QUIT message from its message queue, it
should exit its message loop and return control to the system. The exit
value returned to the system must be the wParam parameter of the WM_QUIT
message.>>
".. exit its message loop .." - Alles klar?
Hier wurden schon 2 Grundgerüste von Windows-Programmen gepostet, eines
von mir und eines von W.S. Beide haben gemeinsam, dass die Message Loop
ein Abbruchkriterium hat: "while (GetMessage(&msg, NULL, 0, 0))"
Es ist übrigens relativ wumpe, ob man nun PostMessage(WM_QUIT,...)
aufruft oder PostQuitMessage(..). Aber das ist in Bezug auf das Thema
dieses Threads egal.
Ich habe bereits darauf hingewiesen, dass in der Eingangsfrage Syntax
und Semantik vermischt wurden, und so die Frage selbst schon paradox
ist. Ich denke, dass wir hier auf einen Troll hereingefallen sind, der
clever genug ist zu wissen, dass man mit genau so etwas Flamewars wie
diesen hier produzieren kann.
> Man kann natürlich durchaus Programme schreiben, ohne sowas zu wissen,> denn heute legt meistens eine IDE oder ein Framework die Messageschleife> an, einschliesslich des Austiegsmechanismus z.B. über den Standardknopf> mit dem X.
Seit Visual C++ und Borland C++ kann man das, ja. Aber wer seine
Programme debuggen will, kommt nicht umhin sich mit den Hintergründen
auseinander zu setzen.
Der Standardknopf mit dem X und übrigens auch das Systemmenü sind
Features, die von Windows bereitgestellt werden und als
Fenster-Attribute eingeschaltet werden. Diese haben nichts damit zu tun,
ob man sein Programm in ANSI-C mit brief oder notepad und Aufruf des
Compilers aus der Kommandozeile oder in C++ mit einer IDE und einer
Klassenbibliothek entwickelt.
Ich habe in diesem Thread bisher auf persönliche Attacken verzichtet,
und es würde der Diskussion gut tun, wenn Du dazu übergehen würdest,
diese läppischen Anspielungen auf meine Programmiererfahrung weg zu
lassen. - Sonst überlege ich es mir noch anders. Angriffsfläche bietest
Du genug..
Joachim Drechsel schrieb:> Einfach CreateDialog() verwenden und 100 Zeilen Code gespart ...
Tolle Idee! Die Programmierer der MFC müssen ja Dumpfbacken sein, dass
die darauf nicht gekommen sind.. Oh Mann, jetzt läuft dieser "Thread"
völlig aus dem Ruder.
Reinhard Kern schrieb:> W.S. schrieb:>> So. Die WinMain läuft solange in der Messageloop, bis GetMessage ne Null>> liefert und quittiert dann den Dienst.> Ja, aber das passiert eben nur, wenn das System das Programm beendet -> sonst liefert GetMessage immer <> Null.
Was denn nun? Wenn das System das Programm beendet, und das tut es nur
in Ausnahmefällen per raise(), ist es "weg" und GetMessage() kehrt nicht
zurück. Wenn ein Programm normal durch User-Eingabe (z.B. <Alt>+<F4>)
beendet wird, läuft die GetMessage()-Schleife erst mal weiter, bis das
Ende-Ritual mit WM_DESTROY und WM_CLOSE am Ende durchlaufen ist, und
GetMessage() 0 zurückliefert. Zu allerletzt beendet sich das Programm
selbst, indem es aus WinMain() zurückkehrt.
> Die Diskussion wie endlos eine Endlosschleife ist führt sowieso zu> nichts. Wir sind uns zweifellos einig, dass in 1 Mio Jahren keine dieser> Schleifen mehr läuft und dass es insofern keine echten Endlosschleifen> gibt.
Aus http://de.wikipedia.org/wiki/Endlosschleife :
"Endlosschleifen in der Informatik sind Schleifen, die nach jeder
Abarbeitung erneut abgearbeitet werden, falls die Ausführung nicht durch
äußere Einflüsse abgebrochen wird. Äußere Einflüsse sind dabei solche,
die im idealtypischen Ablauf des Programms nicht vorkommen,
beispielsweise das Abschalten des Computers."
Der einzige Grund, warum laufende Endlosschleifen in x Jahren nicht mehr
laufen werden, ist dass sie entweder betriebssystemseitig beendet sein
werden oder die Hardware, auf der sie laufen, ausgeschaltet oder gar
nicht mehr existent sein wird.
> Andrerseits behaupte ich nach wie vor Recht zu haben damit, dass> ein laufender Prozessor immer irgendwas ausführt und nicht einfach> stehenbleibt, wie sich das manche vorstellen.
Wer stellt sich dass so vor? Hier im Thread keiner. Vielleicht erkennst
Du irgendwann mal, dass andere als Du nicht pauschal doooof sind, nur
weil Du Dich für superclever hältst. Dann würdest Du auch nicht denen,
die Deine ganz individuellen Interpretationen von allgemeinen
Begriffen nicht teilen so einen Schwachsinn unterstellen, sondern
vielleicht mal auf den Gedanken kommen, dass für alle anderen eine
Endlosschleife eben eine Endlosschleife ist, die definitionsgemäß nur
durch äußeren Eingriff (kill, Powerbutton oder CPU-Tod) beendet wird,
und nicht eine Schleife, die besonders lange läuft, wie es für Dich ganz
persönlich der Fall zu sein scheint.
> Auch nach Ende der WinMain> hört der Prozessor nicht auf Befehle auszuführen. Das Programm kehrt nur> wie bei jedem Unterprogramm dahin zurück wo es aufgerufen wurde.
Überflüssig, längst geklärt. Keiner hat behauptet, dass es auf OS-Ebene
keine Endlosschleifen gibt.
Ich fasse mal grob zusammen:
1. Ein Troll ("Miriam" - ja nee, is klar) provoziert morgens eine
Diskussion um Henne und Ei.
2. Alle fallen darauf rein und machen mit. Die Frage kann keiner
beantworten, weil sie keine Frage ist.
3. Nach etwa 1/2 Stunde entwickelt der Thread Eigenleben. Nun wird über
Implementierungsdetails von Schleifen diskutiert. Da jeder gerade ein
anderes Szenario (µCs, User-Programme, Betriebssysteme) im Kopf hat,
treffen die unterschiedlichsten Vorlieben aufeinander. Nebenbei wird
auch Windows aus der Sicht von User-Programmen erwähnt.
("while(!ich_will_den_benutzer_nerven_bool)-schleife" - Wobei hier das
"!" unnötig ist.)
4. Mittlerweile kloppt man sich um goto und while.
5. Am Abend kommt dann die Behauptung, die GetMessage()-Schleife in
einem Windows-Programm sei auch eine Endlosschleife. Da schalte ich mich
ein, weil ich diese Falschaussage nicht so stehen lassen möchte. Dafür
werde ich von dem Autor besagten Threads blöd angeblökt. Meine
Stellungnahme dazu bleibt unbeantwortet.
6. 1 1/2 Stunden nach Mitternacht gesellt sich Reinhard dazu, der von
sich meint, den tollen Überblick zu haben, und alle anderen wohl für
geistig beschränkt hält. Zumindest disst er erstmal alle Anwesenden als
"lächerlich". OS- und Programmebene durcheinanderwürfelnd postuliert er
die Endlosschleife bei Windows-Programmen und schließt damit ab, den
anderen Teilnehmen die Programmierkompetenz abzusprechen.
7. Ich versuche noch in der Nacht, darauf diplomatisch zu reagieren.
("Wir scheinen unterschiedliche Vorstellungen von Endlosschleifen zu
haben.")
8. Am nächsten Morgen gesellt sich erst mal Olaf dazu, und sagt, dass
man die Endlosschleife bei einem µC-Programm auch über die Rückkehr zum
Startup-Code machen kann, da der dann main() wieder aufruft. Einer der
ganz wenigen Beiträge, der eine Information enthält, sei sie nun
nützlich oder nicht. Daraufhin folgt ein weiterer Vorschlag für eine
nerdige Endlosschleife und jemand äußert seinen Unmut über die
Verschwendung unserer gesammelten Intelligenz und Zeit an diese
(zugegebenermaßen unnötige) Trollfütterung.
9. Reinhard schmeißt wieder mit Halbwissen um die Windows-Programmierung
um sich, ohne eine wirkliche Aussage zu machen, außer dass ich das
"Programm Windows" nicht kennen würde.
10. Die philosophische Diskussion um while und goto geht nebenbei
weiter.
11. Da ich den ganzen Tag über gar nicht zu Hause war, kommt mir einer
der bis dato als goto-Verfechter aktiv war zuvor und demonstriert am
frühen Abend korrekt anhand des Quellcodes eines minimalen
Windows-Programms, dass die GetMessage()-Schleife keine Endlosschleife
ist. Das hatte ich auch schon probiert, aber repititia est marter
studiorum. - Einen Versuch war es wert.
12. Die Hauptdiskussion gleitet nun in den Nebenzweig des return-Typs
von main() ab.
13. In der Diskussion um die GetMessage()-Schleife wird aufgrund
unterschiedlicher Begriffsinterpretationen aneinander vorbei geredet.
14. Ich komme nach Hause, und beantworte den mittäglichen Spökes von
Reinhard, seinen 2. Beitrag übersehend.
15. Zwei Joachims gesellen sich dazu, und lästern eine Runde, einer
davon outet sich als Halbwisser bzgl. Windows-Programmierung.
16. Als ich mich dazu äußere, beschließe ich das ganze mal grob
zusammenzufassen, und dabei fällt mir der abendliche Beitrag von
Reinhard auf, und ich schiebe meine Antwort darauf noch in diesen
Beitrag. Was mir auch auffällt ist das völlig Durcheinander, das dieser
Thread darstellt, und ich beschließe, mich lieber wieder dem Layout des
2. Versuchs meiner Trenntrafo-Anzeige zu widmen und hin und wieder nach
einem schönen oder interessanten Thread zu suchen. :-D
BFN
Spätestens hier wäre die Diskussion zu Ende gewesen.
Miriam schrieb:> kann mir jemand sagen für was ich die while(1) schleife in einem> C-Programm benötige?> mein erster gedanke war, dass dadurch der Programm Code immer wieder> wiederholt wird!
Bingo, stimmt und wird von dem Beispiel erfüllt.
Miriam schrieb:> mein Klassenkamerad meinte aber, dass das C-Programm ein definiertes> Ende braucht
Bingo, stimmt und wird von dem Beispiel erfüllt.
Fragen beantwortet, weitere Diskussion überflüssig oder im
Philosophie-Forum weiterführen.
Grüße
Fritz M.
Philipp Klostermann schrieb:> Oh Mann, jetzt läuft dieser "Thread"> völlig aus dem Ruder.
Ach Philipp, im Grunde geb ich dir zu 100% Recht, aber ich finde dieses
PileUp in gewisser Hinsicht schon sehenswert.
Es ist ja nicht die "warum-eigentlich" Urfrage "für was ich die while(1)
schleife in einem C-Programm benötige?", die mir wie das letzte
Aufbäumen der letzten noch nicht dressierten grauen Zelle einer
dressierten Seele vorkommt, bevor sie sich damit abfindet, daß MAN DAS
EBEN SO ZU TUN HAT. Ob das nun eine gezielte Trollerei ist oder nicht,
mag ich nicht entscheiden. Die korrekte Antwort wäre, daß man while(1)
in einem C-Programm überhaupt nicht benötigt, weil es für das Ausdrücken
der Absicht des Programmierers eine Reihe anderer Möglichkeiten gibt.
Aber:
Es ist viel interessanter, zu beobachten, wie die diversen Disputierer
sich benehmen. Ein buntes Gemisch von Leuten, die nicht lesen, verstehen
und überlegen wollen, sondern sich in einer virtuellen Arena wähnen, wo
man um sich schlagen muß, notfalls in Ermangelung von Argumenten mit
Unterstellungen.
Genau da zeigen sich Trolle höherer Ordnung, um das mal so zu
umschreiben. Immerhin weiß ich nun, wieviel ich von deren Ansichten
halten darf. Das ist der eigentliche Nutzinhalt dieses Threads.
Schönen Abend noch.
W.S.
W.S. schrieb:> Die korrekte Antwort wäre, daß man while(1)> in einem C-Programm überhaupt nicht benötigt, weil es für das Ausdrücken> der Absicht des Programmierers eine Reihe anderer Möglichkeiten gibt.
Warum so zurückhaltend: Das gilt nicht nur für while(1) sondern
natürlich für jedes while und genau so auch für jedes for.
Funktionen sind pfui, wozu gibt es copy&paste.
Und alle Variablen sind global.
Nur Warmduscher schreiben Programme, die auch ein anderer verstehen
kann.
Peter
Also wer glaubt, dass while(1) oder for(;;) oder auch goto nicht in ein
C (C++) Programm dürfen!, der hat auch was falsch verstanden. Es gibt
auch dafür sehr sinnvolle Einsatzbeispiele. Ihr braucht nur mal in den
Linux-Kernel Quellen stöbern, da findet ihr auch alle Varianten, und ich
würde mich nicht trauen zu sagen die Autoren sind Deppen. Schleifen
sollten da abbrechen wo auch die Abbruchbedingung auftritt.
Es bringt niemanden etwas eine Abbruchbedingung im while oder for
Statement zu testen die auf Stellen des Codes referenziert die räumlich
zig oder hunderte Zeilen woanders steht.
Peter Dannegger schrieb:> Echte Männer schreiben Spaghetticode:> #define do goto> #define while goto> #define for goto>> Funktionen sind pfui, wozu gibt es copy&paste.>> Und alle Variablen sind global.>> Nur Warmduscher schreiben Programme, die auch ein anderer verstehen> kann.
Bei der Verwendung von do, while und for macht sich ja, wie wir oben
erfahren haben, des Missbrauchs verdächtig. Und bei goto riskiert man,
von anderen C-Programmierern für einen Basic-Programmierer gehalten zu
werden. Das geht beides nicht.
Deswegen:
#define do goto
#define while goto
#define for goto
#define goto int a,b;\
a = 1;\
b = 0;\
a = a/b;
Dann stürzt der Controller gezielt ab, man wartet auf den Watchdog-Reset
und alles ist gut. So machen das Geisterfahrerüberholer.
mfg.
vn nn schrieb:> µC-Bastler schrieb:>> Miriam schrieb:>>> mein Klassenkamerad meinte aber, dass das C-Programm ein definiertes>>> Ende braucht, kann mir jemand helfen?>>>> Und was soll der µC dann machen?>> Trotzdem fordert der C-Standard ein definiertes Ende.
Wo?
Peter Dannegger schrieb:> Echte Männer schreiben Spaghetticode:
Aber konform sollte er schon sein, denn sonst ist das ja keine Kunst.
Und das hier:
> #define do goto> #define while goto> #define for goto
ist leider nicht konform.
Peter Dannegger schrieb:> Echte Männer schreiben Spaghetticode:#define do goto> #define while goto> #define for goto> Funktionen sind pfui, wozu gibt es copy&paste.> Und alle Variablen sind global.>> Nur Warmduscher schreiben Programme, die auch ein anderer verstehen> kann.lol meine Worte. It was hard to write, it should be hard to read.
Jeder der einen sinnvollen Kommentar im Code schreibt wohnt noch bei
Mutti.
:-)
Philipp Klostermann schrieb:> ("while(!ich_will_den_benutzer_nerven_bool)-schleife" - Wobei hier das> "!" unnötig ist.)
dann hast du meine Intention hinter der Schleife nicht richtig
verstanden, aber in allen anderen Punkten hast du Recht.
Chris schrieb:> Chuck Norris schreibt Programme in nur EINER Zeile
Und ohne Leerzeichen.
Aber das macht nicht nur Chuck Norris. Das machen alle älteren
Programmierer so.
Denn damit nimmt man dem Compiler viel Arbeit ab. Schließlich muß der ja
alles mühsam rausschmeissen. Und das kostet Zeit. Und die hat man
irgendwann nicht mehr. Man will das Release ja noch miterleben.
Joachim Drechsel schrieb:> Dokus
Du weißt, was Dokus sind? Du solltest dich was schämen.
mfg.
Thomas Eckmann schrieb:> Denn damit nimmt man dem Compiler viel Arbeit ab. Schließlich muß der ja> alles mühsam rausschmeissen. Und das kostet Zeit. Und die hat man> irgendwann nicht mehr. Man will das Release ja noch miterleben.
Wieseo denn Compiler? Echte Programmierer hauen den Code gleich direkt
in den Speicher mit einen Hexeditor. Assembler und Comiler brauchen viel
zu lange zum Übersetzen. Man will das Release ja noch miterleben. ;-)
Chris schrieb:> Chuck Norris schreibt Programme in nur EINER Zeile :)
Nein. Mit nur einem Zeichen. Welches das ist, verrät er aber nicht, er
sagt nur: "Das richtige".
Der Entwickler schrieb:> Thomas Eckmann schrieb:>> Denn damit nimmt man dem Compiler viel Arbeit ab. Schließlich muß der ja>> alles mühsam rausschmeissen. Und das kostet Zeit. Und die hat man>> irgendwann nicht mehr. Man will das Release ja noch miterleben.>> Wieseo denn Compiler? Echte Programmierer hauen den Code gleich direkt> in den Speicher mit einen Hexeditor. Assembler und Comiler brauchen viel> zu lange zum Übersetzen. Man will das Release ja noch miterleben. ;-)
Da muß ich doch spontan wieder an diesen Klassiker denken:
http://xkcd.com/378/
Ein µC-Pedant zur magnetisierten Nadel wäre:
Ein Schalter an RESET, zwei Taster für MOSI und SCK, für Feiglinge noch
eine LED an MISO, und los geht's..
Eigentlich hatte ich gestern Abend gehofft, dass dieser Thread in
Vergessenheit gerät, aber so im völligen OT ist er wieder erträglich. :)