Expression versus déclaration

Je demande ce qui concerne c #, mais je suppose que c’est la même chose dans la plupart des autres langues.

Quelqu’un at-il une bonne définition des expressions et des déclarations et quelles sont les différences?

Expression: Quelque chose qui évalue une valeur. Exemple: 1 + 2 / x
Statement: une ligne de code qui fait quelque chose. Exemple: GOTO 100

Dans les premiers langages de programmation polyvalents, comme FORTRAN, la distinction était claire. Dans FORTRAN, une déclaration était une unité d’exécution, une chose que vous avez faite. La seule raison pour laquelle on ne l’appelait pas «ligne», c’est parce qu’elle couvrait parfois plusieurs lignes. Une expression seule ne pouvait rien faire … il fallait l’assigner à une variable.

1 + 2 / X

est une erreur dans FORTRAN, car il ne fait rien. Vous deviez faire quelque chose avec cette expression:

X = 1 + 2 / X

FORTRAN n’avait pas de grammaire telle que nous la connaissons aujourd’hui – cette idée a été inventée avec la forme Backus-Naur (BNF) dans le cadre de la définition d’Algol-60. À ce stade, la distinction sémantique (“avoir une valeur” versus “faire quelque chose”) était inscrite dans la syntaxe : un type de phrase était une expression, un autre était une déclaration et l’parsingur pouvait les distinguer.

Les concepteurs de langages ultérieurs ont brouillé la distinction: ils autorisaient les expressions syntaxiques à faire des choses, et ils autorisaient les énoncés syntaxiques comportant des valeurs. Le premier exemple de langage populaire qui survit encore est C. Les concepteurs de C ont réalisé qu’aucun mal n’était fait si vous étiez autorisé à évaluer une expression et à rejeter le résultat. En C, chaque expression syntaxique peut être transformée en une phrase simplement en pointant un point-virgule le long de la fin:

1 + 2 / x;

est une déclaration tout à fait légitime même si absolument rien ne se passera. De même, en C, une expression peut avoir des effets secondaires – cela peut changer quelque chose.

1 + 2 / callfunc(12);

parce que callfunc pourrait simplement faire quelque chose d’utile.

Une fois que vous autorisez une expression à être une instruction, vous pouvez également autoriser l’opérateur d’assignation (=) à l’intérieur des expressions. C’est pourquoi C vous permet de faire des choses comme

callfunc(x = 2);

Cela évalue l’expression x = 2 (en atsortingbuant la valeur 2 à x), puis transmet cela (le 2) à la fonction callfunc .

