[C] Komma-Operator

OP Persönliche Seite #5122348
Grias Eich :)

beim Googeln bin ich auf das hier gestolpert:
1
int d    = 15   ; //Day     1-31
2
int m    = 5    ; //Month   1-12`
3
int y    = 2013 ; //Year    2013` 
4

5
int weekday  = (d += m < 3 ? y-- : y - 2, 23*m/9 + d + 4 + y/4- y/100 + y/400)%7;

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
Gast #5122369
Der Komma-Operator stellt ja nur die Auswertung von links nach rechts 
sicher.
In dem Beispiel will der Autor vielleicht seinen Hacker Status betonen.
Gast #5122388
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...
Gast #5122407
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... :-)
Gast #5122444
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...:-)
Gast #5122468
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.
Gast #5122732
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.
Gast #5122815
> 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.
#5122826
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.
Gast #5122878
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)
#5123059
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.
Moderator #5123077
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.
Gast #5127825
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ß
1
case ({3;})
kompiliert nicht... Hallo!?! 3 ist konstant?!?
#5128103
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.
Persönliche Seite #5128511
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...
#5128544
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
static uint8_t search_cmd( char *buf[], char *cmds[] )
8
{
9
  char *pbuf, *pcmd;
10
  uint8_t n;
11
  
12
  for( n = 0; *cmds[n] != '\0'; n++ ){                  // empty string = end of table
13
    pcmd = cmds[n];                                     // point to command
14
    pbuf = *buf;                                        // point to buffer
15
    for(; ((*pbuf++ ^ *pcmd++) & CASE_MASK) == 0; ){    // compare
16
      if( *pcmd == '\0' ){                              // command match
17
        *buf = skip_blanks( pbuf );                     // point to next non blank on success
18
        return n;                                       // and return command index
19
      }
20
    }
21
  }
22
  return NOT_FOUND;
23
}

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 9 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.