expresión versus declaración


389

Estoy preguntando con respecto a C#, pero supongo que es el mismo en la mayoría de los demás idiomas.

¿Alguien tiene una buena definición de expresiones y declaraciones y cuáles son las diferencias?

+4

La respuesta que eliges es ambigua. Una expresión también hace algo: evalúa a un valor. Proporcioné una respuesta no ambigua. 09 dic. 112011-12-09 19:36:28

+3

@ShelbyMooreIII - No ambiguo y también incorrecto. La respuesta aceptada está redactada de manera informal, pero esa redacción lo hace fácil de entender, y lo más importante, el significado que transmite es preciso. 13 dic. 122012-12-13 21:56:37

474

Expresión: Algo que se evalúa a un valor. Ejemplo: 1 + 2/x
Declaración: Una línea de código que hace algo.Ejemplo: GOTO 100

En los primeros lenguajes de programación de propósito general, como FORTRAN, la distinción era nítida. En FORTRAN, una declaración fue una unidad de ejecución, una cosa que hiciste. La única razón por la que no se llamaba "línea" era porque a veces abarcaba varias líneas. Una expresión en sí misma no podía hacer nada ... tenías que asignarla a una variable.

1 + 2/X

es un error en FORTRAN, ya que no hace nada. Había que hacer algo con esa expresión:

X = 1 + 2/X

FORTRAN no tiene una gramática tal como la conocemos hoy en día — esa idea fue inventado, junto con la forma de Backus-Naur (BNF), como parte de la definición de Algol-60. En ese punto, la distinción semántica ("tener un valor" frente a "hacer algo") estaba consagrada en sintaxis: un tipo de frase era una expresión y otra era una declaración, y el analizador podía distinguirlas.

Los diseñadores de lenguajes posteriores difuminaron la distinción: permitían expresiones sintácticas para hacer cosas, y permitían declaraciones sintácticas que tenían valores. El primer ejemplo de lenguaje popular que aún sobrevive es C. Los diseñadores de C se dieron cuenta de que no se hacía daño si se les permitía evaluar una expresión y descartar el resultado. En C, cada expresión sintáctica puede ser un hecho en una declaración que acaba de virando un punto y coma lo largo del extremo:

1 + 2/x;

es una declaración totalmente de fiar a pesar de que absolutamente nada ocurrirá. Del mismo modo, en C, una expresión puede tener efectos secundarios — puede cambiar algo.

1 + 2/callfunc(12);

porque callfunc sólo podría hacer algo útil.

Una vez que permite que cualquier expresión sea una instrucción, también puede permitir que el operador de asignación (=) entre expresiones. Es por eso que C le permite hacer cosas como

callfunc(x = 2);

Esto evalúa la expresión x = 2 (asignando el valor de 2 a x) y luego pasa que (el 2) a la función callfunc.