Ce flou d’expressions et d’instructions se produit dans tous les dérivés C (C, C ++, C # et Java), qui ont toujours des instructions (comme while ) mais qui permettent d’utiliser presque toutes les expressions (en assignation C # seulement) , les expressions call, increment et decrement peuvent être utilisées comme instructions, voir la réponse de Scott Wisniewski ).

Avoir deux “catégories syntaxiques” (qui est le nom technique du genre de chose que sont les déclarations et les expressions) peut entraîner une duplication des efforts. Par exemple, C a deux formes de conditionnel, le formulaire de déclaration

 if (E) S1; else S2; 

et la forme d’expression

 E ? E1 : E2 

Et parfois les gens veulent une duplication qui n’existe pas: dans la norme C, par exemple, seule une déclaration peut déclarer une nouvelle variable locale, mais cette capacité est assez utile pour que le compilateur GNU C fournisse une extension GNU permettant à une expression de déclarer une variable locale également.

Les concepteurs d’autres langages n’aimaient pas ce type de duplication, et ils ont rapidement compris que si les expressions peuvent avoir des effets secondaires aussi bien que des valeurs, la distinction syntaxique entre les déclarations et les expressions n’est pas très utile. . Haskell, Icon, Lisp et ML sont tous des langages qui n’ont pas d’énoncés syntaxiques – ils n’ont que des expressions. Même les formes en boucle et conditionnelles structurées en classes sont considérées comme des expressions, et elles ont des valeurs, mais pas très intéressantes.

J’aimerais apporter une petite correction à la réponse de Joel ci-dessus.

C # n’autorise pas l’utilisation de toutes les expressions comme instructions. En particulier, seules les expressions d’affectation, d’appel, d’incrément et de décrémentation peuvent être utilisées comme instructions.

Par exemple, le compilateur C # signalera le code suivant comme une erreur de syntaxe:

1 + 2;

  • une expression est tout ce qui donne une valeur: 2 + 2
  • une déclaration est l’un des “blocs” de base de l’exécution du programme.

Notez que dans C, “=” est en fait un opérateur, qui fait deux choses:

  • renvoie la valeur de la sous-expression de droite.
  • copie la valeur de la sous-expression de droite dans la variable du côté gauche.

Voici un extrait de la grammaire ANSI C. Vous pouvez voir que C n’a pas beaucoup de types d’instructions différentes … la majorité des instructions d’un programme sont des déclarations d’expression, c’est-à-dire une expression avec un point-virgule à la fin.

 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

Une expression est quelque chose qui renvoie une valeur, contrairement à une déclaration.

Pour des exemples:

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

Le Big Deal entre les deux est que vous pouvez enchaîner les expressions, alors que les déclarations ne peuvent pas être enchaînées.

Vous pouvez le trouver sur Wikipedia , mais les expressions sont évaluées à une certaine valeur, tandis que les instructions n’ont aucune valeur évaluée.

Ainsi, les expressions peuvent être utilisées dans les instructions, mais pas l’inverse.

Notez que certains langages (tels que Lisp, et je crois Ruby, et beaucoup d’autres) ne font pas de distinction entre expression et expression … dans ces langages, tout est une expression et peut être enchaîné avec d’autres expressions.

Pour une explication des différences importantes dans la composition (chaînes) des expressions par rapport aux énoncés, ma référence préférée est le prix Turing de John Backus. Peut-on libérer la programmation du style von Neumann? .

Les langages impératifs (Fortran, C, Java, …) mettent l’accent sur les instructions pour structurer les programmes et ont des expressions comme une sorte d’après-pensée. Les langages fonctionnels mettent l’accent sur les expressions. Les langages purement fonctionnels ont des expressions si puissantes que les énoncés peuvent être éliminés.

Simplement: une expression évalue une valeur, pas une déclaration.

Les expressions peuvent être évaluées pour obtenir une valeur, tandis que les instructions ne renvoient pas de valeur (elles sont de type void ).

Les expressions d’appel de fonction peuvent également être considérées comme des instructions bien sûr, mais à moins que l’environnement d’exécution ne dispose d’une variable intégrée spéciale pour contenir la valeur renvoyée, il n’y a aucun moyen de le récupérer.

Les langages orientés sur les instructions exigent que toutes les procédures soient une liste d’instructions. Les langages orientés expression, qui sont probablement tous les langages fonctionnels, sont des listes d’expressions ou, dans le cas de LISP, une expression S longue qui représente une liste d’expressions.

Bien que les deux types puissent être composés, la plupart des expressions peuvent être composées arbitrairement tant que les types correspondent. Chaque type de déclaration a sa propre façon de composer d’autres instructions, si elles peuvent le faire toutes. Les instructions foreach et if requièrent soit une seule instruction, soit toutes les instructions subordonnées dans un bloc d’instructions, les unes après les autres, à moins que les sous-systèmes ne permettent leurs propres sous-instructions.

Les instructions peuvent également inclure des expressions, où une expression n’inclut pas vraiment d’instructions. Une exception, cependant, serait une expression lambda, qui représente une fonction, et peut donc inclure tout ce qu’une fonction peut contenir à moins que le langage ne permette que des lambdas limités, comme les lambdas à expression unique de Python.

Dans un langage basé sur une expression, tout ce dont vous avez besoin est une expression unique pour une fonction, car toutes les structures de contrôle renvoient une valeur (beaucoup retournent NIL). Il n’y a pas besoin d’une déclaration de retour car la dernière expression évaluée dans la fonction est la valeur de retour.

Quelques choses sur les langages basés sur l’expression:


Le plus important: tout retourne une valeur


Il n’y a pas de différence entre les accolades et les accolades pour délimiter les blocs de code et les expressions, puisque tout est une expression. Cela n’empêche pas la scope lexicale: une variable locale peut être définie pour l’expression dans laquelle se trouve sa définition et toutes les instructions qu’elle contient, par exemple.


Dans un langage basé sur une expression, tout renvoie une valeur. Cela peut être un peu étrange au début – Qu’est-ce que (FOR i = 1 TO 10 DO (print i)) retourne?

Quelques exemples simples:

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

Quelques exemples plus complexes:

  • Certaines choses, comme certains appels de fonctions, n’ont pas vraiment de valeur significative à renvoyer (choses qui ne produisent que des effets secondaires?). Appeler OpenADoor(), FlushTheToilet() ou TwiddleYourThumbs() renverra une sorte de valeur banale, telle que OK, Terminé ou Succès.
  • Lorsque plusieurs expressions non liées sont évaluées dans une expression plus grande, la valeur de la dernière chose évaluée dans la grande expression devient la valeur de la grande expression. Pour prendre l’exemple de (FOR i = 1 TO 10 DO (print i)) , la valeur de la boucle for est “10”, elle provoque l’évaluation de l’expression (print i) 10 fois, renvoyant chaque fois i en tant que chaîne. La dernière fois que les retours sont 10 , notre réponse finale

Cela nécessite souvent un léger changement d’état d’esprit pour tirer le meilleur parti d’un langage basé sur une expression, car le fait que tout soit une expression permet de «incorporer» beaucoup de choses.

Comme exemple rapide:

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

est un remplacement parfaitement valide pour le non basé sur l’expression

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

Dans certains cas, la disposition qu’autorise le code basé sur l’expression me semble beaucoup plus naturelle

Bien sûr, cela peut mener à la folie. Dans le cadre d’un projet de loisir dans un langage de script basé sur l’expression appelé MaxScript, j’ai réussi à créer cette ligne de monstre.

 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 ) 

