Tema 6 Estructuras de Control en C

y salida (teclado, pantalla, impresora, disco magnético). En el caso de que se utilizaran posteriormente se indicarıa expresamente la representación de cada ...
248KB Größe 5 Downloads 56 vistas
Tema 6 Estructuras de Control en C ´Indice 6.1. Introducci´ on . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

6-1

6.1.1. Representaci´ on de Algoritmos . . . . . . . . . . . . . . . . . . . . . 6-2 6.1.2. Programaci´ on Estructurada . . . . . . . . . . . . . . . . . . . . . . 6-3 6.2. Estructuras Secuenciales . . . . . . . . . . . . . . . . . . . . . . .

6-3

6.3. Estructuras Selectivas . . . . . . . . . . . . . . . . . . . . . . . . .

6-4

6.3.1. Estructura Selectiva Simple: if else . . . . . . . . . . . . . . . . 6-4 6.3.2. Sentencias Selectivas Simples Anidadas . . . . . . . . . . . . . . . 6-7 6.3.3. Estructura Selectiva M´ ultiple: switch . . . . . . . . . . . . . . . . 6-7 6.4. Estructuras Repetitivas . . . . . . . . . . . . . . . . . . . . . . . . 6-11 6.4.1. Sentencia while . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-12 6.4.2. Sentencia do while . . . . . . . . . . . . . . . . . . . . . . . . . . 6-15 6.4.3. Sentencia for . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-15 6.5. Ejemplos de Uso . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-19 6.5.1. Lectura del teclado . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-19 6.5.2. Soluci´ on de una ecuaci´on de primer grado . . . . . . . . . . . . . . 6-20 6.6. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-20

6.1.

Introducci´ on

En los ejemplos de programas que se han visto hasta ahora, las instrucciones segu´ıan una estructura secuencial: se ejecutaba una sentencia, tras la finalizaci´on se ejecutaba la siguiente, y as´ı sucesivamente hasta alcanzar el final del programa. Evidentemente, esta estructura no es v´alida para todos los casos. Imaginemos que necesitamos obtener la suma de los 100 primeros n´ umeros naturales. Con lo visto hasta ahora, la

6-1

6-2

2007–2008

u ´nica posibilidad consiste en utilizar 100 instrucciones, una a continuaci´on de otra, sumando un n´ umero diferente en cada una de ellas. Otro ejemplo en el que no es suficiente con la estructura secuencial es aqu´el en el que s´olo debemos realizar una operaci´on si se cumple una condici´on previa: por ejemplo, un programa que controla un cajero autom´atico, y s´olo entrega el dinero (y lo resta del saldo) si la cantidad solicitada es inferior o igual al saldo disponible. Realmente, lo dif´ıcil es encontrar un programa que pueda realizarse u ´nicamente con la estructura secuencial. Por eso, el lenguaje C (y todos los lenguajes de programaci´on en general) incorporan una serie de estructuras de control que permiten resolver f´acilmente los ejemplos mostrados anteriormente.

6.1.1.

Representaci´ on de Algoritmos

Un algoritmo, seg´ un el diccionario de la RAE, es un conjunto ordenado y finito de operaciones que permite hallar la soluci´on de un problema. Es evidente, a partir de la definici´on, que un algoritmo es independiente del lenguaje de programaci´on que se utilice para realizar la soluci´on. Por eso es muy conveniente separar la realizaci´on de un programa en dos fases: elaboraci´on del algoritmo que soluciona el problema, y traducci´on del algoritmo al lenguaje de programaci´on deseado (en nuestro caso el C). De las diferentes t´ecnicas que existen para la representaci´on de un algoritmo, la m´as utilizada es la de los diagramas de flujo. En ellos se utilizan s´ımbolos (cajas) unidos por flechas (l´ıneas de flujo) que indican las operaciones a realizar y el orden o direcci´on de flujo del programa respectivamente. Como se puede comprobar es una forma gr´ afica e intuitiva de ver la estructura global de un algoritmo. Algunos de los s´ımbolos utilizados en los diagramas de flujo son los siguientes:

