Question

Je pose la question concernant C#, mais je suppose que c'est la même chose dans la plupart des autres langages.

Quelqu'un a-t-il une bonne définition de expressions et déclarations et quelles sont les différences ?

Était-ce utile?

La solution

Expression: Quelque chose qui s'évalue à une valeur.Exemple: 1+2/x
Déclaration: Une ligne de code qui fait quelque chose.Exemple: ALLER À 100

Dans les premiers langages de programmation à usage général, comme FORTRAN, la distinction était claire.En FORTRAN, une instruction était une unité d'exécution, une chose que vous faisiez.La seule raison pour laquelle on ne l'appelait pas « ligne » était parce qu'elle s'étendait parfois sur plusieurs lignes.Une expression à elle seule ne peut rien faire...il fallait l'attribuer à une variable.

1 + 2 / X

est une erreur en FORTRAN, car il ne fait rien.Il fallait 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 de l'Algol-60.À ce stade, le sémantique Cette distinction (« avoir une valeur » versus « faire quelque chose ») était inscrite dans syntaxe:un type de phrase était une expression et un autre une déclaration, et l'analyseur pouvait les distinguer.

Les concepteurs des langages ultérieurs ont brouillé la distinction :ils permettaient aux expressions syntaxiques de faire des choses, et ils permettaient aux déclarations syntaxiques qui avaient des valeurs.Le premier exemple de langage populaire qui survit encore est le C.Les concepteurs de C ont réalisé qu'il n'y aurait aucun mal à évaluer une expression et à rejeter le résultat.En C, chaque expression syntaxique peut être transformée en instruction simplement en ajoutant un point-virgule à 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 Effets secondaires-ça peut changer quelque chose.

1 + 2 / callfunc(12);

parce que callfunc pourrait juste faire quelque chose d'utile.

Une fois que vous autorisez n'importe quelle expression à être une instruction, vous pouvez tout aussi bien autoriser l'opérateur d'affectation (=) à l'intérieur des expressions.C'est pourquoi C vous permet de faire des choses comme

callfunc(x = 2);

Ceci évalue l'expression x = 2 (attribuant la valeur de 2 à x) puis transmet cela (le 2) à la fonction callfunc.

