Domanda

Sto chiedendo riguardo a C#, ma presumo che sia lo stesso nella maggior parte degli altri linguaggi.

Qualcuno ha una buona definizione di espressioni E dichiarazioni e quali sono le differenze?

È stato utile?

Soluzione

Espressione: Qualcosa che valuta un valore.Esempio: 1+2/x
Dichiarazione: Una riga di codice che fa qualcosa.Esempio: VAI A 100

Nei primi linguaggi di programmazione generici, come FORTRAN, la distinzione era cristallina.In FORTRAN, un'istruzione era un'unità di esecuzione, una cosa che facevi.L'unico motivo per cui non veniva chiamata "linea" era perché a volte si estendeva su più linee.Un'espressione da sola non potrebbe fare nulla...dovevi assegnarlo a una variabile.

1 + 2 / X

è un errore in FORTRAN, perché non fa nulla.Dovevi fare qualcosa con quell'espressione:

X = 1 + 2 / X

FORTRAN non aveva una grammatica come la conosciamo oggi: quell'idea fu inventata, insieme alla forma Backus-Naur (BNF), come parte della definizione di Algol-60.A quel punto il semantico è stata sancita la distinzione ("avere un valore" rispetto a "fare qualcosa"). sintassi:un tipo di frase era un'espressione, e un altro era un'affermazione, e il parser poteva distinguerli.

I progettisti dei linguaggi successivi hanno offuscato la distinzione:permettevano alle espressioni sintattiche di fare cose e permettevano affermazioni sintattiche che avevano valori.Il primo esempio di linguaggio popolare che sopravvive ancora è il C.I progettisti di C si sono resi conto che non veniva fatto alcun danno se ti era stato permesso di valutare un'espressione e buttare via il risultato.In C, ogni espressione sintattica può essere trasformata in un'istruzione semplicemente aggiungendo un punto e virgola alla fine:

1 + 2 / x;

è un’affermazione totalmente legittima anche se non accadrà assolutamente nulla.Allo stesso modo, in C, un'espressione può avere effetti collaterali- può cambiare qualcosa.

1 + 2 / callfunc(12);

Perché callfunc potrebbe semplicemente fare qualcosa di utile.

Una volta consentito a qualsiasi espressione di essere un'istruzione, potresti anche consentire l'operatore di assegnazione (=) all'interno delle espressioni.Ecco perché C ti permette di fare cose come

callfunc(x = 2);

Questo valuta l'espressione x = 2 (assegnando il valore di 2 a x) e poi passa quello (il 2) alla funzione callfunc.