expresi´on

falso

bloque

cierto

El primero representa una decisi´on: en su interior se escribe una condici´on, y si la condici´on se cumple se sigue uno de los flujos (el inferior en la figura) y si no se cumple el otro (el de la derecha en la figura). El segundo representa una conjunto de acciones a realizar, de forma secuencial. El tercero se utiliza para agrupar flujos provenientes de distintos sitios para seguir un camino u ´nico. Tambi´en se pueden utilizar otros s´ımbolos para representar los dispositivos de entrada y salida (teclado, pantalla, impresora, disco magn´etico). En el caso de que se utilizaran posteriormente se indicar´ıa expresamente la representaci´on de cada uno de ellos. Ahora vamos a estudiar las estructuras de control que propone o usa la programaci´on estructurada, y luego veremos como se codifican en el lenguaje C.

Fund. de la Prog.

6.1.2.

2007–2008

6-3

Programaci´ on Estructurada

La programaci´on estructurada se basa en la utilizaci´on de un reducido n´ umero de estructuras que permitan hacer que un programa sea sufucientemente legible, reduciendo considerablemente el n´ umero de errores, y facilitando enormemente la detecci´on y soluci´on de ´estos. La caracter´ıstica fundamental de la programaci´on estructurada consiste en que todas las estructuras tienen un u ´nico punto de entrada y un u ´nico punto de salida. Esto permite descomponer f´acilmente un problema en subproblemas, reduciendo la complejidad y facilitando la programaci´on. Las estructuras que incorpora el C basadas en la programaci´on estructurada son: secuenciales selectivas repetitivas Se debe evitar el uso de cualquier otra estructura que no sea una de las anteriores, ya que conduce a c´odigo no estructurado. Contrariamente a lo que pudiera parecer en un primer momento, esto no supone ninguna limitaci´on a la hora de realizar un programa, ya que se puede demostrar que cualquier programa se puede realizar utilizando u ´nicamente estas estructuras. En concreto, est´a totalmente prohibido en el a´mbito de la asignatura la utilizaci´on de las sentencias goto (que realiza un salto incondicional) y continue (que fuerza una nueva iteraci´on dentro de de una estructura repetitiva), y s´olo se permite la utilizaci´on de la sentencia break (que fuerza la salida de una estructura selectiva o repetitiva) en el ´ambito de la sentencia selectiva m´ ultiple, que se estudiar´a m´as adelante.

6.2.

Estructuras Secuenciales

En un programa en C, las sentencias se ejecutan una tras otra en el orden en el que est´an escritas. El fin de una sentencia marca el comienzo de la siguiente.

#include < stdio .h > /* Obtiene en grados Celsius una temperatura dada en grados Fahrenheit , seg´ u n la expresi´ o n o C = (5/9) * ( o F -32) */

int main () {

float fahrenheit ; float celsius ; printf ( " Temperatura en grados Fahrenheit : " ); scanf ( " %f " , & fahrenheit );

6-4

2007–2008

celsius = ( fahrenheit - 32) * 5 / 9; printf ( " %f grados fahrenheit son %f grados celsius \ n " , fahrenheit , celsius );

return 0; }

Para poder considerar un grupo de sentencias como una sola, podemos encerrarlas entre llaves. A esta construcci´on se le denomina bloque, y puede aparecer en cualquier lugar en el que puede aparecer una sentencia.

6.3.

Estructuras Selectivas

Tambi´en llamadas condicionales; permiten que ciertas sentencias se ejecuten o no en funci´on de una determinada condici´on. En C existen dos tipos de estructuras selectivas: la simple: if else. la m´ ultiple: switch.

6.3.1.

Estructura Selectiva Simple: if else

La estructura general de una estructura selectiva simple en C es la siguiente:

if ( expresion ) bloque_if

