Expresiones y sentencias.
Expresión: Combinación
de operandos mediante operadores. La expresión más
simple es un operando aislado (una constante o una variable.
La asignación
también posee un valor, que es el que adquiere
la variable a la izquierda del signo igual. Así se pueden
realizar asignaciones múltiples.
Ejemplo 2.1. Realizar un programa que asigne
el número diez a tres variables enteras y después
imprima sus valores.
Ejercicio: Modificar
el programa anterior para que lea por teclado el valor de
una variable adicional y posteriormente asigne el valor de dicha
variable adicional a las tres variables anteriores ("a", "b"
y "c") mediante una asignación múltiple.
Un programa es un conjunto de sentencias. En C cada
sentencia debe finalizar con un punto y coma.
Una sentencia
compuesta (bloque) es un conjunto de sentencias encerrado
entre llaves.
La sentencia if.
Permite elegir la
acción o acciones a realizar en función del
valor de verdad de una expresión.
if (<expresión>)
<sentencia>
else
<sentencia>
Ejemplo 2.2. Realizar un programa
que imprima por pantalla el valor absoluto de un entero
pedido por el teclado.
Ejercicio: Modificar
el programa anterior para que lea por teclado dos enteros
y posteriormente imprima en pantalla el máximo de ambos.
Pueden escribirse sentencias anidadas,
donde cada sentencia else es, a su vez,
otra sentencia if-else.
Ejemplo 2.3. Realizar
un programa que lea un número a través del teclado
e indique si dicho número es positivo, negativo o igual a
cero.
#include
<stdio.h>
int
main(){
int x;
printf("Escribe un entero:");
scanf("%d", &x);
putchar('\n'); /* Imprime un carácter de salto de línea */
if (x != 0) {
if (x > 0)
printf("El entero es positivo.\n");
else
printf("El entero es negativo.\n");
} /* Estas llaves pueden omitirse */
else
printf("El entero es igual a cero.\n");
system("pause");
return 0;
}
Ejercicio: Modificar
el programa anterior para que en primer lugar determine si
el entero introducido por teclado es igual a cero, y en caso contrario
discrimine si es positivo o negativo.
Si existen sentencias if-else anidadas, cada
sentencia else corresponde
siempre a la sentencia if más próxima.
Ejemplo 2.4. Ejecutar el siguiente programa y comprobar que
la sentencia else
se halla vinculada a la segunda condición, aunque por el
estilo de escritura (sangrado) parezca que dicha sentencia depende
de la primera condición.
Ejercicio: Modificar
el programa anterior para que la sentencia else quede ahora vinculada
a la primera condición.
La sentencia switch.
Ejercicio:
Desarrollar un programa que lea por teclado dos reales (double) y el signo de uno
de los siguientes operadores: +, -, *, /. El programa, según el carácter del operador,
seleccionará la operación y mostrará el resultado
en la pantalla. También presentará un mensaje de error en
el caso de que el usuario escriba un carácter distinto de los permitidos.
El bucle while.
Pertenece a la categoría de bucles
condicionales. La sentencia (simple o compuesta) se ejecuta
de cero a n veces según el valor de verdad de la expresión
(condición de entrada).
Ejemplo 2.6. Escribir un programa
que lea caracteres del teclado y los imprima por pantalla encriptados,
a excepción del carácter de salto de línea ('\n'). La clave de encriptación
vale diez, de modo que el carácter que se imprime es el
que hace diez a partir
del carácter original, según el código de
entrada/salida usado (ASCII en los ordenadores personales).
Nota: La función
getchar() lee un
carácter de la entrada estándar, y la función
putchar() lo escribe
en la salida estándar.
/* programa sencillo de encriptación */
#include <stdio.h>
#define K 10 /* clave de encriptación */
int main() {
char ch;
while ((ch = getchar()) != EOF) {
if (ch ==
'\n')
putchar(ch); /* '\n' no se encripta */
else
putchar(ch + K); /* otro se encripta */
} /* las
llaves se pueden omitir */
system("pause");
return 0;
}
Ejemplo 2.7. Escribir un programa
que imprima por pantalla la suma de los cien primeros números
naturales.
Nota: Obsérvese
como el programa lleva a cabo una suma iterada: En
cada iteración del bucle se añade al acumulador (suma) el valor correspondiente
del contador (n).
Al principio suma
vale cero, lo cual es lógico puesto que todavía
no se le ha añadido
ningún sumando.
#include <stdio.h>
#define TOPE 100
int main() {
unsigned
n = 1, sum = 0;
while (n
<= TOPE) {
sum += n; /* sum = sum + n; */
n++;
}
printf("\nLa
suma es: %u.\n", sum);
system("pause");
return 0;
}
Ejercicio:
Tomando como base el programa del ejemplo 2.7, escribir otro
que imprima la suma de los cuadrados de los k primeros números naturales. El usuario
deberá introducir por teclado un valor para k mayor
o igual que la unidad.
El bucle do-while.
La sentencia (simple o compuesta) se ejecuta
de una a n veces según el valor de
verdad de la expresión (condición de salida),
la cual se comprueba tras cada iteración.
do
<sentencia>
while (<expresión>);
/* programa para adivinar un número */
#include <stdio.h>
#define NUM 1000 /*número
a adivinar */
int main() {
int elegido;
do {
printf("\nDame un entero: ");
scanf("%d", &elegido);
}
while (elegido != NUM);
puts("\nAcertaste!!!");
system("pause");
return 0;
}
Ejercicio: Rescribir el ejemplo 2.7 haciendo uso de la
sentencia do-while.
El bucle for.
Permite aumentar la legibilidad de los bucles
en algunos casos y escribirlos de forma más compacta. Al principio,
y una sóla vez, se ejecuta la expresión de inicialización.
Posteriormente se evalúa la expresión de test.
Si ésta es cierta, se ejecuta la sentencia (simple o compuesta)
y tras ella la expresión de actualización. El ciclo
"test-sentencia-actualización" se repite mientras sea cierta
la expresión de test.
for (<inicialización>;
<test>; <actualización>)
<sentencia>
El formato anterior puede reescribirse del siguiente
modo:
Ejemplo 2.9. Escribir un programa que imprima
por pantalla el factorial de un entero mayor o igual a cero introducido
por el usuario a través del teclado.
#include
<stdio.h>
int main() {
unsigned i, n;
unsigned fact = 1;
printf("\nEscribe un entero: ");
scanf("%u", &n);
for (i = 1;
i <= n; i++)
fact *= i; /* fact = fact * i; */
printf("\nFactorial de %u: %u.\n", n, fact);
system("pause");
return 0;
}
Ejercicio:
Rescribir el programa del ejemplo 2.7 mediante el uso de la sentencia
for.
Ejemplo
2.10. Escribir un programa que cuente desde uno hasta diez
e imprima por pantalla dicha cuenta.
#include
<stdio.h>
int main() {
unsigned i;
for (i = 1;
i <= 10; i++)
printf("Cuenta: %d.\n", i);
system("pause");
return 0;
}
Ejercicio:
Modificar el programa del ejemplo 2.10 para que imprima la cuenta,
en orden inverso, desde diez hasta uno.
Ejemplo 2.11. Escribir un programa que imprima
en orden las letras minúsculas del abecedario y sus códigos
ASCII.
#include
<stdio.h>
int main() {
char ch;
for (ch =
'a'; ch <= 'z'; ch++)
printf("ASCII de %c: %d.\n", ch,
ch);
system("pause");
return 0;
}
Ejercicio:
Modificar el programa del ejemplo 2.11 para que imprima, en orden
inverso, las letras mayúsculas del abecedario y sus códigos
ASCII.
Ejemplo 2.12. Comprobar que el siguiente programa
contiene un bucle infinito y, por lo tanto, la ejecución
del programa se detiene
en éste y para salir del mismo es necesario cerrar su ventana.
#include
<stdio.h>
int
main() {
for ( ; ;) puts("Eternidad");
puts("Esta sentencia no se ejecuta.");
system("pause");
return 0;
}
Ejemplo 2.13.
Es posible omitir, cuando sea conveniente, algunas de las expresiones
de la sentencia for:
#include
<stdio.h>
int main() {
unsigned i = 1;
for (; i <= 10; ) {
printf("Cuenta: %d.\n", i);
i++;
}
system("pause");
return 0;
}
Las sentencias break; y continue;.
La sentencia break; puede utilizarse con
los tres bucles anteriores. Cuando el programa llega a esta sentencia
dentro de un bucle, el flujo abandona este último y pasa
a ejecutar la siguiente sentencia del programa. Normalmente se usa la
sentencia break; cuando
existe más de una razón para abandonar la estructura
iterativa: La más importante se suele escribir como condición
del bucle y las demás se codifican como sentencias if (...) break;.
Ejemplo
2.14. Escribir
un programa que lea caracteres del teclado y los imprima por
pantalla hasta que el usuario escriba el carácter de fin
de fichero (^Z), el cual se encuentra
codificado en el fichero de encabezamiento <stdio.h> como la constante
EOF, o bien dicho usuario escriba en el teclado el carácter
de salto de línea ('\n').
#include <stdio.h>
int main()
{
char ch;
while ((ch = getchar()) != EOF) {
if (ch == '\n') break;
putchar(ch); /* no depende del "if" */;
}
system("pause");
return 0;
}
La sentencia continue; dentro de un bucle
evita el resto de la iteración y desvia el flujo del programa
de nuevo hacia la expresión de test. Puede utilizarse en
las tres sentencias iterativas anteriormente definidas, pero no en
una sentencia switch.
Ejemplo 2.15. Modificar el programa del ejemplo 2.14 para que
lea caracteres del teclado y los imprima por pantalla a excepción
del carácter de
salto de línea ('\n'), el cual se ignorará cada vez que
el usuario lo escriba. Dicho programa finalizará su ejecución cuando
el usuario escriba el carácter de fin de fichero (^Z), el cual se encuentra codificado
en el fichero de encabezamiento <stdio.h> como la constante
EOF.
#include
<stdio.h>
int main() {
char ch;
while ((ch = getchar()) != EOF) {
if (ch == '\n') continue;
putchar(ch); /* no depende
del "if" */;
}
system("pause");
return 0;
}
Ejercicios de afianzamiento.
Escribir un programa
que acepte tres enteros a través del teclado e imprima por
pantalla el mayor y el menor de éstos.
Desarrollar
un programa que resuelva la ecuación de segundo grado: a x2 + b x + c. Para ello, el programa pedirá en primer lugar los tres coeficientes
reales. A continuación, según el signo del discriminante
(b2 - 4 a c), presentará un mensaje para indicar al
usuario si la ecuación posee dos soluciones reales, una solución
doble o no tiene solución en el conjunto de los números reales.
En los dos primeros casos el programa mostrará la solución:
(-b ± SQRT(b2 - 4 a c)) / 2 a.
Codificar tres programas
que sean equivalentes entre si y proporcionen el mismo resultado.
El primero de ellos utilizara la sentencia while, el segundo la sentencia
do-while
y el tercero la sentencia for.
Desarrollar un
programa que muestre por pantalla la suma de los cien enteros siguientes
a un entero positivo suministrado a través del teclado.
Escribir un programa
que lea del teclado temperaturas expresadas en grados Farenheit y las
convierta a grados Celsius. El programa finalizará cuando lea
un valor de temperatura igual a 999. La conversión de grados Farenheit
(F) en Celsius (C) viene dada por la siguiente expresión: C
= 5/9 * (F - 32).
Nota: Para que la división de 5 entre 9 dé
como resultado un número real y no cero, el dividendo, el divisor
o ambos deben ser de tipo real. Esto puede conseguirse mediante un
moldeado (conversión de tipo) o escribiendo directamente las constantes
como datos reales (double).
Codificar un programa
que muestre los n primeros términos de la sucesión
An = 1/2n. El primer término de la misma se corresponde
con n igual a uno. El valor de n debe suministrarse
a través del teclado.
Modificar el programa
anterior para que muestre la suma de los n primeros términos
de la sucesión An = 1/2n. El primer término de la misma se corresponde con
n igual a uno. El valor de n debe suministrarse a
través del teclado.
Desarrollar un programa
para calcular el máximo común divisor de dos enteros positivos
(unsigned) suministrados
por teclado mediante el Algoritmo de Euclides, el cual se describe a
continuación.
Sea T el máximo
común divisor de X e Y (T = MCD (X, Y)). Entonces se cumple:
a) X > Y => T
= MCD (X, Y) = MCD (X - Y, Y).
b) X < Y => T = MCD (X, Y) = MCD
(X, Y - X).
c) X = Y => T = MCD (X, Y) = X = Y.
Ejemplo: Hallar el máximo
común divisor de 1000 y 450.
MCD (1000, 450) = MCD
(550, 450);
MCD (550, 450) = MCD
(100, 450);
MCD (100, 450) = MCD
(100, 350);
MCD (100, 350) = MCD
(100, 250);
MCD (100, 250) = MCD
(100, 150);
MCD (100, 150) = MCD
(100, 50);
MCD (100, 50) = MCD
(50, 50);
MCD (50, 50) = 50.