¿Por qué se intercambian los puntos y comas y comas en los bucles?

49

En muchos idiomas (una lista amplia, de C a JavaScript):

  • comas , argumentos separados (por ejemplo, func(a, b, c) ), mientras que
  • punto y coma ; instrucciones secuenciales separadas (por ejemplo, instruction1; instruction2; instruction3 ).

Entonces, ¿por qué se invierte esta asignación en los mismos idiomas para para bucles ?

for ( init1, init2; condition; inc1, inc2 )
{
    instruction1;
    instruction2;
}

en lugar de (lo que me parece más natural)

for ( init1; init2, condition, inc1; inc2 )
{
    instruction1;
    instruction2;
}

?

Claro, for no es (generalmente) una función, pero los argumentos (es decir, init , condition , increment ) se comportan más como argumentos de una función que como una secuencia de instrucciones.

¿Se debe a razones históricas / a una convención, o hay una buena razón para el intercambio de , y ; en bucles?

    
pregunta Piotr Migdal 21.04.2013 - 23:16

7 respuestas

18
  

Entonces, ¿por qué en los mismos idiomas, tal asignación se invierte para los bucles?

Técnicamente, la asignación no se "revierte".

  • Las cosas separadas por comas no son parámetros. En (al menos) C ++ y Java, pueden ser declaraciones, por lo que ni siquiera son expresiones.
  • Las cosas separadas por punto y coma tampoco son declaraciones (simples).

En realidad, lo que tenemos aquí es un contexto sintáctico diferente donde los mismos símbolos se usan de manera diferente. No estamos comparando "Me gusta" con "me gusta", por lo que no hay mapeo ni argumento sólido para un mapeo consistente basado en la consistencia semántica.

Entonces, ¿por qué no hacerlo al revés?

Bueno, creo que las razones provienen del significado "natural" de , y ; . En el idioma escrito en inglés, un punto y coma es una ruptura "más fuerte" que una coma, y el glifo para el punto y coma es más visible que una coma. Esas dos cosas se combinan para hacer que los arreglos actuales parezcan (para mí) más naturales.

Pero la única forma de saber con certeza por qué se hizo la elección de sintaxis sería si los diseñadores de C pudieran decirnos lo que pensaban en ~ 1970. Dudo que tengan una memoria clara de las decisiones técnicas tomadas tan atrás en el tiempo.

  

Se debe a razones históricas / una convención

No tengo conocimiento de ningún lenguaje antes de C que usara una sintaxis tipo C para los bucles "for":

  • Donal Fellows señala que BCPL y B no tenían una construcción equivalente.

  • Los equivalentes de FORTRAN, COBOL y Algol-60 (y Pascal) eran menos expresivos y tenían sintaxis que no se parecían a C "para" sintaxis.

Pero los lenguajes como C, C ++ y Java que vinieron después de C claramente toman prestada su sintaxis "for" de C.

    
respondido por el Stephen C 22.04.2013 - 01:02
60

Escribimos bucles como:

 for(x = 0; x < 10; x++)

El idioma se podría haber definido para que los bucles parecieran:

 for(x = 0, x < 10, x++)

Sin embargo, piense en el mismo bucle implementado utilizando un bucle while:

 x = 0;
 while(x < 10)
 {
     x++;
 }

Observe que las declaraciones x=0 y x++ son declaraciones, terminadas por punto y coma. No son expresiones como las que tendrías en una llamada de función. Los puntos y comas se usan para separar sentencias, y como dos de los tres elementos en un bucle for son sentencias, eso es lo que se usa allí. Un bucle for es solo un atajo para ese bucle while.

Además, los argumentos no actúan realmente como argumentos para una función. El segundo y el tercero son evaluados repetidamente. Es cierto que no son una secuencia, pero tampoco son argumentos de función.

Además, el hecho de que pueda usar comas para tener varias declaraciones en el bucle for es realmente algo que puede hacer fuera del bucle for.

x = 0, y= 3;

es una declaración perfectamente válida incluso fuera de un bucle for. Aunque no conozco ningún uso práctico fuera del bucle for. Pero el punto es que las comas siempre subdividen declaraciones; No es una característica especial del bucle for.

    
respondido por el Winston Ewert 21.04.2013 - 23:38
15

En C y C ++, este es el operador de coma, no solo una coma.

La gramática para un bucle for es algo así como

for ([pre-expression]; [terminate-condition]; [increment-expression]) body-expression

En el caso de tu pregunta:

pre-expression -> init1, init2
terminate-condition -> condition
increment-expression -> inc1, inc2

