1. Hacer la prueba de escritorio del programa siguiente:
int a = 100 ;
a = a * 2 ;
a = 6 ;
¿Al final, importaba el valor inicial de la variable a
?
2. Hacer la prueba de escritorio del programa siguiente:
int a = ? ; /* algun valor */
int b = ? ; /* algun valor */
b = 2;
b = a + b;
a = a - 1;
a = 4;
¿Pueden reducir la cantidad de sentencias?
3. Sin hacer la prueba de escritorio, observar el programa siguiente:
/* 1.3 */
int a = 2;
int i;
for(i = 0; i < 5; i = i + 1){
a = 0;
a = a + 1;
a = i + 1;
printf("%d\n", a);
}
¿Se puede obtener el mismo comportamiento con menos sentencias?
La función scanf
es parecida a printf
pero hace la operación contraria, que es, leer valores que el usuario ingrese con el teclado. Estos valores luego pueden ser usados como valores en el programa.
Un ejemplo de uso de scanf
:
#include <stdio.h>
int main(void) {
int a;
printf ("Diga un valor para a:\n");
scanf("%d",&a); /* el usuario ingresa un valor entero,
que se asigna a la variable a */
printf ("el valor es: %d\n",a);
return 0;
}
No terminar un formato con \n
en scanf porque el salto de línea ya sirve para confirmar la entrada.
Usar la documentación de la materia para saber más acerca de scanf
.
Una variable es constituida de:
scanf
Cuando llamamos una funcion siempre se da a la función llamada algun valor:
hola(10); /* valor constante 10 */
hola(x); /* valor de la variable x */
hola(cuadrado(x)); /* valor de cuadrado(x) */
Es decir, se evalua el valor antes de que se haga la llamada.
Si en lugar del valor de una variable, damos la dirección en la memoria de la variable, entonces la función que llamamos es capaz de modificar el valor de esa variable.
En el lenguaje C, la expresión "&x" se puede leer como "la dirección de x".
Cuando llamamos una funcion pasandole un nombre de variable x se dice que la pasamos por valor:
funcion1(x);
Cuando lo hacemos pasandole la direccion de x, se dice que la pasamos por referencia:
funcion2(&x);
Hacemos un programa que pide el año de nacimiento y el año actual al usuario, y muestre la edad calculada del usuario. El programa se puede equivocar de un año (para la gente que todavía no cumplió años).
Definir un programa edad.c que tenga:
nacimiento
, actual
y edad
printf
para mostrar un mensaje invitando el usuario a ingresar su año de nacimientoscanf
para asignar el valor leido a nacimiento
actual
edad
assert
Ejemplo de uso de la función assert
:
#include <stdio.h>
#include <assert.h>
int main(void) {
int a;
printf ("Diga un valor POSITIVO para a:\n");
scanf("%d",&a);
assert(a >= 0); /* si la condición NO se cumple,
el programa se termina acá */
printf ("el valor es: %d\n",a);
return 0;
}
La función assert
sirve para poner una condición que tiene que cumplirse. Al no cumplirse, la ejecución del programa se termina.
assert
es particularmente útil al principio de un algoritmo, cuando solo tiene sentido ejecutarse cuando alguna condición se cumple.
Por ejemplo, un algoritmo de división puede primero comprobar con assert
que el divisor es distinto de cero.
En un programa con valores ingresados por el usuario, la estructura suele ser la siguiente:
assert
)Modificar su programa de cálculo del MCD de dos enteros para que los valores sean leidos por la función scanf
.
Usar la función assert
de la bibliotheca assert.h
para asegurarse que el programa se siga ejecutando solamente si los valores cumplen con la condición a >= b
.
Hasta ahora siempre definimos una sola función en nuestros programas: la función main
.
Ahora, además del main
vamos a definir más funciones, para poder llamarlas desde el main
.
Por el momento, vamos a definir funciones sin parámetros y que no devuelven ningun valor, es decir que su definición siempre va a empezar por:
void mi_funcion(void){
...
}
int main(void){
...
mi_funcion(); /* ejecutamos mi_funcion */
...
}
mi_funcion
tiene que estar antes de la función main
.Definir un programa robot_limpiador.c que muestra exactamente la salida siguiente:
1. limpiar
2. girar a la derecha
3. avanzar
1. limpiar
2. girar a la derecha
3. avanzar
1. limpiar
2. girar a la derecha
3. avanzar
1. limpiar
2. girar a la derecha
3. avanzar
FIN
El programa debe tener las funciones pasos
y main
, y la función pasos
se encarga de mostrar los pasos repetidos en la salida.
En uno de sus programas (robot_limpiador.c
, mcd.c
...) agregar una función void imprimir_autor(void)
que se imprima:
Hacer una llamada a esta función desde el main
de su programa, justo antes de que se termine.
Vamos a conocer unas funciones nuevas para conseguir valores aleatorios.
Compilar y ejecutar el programa siguiente:
#include <stdlib.h>
#include <stdio.h>
int main()
{
int r;
int i;
for(i=0; i<5; i++)
{
r = rand();
printf("%d\n", r);
}
return 0;
}
La biblioteca stdlib.h
proveé la función rand
, cuya llamada devuelve un número número aleatorio. Es como tirar un dado o una moneda, salvo que los valores generados están dentro de un rango muy grande (de 0 a la constante RAND_MAX
).
Si reemplazamos la expresión rand()
por rand() % 100
, restringimos los números aleatorios al rango de 0 a 99:
r = rand() % 100;
Compilar este programa y ejecutarlo varias veces. ¿Qué observamos? ¿Es lo que esperamos?
Explicación: rand()
es un generador pseudo-aleatorio. Genera una secuencia que no es realmente aleatoria, porque cada número generado dependen del número anterior generado.
Para que esa secuencia parezca aleatoria, debemos inicializar el primer nùmero de la secuencia con algun valor que no sea igual entre dos ejecuciones de nuestro programa.
¡Usemos la hora!
La biblioteca time.h
proveé la función time
que devuelve la cantidad de segundos desde el 1970. Luego, llamamos la función srand
para inicializar la secuencia aleatorio que genera rand()
:
#include <stdlib.h>
#include <time.h>
int main(void){
int hora = time(NULL); /* el número de segundos desde el año 1970 */
srand(hora); /* inicializamos la semilla con la "hora" */
...
...
...
...
}
Modificar el programa y observar que los valores generados cambian en cada ejecución.
Ya conocemos el bucle while
, ahora veamos do ... while
que es muy parecido, salvo que garantiza que se ejecuta por lo menos una vez. (Un bucle while
puede no ejecutarse si su condición es falsa.)
Su sintaxis es:
do {
... /* cuerpo del bucle */
} while (/* CONDICION */);
Lo podemos traducir como "ejecutar CODIGO una vez y repetirlo mientras CONDICION es verdadero".
Programemos un juego que consiste en adivinar el número que el programa eligió al azar.
La estructura del programa es la siguiente:
Usemos un bucle do ... while
para que el programa sigua pidiendole al usuario que ingreso del valor por el usuario por lo menos una vez.
El programa tiene que usar los mensajes siguientes (o alguna versión de estos que les parece mejor):
imprimir_autor
Programar el juego en un archivo adivina.c.
Una vez que su juego funciona, agrégenle los cambios siguientes:
Tienen hasta el sábado 28 martes 31 de mayo a las 23hs59 para mandar su proyecto.
Si me mandan su programa antes del martes 31 a las 17hs, les puedo hacer una sola devolución por mail para que lo puedan mejorar.
Consignas:
edad.c
con por lo menos 3 mejoras que ustedes elijen individualmenteimprimir_ayuda
imprimir_autor
Ideas de mejoras posibles:
time.h