else

bloque_else

donde la parte correspondiente al else es opcional. Utilizando diagramas de flujo, tendr´ıamos lo siguiente:

expresi´on

=0

expresi´on

6=0

6=0 bloque else

bloque if

bloque if

El funcionamiento de la estructura selectiva simple es el siguiente:

=0

Fund. de la Prog.

2007–2008

6-5

1. se eval´ ua la expresi´on que acompa˜ na a la cl´ausula if 2. Si la expresi´on es cierta (el valor de la expresi´on es distinto de cero), se ejecuta la sentencia que sigue a continuaci´on y se termina. 3. Si la expresi´on es falsa (el valor de la expresi´on es igual a cero) y existe la cl´ausula else, se ejecuta la sentencia que sigue a la cl´ausula else y se termina. o dicho de otra forma: el bloque que sigue a la cl´ausula if s´olo se ejecuta si el valor de la expresi´on es distinto de cero. si existe una cl´ausula else, el bloque que sigue a dicha cl´ausula s´olo se ejecuta si el valor de la expresi´on es igual a cero.

#include < stdio .h > /* Calcula si un anio es bisiesto o no . Un anio es bisiesto si es divisible por 4 pero no por 100 , excepto aquellos divisibles por 400. */

int main () {

int year = 0; printf ( " Introduzca el anio : " ); scanf ( " %d " , & year );

if ((0 == year % 400) || ((0 == year % 4) && (0 != year % 100))) printf ( " El anio %d es bisiesto \ n " , year );

else

printf ( " El anio %d NO es bisiesto \ n " , year );

return 0; }

Ponga atenci´on en que lo que sigue a un if o a un else es un bloque, y recuerde que un bloque es o una u ´nica sentencia, a un grupo de sentencias encerradas entre llaves. Un problema muy com´ un cuando se utiliza una estructura selectiva simple consiste en utilizar m´as de una sentencia (sin agruparlas en un bloque) bien en el bloque del if bien en el del else:

if ( numero < 0) negativo = 1; suma -= 1;

else

6-6

2007–2008

negativo = 0; suma += 1;

En el primer caso (varias sentencias en el bloque del if), el compilador detectar´ıa el problema, puesto que habr´ıa un else que no se corresponde con ning´ un if (tal y como est´a escrito, la sentencia selectiva simple terminar´ıa con la ejecuci´on de la sentencia negativo = 1). La soluci´on, una vez detectado el problema, es simple: formar un bloque con las dos sentencias encerr´andolas entre llaves:

if ( numero < 0) { negativo = 1; suma -= 1; }

else negativo = 0; suma += 1;

El segundo caso es m´as grave, ya que no es ning´ un error de sintaxis. Desde el punto de vista del compilador, la sentencia selectiva simple finalizar´ıa con la ejecuci´on de la sentencia negativo = 0, y la siguiente sentencia se ejecutar´ıa siempre, independientemente de si numero es menor o no que cero. En consecuencia, si numero es menor que cero, las sentencias que se ejecutar´ıan ser´ıan: negativo = 1; suma -= 1; suma += 1;

y si no es menor que cero: negativo = 0; suma += 1;

Encontrar este error, como se puede comprender, puede resultar muy laborioso. Por eso es muy conveniente escribir los programas en alg´ un editor que sea capaz de entender la sintaxis de C e indente adecuadamente cada sentencia, en funci´on del bloque al que pertenezca. Con un editor de este tipo, el resultado que habr´ıamos obtenido habr´ıa sido:

if ( numero < 0) { negativo = 1; suma -= 1; }

else negativo = 0; suma += 1;

donde puede observarse, por la situaci´on de la sentencia suma += 1, que no pertene al bloque de la cl´ausula else, como deber´ıa.

Fund. de la Prog.

2007–2008

6-7

La soluci´on, al igual que en el caso anterior, pasa por encerrar entre llaves (y formar un bloque) las sentencias que forman parte del a´mbito del else:

