Berechnet den Wochentag aus dem Datum.
Interessant ist der Komma-Operator in der letzten Zeile ...
Ich programmier in C schon seit kA sicher 20 Jahren und eigentlich nicht
nur trivialen Kram ... Aber den Komma-Operator hab ich vorher noch nicht
gesehen ...
Interessanterweise kann man den Teil for den Operator nicht einfach
hinten einsetzen, weil y verändert werden könnte. Krass Lösung ...
Google meinte, in for-Schleifen wird er oft verwendet:
1
for(a=0,b=0;a<10;a++){
2
3
}
Also ja das kannte ich schon, aber außerhalb von for-Schleifen hab ich
den noch nicht gesehen ...
Wer kannte den noch nicht? xD
Aber die Schaltjahr-Berechnung finde ich geil :D
VG
Mampf
Mampf F. schrieb:> Hmm, also wofür gut? ;-)
Berechnung innerhalb function calls und dort wo mensch die
Blockanweisung {} nicht verwenden kann, da
(expr1, expr2) quasi wie { expr1; expr2; } funzt.
Man kann ohne Komma Operator leben.
Ich habe ihn nur dort benötigt, wo Makros was zurückliefern sollten,
aber zusätzlich vorher noch was ausgeführt werden sollte.
Also genau das, was man nieeemals tun sollte, es sei denn man liebt es
sich in den Fuß zu schiessen...
Mampf F. schrieb:> Hmm, also wofür gut? ;-)
Damit d nach der Berechnung zerstört ist und man sich wundert, welcher
Tag nun ist.
y wird auch zerstört (y--), das Komma als sequence point verhindert die
Warnung.
Wenn Du es noch in Deinem Code durch y-1 ersetzt, ist er perfekt.
Peter D. schrieb:> Wenn Du es noch in Deinem Code durch y-1 ersetzt, ist er perfekt.
Auf keinen Fall, dann wird der hintere Teil falsch gerechnet!
Tolles Beispiel für abgefahrenen Code.
Dem Entwickler würde ich anerkennend auf die Schulter klopfen,
für den Geek des Monats, und ihn schnellstens loswerden... :-)
Ich nehme die Entlassung zurück, nach dem Lesen des Wikipedia Artikels
zur Wochentagsberechnug ist der Code ja 27 Jahre alt. Da durfte man noch
so hacken...:-)
Es ging damals darum, es als "Einzeiler" zu haben. Das habe ich schon
von mehr als 27 Jahren gesehen, allerdings nicht als C-Code, damals war
eher BASIC verbreitet (Die Zeit der Heimcomputer).
Ewige Kalender waren damals noch witzig, da es keine Handies gab. Im
Kopf musste man die verschiedenen "Offsets" des Monats auswendig lernen.
Für den Rechner hat dann mal jemand solange krude dividiert, bis es
ganzzahlig zufällig passte. Der Rest ist dann einfache Mathematik. Und
die 400-Jahre-Regel hat damals auch keinen geschert, da sie in der
Vergangenheit nicht (bzw. nur 20 Jahre) relevant war, und in der Zukunft
nicht vor der 10. Generation an Nachfahren.
Die Lösung hier ist halt zusammengebastelt, ohne Komma wäre sie genauso
schwierig oder einfach.
Wobei
return 1,0;
eigentlich viel besser ist um das Lesen von Quelltexten
nicht zu langweilig zu machen.
Gerne auch in Vergleichen:
if(c == 0,040){ ... }
Kommentare sollte Mann da natuerlich sparsam verwenden.
> Für was? :)
Anzahl der Programmfehler messen.
Du baust 100 Fehler absichtlich ein und zählst wie viele absichtliche
und normale Fehler gefunden wurden. Damit kannst du dann berechnen, wie
viele normale Fehler noch nicht gefunden wurden.
Ein wesentliches Motiv für die , und ?: Operatoren liegt in der
Optimierung von Hand. Beispielsweise bei den damals wichtigen Funktionen
getc/putc. Frühe Compiler hatten mit Inlining nichts am Hut. Die
Effizienz der I/O wäre aber mit einem vollständigen Funktionsaufruf pro
char beim Teufel gewesen. Also wurde die Sprache so definiert, dass man
diese und andere kleine Funktionen ggf. auch als Präprozessor-Makros
implementieren konnte. So wurde getc nur bei leerem Puffer zu einem
Funktionsaufruf.
Heute sind solche Konstruktionen weitgehend obsolet.
Noch einer schrieb:> Du baust 100 Fehler absichtlich ein und zählst wie viele absichtliche> und normale Fehler gefunden wurden.
Vielen Dank! ich kannte zwar das Verfahren (mit markierten Fischen im
Teich), aber es auf Fehler anzuwenden: Einfach genial. Egal ob SW, HW,
Texte, Spezifikationen, ... Auch wenn die Stichprobe sicher verzerrt
wird, da die absichtlichen Fehler eher der Art bekannter Fehler
entsprechen (und dadurch häufiger entdeckt werden)
A. K. schrieb:> Heute sind solche Konstruktionen weitgehend obsolet.
Nicht in C++11. Denn constexpr-Funktionen dürfen dort nur ein
return-Statement enthalten. Der komplette Funktionsinhalt muss also als
ein einzelnes Statement geschrieben sein, das als Wert den return-Wert
der Funktion haben muss.
Rolf M. schrieb:> A. K. schrieb:>> Heute sind solche Konstruktionen weitgehend obsolet.>> Nicht in C++11. Denn constexpr-Funktionen dürfen dort nur ein> return-Statement enthalten.
Diese Restriktion wurde aber schon in C++14 stark gelockert, so dass man
in den Funktionen auch if-Anweisungen und nicht-statische Variablen
verwenden kann. Da sich die Aussage von A. K. auf "heute" bezieht,
trifft sie somit auch auf C++ zu.
Unter C++14 ist da so gut wie alles erlaubt, nicht nur if's. Lediglich
auf Exceptions und goto muß man verzichten. Ersteres ist verständlich,
letzteres sinnvoll.
Oliver
Thomas W. schrieb:> Mampf F. schrieb:>> OMG jetzt mach ich es schon selbst und denke, das ist eine gute Idee :'(>>>>> switch (*p) {>> ...>> case 'd': note = !strncmp(p, "is", 2) ? (p+=2, 311.13) : 293.66;>> break;>> ...>> }>>> Nenn es einfach ganz modern "Lambda-Expression", und jeder wird> begeistert sein.
Ich nicht. Statement-Expressions sind einfach cooler - bloß
Mampf F. schrieb:> switch (*p) {> ...> case 'd': note = !strncmp(p, "is", 2) ? (p+=2, 311.13) : 293.66;> break;> ...> }
Wie kann p[0] gleichzeitig 'd' und 'i' sein?
Oliver S. schrieb:> Unter C++14 ist da so gut wie alles erlaubt, nicht nur if's.> Lediglich> auf Exceptions und goto muß man verzichten. Ersteres ist verständlich,> letzteres sinnvoll.>> Oliver
leider nicht.
Ich fänd es super, wenn man funktionen als constexpr definieren könnte,
die tatsächlich rein von den inputs abhängen und nix weiter als ein paar
komplizierte Berechnungen machen (aber dennoch für den selben input
immer den selben output berechnen würden)
Leider sind selbst die grundlegendsten mathematischen Basisfunktionen
(zB aus cmath) alle nicht als constexpr definiert.
Peter D. schrieb:> Mampf F. schrieb:>> switch (*p) {>> ...>> case 'd': note = !strncmp(p, "is", 2) ? (p+=2, 311.13) : 293.66;>> break;>> ...>> }>> Wie kann p[0] gleichzeitig 'd' und 'i' sein?
volatile char *p;-)
Wobei das erste Argument von strncmp const char* ist und das volatile
verloren geht; spielt aber nur eine Rolle bei hosted implementation und
entsprechenden Optimierungen...
Mampf F. schrieb:> War ungetesteter Code ... Werd ich gleich fixen> :)
Ich würds trotzdem nicht so machen. Ich hasse strcmp-Monster wo man sich
die Strings über den Code verteilt zusammen suchen muß.
Ich schreibe lieber eine Parsefunktion, die ein Array abklappert. Das
kann man dann schön leserlich definieren und damit leicht Schreibfehler
oder Doppelungen erkennen.
Die Parsefunktion schreibe ich so, daß sie bei Erfolg den Pufferpointer
hinter die geparsten Zeichen setzt. D.h. man kann sie mehrfach aufrufen,
um zusammengesetzte Strings auszuwerten.
Muß der String in einen Wert umgewandelt werden, geht das bequem als
Arrayindex.
1
/*
2
compare buffer with string from list
3
if match, return index of string
4
list terminated by empty string
5
advance buffer pointer to next non blank character
6
*/
7
staticuint8_tsearch_cmd(char*buf[],char*cmds[])
8
{
9
char*pbuf,*pcmd;
10
uint8_tn;
11
12
for(n=0;*cmds[n]!='\0';n++){// empty string = end of table