Esta difuminación de las expresiones y declaraciones que ocurre en todos los C-derivados (C, C++, C#, y Java), que todavía tiene algunas declaraciones (como while) pero que permiten que casi cualquier expresión que se utiliza como una declaración (en la asignación solo en C#, las expresiones de llamada, incremento y decremento se pueden usar como declaraciones; ver Scott Wisniewski's answer).

Tener dos "categorías sintácticas" (que es el nombre técnico para el tipo de declaraciones y expresiones) puede llevar a la duplicación de esfuerzos.Por ejemplo, C tiene dos formas de condicional, el formulario de declaración

if (E) S1; else S2; 

y la forma de expresión

E ? E1 : E2 

ya veces las personas quieren duplicación que no está ahí: en C estándar, por ejemplo, , solo una declaración puede declarar una nueva variable local — pero esta capacidad es lo suficientemente útil como para que el compilador C de GN proporcione una extensión GNU que permita a una expresión declarar también una variable local.

diseñadores de otros idiomas no les gustaba este tipo de duplicación, y vieron desde el principio que si las expresiones pueden tener efectos secundarios, así como los valores, entonces el sintáctica distinción entre afirmaciones y expresiones que no es del todo útil — así que se deshicieron de eso. Haskell, Icon, Lisp y ML son todos los idiomas que no tienen declaraciones sintácticas. — solo tienen expresiones. Incluso el bucle estructurado de clase y las formas condicionales se consideran expresiones, y tienen valores — pero no muy interesantes.

+9

Si no te estoy interpretando mal aquí, pareces afirmar que "(setf (tercer foo) 'ganso)" es una expresión, no un enunciado, porque es Lisp, que "no tiene enunciados" y porque Lisp tiene más de una década más que C, que era el "primer lenguaje popular para difuminar las líneas [entre expresiones y declaraciones]". Podría explicar los detalles de eso para mí? 24 jun. 092009-06-24 18:24:10

+2

@Curt Sampson, ¿lo has preguntado como una pregunta separada? 27 oct. 092009-10-27 23:06:30

+2

Si no me equivoco, 'callfunc (x = 2);' pasa 'x' a' callfunc', no a '2'. Si 'x' es un flotante, se llamará a' callfunc (float) ', no' callfunc (int) '.Y en C++, si pasa 'x = y' a' func', y 'func' toma una referencia y lo cambia, cambia' x', no 'y'. 23 sep. 112011-09-23 02:34:20

+1

Más precisamente, una declaración debe tener un ** "efecto secundario" ** (es decir, [ser imperativo] (http://stackoverflow.com/questions/602444/what-is-functional-declarative-and-imperative-programming)/8357604 # 8357604)) y una expresión debe tener un ** valor ** tipo (es decir, no el tipo inferior). El [tipo de extracto] (http://james-iry.blogspot.com/2009/08/getting-to-bottom-of-nothing-at-all.html) es el [tipo inferior] (http://stackoverflow.com/a/8450076/615784). 09 dic. 112011-12-09 18:52:41

+2

Encuentro que esta respuesta es ambigua. Una expresión también hace algo: evalúa a un valor. Proporcioné una respuesta no ambigua. 09 dic. 112011-12-09 19:37:11

  0

En la respuesta anterior, está escrito que "Haskell, ... son todos los idiomas que no tienen enunciados sintácticos, solo tienen expresiones". Tengo curiosidad por qué la cláusula 'where' en haskell se considera una expresión y no una afirmación. http://learnyouahaskell.com/syntax-in-functions#where 30 nov. 162016-11-30 05:11:57


5

Las expresiones se pueden evaluar para obtener un valor, mientras que las declaraciones no devuelven un valor (son del tipo void).

Las expresiones de llamada de función también se pueden considerar como instrucciones de curso, pero a menos que el entorno de ejecución tenga una variable incorporada especial para contener el valor devuelto, no hay forma de recuperarlo.

Los lenguajes orientados a instrucciones requieren que todos los procedimientos sean una lista de instrucciones. Los lenguajes orientados a expresiones, que probablemente son todos los lenguajes funcionales, son listas de expresiones, o en el caso de LISP, una expresión S larga que representa una lista de expresiones.

Aunque se pueden componer ambos tipos, la mayoría de las expresiones se pueden componer arbitrariamente siempre que los tipos coincidan. Cada tipo de declaración tiene su propia forma de componer otras declaraciones, si pueden hacer eso todas. Las declaraciones Foreach y if requieren una sola declaración o que todas las declaraciones subordinadas van en un bloque de instrucción, una después de otra, a menos que las subclasificaciones permitan sus propias subestaciones.

Las declaraciones también pueden incluir expresiones, donde una expresión realmente no incluye ninguna instrucción. Una excepción, sin embargo, sería una expresión lambda, que representa una función, y puede incluir cualquier cosa que una función pueda incluir a menos que el lenguaje solo permita lambdas limitadas, como la lambda de una sola expresión de Python.

En un lenguaje basado en expresiones, todo lo que necesita es una expresión única para una función, ya que todas las estructuras de control devuelven un valor (muchas de ellas devuelven NIL). No es necesario un enunciado de retorno ya que la última expresión evaluada en la función es el valor de retorno.

  0

El tipo de extracto es el tipo de fondo. 'Void' no es el tipo de fondo. Ver [mi respuesta] (http://stackoverflow.com/a/8450398/615784). 09 dic. 112011-12-09 19:07:08

+1

¿No es el _null type_ el tipo inferior (valor único de 'null')? ¿No sería 'void' más parecido al _unit type_ (pero con su único valor inaccesible)? 09 dic. 112011-12-09 22:04:16

  0

Si 'void' es el tipo de retorno de una función que nunca regresa (por ejemplo, una función que' throw's a error), es el [tipo de fondo] (http://en.wikipedia.org/wiki/Bottom_type) . De lo contrario 'void' es el [tipo de unidad] (http://en.wikipedia.org/wiki/Bottom_type). Tiene razón en que una afirmación que no puede divergir tiene el tipo de unidad. Pero una afirmación que puede divergir es el tipo inferior. Debido al Teorema de Detención, generalmente no podemos probar que una función no diverge, entonces pienso que la unidad es ficción. El tipo de fondo no puede tener un valor, por lo que no puede tener un solo valor de 'null'. 09 dic. 112011-12-09 22:40:33

+1

Con respecto a lo que dije hace tres años, no sé si sigo creyendo que las declaraciones tienen realmente un tipo _void_ o cualquier tipo. En los lenguajes basados ​​en sentencias con los que estoy familiarizado, solo _values_ y cualquier cosa que almacene o devuelva un valor (por ejemplo, expresiones, variables, miembros y funciones) pueden tener tipos. Generalmente pienso en el tipo de fondo como el conjunto vacío (sin valores) y, por lo tanto, cualquier cosa que no exista ontológicamente tendría este tipo. Un valor 'nulo' es realmente un __pseudovalorado__ que denota que una referencia se refiere a algo que no existe. 10 dic. 112011-12-10 00:57:11

+1

Mark He apreciado la racionalidad de su respuesta. Básicamente sacaste las palabras de mi boca Y espero que haya quedado claro que te admití que estabas en lo cierto al plantear el punto de unidad. Creo que estamos de acuerdo. No iba a molestarme en mencionar esto, pero parece que algunas personas aquí piensan que estoy siendo negativo. Solo estoy tratando de ser real. 10 dic. 112011-12-10 06:27:01


13

Una expresión es algo que devuelve un valor, mientras que una declaración no.

Para ejemplos:

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

el reparto grande entre los dos es que se puede encadenar expresiones, mientras que los estados no pueden ser encadenados.

+5

Se pueden encadenar declaraciones seguras. {stmt1; stmt2; stmt3;} es una cadena, y también es una declaración (compuesta) en sí misma. 08 abr. 092009-04-08 01:54:26

+5

'foo.voidFunc (1);' es una expresión con un valor nulo. 'while' y' if' son enunciados. 02 dic. 092009-12-02 13:57:58

  0

Tengo curiosidad sobre el no encadenamiento de las declaraciones. Algo como "if (x> 1) return;" se considera que encadena dos declaraciones juntas? 29 ene. 132013-01-29 22:25:44


5

Simplemente: una expresión se evalúa como un valor, una instrucción no.

  0

Entonces, ¿qué hace una declaración? ¿Nada? 09 dic. 112011-12-09 19:16:59

+1

Puede hacer algo, pero no evalúa nada. Es decir, no puede asignar el resultado a una variable, mientras que puede hacerlo con una expresión. 10 dic. 112011-12-10 09:52:34

  0

Y, por lo tanto, una declaración debe tener efectos colaterales, ya que mis estados de respuesta votados mucho menos. ¿Qué otra utilidad podría tener una declaración? Incluso si un NO-OP se considerara como una afirmación (es solo "enunciado" en la gramática pero no en la capa de semántica porque se borra después del análisis sintáctico y la semántica es lo que estamos discutiendo aquí), no explicaría qué diablos la utilidad general de una declaración es. 25 ago. 142014-08-25 06:47:48

+1

@ShelbyMooreIII Las declaraciones no necesitan hacer nada ni tener efectos secundarios. por ejemplo, '{}' es una declaración. Poner la palabra en citas de miedo no cambia eso. Las declaraciones son constructos sintácticos con semántica. No existe la "capa de semántica", parece que te refieres a * ejecución *. Usted dice que está tratando de ser exacto, pero ha fallado en eso. Su queja sobre "la ignorancia de los votantes a la baja" es pura ad hominem; no tienes información sobre los estados mentales de los downvoters. 28 jul. 152015-07-28 23:43:39

  0

Sí, todos están equivocados, excepto los intelectualmente deshonestos. '{}' se define como una declaración en la especificación del lenguaje C#. 18 ago. 152015-08-18 07:40:59


8

Puede encontrar esto en wikipedia, pero las expresiones se evalúan con algún valor, mientras que las declaraciones no tienen valor evaluado.

Por lo tanto, las expresiones se pueden utilizar en las declaraciones, pero no al revés.

Tenga en cuenta que algunos lenguajes (como Lisp, y creo que Ruby, y muchos otros) no diferencian declaración contra expresión ... en tales idiomas, todo es una expresión y puede ser encadenado con otras expresiones.


21
  • Una expresión es cualquier cosa que se obtiene un valor de: 2 + 2
  • una declaración es uno de los "bloques" básicos de la ejecución del programa.

Tenga en cuenta que en C, "=" es en realidad un operador, que hace dos cosas:

  • devuelve el valor de la mano derecha subexpresión.
  • copia el valor de la subexpresión del lado derecho en la variable del lado izquierdo.

Aquí hay un extracto de la gramática ANSI C. Puede ver que C no tiene muchos tipos diferentes de enunciados ... la mayoría de los enunciados en un programa son enunciados de expresión, es decir, una expresión con un punto y coma al final.

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

+2

Lógica incorrecta sobre lo que es una declaración. Un programa declarativo también puede ejecutarse, pero un programa declarativo no tiene enunciados. Una declaración es y lo hace ["efectos secundarios"] (http://stackoverflow.com/a/8357604/615784), es decir, es imprescindible. cf. [mi respuesta] (http://stackoverflow.com/a/8450398/615784). 09 dic. 112011-12-09 19:28:33


50

me gustaría hacer una pequeña corrección a la respuesta de Joel anteriormente.

C# no permite utilizar todas las expresiones como declaraciones. En particular, solo las expresiones de asignación, llamada, incremento y decremento se pueden usar como declaraciones.

Por ejemplo, la bandera C# compilador el código siguiente como un error de sintaxis:

1 + 2;

+2

El fraseo del error del compilador es [** Solo las expresiones de asignación, llamada, incremento, decremento y nuevo objeto se pueden usar como una declaración **] (http://msdn.microsoft.com/en-us/library/ k626bk8b.aspx). Probablemente tomes una nueva expresión de objeto para una "llamada", lo cual está bien para mí (pero no tienes un enlace a MSDN). 29 may. 122012-05-29 21:24:54


3

Algunas cosas sobre basada expresión idiomas:


Lo más importante: Todo devuelve un valor


No hay diferencia entre corchetes y llaves para delimitar bloques de código y expresiones, ya que todo es una expresion.Esto no impide ámbito léxico sin embargo: Una variable local se podría definir por la expresión en la que se contiene su definición y todas las declaraciones contenidas dentro de éste, por ejemplo.


En un lenguaje basado en expresiones, todo devuelve un valor. Esto puede ser un poco extraño al principio - ¿Qué (FOR i = 1 TO 10 DO (print i)) cambio?

algunos ejemplos sencillos:

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

un par de ejemplos más complejos:

  • algunas cosas, tales como algunas llamadas de función, en realidad no tienen un valor significativo para volver (Cosas que sólo producen lateral efectos?). Llamando OpenADoor(), FlushTheToilet() o TwiddleYourThumbs() volverá algún tipo de valor mundano, como Aceptar, Hecho, o el éxito.
  • Cuando múltiples expresiones no ligados se evalúan dentro de una mayor expresión, el valor de la última cosa evaluado en la gran expresión se convierte en el valor de la gran expresión. Para tomar el ejemplo de (FOR i = 1 TO 10 DO (print i)), el valor del bucle es "10", hace que la expresión (print i) a ser evaluado 10 veces, cada vez volviendo i como una cadena. La hora final a través de declaraciones de 10, nuestra respuesta final

A menudo requiere un ligero cambio de mentalidad para obtener el máximo rendimiento de un lenguaje basado en la expresión, ya que el hecho de que todo es una expresión hace que sea posible 'inline' muchas cosas

Como un ejemplo rápido:

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

es un sustituto perfectamente válido para la no expresión de base

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

En algunos casos, la disposición de que los permisos de código basadas en expresiones se siente mucho más natural para mí

Por supuesto, esto puede llevar a la locura. Como parte de un proyecto de pasatiempo en un lenguaje de programación basado en la expresión llamada MaxScript, me las arreglé para llegar a esta línea monstruo

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 
) 

3

Una declaración es un caso especial de una expresión, una con void tipo. La tendencia de los idiomas a tratar las declaraciones de manera diferente a menudo causa problemas, y sería mejor si se generalizaran adecuadamente.

Por ejemplo, en C# tenemos el muy útil Func<T1, T2, T3, TResult> grupo sobrecargado de delegados genéricos. Pero también tenemos que tener un conjunto correspondiente de Action<T1, T2, T3>, y la programación de alto orden de propósito general constantemente tiene que ser duplicada para tratar con esta desafortunada bifurcación.

Trivial ejemplo - una función que comprueba si la referencia es nula antes de llamar a otra función:

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

Podría el compilador acuerdo con la posibilidad de ser TResultvoid? Sí. Todo lo que tiene que hacer es requerir que el retorno sea seguido por una expresión del tipo void. El resultado de default(void) sería del tipo void, y el func que se pasa debería ser de la forma Func<TValue, void> (que sería equivalente a Action<TValue>).

Algunas otras respuestas implican que no se pueden entablar enunciados como se puede con expresiones, pero no estoy seguro de dónde viene esta idea. Podemos pensar en el ; que aparece después de los enunciados como un operador infijo binario, tomando dos expresiones del tipo void y combinándolas en una sola expresión del tipo void.


7

Para una explicación de las diferencias importantes en la compibilidad (chainable) de expresiones vs declaraciones, mi referencia favorita es el documento del premio Turing de John Backus, Can programming be liberated from the von Neumann style?.

Los lenguajes imperativos (Fortran, C, Java, ...) enfatizan los enunciados para estructurar programas, y tienen expresiones como una especie de reflexión. Los lenguajes funcionales enfatizan las expresiones. Puramente idiomas funcionales tienen expresiones tan potentes que las declaraciones se pueden eliminar por completo.


1

Las declaraciones son oraciones gramaticalmente completas. Las expresiones no son Por ejemplo

x = 5 

dice "x obtiene 5". Esta es una oración completa. El código

(x + 5)/9.0 

dice, "x más 5 dividido entre 9.0". Esta no es una oración completa. La declaración

while k < 10: 
    print k 
    k += 1 

es una oración completa. Observe que el encabezado del bucle no es; "mientras k < 10," es una cláusula subordinada.

  0

'while' es una expresión en algunos idiomas como Scala. Usted está combinando gramática con mecanografía. Ver [mi respuesta] (http://stackoverflow.com/a/8450398/615784). 09 dic. 112011-12-09 19:12:24

  0

Aquí está el ciclo while en scala: http://www.tutorialspoint.com/scala/scala_while_loop.htm El ciclo con su predicado y sin cuerpo no es una oración gramaticalmente completa. No es una expresión completa. Necesitas que el cuerpo lo complete como una expresión. 08 may. 132013-05-08 00:42:21

  0

Un 'while' con un cuerpo sigue siendo una expresión en Scala. También puede ser una afirmación si crea efectos secundarios, que es lo que permite mi respuesta downvoted (una expresión también puede ser una declaración). Mi respuesta es la única correcta. Lo siento por todos aquellos lectores que no pueden entender. 22 jun. 132013-06-22 16:49:22


-9

más precisamente, una declaración debe tener un "efecto secundario" (es decir be imperative) y una expresión debe tener un valor tipo (es decir, no el tipo de fondo).

El type of a statement es el tipo de unidad, pero debido a la unidad de teorema de detención es ficción así que digamos bottom type.


Void no es precisamente el tipo de fondo (que no es el subtipo de todos los tipos posibles). Existe en idiomas que don't have a completely sound type system.Eso puede sonar como una declaración esnob, pero la integridad such as variance annotations es crítica para escribir software extensible.

Veamos qué tiene que decir Wikipedia sobre este asunto.

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

In computer programming a statement is the smallest standalone element of an imperative programming language that expresses some action to be carried out.

Many languages (e.g. C) make a distinction between statements and definitions, with a statement only containing executable code and a definition declaring an identifier, while an expression evaluates to a value only.

  0

No redefina los términos técnicos generales 'expresión' y 'declaración'. Mis comentarios y respuestas son correctos para C#. Si 'f();' tiene el tipo void y no tiene efectos secundarios, entonces es un NOOP. Un buen compilador no permitirá los NOOP. Si 'f();' no tiene efectos secundarios y no se usa su valor de retorno, también es un NOOP. Respondí la pregunta w.r.t. DO#. Respondí con una oración precisa. Esa oración es correcta para C#. Luego, expliqué sobre lo que significa el vacío en C# en términos de teoría de tipos. La teoría de tipos se aplica a C#. 10 dic. 112011-12-10 06:33:44

  0

Vea mis comentarios bajo la respuesta de Mark Cidade, que explican por qué una declaración a menudo es en realidad el tipo de letra de abajo y no el tipo de unidad. Decir que una declaración "hace algo" es increíblemente imprecisa, ya que una expresión también "hace algo": se evalúa como un valor. Sé lo que las personas intentan decir, simplemente no eligen palabras y definiciones precisas. La palabra precisa es (una declaración no debe ser) referencialmente transparente (es decir, imperativa). Eso es más preciso que "hace algo" o "efecto secundario". 10 dic. 112011-12-10 06:35:33

+4

Una afirmación no necesita tener un efecto secundario. Por ejemplo, en python 'pass' es una declaración. No es operativo, y no evalúa nada. 10 dic. 112011-12-10 10:01:19

  0

@MatthewSchinckel Si no tiene un efecto secundario, entonces es una expresión o un NOOP. Un NOOP no hace nada, por lo que puede eliminarse del programa. Es un proceso simple de eliminación lógica. Si no define el enunciado como que requiere un efecto secundario, el enunciado es lo mismo que expresión. ¿Qué otro atributo usarías para diferenciar una declaración de una expresión? 10 dic. 112011-12-10 12:05:13

+7

-1 Esto está mal. Una declaración no * tiene * para tener un efecto secundario. Consulte la sección 1.5 de la [Especificación del lenguaje C#] (http://msdn.microsoft.com/en-us/library/ms228593.aspx). No solo ** no ** especifica que las declaraciones * deben * tener efectos secundarios, sino que también enumera varias declaraciones que pueden tener ** efectos secundarios *. 10 dic. 112011-12-10 19:35:44

+2

@NullUserException Leí esa sección. Declaraciones de Declaración, Expresión, Selección, Iteración y Salto pueden crear efectos secundarios. Pero si hay una expresión RT, entonces no es una declaración. Me doy cuenta de que la especificación equivale a expresiones con declaraciones, pero esta pregunta pregunta por la diferencia entre ellas.Entonces, o la pregunta no tiene respuesta, o estás tomando la especificación C# demasiado literalmente. La respuesta más votado es intentar decir lo que hice. Pero "hace algo" no tiene sentido. "efecto secundario" es la forma significativa de decir "hace algo". Tenemos que pensar, no solo regurgitar. 12 dic. 112011-12-12 06:34:16

+13

@ShelbyMooreIII Tienes razón. La documentación oficial está ** mal **. Marc Gravell y Jon Skeet, quienes son posiblemente los que más respetan los carteles de C# activos en SO fuera de Eric Lippert, están ** equivocados **. Yo y todos los demás que te votaron negativamente y dejamos comentarios que explican nuestra posición están ** equivocados **. Tienes razón. Claramente eres la única persona que sabe de lo que están hablando, ya que eres mucho más inteligente que todo el resto de SO. 12 dic. 112011-12-12 07:19:58

+1

@NullUserException Tienen mucha razón sobre la forma en que la mayoría de los usuarios de C# desean comprender los conceptos. Pero les estoy mostrando una gran perspectiva, quizás no hayan sido expuestos. Entiendo [disonancia cognitiva] (http://www.youtube.com/watch?v=YW6mJOqRDI4#t=6987s), lo sufro también. Hice suposiciones similares más estrechas en el pasado. Solía ​​venir del mundo de C/C++/C#, así que sé lo difícil que fue para mí adaptarme a Haskell, Scala y conceptos más generales. Pero estoy dispuesto a aceptar que mis respuestas no son tan útiles como otras en este contexto. Entonces digamos que es ** correcto ** en cierto sentido 12 dic. 112011-12-12 07:27:22

+3

Conocer la definición precisa de conceptos como enunciado, expresión, conversión, conversión, etc. tiene un impacto cero en el 99.999% de las tareas diarias de programación. Piénsalo*. Además: [la mayoría de las personas no se preocupan por Haskell y Scala.] (Http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html) 12 dic. 112011-12-12 07:30:58

+1

@NullUserException Pero si puedo, por favor piense sobre esto. Si la expresión es distinta de la declaración, ¿cuál es el atributo distinto? "Hace algo"? Definir "algo". Creo que encontrará que mi respuesta es la misma que la respuesta más votado. Acabo de definir qué es "algo". La especificación de C# solo es literal como una conveniencia. No se espera que piense que las expresiones no son distintas de las declaraciones. O cree que las expresiones son solo un subconjunto de declaraciones, pero eso no funciona. ¿Debo mostrar cómo eso no puede funcionar? 12 dic. 112011-12-12 07:35:28

+2

@ShelbyMooreIII Nunca dije que las expresiones son solo un subconjunto de declaraciones. Pero de nuevo, eso es irrelevante. 12 dic. 112011-12-12 07:38:33

  0

@NullUserException De hecho, Haskell es obtuso y debido a la evaluación perezosa tiene indeterminismo de espacio y tiempo, lo que hace que sea muy difícil de depurar. Además, no tiene herencia virtual. Scala arregla muchas de estas cosas y es el lenguaje de más rápido crecimiento en este momento, pero aún es una adopción muy pequeña. Scala es bastante bueno, pero su sintaxis tiene demasiadas variantes, p. 9 formas de escribir una función y otros problemas. También está ligado a las bibliotecas de Java en su mayor parte por ahora. ¿Funciona C# en Android? Está bien que no pienses que las expresiones son subconjunto de enunciados. ¿Qué significa "hace algo"? Que es algo"? 12 dic. 112011-12-12 07:39:49

+1

permítanos [continuar esta discusión en el chat] (http://chat.stackoverflow.com/rooms/5762/discussion-between-nulluserexception-and-shelby-moore-iii) 12 dic. 112011-12-12 07:44:17

+2

@NullUserException Respeto a esos muchachos. Nunca podría responder todas las preguntas que hacen. Su conocimiento es mucho más amplio que el mío. Son realmente profundos y actuales con la codificación en esas plataformas. Probablemente también tengan mucha más energía que yo. Y probablemente sean igual de inteligentes, si no más inteligentes que yo. Quiero que quede claro que no es un tema de respeto. Solo quiero que las personas sean de mente abierta y den tiempo a las cosas. A veces las cosas no son lo que parecen ser. 12 dic. 112011-12-12 07:44:35

+2

La [especificación del lenguaje C#] (http://msdn.microsoft.com/en-us/library/ms228593.aspx) * no * requiere que las declaraciones tengan efectos secundarios. Las declaraciones vacías son legales (sección 8.3), independientemente de si el compilador las deja o no. De hecho, dado que lidiar con declaraciones no opcionales se deja a la altura de la implementación, incluso los NOOP pueden afectar potencialmente el código compilado y el rendimiento del programa. Entonces tu respuesta es académica y prácticamente incorrecta. 13 dic. 122012-12-13 21:46:53

+1

Si los NOOP se compilan o no es irrelevante de todos modos. '{return 5; } 'es una afirmación que no produce efectos secundarios, a menos que se deba redefinir el" efecto secundario "para incluir la devolución de un solo valor. No solo esto no es el significado aceptado (incluso en Haskell), sino que solo tiene sentido en un sentido completamente académico. '() => 5' y'() => {return 5; } 'tienen el mismo resultado una vez evaluado, pero uno es una expresión y el otro no. 13 dic. 122012-12-13 21:53:58

+1

@JustinMorgan en el nivel abstracto del diseño del lenguaje, un 'retorno' es simplemente una expresión que es el valor de la función adjunta o es ambas cosas y un atajo para escribir una estructura 'if-else' más compleja de modo que todas las rutas de código se resuelven en un valor.Que los lenguajes no funcionales obtengan este error no es sorprendente. Por ejemplo, en Scala el 'return' puede omitirse y puede escribir' 5' al final de la ruta del código para la función. 15 ene. 132013-01-15 17:12:41

  0

@MatthewSchinckel A [pass statement] (http://www.programiz.com/python-programming/pass -statement) definitivamente tiene efectos secundarios. Hace que el intérprete gaste ciclos de CPU para eludirlo. También está pensado como marcador de posición para una función que agregará efectos secundarios en lugar de la declaración 'pass', por lo que es una forma de indicar futuros efectos colaterales. 17 ago. 152015-08-17 17:44:07


2

Declaraciones -> Instrucciones a seguir secuencialmente
Expresiones -> Evaluación que devuelve un valor

declaraciones son básicamente como pasos o instrucciones de un algoritmo, el resultado de la ejecución de una declaración es la actualización del puntero de instrucción (llamado en ensamblador)

Las expresiones no implican orden de ejecución al principio si ght, su propósito es evaluar y devolver un valor. En los lenguajes de programación imperativos, la evaluación de una expresión tiene un orden, pero es solo por el modelo imperativo, pero no es su esencia.

Ejemplos de Declaraciones:

for 
goto 
return 
if 

(todos ellos implican el avance de la línea (declaración) de ejecución a otra línea)

ejemplo de expresiones:

2+2 

(no implica la idea de ejecución, sino de la evaluación)

  0

¿Qué pasa con los efectos secundarios? 23 sep. 122012-09-23 03:20:45


0

Statement,

Una declaración es un bloque de construcción procedural a partir del cual se construyen todos los programas de C#. Una declaración puede declarar una variable local o constante, llamar a un método, crear un objeto o asignar un valor a una variable, propiedad o campo.

Una serie de instrucciones rodeadas de llaves forman un bloque de código. Un cuerpo de método es un ejemplo de un bloque de código.

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

Las declaraciones en C# a menudo contienen expresiones. Una expresión en C# es un fragmento de código que contiene un valor literal, un nombre simple o un operador y sus operandos.

Expression,

Una expresión es un fragmento de código que puede ser evaluada a un solo valor, objeto, el método o espacio de nombres. Los dos tipos más simples de expresiones son literales y nombres simples. Un literal es un valor constante que no tiene nombre.

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

Tanto i y s son simples nombres que identifican las variables locales. Cuando esas variables se usan en una expresión, el valor de la variable se recupera y se usa para la expresión.

  0

Prefiero escribir 'if (number> = 0) return true; else return false; 'o incluso mejor' bool? IsPositive (número int) {if (número> 0) devuelve verdadero; else si (número <0) devuelve falso; else return null;} ':) 28 jul. 132013-07-28 20:18:10


1

Prefiero el significado de statement en el sentido lógico formal de la palabra. Es uno que cambia el estado de una o más de las variables en el cálculo, permitiendo que se haga una declaración verdadera o falsa sobre su valor (es).

Supongo que siempre habrá confusión en el mundo de la informática y la ciencia en general cuando se introducen nuevas terminologías o palabras, las palabras existentes son 'reutilizadas' o los usuarios ignoran la terminología existente, establecida o 'propia' de lo que están describiendo


0

Aquí está el resumen de una de las respuestas más simples que encontré.

respondió en primer lugar por Anders Kaseorg

Una declaración es una línea completa de código que realiza alguna acción, mientras que una expresión es cualquier sección del código que se evalúa como un valor.

Las expresiones se pueden combinar "horizontalmente" en expresiones más grandes utilizando operadores, mientras que las declaraciones solo se pueden combinar "verticalmente" escribiendo una tras otra, o con construcciones de bloques.

Cada expresión se puede usar como una declaración (cuyo efecto es evaluar la expresión e ignorar el valor resultante), pero la mayoría de las declaraciones no se pueden usar como expresiones.

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


1

No estoy realmente satisfecho con cualquiera de las respuestas aquí. Miré la gramática para C++ (ISO 2008). Sin embargo, tal vez por el bien de la didáctica y la programación, las respuestas podrían ser suficientes para distinguir los dos elementos (sin embargo, la realidad parece más complicada).

Una instrucción consta de cero o más expresiones, pero también puede haber otros conceptos de lenguaje. Esta es la forma más extendida de Backus Naur para la gramática (extracto de declaración):

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

Podemos ver los otros conceptos que se consideran declaraciones en C++.

  • expresión comunicado s es autoexplicativo (una declaración puede constar de cero o más expresiones, leer la gramática cuidadosamente, es complicado)
  • case por ejemplo, es un marcado con declaración
  • selección declaración- s son ifif/else, case
  • iteración-declaración s son while, do...while, for (...)
  • salto-declaración s son break, continue, return (puede volver expresión), goto
  • declaración-declaración es el conjunto de declaraciones
  • try-block es una declaración que representa try/catch bloques
  • yt aquí podría ser un poco más abajo de la gramática

Este es un extracto que muestra la parte expresiones:

expression: 
     assignment-expression 
     expression "," assignment-expression 
assignment-expression: 
     conditional-expression 
     logical-or-expression assignment-operator initializer-clause 
     throw-expression 
  • expresiones son o contienen a menudo asignaciones de
  • condicional expresión (suena engañosa) se refiere al uso de los operadores (+, -, *, /, &, |, &&, ||, ...)
  • throw-expression - uh? la cláusula throw es una expresión demasiado

-3

mejorar y validar mi respuesta anterior, las definiciones de los términos del lenguaje de programación deben ser explicados a partir de la teoría de tipos de informática en su caso.

Una expresión tiene un tipo distinto del tipo Inferior, es decir, tiene un valor. Una declaración tiene el tipo de Unidad o Inferior.

De esto se deduce que una declaración solo puede tener algún efecto en un programa cuando crea un efecto secundario, porque no puede devolver un valor o solo devuelve el valor del tipo de Unidad que es no asignable (en algunos idiomas como C void) o (como en Scala) se pueden almacenar para una evaluación retrasada de la declaración.

Obviamente un @pragma o un /*comment*/ no tienen ningún tipo y por lo tanto se diferencian de las declaraciones. Por lo tanto, el único tipo de enunciado que no tendría efectos secundarios sería una no operación. La no operación solo es útil como marcador de posición para futuros efectos secundarios. Cualquier otra acción debido a una declaración sería un efecto secundario. De nuevo, una sugerencia del compilador, p. @pragma, no es una declaración porque no tiene ningún tipo.