if ( numero < 0) { negativo = 1; suma -= 1; }

else { negativo = 0; suma += 1; }

6.3.2.

Sentencias Selectivas Simples Anidadas

Dentro de los bloques del if o del else en una sentencia selectiva simple pueden utilizarse a su vez sentencias selectivas simples, dando lugar a sentencias selectivas simples anidadas. En este caso, hay que tener en cuenta que la sentencia else se asocia siempre al if m´as cercano. Por ejemplo, en el siguiente fragmento de c´odigo:

if ( n > 0) if ( a > b ) z = a;

else

z = b;

la cl´ausula else se asocia a if (a > b). Si quisi´eramos que se aplicara al primer if, bastar´a con encerrar entre llaves el segundo if:

if ( n > 0) {

if ( a > b ) z = a;

}

else z = b;

De hecho es muy conveniente, en el caso de sentencias de selecci´on simples anidadas, encerrar siempre entre llaves los bloques correspondientes a cada una de las cl´ausulas if y else que aparezcan, para dejar claro el a´mbito de cada una de ellas.

6.3.3.

Estructura Selectiva M´ ultiple: switch

En la estructura selectiva m´ ultiple, se puede seleccionar entra varias alternativas seg´ un el valor de una expresi´on. La forma general de la estructura selectiva m´ ultiple es:

6-8

2007–2008

switch ( expresion ) {

case exprConst1 : listaProp1 case exprConst2 : listaProp2 case exprConstN : listaPropN default : propDefault

}

El diagrama de flujo de esta estructura ser´ıa el siguiente:

expresi´on entera

valor 1

=

bloque 1

6=

valor 2

=

bloque 2

6=

default

=

bloque por defecto

El funcionamiento de esta estructura es como sigue: 1. Se eval´ ua la expresi´on que acompa˜ na al switch. Esta expresi´on se eval´ ua como expresi´on entera. 2. Se compara el valor obtenido, secuencialmente, con los valores que acompa˜ nan los diferentes case, deteni´endose en el primero que coincida. Estos valores deber´an ser siempre expresiones constantes enteras. Existe una etiqueta especial, default, que siempre es cierta, por lo que se utiliza para contemplar el resto de casos que no se han considerado en los case anteriores. Por eso es

Fund. de la Prog.

2007–2008

6-9

muy importante que esta etiqueta se sit´ ue como la u ´ltima del bloque, puesto que las que se pongan detr´as de ella nunca ser´an consideradas (como se ha obtenido la coincidencia en una etiqueta, se deja de comprobar el resto de etiquetas). El problema de esta estructura es que si la expresi´on coincide con un case, se ejecuta ´ese y todos los que hubiera por debajo (los case hacen las funciones de etiquetas), que no es lo que habitualmente se desea. La soluci´on consiste en poner un break como u ´ltima proposici´on dentro de cada case, lo que hace que se finalice la ejecuci´on de la estructura switch:

switch ( expresion ) {

case exprConst1 : listaProp1 break ; case exprConst2 : listaProp2 break ; case exprConstN : listaPropN break ; default : propDefault break ;

}

lo que se recoge en la siguiente figura:

expresi´on entera

valor 1

=

bloque 1

break;

bloque 2

break;

bloque por defecto

break;

6=

valor 2

=

6=

default:

=

6-10

2007–2008

#include < stdio .h > /* Programa que lea un n´ u mero de mes ( en el rango de 1 a 12) e indique el n´ u mero de d´ ı as del mes . */

int main () {

int mes = 0; int ndias = 0; printf ( " Introduzca el numero de un mes (1 -12): " ); scanf ( " %2d " , & mes );

switch ( mes ) {

case 2:

ndias = 28; break ; case 4: case 6: case 9: case 11: ndias = 30; break ; default : ndias = 31; break ; } printf ( " \ tEl mes %d tiene %d dias .\ n " , mes , ndias );

return 0; }

