Warum erfordern Sprachen Klammern um Ausdrücke, wenn sie mit "if" und "while" verwendet werden?


67

Sprachen wie C, Java und C ++ erfordern alle Klammern um den gesamten Ausdruck , wenn sie in einem verwendet if, whileoder switch.

if (true) {
    // Do something
}

im Gegensatz zu

if true {
    // Do something
}

Das kommt mir merkwürdig vor, weil die Klammern überflüssig sind. In diesem Beispiel trueist es ein einzelner Ausdruck für sich. Die Klammer ändert ihre Bedeutung in keiner mir bekannten Weise. Warum gibt es diese ungewöhnliche Syntax und warum ist sie so verbreitet? Gibt es einen Vorteil, den ich nicht kenne?


20
Pascal benötigt keine Klammern (weil es a benötigt THEN).
JimmyB

30
Python, Ruby nicht.
smci

31
Ich glaube, C verwendet Klammern, weil die Klammern für einen Text mit einer Anweisung optional sind. Oder besser gesagt, die geschweiften Klammern sind nicht Teil der ifAnweisung, sondern erstellen nur eine zusammengesetzte Anweisung.
Fred Larson

7
Interessanterweise erfordert Go Klammern, aber keine Klammern.
Kos

25
Die Frage ist ein bisschen tautologisch. Warum sind runde Kanaldeckel rundum? Warum sind alle Brüder männlich? Warum benötigen alle Sprachen, die Eltern brauchen, Eltern? Runde Kanaldeckel sind per Definition rund; Brüder sind per Definition männlich; Sprachen, die parens erfordern, erfordern per definitionem parens.
Eric Lippert

Antworten:


155

Es muss sein , einige Möglichkeit zu sagen , wo der Zustand endet und der Zweig beginnt. Dafür gibt es viele verschiedene Möglichkeiten.

In einigen Sprachen gibt es kein conditionals überhaupt , zB in Smalltalk, Selbst, Neusprech, Io, Ioke, Seph und Fancy. Die bedingte Verzweigung wird einfach wie jede andere Methode als normale Methode implementiert. Die Methode wird auf Booleschen Objekten implementiert und auf einem Booleschen Objekt aufgerufen. Auf diese Weise ist die Bedingung einfach der Empfänger der Methode, und die beiden Zweige sind zwei Argumente, z. B. in Smalltalk:

aBooleanExpression ifTrue: [23] ifFalse: [42].

Falls Sie mit Java besser vertraut sind, entspricht dies dem Folgenden:

aBooleanExpression.ifThenElse(() -> 23, () -> 42);

In der Lisp-Sprachfamilie ist die Situation ähnlich: Bedingungen sind nur normale Funktionen (eigentlich Makros) und das erste Argument ist die Bedingung, das zweite und dritte Argument sind die Zweige, also sind sie nur normale Funktionsargumente, und es gibt sie es ist nichts Besonderes erforderlich, um sie abzugrenzen:

(if aBooleanExpression 23 42)

Einige Sprachen verwenden Schlüsselwörter als Begrenzer, z. B. Algol, Ada, BASIC, Pascal, Modula-2, Oberon, Oberon-2, Active Oberon, Komponente Pascal, Zonnon, Modula-3:

IF aBooleanExpression THEN RETURN 23 ELSE RETURN 42;

In Ruby können Sie entweder ein Schlüsselwort oder ein Ausdruckstrennzeichen (Semikolon oder Zeilenvorschub) verwenden:

if a_boolean_expression then 23 else 42 end

if a_boolean_expression; 23 else 42 end

# non-idiomatic, the minimum amount of whitespace required syntactically
if a_boolean_expression
23 else 42 end

# idiomatic, although only the first newline is required syntactically
if a_boolean_expression
  23
else
  42
end

Go setzt voraus, dass die Zweige Blöcke sind, und lässt keine Ausdrücke oder Anweisungen zu, weshalb geschweifte Klammern obligatorisch sind. Daher sind keine Klammern erforderlich, obwohl Sie sie hinzufügen können, wenn Sie möchten. Perl6 und Rust sind in dieser Hinsicht ähnlich:

