Frage

Ich frage nach c#, aber ich gehe davon aus, dass es in den meisten anderen Sprachen dasselbe ist.

Hat jemand eine gute Definition von Ausdrücke Und Aussagen und was sind die Unterschiede?

War es hilfreich?

Lösung

Ausdruck: Etwas, das einen Wert ergibt.Beispiel: 1+2/x
Stellungnahme: Eine Codezeile, die etwas bewirkt.Beispiel: GOTO 100

In den frühesten Allzweck-Programmiersprachen wie FORTRAN war der Unterschied glasklar.In FORTRAN war eine Anweisung eine Ausführungseinheit, eine Sache, die Sie getan haben.Der einzige Grund, warum es nicht als „Linie“ bezeichnet wurde, war, dass es sich manchmal über mehrere Zeilen erstreckte.Ein Ausdruck allein könnte nichts bewirken ...Sie mussten es einer Variablen zuweisen.

1 + 2 / X

ist ein Fehler in FORTRAN, weil es nichts bewirkt.Mit diesem Ausdruck musste man etwas anfangen:

X = 1 + 2 / X

FORTRAN hatte keine Grammatik, wie wir sie heute kennen – diese Idee wurde zusammen mit der Backus-Naur-Form (BNF) als Teil der Definition von Algol-60 erfunden.Zu diesem Zeitpunkt semantisch Die Unterscheidung („einen Wert haben“ versus „etwas tun“) wurde darin verankert Syntax:Eine Art Phrase war ein Ausdruck und eine andere eine Aussage, und der Parser konnte sie unterscheiden.

Designer späterer Sprachen haben die Unterscheidung verwischt:Sie erlaubten syntaktischen Ausdrücken, Dinge zu tun, und sie erlaubten syntaktischen Anweisungen, die Werte hatten.Das früheste noch erhaltene populäre Sprachbeispiel ist C.Die Designer von C erkannten, dass es keinen Schaden anrichtete, wenn man einen Ausdruck auswerten und das Ergebnis verwerfen durfte.In C kann jeder syntaktische Ausdruck in eine Anweisung umgewandelt werden, indem einfach am Ende ein Semikolon angehängt wird:

1 + 2 / x;

ist eine absolut legitime Aussage, auch wenn absolut nichts passieren wird.Ebenso kann in C ein Ausdruck haben Nebenwirkungen– es kann etwas verändern.

1 + 2 / callfunc(12);

Weil callfunc könnte einfach etwas Nützliches bewirken.

Sobald Sie zulassen, dass ein Ausdruck eine Anweisung ist, können Sie auch den Zuweisungsoperator (=) innerhalb von Ausdrücken zulassen.Deshalb können Sie mit C Dinge tun wie

callfunc(x = 2);

Dies wertet den Ausdruck x = 2 aus (weist x den Wert 2 zu) und übergibt diesen (die 2) dann an die Funktion callfunc.