Observe c´omo tras la u ´ltima sentencia de cada bloque aparece una sentencia break para dar por finalizada la ejecuci´on de la estructura selectiva m´ ultiple (incluyendo el caso por defecto, default). El caso por defecto (default) suele utilizarse para detectar caso no v´alidos o err´oneos, evitando que se produzcan errores en la ejecuci´on. El siguiente ejemplo determina si un n´ umero entre el 1 y el 10 es par o impar; el caso por defecto se ha utilizado en este programa para los n´ umeros que est´an fuera de ese rango:

#include < stdio .h > /* Determina si un n´ u mero entre el 1 y el 10 es par o impar . */

int main ()

Fund. de la Prog.

{

2007–2008

6-11

int num = 0; printf ( " \ nIntroduzca el n´ u mero : " ); scanf ( " %d " , & num );

switch ( num ) {

case case case case case

1: 3: 5: 7: 9: printf ( " \ n El n´ u mero %d es impar \ n " , num ); break ; case 2: case 4: case 6: case 8: case 10: printf ( " \ n El n´ u mero %d es par \ n " , num ); break ; default : printf ( " \ n FUERA DE RANGO \ n " , num ); break ; }

return 0; }

6.4.

Estructuras Repetitivas

En este tipo de estructuras, se repite un conjunto de instrucciones en funci´on de una condici´on. La principal diferencia entre las diferentes estructuras repetitivas consiste en qu´e punto se realiza la comprobaci´on de la condici´on. En C existen tres tipos de estructuras repetitivas: while do while for

6-12

2007–2008

6.4.1.

Sentencia while

La sintaxis de la sentencia while es la siguiente:

while ( expresion ) bloque

El diagram de flujo correspondiente es:

expresi´on

=0

6=0

bloque while

El funcionamiento es el siguiente: 1. se eval´ ua la expresi´on que acompa˜ na a la cl´ausula while 2. Si la expresi´on es cierta (el valor de la expresi´on es distinto de cero), se ejecuta el bloque que sigue a continuaci´on. 3. se vuelve al primer paso, y se repite el proceso. Algunos aspectos de inter´es sobre esta estructura ser´ıan: Puede que el bloque que sigue al while no se ejecute ninguna vez. Si la primera vez que se calcula la condici´on el resultado es cero (falso), no se pasar´ıa a ejecutar el bloque, y se pasar´ıa directamente a la sentencia que siga a la sentencia while. Alguno de los valores que determinan la condici´on debe ser modificado dentro del bloque. Si no fuera as´ı, y la condici´on fuera cierta (distinta de cero) la primera vez que la comprob´aramos, pasar´ıamos a ejecutar el bloque, y ya no saldr´ıamos nunca de ´el puesto que la condici´on seguir´ıa siendo cierta de forma indefinida. En la condici´on, es conveniente utilizar los operadores de rango (, =) en lugar de los operadores de igualdad y desigualdad (== o !=). Al igual que suced´ıa en el caso de las sentencias selectivas simples, es un error muy com´ un querer utilizar m´as de una sentencia dentro del bloque del while pero no encerrarlas entre llaves, como en el siguiente ejemplo:

Fund. de la Prog.

2007–2008

6-13

#include < stdio .h > int main () {

int num = 0; int suma = 0; while (10 > num ) num ++; suma += num ; printf ( " La suma hasta el %d vale %d \ n " , num , suma );

return 0; }

Si lo compilamos y ejecutamos, obtenemos el siguiente resultado: local> gcc -W -Wall -o whileMal whileMal.c local> ./whileMal La suma hasta el 10 vale 10 local>

Como puede observarse, y en contra de lo que pudiera parecer a simple vista, el fragmento de c´odigo anterior no suma los diez primeros n´ umeros (del 1 al 10), sino u ´nicamente el u ´ltimo (10); a pesar de que el compilador no ha detectado ning´ un error. Eso es porque el bloque del while est´a formado u´nicamente por la sentencia num++;, que es la que se repite 10 veces. Una vez finalizado el bucle while es cuando se ejecuta la sentencia suma += num;, que l´ogicamente s´olo se ejecuta una vez. La forma correcta ser´ıa la siguiente:

