Ich habe mich mit Ruby beschäftigt und finde die Schlüsselwörter „until“ und „unless“ sehr interessant. Also dachte ich, was eine gute Möglichkeit wäre, ähnliche Schlüsselwörter in C/C++ hinzuzufügen. Das ist mir eingefallen:
Ich suche hierzu ein paar Anregungen. Kann jemand eine bessere Alternative vorschlagen?
Hier ist ein Beispiel für ein Programm, das ich geschrieben habe, um zu veranschaulichen, was ich vorhatte:
#include <stdio.h>
#include <stdlib.h>
#define until(x) while(!(x))
#define unless(x) if(!(x))
unsigned int factorial(unsigned int n) {
unsigned int fact=1, i;
until ( n==0 )
fact *= n--;
return fact;
}
int main(int argc, char*argv[]) {
unless (argc==2)
puts("Usage: fact <num>");
else {
int n = atoi(argv[1]);
if (n<0)
puts("please give +ve number");
else
printf("factorial(%u) = %u\n",n,factorial(n));
}
return 0;
}
Es wäre großartig, wenn Sie mir einige Referenzen für ähnliche Tricks nennen könnten, die in C oder C++ eingesetzt werden können.
Es scheint, als hättest du es bereits getan.
– Thiago Cardoso
9. April 2011 um 19:26 Uhr
Obwohl diese auf den ersten Blick sehr schick aussehen, ist es angemessener, stattdessen Standard-C++ zu verwenden, auch wenn Sie nur für sich selbst programmieren. In der Teamarbeit ist das ein No-Go. Ihr Code wird ungewohnt aussehen. Ich erinnere mich an eine bestimmte sugar.h enthält Pascal-ähnliche Definitionen …
– mbx
9. April 2011 um 19:27 Uhr
Ich glaube nicht, dass ich mag unless mit einem else -Klausel (ich liebe es jedoch, wenn/es sei denn beim Lispeln). Ich bin nicht wirklich beeindruckt von einem until Schleife, kann aber daran liegen, dass ich sie noch nie zuvor benutzt habe.
– 6502
9. April 2011 um 19:42 Uhr
Dieses Projekt könnte Sie interessieren: lolcode.com die auch etwas syntaktischen Zucker hinzufügen … 😀
– Invers
21. April 2011 um 20:57 Uhr
Wenn Sie dies tun müssen, ist mein einziger Vorschlag, zu buchstabieren until richtig.
– Zach Rattner
22. April 2011 um 14:40 Uhr
James McNellis
Kann jemand eine bessere Alternative vorschlagen?
Ja. Tun Sie dies auf keinen Fall. Verwenden Sie einfach die while und if Aussagen direkt.
Wenn Sie in C oder C++ programmieren, programmieren Sie in C oder C++. Während until und unless in einigen Sprachen häufig und idiomatisch verwendet werden, sind sie nicht in C oder C++.
+1 dazu. Es mag idiomatisch sein, dies in Ruby zu tun, aber Sie programmieren nicht in Ruby, oder? Versuchen Sie nicht, eine Sprache dazu zu zwingen, sich wie eine andere zu verhalten, Sie werden auf diese Weise nur schlechten Code schreiben.
– Mike Bailey
9. April 2011 um 19:29 Uhr
Ich weiß, dass in einer großen Umgebung Codierung wie diese nur Ärger hervorrufen wird. Aber meine Frage war, wie ich das am besten mache; und nicht darüber, ob man das tun soll oder nicht.
– BiGYan
10. April 2011 um 6:57 Uhr
@BiGYaN: Der beste Weg, dies zu tun, besteht darin, dies überhaupt nicht zu tun.
– James McNellis
10. April 2011 um 7:31 Uhr
Das ist !nützlich.
– n-Schläge
13. Juli 2020 um 21:34 Uhr
Jack v.
Die Art und Weise, wie Sie es getan haben, scheint mir die richtige zu sein, wenn Sie es überhaupt tun wollen. Denn die Erweiterung des Makros ist Also ähnlich wie Sie es erwarten würden[1]ich denke, es ist richtig, das Makro wie syntax () aussehen zu lassen, anstatt wie die normalerweise empfohlenen SCARY_UPPERCASE_MACROS(), die verwendet werden, um zu zeigen, dass dieser Code nicht der üblichen Syntax folgt und Sie ihn nur vorsichtig verwenden sollten.
[1] Der einzige Fehler ist die Unfähigkeit, Variablen zu deklarieren, was sowieso unwahrscheinlich ist und bei falscher Verwendung wahrscheinlich einen Fehler an der richtigen Stelle erzeugt, anstatt etwas Seltsames zu tun.
Darüber hinaus sind auch kleine Steigerungen der Lesbarkeit wichtig, so kann man sagen until ( Anstatt von while (! macht es wirklich einfacher, viele Schleifen zu lesen. Wenn die Endbedingung leichter als Ausnahmebedingung angesehen werden kann (unabhängig davon, ob dies der Fall ist oder nicht), erleichtert das Schreiben der Schleife in dieser Richtung das Lesen. Obwohl es also nur syntaktischer Zucker ist, denke ich, dass es Grund gibt, darüber nachzudenken.
Jedoch Ich glaube nicht, dass es das wert ist. Der Nutzen ist gering, da die meisten Programmierer ans Lesen gewöhnt sind if (! und die Kosten sind real: Jeder, der den Code liest, muss prüfen, ob es sich um ein Makro oder einen benutzerdefinierten Compiler handelt und ob er das tut, was er denkt. Und es kann Sie fälschlicherweise glauben machen, dass Sie Dinge tun können wie i=5 unless xxxx;. Solche kleinen Verbesserungen würden, wenn sie weit verbreitet wären, die Sprache fragmentieren, daher ist es oft am besten, die Dinge auf die übliche Weise zu tun und Verbesserungen langsam anzunehmen.
Es kann jedoch gut gemacht werden: Die Gesamtheit von boost und tr1, insbesondere das Zeug, das mit Templates gemacht wird, um wie Erweiterungen der Bibliothek auszusehen, beinhaltet das Erweitern von C++ auf verschiedene Arten, von denen viele nicht übernommen werden, da sie sich nicht lohnen es, aber viele davon haben eine geringe oder sehr weit verbreitete Akzeptanz, weil sie echte Verbesserungen gebracht haben.
Der erste Absatz dieser Antwort ist, gelinde gesagt, problematisch! Makros haben keinen Namensraum; sie sind total global. So ist es abscheulich um ihnen Kurznamen zu geben, die woanders verwendet werden könnten. Wenn Sie ein Makro mit einem kurzen Namen wie z untilund dann fügen Sie einen Header eines Drittanbieters ein, der eine Memberfunktion deklariert until, wird dieser Header beschädigt. Es wird versuchen zu erklären void until(int a); sondern wird stattdessen sagen void while(!(int a)); Viel Glück beim Entschlüsseln dieser Fehlermeldung! Und so verwendet Boost (wenig überraschend) gruselige Namen in Großbuchstaben mit Präfixen für all seine Makrotricks.
– Daniel Earwicker
11. November 2013 um 12:31 Uhr
Das erinnerte mich an etwas, das ich in jemandes Code gesehen habe:
#define R return;
Außerdem erhöhen Sie die Wartungskosten, indem Sie den Code schwer verständlich machen.
Ich schlage vor, es wäre besser, sie nicht zu verwenden.
Sie können sie nicht im Ruby-Stil verwenden
`printf("hello,world") unless(a>0);`
ist illegal.
Und für C-Programmierer wäre es schwieriger, den Code zu verstehen. In der Zwischenzeit könnte das zusätzliche Makro ein Problem sein.
Wenn Sie Makros definieren, ist es eine gute Praxis, sie wirklich hässlich aussehen zu lassen. Insbesondere sollten sie nur aus Großbuchstaben bestehen und eine Art Präfix haben. Dies liegt daran, dass es keine Namensräume und keine Koordination mit dem Typsystem oder der Überladungsauflösung von C++ gibt.
Also wenn dein Makro aufgerufen wurde BIGYAN_UNNECESSARY_MACRO_UNTIL dann wäre es nicht ganz “jenseits”.
Wenn Sie C++ mit neuen Schleifenkonstrukten erweitern möchten, sollten Sie Lambdas in C++0x untersuchen, wo Sie Folgendes zulassen könnten:
Es ist nicht perfekt, aber es ist besser als Makros.
Ihre vorgeschlagene Verwendung von Lambdas dafür wird mir heute Nacht Alpträume bereiten
– 6502
9. April 2011 um 19:39 Uhr
Ich bin in Konflikt geraten: Diese Verwendung von Lambdas ist gleichzeitig schrecklich und großartig. Ich mag es aber.
– James McNellis
9. April 2011 um 19:57 Uhr
Für etwas so Einfaches wie die Neuimplementierung while(!b) es ist eindeutig übertrieben.
– Daniel Earwicker
9. April 2011 um 20:01 Uhr
Es ist in der Tat schrecklich und großartig. Dies ist jedoch ganz normaler Code (und ziemlich sauber) in FP-Sprachen. Die Möglichkeit, eine eigene Kontrollstruktur zu definieren, ist sehr, sehr nützlich.
– ysdx
9. April 2011 um 23:45 Uhr
Ich denke nicht, dass Ihre Makros besonders schlecht sind, wenn sie nur in Ihrer eigenen Codebasis verwendet werden. Dieser Artikel
könnte für dich interessant sein. Davon abgesehen sehe ich einige Nachteile in Ihren Makros, wenn wir sie in C++ verwenden.
Zum Beispiel können wir nicht schreiben als:
until (T* p = f(x)) ...
unless (T* p = f(x)) ...
andererseits können wir schreiben als:
while (T* p = f(x)) ...
if (T* p = f(x)) ...
Wie für unlesswenn wir es definieren als:
#define unless(x) if (x) {} else
dann können wir schreiben unless (T* p = f(x)) .... In diesem Fall können wir jedoch nicht hinzufügen else Klausel danach.
Ihre vorgeschlagene Verwendung von Lambdas dafür wird mir heute Nacht Alpträume bereiten
– 6502
9. April 2011 um 19:39 Uhr
Ich bin in Konflikt geraten: Diese Verwendung von Lambdas ist gleichzeitig schrecklich und großartig. Ich mag es aber.
– James McNellis
9. April 2011 um 19:57 Uhr
Für etwas so Einfaches wie die Neuimplementierung while(!b) es ist eindeutig übertrieben.
– Daniel Earwicker
9. April 2011 um 20:01 Uhr
Es ist in der Tat schrecklich und großartig. Dies ist jedoch ganz normaler Code (und ziemlich sauber) in FP-Sprachen. Die Möglichkeit, eine eigene Kontrollstruktur zu definieren, ist sehr, sehr nützlich.
– ysdx
9. April 2011 um 23:45 Uhr
Thorsten
Gutes Beispiel für Syntaxzucker (IMHO):
struct Foo {
void bar() {}
};
typedef std::vector<Foo*> FooVector;
typedef boost::ptr_vector<Foo> FooPtrVector;
FooVector v1;
for (FooVector::iterator it = v1.begin(); it != v1.end(); ++it)
(*it)->bar(); // ugly
FooPtrVector v2;
for (FooPtrVector::iterator it = v2.begin(); it != v2.end(); ++it)
it->bar(); // nice
13841500cookie-checkSyntaktischer Zucker in C/C++yes
Es scheint, als hättest du es bereits getan.
– Thiago Cardoso
9. April 2011 um 19:26 Uhr
Obwohl diese auf den ersten Blick sehr schick aussehen, ist es angemessener, stattdessen Standard-C++ zu verwenden, auch wenn Sie nur für sich selbst programmieren. In der Teamarbeit ist das ein No-Go. Ihr Code wird ungewohnt aussehen. Ich erinnere mich an eine bestimmte
sugar.h
enthält Pascal-ähnliche Definitionen …– mbx
9. April 2011 um 19:27 Uhr
Ich glaube nicht, dass ich mag
unless
mit einemelse
-Klausel (ich liebe es jedoch, wenn/es sei denn beim Lispeln). Ich bin nicht wirklich beeindruckt von einemuntil
Schleife, kann aber daran liegen, dass ich sie noch nie zuvor benutzt habe.– 6502
9. April 2011 um 19:42 Uhr
Dieses Projekt könnte Sie interessieren: lolcode.com die auch etwas syntaktischen Zucker hinzufügen … 😀
– Invers
21. April 2011 um 20:57 Uhr
Wenn Sie dies tun müssen, ist mein einziger Vorschlag, zu buchstabieren
until
richtig.– Zach Rattner
22. April 2011 um 14:40 Uhr