Pocos programas siguen exactamente una ruta de control, con cada instrucción claramente indicada. Para programar con eficacia, es necesario comprender cómo cambiar los pasos que sigue un programa en respuesta a la entrada del usuario o a otras condiciones, cómo realizar múltiples pasos utilizando una pequeña cantidad de código y cómo un programa puede mostrar una comprensión inicial de la lógica. Las construcciones de C conocidas como condicionales y bucles proporcionan esta capacidad.
A partir de ahora, es necesario entender las palabrasterrón (de tierra)Lo que suele significar. Un bloque es un conjunto de sentencias de código asociadas y destinadas a ejecutarse como una unidad. En C, el comienzo de un bloque de código se denota por { (rizado a la izquierda) y el final del bloque se denota por }. No es necesario colocar un punto y coma después del final de un bloque. Los bloques pueden estar vacíos, como en {}. Los bloques también pueden estar anidados; es decir, pueden existir bloques de código dentro de bloques más grandes.
requisito previo
Es posible que no haya programas significativos escritos en los que los ordenadores no puedan demostrar habilidades básicas de toma de decisiones. De hecho, se puede afirmar que no existe ninguna actividad humana significativa en la que no se produzca algún tipo de toma de decisiones, instintiva o no. Por ejemplo, cuando uno conduce un coche y se acerca a un semáforo, no piensa: "Voy a pasar por el cruce". Más exactamente, uno pensaría: "Me detendré si el semáforo está en rojo, me detendré si el semáforo está en verde; y me detendré si recorro cierta distancia de la intersección a cierta velocidad, en amarillo". Este tipo de procesos pueden modelarse en C mediante condicionales.
Las sentencias condicionales son sentencias que ordenan al ordenador ejecutar un bloque de código o cambiar ciertos datos sólo cuando se cumplen determinadas condiciones. La condicional más común es la sentencia If-Else; las expresiones condicionales y las sentencias Switch-Case se utilizan a menudo como métodos más concisos.
Antes de poder entender las sentencias condicionales, primero hay que entender cómo se expresan las relaciones lógicas en C. C trata la lógica como aritmética. El valor 0 (cero) significa falso.Todos los demás valoresSi eliges un valor particular para representar true y luego comparas el valor con él, tu código fallará tarde o temprano cuando tu valor asumido (normalmente 1) resulte ser incorrecto. El código escrito por personas que no se sienten cómodas con C a menudo puede determinar el valor de TRUE utilizando #define. [
Dado que la lógica es aritmética en C, los operadores aritméticos y lógicos son uno y el mismo. Sin embargo, hay muchos operadores comúnmente asociados con la lógica:
Relaciones y expresiones equivalentes:
a <b siamenos debentonces 1 , en caso contrario 0. a> b siasuperan abentonces 1 , en caso contrario 0. a <= b siaInferior o igual abentonces 1 , en caso contrario 0. a> = b siamayor o igual quebentonces 1 , en caso contrario 0. a == b siaequivaldría abentonces 1 , en caso contrario 0. a!= b siano igual ≠bSi no lo es, será 1, en caso contrario será 0.
Los nuevos programadores deben prestar especial atención al hecho de que el operador "igual" es ==, no =. Esta es la causa de muchos errores de codificación, y a menudo es un error difícil de detectar porque la expresión(a = b)estableceraequivaldría aby posterior evaluaciónb; pero(a == b)La expresión habitual de la intención comprueba si elaequivaldría ab. Debe tenerse en cuenta que si se confunde = con = =, el compilador no suele llamar la atención. Enunciados como if (c = 20) {}Considerado totalmente válido por la lengua, pero siempre asignado al 20cy se evalúa como verdadero. La técnica sencilla para evitar este error (en muchos casos, no en todos) es poner la constante en primer lugar. Si == está mal escrito = =, esto hará que el compilador emita un error.
Tenga en cuenta que C no tiene un tipo booleano especializado como muchos otros lenguajes. 0 significa error, cualquier otra cosa es verdadero. Así que los siguientes son equivalentes:
si (foo ()) {
//Hacer algo
}
responder cantando
si ¡(foo ()! ! = 0) {
//Hacer algo
}
no recurrente#define TRUE 1responder cantando#define FALSE 0Se utiliza para solucionar la falta de un tipo booleano. Esto es una mala práctica porque hace suposiciones que no son válidas. Es mejor indicar lo que realmente se espera a través de una llamada a función, ya que hay muchas formas diferentes de indicar una condición de error dependiendo de la situación.
si (strstr ("foo", bar) >= 0) {
// La barra contiene "foo".
}
Toma.strstrDevuelve el índice en el que se encontró la subcadena foo, o -1 si no se encontró. tenga en cuenta que esto fallará.TRUEmencionada en el párrafo anterior. Si la omitimos, tampoco se obtiene el resultado esperado >= 0.
También es importante señalar que las expresiones relacionales no se evaluarán como lo harían en un texto matemático. Es decir, la expresiónmiMin < valor < miMax No se evaluará como usted cree. De Matemáticaspor lo que respecta a algoEsto pondrá a pruebamiMinresponder cantandomyMaxinter-estar de serviciosi existe o no. Pero en C, primero elestar de serviciojunto conmiMinCompara este valor con miMáx. Esto produce 0 o 1. Este valor se compara con miMáx. Ejemplo:
int valor = 20 ;
/ * ... * /
si (0 < valor < 10) { / ¡No lo hagas! Siempre se evalúa como "verdadero".
/ *Haz algo* /
}
debido avalores mayor que 0, por lo que la primera comparación produce un valor de 1. Ahora la comparación de 1 es menor que 10, que es verdadero, por lo que se ejecuta la sentencia en if. Esto puede no ser lo que el programador espera. El código apropiado sería
int valor = 20 ;
/ * ... * /
si (0 < valor && valor < 10) { // && significa "y".
/ *Haciendo algo* /
}
expresión lógica
a || b cuandoatal vezbes verdadero (o ambos), el resultado es 1, en caso contrario el resultado es 0. a && b cuandoaresponder cantandobEl resultado es 1 cuando ambos son verdaderos; en caso contrario, el resultado es 0. Un resultado que es verdadero cuandoaes verdadero, el resultado es 0 cuandoaCuando es 0, el resultado es 1.
Este es un ejemplo de una expresión lógica mayor. En la declaración
e = ((&& b)||(c> d));
Si a y b no son cero, o si c es mayor que d, e se pone a 1. En los demás casos, e se pone a 0.
C utiliza la evaluación en cortocircuito de expresiones lógicas. Es decir, una vez que es capaz de determinar la verdad de una expresión lógica, no realiza más evaluaciones. Esto es a menudo útil, como se muestra a continuación:
int miMatriz [12];
....
if (i 3){
....
En el fragmento de código, la comparación de i con 12 se realiza en primer lugar. Si el resultado es 0 (falso), se ejecuta la funciónmeservirá comomiMatrizdel índice está fuera de rango. En este caso, el programa nunca intentará acceder almiMatriz [i].Esto se debe a que se sabe que la verdad de la expresión es falsa. Por lo tanto, si ya se sabe que i es mayor o igual que cero, no tenemos que preocuparnos de intentar acceder a elementos de la matriz fuera de los límites. Algo similar ocurre con las expresiones que implican los operadores or o |.
while (doThis()|| doThat())...
Si doThis() devuelve un valor distinto de cero (verdadero), nunca se llama a doThat().
Sentencia If-Else
If-Else proporciona una forma de ordenar al ordenador que ejecute un bloque de código sólo cuando se cumplan ciertas condiciones.La sintaxis de la construcción If-Else es:
si (/ * condición hasta aquí * / ) {
/ * Este código se ejecutará si la condición es distinta de cero (verdadero) * /
} si no {
/ * Si la condición es 0 (falso), se ejecutará este código / /
}
Si la condición entre paréntesis que sigue a if es distinta de cero (verdadero), la funciónprincipioSe ejecuta el primer bloque; en caso contrario, se ejecuta el segundo bloque.
existeel restocon el siguiente bloque de código es completamente opcional. Si la condición no se mantiene entonces el código no necesita ser ejecutado, déjelo en su lugar.
Además, recuerda.siSe puede seguir directamentesi noDeclaraciones. Aunque esto puede ser útil a veces, enlazar más de dos o tres if-elses de esta manera se considera una mala práctica de programación. Podemos resolver este problema con la construcción Switch-Case descrita más adelante.
Hay otros dos comentarios sintácticos genéricos que hacer, que también verá en otras construcciones de control: en primer lugar, observe que el caráctersital vezsi noNo hay punto y coma después. Podría haberlo, pero el bloque (el código contenido en { y }) lo sustituye. En segundo lugar, si sólo pretende ejecutarsital vezsi noLos resultados de laprincipioNo son necesarias las llaves. Sin embargo, muchos programadores consideran una buena práctica de programación insertar las llaves en este caso.
El siguiente código establece la variable c igual a la mayor de las dos variables a y b, o 0 si a y b son iguales.
si (a > b) {
c = a ; }
} si no en caso de que (b > uno) {
C ^ = b ;
} si no {
c = 0 ;
}
Considera esta pregunta: ¿por qué no puedes olvidarel restoY anota el código:
si (a > b) {
c = a ; }
}
si (a < b) {
c = b ;)
}
si (a == b) {
c = 0; }
}
Hay varias respuestas. La más importante es que, si sus condiciones no son mutuamente excluyentes, pueden realizarseambosCaso en lugar de un caso. ¿Qué pasa si el código es diferente y el valor de a o b cambia de alguna manera (por ejemplo, reseteando el menor de a y b a 0 después de una comparación) en uno de los bloques? Puede acabar llamando a más de unsideclaración, que no es su intención. Además, la evaluación de laen caso de queLas sentencias condicionales requieren tiempo de procesador. Si utiliza la funciónsi nopara manejar estos casos, bajo la suposición anterior de que (a> b) es distinto de cero (verdadero), el procedimiento está exento de evaluar el adicionalsicoste de la declaración. Y lo que es más importante, suele ser mejor insertar unsi no Cláusulas para todos los casos en los que la condición no se evaluará como distinta de cero (verdadero).
expresión condicional
Las expresiones condicionales son una forma de establecer valores condicionalmente de una forma más sencilla que If-Else. La sintaxis es:
(/ * expresión lógica aquí * /)? (/ * si es distinto de cero (verdadero) * /):( / * si es 0 (falso) * /)
Evalúa la expresión lógica. Si no es cero (verdadero), toda la expresión condicional se evalúa como una expresión situada entre ? entre las expresiones y: en caso contrario, evalúa la expresión situada después de:. Así, el ejemplo anterior (que cambia ligeramente su función para que c se establezca en b cuando a y b sean iguales) se convierte en:
c = (a> b)?a:b;
En ocasiones, las expresiones condicionales pueden aclarar la intención del código. Por lo general, deben evitarse los operadores condicionales anidados. Las expresiones condicionales se utilizan mejor sólo cuando las expresiones para a y b son simples. Además, contrariamente a la opinión del principiante medio, las expresiones condicionales no producen un código más rápido. No existe tal correlación debido a la suposición de que menos líneas de código dan lugar a tiempos de ejecución más cortos.
Sentencias Switch-Case
Suponga que escribe un programa en el que el usuario introduce los números del 1 al 5 (correspondientes a las calificaciones de los alumnos, A (denotada como 1) - D (4) y F (5)), almacenándolos en la variablemitad de la escalael programa responde imprimiendo en la pantalla la letra correspondiente a la calificación. Si implementara esto usando If-Else, su código se vería así:
si (nota == 1) {
printf ("A \ n " );
} si no si (nota == 2) {
printf ("B \ n " );
} si no en caso de que / * Espera, espera, espera *
Tener una larga cadena de if-else-if-else-else-else es un fastidio para los programadores y para cualquiera que lea código. Afortunadamente, existe una solución: la construcción Switch-Case, cuya sintaxis básica es:
interruptor (/ * entero o enum hasta aquí * / ) {
caso / * Valor potencial del int o enum anterior * / ::
/ *Código* /
caso / *diferentes valores potenciales* / ::
/ *código diferente* /
/ *Inserte otros casos según sea necesario* /
por defecto ::
/ *Más código* /
}
La construcción Switch-Case acepta una variable, normalmente un int o un enum, colocada en el campointerruptorDespués de eso, y conectándolo a lacasoSe compara el valor que sigue a la palabra clave. Si la variable es igual acasoSi el valor se especifica después de la sentencia case, la construcción se "activa", o la ejecución del código comienza después de la sentencia case. Una vez "activada" la construcción, no se producirá ningún cambio en el valor de la sentenciacaso (derecho)Llevar a cabo nuevas evaluaciones.
Switch-Case es gramaticalmente "raro" porque no es lo mismo quecaso (derecho)El código asociado no requiere llaves.
muy importanteNormalmente, la última sentencia en cada caso es una sentencia break. Esto hace que la ejecución del programa salte a la sentencia después del paréntesis de cierre de la sentencia switch, que es la sentencia que uno normalmente querría que ocurriera. Sin embargo, si se omite la sentencia break, el programa continuará ejecutando la primera línea del siguiente caso, si lo hubiera. Esto se conoce comouna caída en desgracia. Cuando el programador desee realizar esta acción, deberá añadir un comentario al final del bloque de sentencia para indicar que es necesario pasarlo. De lo contrario, otro programador que mantenga el código puede considerar que la omisión del "break" es un error y "corregir" inadvertidamente el problema. He aquí un ejemplo:
interruptor (algunaVariable) {
caso 1 :
printf ("Este código trata el caso 1. \ n ").
smash;
caso 2 :
printf ("Imprimir cuando algunaVariable es 2, mientras ...... \ n ").
/ * CAER A TRAVÉS DE * /
caso 3 :
printf ("Imprimir cuando algunaVariable es 2 o 3.\ n ").
smash;
}
Si especifica elpor defecto (ajuste)caso, entonces si no hay otro caso que coincidasituaciónbajo el cual se ejecuta la sentencia asociada. Apor defectocase es opcional. Se trata de una sentencia switch, correspondiente a la secuencia de sentencias if - else if anterior.
Volvamos al ejemplo anterior. Este es el aspecto de Switch-Case:
aparamenta (nivel) {
caso (derecho) 1:
printf ("A \ n ").
smash;
caso (derecho) 2:
printf ("B \ n ").
smash;
caso (derecho) 3:
printf ("C \ n ").
smash;
caso (derecho) 4:
printf ("D \ n ").
smash;
valor por defecto:
printf ("F \ n").
rompe;
}
Un conjunto de sentencias a ejecutar puede agruparse utilizando múltiples valores de variables, como se muestra en el siguiente ejemplo. (No es necesario pasar comentarios aquí, ya que el comportamiento esperado es obvio).
interruptor (algo) {
caso (derecho) 2:
caso (derecho) 3:
caso (derecho) 4:
/* Algunos de ellos van a ser 2, 3 o 4 * /
romperuna afirmación;
situación 1:
por defecto (ajuste)::
/ * Algunas sentencias deben ser ejecutadas aparte de 1 o 2,3 y 4 * /
romper ;
}
Si se compara con la definida por el usuarioenumeraciónLa construcción Switch-Case es especialmente útil cuando se utilizan tipos de datos combinados. Algunos compiladores son capaces de advertir de valores de enumeración no procesados, lo que puede ayudar a evitar errores.
ciclo
A menudo, en programación informática, una acción debe realizarse un número determinado de veces o hasta que se cumpla una condición. Escribir una sentencia o un conjunto de sentencias varias veces resulta poco práctico y tedioso, por no hablar de que es demasiado inflexible y no se puede esperar que se detenga cuando se produzca un determinado evento. Como analogía del mundo real, alguien le pregunta al friegaplatos de un restaurante qué ha hecho en toda la noche. Él respondería: "Lavé platos toda la noche". Es poco probable que responda: "Lavé un plato, luego un plato, luego un plato, luego un plato, luego ......". Las construcciones que permiten a un ordenador realizar ciertas tareas repetitivas se denominan bucles.
ciclo
El bucle while es el tipo más básico de bucle. Se ejecuta mientras la condición sea distinta de cero (verdadero). Por ejemplo, si intentas lo siguiente, el programa aparecerá bloqueado y tendrás que cerrarlo manualmente. Una situación en la que la condición para salir del bucle nunca se cumple se denomina bucle infinito.
int a = 1 ;
(indica relación causal) (42) {
a = a * 2 ;
}
Este es otro ejemplo de bucle while. Imprime dos todas las potencias menores que 100.
int a = 1 ;
mientras que (a < 100) {
printf ("a es%d \ n ", a); a = a * 2 ;
a = a * 2 ;
}
El flujo de todos los bucles también se puede pasar a través delromperresponder cantandocontinuarLa sentencia break saldrá inmediatamente del bucle cerrado. continue saltará el resto del bloque y empezará de nuevo con la sentencia de condición de control. Ejemplo:
int a = 1 ;
mientras que (42) { // Bucle hasta que se ejecute la sentencia break del bucle.
printf ("a es %d", a );
a = a * 2 ;
si (a > 100) {
romper ;
} si no en caso de que (uno == 64) {
proceder con; //Reiniciar inmediatamente saltándose el siguiente paso
}
printf ("a no es 64 \ n" );
}
En este ejemplo, el ordenador imprime el valor de a como siempre e imprime el aviso de que a no es 64 (a menos que la sentencia continue se lo salte).
De forma similar al If anterior, puede omitir las llaves del bloque de código asociado con el bucle While si el código contiene sólo una sentencia, por ejemplo:
int a = 1 ; (indica relación causal) (a < 100) a = a * 2 ;
Esto sólo aumentará a hasta que a no sea inferior a 100.
Cuando el ordenador llega al final de un bucle while, siempre vuelve a la sentencia while en la parte superior del bucle, donde reevalúa la condición de control. Si la condición es "verdadera" en ese momento - incluso si es temporalmente cero para algunas sentencias en el bucle - entonces el ordenador comienza a ejecutar sentencias dentro del bucle de nuevo; de lo contrario el ordenador sale del bucle. El ordenador no "comprueba continuamente" la condición de control del bucle while durante la ejecución del bucle. Cada vez que alcanzamientras queEn la parte superior del bucle, sólo "controla" la condición de control.
Es importante tener en cuenta que una vez que la condición de control del bucle While se convierte en 0 (falso), el bucle no terminará hasta que finalice el bloque y sea el momento de volver a evaluar la condición. Si necesita terminar el bucle While tan pronto como se alcance una condición, considere utilizar la funciónromper.
Una expresión común es escribir:
int i = 5 ;
mientras que (i - ) {
printf ("java y c# no pueden hacer esto")\ n " );
}
Esto ejecuta el código en el bucle while 5 veces, donde los valores de i van de 4 a 0 (dentro del bucle). Convenientemente, estos son los valores necesarios para acceder a cada elemento de una matriz que contiene 5 elementos.
Bucle For
Un bucle for suele tener este aspecto:
para(inicialización ; prueba ; incrementar) {
/ *code* /
}
existeinicializaciónse ejecuta una vez, antes de la primera evaluación de la sentenciapruebasCondición. Normalmente, se utiliza para asignar un valor inicial a una variable, aunque esto no es absolutamente necesario. En lainicializacióntambién puede utilizarse para declarar e inicializar variables utilizadas en un bucle.
existeprueba (maquinaria, etc.)El código de la expresión se evalúa cada vez antes de quedebido aEjecución del bucle. Si esta expresión se evalúa a cero (falso) cuando se comprueba (es decir, la expresión no es verdadera), el bucle no se (re)introduce y el código que sigue inmediatamente al bucle FOR se ejecuta normalmente. Si la expresión es distinta de cero (verdadero), se ejecuta el código dentro del paréntesis del bucle.
Después de cada iteración del bucle, ejecute la funciónen orden creciente. Se utiliza normalmente para incrementar el índice de bucle de un bucle en el que la variable se inicializa en una expresión de inicialización y se comprueba en una expresión de prueba. Después de ejecutar esta sentencia, el control vuelve a la parte superior del bucle donde la variableprueba (maquinaria, etc.)Funcionamiento. Si elparaEjecutar en buclecontinuarla sentencia incremental será la siguiente en ejecutarse.
Cada parte de la sentencia for es opcional y puede omitirse. Debido a su naturaleza libre, la sentencia for se puede utilizar para hacer algunas cosas bastante exóticas. Es común usar un bucle for para iterar a través de los elementos de un array, procesando cada elemento de uno en uno.
int miMatriz [ 12 ].
int ix ;
para (ix = 0 ; ix < 12 ; ix ++ ) {
miMatriz [ ix ] = 5 * ix + 3 ; )
}
El bucle for anterior inicializa cada uno de los 12 elementos de miMatriz. El índice del bucle puede comenzar en cualquier valor. En el siguiente caso, comienza con 1.
para (ix = 1 ; ix <= 10 ; ix ++ ) {
printf ("%d", ix); }
}
Esto imprimirá
1 2 3 4 5 6 7 8 9 10
La mayoría de las veces se utiliza un índice cíclico que empieza en 0 porque la matriz tiene un índice cero, pero a veces se utilizan otros valores para inicializar el índice cíclico.
deberíaincrementalLas acciones pueden hacer otras cosas, comoreducción. Así que este ciclo es habitual:
para (i = 5 ; i > 0 ; i - ) {
printf ("%d", i); }
}
capacidad de producción
5 4 3 2 1
Este es un ejemplo en el que la condición de prueba es sólo una variable. Si el valor de la variable es 0 o NULL, el bucle sale, en caso contrario se ejecutan las sentencias del cuerpo del bucle.
para (t = cabeza_de_lista ; t ; t = NextItem (t )) {
/ * Cuerpo del bucle * /
}
Los bucles WHILE se pueden utilizar para realizar las mismas operaciones que los bucles FOR, pero los bucles FOR son una forma más concisa de realizar un cierto número de repeticiones porque toda la información necesaria está en una línea de sentencias.
Los bucles FOR también pueden ser incondicionales, por ejemplo:
para (;;;) {
/ *bloque de declaraciones* /
}
Esto se llama un bucle infinito porque se repetirá para siempre a menos que el bucle for tenga una sentencia break en su sentencia. La condición de prueba nula se evalúa efectivamente a verdadero.
También es habitual utilizar el operador coma en un bucle for para ejecutar varias sentencias.
int i , j , n = 10 ;
para (i = 0, j = 0 ; i <= n ; i ++, j += 2) {
printf ("i = %d, j = %d \ n ", i, j).
}
Debe tenerse especial cuidado al diseñar o refactorizar secciones condicionales, sobre todo en el uso de < o <=, si el inicio y el fin deben corregirse a 1, y el caso de la notación prefijo y sufijo. (Hay 11 árboles en un paseo de 100 metros, con un árbol cada 100 metros).
int i , n = 10 ;
para (i = 0 ; i < n ; i ++ )
printf ("%d", i); // Procesar n veces => 0 1 2 3 ... (n-1)
printf (" \ n ").
para (i = 0 ; i <= n ; i ++ )
printf ("%d", i); // procesado (n + 1) veces => 0 1 2 3 ... n
printf (" \ n ").
para (i = n ; i - ;))
printf ("%d", i). // Procesar n veces => (n-1)... 3 2 1 0
printf (" \ n ").
para (i = n ; - i ;))
printf ("%d", i). // procesado (n-1) veces => (n-1)... 4 3 2 1
printf (" \ n ").
Bucle Do-While
El bucle DO-WHILE es un bucle while post-check, lo que significa que comprueba la condición después de cada ejecución. Como resultado, se ejecutará al menos una vez incluso si la condición es cero (falso). Sigue la siguiente forma:
utilizarse para {
/ *Haciendo cosas* /
} (indica relación causal) (condiciones).
Observe el punto y coma final. Es necesario para que la sintaxis sea correcta. Dado que también se trata de un bucle while, el bucle romperresponder cantandocontinuarfuncionan en consecuencia. Aproceder conprovoca un salto a la prueba de esa condición y la sentenciarompepara salir del bucle.
Vale la pena señalar que Do-While y While son funcionalmente casi idénticos, con una diferencia importante: los bucles Do-While siempre tienen garantizada su ejecución al menos una vez, pero si su condición es 0 (falso), el bucle no realizará la primera evaluación en absoluto.
Una última cosa: vaya a
ir aes un mecanismo de control muy simple y tradicional. Es una sentencia que se utiliza para saltar inmediata e incondicionalmente a otra línea de código. Para utilizar goto, debe colocar una etiqueta en algún lugar de su programa. Una etiqueta consiste en un nombre seguido de dos puntos (:). A continuación, puede escribir "goto etiqueta ;" en el punto deseado de su plan. El código continuará conetiquetaEl comienzo de la ejecución. Esto parece:
MiEtiqueta: / *algún código* / ir a MiEtiqueta ;
La habilidad de pasar flujo de control habilitado por gotos es tan poderosa que todo excepto un simple if puede ser escrito usando gotos. Aquí, podemos hacer "S" y "T" declaraciones arbitrarias:
si (''cond'') {
S ;-
} si no {
T ;
}
/ * ... * /
El mismo enunciado puede realizarse utilizando dos gotos y dos etiquetas:
si (''cond'') cambiar a Etiqueta1 ; T
T ;
cambiar a Etiqueta2.
Etiqueta1 :
Etiqueta1: S ; Etiqueta2.
Etiqueta2 :
/ * ... * /
Aquí, el primer goto es condicional al valor de "cond". El segundo goto es incondicional. Podemos realizar la misma conversión en un bucle:
mientras que (''cond1'') {
S ;
si (''cond2'')
perturbaciones;
T ;
}
/ * ... * /
Que se puede escribir como:
Comienza:
en caso de que ¡(! cond1'') cambiar a Fin ;S ;
S ;
si (''cond2'') ir a Fin
T ;
cambiar a Comienzo;
Fin:
/ * ... * /
Como muestran estos casos, a menudo es posible expresar la estructura de un programa en ejecución sin utilizar gotos. El uso indisciplinado de gotos puede producir un código incomprensible e imposible de mantener cuando otras alternativas más habituales (como if-elses o bucles for) pueden expresar mejor su estructura. Teóricamente, pasar a una estructura no es tan importante como lo ha sido nunca ennecesariamenteusar, pero hay ocasiones en las que puede añadir legibilidad, evitar la duplicación de código o hacer innecesarias las variables de control. Tenga en cuenta que muchas (si no la mayoría) de las guías de estilo de Cestrictamente prohibidoutilizarir aLa única excepción habitual es el siguiente ejemplo.
Un uso de goto es romper bucles profundamente anidados. Dado queromperno funciona (sólo puede escapar de un bucle), la funciónir apara salir del bucle. Salir de bucles profundamente anidados sin usar goto siempre es posible, pero normalmente implica crear y probar variables adicionales que pueden hacer que el código resultante sea mucho menos legible que el códigoir a. Utiliceir aLas operaciones pueden deshacerse fácilmente de forma ordenada, normalmente para evitar liberar memoria que ya ha sido asignada.
Otro uso aceptado es crear máquinas de estados. Este es un tema bastante avanzado, pero no muy común.
ejemplo típico
1TP5Incluido <errno.h>
1TP5Incluido <stdio.h>
1TP5Incluido <stdlib.h>
int main (void )
int main (void )
int años ;
printf ("Introduzca su edad:" ); fflush (stdout );; fflush (stdout ); fflush (stdout )
fflush (stdout ); }
fflush (stdout ); errno = 0 ;
si ¡(scanf ("%d", &años)! = 1 || errno )
devolver EXIT_FAILURE ;
printf ("Su edad es %d") \ n ", año * 365).
volver (o regresar) 0 ;
}
Supongo que quieres leer:9. Programación en C. 10. Procedimientos y funciones