#include < stdio .h > int main () {

int num = 0; int suma = 0; while (10 > num ) { num ++; suma += num ; } printf ( " La suma hasta el %d vale %d \ n " , num , suma );

return 0; }

6-14

2007–2008

Si lo compilamos y ejecutamos, obtenemos el siguiente resultado: local> gcc -W -Wall -o whileBien whileBien.c local> ./whileBien La suma hasta el 10 vale 55 local>

Se pueden evitar estas confusiones si siempre agrupamos las sentencias que forman el a´mbito de aplicaci´on del while entre llaves, aunque sea una u ´nica sentencia. O utilizando un editor de textos que entienda la sintaxis de C e indente adecuadmanete cada sentencia, en funci´on del bloque a que pertenezca. Valores Extremos en la Condici´ on En las estructuras repetitivas en general, y como caso particular en la sentencia while, es muy importante comprobar que los valores extremos de la condici´on (el primer y el u ´ltimo valor para los que se ejecuta el bloque que acompa˜ na a la cl´ausula while) son los adecuados. Para ello es de gran utilidad repasar mentalmente (o con ayuda de papel y l´apiz) qu´e sucede en la condici´on de la sentencia while la primera vez que se llega a ella y la u ´ltima vez que se realiza la comprobaci´on (la vez que se termina la sentencia). Vamos a utilizar como ejemplo para ver esto el del apartado anterior, de suma de los 10 primeros n´ umeros. La primera vez que llegamos al while, el valor de num vale 0 (lo acabamos de inicializar), que cumple la condici´on (10 > num), por lo que entraremos a ejecutar el bloque. Incrementamos el valor de num (que ahora pasar´a a valer 1) y lo sumamos. Comprobamos pues que el primer valor del bucle es el correcto. Supongamos ahora que num vale 9; la condici´on se sigue cumpliendo, y por tanto entramos en el bucle: incrementamos num, que ahora pasa a valer 10, y lo sumamos. En la siguiente iteraci´on, la condici´on no se cumple y saldremos de la sentencia while. Hemos comprobado por tanto que efectivamente hemos sumado los n´ umeros del 1 al 10. Lo anterior se resume en la siguiente tabla:

num Condici´on Valor sumado num 0 ... 9 10

cierta

1

1

cierta falsa

10

10

Modifique el programa del apartado anterior si el bloque de la sentencia while es: suma += num ; num ++;

Fund. de la Prog.

6.4.2.

2007–2008

6-15

Sentencia do while

La sintaxis de la sentencia do while es la siguiente:

do bloque

while ( expresion ); El diagrama de flujo de esta sentencia ser´ıa:

bloque do-while

expresi´on

=0

6=0

A diferencia de la sentencia while, en esta estructura repetitiva primero se ejecuta el bloque y posteriormente se comprueba la condici´on. Por tanto, el bloque de una sentencia do while se ejecuta siempre al menos una vez. Se recomienda usar siempre las llaves para delimitar el bloque de sentencias a ejecutar dentro del bucle. Esto no es necesario cuando el bloque est´a formado por una u ´nica sentencia.

6.4.3.

Sentencia for

La sintaxis de la sentencia for es la siguiente:

for ( inicial ; expresi´ on ; final ) bloque

El diagrama de flujo de esta sentencia ser´ıa:

6-16

2007–2008

inicial

expresi´on

=0

6=0

bloque for

final