Questa confusione di espressioni e istruzioni si verifica in tutti i derivati ​​C (C, C++, C# e Java), che hanno ancora alcune istruzioni (come while) ma che consentono di utilizzare quasi tutte le espressioni come istruzioni (in C# solo le espressioni di assegnazione, chiamata, incremento e decremento possono essere utilizzate come istruzioni);Vedere La risposta di Scott Wisniewski).

Avere due "categorie sintattiche" (che è il nome tecnico per il genere di cose che sono le affermazioni e le espressioni) può portare alla duplicazione degli sforzi.Ad esempio, il C ha due forme di condizionale, la forma di istruzione

if (E) S1; else S2;

e la forma espressiva

E ? E1 : E2

E a volte le persone Volere duplicazione che non c'è:Nello standard C, ad esempio, solo un'istruzione può dichiarare una nuova variabile locale, ma questa capacità è abbastanza utile che il compilatore GNU C fornisca un'estensione GNU che consente a un'espressione di dichiarare anche una variabile locale.

Ai progettisti di altri linguaggi non piaceva questo tipo di duplicazione, e si resero subito conto che se le espressioni possono avere effetti collaterali oltre ai valori, allora il sintattico la distinzione tra affermazioni ed espressioni non è poi così utile, quindi se ne sono sbarazzate.Haskell, Icon, Lisp e ML sono tutti linguaggi che non hanno istruzioni sintattiche: hanno solo espressioni.Anche i cicli strutturati in classi e le forme condizionali sono considerati espressioni e hanno valori, ma non molto interessanti.

Altri suggerimenti

Vorrei apportare una piccola correzione alla risposta di Joel sopra.

C# non consente l'utilizzo di tutte le espressioni come istruzioni.In particolare, solo le espressioni di assegnazione, chiamata, incremento e decremento possono essere utilizzate come istruzioni.

Ad esempio, il compilatore C# contrassegnerà il codice seguente come errore di sintassi:

1 + 2;

  • un'espressione è tutto ciò che produce un valore:2 + 2
  • un'istruzione è uno dei "blocchi" fondamentali dell'esecuzione del programma.

Tieni presente che in C, "=" è in realtà un operatore, che fa due cose:

  • restituisce il valore della sottoespressione della mano destra.
  • copia il valore della sottoespressione di destra nella variabile sul lato sinistro.

Ecco un estratto dalla grammatica ANSI C.Puoi vedere che il C non ha molti tipi diversi di istruzioni...la maggior parte delle istruzioni in un programma sono istruzioni di espressione, cioèun'espressione con un punto e virgola alla fine.

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

Un'espressione è qualcosa che restituisce un valore, mentre un'istruzione no.

Per esempio:

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

Il grosso problema tra i due è che puoi concatenare le espressioni, mentre le istruzioni non possono essere concatenate.

Puoi trovare questo su Wikipedia, ma le espressioni vengono valutate con un certo valore, mentre le istruzioni non hanno alcun valore valutato.

Pertanto, le espressioni possono essere utilizzate nelle istruzioni, ma non viceversa.

Nota che alcuni linguaggi (come Lisp, e credo Ruby, e molti altri) non differenziano affermazione ed espressione...in tali lingue tutto è un'espressione e può essere concatenato con altre espressioni.

Per una spiegazione delle importanti differenze nella componibilità (concatenabilità) di espressioni e affermazioni, il mio riferimento preferito è il documento del premio Turing di John Backus, È possibile liberare la programmazione dallo stile di von Neumann?.

I linguaggi imperativi (Fortran, C, Java, ...) enfatizzano le istruzioni per strutturare i programmi e hanno le espressioni come una sorta di ripensamento.I linguaggi funzionali enfatizzano le espressioni. Puramente i linguaggi funzionali hanno espressioni così potenti che le istruzioni possono essere eliminate del tutto.

Semplicemente:un'espressione restituisce un valore, un'istruzione no.

Le espressioni possono essere valutate per ottenere un valore, mentre le istruzioni non restituiscono un valore (sono di tipo vuoto).

Naturalmente anche le espressioni di chiamata di funzione possono essere considerate istruzioni, ma a meno che l'ambiente di esecuzione non abbia una variabile incorporata speciale per contenere il valore restituito, non c'è modo di recuperarlo.

I linguaggi orientati alle istruzioni richiedono che tutte le procedure siano un elenco di istruzioni.I linguaggi orientati alle espressioni, che probabilmente sono tutti i linguaggi funzionali, sono elenchi di espressioni o, nel caso di LISP, una lunga espressione S che rappresenta un elenco di espressioni.

Sebbene entrambi i tipi possano essere composti, la maggior parte delle espressioni può essere composta arbitrariamente purché i tipi corrispondano.Ogni tipo di affermazione ha il suo modo di comporre altre affermazioni, se possono farlo tutte.Le istruzioni foreach e if richiedono una singola affermazione o che tutte le istruzioni subordinate vadano in un blocco di istruzioni, una dopo l'altra, a meno che le sotto-proposizioni non consentano le proprie sotto-proposizioni.

Le istruzioni possono anche includere espressioni, laddove un'espressione in realtà non include alcuna istruzione.Un'eccezione, tuttavia, sarebbe un'espressione lambda, che rappresenta una funzione, e quindi può includere tutto ciò che una funzione può includere a meno che il linguaggio non consenta solo lambda limitati, come i lambda a espressione singola di Python.

In un linguaggio basato sulle espressioni, tutto ciò di cui hai bisogno è una singola espressione per una funzione poiché tutte le strutture di controllo restituiscono un valore (molte di esse restituiscono NIL).Non è necessaria un'istruzione return poiché l'ultima espressione valutata nella funzione è il valore restituito.

Alcune cose sui linguaggi basati sulle espressioni:


Più importante:Tutto restituisce un valore


Non c'è differenza tra parentesi graffe e parentesi graffe per delimitare blocchi di codice ed espressioni, poiché tutto è un'espressione.Ciò non impedisce tuttavia l'ambito lessicale:Ad esempio, è possibile definire una variabile locale per l'espressione in cui è contenuta la sua definizione e tutte le istruzioni contenute al suo interno.


In un linguaggio basato sulle espressioni, tutto restituisce un valore.All'inizio può essere un po' strano: cosa fa? (FOR i = 1 TO 10 DO (print i)) ritorno?

Alcuni semplici esempi:

  • (1) ritorna 1
  • (1 + 1) ritorna 2
  • (1 == 1) ritorna TRUE
  • (1 == 2) ritorna FALSE
  • (IF 1 == 1 THEN 10 ELSE 5) ritorna 10
  • (IF 1 == 2 THEN 10 ELSE 5) ritorna 5

Un paio di esempi più complessi:

  • Alcune cose, come alcune chiamate di funzione, non hanno realmente un valore significativo da restituire (cose che producono solo effetti collaterali?).Chiamando OpenADoor(), FlushTheToilet() O TwiddleYourThumbs() restituirà una sorta di valore banale, come OK, Fatto o Successo.
  • Quando più espressioni non collegate vengono valutate all'interno di un'espressione più grande, il valore dell'ultimo elemento valutato nell'espressione grande diventa il valore dell'espressione grande.Per prendere l'esempio di (FOR i = 1 TO 10 DO (print i)), il valore del ciclo for è "10", causa l' (print i) espressione da valutare 10 volte, restituendo ogni volta i come stringa.L'ultima volta attraverso i resi 10, la nostra risposta finale

Spesso è necessario un leggero cambio di mentalità per ottenere il massimo da un linguaggio basato sulle espressioni, poiché il fatto che tutto sia un'espressione rende possibile "inline" molte cose

Per fare un rapido esempio:

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

è un sostituto perfettamente valido per il non basato sull'espressione

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

In alcuni casi, il layout consentito dal codice basato sulle espressioni mi sembra molto più naturale

Naturalmente, questo può portare alla follia.Nell'ambito di un progetto hobbistico in un linguaggio di scripting basato su espressioni chiamato MaxScript, sono riuscito a inventare questa linea mostruosa

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
)