if aBooleanExpression { return 23 } else { return 42 }

Einige Sprachen verwenden andere nicht alphanumerische Zeichen, um die Bedingung abzugrenzen, z. B. Python:

if aBooleanExpression: return 23
else: return 42

Die Quintessenz lautet: Sie müssen in irgendeiner Weise feststellen, wo die Bedingung endet und der Zweig beginnt. Es gibt viele Möglichkeiten, Klammern sind nur eine davon.


8
Sehr gute Übersicht.
Peter - Reinstate Monica

2
Natürlich in einer Sprache, in der entweder bloße Ausdrücke keine Anweisung sind (z. B. in einer älteren BASIC-Sprache, in der ein berechneter Wert entweder einer Variablen zugewiesen oder einer anderen Anweisung übergeben werden muss) oder in der es keine Präfixoperatoren gibt, die Sie immer können sollten ohnehin das Ende eines Ausdrucks und den Beginn einer Anweisung zu identifizieren. Ich konnte definitiv eine BASIC-Variante sehen, die am Ende einer IF-Anweisung ohne Begrenzer auskommt.
Periata Breatta

4
Da C in den 70er Jahren entwickelt wurde und die Berechnung teuer war, würde das Hinzufügen einer kleinen Klammer wahrscheinlich das Schreiben des Parsers ein wenig erleichtern.
Machado

4
Re: Lisp: "eigentlich Makros". In der Praxis ist IF eine Sonderform in Schema und CL (nur der Vollständigkeit halber).
Coredump

1
@Leushenko: Und zB in MISC, das standardmäßig faul ist, sind alle bedingten Formen nur normale Funktionen, weder Makros noch Sonderformen. (In der Tat, AFAIR, MISC hat keine Sonderformen?)
Jörg W Mittag

70

Die Klammern sind nur dann nicht erforderlich, wenn Sie geschweifte Klammern verwenden.

if true ++ x;

Zum Beispiel wird ohne sie mehrdeutig.


28
@RobertHarvey - Die Klammern werden von so ziemlich jeder Sprache benötigt, die ich kenne. Mit Sicherheit C und seine Verwandten. Die OP ist zu fragen , warum sie sind erforderlich - und es ist , weil die Sprache sonst mehrdeutig werden würde.
Telastyn

25
Gerade aus dem Kopf, Klammern sind nicht erforderlich für if: Basic, Assembly, Python, Bash / Zsh, Tcl, Batch, Brainfuck oder Maschinencode. Fehlende Klammern machen nur dann ifmehrdeutig, wenn die Sprache so gestaltet wurde, dass sie von ihnen abhängt.
candied_orange

12
Ich bin erstaunt, dass niemand die logischste und lesbarste Version erwähnt hat - in Pascal (inkl. Delphi) if Condition then ....
Ulrich Gerhardt

18
Go ist ein gutes Beispiel für das Gegenteil. Es macht Klammern {}obligatorisch und erfordert daher keine Parens um den Ausdruck. Nicht nur, dass keine Parens erforderlich sind, sondern wenn ich mich erinnere, dass das Hinzufügen von Parens einen Kompilierungsfehler verursachen würde - sie sind verboten
slebetman

10
@Eiko Lass mich umformulieren. Das Beispiel in der Antwort ist syntaktisch mehrdeutig, obwohl es semantisch eindeutig ist (wie Sie bemerkt haben). Da die Parsing-Phase jedoch vor der semantischen Analyse stattfindet, wird der Parser auf die Mehrdeutigkeit stoßen - und muss entweder eine uninformierte Vermutung anstellen oder fehlschlagen. Wenn der Parser (aus irgendeinem Grund) festlegt, dass er nicht scheitern soll, arbeitet der Semantic Analyzer mit dem resultierenden Baum. Ich habe noch keinen Compiler gesehen, in dem der Semantikanalysator den Parser auffordert, den Teilbaum neu zu analysieren und eine andere Wahl für das syntaktisch mehrdeutige Konstrukt zu treffen.
Theodoros Chatzigiannakis

