Tengo este profesor, es bastante inteligente (a veces, jaja), dijo que los buenos programadores intentan usar whilebucles en lugar de forbucles. La razón que dio para esto es porque los whilebucles se pueden probar, ya que en uno se puede explicar completamente lo que sucede en un whilebucle, mientras que no se puede hacer eso para un forbucle. También dijo algo sobre los programadores de la NASA que solo usan whilebucles y no se les permite hacer forbucles debido a esto.
Me cuesta mucho entender esto, para ambos bucles uno puede explicar cómo funcionan en detalle, ¿verdad? para ambos siempre sabrás lo que va a pasar?
¿Alguien puede explicarme por qué whilese pueden probar los bucles (y por eso, podría ser mejor que los forbucles, en algunos casos al menos).
Aunque esto todavía no dice nada sobre la diferencia entre while y for loops.

formáswhilesimplemente no tiene sentido. Puede haber uno, pero este no lo es.for (init; test; step) { body }tiene un desugaring trivialwhile:{init; while (test) { step; body }}.Respuestas:
En pocas palabras : lo que su maestro probablemente quiso decir es que la semántica de
whilees más o menos la misma en la mayoría de los idiomas, mientras que la semántica deforpuede cambiar considerablemente (vea la discusión a continuación). Por lo tanto, las pruebas independientes del lenguaje abstracto son más confiables con awhile, pero se debe tener cuidado de que una prueba con unforbucle no coincida con la semántica delforbucle en muchos idiomas.Su pregunta no es lo suficientemente precisa (aunque puede que no sea su culpa).
El punto es que, afaik, no hay un estándar oficial, compatible con ISO, o una definición de referencia
forywhilebucles aceptados oficialmente . La definición depende del lenguaje de programación.Por lo tanto, no puede hacer ninguna declaración general con respecto a su equivalencia antes de haber definido exactamente lo que cada uno puede hacer. Me refiero a eso más precisamente, ya que es uno de los principales argumentos utilizados en otras respuestas (y la discusión será útil en lo que sigue).
Sobre intertranslatabilidad de
forywhilebuclesResumen : depende del lenguaje de programación, pero siempre es posible siempre que pueda tener un bucle infinito y una forma de salir de él.
Pero puede hacer tal declaración para un lenguaje de programación específico, y la respuesta dependerá de las características del lenguaje.
Eso también significa que no hay pruebas generales, sino solo una para cada lenguaje de programación.
Una cosa que generalmente es cierta es que un
whilebucle generalmente puede imitar unforbucle, porque el bucle while puede hacer la prueba de condición de salida del bucle for, realizar la inicialización de la variable de control con una asignación antes de ingresar al bucle y hacer el incremento al final del cuerpo del bucle, para quese convierte
Esto funciona más o menos para la mayoría de los idiomas, pero no es tan obvio como parece, y puede haber muchos "detalles" de los que preocuparse.
Por ejemplo, en muchos idiomas, el
forbucle evalúa 3 argumentos (valor inicial, incremento y valor final) como argumentos estrictos , evaluados una vez antes de ingresar al bucle, mientras que otros tomarán luego como argumentos thunk para ser reevaluados en cada turno, o posiblemente como argumento perezoso para ser evaluado solo cuando sea necesario.Otro punto puede ser que la variable de incremento puede ser local al
forbucle, o tener que ser una variable local de la función donde aparece el bucle.Dependiendo de tales problemas, la traducción de a
fora awhilepuede variar ampliamente, aunque generalmente es posible lograrlo.Lo mismo vale para lo contrario, traduciendo a
whileen unforbucle.El primer problema es que un
whilebucle siempre reevaluará la condición de salida en cada vuelta. Pero algunosforbucles no proporcionan una condición que se reevalúa en cada turno, aparte de la comparación de la variable de control con algún valor fijo calculado en la entrada del bucle. Entonces la traducción no es posible a menos que exista algún otro medio para salirse del ciclo en algunas condiciones arbitrarias.Esto se puede lograr con varios dispositivos, generalmente comenzando con una declaración condicional que pruebe la condición, seguida de un salto implementado, según esté disponible, por una declaración de salida del ciclo, una declaración de retorno (después de encapsular el ciclo en una función), una declaración goto o un aumento de excepción.
En otras palabras, nuevamente depende mucho de los idiomas, y posiblemente de las características sutiles de los idiomas.
Esto dice, como respondió @milleniumbug , la intertranslación es fácil en el lenguaje C, porque un
forlopp es esencialmente unwhilebucle más algo extra para una variable de control incrementada.Pero esto no se aplica necesariamente a otros idiomas, y muy probablemente no de la misma manera.
Dicho esto, generalmente se supone que los lenguajes de programación tienen poder de Turing con solo uno de estos bucles, ya que todo lo que necesita es un bucle infinito. Entonces, siempre y cuando tenga alguna forma de bucle para siempre, y posiblemente decida detenerse, está bastante seguro de que puede imitar cualquier otra construcción ... pero no necesariamente fácil.
En cuanto a las pruebas
Resumen : No conozco ninguna razón para afirmar que las pruebas deberían ser significativamente más difíciles con una u otra (a menos que alguna característica extraña del lenguaje).
Probablemente hay un malentendido, o tu maestro tenía su mente en otra cosa.
La semántica formal se puede definir para los diversos tipos de bucles definidos en los lenguajes de programación, y luego usarse para probar propiedades.
Puede ser, nuevamente según el idioma, que la realización de pruebas formales con respecto a los programas puede ser más compleja en algunos casos. Pero eso depende del idioma.
No puedo imaginar una razón por la cual las pruebas deberían ser significativamente más difíciles con una construcción más que con la otra. El
forciclo puede ser más complejo ya que puede ofrecer, como en C, todo lo que se hace con unwhileplus más. Pero si lo hicieras con unwhile, tendrías que agregar los extras en alguna otra forma.Podría usar el argumento general formal de intertranslatabilidad, siempre y cuando exista la posibilidad de un solo bucle infinito. Sin embargo, me abstendré de hacer eso, ya que las construcciones involucradas no son nada con lo que quieras lidiar en una prueba, y claramente sería una declaración injusta, al menos en la práctica.
Sin embargo, siguiendo la discusión anterior, hemos visto que las dificultades para la intertranslatabilidad provienen de la gran variabilidad del
forciclo de un idioma a otro. De ahí la siguiente conclusión, que probablemente sea la respuesta correcta:Una posibilidad para comprender la afirmación de su maestro es que la semántica del
whilebucle es prácticamente la misma en todos los lenguajes de programación, mientras que la sintaxis y la semántica delforbucle pueden variar significativamente de un idioma a otro. Por lowhilefortanto, es posible hacer pruebas "abstractas" generales con bucles que tienen una semántica independiente del lenguaje en buena medida, mientras que esto no es posible para el bucle que tiene una sintaxis y una semántica que cambian demasiado de un idioma a otro. Pero esto no se aplica dentro de un lenguaje dado, cuando la semántica de ambos se define con precisión.Mi mejor sugerencia es que le preguntes a tu maestro qué quiso decir exactamente y si puede darte un ejemplo. Frases o malentendidos es un evento común.
fuente
En el lenguaje C puede reescribir cada
forciclo a unwhileciclo equivalente y viceversa.while -> fortransformación:Volver a escribir
a
for -> whiletransformación:Esto es un poco más complicado, especialmente si tiene una
continuedeclaración en su ciclo.Volver a escribir:
a:
pero reemplace cada
continue;declaración congoto next_label;declaración. Siconditiones una instrucción nula, reemplácela contrue.Como puede ver, en el lenguaje C ninguno de los dos es más "demostrable" (lo que sea que eso signifique) que el otro, ya que incluso si uno de los bucles lo fuera, podría reescribirlo en términos de otro bucle.
Ahora, existen otros idiomas donde esta
while <-> forequivalencia no existe. Por ejemplo, en Pascal, puede asumir más sobre elforciclo. Esto significa que no puede expresar cada concepto al escribir unforbucle, pero puede probar más sobre el flujo del código:Aquí,
nse guarda al comienzo del ciclo, por lo que los cambiosnno influyen en el recuento de iteraciones, y no se puede modificarien el cuerpo del ciclo. Esto significa que puede probar trivialmente que este ciclo finalmente terminará (comones finito, y no puede modificarloi).fuente
goto. Si se agregan banderas, todos los demás bucles se pueden emular usando un solo "while (1) ..." alrededor de una función que se ejecuta hasta un "retorno"; si uno agrega "goto", todos los otros bucles se pueden emular usando eso.En la lógica de Floyd-Hoare , el sistema formal más común para razonar sobre la corrección de los programas de computadora, existe la regla while .
En palabras, si tiene una cláusula de protección (la expresión entre paréntesis en el
while()), una función variante (una expresión con valores discretos que se puede mostrar que disminuye monotónicamente cada vez que se ejecuta el bucle, y siempre es positiva), y un bucle invariante (una declaración lógica que siempre es verdadera antes y después de cada vez que se ejecuta el ciclo), puede probar que el ciclo while finalizará (porque la función variante no puede seguir disminuyendo) y que eventualmente la cláusula de protección será falsa y el ciclo invariante sea cierto.La lógica de Floyd-Hoare no tiene reglas para los
forbucles o cualquier construcción que los lenguajes reales puedan tener.Sin embargo, como explican otras respuestas, los bucles for siempre se pueden escribir en términos de bucles while. Eso significa que se puede razonar sobre ellos, solo requiere un poco más de trabajo.
Si su maestro tenía cursos en la universidad donde tenía que proporcionar pruebas de corrección de sus programas, probablemente escribía programas utilizando solo bucles while. Sé que lo hice. Y una vez que estás acostumbrado a pensar en términos de guardias y funciones variantes e invariantes de bucle, parecen muy naturales. El uso excesivo de los bucles es un hábito que ves con los graduados de CS, tuve que aprender a dejar de hacerlo en mis primeros meses como desarrollador profesional.
En algún momento, su maestro recordaba todo esto como "buenos programadores usan bucles while", mientras que lo que realmente sucede es más como "algunos graduados de CS convierten sus hábitos de prueba de corrección en hábitos prácticos de programación".
fuente
forciclo, que no tiene una definición fija y es más complejo, sin ser formalmente necesario.En realidad, en cierto sentido, todo lo contrario es cierto.
Un lenguaje con solo
forbucles no es completo de Turing, solo puede calcular las funciones primitivas-recursivas, no todas las funciones computables de Turing. Dado que todos los cálculos en un lenguaje con soloforbucles siempre terminan, el problema de detención y todos los demás problemas de decidibilidad basados en él, simplemente no surgen, por lo que es posible decidir mecánicamente muchas más propiedades estáticas de los programas que en un lenguaje conwhilebuclesOTOH, un lenguaje con solo números naturales, una sola variable y
while-loops es Turing-complete, por lo que no es posible decidir incluso las propiedades más simples: ¿este programa devolverá un resultado?fuente
forlenguaje único puede producir unwhilecomportamiento equivalente al disminuir la variable de bucle (suponiendo que el lenguaje lo permita) durante las iteraciones que no se supone que den como resultado una terminación. (Por ejemplofor n in 1 to 2 { if condition then n := n-1 })Me gustaría decir que, en realidad, no hay diferencia. Su pregunta es irrelevante. Puede ser que tu maestro haya querido usar while-loop cuando no. de iteraciones no se conoce de antemano. En muchos casos necesitamos usar un ciclo while para extraer dígitos de un no. cuando el usuario ingresa el no. que puede ser de cualquier longitud. Técnicamente hablando, la similitud entre el bucle for & while es que ambos son bucles controlados por entrada en los que la (expresión / condición de prueba) se evalúa antes de ingresar al cuerpo del bucle. Esta es la distinción entre los bucles while y do-while.
fuente
Probablemente proviene de la programación inicial de C donde, según las normas actuales, los bucles fueron ampliamente abusados y mal utilizados, especialmente la modificación condicional. A medida que los programadores comenzaron a comprender el efecto que tenían ciertos estilos de programación, el abuso y el mal uso de los condicionales de bucle cayeron en desgracia, y la declaración, aunque (posiblemente) una vez válida, ya no tiene ninguna verdad.
La declaración no tiene absolutamente ninguna verdad si observa únicamente la definición y la sintaxis del lenguaje e ignora cómo se estaba utilizando.
Sin embargo, la declaración en sí ofrece una valiosa lección a cualquiera que quiera entenderla, su historia y por qué ya no se considera verdadera. - ¿Cuál es la expresión sobre el aprendizaje, los errores y repetirlos .....
fuente
¡Tu profesor tiene razón!
La razón es la siguiente es válida C
¡No puede garantizar que las variables de condición no hayan sido manipuladas!
fuente
whilebucles funcionen mejor aquí?whilebucles, ¿puede garantizar que la variable de condición no haya sido alterada? De hecho, la manipulación de la variable de condición es la única forma de salir de unwhilebucle. Por lo general, me abstengo de votar negativamente, pero por esta respuesta, haré una excepción.