Una dichiarazione è un caso speciale di espressione, uno con void tipo.La tendenza delle lingue a trattare le affermazioni in modo diverso spesso causa problemi, e sarebbe meglio se fossero adeguatamente generalizzate.

Ad esempio, in C# abbiamo l'utility Func<T1, T2, T3, TResult> insieme sovraccarico di delegati generici.Ma dobbiamo anche avere un corrispondente Action<T1, T2, T3> impostato, e la programmazione di ordine superiore per scopi generali deve essere costantemente duplicata per affrontare questa sfortunata biforcazione.

Esempio banale: una funzione che controlla se un riferimento è nullo prima di chiamare un'altra funzione:

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

Il compilatore potrebbe gestire la possibilità di TResult essendo void?SÌ.Tutto quello che deve fare è richiedere che return sia seguito da un'espressione di tipo void.Il risultato di default(void) sarebbe di tipo void, e la funzione da passare dovrebbe essere nel formato Func<TValue, void> (che sarebbe equivalente a Action<TValue>).

Numerose altre risposte implicano che non è possibile concatenare istruzioni come si può fare con le espressioni, ma non sono sicuro da dove provenga questa idea.Possiamo pensare a ; che appare dopo le istruzioni come operatore infisso binario, accettando due espressioni di tipo void e combinandoli in un'unica espressione di tipo void.