21

Klammern in einer ifAnweisung haben nicht die gleiche Bedeutung wie Klammern, die in einem arithmetischen Ausdruck verwendet werden. Klammern in einem arithmetischen Ausdruck werden zum Gruppieren von Ausdrücken verwendet. Klammern in einer ifAnweisung werden verwendet, um den Booleschen Ausdruck abzugrenzen. das heißt, den booleschen Ausdruck vom Rest der ifAnweisung zu unterscheiden.

In einer ifAnweisung führen Klammern keine Gruppierungsfunktion aus (obwohl Sie in der ifAnweisung weiterhin Klammern verwenden können, um arithmetische Ausdrücke zu gruppieren. Der äußere Satz von Klammern dient dann zur Begrenzung des gesamten booleschen Ausdrucks). Das Erfordernis vereinfacht den Compiler, da sich der Compiler darauf verlassen kann, dass diese Klammern immer vorhanden sind.


Ich verstehe nicht, wie es den Compiler vereinfacht. Die Regel "IF" ("Ausdruck") "Anweisung" ist nicht einfacher als IF primary_expression statement. Beachten Sie, dass letzteres ebenso eindeutig ist.
user58697

@ user58697: Nein, nur letzteres weist die Mehrdeutigkeit auf, bei der ein Postfix-Operator primary_expressionnicht von einem Präfix-Operator in einer Ausdrucksanweisung unterschieden werden kann. So kopieren Sie Telastyn Antwort, if true ++ x;. Wenn leere Anweisungen vorhanden sind, if a & f;kann dies entweder eine leere Anweisung und eine binäre Anweisung &innerhalb der Bedingung oder eine unäre &Anweisung am Anfang der Anweisung sein. Wenn Sie jedoch Klammern verwenden, gibt es genau eine Übereinstimmung für die Eröffnung (
MSalters

@MSalters Ein Postfix-Operator wird nicht als primärer Operator analysiert. Ein primärer Ausdruck eines von IDENTIFIER, CONSTANT, STRING_LITERALund '(' expression ')'.
user58697

@ user58697: Sie scheinen eine bestimmte Sprache im Auge zu haben. Und es scheint eine Regel zu geben, dass Klammern nur dann nicht benötigt werden, wenn die Bedingungen "IDENTIFIER, CONSTANT oder STRING_LITERAL" sind. Ich bin mir nicht sicher, ob das die Sache einfacher macht.
MSalters

16

Wie andere bereits teilweise ausgeführt haben, liegt dies daran, dass Ausdrücke auch gültige Anweisungen sind und bei einem Block mit nur einer Anweisung geschweifte Klammern weggelassen werden können. Dies bedeutet, dass Folgendes nicht eindeutig ist:

if true
    +x;

Weil es so interpretiert werden könnte:

if (true + x) {}

Anstatt von:

if (true) {+x;}

In einer Reihe von Sprachen (z. B. Python) können Sie die Klammern umgehen, haben aber immer noch einen Endbedingungsmarker:

wenn ja : + x

Sie haben jedoch Recht, dass wir eine Sprache definieren könnten , in der die Klammern niemals erforderlich sind: Eine Sprache, in der ein Ausdruck keine gültige Aussage ist, wird dieses Problem nicht haben.

Leider bedeutet dies, dass Dinge wie:

 ++x;
 functionCall(1,2,3);

Es wären keine gültigen Anweisungen, daher müssten Sie eine seltsame Syntax einführen, um solche Aktionen ausführen zu können, ohne Ausdrücke zu erstellen. Eine einfache Möglichkeit, dies zu tun, besteht darin, dem Ausdruck einfach einen Marker voranzustellen, wie z [statement].

[statement] ++x;
[statement] functionCall(1,2,3);

Jetzt verschwindet die Zweideutigkeit, da Sie schreiben müssten:

if true
    [statement] ++x;

Aber wie Sie sehen, ist eine solche Sprache nicht weit verbreitet, da es viel besser ist, die Klammer um eine ifBedingung (oder ein :am Ende) zu setzen, als für jede Ausdrucksanweisung einen solchen Marker zu setzen.


Hinweis : Die Verwendung eines [statement]Markers ist nur die einfachste Syntax, die ich mir vorstellen kann. Sie könnten jedoch zwei völlig unterschiedliche Syntaxen für Ausdrücke und Anweisungen ohne Mehrdeutigkeit zwischen ihnen haben, für die ein solcher Marker nicht erforderlich wäre. Das Problem ist: Die Sprache wäre extrem seltsam, da Sie für die gleichen Aufgaben in einem Ausdruck oder einer Anweisung eine völlig andere Syntax verwenden müssten.

Eine Sache, die mir in den Sinn kommt, zwei getrennte Syntaxen ohne solch einen expliziten Marker zu haben, wäre zum Beispiel: Erzwinge Anweisungen, Unicode-Symbole zu verwenden (also anstatt foreine Unicode-Variation der Buchstaben zu verwenden f, ound r), während Ausdrücke zu sein Nur ASCII.


2
Es gibt tatsächlich eine Sprache, die einen solchen Ausdrucksanweisungsmarker verwendet: Wenn Sie einen Ausdruck auf seine Nebenwirkungen untersuchen möchten, müssen Sie discardseinen Wert in Nim explizit angeben . Dies geschieht jedoch nur aus Gründen der Typensicherheit und nicht aus syntaktischen Gründen.
amon

@amon Schön, das wusste ich nicht. Wie auch immer, wie gesagt, der Marker wird nicht wirklich benötigt, es ist nur ein einfacher Weg, um diese Unterscheidung zu erreichen, ohne unintuitive Syntaxen zu erfinden.
Bakuriu

1
@amon - Viele BASIC-Varianten haben auch eine strikte Trennung zwischen Ausdrücken und Anweisungen. Ausdrücke sind nur an Stellen zulässig, an denen der Wert tatsächlich verwendet wird (z. B. Variablenzuweisungen, Anweisungen wie PRINT, die eine Aktion ausführen usw.). Prozeduren, die nicht zum Berechnen eines Werts verwendet werden, werden durch ein Schlüsselwort aufgerufen (normalerweise "CALL", obwohl mindestens eine mir bekannte Variante "PROC" verwendet), dem der Name vorangestellt ist. Und so weiter. BASIC begrenzt normalerweise das Ende des Ausdrucks in einer IF-Anweisung mit "THEN", aber ich sehe keinen technischen Grund dafür, dass die Anforderung nicht gelöscht werden konnte.
Periata Breatta

1
Es gibt eine Sprache, die in den 80er Jahren sehr beliebt war und Blöcke ohne Parens, geschweifte Klammern, Doppelpunkte oder andere Markierungen enthält und Ausdrücke überall als Anweisungen akzeptiert. Einige Anweisungen verhalten sich wie Ausdrücke (zusammengesetzte Operatoren wie + = und ++). Es ist schlimm, dass es vor dem Compiler einen dummen Preprozessor gibt ( ?simbol ist in diesem Beispiel eine Funktion nach PP). Es gibt keine ;. Sicher, es braucht einen Marker für die Fortsetzung, aber davon wird abgeraten. harbour.github.io/doc/clc53.html#if-cmd . Der Compiler ist schnell und einfach (erstellt mit Bison / Flex).
Maniero

@bigown Sie erreichen , dass durch eine separate Syntax für logische Bedingungen verwenden, so grundsätzlich die Voraussetzungen für die if, whileecc begrenzt sind im Vergleich zu generischen Ausdrücke in anderen Sprachen verwendet. Klar: Wenn Sie mehr als zwei syntaktische Kategorien haben (wie Aussage, Ausdruck, logischer Ausdruck, Kaffeezubereitungsausdruck, ...), können Sie mit etwas Freiheit handeln.
Bakuriu

10

Es ist üblich, dass Sprachen der C-Familie diese Klammern benötigen, jedoch nicht universell.

Einer von Perl 6 ist stärker spürbar syntaktischen Änderungen ist , dass sie die Grammatik modifiziert , so dass Sie nicht die Klammern geben müssen if, forund ähnliche Bedingungen Aussagen. So etwas ist in Perl 6 absolut gültig:

if $x == 4 {
    ...
}

wie es ist

while $queue.pop {
    ...
}

Da es sich jedoch nur um Ausdrücke handelt, können Sie sie nach Belieben in Klammern setzen. In diesem Fall handelt es sich nur um gewöhnliche Gruppierungen anstelle eines erforderlichen Teils der Syntax wie in C, C #, Java usw.

Rust hat eine ähnliche Syntax wie Perl 6 in dieser Abteilung:

if x == 4 {
    ...
}

Mir scheint, dass ein Merkmal moderner C-inspirierter Sprachen darin besteht, sich solche Dinge anzuschauen und sich zu fragen, ob sie entfernt werden sollen.


Während Ihre Antwort einen Einblick in andere Sprachen bietet, antwortet sie nicht "Warum gibt es diese seltsame Syntax und warum ist sie so häufig?".

Du bist ganz richtig. Ich habe wirklich versucht, der Frage Kontext hinzuzufügen, was auf dieser Plattform nicht einfach ist. Letztendlich denke ich, wenn ich eine Antwort auf die Frage gebe, dann "nur, weil es keinen technischen Grund gibt, warum die Grammatik es nicht hätte ertragen können, sie nicht zu haben". Aber das ist keine sehr nützliche Antwort.
Matthew Walton

In Perl 5 gibt es beides. Für normale if Konstrukte oder Schleifenkonstrukte mit BLOCKs werden die Parens benötigt, z . B. in if ( $x == 4 ) { ... }oder foreach my $foo ( @bar ) { ... }. Wenn die Postfix-Notation verwendet wird, sind die Parens wie in return unless $foo;oder optional ++$x while s/foo/bar/g;.
Simbabque

6

Es gibt einen Aspekt, der mich überrascht, dass keine der vorhandenen Antworten zur Sprache gebracht hat.

C und viele C-Derivate und Look-Alikes haben die Besonderheit, dass der Wert einer Zuweisung der zugewiesene Wert ist. Dies hat zur Folge, dass eine Zuweisung dort verwendet werden kann, wo ein Wert erwartet wird.

Dies ermöglicht es Ihnen, Dinge wie zu schreiben

if (x = getValue() == 42) { ... }

oder

if (x == y = 47) { ... }

oder

unsigned int n = 0 /* given m == SOME_VALUE */;
while (n < m && *p1++ = *p2++) { n++; }

(was implizit so behandelt wird, while (n < m && *p1++ = *p2++ != 0) { n++; }weil C eine Abweichung von Null als wahr behandelt; ich denke übrigens, das ist nur ungefähr strncpy () in der C-Standardbibliothek)

oder auch

if (x = 17);

und es ist alles gültig. Nicht alle syntaktisch gültigen Kombinationen sind notwendigerweise nützlich (und moderne Compiler warnen speziell vor Zuweisungen innerhalb von Bedingungen, da es sich um einen häufigen Fehler handelt), aber ein Teil davon ist tatsächlich nützlich.

Das Parsen solcher Anweisungen wäre wahrscheinlich weitaus schwieriger, wenn nicht eindeutig festgestellt werden könnte, wo der bedingte Ausdruck beginnt und endet.

Klammern wurden bereits verwendet, um Funktionsnamen von Funktionsargumenten abzugrenzen. Ich denke, sie waren eine logische Wahl, um auch Schlüsselwörter von Schlüsselwortargumenten abzugrenzen.

Natürlich könnten alternative Syntaxen definiert werden, um dasselbe zu tun. Dies würde jedoch die Komplexität erhöhen, insbesondere im Parser, der sich dann mit zwei verschiedenen Syntaxsätzen für weitgehend dasselbe befassen müsste. Bereits bei der Entwicklung von C war die Rechenleistung (sowohl in Bezug auf die Fähigkeit zur Eingabe von Zahlen als auch auf den Arbeitsspeicher und die Speicherkapazität) äußerst begrenzt. Alles, was die Komplexität zu geringen oder keinen Kosten für die Lesbarkeit verringerte, war mit ziemlicher Sicherheit eine willkommene Änderung.

Die Verwendung von Klammern mag heute ein wenig archaisch erscheinen, aber wenn jemand mit der Sprache vertraut ist, beeinträchtigt dies nicht die Lesbarkeit im Vergleich zu einer anderen Syntax, die in der Lage ist, dieselben Dinge auszudrücken.


5

Der Grund ist meistens Geschichte.

Zum Zeitpunkt, als der erste C-Compiler geschrieben wurde, gab es auf Computern nur sehr wenige RAM-, CPU- und Compiler-Programme, die mit wenigen Tools „von Hand“ geschrieben wurden, um den Compiler-Autoren zu helfen. Daher war die Implementierung komplexer Regeln in einem Compiler kostspielig . C ++, C #, Java usw. sollten für C-Programmierer einfach zu erlernen sein, daher wurden keine „unnötigen“ Änderungen vorgenommen.

In "c like" -Sprachen if, while, etcerfordern conditionals ( ) keinen expliziten blockOff-Code. Sie können einfach eine einfache Anweisung verwenden.

if (a == d) doIt()

oder Sie können Anweisungen zu einer kombinieren, compound statementindem Sie sie mit in einfügen{}

Wir möchten, dass der Compiler Fehler findet, die wir machen, und eine Fehlermeldung ausgibt, die wir verstehen können.


3

Java und C ++ wurden beide entwickelt, nachdem C eine sehr beliebte Programmiersprache geworden war. Eine Überlegung bei der Gestaltung jeder dieser Sprachen war, dass sie C-Programmierer ansprechen und diese Programmierer auffordern würde, die neue Sprache zu verwenden. (Ich war einer der C-Programmierer, die sie erfolgreich umwarben.) C ++ wurde außerdem so entworfen, dass es (fast) mit C-Code austauschbar ist. Um angenommen ist viel von C diese Ziele, sowohl C ++ und Java zu unterstützen Syntax, einschließlich der Klammern um die Bedingungen if, whileund switchAussagen.

Daher ist der Grund, warum alle diese Sprachen Klammern um die Bedingungen dieser Anweisungen benötigen, der, dass C dies tut, und die Frage ist wirklich nur, warum C diese Klammern benötigt.

Die Ursprünge der C-Sprache werden in diesem Artikel von Dennis Ritchie beschrieben, einem der Hauptautoren seiner Entwicklung (einige könnten sogar den Hauptautor seiner Entwicklung nennen). Wie in diesem Artikel erwähnt, wurde C ursprünglich in den frühen 1970er Jahren als Systemprogrammiersprache für Computer mit extrem begrenztem Platz im Hauptspeicher entwickelt. Es war wünschenswert, eine Sprache zu haben, die über der Assemblersprache lag. Angesichts der zur Verfügung stehenden Ressourcen war jedoch auch die einfache Syntaxanalyse der Sprache wichtig. Das Erfordernis der Klammern würde es relativ einfach machen, den bedingten Code zu identifizieren.

Man könnte auch schließen, dass die Fähigkeit, Programme mit weniger Zeichen zu schreiben, als Vorteil angesehen wurde und zwei Klammern weniger Platz beanspruchen als das Schlüsselwort THEN, das zu dieser Zeit in FORTRAN und anderen Hochsprachen verwendet wurde. Tatsächlich if(a==b)waren vier ganze Zeichen kürzer als , da die Klammern auch Leerzeichen als Begrenzer von Symbolen ersetzen konnten IF a==b THEN.

In jedem Fall musste ein Gleichgewicht hergestellt werden zwischen der Fähigkeit des Menschen, in C geschriebene Programme zu lesen, zu schreiben und zu verstehen, der Fähigkeit eines Compilers, in C geschriebene Programme zu analysieren und zu kompilieren, und der Anzahl der Kilobyte (!). wäre sowohl für die Programmquelle als auch für den Compiler selbst erforderlich. Und in Klammern um die Bedingungen von if, whileund switch Aussagen stand, wie sich die Leute entschieden haben, dieses Gleichgewicht bei der Gestaltung von C. zu finden.

Wie aus mehreren anderen Antworten hervorgeht, wurden, nachdem Sie die besonderen Umstände, unter denen C entwickelt wurde, entfernt haben, alle Arten von alternativen Syntaxformen für die Bedingungen verschiedener Programmiersprachen verwendet. Die Klammern kommen also wirklich nur zu einer Entwurfsentscheidung, die von einigen wenigen Personen unter bestimmten Einschränkungen zu einem bestimmten Zeitpunkt in der Geschichte getroffen wurde.


Ich bin mir nicht sicher, ob C ++ so entworfen wurde, wie es war, "um diese Programmierer dazu zu bewegen, eine neue Sprache zu verwenden". Erinnerst du dich an C mit Klassen ?
ein CVn

@ MichaelKjörling Zugegeben, die Java-Entwickler äußerten sich viel deutlicher zum "Werben". Beachten Sie jedoch, dass der verlinkte Artikel als einen Grund, warum Stroustrup C als Grundlage seiner Sprache gewählt hat, angibt, dass C weit verbreitet ist. Eine Möglichkeit, um nahe an C zu bleiben, bestand darin, dass vorhandener Code leicht angepasst werden konnte (wie ich bereits sagte) - aber auch vorhandene Codierer konnten sich leicht anpassen.
David K

@ MichaelKjörling Ich nehme an, der ursprüngliche Wortlaut meiner Antwort deutete darauf hin, dass das "Werben" ein größerer Faktor bei der Sprachgestaltung war, als es tatsächlich war. Ich habe die Antwort bearbeitet, um zu verdeutlichen, dass es nur eine Sache war, die in das Sprachdesign einging.
David K

3

Viele begründen hier, dass ohne die Klammern die Syntax mehrdeutig wäre und implizieren stillschweigend, dass dies irgendwie schlimm oder gar eine unmögliche Situation wäre.

Tatsächlich haben Sprachen viele Möglichkeiten, mit Mehrdeutigkeiten umzugehen. Die Operatorrangfolge ist nur eine Instanz dieses Themas.

Nein, Mehrdeutigkeit ist nicht der Grund für die Klammern. Ich denke, man könnte einfach eine Version von C erstellen, bei der die Klammern um die Bedingung nicht erforderlich sind (so dass sie optional sind) und bei der in allen Fällen immer noch gültiger Code erstellt wird. Das Beispiel von if a ++ b;könnte als äquivalent zu if (a) ++b;oder interpretiert werden if (a++) b;, was angemessener erscheint.

Die Frage, warum Dennis Ritchie das () zur Pflicht gemacht hat (und dieses Meme daher für viele abgeleitete Sprachen prägt), ist eher sprachlich. Ich denke, der Gedanke, klar zu sagen, dass der Zustand eher ein Ausdruck als ein Befehl ist, war der Vater des Gedankens.

Tatsächlich wurde C so konzipiert, dass es mit einem One-Pass-Parser analysiert werden kann. Die Verwendung einer Syntax mit obligatorischen Klammern um die Bedingung unterstützt diesen Aspekt.


Ich sehe eine Ablehnung meiner Antwort. Erkläre bitte in einem Kommentar, was dir nicht gefallen hat. Vielleicht kann ich es dann verbessern.
Alfe

0

Klammern um ifBedingungen sind in Fortran, Cobol, PL / 1, Algol, Algo-68, Pascal, Modula, XPL, PL / M, MPL usw. oder einer anderen Sprache mit einem thenSchlüsselwort nicht erforderlich . thendient zur Abgrenzung conditiondes Folgenden statement.

Die schließende Klammer in C usw. funktioniert als then, und die öffnende ist formal überflüssig.

Die obigen Ausführungen gelten für traditionell geparste Sprachen.


Fortran tut Klammern in allen Versionen seiner IF, einschließlich struktureller Natur erfordern.
Netch
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.