Ce flou entre expressions et instructions se produit dans tous les dérivés C (C, C++, C# et Java), qui contiennent encore certaines instructions (comme while) mais qui permettent d'utiliser presque n'importe quelle expression comme instruction (en C#, seules les expressions d'affectation, d'appel, d'incrémentation et de décrémentation peuvent être utilisées comme instructions ;voir La réponse de Scott Wisniewski).

Avoir deux « catégories syntaxiques » (qui est le nom technique du type de choses que sont les déclarations et les expressions) peut conduire à une duplication des efforts.Par exemple, C a deux formes de conditionnel, la forme instruction

if (E) S1; else S2;

et la forme d'expression

E ? E1 : E2

Et parfois les gens vouloir une duplication qui n'existe pas :Dans la norme C, par exemple, seule une instruction peut déclarer une nouvelle variable locale, mais cette capacité est suffisamment utile pour que le compilateur GNU C fournit une extension GNU qui permet également à une expression de déclarer une variable locale.

Les concepteurs d'autres langages n'aimaient pas ce type de duplication, et ils ont compris très tôt que si les expressions pouvaient avoir des effets secondaires ainsi que des valeurs, alors le syntaxique la distinction entre les déclarations et les expressions n’est pas très utile, alors ils l’ont supprimée.Haskell, Icon, Lisp et ML sont tous des langages qui n'ont pas d'instructions syntaxiques : ils n'ont que des expressions.Même les boucles structurées de classe et les formes conditionnelles sont considérées comme des expressions et elles ont des valeurs, mais pas très intéressantes.

Autres conseils

Je voudrais 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émentation 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 instruction est l'un des "blocs" de base de l'exécution d'un programme.

Notez qu'en 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 de gauche.

Voici un extrait de la grammaire ANSI C.Vous pouvez voir que C n'a pas beaucoup de types d'instructions différents...la majorité des instructions dans un programme sont des instructions d'expression, c'est-à-direune 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 instruction.

Pour des exemples:

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

Le gros problème entre les deux est que vous pouvez enchaîner des expressions, alors que les instructions ne peuvent pas être enchaînées.

Vous pouvez trouver ceci sur Wikipédia, 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 des instructions, mais pas l'inverse.

Notez que certains langages (tels que Lisp, et je crois Ruby, et bien d'autres) ne font pas de différence entre instruction et expression...dans de telles langues, tout est une expression et peut être enchaîné avec d'autres expressions.

Pour une explication des différences importantes dans la composabilité (chainabilité) des expressions par rapport aux déclarations, ma référence préférée est l'article du prix Turing de John Backus, La programmation peut-elle s’affranchir 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 de réflexion après coup.Les langages fonctionnels mettent l'accent sur les expressions. Purement les langages fonctionnels ont des expressions si puissantes que les déclarations peuvent être complètement éliminées.

Simplement:une expression est évaluée à une valeur, pas une instruction.

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

Les expressions d'appel de fonction peuvent bien sûr également être considérées comme des instructions, 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 la récupérer.

Les langages orientés instructions exigent que toutes les procédures soient une liste d'instructions.Les langages orientés expressions, qui sont probablement tous les langages fonctionnels, sont des listes d'expressions, ou dans le cas de LISP, une longue expression S 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 d'énoncé a sa propre façon de composer d'autres énoncés, s'ils peuvent tout faire.Les instructions Foreach et if nécessitent soit une seule instruction, soit que toutes les instructions subordonnées soient placées dans un bloc d'instructions, l'une après l'autre, à moins que les sous-instructions n'autorisent leurs propres sous-instructions.

Les instructions peuvent également inclure des expressions, lorsqu'une expression n'inclut pas réellement d'instructions.Une exception, cependant, serait une expression lambda, qui représente une fonction, et peut donc inclure tout ce qu'une fonction peut inclure, à moins que le langage n'autorise que des lambdas limités, comme les lambdas à expression unique de Python.

Dans un langage basé sur des expressions, tout ce dont vous avez besoin est une seule expression pour une fonction puisque toutes les structures de contrôle renvoient une valeur (beaucoup d'entre elles renvoient NIL).Il n'est pas nécessaire d'utiliser une instruction return puisque la dernière expression évaluée dans la fonction est la valeur de retour.

Quelques éléments sur les langages basés sur des expressions :


Le plus important:Tout renvoie une valeur


Il n'y a aucune 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 cependant pas la portée lexicale :Une variable locale peut être définie pour l'expression dans laquelle sa définition est contenue et toutes les instructions contenues dans celle-ci, par exemple.


Dans un langage basé sur des expressions, tout renvoie une valeur.Cela peut paraître un peu étrange au début -- Qu'est-ce que (FOR i = 1 TO 10 DO (print i)) retour?

Quelques exemples simples :

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

Quelques exemples plus complexes :

  • Certaines choses, comme certains appels de fonction, n'ont pas vraiment de valeur significative à renvoyer (des choses qui ne produisent que des effets secondaires ?).Appel 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 le (print i) expression à évaluer 10 fois, renvoyant à chaque fois i sous forme de chaîne.La dernière fois à travers les retours 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 des expressions, car le fait que tout soit une expression permet d'« intégrer » beaucoup de choses.

À titre d'exemple rapide :

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

est un remplacement parfaitement valable pour le non basé sur l'expression

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

Dans certains cas, la disposition permise par le code basé sur les expressions me semble beaucoup plus naturelle.

Bien sûr, cela peut conduire à la folie.Dans le cadre d'un projet de loisir dans un langage de script basé sur des expressions appelé MaxScript, j'ai réussi à proposer cette ligne 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'expression, avec void taper.La tendance des langues à traiter différemment les énoncés pose souvent des problèmes, et il vaudrait mieux qu’ils soient correctement généralisés.

Par exemple, en C# nous avons le très utile Func<T1, T2, T3, TResult> ensemble surchargé de délégués génériques.Mais nous devons aussi avoir un correspondant Action<T1, T2, T3> également, et la programmation générale d'ordre supérieur doit constamment être dupliquée pour faire face à cette malheureuse bifurcation.

Exemple trivial - une fonction qui vérifie si une référence est nulle avant d'appeler une autre fonction :

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

Le compilateur pourrait-il gérer la possibilité de TResult être void?Oui.Il suffit d'exiger que return soit suivi d'une expression de type void.Le résultat de default(void) serait du type void, et la fonction transmise devrait être de la forme Func<TValue, void> (ce qui équivaudrait à Action<TValue>).

Un certain nombre d'autres réponses impliquent que vous ne pouvez pas enchaîner des déclarations comme vous le pouvez avec des expressions, mais je ne sais pas d'où vient cette idée.On peut penser au ; qui apparaît après les instructions comme un opérateur infixe binaire, prenant deux expressions de type void et en les combinant en une seule expression de type void.

Déclarations -> Instructions à suivre séquentiellement
Expressions -> Évaluation 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 (ce qu'on appelle en assembleur)

Les expressions n'impliquent pas d'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 uniquement à cause du modèle impératif, mais ce n'est pas leur essence.

Exemples de déclarations :

for
goto
return
if

(tous impliquent l'avance de la ligne (instruction) d'exécution vers une autre ligne)

Exemple d'expressions :

2+2

(cela n'implique pas l'idée d'exécution, mais d'évaluation)

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

x = 5

Lit comme "x obtient 5." Il s'agit d'une phrase complète.Le code

(x + 5)/9.0

Dit: "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 ne l'est pas ;"tandis que k < 10" est une clause de subordination.

Déclaration,

Une instruction est un élément procédural à partir duquel tous les programmes C# sont construits.Une instruction peut déclarer une variable locale ou une constante, appeler une méthode, créer un objet ou attribuer 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 qui peut être évalué en une seule valeur, un objet, une méthode ou un 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 qui n'a pas de nom.

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

i et s sont des noms simples identifiant des variables locales.Lorsque ces variables sont utilisées dans une expression, la valeur de la variable est récupérée et utilisée pour l'expression.

Je préfère le sens de statement au sens logique formel du terme.C'est celui qui change l'état d'une ou plusieurs variables dans le calcul, permettant de faire une déclaration vraie ou fausse sur leur(s) valeur(s).

Je suppose qu'il y aura toujours de la confusion dans le monde informatique et dans la science en général lorsque de nouvelles terminologies ou de nouveaux mots sont introduits, que des mots existants sont « réutilisés » ou que les utilisateurs ignorent la terminologie existante, établie ou « appropriée » pour ce qu'ils décrivent.

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

Une déclaration se compose de zéro ou plusieurs expressions, mais peut également être d'autres concepts linguistiques.Voici la forme Extended Backus Naur pour la grammaire (extrait de l'instruction) :

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 qui sont considérés comme des instructions en C++.

  • expression-déclarations s'explique d'elle-même (une instruction peut consister en zéro ou plus expressions, lisez attentivement la grammaire, c'est délicat)
  • case par exemple est un déclaration étiquetée
  • déclaration de sélectionles s sont if if/else, case
  • instruction d'itérationles s sont while, do...while, for (...)
  • instruction de sautles s sont break, continue, return (peut renvoyer une expression), goto
  • déclaration-déclaration est l'ensemble des déclarations
  • essayer de bloquer est une déclaration représentant try/catch blocs
  • et il pourrait y en avoir d'autres dans la grammaire

Voici un extrait montrant la partie 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 (cela semble trompeur) fait référence à l'utilisation des opérateurs (+, -, *, /, &, |, &&, ||, ...)
  • expression de lancer - euh?le throw la clause est aussi une expression

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

Réponse originale de 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 » en expressions plus grandes à l'aide d'opérateurs, tandis que les instructions ne peuvent être combinées « verticalement » qu'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-between-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 à partir de la théorie des types informatiques, le cas échéant.

Une expression a un type autre que le type Bottom, c'est-à-direcela a une valeur.Une instruction est de type Unit ou Bottom.

Il s'ensuit qu'une instruction ne peut avoir un effet dans un programme que lorsqu'elle crée un effet secondaire, car soit elle ne peut pas renvoyer de valeur, soit elle renvoie uniquement la valeur du type Unit qui est soit non assignable (dans certains langages tels que un C void) ou (comme dans Scala) peuvent être stockés pour une évaluation différée de l'instruction.

Évidemment un @pragma ou un /*comment*/ n'ont pas de type et sont donc différenciés 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 comme espace réservé pour de futurs effets secondaires.Toute autre action due à une déclaration serait un effet secondaire.Encore une fois, un indice du compilateur, par ex. @pragma, n'est pas une instruction car elle 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 valeur type (c'est-à-direpas le type inférieur).

Le type de déclaration est le type d'unité, mais en raison du théorème de Halting, l'unité est une fiction, disons donc que type de fond.


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 je n'ai pas un système complètement sonore.Cela peut paraître snob, mais l’exhaustivité comme les annotations de variance sont essentiels à l’écriture de logiciels extensibles.

Voyons ce que Wikipédia a à dire à ce sujet.

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

En programmation informatique, une instruction est le plus petit élément autonome d'un impératif langage de programmation qui exprime une action à réaliser.

De nombreuses langues (par ex.C) faire une distinction entre les instructions et les définitions, avec une instruction contenant uniquement du code exécutable et une définition déclarant un identifiant, tandis qu'une expression est évaluée uniquement à une valeur.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top