Dichiarazioni -> Istruzioni da seguire in sequenza
Espressioni -> Valutazione che restituisce un valore

Le istruzioni sono fondamentalmente come passi, o istruzioni in un algoritmo, il risultato dell'esecuzione di un'istruzione è l'attualizzazione del puntatore dell'istruzione (cosiddetto in assembler)

Le espressioni non implicano un ordine di esecuzione a prima vista, il loro scopo è valutare e restituire un valore.Nei linguaggi di programmazione imperativi la valutazione di un'espressione ha un ordine, ma è proprio a causa del modello imperativo, ma non è la loro essenza.

Esempi di dichiarazioni:

for
goto
return
if

(tutti implicano l'avanzamento della riga (dichiarazione) di esecuzione su un'altra riga)

Esempio di espressioni:

2+2

(non implica l'idea dell'esecuzione, ma della valutazione)

Le affermazioni sono frasi grammaticalmente complete.Le espressioni no.Per esempio

x = 5

Si legge come "X ottiene 5." Questa è una frase completa.Il codice

(x + 5)/9.0

recita: "X più 5 tutti divisi per 9.0." Questa non è una frase completa.La dichiarazione

while k < 10: 
    print k
    k += 1

è una frase completa.Si noti che l'intestazione del ciclo non lo è;"mentre k < 10" è una clausola subordinata.

Dichiarazione,

Un'istruzione è un elemento procedurale da cui vengono costruiti tutti i programmi C#.Un'istruzione può dichiarare una variabile o costante locale, chiamare un metodo, creare un oggetto o assegnare un valore a una variabile, proprietà o campo.

Una serie di istruzioni racchiuse tra parentesi graffe forma un blocco di codice.Il corpo di un metodo è un esempio di blocco di codice.

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

Le istruzioni in C# spesso contengono espressioni.Un'espressione in C# è un frammento di codice contenente un valore letterale, un nome semplice o un operatore e i relativi operandi.

Espressione,

Un'espressione è un frammento di codice che può essere valutato in un singolo valore, oggetto, metodo o spazio dei nomi.I due tipi più semplici di espressioni sono i letterali e i nomi semplici.Un letterale è un valore costante che non ha nome.

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

Sia i che s sono nomi semplici che identificano variabili locali.Quando tali variabili vengono utilizzate in un'espressione, il valore della variabile viene recuperato e utilizzato per l'espressione.

Preferisco il significato di statement nel senso logico formale del termine.È uno che cambia lo stato di una o più variabili nel calcolo, consentendo di fare un'affermazione vera o falsa sui loro valori.

Immagino che ci sarà sempre confusione nel mondo informatico e nella scienza in generale quando vengono introdotte nuove terminologie o parole, quando le parole esistenti vengono "riproposte" o gli utenti ignorano la terminologia esistente, consolidata o "corretta" per ciò che stanno descrivendo

Non sono davvero soddisfatto di nessuna delle risposte qui.Ho guardato la grammatica per C++ (ISO2008).Ma forse ai fini didattici e di programmazione le risposte potrebbero essere sufficienti per distinguere i due elementi (la realtà però sembra più complicata).

Un'affermazione è composta da zero o più espressioni, ma può anche essere costituita da altri concetti linguistici.Questa è la forma estesa di Backus Naur per la grammatica (estratto per la frase):

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