Tenga en cuenta que el operador de coma le permite realizar múltiples acciones en una declaración (como lo ve el compilador). Si su sugerencia fuera implementada, habría una ambigüedad en la gramática con respecto a cuándo el programador tenía la intención de escribir una declaración del operador de coma o un separador.

En resumen, ; significa el final de una declaración. Un bucle for es una palabra clave seguida de una lista de instrucciones opcionales rodeadas por () . La declaración del operador de coma permite el uso de , en una sola declaración.

    
respondido por el James 22.04.2013 - 01:44
8

No hay inversión conceptual.

Los puntos y comas en C representan más divisiones importantes que comas. Ellos separan declaraciones y declaraciones.

Las principales divisiones en el bucle for es que hay tres expresiones (o una declaración y dos expresiones) y un cuerpo.

Las comas que ves en C para bucles no son parte de la sintaxis del bucle for específicamente. Solo son manifestaciones del operador de coma.

Las comas son separadores importantes entre los argumentos en las llamadas de función y entre los parámetros en las declaraciones de función, pero no se utilizan puntos y coma. El bucle for es una sintaxis especial; no tiene nada que ver con funciones o llamadas a funciones.

    
respondido por el Kaz 22.04.2013 - 03:45
2

Tal vez esto sea algo específico para C / C ++, pero publico esta respuesta, porque la sintaxis de los lagnuages que describiste está influenciada principalmente por la C-Sintaxis.

Además de que las preguntas respondidas anteriormente son verdaderas, desde un punto de vista técnico, eso también se debe a que en C (y C ++) la coma es en realidad un operador , que puede incluso sobrecarga . El uso de un operador de punto y coma ( operator;() ) posiblemente dificultaría la escritura de compiladores, ya que el punto y coma es el terminador de la expresión axiomática.

Lo que hace que esta intersección sea el hecho es que la coma se usa ampliamente como separador en todo el idioma. Parece que el operador de coma es una excepción, que se usa principalmente para obtener for -loops con varias condiciones funcionando, así que, ¿cuál es el problema?

De hecho, operator, está diseñado para hacer lo mismo que en las definiciones, listas de argumentos, etc.: se ha creado para separar expresiones, algo que el constructo sintáctico , no puede hacer. Solo puede separar lo que se ha definido en la norma.

Sin embargo, el punto y coma no se separa, termina . Y esto es también lo que nos lleva de nuevo a la pregunta original:

for (int a = 0, float b = 0.0f; a < 100 && b < 100.0f; a++, b += 1.0f)
    printf("%d: %f", a, b);

La coma separa las expresiones en las tres partes del bucle, mientras que el punto y coma termina una parte (inicialización, condición o idea) de la definición del bucle.

Es posible que los lenguajes de programación más nuevos (como C #) no permitan la sobrecarga del operador de coma, pero es muy probable que mantengan la sintaxis, porque cambiarla se siente de alguna manera poco natural.

    
respondido por el Aschratt 22.04.2013 - 12:38
0

Para mí se utilizan un significado menos similar a su sentido lingüístico. Las comas se usan con listas y punto y coma con partes más separadas.

En func(a, b, c) tenemos una lista de argumentos.

instruction1; instruction2; instruction3 es quizás una lista pero una lista de instrucciones separadas e independientes.

Mientras que en for ( init1, init2; condition; inc1, inc2 ) tenemos tres partes separadas: una lista de inicializaciones, una condición y una lista de expresiones de incremento.

    
respondido por el ludwika 22.04.2013 - 01:26
0

La forma más fácil de verlo es la siguiente:

for(x = 0; x < 10; x++)

es:

for(
x = 0;
x < 10;
x++
)

En otras palabras, esos x = 0 thingy son en realidad una declaración / instrucciones en lugar de un parámetro. Usted inserta una declaración allí. De ahí que estén separados por punto y coma.

De hecho, no hay forma de que estén separados por comas. ¿Cuándo es la última vez que inserta cosas como x < 10 como parámetro? Hágalo si desea computar x < 10 una vez e inserte el resultado de esa operación como parámetro. Entonces, en el mundo de las comas, deberías poner x < 10 si quieres pasar el valor de x < 0 a una función.

Aquí usted especifica que el programa debe verificar x < 10 cada vez que se pasa el bucle. Así que eso es una instrucción.

x ++ es definitivamente otra instrucción.

Esas son todas las instrucciones. Así que están separados por punto y coma.

    
respondido por el user4951 22.04.2013 - 06:46

Lea otras preguntas en las etiquetas