El funcionamiento de esta sentencia es el siguiente: 1. se ejecuta el bloque inicial. 2. se eval´ ua la expresi´on. 3. si es igual a cero, se finaliza la ejecuci´on de la sentencia. 4. si es distinta de cero: se ejecuta el bloque. se ejecuta el bloque final. se vuelve al paso 2. En una sentencia for puede omitirse cualquiera de los tres campos, pero es imprescindible mantener los ;. Si se omite el segundo campo, la condici´on se da por cierta, y se obtiene un bucle infinito.

#include < stdio .h > /* Programa que obtiene la suma de los n´ u meros pares comprendidos entre 2 y 1000. */

int main () {

Fund. de la Prog.

2007–2008

6-17

int i ; int suma = 0; for ( i = 2; i /* Programa que obtiene la suma de los n´ u meros pares comprendidos entre 2 y 1000. */

int main () {

int i ; int suma ; for ( suma = 0 , i = 2; i /* Calcula la potencia n de un n´ u mero num */

int main () {

int int int int

num exponente potencia i

= = = =

0; 0; 1; 0;

/* var . de control del bucle */

6-18

2007–2008

printf ( " \ nIntroduzca el n´ u mero y exponente : " ); scanf ( " %d %d " , & num , & exponente );

for ( i = 1; i /* Imprime tablas de multiplicar */

int main () {

int i = 0; int j = 0; /* Primera aproximaci´ o n */ for ( i = 1; i

Fund. de la Prog.

2007–2008

6-21

#define MAX 10 /* Representaci´ o n de un bucle desde con mientras y hacer - mientras . */

int main () {

int i = 0;

/* Variable ´ ı ndice o de control */

printf ( " \ n Bucle DESDE con for \ n " ); for ( i = 1; i /* Determina si un n´ u mero cualquiera ( incluso negativo ) es par o impar . */

int main () {

int num = 0; printf ( " \ nIntroduzca el n´ u mero : " ); scanf ( " %d " , & num ); switch ( num % 2) { case 0: printf ( " \ n El n´ u mero %d es par \ n " , num ); break ; case 1: case -1: printf ( " \ n El n´ u mero %d es impar \ n " , num ); break ; default : printf ( " \ n El m´ o dulo es distinto de 0 , 1 , -1\ n " ); break ; }

return 0;

6-22

2007–2008

}

Modificarlo sustituyendo el bloque switch por una simple sentencia selectiva if. 3. Realizar un programa que pida un n´ umero positivo y escriba el cuadrado del mismo si dicho n´ umero se encuentra comprendido dentro del rango de 0 a 100, en caso contrario dar un mensaje. 4. Programa que calcule el valor medio de los n´ umeros del 100 al 1000. 5. El siguiente programa (que denominaremos cuentaLineas.c) lee el n´ umero de l´ıneas de texto que se escriben por teclado:

#include < stdio .h > /* Programa que lee el numero de lineas a la entrada . El texto de entrada es una secuencia de lineas , cada una de ellas terminada con un ’\ n ’ ( caracter nueva linea ). El caracter que marca el final del texto es EOF , que en los terminales se consigue con Ctrl - D . */

int main () {

int c = 0; int nl = 0;

/* Almacena caracteres */ /* Cuenta lineas */

c = getchar (); while ( c != EOF ) { if ( c == ’\ n ’) ++ nl ; c = getchar (); } printf ( " El numero de l´ ı neas es %d \ n " , nl );

return 0; }

Modificar el c´odigo para que cuente todos los caracteres. 6. Modificar cuentaLineas para que cuente palabras. 7. Escriba un programa que pida un n´ umero y un exponente, ambos enteros, y calcule el valor del n´ umero elevado al exponente, utilizando la propiedad de que elevar un n´ umero a un exponente equivale a multiplicar el n´ umero tantas veces como indique el exponente.

Fund. de la Prog.

2007–2008

6-23

8. Escribir un programa que lea n´ umeros enteros del teclado y los sume. El programa terminar´a cuando se introduzca un n´ umero negativo, imprimi´endose la suma. 9. Realizar un programa que multiplique, sume o reste dos n´ umeros en funci´on de la opci´on elegida.