Possiamo vedere gli altri concetti che sono considerati istruzioni in C++.

  • espressione-affermaziones si spiega da sé (un'istruzione può consistere di zero o Di più espressioni, leggi attentamente la grammatica, è complicato)
  • case per esempio è a istruzione-etichettata
  • dichiarazione-di-selezionelo sono if if/else, case
  • istruzione-iterazionelo sono while, do...while, for (...)
  • salto-istruzionelo sono break, continue, return (può restituire un'espressione), goto
  • dichiarazione-dichiarazione è l'insieme delle dichiarazioni
  • prova-blocco è una dichiarazione che rappresenta try/catch blocchi
  • e potrebbero essercene altri nella grammatica

Questo è un estratto che mostra la parte delle espressioni:

expression:
        assignment-expression
        expression "," assignment-expression
assignment-expression:
        conditional-expression
        logical-or-expression assignment-operator initializer-clause
        throw-expression
  • le espressioni sono o contengono spesso assegnazioni
  • espressione condizionale (sembra fuorviante) si riferisce all'utilizzo degli operatori (+, -, *, /, &, |, &&, ||, ...)
  • espressione di lancio - eh?IL throw anche la clausola è un'espressione

Ecco il riassunto di una delle risposte più semplici che ho trovato.

originariamente risposto da Anders Kaseorg

Un'istruzione è una riga completa di codice che esegue alcune azioni, mentre un'espressione è qualsiasi sezione del codice che restituisce un valore.

Le espressioni possono essere combinate "orizzontalmente" in espressioni più grandi utilizzando gli operatori, mentre le istruzioni possono essere combinate solo "verticalmente" scrivendo una dopo l'altra o con costrutti a blocchi.

Ogni espressione può essere utilizzata come un'istruzione (il cui effetto è valutare l'espressione e ignorare il valore risultante), ma la maggior parte delle istruzioni non può essere utilizzata come espressioni.

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

Per migliorare e convalidare la mia risposta precedente, le definizioni dei termini del linguaggio di programmazione dovrebbero essere spiegate dalla teoria dei tipi informatici, quando applicabile.

Un'espressione ha un tipo diverso dal tipo Bottom, ad es.ha un valore.Un'istruzione ha il tipo Unit o Bottom.

Da ciò ne consegue che un'istruzione può avere qualsiasi effetto in un programma solo quando crea un effetto collaterale, perché non può restituire un valore o restituisce solo il valore del tipo Unit che non è assegnabile (in alcuni linguaggi come sindrome coronarica acuta void) o (come in Scala) possono essere memorizzati per una valutazione ritardata della dichiarazione.

Ovviamente a @pragma o a /*comment*/ non hanno tipo e quindi sono differenziati dalle istruzioni.Pertanto l'unico tipo di dichiarazione che non avrebbe effetti collaterali sarebbe una non operazione.La mancata operazione è utile solo come segnaposto per futuri effetti collaterali.Qualsiasi altra azione dovuta a una dichiarazione sarebbe un effetto collaterale.Ancora una volta un suggerimento del compilatore, ad es. @pragma, non è un'istruzione perché non ha tipo.

Più precisamente, una dichiarazione deve avere a "effetto collaterale" (cioè. essere imperativo) e un'espressione must Avere UN valore tipo (cioènon il tipo inferiore).

IL tipo di dichiarazione è il tipo di unità, ma a causa del teorema di Halting l'unità è finzione, quindi diciamo che tipo inferiore.


Void non è esattamente il tipo inferiore (non è il sottotipo di tutti i tipi possibili).Esiste nelle lingue that non hanno un sistema di tipo completamente valido.Potrebbe sembrare un'affermazione snob, ma è completa come le annotazioni di varianza sono fondamentali per scrivere software estensibile.

Vediamo cosa ha da dire Wikipedia a riguardo.

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

Nella programmazione informatica un'istruzione è il più piccolo elemento autonomo di un imperativo linguaggio di programmazione che esprime qualche azione da effettuare.

Molte lingue (es.C) fare una distinzione tra istruzioni e definizioni, con un'istruzione che contiene solo codice eseguibile e una definizione che dichiara un identificatore, mentre un'espressione valuta solo un valore.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top