Diese Verwischung von Ausdrücken und Anweisungen tritt in allen C-Derivaten (C, C++, C# und Java) auf, die noch einige Anweisungen haben (wie while), die aber die Verwendung fast aller Ausdrücke als Anweisung ermöglichen (in C# dürfen nur Zuweisungs-, Aufruf-, Inkrementierungs- und Dekrementierungsausdrücke als Anweisungen verwendet werden;sehen Scott Wisniewskis Antwort).

Das Vorhandensein zweier „syntaktischer Kategorien“ (das ist die technische Bezeichnung für die Art von Aussagen und Ausdrücken) kann zu Doppelarbeit führen.Beispielsweise gibt es in C zwei Formen der Bedingung: die Anweisungsform

if (E) S1; else S2;

und die Ausdrucksform

E ? E1 : E2

Und manchmal auch Menschen wollen Vervielfältigung, die nicht vorhanden ist:In Standard C kann beispielsweise nur eine Anweisung eine neue lokale Variable deklarieren - aber diese Fähigkeit ist nützlich genug, dass der GNU C -Compiler eine GNU -Erweiterung bietet, die es einem Ausdruck ermöglicht, auch eine lokale Variable zu deklarieren.

Designer anderer Sprachen mochten diese Art der Duplizierung nicht und erkannten schon früh, dass, wenn Ausdrücke neben Werten auch Nebenwirkungen haben können, dann die syntaktisch Die Unterscheidung zwischen Aussagen und Ausdrücken ist nicht besonders nützlich – also haben sie sie abgeschafft.Haskell, Icon, Lisp und ML sind alles Sprachen, die keine syntaktischen Anweisungen haben – sie haben nur Ausdrücke.Sogar die klassenstrukturierten Schleifen und bedingten Formen gelten als Ausdrücke und haben Werte – aber keine sehr interessanten.

Andere Tipps

Ich möchte eine kleine Korrektur an Joels Antwort oben vornehmen.

C# erlaubt nicht die Verwendung aller Ausdrücke als Anweisungen.Als Anweisungen dürfen insbesondere nur Zuweisungs-, Aufruf-, Inkrementierungs- und Dekrementierungsausdrücke verwendet werden.

Beispielsweise markiert der C#-Compiler den folgenden Code als Syntaxfehler:

1 + 2;

  • Ein Ausdruck ist alles, was einen Wert liefert:2 + 2
  • Eine Anweisung ist einer der grundlegenden „Blöcke“ der Programmausführung.

Beachten Sie, dass „=" in C eigentlich ein Operator ist, der zwei Dinge bewirkt:

  • gibt den Wert des rechten Unterausdrucks zurück.
  • kopiert den Wert des rechten Unterausdrucks in die Variable auf der linken Seite.

Hier ist ein Auszug aus der ANSI-C-Grammatik.Sie können sehen, dass C nicht viele verschiedene Arten von Anweisungen hat ...Die meisten Anweisungen in einem Programm sind Ausdrucksanweisungen, d. h.ein Ausdruck mit einem Semikolon am Ende.

statement
    : labeled_statement
    | compound_statement
    | expression_statement
    | selection_statement
    | iteration_statement
    | jump_statement
    ;

expression_statement
    : ';'
    | expression ';'
    ;

http://www.lysator.liu.se/c/ANSI-C-grammar-y.html

Ein Ausdruck ist etwas, das einen Wert zurückgibt, eine Anweisung hingegen nicht.

Zum Beispiel:

1 + 2 * 4 * foo.bar()     //Expression
foo.voidFunc(1);          //Statement

Der große Unterschied zwischen beiden besteht darin, dass Ausdrücke miteinander verkettet werden können, während Anweisungen nicht verkettet werden können.

Dies finden Sie hier Wikipedia, aber Ausdrücke werden auf einen bestimmten Wert ausgewertet, während Anweisungen keinen ausgewerteten Wert haben.

Daher können Ausdrücke in Anweisungen verwendet werden, nicht jedoch umgekehrt.

Beachten Sie, dass einige Sprachen (wie Lisp und ich glaube Ruby und viele andere) keine Unterscheidung zwischen Anweisung und Ausdruck machen ...In solchen Sprachen ist alles ein Ausdruck und kann mit anderen Ausdrücken verkettet werden.

Für eine Erklärung wichtiger Unterschiede in der Zusammensetzbarkeit (Verkettbarkeit) von Ausdrücken und Aussagen ist meine Lieblingsreferenz John Backus‘ Turing-Award-Artikel. Kann die Programmierung vom von Neumann-Stil befreit werden?.

Imperative Sprachen (Fortran, C, Java, ...) betonen Anweisungen zur Strukturierung von Programmen und haben Ausdrücke als eine Art nachträglichen Gedanken.Funktionale Sprachen betonen Ausdrücke. Rein Funktionale Sprachen haben so mächtige Ausdrücke, dass Aussagen vollständig eliminiert werden können.

Einfach:Ein Ausdruck ergibt einen Wert, eine Anweisung jedoch nicht.

Ausdrücke können ausgewertet werden, um einen Wert zu erhalten, wohingegen Anweisungen keinen Wert zurückgeben (sie sind vom Typ Leere).

Funktionsaufrufausdrücke können natürlich auch als Anweisungen betrachtet werden, aber es gibt keine Möglichkeit, ihn abzurufen, es sei denn, die Ausführungsumgebung verfügt über eine spezielle integrierte Variable, die den zurückgegebenen Wert speichert.

Aussageorientierte Sprachen erfordern, dass alle Prozeduren eine Liste von Anweisungen sind.Ausdrucksorientierte Sprachen, bei denen es sich wahrscheinlich um alle funktionalen Sprachen handelt, sind Listen von Ausdrücken oder im Fall von LISP ein langer S-Ausdruck, der eine Liste von Ausdrücken darstellt.

Obwohl beide Typen zusammengesetzt werden können, können die meisten Ausdrücke beliebig zusammengesetzt werden, solange die Typen übereinstimmen.Jeder Anweisungstyp hat seine eigene Art, andere Anweisungen zu verfassen, sofern sie das alles können.Foreach- und if-Anweisungen erfordern entweder eine einzelne Anweisung oder dass alle untergeordneten Anweisungen nacheinander in einem Anweisungsblock stehen, es sei denn, die Unteranweisungen erlauben ihre eigenen Unteranweisungen.

Anweisungen können auch Ausdrücke enthalten, wobei ein Ausdruck eigentlich keine Anweisungen enthält.Eine Ausnahme wäre jedoch ein Lambda-Ausdruck, der eine Funktion darstellt und daher alles enthalten kann, was eine Funktion enthalten kann, es sei denn, die Sprache erlaubt nur begrenzte Lambdas, wie Pythons Einzelausdruck-Lambdas.

In einer ausdrucksbasierten Sprache benötigen Sie lediglich einen einzelnen Ausdruck für eine Funktion, da alle Kontrollstrukturen einen Wert zurückgeben (viele von ihnen geben NIL zurück).Es ist keine Return-Anweisung erforderlich, da der zuletzt ausgewertete Ausdruck in der Funktion der Rückgabewert ist.

Einige Dinge über ausdrucksbasierte Sprachen:


Am wichtigsten:Alles gibt einen Wert zurück


Es gibt keinen Unterschied zwischen geschweiften Klammern und geschweiften Klammern zur Begrenzung von Codeblöcken und Ausdrücken, da alles ein Ausdruck ist.Dies verhindert jedoch nicht die lexikalische Festlegung des Gültigkeitsbereichs:Eine lokale Variable könnte beispielsweise für den Ausdruck definiert werden, in dem ihre Definition enthalten ist, und für alle darin enthaltenen Anweisungen.


In einer ausdrucksbasierten Sprache gibt alles einen Wert zurück.Das kann zunächst etwas seltsam sein – Was bedeutet (FOR i = 1 TO 10 DO (print i)) zurückkehren?

Einige einfache Beispiele:

  • (1) kehrt zurück 1
  • (1 + 1) kehrt zurück 2
  • (1 == 1) kehrt zurück TRUE
  • (1 == 2) kehrt zurück FALSE
  • (IF 1 == 1 THEN 10 ELSE 5) kehrt zurück 10
  • (IF 1 == 2 THEN 10 ELSE 5) kehrt zurück 5

Ein paar komplexere Beispiele:

  • Manche Dinge, wie zum Beispiel einige Funktionsaufrufe, haben keinen wirklich sinnvollen Rückgabewert (Dinge, die nur Nebenwirkungen erzeugen?).Berufung OpenADoor(), FlushTheToilet() oder TwiddleYourThumbs() wird einen alltäglichen Wert zurückgeben, z. B. „OK“, „Fertig“ oder „Erfolgreich“.
  • Wenn mehrere nicht verknüpfte Ausdrücke innerhalb eines größeren Ausdrucks ausgewertet werden, wird der Wert des zuletzt im großen Ausdruck ausgewerteten Elements zum Wert des großen Ausdrucks.Um das Beispiel zu nehmen (FOR i = 1 TO 10 DO (print i)), der Wert der for-Schleife ist „10“, es verursacht das (print i) Ausdruck, der zehnmal ausgewertet werden soll und jedes Mal i als Zeichenfolge zurückgibt.Das letzte Mal durch Retouren 10, unsere letzte Antwort

Um das Beste aus einer ausdrucksbasierten Sprache herauszuholen, ist oft eine leichte Änderung der Denkweise erforderlich, da die Tatsache, dass alles ein Ausdruck ist, es ermöglicht, viele Dinge „inline“ zu machen

Als kurzes Beispiel:

 FOR i = 1 to (IF MyString == "Hello, World!" THEN 10 ELSE 5) DO
 (
    LotsOfCode
 )

ist ein vollkommen gültiger Ersatz für das, was nicht ausdrucksbasiert ist

IF MyString == "Hello, World!" THEN TempVar = 10 ELSE TempVar = 5 
FOR i = 1 TO TempVar DO
(    
    LotsOfCode  
)

In manchen Fällen fühlt sich das Layout, das ausdrucksbasierter Code ermöglicht, für mich viel natürlicher an

Das kann natürlich zum Wahnsinn führen.Im Rahmen eines Hobbyprojekts in einer ausdrucksbasierten Skriptsprache namens MaxScript ist es mir gelungen, diese Monsterzeile zu entwickeln

IF FindSectionStart "rigidifiers" != 0 THEN FOR i = 1 TO (local rigidifier_array = (FOR i = (local NodeStart = FindsectionStart "rigidifiers" + 1) TO (FindSectionEnd(NodeStart) - 1) collect full_array[i])).count DO
(
    LotsOfCode
)

Eine Anweisung ist ein Sonderfall eines Ausdrucks, eins mit void Typ.Die Tendenz von Sprachen, Aussagen unterschiedlich zu behandeln, verursacht oft Probleme, und es wäre besser, wenn sie richtig verallgemeinert würden.

In C# haben wir zum Beispiel das sehr nützliche Func<T1, T2, T3, TResult> überladener Satz generischer Delegaten.Aber wir müssen auch eine entsprechende haben Action<T1, T2, T3> festgelegt, und allgemeine Programmierung höherer Ordnung muss ständig dupliziert werden, um diese unglückliche Zweiteilung zu bewältigen.

Triviales Beispiel – eine Funktion, die prüft, ob eine Referenz null ist, bevor sie eine andere Funktion aufruft:

TResult IfNotNull<TValue, TResult>(TValue value, Func<TValue, TResult> func)
                  where TValue : class
{
    return (value == null) ? default(TValue) : func(value);
}

Könnte der Compiler mit der Möglichkeit umgehen? TResult Sein void?Ja.Es muss lediglich verlangt werden, dass auf „return“ ein Ausdruck vom Typ folgt void.Das Ergebnis von default(void) wäre vom Typ void, und die übergebene Funktion müsste die Form haben Func<TValue, void> (was äquivalent wäre zu Action<TValue>).

Eine Reihe anderer Antworten implizieren, dass Sie Anweisungen nicht wie mit Ausdrücken verketten können, aber ich bin mir nicht sicher, woher diese Idee kommt.Wir können uns das vorstellen ; das nach Anweisungen als binärer Infix-Operator erscheint und zwei Ausdrücke des Typs annimmt void und sie zu einem einzigen Ausdruck des Typs zu kombinieren void.

Anweisungen -> Anweisungen, die der Reihe nach befolgt werden müssen
Ausdrücke -> Auswertung, die einen Wert zurückgibt

Anweisungen ähneln im Grunde Schritten oder Anweisungen in einem Algorithmus. Das Ergebnis der Ausführung einer Anweisung ist die Aktualisierung des Anweisungszeigers (in Assembler so genannt).

Ausdrücke implizieren nicht auf den ersten Blick eine Ausführungsreihenfolge, ihr Zweck besteht darin, einen Wert auszuwerten und zurückzugeben.In den imperativen Programmiersprachen hat die Auswertung eines Ausdrucks eine Reihenfolge, die jedoch nur auf das imperative Modell zurückzuführen ist, aber nicht deren Wesen ist.

Beispiele für Aussagen:

for
goto
return
if

(alles impliziert das Vorrücken der Ausführungszeile (Anweisung) in eine andere Zeile)

Beispiel für Ausdrücke:

2+2

(Dabei geht es nicht um die Idee der Ausführung, sondern um die Bewertung)

Aussagen sind grammatikalisch vollständige Sätze.Ausdrücke sind es nicht.Zum Beispiel

x = 5

liest als "x bekommt 5." Dies ist ein vollständiger Satz.Der Code

(x + 5)/9.0

Laut "X Plus 5 sind alle durch 9.0 geteilt." Dies ist kein vollständiger Satz.Die Aussage

while k < 10: 
    print k
    k += 1

ist ein vollständiger Satz.Beachten Sie, dass der Schleifenheader nicht vorhanden ist.„while k < 10“ ist ein Nebensatz.

Stellungnahme,

Eine Anweisung ist ein prozeduraler Baustein, aus dem alle C#-Programme aufgebaut sind.Eine Anweisung kann eine lokale Variable oder Konstante deklarieren, eine Methode aufrufen, ein Objekt erstellen oder einer Variablen, Eigenschaft oder einem Feld einen Wert zuweisen.

Eine Reihe von Anweisungen, die von geschweiften Klammern umgeben sind, bilden einen Codeblock.Ein Methodenkörper ist ein Beispiel für einen Codeblock.

bool IsPositive(int number)
{
    if (number > 0)
    {
        return true;
    }
    else
    {
        return false;
    }
}

Anweisungen in C# enthalten häufig Ausdrücke.Ein Ausdruck in C# ist ein Codefragment, das einen Literalwert, einen einfachen Namen oder einen Operator und seine Operanden enthält.

Ausdruck,

Ein Ausdruck ist ein Codefragment, das zu einem einzelnen Wert, Objekt, einer einzelnen Methode oder einem Namensraum ausgewertet werden kann.Die beiden einfachsten Arten von Ausdrücken sind Literale und einfache Namen.Ein Literal ist ein konstanter Wert, der keinen Namen hat.

int i = 5;
string s = "Hello World";

Sowohl i als auch s sind einfache Namen, die lokale Variablen identifizieren.Wenn diese Variablen in einem Ausdruck verwendet werden, wird der Wert der Variablen abgerufen und für den Ausdruck verwendet.

Ich bevorzuge die Bedeutung von statement im formallogischen Sinne des Wortes.Dabei handelt es sich um eine Variable, die den Zustand einer oder mehrerer Variablen in der Berechnung ändert und so eine wahre oder falsche Aussage über deren Wert(e) ermöglicht.

Ich vermute, dass es in der Computerwelt und in der Wissenschaft im Allgemeinen immer Verwirrung geben wird, wenn neue Terminologien oder Wörter eingeführt werden, bestehende Wörter „umgewidmet“ werden oder Benutzer die bestehende, etablierte oder „richtige“ Terminologie für das, was sie beschreiben, nicht kennen

Ich bin mit keiner der Antworten hier wirklich zufrieden.Ich habe mir die Grammatik angesehen C++ (ISO 2008).Aus didaktischen und programmtechnischen Gründen könnten die Antworten jedoch ausreichen, um die beiden Elemente zu unterscheiden (die Realität sieht jedoch komplizierter aus).

Eine Aussage besteht aus null oder mehreren Ausdrücken, kann aber auch aus anderen Sprachkonzepten bestehen.Dies ist die erweiterte Backus-Naur-Form für die Grammatik (Auszug für die Aussage):

statement:
        labeled-statement
        expression-statement <-- can be zero or more expressions
        compound-statement
        selection-statement
        iteration-statement
        jump-statement
        declaration-statement
        try-block

Wir können die anderen Konzepte sehen, die in C++ als Anweisungen gelten.

  • Ausdrucksaussages ist selbsterklärend (eine Aussage kann aus Null oder bestehen mehr Ausdrücke, lesen Sie die Grammatik sorgfältig, es ist schwierig)
  • case ist zum Beispiel ein beschriftete Aussage
  • Auswahl-Anweisungs sind if if/else, case
  • Iteration-Anweisungs sind while, do...while, for (...)
  • Sprunganweisungs sind break, continue, return (kann Ausdruck zurückgeben), goto
  • Deklarationsanweisung ist die Menge der Deklarationen
  • Try-Block ist eine Aussage, die Folgendes darstellt try/catch Blöcke
  • und es könnte noch etwas mehr in der Grammatik sein

Dies ist ein Auszug, der den Ausdrucksteil zeigt:

expression:
        assignment-expression
        expression "," assignment-expression
assignment-expression:
        conditional-expression
        logical-or-expression assignment-operator initializer-clause
        throw-expression
  • Ausdrücke sind oder enthalten häufig Zuweisungen
  • bedingter Ausdruck (klingt irreführend) bezieht sich auf die Verwendung der Operatoren (+, -, *, /, &, |, &&, ||, ...)
  • Wurfausdruck - äh?Die throw Die Klausel ist ebenfalls ein Ausdruck

Hier ist die Zusammenfassung einer der einfachsten Antworten, die ich gefunden habe.

Ursprünglich beantwortet von Anders Kaseorg

Eine Anweisung ist eine vollständige Codezeile, die eine Aktion ausführt, während ein Ausdruck ein beliebiger Abschnitt des Codes ist, der einen Wert ergibt.

Ausdrücke lassen sich „horizontal“ über Operatoren zu größeren Ausdrücken zusammenfassen, während Anweisungen „vertikal“ nur durch nacheinander Schreiben oder mit Blockkonstrukten verknüpft werden können.

Jeder Ausdruck kann als Anweisung verwendet werden (deren Wirkung darin besteht, den Ausdruck auszuwerten und den resultierenden Wert zu ignorieren), aber die meisten Anweisungen können nicht als Ausdrücke verwendet werden.

http://www.quora.com/Python-programming-sprache-1/Whats-the-difference-between-a-statement-and-an-expression-in-Python

Um meine vorherige Antwort zu verbessern und zu validieren, sollten Definitionen von Programmiersprachenbegriffen gegebenenfalls anhand der Typentheorie der Informatik erläutert werden.

Ein Ausdruck hat einen anderen Typ als den Bottom-Typ, d. h.es hat einen Wert.Eine Anweisung hat den Typ Unit oder Bottom.

Daraus folgt, dass eine Anweisung nur dann eine Wirkung in einem Programm haben kann, wenn sie einen Nebeneffekt erzeugt, weil sie entweder keinen Wert zurückgeben kann oder nur den Wert des Unit-Typs zurückgibt, der entweder nicht zuweisbar ist (in einigen Sprachen wie z ein C void) oder (z. B. in Scala) für eine verzögerte Auswertung der Anweisung gespeichert werden.

Offensichtlich ein @pragma oder ein /*comment*/ haben keinen Typ und unterscheiden sich daher von Aussagen.Daher wäre die einzige Art von Anweisung, die keine Nebenwirkungen hätte, eine Nichtoperation.Eine Nichtoperation ist nur als Platzhalter für zukünftige Nebenwirkungen sinnvoll.Jede andere Aktion aufgrund einer Aussage wäre eine Nebenwirkung.Wieder ein Compiler-Hinweis, z.B. @pragma, ist keine Anweisung, da sie keinen Typ hat.

Genauer gesagt muss eine Aussage eine haben "Nebenwirkung" (d. h. unbedingt erforderlich sein) und ein Ausdruck muss haben A Wert Typ (d. h.nicht der unterste Typ).

Der Art einer Aussage ist der Einheitentyp, aber aufgrund des Halting-Theorems ist die Einheit eine Fiktion, also sagen wir die Bodentyp.


Void ist nicht genau der unterste Typ (es ist nicht der Untertyp aller möglichen Typen).Es existiert in Sprachen, die Ich habe kein völlig solides System.Das mag wie eine snobistische Aussage klingen, ist aber vollständig wie etwa Varianzanmerkungen sind entscheidend für das Schreiben erweiterbarer Software.

Mal sehen, was Wikipedia zu diesem Thema zu sagen hat.

https://en.wikipedia.org/wiki/Statement_(computer_science)

In der Computerprogrammierung ist eine Anweisung das kleinste eigenständige Element einer Imperativ Programmiersprache, die ausdrückt etwas Action ausgetragen werden.

Viele Sprachen (z.B.C) zwischen Anweisungen und Definitionen unterscheiden, wobei eine Anweisung nur ausführbaren Code enthält und eine Definition einen Bezeichner deklariert, während ein Ausdruck nur einen Wert ergibt.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top