087 146 Capitulo 4 Estructuras de Control

Embed Size (px)

Citation preview

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    1/60

    CAPTULO 4

    ESTRUCTURAS DE CONTROL

    El lenguaje C pertenece a la familia de lenguajes del paradigma de la

    programacin estructurada. En este captulo quedan recogidas las reglas

    de la programacin estructurada y, en concreto, las reglas sintcticas

    que se exige en el uso del lenguaje C para el diseo de esas estructuras.

    El objetivo del captulo es aprender a crear estructuras

    condicionales y estructuras de iteracin. Tambin veremos una

    estructura especial que permite seleccionar un camino de ejecucin de

    entre varios establecidos. Y veremos las sentencias de salto que nos

    permiten abandonar el bloque de sentencias iteradas por una estructura

    de control.

    Introduccin.

    Las reglas de la programacin estructurada son:

    1. Todo programa consiste en una serie de acciones o sentencias que

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    2/60

    Fundamentos de informtica. Programacin en Lenguaje C

    88

    se ejecutan en secuencia, una detrs de otra.

    2. Cualquier accin puede ser sustituida por dos o ms acciones en

    secuencia. Esta reglase conoce como la de apilamiento.

    3. Cualquier accin puede ser sustituida por cualquier estructura de

    control; y slo se consideran tres estructuras de control: la

    secuencia, la seleccin y la repeticin. Esta regla se conoce

    como regla de anidamiento. Todas las estructuras de control de la

    programacin estructurada tienen un solo punto de entrada y un solo

    punto de salida.

    4. Las reglas de apilamiento y de anidamiento pueden aplicarse tantas

    veces como se desee y en cualquier orden.

    Ya hemos visto cmo se crea una sentencia: con un punto y coma

    precedido de una expresin que puede ser una asignacin, la llamada a

    una funcin, una declaracin de una variable, etc. O, si la sentencia es

    compuesta, agrupando entonces varias sentencias simples en un bloque

    encerrado por llaves.

    Los programas discurren, de instruccin a instruccin, una detrs de

    otra, en una ordenacin secuencial y nunca dos al mismo tiempo, como

    queda representado en la figura 4.1.

    Pero un lenguaje de programacin no slo ha de poder ejecutar las

    instrucciones en orden secuencial: es necesaria la capacidad para

    modificar ese orden de ejecucin. Para ello estn las estructuras de

    control. Al acabar este captulo, una vez conocidas las estructuras de

    control, las posibilidades de resolver diferentes problemas mediante el

    lenguaje de programacin C se habrn multiplicado enormemente.

    Instruccin 1 Instruccin 2 Instruccin N

    Figura 4.1.: Esquema de ordenacin secuencial de sentencias.

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    3/60

    Captulo 4. Estructuras de control.

    89

    A lo largo del captulo iremos viendo abundantes ejemplos. Es

    conveniente pararse en cada uno: comprender el cdigo que se propone

    en el manual, o lograr resolver aquellos que se dejan propuestos. En

    algunos casos ofreceremos el cdigo en C; en otros dejaremos apuntado

    el modo de resolver el problema ofreciendo el pseudocdigo del

    algoritmo o el flujograma. Muchos de los ejemplos que aqu se van a

    resolver ya tienen planteado el flujograma o el pseudocdigo en el libro

    Fundamentos de Informtica. Codificacin y Algoritmia.

    Conceptos previos.

    La regla 3 de la programacin estructurada habla de tres estructuras de

    control: la secuencia, la seleccin y la repeticin. Nada nuevo hay ahora

    que decir sobre la secuencia, que vendra esquematizada en la figura

    4.1. En la figura 4.2. se esquematizan diferentes posibles estructuras de

    seleccin; y en la figura 4.3. las dos estructuras bsicas de repeticin.

    Las dos formas que rompen el orden secuencial de ejecucin desentencias son:

    1. Instruccin condicional: Se evala una condicin y si se cumple

    se transfiere el control a una nueva direccin indicada por la

    instruccin.

    2. Instruccin incondicional. Se realiza la transferencia a una nueva

    direccin sin evaluar ninguna condicin (por ejemplo, llamada a una

    funcin).

    En ambos casos la transferencia del control se puede realizar con o sin

    retorno: en el caso de que exista retorno, despus de ejecutar el bloque

    de instrucciones de la nueva direccin se retorna a la direccin que

    sucede a la que ha realizado el cambio de flujo.

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    4/60

    Fundamentos de informtica. Programacin en Lenguaje C

    90

    Las estructuras de control que se van a ver en este captulo son

    aquellas con trasfieren el control a una nueva direccin, de

    acuerdo a una condicin evaluada.

    Estructuras de control condicionales.

    Las estructuras de control condicionales que se van a ver son la

    bifurcacin abierta y la bifurcacin cerrada. Un esquema del flujo de

    ambas estructuras ha quedado recogido en la Figura 4.2.

    La bifurcacin abierta. La sentencia i f.

    La sentencia que est precedida por la estructura de control

    condicionada se ejecutar si la condicin de la estructura de control es

    verdadera; en caso contrario no se ejecuta la instruccin condicionada y

    Condicin

    Instruccin Instruccin

    Instruccin

    Condicin

    Instruccin

    Instruccin

    Bifurcacin abierta Bifurcacin cerrada

    Figura 4.2.: Estructuras de seleccin.

    S SNoNo

    Condicin

    Instruccin

    Instruccin

    SNo

    Figura 4.3.: Estructuras de repeticin.

    Condicin

    InstruccinInstruccin

    SNo

    Estructura w h i l e Estructura d o - w h i l e

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    5/60

    Captulo 4. Estructuras de control.

    91

    continua el programa con la siguiente instruccin. En la figura 4.2. se

    puede ver un esquema del comportamiento de la bifurcacin abierta.

    La sintaxis de la estructura de control condicionada abierta es la

    siguiente:

    i f ( c o n d i c i n ) s e n t e n c i a ;

    Si la condicin es verdadera (distinto de cero en el lenguaje C), se

    ejecuta la sentencia. Si la condicin es falsa (igual a cero en el lenguaje

    C), no se ejecuta la sentencia.

    Si en lugar de una sentencia, se desean condicionar varias de ellas,

    entonces se crea una sentencia compuesta mediante llaves.

    Ejemplo:

    Programa que solicite dos valores enteros y muestre el cociente:

    #i ncl ude void mai n( void){

    short D, d;pr i nt f ( "Progr ama par a di vi di r dos ent er os. . . \ n") ;pr i nt f ( " I nt roduzca el di vi dendo . . . ") ;scanf ( "%hd" , &D) ;pr i nt f ( " I nt roduzca el di vi sor . . . " ) ;scanf ( "%hd" , &d) ;if( d ! = 0) pr i nt f ( "%hu / %hu = %hu", D, d, D / d) ;

    }

    Se efectuar la divisin nicamente en el caso en que se verifique la

    condicin de que d != 0.

    La bifurcacin cerrada. La sentencia i f e ls e.

    En una bifurcacin cerrada, la sentencia que est precedida por una

    estructura de control condicionada se ejecutar si la condicin de la

    estructura de control es verdadera; en caso contrario se ejecuta una

    instruccin alternativa. Despus de la ejecucin de una de las dos

    sentencias (nunca las dos), el programa contina la normal ejecucin de

    las restantes sentencias que vengan a continuacin.

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    6/60

    Fundamentos de informtica. Programacin en Lenguaje C

    92

    La sintaxis de la estructura de control condicionada cerrada es la

    siguiente:

    i f ( c o n d i c i n ) s en t e n c i a 1 ;e l s e s e n t e n c i a 2 ;

    Si la condicin es verdadera (distinto de cero en el lenguaje C), se

    ejecuta la sentencia llamada sentencia1. Si la condicin es falsa (igual a

    cero en el lenguaje C), se ejecuta la sentencia llamada sentencia2.

    Si en lugar de una sentencia, se desean condicionar varias de ellas,

    entonces se crea una sentencia compuesta mediante llaves.

    Ejemplo:

    El mismo programa anteriormente visto. Quedar mejor si se escribe de

    la siguiente forma:

    #i ncl ude void mai n( void){

    short D, d;pr i nt f ( "Progr ama par a di vi di r dos ent er os. . . \ n") ;

    pr i nt f ( " I nt roduzca el di vi dendo . . . ") ;scanf ( "%hd" , &D) ;pr i nt f ( " I nt roduzca el di vi sor . . . " ) ;scanf ( "%hd" , &d) ;if( d ! = 0) pr i nt f ( "%hu / %hu = %hu", D, d, D / d) ;else pr i nt f ( No se puede r eal i zar di vi si on por cer o) ;

    }

    Se efectuar la divisin nicamente en el caso en que se verifique la

    condicin de que d != 0. Si el divisor introducido es igual a cero,

    entonces imprime en pantalla un mensaje de advertencia.

    Anidamiento de estructuras condicionales.

    Decimos que se produce anidamiento de estructuras de control cuando

    una estructura de control aparece dentro de otra estructura de control

    del mismo tipo.

    Tanto en la parte i f como en la parte e l s e , los anidamientos pueden

    llegar a cualquier nivel. De esa forma podemos elegir entre numerosas

    sentencias estableciendo las condiciones necesarias.

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    7/60

    Captulo 4. Estructuras de control.

    93

    Una estructura de anidamiento tiene, por ejemplo, la forma:

    if( expr esi n_1) / * pr i mer i f */{

    if( expr esi n_2) / * segundo i f */{

    if( expr esi n_3) / * t er cer i f */sent enci a_1;

    else / * al t ernat i va al t ercer i f * /sent enci a_2;

    }else / * al t ernat i va al 2 i f * /

    sent enci a_3;}else / * al t er nat i va al pr i mer i f * /

    sent enci a_4;

    (se puede ver el organigrama de este cdigo en la figura 4.4.)

    Cada e l s e se asocia al i f ms prximo en el bloque en el que se

    encuentre y que no tenga asociado un e l s e . No est permitido (no

    tendra sentido) utilizar un e l s e sin un i f previo. Y la estructura e l s e

    debe ir inmediatamente despus de la sentencia condicionada con su i f.

    Un ejemplo de estructura anidada sera, siguiendo con los ejemplos

    anteriores, el caso de que, si el divisor introducido ha sido el cero, el

    programa preguntase si se desea introducir un divisor distinto.

    C1

    C2

    C3

    S4S3S1 S2

    F

    C

    Figura 4.4.: Ejemplo deestructuras condicionales anidadas.

    NoS

    NoS

    NoS

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    8/60

    Fundamentos de informtica. Programacin en Lenguaje C

    94

    #i ncl ude void mai n( void){

    short D, d;char opci on;pr i nt f ( "Progr ama par a di vi di r dos ent er os. . . \ n") ;pr i nt f ( " I nt roduzca el di vi dendo . . . ") ;scanf ( "%hd" , &D) ;pr i nt f ( " I nt roduzca el di vi sor . . . " ) ;scanf ( "%hd" , &d) ;if( d ! = 0)

    pr i nt f ( "%hu / %hu = %hu", D, d, D / d) ;else

    { pr i nt f ( "No se puede di vi di r por cer o. \ n") ;pr i nt f ( "I nt r oduci r otr o denomi nador ( s/ n) ?") ;opci on = get char ( ) ;if( opci on == ' s' ){

    pr i nt f ( "\ nNuevo denomi nador . . . ") ;scanf ( "%hd" , &d) ;if( d != 0)

    pr i nt f ( "%hu / %hu = %hu" , D, d, D/ d) ;else

    pr i nt f ( "De nuevo ha i nt r oduci do 0. ") ;}

    }}

    La funcin getchar()est definida en la biblioteca stdio.h. Esta funcin

    espera a que el usuario pulse una tecla del teclado y, una vez pulsada,

    devuelve el cdigo ASCII de la tecla pulsada.

    En este ejemplo hemos llegado hasta un tercer nivel de anidacin.

    Escala i f - e l se i f

    Cuando se debe elegir entre una lista de opciones, y nicamente una de

    ellas ha de ser vlida, se llega a producir una concatenacin de

    condiciones de la siguiente forma:

    i f(condicin1) setencia1;e l s e {

    i f(condicin2) sentencia2;e l s e {

    i f(condicin3) sentencia3;

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    9/60

    Captulo 4. Estructuras de control.

    95

    e l s e sentencia4;}}

    El flujograma recogido en la Figura 4.4. representara esta situacin sin

    ms que intercambiar los caminos de verificacin de las condiciones C1,

    C2 y C3 recogidas en l (es decir, intercambiando los rtulos de S y

    de No).

    Este tipo de anidamiento se resuelve en C con la estructura e l s e i f , que

    permite una concatenacin de las condicionales. Un cdigo como el

    antes escrito quedara:

    i f(condicin1) sentencia1;e l s e i f (condicin2) sentencia2;e l s e i f (condicin3) sentencia3;e l s e sentencia4;

    Como se ve, una estructura as anidada se escribe con mayor facilidad y

    expresa tambin ms claramente las distintas alternativas. No es

    necesario que, en un anidamiento de sentencias condicionales,

    encontremos un e l s e final: el ltimo i f puede ser una bifurcacinabierta:

    i f(condicin1) sentencia1;e l s e i f (condicin2) sentencia2;e l s e i f (condicin3) sentencia3;

    Un ejemplo de concatenacin podra ser el siguiente programa, que

    solicita al usuario la nota de un examen y muestra por pantalla la

    calificacin acadmica obtenida:

    #i ncl ude

    void mai n( void){float not a;pr i nt f ( "I nt r oduzca l a not a del examen . . . ") ;scanf ( "%f ", &not a) ;if( not a < 0 | | not a > 10) pr i nt f ( "Not a i ncor r ect a. ") ;else if( not a < 5) pr i nt f ( "Suspenso. ") ;else if( not a < 7) pr i nt f ( "Apr obado. ") ;else if( not a < 9) pri nt f ( "Not abl e. ") ;else if( not a < 10) pr i nt f ( "Sobr esal i ent e. ") ;else pr i nt f ( "Mat r cul a de honor . ") ;

    }

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    10/60

    Fundamentos de informtica. Programacin en Lenguaje C

    96

    nicamente se evaluar un e l s e i f cuando no haya sido cierta la

    condicin de ninguno de los anteriores ni del i f inicial. Si todas las

    condiciones resultan ser falsas, entonces se ejecutar (si existe) el

    ltimo e l s e .

    La estructura condicional y el operador condicional

    Existe un operador que selecciona entre dos opciones, y que realiza, de

    forma muy sencilla y bajo ciertas limitaciones la misma operacin que la

    estructura de bifurcacin cerrada. Es el operador interrogante, dos

    puntos(? :).

    La sintaxis del operador es la siguiente:

    e x p r e s i n _ 1 ? ex p r e s i n _ 2 : e x p r e s i n 3 ;

    Se evala expresin_1; si resulta ser verdadera, entonces se ejecutar

    la sentencia recogida en expresin_2; y si es falsa, entonces se

    ejecutar la sentencia recogida en expresin_3. Tanto expresin_2

    como expresin_3pueden ser funciones, o expresiones muy complejas,

    pero siempre deben ser sentencias simples.

    Es conveniente no renunciar a conocer algn aspecto de la sintaxis de

    un lenguaje de programacin. Es cierto que el operador interrogante

    dos puntos se puede siempre sustituir por la estructura de control

    condicional i f e lse. Pero el operador puede, en muchos casos,

    simplificar el cdigo o hacerlo ms elegante. Y hay que tener en cuenta

    que el resto de los programadores s hacen uso del operador y el cdigo

    en C est lleno de ejemplos de su uso.

    Por ejemplo, el cdigo:

    if(x >= 0)printf(Positivo\n);

    elseprintf(Negativo\n);

    es equivalente a:printf(%s\n, x >= 0 ?Positivo:Negativo);

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    11/60

    Captulo 4. Estructuras de control.

    97

    Estructura de seleccin mltiple: Sentencia s w i t c h .La sentencia s w i t ch permite transferir el control de ejecucin del

    programa a un punto de entrada etiquetado en un bloque de sentencias.

    La decisin sobre a qu instruccin del bloque se trasfiere la ejecucin

    se realiza mediante una expresin entera.

    La forma general de la estructura s w i t ch es:

    switch(variable_del_switch){

    caseexpresionConstante1:[sentencias;][break;]

    caseexpresionConstante2:[sentencias;][break;]

    []caseexpresionConstanteN:

    [sentencias;][break;]

    [defaultsentencias;]

    }El cuerpo de la sentencia s w i t ch se conoce como bloque s w i t ch y

    permite tener sentencias prefijadas con las etiquetas c a se. Una etiqueta

    c a s e es una constante entera (variables de tipo c h a r s h o r t l o n g ,

    con o sin signo). Si el valor de la expresin de s w i t ch coincide con el

    valor de una etiqueta c a se, el control se transfiere a la primera

    sentencia que sigue a la etiqueta. No puede haber dos c a se con el

    mismo valor de constante. Si no se encuentra ninguna etiqueta c a s e

    que coincida, el control se transfiere a la primera sentencia que sigue ala etiqueta d e f a u l t . Si no existe esa etiqueta d e f a u l t , y no existe una

    etiqueta coincidente, entonces no se ejecuta ninguna sentencia del

    s w i t ch y se contina, si la hay, con la siguiente sentencia posterior a la

    estructura.

    Por ejemplo, para el cdigo que se muestra a continuacin, y cuyo

    flujograma queda recogido en la figura 4.5.:

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    12/60

    Fundamentos de informtica. Programacin en Lenguaje C

    98

    switch(a){case 1: pr i nt f ( UNO\ t );case 2: pr i nt f ( DOS\ t );case 3: pr i nt f ( TRES\ t ) ;default: pr i nt f ( NI NGUNO\ n) ;

    }

    Si el valor de a es, por ejemplo, 2, entonces comienza a ejecutar el

    cdigo del bloque a partir de la lnea que da entrada el c a s e 2 : .

    Producir la siguiente salida por pantalla:

    DOS TRES NI NGUNO.

    Una vez que el control se ha trasferido a la sentencia que sigue a una

    etiqueta concreta, ya se ejecutan todas las dems sentencias del bloque

    s w i t ch , de acuerdo con la semntica de dichas sentencias. El que

    aparezca una nueva etiqueta c a seno obliga a que se dejen de ejecutar

    las sentencias del bloque. Si se desea detener la ejecucin de sentenciasen el bloque s w i t ch , debemos transferir explcitamente el control al

    exterior del bloque. Y eso se realiza utilizando la sentencia b r e a k .

    Dentro de un bloque s w i t ch , la sentencia b r e a k transfiere el control a

    la primera sentencia posterior al s w i t ch . Ese es el motivo por el que en

    la sintaxis de la estructura s w i t ch se escriba (en forma opcional) las

    sentencias b r e a k en las instrucciones inmediatamente anteriores a cada

    una de las etiquetas.

    = 1a

    C

    F

    UNO

    = 2a DOS

    = 3a

    TRES

    NINGUNO

    SNo

    SNo

    SNo

    Figura 4.5.: Flujograma delprograma ejemplo con s w i t ch , sinsentencias b r e a k .

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    13/60

    Captulo 4. Estructuras de control.

    99

    En el ejemplo anterior, si colocamos la sentencia b r e a k en cada c a se,

    switch(a){

    case 1: pr i nt f ( UNO) ;break;case 2: pr i nt f ( DOS) ;break;case 3: pr i nt f ( TRES);break;default: pr i nt f ( NI NGUNO) ;

    }

    Entonces la salida por pantalla, si la variable a tiene el valor 2 sernicamente:

    DOS

    (Puede verse el flujograma de este nuevo cdigo en la figura 4.6.)

    La ejecucin de las instrucciones que siguen ms all de la siguiente

    etiqueta c a sepuede ser til en algunas circunstancias. Pero lo habitual

    ser que aparezca una sentencia b r e a k al final del cdigo de cada

    etiqueta c a se.

    Una sola sentencia puede tener ms de una etiqueta c a se. Queda claro

    en el siguiente ejemplo:

    short int nota;pr i nt f ( "I nt r oduzca l a not a del examen . . . ") ;scanf ( "%hd", &not a) ;

    = 1a

    C

    F

    UNO

    = 2a DOS

    = 3a TRES

    NINGUNO

    SNo

    SNo

    SNo

    Figura 4.6.: Flujograma delprograma ejemplo con s w i t ch ,con sentencias b r e a k .

    break;

    break;

    break;

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    14/60

    Fundamentos de informtica. Programacin en Lenguaje C

    100

    switch(nota){case 1:case 2:case 3:case 4: pr i nt f ( SUSPENSO) ;

    break;case 5:case 6: pri nt f ( APROBADO) ;

    break;case 7:case 8: pr i nt f ( NOTABLE) ;

    break;

    case 9: pr i nt f ( SOBRESALI ENTE) ;break;case 10: pr i nt f ( MATR CULA DE HONOR) ;

    break;default: pr i nt f ( Not a i nt r oduci da er r nea. ) ;

    }

    No se puede poner una etiqueta c a s e fuera de un bloque s w i t ch . Y

    tampoco tiene sentido colocar instrucciones dentro del bloque s w i t ch

    antes de aparecer el primer c a se: eso supondra un cdigo que jams

    podra llegar a ejecutarse. Por eso, la primera sentencia de un bloque

    s w i t ch debe estar ya etiquetada.

    Se pueden anidar distintas estructuras s w i t ch .

    El ejemplo de las notas, que ya se mostr al ejemplificar una anidacin

    de sentencias i fe lsei fpuede servir para comentar una caracterstica

    importante de la estructura s w i t ch . Esta estructura no admite, en sus

    distintas entradas c a se, ni expresiones lgicas o relacionales, ni

    expresiones aritmticas, sino literales. La nica relacin aceptada es,

    pues, la de igualdad. Y adems, el trmino de la igualdad es siempre

    entre una variable o una expresin entera (la del s w i t ch ) y valores

    literales: no se puede indicar el nombre de una variable. El programa de

    las notas, si la variable notahubiese sido de tipo f l o a t , como de hecho

    quedo definida cuando se resolvi el problema con los condicionales i f

    e lse i fno tiene solucin posible mediante la estructura s w i t ch .

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    15/60

    Captulo 4. Estructuras de control.

    101

    Y una ltima observacin: las sentencias de un c a se no forman un

    bloque y no tiene porqu ir entre llaves. La estructura s w i t ch entera,

    con todos sus c a ses, s es un bloque.

    Un ejercicio planteado.

    Planteamos ahora un ejercicio a resolver: solicite del usuario que

    introduzca por teclado un da, mes y ao, y muestre entonces por

    pantalla el da de la semana que le corresponde.

    La resolucin de este problema es sencilla si se sabe el cmo. Sin un

    correcto algoritmo que nos permita saber cmo procesar la entrada no

    podemos hacer nada.

    Por lo tanto, antes de intentar implementar un programa que resuelva

    este problema, ser necesario preguntarse si somos capaces de

    resolverlo sin programa. Porque si no sabemos hacerlo nosotros, menos

    sabremos explicrselo a la mquina.

    Buscando en Internet he encontrado lo siguiente: Para saber a qu da

    de la semana corresponde una determinada fecha, basta aplicar la

    siguiente expresin:

    ( ) = + + + + 26 2 10 4 4 2 mod7d M D A A C C

    Donde d es el da de la semana ( = 0d es el domingo; = 1d es el

    lunes,, = 6d es el sbado); D es el da del mes de la fecha; Mes el

    mes de la fecha; A es el ao de la fecha; y Ces la centuria (es decir,

    los dos primero dgitos del ao) de la fecha.

    A esos valores hay que introducirle unas pequeas modificaciones: se

    considera que el ao comienza en marzo, y que los meses de enero y

    febrero son los meses 11 y 12 del ao anterior.

    Hagamos un ejemplo a mano: Qu da de la semana fue el 15 de

    febrero de 1975?:

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    16/60

    Fundamentos de informtica. Programacin en Lenguaje C

    102

    = 15D

    = 12M : hemos quedado que en nuestra ecuacin el mes de febrero

    es el dcimo segundo mes del ao anterior.

    = 74A : hemos quedado que el mes de febrero corresponde al

    ltimo mes del ao anterior.

    = 19C

    Con todos estos valores, el da de la semana queda:

    ( ) = + + + + 26 12 2 10 15 74 74 4 19 4 2 19 mod7d

    que es igual a 6, es decir, sbado.

    Slo queda hacer una ltima advertencia a tener en cuenta a la hora de

    calcular nuestros valores de A y de C: Si queremos saber el da de la

    semana del 1 de febrero de 2000, tendremos que = 12M , que = 99A y

    que = 19C : es decir, primero convendr hacer las rectificaciones al ao

    y slo despus calcular los valores de A y de C. se da fue

    ( ) = + + + + = 26 12 2 10 1 99 99 4 19 4 2 19 mod7 2d

    es decir martes!

    Queda ahora hacer el programa que nos d la respuesta al da de la

    semana en el que estamos. Har falta emplear dos veces la estructura

    de control condicional i fy una vez el s w i t ch . El programa queda como

    sigue:

    #i ncl ude

    voi d mai n( voi d){

    unsigned short D, mm, aaaa;unsigned short M, A, C;

    pr i nt f ( " I nt roduzca l a f echa . . . \ n") ;pr i nt f ( " D a . . . " ) ;scanf ( "%hu" , &D) ;

    pr i nt f ( "Mes . . . " ) ;scanf ( "%hu" , &mm) ;

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    17/60

    Captulo 4. Estructuras de control.

    103

    pr i nt f ( "Ao . . . " ) ;scanf ( "%hu" , &aaaa) ;

    / / Val or es de l as var i abl es:

    / / El val or de D ya ha quedado i nt r oduci do por el usuar i o./ / Val or de M:

    if( mm< 3){

    M = mm + 10;A = ( aaaa - 1) % 100;C = ( aaaa - 1) / 100;

    }else{

    M = mm - 2;A = aaaa % 100;C = aaaa / 100;

    }

    pr i nt f ( "El d a %2hu de %2hu de %4hu f ue " , D, mm, aaaa) ;switch( ( 70+( 26*M- 2) / 10 + D + A + A/ 4 + C/ 4 - C*2 ) % 7){case 0: pr i nt f ( "DOMI NGO") ; break;case 1: pr i nt f ( "LUNES") ; break;

    case 2: pr i nt f ( "MARTES") ; break;case 3: pr i nt f ( "MI RCOLES") ; break;case 4: pr i nt f ( "J UEVES") ; break;case 5: pr i nt f ( "VI ERNES") ; break;case 6: pr i nt f ( "SBADO") ;}

    }

    Si, por ejemplo, introducimos la fecha 25 de enero de 1956, la salida del

    programa tendr el siguiente aspecto:

    I nt r oduzca l a f echa . . .D a . . . 25

    Mes . . . 1Ao . . . 1956El d a 25 de 1 de 1956 f ue MI RCOLES

    Falta aclarar por qu he sumado 70 al valor de la expresin que

    calculamos en el switch. Veamos un ejemplo para justificar ese valor:

    supongamos la fecha 2 de abril de 2001. Tendremos que = 2D , = 2M ,

    = 1A y = 20C , y entonces el valor de dqueda: 27%7 que es igual a

    6 . Nuestro algoritmo trabaja con valores entre 0 y 6, y al salir

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    18/60

    Fundamentos de informtica. Programacin en Lenguaje C

    104

    negativo el valor sobre el que se debe calcular el mdulo de 7, el

    resultado nos sale fuera de ese rango de valores. Pero la operacin

    mdulo establece una relacin de equivalencia entre el conjunto de los

    enteros y el conjunto de valores comprendidos entre 0 y el valor del

    mdulo menos 1. Le sumamos al valor calculado un mltiplo de 7

    suficientemente grande para que sea cual sea el valor de las variables,

    al final obtenga un resultado positivo. As, ahora, el valor obtenido ser

    = =70 27%7 43%7 1, es decir, lunes:

    I nt r oduzca l a f echa . . .D a . . . 2Mes . . . 4Ao . . . 2001El d a 2 de 4 de 2001 f ue LUNES

    Estructuras de repeticin. Iteracin.

    Una estructura de repeticin o de iteracin es aquella que nos permite

    repetir un conjunto de sentencias mientras que se cumpla una

    determinada condicin.

    Las estructuras de iteracin o de control de repeticin, en C, se

    implementan con las estructuras d ow h i l e , w h i l e y f o r. Todas ellas

    permiten la anidacin de unas dentro de otras a cualquier nivel. Puede

    verse un esquema de su comportamiento en la figura 4.3., en pginas

    anteriores.

    Estructura w h i l e .

    La estructura w h i l e , tambin llamada condicional, o centinela, seemplea en aquellos casos en que no se conoce por adelantado el

    nmero de veces que se ha de repetir la ejecucin de una determinada

    sentencia o bloque: ninguna, una o varias.

    La sintaxis de la estructura w h i l e es la que sigue:

    w h i l e ( c o n d i c in ) s e n t e n c ia ;

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    19/60

    Captulo 4. Estructuras de control.

    105

    donde condicin es cualquier expresin vlida en C. Esta expresin se

    evala cada vez, antes de la ejecucin de la sentencia iterada (o bloque

    de sentencias si se desea iterar una sentencia compuesta). Puede por

    tanto no ejecutarse nunca el bloque de sentencias de la estructura de

    control. Las sentencias se volvern a ejecutar una y otra vez mientras

    condicin siga siendo verdadero. Cuando la condicin resulta ser falsa,

    entonces el contador de programa se sita en la inmediata siguiente

    instruccin posterior a la sentencia gobernada por la estructura.

    Veamos un ejemplo sencillo. Hagamos un programa que solicite un

    entero y muestre entonces por pantalla la tabla de multiplicar de ese

    nmero. El programa es muy sencillo gracias a las sentencias de

    repeticin:

    #i ncl ude void mai n( void){

    short int n, i ;pr i nt f ( "Tabl a de mul t i pl i car del . . . " ) ;scanf ( "%hd" , &n) ;

    i = 0;while( i

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    20/60

    Fundamentos de informtica. Programacin en Lenguaje C

    106

    alguno de los parmetros que intervienen en la condicin. Ms adelante,

    en este captulo, veremos otras formas de salir de la iteracin.

    Este ltimo ejemplo ha sido sencillo. Veamos otro ejemplo que requiere

    un poco ms de imaginacin. Supongamos que queremos hacer un

    programa que solicite al usuario la entrada de un entero y que entonces

    muestre por pantalla el factorial de ese nmero. Ya se sabe la definicin

    de factorial: = ! ( 1) ( 2) ... 2 1n n n n .

    Antes de mostrar el cdigo de esta sencilla aplicacin, conviene volver a

    una idea comentada captulos atrs. Efectivamente, habr que saber

    decir en el lenguaje C cmo se realiza esta operacin. Pero previamente

    debemos ser capaces de expresar el procedimiento en castellano. En el

    captulo 4 de Fundamentos de Informtica. Codificacin y Algoritmia.

    se encuentra extensamente documentado este y otros muchos

    algoritmos de iteracin que veremos ahora implementados en C, en

    estas pginas.

    Veamos una posible solucin al programa del factorial:#i ncl ude void mai n( void){

    unsigned short n;unsigned long Fact;pr i nt f ( " I nt roduzca el ent ero . . . ") ;scanf ( "%hu" , &n) ;pr i nt f ( "El f act or i al de %hu es . . . " , n) ;Fact = 1;while( n ! = 0){

    Fact = Fact * n;

    n = n - 1;}pr i nt f ( "%l u. " , Fact ) ;

    El valor de la variable Fact se inicializa a uno antes de comenzar a

    usarla. Efectivamente es muy importante no emplear esa variable sin

    darle el valor inicial que a nosotros nos interesa. La variable n se

    inicializa con la funcin scanf.

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    21/60

    Captulo 4. Estructuras de control.

    107

    Mientras que n no sea cero, se ir multiplicando Fact (inicialmente a

    uno) con n. En cada iteracin el valor de n se ir decrementando en

    uno.

    La tabla de los valores que van tomando ambas variables se muestra en

    la tabla 4.1. (se supone que la entrada por teclado ha sido el nmero 5).

    Cuando la variable nalcanza el valor cero termina la iteracin. En ese

    momento se espera que la variable Facttenga el valor que corresponde

    al factorial del valor introducido por el usuario.

    La iteracin se ha producido tantas veces como el cardinal del nmero

    introducido. Por cierto, que si el usuario hubiera introducido el valor

    cero, entonces el bucle no se hubiera ejecutado ni una sola vez, y el

    valor de Fact hubiera sido uno, que es efectivamente el valor por

    definicin ( =0! 1 ).

    n 5 4 3 2 1 0Fact 5 20 60 120 120 120

    Tabla 4.1.: Valores que van tomando las variables delbucle del programa del clculo del factorial si la entradadel usuario ha sido n= 5.

    La estructura de control mostrada admite formas de presentacin ms

    compacta y, de hecho, lo habitual ser que as se presente. Por

    ejemplo:

    while( n != 0){

    Fact *= n;n = n - 1;

    }

    donde todo es igual excepto que ahora se ha hecho uso del operador

    compuesto en la primera sentencia del bloque. Pero an se puede

    compactar ms:

    1. La condicin de permanencia ser verdad siempre que nno sea cero.

    Y por definicin de verdad en C (algo es verdadero cuando es

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    22/60

    Fundamentos de informtica. Programacin en Lenguaje C

    108

    distinto de cero) se puede decir que la n != 0es verdadero s y slo

    si nes verdadero.

    2. Las dos sentencias simples iteradas en el bloque pueden

    condensarse en una sola: Fact *= n--;

    As las cosas, la estructura queda:

    while( n) Fact *= n- - ;

    Hacemos un comentario ms sobre la estructura w h i l e . Esta estructura

    permite iterar una sentencia sin cuerpo. Por ejemplo, supongamos que

    queremos hacer un programa que solicite continuamente del usuario

    que pulse una tecla, y que esa solicitud no cese hasta que ste

    introduzca el carcter, por ejemplo, a. La estructura quedar tan

    simple como lo que sigue:

    while( ( ch = get char ( ) ) ! = a ) ;

    Esta lnea de programa espera una entrada por teclado. Cuando sta se

    produzca comprobar que hemos tecleado el carcter a minscula; deno ser as, volver a esperar otro carcter.

    Una forma ms sencilla fcil de ver el significado de esta ltima lnea

    de cdigo vista sera expresarlo de la siguiente manera:

    while( ch ! = a )ch = get char ( ) ;

    Un ltimo ejemplo clsico de uso de la estructura w h i le . El clculo del

    mximo comn divisor de dos enteros que introduce el usuario por

    teclado.No es necesario explicar el concepto de mximo comn divisor. S es

    necesario en cambio explicar un mtodo razonable de plantear al

    ordenador cmo se calcula ese valor: porque este ejemplo deja claro la

    importancia de tener no slo conocimientos de lenguaje de

    programacin, sino tambin de algoritmos vlidos.

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    23/60

    Captulo 4. Estructuras de control.

    109

    Euclides, matemtico del siglo V a. de C. present un algoritmo muy

    fcil de implementar, y de muy bajo coste computacional. El algoritmo

    de Euclides dice que el mximo comn divisor de dos enteros 1a y 1b

    (diremos 1 1( , )mcd a b ), donde 1 0b es igual a 2 2( , )mcd a b donde

    =2 1a b y donde =2 1 1%b a b , entendiendo por 1 1%a b el resto de la

    divisin de 1a con 1b . Y el proceso puede seguirse hasta llegar a unos

    valores de ia y de ib que verifiquen que 0ia , 0ib y =% 0i ia b .

    Entonces, el algoritmo de Euclides afirma que, llegado a estos valores el

    valor buscado es =1 1( , ) imcd a b b .

    Ahora falta poner esto en lenguaje C. Ah va:

    #i ncl ude void mai n( void){

    short int a, b, aux;short int mcd;pr i nt f ( "Val or de a . . . " ) ;scanf ( "%hd" , &a) ;pr i nt f ( "Val or de b . . . " ) ;scanf ( "%hd" , &b) ;

    pr i nt f ( "El mcd de %hd y %hd es . . . ", a, b) ;while(b){

    aux = a % b;a = b;b = aux;

    }pr i nt f ( "%hu", a) ;

    }

    (De nuevo recordamos que se encuentran en el manual complementario

    a ste, titulado Fundamentos de Informtica. Codificacin y Algoritmia.

    explicaciones a este nuevo algoritmo y a otros muchos que veremos enestas pginas.)

    Hemos tenido que emplear una variable auxiliar, que hemos llamado

    aux, para poder hacer el intercambio de variables: que apase a valer el

    valor de by bel del resto de dividir apor b.

    As como queda escrito el cdigo, se irn haciendo los intercambios de

    valores en las variables ay bhasta llegar a un valor de bigual a cero;

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    24/60

    Fundamentos de informtica. Programacin en Lenguaje C

    110

    entonces, el anterior valor de b (que est guardado en a) ser el

    mximo comn divisor.

    Estructura d ow h i l e .

    La estructura d ow h i l e es muy similar a la anterior. La diferencia ms

    sustancial est en que con esta estructura el cdigo de la iteracin se

    ejecuta, al menos, una vez. Si despus de haberse ejecutado, la

    condicin se cumple, entonces vuelve a ejecutarse, y as hasta que la

    condicin no se cumpla. Puede verse un esquema de su comportamiento

    en la figura 4.3., en pginas anteriores.

    La sintaxis de la estructura es la siguiente:

    d o s e n t e n c ia w h i l e ( c o n d i c in ) ;

    Y si se desea iterar un bloque de sentencias, entonces se agrupan en

    una sentencia compuesta mediante llaves.

    Habitualmente, toda solucin a un problema resuelto con una

    estructura, es tambin solventable, de forma ms o menos similar, porcualquiera de las otras dos estructuras. Por ejemplo, la tabla de

    multiplicar quedara:

    #i ncl ude void mai n( void){

    short int n, i = 0;pr i nt f ( "Tabl a de mul t i pl i car del . . . " ) ;scanf ( "%hd" , &n) ;do

    {pr i nt f ( "%3hu * %3hu = %3hu\ n" , i , n, i * n) ;i ++:

    }while( i

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    25/60

    Captulo 4. Estructuras de control.

    111

    cdigo ahora requiere de otra estructura de repeticin, que vuelva a

    ejecutar el cdigo mientras que el usuario no diga basta. Una posible

    codificacin de este proceso sera (ver figura 4.7.):

    #i ncl ude void mai n( void){

    unsigned short n;unsigned long Fact;char opci on;do{

    Fact = 1;pr i nt f ( " \ n\ nI nt roduzca el ent ero . . . ") ;scanf ( "%hu" , &n) ;pr i nt f ( "El f act or i al de %hu es . . . " , n) ;while( n ! = 0) Fact *= n- - ;pr i nt f ( " %l u. " , Fact ) ;pr i nt f ( " \ n\ nCal cul ar ot ro fact or i al (s / n) " ) ;

    }while( opci on = get char ( ) == ' s' ) ;}

    La estructura d ow h i l e repetir el cdigo que calcula el factorial del

    entero solicitado mientras que el usuario responda con una s a la

    pregunta de si desea que se calcule otro factorial.

    Podemos afinar un poco ms en la presentacin. Vamos a rechazar

    cualquier contestacin que no sea o s o n: si el usuario responde s,

    entonces se repetir la ejecucin del clculo del factorial; si responde n

    el programa terminar su ejecucin; y si el usuario responde cualquier

    otra letra, entonces simplemente ignorar la respuesta y seguir

    esperando una contestacin vlida.

    Figura 4.7.: Flujogramapara repeticin de proceso.

    repetir

    C

    F

    S No

    PROCESO

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    26/60

    Fundamentos de informtica. Programacin en Lenguaje C

    112

    El cdigo queda ahora de la siguiente manera:

    #i ncl ude void mai n( void){

    unsigned short n;unsigned long Fact;char opci on;do{

    Fact = 1;pr i nt f ( " \ n\ nI nt r oduzca el ent er o . . . ") ;scanf ( "%hu", &n) ;

    pr i nt f ( "El f actor i al de %hu es . . . " , n) ;

    while( n ! = 0) Fact *= n- - ;

    pr i nt f ( " %l u. " , Fact ) ;pr i nt f ( " \ n\ nCal cul ar ot ro factor i al (s / n) " ) ;

    doopci on = getchar ( ) ;

    while ( opci on ! = s && opci on ! = n ) ;}while( opci on = get char ( ) == ' s' ) ;

    }

    Ahora el valor de la variable opcion se ir pidiendo mientras que elusuario no introduzca correctamente una de las dos respuestas vlidas:

    o s (s), o no (n). El flujograma de esta nueva solucin queda recogido

    en la figura 4.8.

    C1

    C

    F

    S No

    Figura 4.8.: Flujogramapara repeticin de proceso.

    PROCESO

    opcion

    C2S No

    1 ' ' | ' 'C opcion s opcion n

    =2 ' 'C opcion s

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    27/60

    Captulo 4. Estructuras de control.

    113

    Estructura f o r.

    Una estructura f o rtiene una sintaxis notablemente distinta a la indicada

    para las estructuras w h i l e y d ow h i l e . Pero la funcin que realiza es la

    misma. Con la palabra reservada f o r podemos crear estructuras de

    control que se dicen controladas por variable.

    La sintaxis de la estructura f o res la siguiente:

    f o r ( s e n t e n c i a s _ 1 , e x p r e s i n ; se n t e n c i a s_ 2 ) s e n t e n c i a _ 3 ;

    Donde s e n t e n c i a 3 es la sentencia que se itera, la que queda

    gobernada por la estructura de control f o r.

    Donde s e n t e n c i a s _ 1 es un grupo de sentencias que se ejecutan antes

    que ninguna otra en una estructura f o r, y siempre se ejecutan una vez

    y slo una vez. Son sentencias, separadas por el operador coma, de

    inicializacin de variables.

    Donde e x p r e s i n es la condicin de permanencia en la estructura

    f o r. Siempre que se cumpla expresin volver a ejecutarse la sentencia

    iterada por la estructura f o r.

    e1

    C

    F

    S No

    Figura 4.9.: Flujograma laestructura de controlf o r(s1 ; e1 ; s2) s3;

    s1

    s3

    s2

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    28/60

    Fundamentos de informtica. Programacin en Lenguaje C

    114

    Donde s e n t e n c i a s _ 2 son un grupo de sentencias que se ejecutan

    despus de la sentencia iterada(despus de sentencia_3).

    El orden de ejecucin es, por tanto (ver flujograma en figura 4.9.):

    1. Se inicializan variables segn el cdigo recogido en sentencias_1.

    2. Se verifica la condicin de permanencia recogida en expresin. Si

    expresines verdadero se sigue en el paso 3; si es falso entonces se

    sigue en el paso 6.

    3. Se ejecuta la sentencia iterada llamada, en nuestro esquema de

    sintaxis, sentencia_3.

    4. Se ejecutan las sentencias recogidas en sentencias_2.

    5. Vuelta al paso 2.

    6. Fin de la iteracin.

    As, una estructura f o r es equivalente a una estructura w h i l e de la

    forma:

    s e n t e n c i a s _ 1 ;w h i l e ( e x p r e s in ){

    s e n t e n c i a _ 3 ;s e n t e n c i a s _ 2 ;

    }

    Por ejemplo, veamos un programa que muestra por pantalla los enteros

    pares del 1 al 100:

    #i ncl ude void mai n( void)

    {short i ;for( i = 2 ; i

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    29/60

    Captulo 4. Estructuras de control.

    115

    { short i ;for( i = 2 ; i

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    30/60

    Fundamentos de informtica. Programacin en Lenguaje C

    116

    Bloquear la ejecucin hasta que se pulse la tecla a:

    for( ; ch ! = a ; ch = get char ( ) ) ;

    Bsqueda del mximo comn divisor de dos enteros:

    for( ; b ; ){

    aux = a % b;a = b;b = aux;

    }pr i nt f ( "%hu", a) ;

    Sentencias de salto: b r e a k y c o n t i n u e .

    Hay dos sentencias que modifican el orden del flujo de instrucciones

    dentro de una estructura de iteracin. Son las sentencias b r e a k y

    c o n t i n u e . Ambas sentencias, en una estructura de iteracin, se

    presentan siempre condicionadas.

    Una sentencia b r e a k dentro de un bloque de instrucciones de una

    estructura de iteracin interrumpe la ejecucin de las restantes

    sentencias iteradas y abandona la estructura de control, asignando al

    contador de programa la direccin de la siguiente sentencia posterior a

    la llave que cierra el bloque de sentencias de la estructura de control.

    Por ejemplo, podemos hacer un programa que solicite al usuario que

    vaya introduciendo nmeros por teclado hasta que la entrada sea un

    nmero par. En ese momento el programa abandonar la solicitud de

    datos e indicar cuntos enteros ha introducido el usuario hasta

    introducir uno que sea par. El cdigo podra quedar as:

    #i ncl ude void mai n( void){

    short i , num;for( i = 1 ; ; i ++){

    pr i nt f ( " I nt r oduzca un ent er o . . . ") ;scanf ( "%hd", &num) ;if( num % 2 == 0) break;

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    31/60

    Captulo 4. Estructuras de control.

    117

    }pr i nt f ( "Ha i nt r oduci do el ent er o par %hd" , num) ;pr i nt f ( " despus de %hd i mpar es. ", i - 1) ;

    }

    Se habrn introducido tantos enteros como indique la variable i. De

    ellos, todos menos el ltimo habrn sido impares. Desde luego, el

    cdigo hara lo mismo si la expresin que condiciona al b r e a k se

    hubiese colocado en el segundo espacio que ofrece la sintaxis del f o r

    (all donde se colocan las condiciones de permanencia) y se hubiese

    cambiado en algo el cdigo; pero no resulta intuitivamente tan sencillo.Si comparamos la estructura forvista arriba con otra similar, en la que

    la condicin de salto queda recogida en el for tendremos:

    for( i = 1 ; ; i ++){

    pr i nt f ( "ent ero: " ) ; scanf ( "%hd" , &num) ;

    if( num % 2 == 0)break;}

    for( i = 1 ; num%2 == 0 ; i ++){

    pr i nt f ( " entero: " ) ; scanf ( "%hd", &num) ;}

    Aparentemente ambos cdigos hacen lo mismo. Pero si comparamos sus

    flujogramas recogidos en la figura 4.10. veremos que se ha introducidouna diferencia no pequea.

    Habitualmente esta sentencia b r e a k siempre podr evitarse con un

    diseo distinto de la estructura de control. Segn en qu ocasiones, el

    cdigo adquiere mayor claridad si se utiliza el b r e a k . El uso de la

    sentencia de salto b r e a k es prctica habitual en la programacin

    estructurada como es el caso del paradigma del lenguaje C.

    Figura 4.10.: Salto con o sin b r e a k .

    =1 mod2 0C num

    C1

    1i

    + 1i i

    F

    C

    num

    C1

    1i + 1i i

    F

    Cnum

    Con b r e a k Sin b r e a k

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    32/60

    Fundamentos de informtica. Programacin en Lenguaje C

    118

    Con la sentencia b r e a k es posible definir estructuras de control sin

    condicin de permanencia, o con una condicin que es siempre

    verdadera. Por ejemplo:

    long int suma = 0, num;do{

    pr i nt f ( I nt r oduzca un nuevo sumando . . . ) ;scanf ( %l d, &num) ;if( num % 2 ! = 0) break;suma += num;

    }while( 1 ) ;

    pr i nt f ( La suma es . . . %l d, suma) ;

    En esta estructura, la condicin de permanencia es verdadera siempre,

    por definicin, puesto que es un literal diferente de cero. Pero hay una

    sentencia b r e a k condicionada dentro del bloque iterado. El cdigo ir

    guardando en la variable sumala suma acumulada de todos los valores

    introducidos por teclado mientras que esos valores sean enteros pares.

    En cuanto se introduzca un entero impar se abandona la estructura de

    iteracin y se muestra el valor sumado.

    El diagrama de flujo de este ltimo ejemplo queda recogido en la figura

    4.11.

    Tambin se pueden tener estructuras f o rsin ninguna expresin recogida

    entre sus parntesis. Por ejemplo:

    for( ; ; ){

    ch = get char ( ) ;

    Figura 4.11.: Otro ejemplo de salto con b r e a k .

    C1

    F

    C

    0suma

    +

    sumasuma num

    num

    1 mod2 0C num

    suma

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    33/60

    Captulo 4. Estructuras de control.

    119

    pr i nt f ( Esto es un bucl e i nf i ni t o\ n);if( ch == a ) break;}

    que repetir la ejecucin del cdigo hasta que se pulse la tecla a, y que

    ocasionar la ejecucin del b r e a k .

    Una sentencia c o n t i n u e dentro de un bloque de instrucciones de una

    estructura de iteracin interrumpe la ejecucin de las restantes

    sentencias iteradas y vuelve al inicio de las sentencias de la estructura

    de control, si es que la condicin de permanencia as lo permite.

    Veamos, por ejemplo, el programa antes presentado que muestra por

    pantalla los 100 primeros enteros pares positivos. Otro modo de

    resolver ese programa podra ser el siguiente:

    #i ncl ude void mai n( void){

    short i ;for( i = 1 ; i

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    34/60

    Fundamentos de informtica. Programacin en Lenguaje C

    120

    permanencia en la iteracin as lo permite, vuelve a comenzar la

    iteracin por su primera sentencia del bloque iterado. El diagrama de

    flujo del cdigo escrito queda recogido en la figura 4.12.

    Palabra reservada g o t o .

    La palabra reservada de C g o t o no debe ser empleada.

    La sentencia de salto g o t o no respeta las reglas de la programacin

    estructurada. Todo cdigo que se resuelve empleando una sentencia

    g o t o puede encontrar una solucin mejor con una estructura de

    iteracin.

    Si alguna vez ha programado con esta palabra, la recomendacin es que

    se olvide de ella. Si nunca lo ha hecho, la recomendacin es que la

    ignore.

    Y, eso s: hay que acordarse de que esa palabra es clave en C: no se

    puede generar un identificador con esa cadena de letras.

    Variables de control de iteraciones.

    Hasta el momento, hemos hecho siempre uso de las variables para

    poder almacenar valores concretos. Pero pueden tener otros usos. Por

    ejemplo, podemos hacer uso de ellas como chivatos o centinelas: su

    informacin no es el valor concreto numrico que puedan tener, sino la

    de una situacin del proceso.

    Como vamos viendo en los distintos ejemplos que se presentan, el

    diseo de bucles es tema delicado: acertar en la forma de resolver un

    problema nos permitir llevar solucin a muy diversos problemas. Pero,

    como estamos viendo, es importante acertar en un correcto control del

    bucle: decidir bien cuando se ejecuta y cuando se abandona.

    Existen dos formas habituales de controlar un bucle o iteracin:

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    35/60

    Captulo 4. Estructuras de control.

    121

    1. Control mediante variable contador. En ellos una variable se

    encarga de contar el nmero de veces que se ejecuta el cuerpo del

    bucle. Esos contadores requieren una inicializacin previa, externa al

    bucle, y una actualizacin en cada iteracin para llegar as

    finalmente a un valor que haga falsa la condicin de permanencia.

    Esa actualizacin suele hacerse al principio o al final de las

    sentencias iteradas. Hay que garantizar, cuando se disea una

    iteracin, que se llega a una situacin de salida.

    2. Control por suceso. Este tipo de control acepta, a su vez,

    diferentes modalidades:

    2.1.Consulta explcita: El programa interroga al usuario si desea

    continuar la ejecucin del bucle. La contestacin del usuario

    normalmente se almacena en una variable tipo c h a r o i n t. Es el

    usuario, con su contestacin, quien decida la salida de la

    iteracin.

    2.2.

    Centinelas: la iteracin se termina cuando la variable de controltoma un valor determinado. Este tipo de control es usado

    habitualmente para introducir datos. Cuando el usuario

    introduce el valor que el programador ha considerado como

    valor de fin de iteracin, entonces, efectivamente, se termina

    esa entrada de datos. As lo hemos visto en el ejemplo de

    introduccin de nmeros, en el programa del clculo de la

    media, en el que hemos considerado que la introduccin del

    valor cero era entendido como final de la introduccin de datos.

    2.3.Banderas: Es similar al centinela, pero utilizando una variable

    lgica que toma un valor u otro en funcin de determinadas

    condiciones que se evalan durante la ejecucin del bucle. As se

    puede ver, por ejemplo, en el ejercicio 7 planteado al final de

    captulo: la variable que hemos llamado chivatoes una variable

    bandera.

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    36/60

    Fundamentos de informtica. Programacin en Lenguaje C

    122

    Normalmente la bandera siempre se puede sustituir por un

    centinela, pero se emplea en ocasiones donde la condicin de

    terminacin resulta compleja y depende de varios factores que se

    determinan en diferentes puntos del bucle.

    Recapitulacin.

    Hemos presentado las estructuras de control posibles en el lenguaje C.

    Las estructuras condicionales de bifurcacin abierta o cerrada,condicionales anidadas, operador interrogante, dos puntos, y sentencia

    s w i t ch . Tambin hemos visto las posibles iteraciones creadas con las

    estructuras f o r, w h i l e y d o w h i l e , y las modificaciones a las

    estructuras que podemos introducir gracias a las palabras reservadas

    b r e a k y c o n t i n u e .

    El objetivo final de este tema es aprender unas herramientas de enorme

    utilidad en la programacin. Conviene ahora ejercitarse en ellas,

    resolviendo ahora los diferentes ejercicios propuestos.

    Ejercicios.

    En todos los ejercicios que planteamos a continuacin quiz ser

    conveniente que antes de abordar la implementacin se intente disear

    un algoritmo en pseudocdigo o mediante un diagrama de flujo. Si en

    algn caso el problema planteado supone especial dificultad quedarrecogido ese flujograma en estas pginas. En bastantes casos, puede

    consultarse ste en las pginas del manual Fundamentos de

    informtica. Codificacin y algoritmia.

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    37/60

    Captulo 4. Estructuras de control.

    123

    2 0 . Ca l c u l a r l a s um a d e l o s p a r e s p o s i t i v o s m e n o r e s o i g u a l a 2 0 0 .

    #i ncl ude void mai n( void){

    long suma = 0;short i ;for( i = 2 ; i

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    38/60

    Fundamentos de informtica. Programacin en Lenguaje C

    124

    2 2 . M o s t r a r p o r p a n t a l l a l o s n m e r o s p e r f e c t o s m e n o r e s d e 1 0 0 0 0 .

    Se e n t i e n d e p o r nm e r o p e r f e c t o a q u e l q u e e s ig u a l a l a sum a

    d e s u s d i v i so r e s . P o r e j e m p l o , 6 = 1 + 2 + 3 q u e s o n ,

    e f e c t i v am e n t e , s u s d i v i s o r e s .

    #i ncl ude void mai n( void){

    short suma;short i , num;for( num = 2 ; num < 10000 ; num++){

    for( i = 1, suma = 0 ; i

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    39/60

    Captulo 4. Estructuras de control.

    125

    2 3 . S o l i c i t a r d e l u s u a r i o c u a t r o nm e r o s y m o s t r a r l o s p o r p a n t a l l a

    o r d e n a d o s d e m e n o r a m a y o r .

    #i ncl ude void mai n( void){

    unsigned short int a0, a1, a2, a3;

    pr i nt f ( "I nt r oduzca cuat r o ent er os . . . \ n\ n") ;pr i nt f ( "Pr i mer ent ero . . . " ) ;scanf ( "%hu" , &a0) ;pr i nt f ( "Segundo ent er o . . . ") ;scanf ( "%hu" , &a1) ;pr i nt f ( "Tercer ent ero . . . " ) ;scanf ( "%hu" , &a2) ;pr i nt f ( "Cuart o ent er o . . . ") ;scanf ( "%hu" , &a3) ;if( a0 > a1){

    a0 = a1;a1 = a0;

    a0 = a1;}if( a0 > a2){

    a0 = a2;a2 = a0;a0 = a2;

    }if( a0 > a3){

    a0 = a3;a3 = a0;a0 = a3;

    }if( a1 > a2){

    a1 = a2;a2 = a1;a1 = a2;

    }if( a1 > a3){

    a1 = a3;a3 = a1;a1 = a3;

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    40/60

    Fundamentos de informtica. Programacin en Lenguaje C

    126

    }if( a2 > a3){

    a2 = a3;a3 = a2;a2 = a3;

    }pr i nt f ( " \ nOrdenados. . . \ n") ;pr i nt f ( "%hu

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    41/60

    Captulo 4. Estructuras de control.

    127

    bien. De hecho no existe error sintctico alguno. El error se ver en

    tiempo de ejecucin, cuando se compruebe que se ha cado en un bucle

    infinito.

    Para comprobarlo basta observar la condicin de permanencia en la

    iteracin gobernada por la estructura f o r, mediante la variable que

    hemos llamado a: a

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    42/60

    Fundamentos de informtica. Programacin en Lenguaje C

    128

    signed long a;unsigned long Test;char opci on;do{

    Test = 0x80000000;pr i nt f ( " \ n\ nI ndi que el entero . . . " ) ;scanf ( "%l d", &a) ;while(Test){

    Test & a ? pr i nt f ( "1") : pr i nt f ( "0") ;Test >>= 1;

    }

    pr i nt f ( "\ nDesea i nt r oduci r otr o ent er o? . . . ") ;doopci on = getchar ( ) ;

    while ( opci on ! = ' s' && opci on ! = ' n' ) ;}while( opci on == ' s' ) ;

    }

    La variable Test se inicializa al valor hexadecimal 80000000, es decir,

    con un 1 en el bit ms significativo y en cero en el resto. Posteriormente

    sobre esta variable se va operando un desplazamiento a derecha de un

    bit cada vez. As, siempre tenemos localizado un nico bit en la

    codificacin de la variable Test, hasta que este bit se pierda por la partederecha en un ltimo desplazamiento.

    Antes de cada desplazamiento, se realiza la operacin and a nivel de bit

    entre la variable Test, de la que conocemos donde est su nico bit, y la

    variable de la que queremos conocer su cdigo binario.

    En el principio, tendremos as las dos variables:

    Test 1000 0000 0000 0000 0000 0000 0000 0000a xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx

    Test & a x000 0000 0000 0000 0000 0000 0000 0000Tenemos certeza de que la operacin and dejar un cero en todos los

    bits (menos el ms significativo) de Test & a, porque Test tiene todos

    esos bits a cero. Todos menos el primero. Entonces la operacin dar

    un valor distinto de cero nicamente si en ese bit se encuentra un 1 en

    la variable a. Sino, el resultado de la operacin ser cero.

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    43/60

    Captulo 4. Estructuras de control.

    129

    Al desplazar ahora Test un bit a la derecha tendremos la misma

    situacin que antes, pero ahora el bit de atesteado ser el segundo por

    la derecha.

    Test 0100 0000 0000 0000 0000 0000 0000 0000a xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxxTest & a 0x00 0000 0000 0000 0000 0000 0000 0000

    Y as sucesivamente, imprimiremos un 1 cuando la operacin and sea

    diferente de cero, e imprimiremos un 0 cuando la operacin and d un

    valor igual a cero.

    El programa que hemos presentado permite al usuario ver el cdigo de

    tantos nmeros como quiera introducir por teclado: hay una estructura

    d ow h i l e que anida todo el proceso.

    2 6 . Es c r i b i r u n p r o g r am a q u e s o l i ci t e a l u s u a r i o u n e n t e r o p o s i t i v o

    e i n d i q u e s i es e n m e r o i n t r o d u c i d o e s p r i m o o c om p u e s t o .

    #i ncl ude #i ncl ude void mai n( void){

    unsigned long int numer o, r ai z;unsigned long int di v;char chi vat o;pr i nt f ( "Dame el numero que vamos a testear . . . " ) ;scanf ( "%l u" , &numero) ;chi vat o = 0;r ai z = sqr t ( numer o) ;for( di v = 2 ; di v

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    44/60

    Fundamentos de informtica. Programacin en Lenguaje C

    130

    Antes de explicar brevemente el algoritmo, conviene hacer una digresin

    sencilla matemtica: todo entero verifica que, si tiene divisores distintos

    del 1 y del mismo nmero (es decir, si es compuesto), al menos uno de

    esos divisores es menor que su raz cuadrada. Eso es sencillo de

    demostrar por reduccin al absurdo: supongamos que tenemos un

    entero n y que tiene dos factores distintos de 1 y de n ; por ejemplo, a

    y b , es decir, = n a b . Supongamos que ambos factores son mayores

    (estrictamente mayores) que la raz cuadrada de n . Entonces

    tendremos:

    = < =

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    45/60

    Captulo 4. Estructuras de control.

    131

    estructura f o r es verificar el valor de esa variable contador. Si la

    variable dives mayor que raizentonces est claro que hemos salido del

    bucle por haber terminado la bsqueda de posibles divisores y numero

    es primo. Si dives menor o igual que raiz, entonces est tambin claro

    que hemos encontrado un divisor: es otra forma de hacer el programa,

    sin necesidad de crear la variable chivato.

    El cdigo, en ese caso, podra quedar de la siguiente manera:

    #i ncl ude

    #i ncl ude void mai n( void){

    unsigned long int n, r ai z;unsigned long int di v;pr i nt f ( "Dame el numero que vamos a testear . . . " ) ;scanf ( "%l u", &n) ;r ai z = sqr t ( n) ;for( di v = 2 ; di v r ai z ? pr i mo: compuest o) ;

    }

    2 7 . Es c r i b a u n p r o g r am a q u e m u e s t r e p o r p a n t a l l a u n trm i n o

    c u a l q u i e r a d e l a s e r i e d e Fi b o n a c c i .

    La serie de Fibonacci est definida de la siguiente manera: el primer y el

    segundo elementos son iguales a 1. A partir del tercero, cualquier otro

    elemento de la serie es igual a la suma de sus dos elementos anteriores.

    Escribir el cdigo es muy sencillo una vez se tiene el flujograma. Intentehacer el flujograma, o consulte pgina 60 del manual Fundamentos de

    Informtica. Codificacin y Algoritmia.

    #i ncl ude

    void mai n( void){

    unsigned long f i b1 = 1, f i b2 = 1, Fi b = 1;unsigned short n, i = 3;

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    46/60

    Fundamentos de informtica. Programacin en Lenguaje C

    132

    pr i nt f ( "I ndi que el el ement o que se debe most r ar . . . ") ;scanf ( "%hu" , &n) ;

    while( i

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    47/60

    Captulo 4. Estructuras de control.

    133

    pr i nt f ( "x1: %l f + %l f * i \ n", - b/ ( 2*a) , r / ( 2*a) ) ;pr i nt f ( " x2: %l f + %l f * i \ n" , - b/ (2*a) , - r / ( 2*a) ) ;}/ / Ecuaci n de segundo gr ado. Sol uci ones r eal es.else{

    pr i nt f ( "Las sol uci ones son: \ n") ;r = sqrt ( r ) ;pr i nt f ( " \ t x1 - - > %l f \ n", ( - b + r ) / ( 2 * a) ) ;pr i nt f ( " \ t x2 - - > %l f \ n" , ( - b - r ) / (2 * a) ) ;

    }}

    2 9 . Es cr i b a u n p r o g r a m a q u e m u e s t r e t o d o s l o s d i v i so r e s d e u n

    e n t e r o q u e s e r e c ib e com o e n t r a d a d e l a l g o r i t m o .

    #i ncl ude

    void mai n( void){

    long int numer o;long int di v;

    pr i nt f ( "Nmer o - - > ") ;scanf ( "%l d" , &numer o) ;

    pr i nt f ( "\ n\ nLos di vi sor es de %l d son: \ n\ t ", numer o) ;pr i nt f ( "1, " ) ;

    for( di v = 2 ; di v 456Los divisores de 456 son:

    1, 2, 3, 4, 6, 8, 12, 19, 24, 38, 57, 76, 114, 152, 228, 456.

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    48/60

    Fundamentos de informtica. Programacin en Lenguaje C

    134

    3 0 . Es c r i b a u n p r o g r am a q u e c a l cu l e e l nm e r o , s a b i e n d o q u e

    e s t e nm e r o v e r i f i ca l a s i g u i e n t e r e l a c i n :

    =

    =2

    21

    16 k k

    .

    #i ncl ude #i ncl ude

    #def i ne LI MI TE 10000

    void mai n( void){

    double PI = 0;

    for( int i = 1 ; i < LI MI TE ; i ++)PI += 1. 0 / ( i * i ) ;

    PI *= 6;PI = sqrt ( PI ) ;pr i nt f ( "El val or de PI es . . . %l f . " , PI ) ;

    }

    Que ofrece la siguiente salida por pantalla:

    El valor de PI es ... 3.141497.

    El programa va haciendo, en la iteracin gobernada por la estructura

    f o r, el sumatorio de los inversos de los cuadrados. El numerador se

    debe poner como 1.0 para que el resultado del cociente no sea un

    entero igual a cero sino un valor d o u b l e .

    3 1 . Es c r i b a u n p r o g r am a q u e c a l cu l e e l nm e r o , s a b i e n d o q u e

    e s t e nm e r o v e r i f i ca l a s i g u i e n t e r e l a c i n :

    ( )

    =

    =

    +01

    4 2 1

    k

    k k

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    49/60

    Captulo 4. Estructuras de control.

    135

    #i ncl ude #def i ne LI MI TE 100000

    void mai n( void){

    double PI = 0;

    for( int i = 1 , e = 4 ; i < LI MI TE ; i += 2 , e = - e)PI += e / ( double) i ;

    pr i nt f ( "El val or de PI es . . . %l f . " , PI ) ;}

    Que ofrece la siguiente salida por pantalla:El valor de PI es ... 3.141573.

    La variable PI se inicializa a cero. En cada iteracin ir almacenando la

    suma de todos los valores calculados. En lugar de calcular 4 ,

    calculamos directamente el valor de : por eso el numerador (variable

    que hemos llamado e) no vara entre -1 y +1, sino entre -4 y +4. El

    valor de la variable i aumenta de dos en dos, y va tomando los

    diferentes valores del denominador +2 1k . Es necesario forzar el tipo

    de la variable ia double, para que el resultado de la operacin cociente

    no sea un entero, que a partir de iigual a cero dara como resultado el

    valor cero.

    3 2 . Es c r i b a u n p r o g r am a q u e c a l cu l e e l nm e r o , s a b i e n d o q u e

    e s t e nm e r o v e r i f i ca l a s i g u i e n t e r e l a c i n :

    = 2 2 4 4 6 6 8 8

    ...

    2 1 3 3 5 5 7 7 9.

    De nuevo el clculo del valor del nmero pi. Estos ejercicios son muy

    sencillos de buscar (Internet est llena de definiciones de propiedades

    del nmero pi) y siempre es fcil comprobar si hemos realizado un buen

    cdigo: basta ejecutarlo y comprobar si sale el famoso 3.14.

    En esta ocasin, el cdigo podra tomar la siguiente forma:

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    50/60

    Fundamentos de informtica. Programacin en Lenguaje C

    136

    #i ncl ude #def i ne LI MI TE 100000void mai n( void){

    double PI = 2;for( int num = 2 , den = 1, i = 1 ;i < LI MI TE ; i ++ , i % 2 ? num+=2 : den+=2)

    PI *= num / ( double) den;pr i nt f ( "El val or de PI es . . . %l f . " , PI ) ;

    }

    Por problemas de espacio se ha tenido que mostrar la estructura for

    truncada en dos lneas. Esta forma de escribir es perfectamente vlida

    en C. El compilador considera lo mismo un espacio en blanco que tres

    lneas blancas. Para el compilador estos dos cdigos significan lo mismo:

    short int a = 0 , b = 1, c = 2;double x , y , z ;short int

    a = 0,b = 1,c = 2,

    doublex,y , z ;

    3 3 . Ci n c o m a r i n e r o s l l e g a n , t r a s u n n a u f r a g i o , a u n a i s la d e s i e r t a

    c o n u n g r a n nm e r o d e c o c o t e r o s y u n p e q u eo m o n o . D e d i c a n

    e l p r im e r d a a r e c o l e c t a r c o c o s , p e r o e j e c u t a n c o n t a n t o a fn

    e s t e t r a b a j o q u e a c a b a n a g o t a d o s , p o r l o q u e d e c i d e n

    r e p a r t i r s e l o s c o c o s a l da s i g u i e n t e .

    D u r a n t e l a n o c h e u n m a r i n e r o s e d e sp i e r t a y , d e sc o n f ia n d o d e

    s u s c om pae r o s , d e c i d e t om a r s u p a r t e . P a r a e l l o , d i v i d e e l

    m o n t n d e c o c o s e n c i n c o p a r t e s i g u a l e s , s o b rn d o l e u n c o c o ,

    q u e r e g a l a a l m o n o . U n a v e z c a l cu l a d a s u p a r t e l a e s c o n d e y s e

    v u e l v e a a c o s t a r .

    U n p o c o m s t a r d e o t r o m a r i n e r o t am b in s e d e s p i e r t a y v u e l v e

    a r e p e t i r l a o p e r a c i n , s o b rnd o l e t am b in u n c o c o q u e r e g a l a

    a l m o n o . En e l r e s t o d e l a n o c h e s u c e d e lo m i sm o c o n l o s o t r o s

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    51/60

    Captulo 4. Estructuras de control.

    137

    t r e s m a r i n e r o s.

    A l l e v a n t a r s e p o r l a m aana p r o c e d i e r o n a r e p a r t i r s e l o s c o c o s

    q u e q u e d a b a n e n t r e e l lo s c in c o , n o s o b r a n d o a h o r a n i n g u n o .

    Cun t o s co co s h a b an r e c o g i d o i n i c i a lm e n t e ? Mo s t r a r t o d a s la s

    s o l u c i o n e s p o s i b l e s m e n o r e s d e 1 m i l l n d e c o c o s .

    Este programa es sencillo de implementar. Pero hay que saber resolverel problema. Es un ejemplo de cmo saber un lenguaje no lo es todo en

    programacin; ms bien podramos decir que saber un lenguaje es lo de

    menos: lo importante es saber qu decir.

    Este algoritmo est ya explicado en el otro manual, ya tantas veces

    referenciado en ste. Aqu dejamos slo el cdigo resultante.

    #i ncl ude

    void mai n( void){

    unsigned long N = 6, n;unsigned long sol uci ones = 0;

    pri nt f ( "Val or es posi bl es de N . . . \ n\ n") ;

    while( N < 4000000){

    unsigned short int i ;N += 5;n = N;for( i = 0 ; i < 5 ; i ++){

    if( (n - 1 ) %5)break;n = 4 * ( n - 1) / 5;

    }if( i == 5 && ! ( n % 5) ){

    pr i nt f ( "( %4l u) %- 8l u", ++sol uci ones, N) ;if( ! ( sol uci ones %5) ) pr i nt f ( " \ n") ;

    }}

    }

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    52/60

    Fundamentos de informtica. Programacin en Lenguaje C

    138

    3 4 . El c a l en d a r i o j u l i a n o ( d e b i d o a j u l i o Ce s a r ) c o n s i d e r a b a q u e e l

    ao d u ra ba 3 65 . 25 das , p o r l o q u e se es t ab l e c i q u e l o s aos

    t e nd ran un a d u r a c i n d e 3 65 das y cad a cu a t r o aos se

    aad ie se u n d a m s ( ao b is ie s t o ) .

    Si n em b a r g o s e c om p r o b q u e e n r e a l i d a d e l ao t i e n e

    3 6 5 . 2 4 2 2 da s , l o q u e i m p l i c a q u e e l c a le n d a r i o j u l i a n o l l e v a s e

    u n d e s f a se d e u n o s o n c e m i n u t o s . Es t e er r o r e s r e l a t iv a m e n t e

    p e q u eo , p e r o , c o n e l t r a n s c u r r i r d e l t i em p o , e l e r r o ra c u m u l a d o p u e d e se r im p o r t a n t e .

    El p a p a G r e g o r io X I I , e n 1 5 8 2 , p r o p u s o r e f o r m a r e l c a l e n d a r io

    j u l i a n o p a r a e v i t a r l o s e r r o r e s a r r a s t r a d o s d e ao s a n t e r i o r e s .

    L o s a cu e r d o s t om a d o s e n t o n c e s , q u e s o n p o r l o s q u e n o s an

    n o s r e g i m o s , f u e r o n l o s si g u i e n t e s :

    P ar a s u p r i m i r e l e r r o r a c u m u l a d o p o r e l c a l e n d a r io j u l i an o ,

    s e s u p r im i e r o n d i e z da s . De t a l m a n e r a q u e e l d a s i g u i e n t e

    a l 4 d e o c t u b r e d e 1 5 8 2 f u e l e l da 1 5 d e l m i sm o m e s .

    La d u ra c in d e l o s aos se ra d e 3 6 5 d as o 3 6 6 e n ca so d e

    s e r b i s i e s t o .

    Se rn b i s i e s t o s t o d o s l o s aos q ue sean m l t i p l o s d e 4 ,

    s a l v o l o s q u e f i n a l i z a n e n 0 0 , q u e sl o l o s e rn c u a n d o

    t am b in s e a n m l t i p l o s d e 4 0 0 , p o r e j em p l o 1 8 0 0 n o f u e

    b i s i e s t o y e l 2 00 0 s.

    Con e s t a r e f o r m a e l d e s f a s e e x i s t e n t e e n t r e e l ao c i v i l y e lao r e a l s e r e d u c e a m en o s d e t r e i n t a s e g u n d o s a n u a l e s .

    D e f i n i r u n a l g o r i t m o q u e s o l i c i t e a l u s u a r i o u n a f e c h a

    i n t r o d u c i d a m ed i a n t e t r e s d a t o s : d a , m e s y ao ; e s e p r o g r am a

    d e b e v a l i d a r l a f e c h a : e s d e ci r c om p r o b a r q u e l a f e ch a e s

    c o r r e c t a c um p l i e n d o l a s s i g u i e n t e s r e g l a s :

    E l ao de be se r m ay o r q ue 0 .

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    53/60

    Captulo 4. Estructuras de control.

    139

    El m e s d e b e s er u n n m e r o e n t r e u n o y d o c e .

    El da d e b e e s t a r e n t r e 1 y 3 0 , 3 1 , 2 8 2 9 d e p e n d i e n d o e l

    m e s d e q u e s e t r a t e y s i e l ao e s b i s i e s t o o n o .

    Se deja propuesto. En otro lugar est recogido el flujograma del

    algoritmo.

    3 5 . Ca l c u l e e l v a l o r d e l nm e r o e . s a b i e n d o q u e v e r i f i ca l a s i g u i e n t e

    r e l a c i n :

    = + + + +1 1 1 1

    ...0! 1! 2! 3!

    e

    #i ncl ude void mai n( void)

    {double p = 1, e = 1;for( short n = 1 ; n < 100 ; n++){

    p *= 1. 0 / n;e += p;

    }pr i nt f ( "El numer o e es . . . %20. 17l f . ", e) ;

    }

    3 6 . J u e g o d e la s 1 5 c e r i l la s : P a r t i c ip a n d o s j u g a d o r e s .I n i c ia l m e n t e s e c o lo c a n 1 5 c e r i l la s s o b r e u n a m e s a y c a d a u n o

    d e l o s d o s j u g a d o r e s t o m a , a lt e r n a t i v a m e n t e 1 , 2 o 3 c e r i l la s

    p i e r d e e l j u g a d o r q u e t om a l a l t i m a c e r i l l a .

    B u s ca r e l a l g o r i t m o g a n a d o r p a r a e s t e j u e g o , g e n e r a l iz a n d o :

    i n i c i a lm e n t e h a y Nce r i l l as y c a d a v e z se p u e d e t om a r h a s t a u n

    m x im o d e kc e r i l l a s . L o s v a l o r e s Ny ks o n i n t r o d u c i d o s p o r

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    54/60

    Fundamentos de informtica. Programacin en Lenguaje C

    140

    t e c l a d o y d e c i d i d o s p o r u n j u g a d o r ( q u e s e r e l j u g a d o r

    p e r d e d o r ) , e l o t r o j u g a d o r ( q u e s e r e l o r d e n a d o r , y q u e

    s ie m p r e d e b e g a n a r ) d e c id e q u i e n em p i e za e l j u e g o .

    #i ncl ude

    void mai n( void){/ / Con cunt as cer i l l as se va a j ugar .

    unsigned short cer i l l as;/ / Cunt as cer i l l as se pueden qui t ar cada vez.unsigned short qui t ar ;

    / / Cer i l l as que qui t a el ganador y el per dedor .unsigned short qp, qg;char ganador;

    do{

    pr i nt f ( "\ n\ n\ nCon cunt as cer i l l asse va a j ugar . . . ") ;

    scanf ( "%hu", &cer i l l as) ;if( cer i l l as == 0) break;

    do{pr i nt f ( "\ Cunt as cer i l l as pueden

    qui t ar se de una vez. . . ") ;scanf ( "%hu", &qui t ar ) ;if( qui t ar >= cer i l l as)

    pr i nt f ( "No pueden qui t ar se t ant ascer i l l as. \ n" ) ;

    }while( qui t ar >= cer i l l as);

    qg = ( cer i l l as - 1) % ( qui t ar + 1) ;/ / MOSTRAR CERI LLAS . . .

    pr i nt f ( " \ n" ) ;

    for( shor t i = 1 ; i

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    55/60

    Captulo 4. Estructuras de control.

    141

    cer i l l as - = qg;/ / MOSTRAR CERI LLAS . . .pr i nt f ( " \ n" ) ;for( short i = 1 ; i qui t ar )

    pr i nt f ( " \ nNo puede qui t ar masde %hu. \ n", qui t ar ) ;

    }while( qp > qui t ar ) ;cer i l l as - = qp;

    / / MOSTRAR CERI LLAS . . .

    pr i nt f ( " \ n" ) ;for( short i = 1 ; i

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    56/60

    Fundamentos de informtica. Programacin en Lenguaje C

    142

    / / Fi n de MOSTRAR CERI LLASif( cer i l l as == 1) ganador = ' m' ;}

    if( ganador == ' j ' )pr i nt f ( "\ nHa ganado el j ugador . . . ") ;

    else if( ganador == ' m' )pr i nt f ( "\ nHe ganado yo, l a mqui na. . . ") ;

    }while( cer i l l as) ;}

    El programa ha quedado un poco ms largo que los anteriores. Se ha

    dedicado un poco de cdigo a la presentacin en el momento de la

    ejecucin. Ms adelante, cuando se haya visto el modo de definir

    funciones, el cdigo quedar visiblemente reducido. Por ejemplo, en

    cuatro ocasiones hemos repetido el mismo cdigo destinado a visualizar

    por pantalla las cerillas que quedan por retirar.

    37 . E l nm e r o u r eo ( ) v e r i f i c a m u ch a s cu r i o s a s p r o p i e d a d e s .

    P o r e j e m p l o :

    = +2 1 = 1 1 = + 3 ( 1) ( 1)

    = + 1 1 = + 1 y o t r a s

    L a p e nl t i m a e x p r e s i n p r e s e n t a d a ( = + 1 1 ) m u e s t r a u n

    c am i n o c u r i o s o p a r a e l cl c u l o d e l n m e r o u r e o :

    S i = + = + = +

    + +

    +

    1 1 11 1 1 ...

    1 11 1

    11

    Y , e n t o n c e s u n m od o d e c a l c u l a r e l nm e r o u r e o e s : i n i c i a l i z a r

    a l v a l o r 1 , e i r a f i n a n d o e n e l cl c u l o d e l v a l o r d e l n m e r o

    u r e o a b a se d e r e p e t i r m u ch a s v e ce s q u e = + 1 1 :

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    57/60

    Captulo 4. Estructuras de control.

    143

    +

    +

    +

    +

    +

    111

    11

    11

    1 ...1

    11

    Es c r i b a u n p r o g r am a p a r a c a l c u l a r e l nm e r o u r e o m e d i a n t e

    e s t e p r o c e d i m i e n t o h a c i e n d o , p o r e j em p l o , l a s u s t i t u c i n

    = + 1 1 m i l v e c e s . M o s t r a r l u e g o e l r e s u l t a d o p o r p a n t a l l a .

    #i ncl ude #def i ne LI MI TE 1000

    void mai n( void){

    double au = 1;

    for( int i = 0 ; i < LI MI TE ; i ++)au = 1 + 1 / au;

    pr i nt f ( "El nmer o ur eo es . . . . . %l f . \ n", au) ;

    pr i nt f ( "ur eo al cuadr ado es . . . %l f . \ n", au * au) ;}

    No se ha hecho otra cosa que considerar lo que sugiere el enunciado:

    inicializar el nmero ureo a 1, y repetir mil veces la iteracin

    = + 1 1 . Al final mostramos tambin el cuadrado del nmero ureo:

    es un modo rpido de verificar que, efectivamente, el nmero hallado es

    el nmero buscado: el nmero ureo verifica que su cuadrado es igual al

    nmero incrementado en uno.

    La salida que ofrece este cdigo por pantalla es la siguiente:El nmero ureo es ..... 1.618034.

    ureo al cuadrado es ... 2.618034.

    3 8 . S ig u i e n d o c o n e l m i sm o e n u n c i a d o , t am b in p o d em o s p l a n t e a r n o s

    c a l c u l a r e l n m e r o u r e o a p a r t i r d e l a r e l a c i n = + 1 . D e n u e v o

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    58/60

    Fundamentos de informtica. Programacin en Lenguaje C

    144

    t e n e m o s :

    = + = + + = + + + = = + + + + + + 1 1 1 1 1 1 ... 1 1 1 1 1 ... 1

    #i ncl ude #i ncl ude #def i ne LI MI TE 100000

    void mai n( void)

    { double au = 1;

    for( i nt i = 0 ; i < LI MI TE ; i ++)au = sqr t ( 1 + au) ;

    pr i nt f ( "El nmer o ur eo es . . . . . %l f . \ n", au) ;pr i nt f ( "ur eo al cuadr ado es . . . %l f . \ n", au * au) ;

    }

    Este programa ofrece una salida idntica a la anterior. Y el cdigo es

    casi igual que el anterior: nicamente cambia la definicin de la

    iteracin.

    3 9 . M u e s t r e p o r p a n t a l l a t o d o s l o s e n t e r o s p r i m o s c om p r e n d i d o s

    e n t r e d o s e n t e r o s i n t r o d u c id o s p o r t e c la d o .

    #i ncl ude #i ncl ude

    void mai n( void){

    long a, b, di v;pr i nt f ( " L mi te i nf er i or . . . " ) ;scanf ( "%l d", &a) ;pr i nt f ( "L mi t e super i or . . . " ) ;scanf ( "%l d", &b) ;

    pr i nt f ( "Los pr i mos ent r e %l d y %l d son . . . \ n\ t ", a, b) ;for( long num = a, pr i mos = 0 ; num

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    59/60

    Captulo 4. Estructuras de control.

    145

    for( di v = 2 ; di v < sqr t ( num) ; di v++)if( num % di v == 0) br eak;if( num % di v == 0) cont i nue;if( pr i mos ! = 0 && pr i mos % 10 == 0)

    pr i nt f ( " \ n\ t " ) ;pr i mos++;pr i nt f ( "%6l d, ", num) ;

    }}

    El primer f o r recorre todos los enteros comprendidos entre los dos

    lmites introducidos por teclado. El segundo f o raverigua si la variable

    num codifica en cada iteracin del primer f o r un entero primo ocompuesto: si al salir del segundo f o rse tiene que num % dives igual a

    cero, entonces numes compuesto y se ejecuta las sentencia c o n t i n u e

    que vuelve a la siguiente iteracin del primer f o r. En caso contrario, el

    valor de numes primo, y entonces sigue adelante con las sentencias del

    primer f o r, que estn destinadas nicamente a mostrar por pantalla, de

    forma ordenada, ese entero primo, al igual que habr mostrado

    previamente todos los otros valores primos y mostrar los que siga

    encontrando posteriormente.La salida por pantalla del programa podra ser la siguiente:

    Lmite inferior ... 123Lmite superior ... 264Los primos entre 123 y 264 son ...

    127, 131, 137, 139, 149, 151, 157, 163, 167, 173,179, 181, 191, 193, 197, 199, 211, 223, 227, 229,233, 239, 241, 251, 257, 263,

    Para este ltimo programa se recomienda que se dibuje el diagrama de

    flujo.

  • 7/21/2019 087 146 Capitulo 4 Estructuras de Control

    60/60

    Fundamentos de informtica. Programacin en Lenguaje C