Une instruction est un cas particulier d’une expression, une avec un type void . La tendance des langues à traiter les déclarations différemment pose souvent des problèmes et il serait préférable qu’elles soient généralisées.

Par exemple, en C #, nous avons le très utile ensemble de delegates génériques Func . Mais nous devons également définir une Action , et la programmation générale d’ordre supérieur doit constamment être dupliquée pour faire face à cette malheureuse bifurcation.

Exemple sortingvial – une fonction qui vérifie si une référence est nulle avant d’appeler une autre fonction:

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

Le compilateur pourrait-il gérer la possibilité que TResult soit void ? Oui. Tout ce qu’il a à faire est d’exiger que return soit suivi par une expression de type void . Le résultat default(void) serait de type void , et le func transmis devrait être de la forme Func (ce qui équivaudrait à Action ).

Un certain nombre d’autres réponses impliquent que vous ne pouvez pas enchaîner des déclarations comme vous pouvez le faire avec des expressions, mais je ne suis pas sûr de l’origine de cette idée. Nous pouvons penser à la ; qui apparaît après les instructions en tant qu’opérateur infix binary, en prenant deux expressions de type void et en les combinant en une seule expression de type void .

Déclarations -> Instructions à suivre séquentiellement
Expressions -> Evaluation qui renvoie une valeur

Les instructions sont fondamentalement comme des étapes ou des instructions dans un algorithme, le résultat de l’exécution d’une instruction est l’actualisation du pointeur d’instruction (appelé assembleur).

Les expressions n’impliquent pas et l’ordre d’exécution à première vue, leur but est d’évaluer et de renvoyer une valeur. Dans les langages de programmation impératifs, l’évaluation d’une expression a un ordre, mais c’est simplement à cause du modèle impératif, mais ce n’est pas leur essence.

Exemples de déclarations:

 for goto return if 

(tous impliquent l’avancement de la ligne d’exécution de l’instruction sur une autre ligne)

Exemple d’expressions:

 2+2 

(cela n’implique pas l’idée de l’exécution, mais de l’évaluation)

Les déclarations sont des phrases grammaticalement complètes. Les expressions ne sont pas. Par exemple

 x = 5 

se lit comme “x obtient 5.” Ceci est une phrase complète. Le code

 (x + 5)/9.0 

lit, “x plus 5 tous divisés par 9.0.” Ce n’est pas une phrase complète. La déclaration

 while k < 10: print k k += 1 

est une phrase complète. Notez que l'en-tête de la boucle n'est pas; "while k <10" est une clause subordonnée.

Déclaration ,

Une instruction est un bloc de construction procédural à partir duquel tous les programmes C # sont construits. Une instruction peut déclarer une variable ou une constante locale, appeler une méthode, créer un object ou affecter une valeur à une variable, une propriété ou un champ.

Une série d’instructions entourées d’accolades forment un bloc de code. Un corps de méthode est un exemple de bloc de code.

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

Les instructions en C # contiennent souvent des expressions. Une expression en C # est un fragment de code contenant une valeur littérale, un nom simple ou un opérateur et ses opérandes.

Expression ,

Une expression est un fragment de code pouvant être évalué en une seule valeur, object, méthode ou espace de noms. Les deux types d’expressions les plus simples sont les littéraux et les noms simples. Un littéral est une valeur constante sans nom.

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

Les deux i et s sont des noms simples identifiant les variables locales. Lorsque ces variables sont utilisées dans une expression, la valeur de la variable est extraite et utilisée pour l’expression.

Je préfère le sens de l’ statement au sens logique formel du mot. C’est celui qui modifie l’état d’une ou plusieurs des variables du calcul, permettant de faire une déclaration vraie ou fausse sur leurs valeurs.

