Je demande en 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?
Je demande en 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?
Réponses:
Expression: quelque chose qui correspond à une valeur. Exemple: 1 + 2 / x
Instruction: une ligne de code qui fait quelque chose. Exemple: GOTO 100
Dans les premiers langages de programmation à usage général, comme FORTRAN, la distinction était limpide. À FORTRAN, une déclaration était une unité d'exécution, une chose que vous avez faite. La seule raison pour laquelle elle n'était pas appelée "ligne" était parce qu'elle s'étalait parfois sur plusieurs lignes. Une expression seule ne pouvait rien faire ... vous deviez l'assigner à une variable.
est une erreur dans FORTRAN, car il ne fait rien. Il fallait faire quelque chose avec cette expression:
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, la distinction sémantique («avoir une valeur» par rapport à «faire quelque chose») était inscrite dans la syntaxe : un type de phrase était une expression, et un autre était une déclaration, et l'analyseur pouvait les distinguer.
Les concepteurs des langages ultérieurs ont brouillé la distinction: ils ont permis aux expressions syntaxiques de faire des choses, et ils ont autorisé les déclarations syntaxiques qui avaient 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 à jeter le résultat. En C, chaque expression syntaxique peut être transformée en une instruction en plaçant simplement un point-virgule à la fin:
est une déclaration totalement légitime même si absolument rien ne se passera. De même, en C, une expression peut avoir des effets secondaires - elle peut changer quelque chose.
parce
callfunc
que ça pourrait faire quelque chose d'utile.Une fois que vous autorisez une expression à être une instruction, vous pouvez tout aussi bien autoriser l'opérateur d'affectation (=) à l'intérieur des expressions. Voilà pourquoi C vous permet de faire des choses comme
Cela évalue l'expression x = 2 (en affectant la valeur de 2 à x), puis la transmet (les 2) à la fonction
callfunc
.Ce flou des expressions et des instructions se produit dans toutes les dérivées C (C, C ++, C # et Java), qui ont encore quelques instructions (comme
while
) mais qui permettent à presque toutes les expressions d'être utilisées comme instruction (en affectation C # uniquement, les expressions call, increment et decrement peuvent être utilisées comme des instructions; voir la réponse de Scott Wisniewski ).Le fait d'avoir deux «catégories syntaxiques» (qui est le nom technique du genre de déclarations et d'expressions) peut entraîner une duplication des efforts. Par exemple, C a deux formes de conditionnel, le formulaire de déclaration
et la forme d'expression
Et parfois, les gens veulent une duplication qui n'est pas là: en C standard, par exemple, seule une instruction peut déclarer une nouvelle variable locale, mais cette capacité est suffisamment utile pour que le compilateur GNU C fournisse une extension GNU qui permet à une expression de déclarer un variable locale également.
Les concepteurs d'autres langages n'aimaient pas ce type de duplication, et ils ont vu très tôt que si les expressions pouvaient avoir des effets secondaires ainsi que des valeurs, alors la distinction syntaxique entre les déclarations et les expressions n'était pas très utile - alors ils s'en sont débarrassés. . Haskell, Icon, Lisp et ML sont tous des langages qui n'ont pas d'instructions syntaxiques - ils ont seulement des expressions. Même les formes en boucle structurée et conditionnelles de classe sont considérées comme des expressions, et elles ont des valeurs, mais pas très intéressantes.
la source
callfunc(x = 2);
passex
àcallfunc
, non2
. Six
est un flotteur,callfunc(float)
sera appelé, noncallfunc(int)
. Et en C ++, si vous passezx=y
àfunc
, etfunc
prend une référence et la change, elle changex
, nony
.where
clause dans haskell est considérée comme une expression et non comme une déclaration. Learnyouahaskell.com/syntax-in-functions#wherewhere
est en fait une partie de la déclaration de fonction, pas une expression ou une déclaration.Notez qu'en C, "=" est en fait un opérateur, qui fait deux choses:
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-à-dire une expression avec un point-virgule à la fin.
http://www.lysator.liu.se/c/ANSI-C-grammar-y.html
la source
Une expression est quelque chose qui renvoie une valeur, contrairement à une instruction.
Pour des exemples:
Le gros problème entre les deux est que vous pouvez enchaîner les expressions, tandis que les déclarations ne peuvent pas être enchaînées.
la source
foo.voidFunc(1);
est une expression avec une valeur nulle.while
etif
sont des déclarations.return
est considéré comme une sous-déclaration.Vous pouvez le trouver sur wikipedia , mais les expressions sont évaluées selon une certaine valeur, tandis que les instructions n'ont pas de valeur évaluée.
Ainsi, les expressions peuvent être utilisées dans les instructions, mais pas l'inverse.
Notez que certaines langues (comme Lisp, et je crois que Ruby, et bien d'autres) ne font pas la différence entre déclaration et expression ... dans de telles langues, tout est une expression et peut être enchaîné avec d'autres expressions.
la source
Pour une explication des différences importantes dans la composabilité (chaînabilité) des expressions par rapport aux déclarations, ma référence préférée est le prix Turing Award de John Backus, La programmation peut-elle être libérée 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. Les langages purement fonctionnels ont des expressions si puissantes que les déclarations peuvent être complètement éliminées.
la source
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, mais à moins que l'environnement d'exécution n'ait 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 nécessitent 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 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 de déclaration a sa propre façon de composer d'autres déclarations, si elles peuvent tout faire. Pour chaque instruction et si les instructions 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 ne permettent leurs propres sous-instructions.
Les instructions peuvent également inclure des expressions, où une expression n'inclut vraiment aucune instruction. Une exception, cependant, serait une expression lambda, qui représente une fonction, et peut donc inclure tout ce qu'une fonction peut exclure à 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 seule expression pour une fonction puisque toutes les structures de contrôle renvoient une valeur (beaucoup d'entre elles renvoient NIL). Il n'y a pas besoin d'une instruction de retour car la dernière expression évaluée dans la fonction est la valeur de retour.
la source
Void
n'est pas le type inférieur. Voir ma réponse .null
)? Ne serait-ce pasvoid
plus comme le type d'unité (mais avec sa valeur unique inaccessible)?void
est le type de retour d'une fonction qui ne retourne jamais (par exemple une fonction quithrow
est une erreur), c'est le type du bas . Sinon,void
c'est le type d'unité . Vous avez raison de dire qu'une instruction qui ne peut pas diverger a le type d'unité. Mais une déclaration qui peut diverger est le type le plus bas. En raison du théorème de l'arrêt, nous ne pouvons généralement pas prouver qu'une fonction ne diverge pas, donc je pense que l'unité est une fiction. Le type inférieur ne peut pas avoir de valeur, il ne peut donc pas avoir une seule valeur denull
.null
valeur est vraiment une pseudovalue indiquant qu'une référence se réfère à quelque chose qui n'existe pas.Simplement: une expression évalue une valeur, une instruction ne le fait pas.
la source
{}
est une déclaration. Mettre le mot entre guillemets effrayants ne change rien à cela. Les instructions sont des constructions syntaxiques avec une sémantique. Il n'y a rien de tel que «la couche sémantique» - vous semblez faire référence à l' exécution . Vous dites que vous essayez d'être précis, mais vous avez échoué. Votre plainte concernant "l'ignorance des électeurs" est pure ad hominem; vous n'avez aucune information sur les états mentaux des downvoters.{}
est défini comme une instruction dans la spécification du langage C #.Certaines choses sur les langages basés sur l'expression:
Le plus important: tout renvoie 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, car tout est une expression. Cela n'empêche cependant pas la portée lexicale: une variable locale pourrait ê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 l'expression, tout renvoie une valeur. Cela peut être un peu étrange au début - Qu'est-ce qui
(FOR i = 1 TO 10 DO (print i))
revient?Quelques exemples simples:
(1)
Retour1
(1 + 1)
Retour2
(1 == 1)
RetourTRUE
(1 == 2)
RetourFALSE
(IF 1 == 1 THEN 10 ELSE 5)
Retour10
(IF 1 == 2 THEN 10 ELSE 5)
Retour5
Quelques exemples plus complexes:
OpenADoor(), FlushTheToilet()
ouTwiddleYourThumbs()
renverra une sorte de valeur banale, comme OK, Terminé ou Réussite.(FOR i = 1 TO 10 DO (print i))
, la valeur de la boucle for est "10", elle provoque l'(print i)
évaluation de l' expression 10 fois, renvoyant à chaque fois i sous forme de chaîne. La dernière fois grâce aux retours10
, notre réponse finaleCela nécessite souvent un léger changement de mentalité pour tirer le meilleur parti d'un langage basé sur l'expression, car le fait que tout soit une expression permet de `` mettre en ligne '' beaucoup de choses
Comme exemple rapide:
est un remplacement parfaitement valide pour le non basé sur l'expression
Dans certains cas, la disposition permise par le code basé sur l'expression 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 l'expression appelé MaxScript, j'ai réussi à trouver cette ligne monstre
la source
Une instruction est un cas particulier d'une expression, une de
void
type. La tendance des langues à traiter les énoncés différemment pose souvent des problèmes et il serait préférable qu’elles soient correctement généralisées.Par exemple, en C #, nous avons l'
Func<T1, T2, T3, TResult>
ensemble surchargé très utile de délégués génériques. Mais nous devons également disposer d'unAction<T1, T2, T3>
ensemble correspondant , et la programmation d'ordre supérieur à usage général 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 sur une autre fonction:
Le compilateur pourrait-il gérer la possibilité de l'
TResult
êtrevoid
? Oui. Il suffit d'exiger que return soit suivi d'une expression de typevoid
. Le résultat dedefault(void)
serait de typevoid
, et la fonction transmise devrait être de la formeFunc<TValue, void>
(qui serait équivalente àAction<TValue>
).Un certain nombre d'autres réponses impliquent que vous ne pouvez pas enchaîner des instructions comme vous le pouvez avec des expressions, mais je ne sais pas d'où vient cette idée. Nous pouvons penser à ce
;
qui apparaît après les instructions comme un opérateur d'infixe binaire, prenant deux expressions de typevoid
et les combinant en une seule expression de typevoid
.la source
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 (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:
(tous impliquent le passage de la ligne (instruction) d'exécution à une autre ligne)
Exemple d'expressions:
(cela n'implique pas l'idée d'exécution, mais l'évaluation)
la source
Statement ,
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 objet 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.
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 valeur, un objet, une méthode ou un espace de noms unique. 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.
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.
la source
if(number >= 0) return true; else return false;
ou encore mieuxbool? IsPositive(int number) { if(number > 0) return true; else if(number < 0) return false; else return null;}
:)Je préfère le sens de
statement
dans le sens logique formel du mot. Il en est une qui change l'état d'une ou plusieurs des 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 de l'informatique et de la science en général lorsque de la nouvelle terminologie ou de nouveaux mots sont introduits, des mots existants sont «réaffectés» ou que les utilisateurs ignorent la terminologie existante, établie ou «appropriée» pour ce qu'ils décrivent.
la source
Je ne suis vraiment satisfait d'aucune des réponses ici. J'ai regardé la grammaire du C ++ (ISO 2008) . Cependant, peut-être 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 instruction se compose de zéro ou plusieurs expressions, mais peut également être d'autres concepts de langage. Il s'agit du formulaire Extended Backus Naur pour la grammaire (extrait de la déclaration):
Nous pouvons voir les autres concepts qui sont considérés comme des instructions en C ++.
case
par exemple, est une déclaration étiquetéeif
if/else
,case
while
,do...while
,for (...)
break
,continue
,return
(peut retourner l' expression),goto
try/catch
blocsCeci est un extrait montrant la partie des expressions:
+
,-
,*
,/
,&
,|
,&&
,||
, ...)throw
clause est aussi une expressionla source
Les déclarations sont des phrases grammaticalement complètes. Les expressions ne le sont pas. Par exemple
se lit comme "x obtient 5." Ceci est une phrase complète. Le code
lit, "x plus 5 tous divisés par 9,0." Ce n'est pas une phrase complète. La déclaration
est une phrase complète. Notez que l'en-tête de boucle ne l'est pas; "tandis que k <10," est une clause subordonnée.
la source
while
est une expression est quelques langues telles que Scala. Vous confondez la grammaire avec la dactylographie. Voir ma réponse .while
avec un corps est toujours une expression en Scala. Il peut également s'agir d'une déclaration si elle crée des effets secondaires, ce que permet ma réponse fortement défavorisée (une expression peut également être une déclaration). Ma réponse est la seule correcte. Désolé à tous ces lecteurs qui ne comprennent pas.(x + 5)/9.0
peut certainement être autonome en tant que déclaration. En outre, si par grammaticalement complet, vous entendez un programme valide, C ne permet pas aux instructions de se tenir seules en tant que programme unique.Voici le résumé d'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 évalue 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
la source
La base de facto de ces concepts est:
Expressions : catégorie syntaxique dont l'instance peut être évaluée en une valeur.
Instruction : une catégorie syntaxique dont l'instance peut être impliquée dans les évaluations d'une expression et la valeur résultante de l'évaluation (le cas échéant) n'est pas garantie disponible.
Outre le contexte très initial de FORTRAN dans les premières décennies, les définitions des expressions et des déclarations dans la réponse acceptée sont évidemment fausses:
sizeof
opérateur n'est jamais évaluée.(BTW, je veux ajouter [la citation nécessaire] à cette réponse concernant les documents sur C parce que je ne me souviens pas si DMR a de telles opinions. Il ne semble pas, sinon il ne devrait pas y avoir de raisons de préserver la duplication des fonctionnalités dans la conception de C : notamment, l'opérateur virgule vs les instructions.)
(La justification suivante n'est pas la réponse directe à la question d'origine, mais je pense qu'il est nécessaire de clarifier quelque chose qui a déjà répondu ici.)
Néanmoins, il est douteux que nous ayons besoin d'une catégorie spécifique d '"instructions" dans les langages de programmation à usage général:
begin
dans Scheme) ou du sucre syntaxique de structures monadiques.++i + ++i
n'a pas de sens en C.)Alors pourquoi des déclarations? Quoi qu'il en soit, l'histoire est déjà un gâchis. Il semble que la plupart des concepteurs de langues ne prennent pas leur choix avec soin.
Pire encore, cela donne même à certains amateurs de systèmes de types (qui ne connaissent pas suffisamment l'histoire du PL) des idées fausses selon lesquelles les systèmes de types doivent avoir des choses importantes à faire avec les conceptions plus essentielles des règles sur la sémantique opérationnelle.
Sérieusement, le raisonnement selon les types n'est pas si mal dans de nombreux cas, mais surtout pas constructif dans ce cas particulier. Même les experts peuvent tout gâcher.
Par exemple, quelqu'un met l'accent sur la nature bien typée comme argument central contre le traitement traditionnel des continuations non délimitées . Bien que la conclusion soit quelque peu raisonnable et que les informations sur les fonctions composées soient correctes ( mais encore beaucoup trop naïves à l'essentiel ), cet argument n'est pas valable car il ignore totalement l'approche "canal latéral" dans la pratique comme
_Noreturn any_of_returnable_types
(en C11) pour coderFalsum
. Et à proprement parler, une machine abstraite à l'état imprévisible n'est pas identique à "un ordinateur en panne".la source
Dans un langage de programmation orienté instructions, un bloc de code est défini comme une liste d'instructions. En d'autres termes, une instruction est un élément de syntaxe que vous pouvez placer dans un bloc de code sans provoquer d'erreur de syntaxe.
Wikipédia définit le mot énoncé de la même façon
Notez la dernière déclaration. (bien que "un programme" dans ce cas soit techniquement incorrect parce que C et Java rejettent un programme qui ne contient rien d'instructions.)
Wikipedia définit l'expression du mot comme
Ceci est cependant faux, car dans Kotlin,
throw new Exception("")
est une expression mais lorsqu'elle est évaluée, elle lève simplement une exception, ne renvoyant jamais aucune valeur.Dans un langage de programmation typé statiquement, chaque expression a un type. Cette définition, cependant, ne fonctionne pas dans un langage de programmation typé dynamiquement.
Personnellement, je définis une expression comme un morceau de syntaxe qui peut être composé avec un opérateur ou des appels de fonction pour produire une expression plus grande. Ceci est en fait similaire à l'explication de l'expression par Wikipedia:
Mais, le problème est dans le langage de programmation C, étant donné une fonction executeSomething comme ceci:
Est-ce
executeSomething()
une expression ou une déclaration? Selon ma définition, il s'agit d'une déclaration car, comme défini dans la grammaire de référence C de Microsoft,Mais la même page indique clairement qu'une telle syntaxe est une expression.
la source
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-à-dire qu'elle a une valeur. Une instruction a le type Unit ou Bottom.
Il s'ensuit qu'une instruction ne peut avoir d'effet dans un programme que lorsqu'elle crée un effet secondaire, car elle ne peut pas renvoyer de valeur ou elle ne renvoie que la valeur du type Unit qui est soit non assignable (dans certaines langues telles que un C
void
) ou (comme dans Scala) peuvent être stockés pour une évaluation différée de la déclaration.De toute évidence, a
@pragma
ou a/*comment*/
n'ont pas de type et sont donc différenciés des déclarations. 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 exemple@pragma
, n'est pas une instruction car il n'a pas de type.la source
@pragma
ou/*comment*/
sont logiquement incohérents.Plus précisément, une déclaration doit avoir un «effet secondaire» (c'est- à- dire être impérative ) 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 l'unité du théorème de Halting, c'est de la fiction, alors disons le type du bas .
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 n'ont pas de système de type complètement sonore . Cela peut ressembler à une déclaration snob, mais l'exhaustivité comme les annotations de variance est essentielle à l'écriture d'un logiciel extensible.Voyons ce que Wikipedia a à dire à ce sujet.
https://en.wikipedia.org/wiki/Statement_(computer_science)
la source
pass
est une déclaration. C'est un no-op, et il n'évalue rien.