1. Tema 6
Estructuras de Control en C
´
Indice
6.1. Introducci´n . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
o 6-1
6.1.1. Representaci´n de Algoritmos . . . . . . . . . . . . . . . . . . . . . 6-2
o
6.1.2. Programaci´n Estructurada . . . . . . . . . . . . . . . . . . . . . . 6-3
o
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´ltiple: switch . . . . . . . . . . . . . . . . 6-7
u
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´n de una ecuaci´n de primer grado . . . . . . . . . . . . . . 6-20
o o
6.6. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-20
6.1. Introducci´n
o
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´n se ejecutaba la
o
siguiente, y as´ sucesivamente hasta alcanzar el final del programa.
ı
Evidentemente, esta estructura no es v´lida para todos los casos. Imaginemos que nece-
a
sitamos obtener la suma de los 100 primeros n´meros naturales. Con lo visto hasta ahora, la
u
6-1
2. 6-2 2007–2008
unica posibilidad consiste en utilizar 100 instrucciones, una a continuaci´n de otra, sumando
´ o
un n´mero diferente en cada una de ellas.
u
Otro ejemplo en el que no es suficiente con la estructura secuencial es aqu´l en el que
e
s´lo debemos realizar una operaci´n si se cumple una condici´n previa: por ejemplo, un
o o o
programa que controla un cajero autom´tico, y s´lo entrega el dinero (y lo resta del saldo)
a o
si la cantidad solicitada es inferior o igual al saldo disponible.
Realmente, lo dif´ es encontrar un programa que pueda realizarse unicamente con la
ıcil ´
estructura secuencial. Por eso, el lenguaje C (y todos los lenguajes de programaci´n en o
general) incorporan una serie de estructuras de control que permiten resolver f´cilmente los
a
ejemplos mostrados anteriormente.
6.1.1. Representaci´n de Algoritmos
o
Un algoritmo, seg´n el diccionario de la RAE, es un conjunto ordenado y finito de opera-
u
ciones que permite hallar la soluci´n de un problema. Es evidente, a partir de la definici´n,
o o
que un algoritmo es independiente del lenguaje de programaci´n que se utilice para realizar
o
la soluci´n.
o
Por eso es muy conveniente separar la realizaci´n de un programa en dos fases: elabo-
o
raci´n del algoritmo que soluciona el problema, y traducci´n del algoritmo al lenguaje de
o o
programaci´n deseado (en nuestro caso el C).
o
De las diferentes t´cnicas que existen para la representaci´n de un algoritmo, la m´s
e o a
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´n de flujo
o
del programa respectivamente. Como se puede comprobar es una forma gr´fica e intuitiva
a
de ver la estructura global de un algoritmo.
Algunos de los s´ımbolos utilizados en los diagramas de flujo son los siguientes:
falso
expresi´n
o bloque
cierto
El primero representa una decisi´n: en su interior se escribe una condici´n, y si la con-
o o
dici´n se cumple se sigue uno de los flujos (el inferior en la figura) y si no se cumple el otro
o
(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 unico.
´
Tambi´n se pueden utilizar otros s´
e ımbolos para representar los dispositivos de entrada
y salida (teclado, pantalla, impresora, disco magn´tico). En el caso de que se utilizaran
e
posteriormente se indicar´ expresamente la representaci´n de cada uno de ellos.
ıa o
Ahora vamos a estudiar las estructuras de control que propone o usa la programaci´n o
estructurada, y luego veremos como se codifican en el lenguaje C.
3. Fund. de la Prog. 2007–2008 6-3
6.1.2. Programaci´n Estructurada
o
La programaci´n estructurada se basa en la utilizaci´n de un reducido n´mero de es-
o o u
tructuras que permitan hacer que un programa sea sufucientemente legible, reduciendo con-
siderablemente el n´mero de errores, y facilitando enormemente la detecci´n y soluci´n de
u o o
´stos.
e
La caracter´
ıstica fundamental de la programaci´n estructurada consiste en que todas las
o
estructuras tienen un unico punto de entrada y un unico punto de salida. Esto permite des-
´ ´
componer f´cilmente un problema en subproblemas, reduciendo la complejidad y facilitando
a
la programaci´n.
o
Las estructuras que incorpora el C basadas en la programaci´n estructurada son:
o
secuenciales
selectivas
repetitivas
Se debe evitar el uso de cualquier otra estructura que no sea una de las anteriores, ya que
conduce a c´digo no estructurado. Contrariamente a lo que pudiera parecer en un primer
o
momento, esto no supone ninguna limitaci´n a la hora de realizar un programa, ya que
o
se puede demostrar que cualquier programa se puede realizar utilizando unicamente estas
´
estructuras.
En concreto, est´ totalmente prohibido en el ambito de la asignatura la utilizaci´n de
a ´ o
las sentencias goto (que realiza un salto incondicional) y continue (que fuerza una nueva
iteraci´n dentro de de una estructura repetitiva), y s´lo se permite la utilizaci´n de la sen-
o o o
tencia break (que fuerza la salida de una estructura selectiva o repetitiva) en el ´mbito de
a
la sentencia selectiva m´ltiple, que se estudiar´ m´s adelante.
u a a
6.2. Estructuras Secuenciales
En un programa en C, las sentencias se ejecutan una tras otra en el orden en el que est´n
a
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´ n la expresi´ n o C = (5/9) * ( o F -32) */
u o
int main ()
{
float fahrenheit ;
float celsius ;
printf ( " Temperatura en grados Fahrenheit : " );
scanf ( " %f " , & fahrenheit );
4. 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´n se le denomina bloque, y puede aparecer en cualquier lugar en
o
el que puede aparecer una sentencia.
6.3. Estructuras Selectivas
Tambi´n llamadas condicionales; permiten que ciertas sentencias se ejecuten o no en
e
funci´n de una determinada condici´n.
o o
En C existen dos tipos de estructuras selectivas:
la simple: if else.
la m´ltiple: switch.
u
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:
=0 =0
expresi´n
o expresi´n
o
=0 =0
bloque else
bloque if bloque if
El funcionamiento de la estructura selectiva simple es el siguiente:
5. Fund. de la Prog. 2007–2008 6-5
1. se eval´a la expresi´n que acompa˜a a la cl´usula if
u o n a
2. Si la expresi´n es cierta (el valor de la expresi´n es distinto de cero), se ejecuta la
o o
sentencia que sigue a continuaci´n y se termina.
o
3. Si la expresi´n es falsa (el valor de la expresi´n es igual a cero) y existe la cl´usula
o o a
else, se ejecuta la sentencia que sigue a la cl´usula else y se termina.
a
o dicho de otra forma:
el bloque que sigue a la cl´usula if s´lo se ejecuta si el valor de la expresi´n es distinto
a o o
de cero.
si existe una cl´usula else, el bloque que sigue a dicha cl´usula s´lo se ejecuta si el
a a o
valor de la expresi´n es igual a cero.
o
#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´n en que lo que sigue a un if o a un else es un bloque, y recuerde que
o
un bloque es o una unica sentencia, a un grupo de sentencias encerradas entre llaves. Un
´
problema muy com´n cuando se utiliza una estructura selectiva simple consiste en utilizar
u
m´s de una sentencia (sin agruparlas en un bloque) bien en el bloque del if bien en el del
a
else:
if ( numero < 0)
negativo = 1;
suma -= 1;
else
6. 6-6 2007–2008
negativo = 0;
suma += 1;
En el primer caso (varias sentencias en el bloque del if), el compilador detectar´ el pro-
ıa
blema, puesto que habr´ un else que no se corresponde con ning´n if (tal y como est´ es-
ıa u a
crito, la sentencia selectiva simple terminar´ con la ejecuci´n de la sentencia negativo =
ıa o
1). La soluci´n, una vez detectado el problema, es simple: formar un bloque con las dos
o
sentencias encerr´ndolas entre llaves:
a
if ( numero < 0)
{
negativo = 1;
suma -= 1;
}
else
negativo = 0;
suma += 1;
El segundo caso es m´s grave, ya que no es ning´n error de sintaxis. Desde el punto de
a u
vista del compilador, la sentencia selectiva simple finalizar´ con la ejecuci´n de la sentencia
ıa o
negativo = 0, y la siguiente sentencia se ejecutar´ siempre, independientemente de si
ıa
numero es menor o no que cero. En consecuencia, si numero es menor que cero, las sentencias
que se ejecutar´ ser´
ıan ı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´n editor que sea capaz de entender la sintaxis
u
de C e indente adecuadamente cada sentencia, en funci´n del bloque al que pertenezca. Con
o
un editor de este tipo, el resultado que habr´
ıamos obtenido habr´ sido:
ıa
if ( numero < 0)
{
negativo = 1;
suma -= 1;
}
else
negativo = 0;
suma += 1;
donde puede observarse, por la situaci´n de la sentencia suma += 1, que no pertene al
o
bloque de la cl´usula else, como deber´
a ıa.
7. Fund. de la Prog. 2007–2008 6-7
La soluci´n, al igual que en el caso anterior, pasa por encerrar entre llaves (y formar un
o
bloque) las sentencias que forman parte del ambito 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´s a
cercano.
Por ejemplo, en el siguiente fragmento de c´digo:
o
if ( n > 0)
if ( a > b )
z = a;
else
z = b;
la cl´usula else se asocia a if (a > b). Si quisi´ramos que se aplicara al primer if,
a e
bastar´ con encerrar entre llaves el segundo if:
a
if ( n > 0)
{
if ( a > b )
z = a;
}
else
z = b;
De hecho es muy conveniente, en el caso de sentencias de selecci´n simples anidadas,
o
encerrar siempre entre llaves los bloques correspondientes a cada una de las cl´usulas if y
a
else que aparezcan, para dejar claro el ambito de cada una de ellas.
´
6.3.3. Estructura Selectiva M´ ltiple: switch
u
En la estructura selectiva m´ltiple, se puede seleccionar entra varias alternativas seg´n
u u
el valor de una expresi´n. La forma general de la estructura selectiva m´ltiple es:
o u
8. 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´ el siguiente:
ıa
expresi´n entera
o
=
valor 1 bloque 1
=
=
valor 2 bloque 2
=
=
default bloque por defecto
El funcionamiento de esta estructura es como sigue:
1. Se eval´a la expresi´n que acompa˜a al switch. Esta expresi´n se eval´a como expre-
u o n o u
si´n entera.
o
2. Se compara el valor obtenido, secuencialmente, con los valores que acompa˜an los
n
diferentes case, deteni´ndose en el primero que coincida. Estos valores deber´n ser
e a
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
9. Fund. de la Prog. 2007–2008 6-9
muy importante que esta etiqueta se sit´e como la ultima del bloque, puesto que las que se
u ´
pongan detr´s de ella nunca ser´n consideradas (como se ha obtenido la coincidencia en una
a a
etiqueta, se deja de comprobar el resto de etiquetas).
El problema de esta estructura es que si la expresi´n coincide con un case, se ejecuta ´se
o e
y todos los que hubiera por debajo (los case hacen las funciones de etiquetas), que no es lo
que habitualmente se desea. La soluci´n consiste en poner un break como ultima proposici´n
o ´ o
dentro de cada case, lo que hace que se finalice la ejecuci´n de la estructura switch:
o
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´n entera
o
=
valor 1 bloque 1 break;
=
=
valor 2 bloque 2 break;
=
=
default: bloque por defecto break;
10. 6-10 2007–2008
#include < stdio .h >
/* Programa que lea un n´ mero de mes ( en el rango de 1 a 12)
u
e indique el n´ mero de d´ as del mes . */
u ı
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´mo tras la ultima sentencia de cada bloque aparece una sentencia break para
o ´
dar por finalizada la ejecuci´n de la estructura selectiva m´ltiple (incluyendo el caso por
o u
defecto, default).
El caso por defecto (default) suele utilizarse para detectar caso no v´lidos o err´neos,
a o
evitando que se produzcan errores en la ejecuci´n. El siguiente ejemplo determina si un
o
n´mero entre el 1 y el 10 es par o impar; el caso por defecto se ha utilizado en este programa
u
para los n´meros que est´n fuera de ese rango:
u a
#include < stdio .h >
/* Determina si un n´ mero entre el 1 y el 10 es par o impar . */
u
int main ()
11. Fund. de la Prog. 2007–2008 6-11
{
int num = 0;
printf ( " nIntroduzca el n´ mero : " );
u
scanf ( " %d " , & num );
switch ( num )
{
case 1:
case 3:
case 5:
case 7:
case 9:
printf ( " n El n´ mero %d es impar n " , num );
u
break ;
case 2:
case 4:
case 6:
case 8:
case 10:
printf ( " n El n´ mero %d es par n " , num );
u
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´n de una condi-
o
ci´n. La principal diferencia entre las diferentes estructuras repetitivas consiste en qu´ punto
o e
se realiza la comprobaci´n de la condici´n.
o o
En C existen tres tipos de estructuras repetitivas:
while
do while
for
12. 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:
=0
expresi´n
o
=0
bloque while
El funcionamiento es el siguiente:
1. se eval´a la expresi´n que acompa˜a a la cl´usula while
u o n a
2. Si la expresi´n es cierta (el valor de la expresi´n es distinto de cero), se ejecuta el
o o
bloque que sigue a continuaci´n.
o
3. se vuelve al primer paso, y se repite el proceso.
Algunos aspectos de inter´s sobre esta estructura ser´
e ıan:
Puede que el bloque que sigue al while no se ejecute ninguna vez. Si la primera vez que
se calcula la condici´n el resultado es cero (falso), no se pasar´ a ejecutar el bloque, y
o ıa
se pasar´ directamente a la sentencia que siga a la sentencia while.
ıa
Alguno de los valores que determinan la condici´n debe ser modificado dentro del
o
bloque. Si no fuera as´ y la condici´n fuera cierta (distinta de cero) la primera vez que
ı, o
la comprob´ramos, pasar´
a ıamos a ejecutar el bloque, y ya no saldr´ ıamos nunca de ´le
puesto que la condici´n seguir´ siendo cierta de forma indefinida.
o ıa
En la condici´n, es conveniente utilizar los operadores de rango (<, >, <= o >=) en
o
lugar de los operadores de igualdad y desigualdad (== o !=).
Al igual que suced´ en el caso de las sentencias selectivas simples, es un error muy com´n
ıa u
querer utilizar m´s de una sentencia dentro del bloque del while pero no encerrarlas entre
a
llaves, como en el siguiente ejemplo:
13. 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´digo anterior no suma los diez primeros n´meros (del 1 al 10), sino unicamente el ultimo
o u ´ ´
(10); a pesar de que el compilador no ha detectado ning´n error. Eso es porque el bloque del
u
while est´ formado unicamente por la sentencia num++;, que es la que se repite 10 veces.
a ´
Una vez finalizado el bucle while es cuando se ejecuta la sentencia suma += num;, que
l´gicamente s´lo se ejecuta una vez. La forma correcta ser´ la siguiente:
o o ıa
#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;
}
14. 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
ambito de aplicaci´n del while entre llaves, aunque sea una unica sentencia. O utilizando
´ o ´
un editor de textos que entienda la sintaxis de C e indente adecuadmanete cada sentencia,
en funci´n del bloque a que pertenezca.
o
Valores Extremos en la Condici´n
o
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´n (el primer y el ultimo
o ´
valor para los que se ejecuta el bloque que acompa˜a a la cl´usula while) son los adecuados.
n a
Para ello es de gran utilidad repasar mentalmente (o con ayuda de papel y l´piz) qu´ su-
a e
cede en la condici´n de la sentencia while la primera vez que se llega a ella y la ultima vez
o ´
que se realiza la comprobaci´n (la vez que se termina la sentencia).
o
Vamos a utilizar como ejemplo para ver esto el del apartado anterior, de suma de los
10 primeros n´meros. La primera vez que llegamos al while, el valor de num vale 0 (lo
u
acabamos de inicializar), que cumple la condici´n (10 > num), por lo que entraremos a
o
ejecutar el bloque. Incrementamos el valor de num (que ahora pasar´ a valer 1) y lo sumamos.
a
Comprobamos pues que el primer valor del bucle es el correcto. Supongamos ahora que num
vale 9; la condici´n se sigue cumpliendo, y por tanto entramos en el bucle: incrementamos
o
num, que ahora pasa a valer 10, y lo sumamos. En la siguiente iteraci´n, la condici´n no se
o o
cumple y saldremos de la sentencia while. Hemos comprobado por tanto que efectivamente
hemos sumado los n´meros del 1 al 10.
u
Lo anterior se resume en la siguiente tabla:
num Condici´n Valor sumado num
o
0 cierta 1 1
...
9 cierta 10 10
10 falsa
Modifique el programa del apartado anterior si el bloque de la sentencia while es:
suma += num ;
num ++;
15. Fund. de la Prog. 2007–2008 6-15
6.4.2. 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
=0
expresi´n
o
=0
A diferencia de la sentencia while, en esta estructura repetitiva primero se ejecuta el
bloque y posteriormente se comprueba la condici´n. Por tanto, el bloque de una sentencia
o
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´ formado por una unica sentencia.
a ´
6.4.3. Sentencia for
La sintaxis de la sentencia for es la siguiente:
for ( inicial ;
expresi´ n ;
o
final )
bloque
El diagrama de flujo de esta sentencia ser´
ıa:
16. 6-16 2007–2008
inicial
=0
expresi´n
o
=0
bloque for
final
El funcionamiento de esta sentencia es el siguiente:
1. se ejecuta el bloque inicial.
2. se eval´a la expresi´n.
u o
3. si es igual a cero, se finaliza la ejecuci´n de la sentencia.
o
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´n se da por cierta, y se obtiene un
o
bucle infinito.
#include < stdio .h >
/* Programa que obtiene la suma de los n´ meros pares
u
comprendidos entre 2 y 1000. */
int main ()
{
17. Fund. de la Prog. 2007–2008 6-17
int i ;
int suma = 0;
for ( i = 2; i <= 1000; i += 2 )
suma += i ;
printf ( " La suma de los pares hasta 1000 es %d n " , suma );
return 0;
}
Pueden introducirse varias sentencias tanto en el bloque inicial como en el bloque
final. En ese caso, las sentencias van separadas por comas, ejecut´ndose de izquierda a
a
derecha:
#include < stdio .h >
/* Programa que obtiene la suma de los n´ meros pares
u
comprendidos entre 2 y 1000. */
int main ()
{
int i ;
int suma ;
for ( suma = 0 , i = 2; i <= 1000; suma += i , i += 2)
;
printf ( " La suma de los pares hasta 1000 es %d n " , suma );
return 0;
}
Obs´rvese el ; aislado que aparece tras la cl´usula for. Esto es necesario porque una sen-
e a
tencia for siempre incluye un bloque for. Si no hubi´ramos incluido ese ; (que representa
e
una sentencia vac´ el bloque del for lo hubiera constituido la sentencia printf, que se
ıa),
habr´ ejecutado 500 veces.
ıa
#include < stdio .h >
/* Calcula la potencia n de un n´ mero num */
u
int main ()
{
int num = 0;
int exponente = 0;
int potencia = 1;
int i = 0; /* var . de control del bucle */
18. 6-18 2007–2008
printf ( " nIntroduzca el n´ mero y exponente : " );
u
scanf ( " %d %d " , & num , & exponente );
for ( i = 1; i <= exponente ; i ++)
potencia *= num ;
printf ( " %d elevado a %d vale %d n " , num , exponente , potencia );
/* Proponer modificaci´ n para c´ lculo del factorial !!
o a
en el tema siguiente se ver´ de forma recursiva */
a
return 0;
}
Estructuras Repetitivas Anidadas
Una estructura puede contener otra dentro, cumpliendo que est´n totalmente anidadas:
e
for (......)
{
for (..........)
{
while (...)
{
...........
}
}
}
En bucles anidados cada alteraci´n del bucle externo provoca la ejecuci´n completa del
o o
bucle interno.
#include < stdio .h >
/* Imprime tablas de multiplicar */
int main ()
{
int i = 0;
int j = 0;
/* Primera aproximaci´ n */
o
for ( i = 1; i <= 10; i ++)
for ( j = 1; j <= 10; j ++)
printf ( " %d x %d = %d n " , i , j , i * j );
/* M´ s presentable */
a
for ( i = 1; i <= 10; i ++)
19. Fund. de la Prog. 2007–2008 6-19
{
printf ( " nTabla del %d n ============= n " , i );
for ( j = 1; j <= 10; j ++)
printf ( " %d x %d = %d " , i , j , i * j );
}
/* Ahora las tablas en paralelo .
OJO a como se recorren los ´ ndices . */
ı
for ( i = 1; i <= 10; i ++)
{
printf ( " n " );
for ( j = 1; j <= 10; j ++)
printf ( " %d x %d = %d t " , i , j , i * j );
}
printf ( " n " );
return 0;
}
6.5. Ejemplos de Uso
6.5.1. Lectura del teclado
El siguiente programa lee desde el teclado car´cter a car´cter, mediante la funci´n
a a o
getchar, y escribe lo le´ en la pantalla mediante la funci´n putchar. El proceso finaliza
ıdo o
cuando se recibe el car´cter de fin de entrada, EOF, que se obtiene pulsando simult´nea-
a a
mente las teclas Ctrl y D.
#include < stdio .h >
/* Programa que copia la entrada estandar a la salida estandar */
int main ()
{
int c = 0; /* Almacena caracteres */
c = getchar ();
while (( c = getchar ()) != EOF )
putchar ( c );
return 0;
}
20. 6-20 2007–2008
6.5.2. Soluci´n de una ecuaci´n de primer grado
o o
El siguiente programa calcula la soluci´n de una ecuaci´n de primer grado del tipo
o o
ax + b = 0
Para ello solicita los dos par´metros necesarios, y resuelve la ecuaci´n considerando de forma
a o
separada los casos especiales.
#include < stdio .h >
/* Resuelve una ecuaci´ n de primer grado :
o
0 = ax + b
a <> 0 = > x = -b / a
a == 0 y b <> 0 = > soluci´ n imposible
o
a == 0 y b == 0 = > sol . indeterminada */
int main ()
{
int a = 0; /* Coeficiente de la variable independiente */
int b = 0; /* T´ rmino independiente */
e
float x = 0; /* Soluci´ n */
o
printf ( " nIntroduzca los coeficientes a y b : " );
scanf ( " %d %d " , &a , & b );
if (0 != a )
{
x = -( float ) b / a ;
/* Razonar el resultado sin la conversi´ n forzada */
o
printf ( " nLa soluci´ n es %f n " , x );
o
}
else if ( b )
/* La condici´ n anterior equivale a esta otra : 0 != b */
o
printf ( " n Soluci´ n imposible n " );
o
else
printf ( " n Soluci´ n indeterminada n " );
o
return 0;
}
6.6. Ejercicios
1. El siguiente programa imprime los 10 primeros enteros utilizando una sentencia for:
#include < stdio .h >
21. Fund. de la Prog. 2007–2008 6-21
#define MAX 10
/* Representaci´ n de un bucle desde con mientras y
o
hacer - mientras . */
int main ()
{
int i = 0; /* Variable ´ ndice o de control */
ı
printf ( " n Bucle DESDE con for n " );
for ( i = 1; i <= MAX ; i ++)
printf ( " %d t " , i );
return 0;
}
Escriba un programa que realice la misma funci´n utilizando un bucle while. Repita
o
el ejercicio utilizando un bucle do-while.
2. El siguiente c´digo determina si un n´mero es par o impar:
o u
#include < stdio .h >
/* Determina si un n´ mero cualquiera ( incluso negativo )
u
es par o impar . */
int main ()
{
int num = 0;
printf ( " nIntroduzca el n´ mero : " );
u
scanf ( " %d " , & num );
switch ( num % 2)
{
case 0:
printf ( " n El n´ mero %d es par n " , num );
u
break ;
case 1:
case -1:
printf ( " n El n´ mero %d es impar n " , num );
u
break ;
default :
printf ( " n El m´ dulo es distinto de 0 , 1 , -1 n " );
o
break ;
}
return 0;
22. 6-22 2007–2008
}
Modificarlo sustituyendo el bloque switch por una simple sentencia selectiva if.
3. Realizar un programa que pida un n´mero positivo y escriba el cuadrado del mismo si
u
dicho n´mero se encuentra comprendido dentro del rango de 0 a 100, en caso contrario
u
dar un mensaje.
4. Programa que calcule el valor medio de los n´meros del 100 al 1000.
u
5. El siguiente programa (que denominaremos cuentaLineas.c ) lee el n´mero de l´
u ı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; /* Almacena caracteres */
int nl = 0; /* 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´digo para que cuente todos los caracteres.
o
6. Modificar cuentaLineas para que cuente palabras.
7. Escriba un programa que pida un n´mero y un exponente, ambos enteros, y calcule
u
el valor del n´mero elevado al exponente, utilizando la propiedad de que elevar un
u
n´mero a un exponente equivale a multiplicar el n´mero tantas veces como indique el
u u
exponente.
23. Fund. de la Prog. 2007–2008 6-23
8. Escribir un programa que lea n´meros enteros del teclado y los sume. El programa
u
terminar´ cuando se introduzca un n´mero negativo, imprimi´ndose la suma.
a u e
9. Realizar un programa que multiplique, sume o reste dos n´meros en funci´n de la
u o
opci´n elegida.
o