Je suppose qu’il y aura toujours de la confusion dans le monde de l’informatique et de la science en général lorsque de nouveaux termes ou termes sont utilisés, que les mots existants sont «réutilisés» ou que les utilisateurs ignorent la terminologie existante ou établie.

Je ne suis pas vraiment satisfait des réponses ici. J’ai regardé la grammaire pour C ++ (ISO 2008) . Cependant, pour des raisons de didactique et de programmation, les réponses pourraient suffire à distinguer les deux éléments (la réalité semble plus compliquée).

Une instruction se compose de zéro ou plusieurs expressions, mais peut également être d’autres concepts de langage. Ceci est la forme étendue de Backus Naur pour la grammaire (extrait de la déclaration):

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

Nous pouvons voir les autres concepts considérés comme des instructions en C ++.

  • expression-expression s s'explique d'elle-même (une instruction peut être composée de zéro ou de plusieurs expressions, lisez attentivement la grammaire, c'est délicat)
  • case par exemple est une déclaration étiquetée
  • déclaration de sélection s if if/else , case
  • iteration-statement s sont while , do...while , for (...)
  • les instructions de saut sont des sauts , continue , return (peuvent renvoyer une expression), goto
  • déclaration-déclaration est l'ensemble des déclarations
  • try-block est une déclaration représentant try/catch blocs try/catch
  • et il pourrait y avoir un peu plus bas dans la grammaire

Ceci est un extrait montrant la partie des expressions:

 expression: assignment-expression expression "," assignment-expression assignment-expression: conditional-expression logical-or-expression assignment-operator initializer-clause throw-expression 
  • les expressions sont ou contiennent souvent des affectations
  • expression conditionnelle (sonne trompeur) fait référence à l'utilisation des opérateurs ( + , - , * , / , & , | , && , || , ...)
  • expression-lancer - euh? la clause throw est une expression aussi

Voici le résumé de l’une des réponses les plus simples que j’ai trouvées.

Répondu à l’origine par Anders Kaseorg

Une instruction est une ligne complète de code qui effectue une action, tandis qu’une expression est une section du code qui donne une valeur.

Les expressions peuvent être combinées «horizontalement» dans des expressions plus grandes à l’aide d’opérateurs, tandis que les instructions ne peuvent être combinées que «verticalement» en écrivant les unes après les autres ou avec des constructions de blocs.

Chaque expression peut être utilisée comme une instruction (dont l’effet est d’évaluer l’expression et d’ignorer la valeur résultante), mais la plupart des instructions ne peuvent pas être utilisées comme expressions.

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

Pour améliorer et valider ma réponse précédente, les définitions des termes du langage de programmation doivent être expliquées par la théorie de type informatique si applicable.

Une expression a un type autre que le type Bottom, c’est-à-dire qu’elle a une valeur. Une déclaration a le type Unit ou Bottom.

De ce fait, une instruction ne peut avoir d’effet dans un programme que si elle crée un effet secondaire, car elle ne peut pas renvoyer une valeur ou elle ne renvoie que la valeur du type d’unité non atsortingbuable (dans certaines langues, par exemple). un void de C) ou (comme dans Scala) peut être stocké pour une évaluation différée de la déclaration.

De toute évidence, un @pragma ou un /*comment*/ n’a pas de type et se distingue donc des instructions. Ainsi, le seul type de déclaration qui n’aurait aucun effet secondaire serait une non-opération. La non-opération n’est utile que pour les effets secondaires futurs. Toute autre action due à une déclaration serait un effet secondaire. Encore une fois, un indice de compilation, par exemple @pragma , n’est pas une déclaration car il n’a pas de type.

Plus précisément, une déclaration doit avoir un “effet secondaire” (c’est- à- dire être impératif ) et une expression doit avoir un type de valeur (c’est-à-dire pas le type inférieur).

Le type d’une déclaration est le type d’unité, mais en raison de la mise en halte du théorème, l’unité est la fiction, alors disons le type inférieur .


Void n’est pas précisément le type inférieur (ce n’est pas le sous-type de tous les types possibles). Il existe dans des langues qui ne disposent pas d’un système de type complètement sonore . Cela peut sembler être une déclaration de snobisme, mais la complétude telle que les annotations de variance est essentielle pour écrire un logiciel extensible.

Voyons ce que Wikipedia a à dire à ce sujet.

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

En programmation informatique, un énoncé est le plus petit élément autonome d’un langage de programmation impératif qui exprime certaines actions à effectuer.

De nombreux langages (par exemple, C) font une distinction entre les déclarations et les définitions, une déclaration ne contenant que du code exécutable et une définition déclarant un identifiant, tandis qu’une expression ne donne qu’une valeur.