Noción de parametro formal y parametro real.
Ejemplo:
#include <stdio.h>
void hola(void){
printf("Hola mundo!\n");
}
void mostrar1(int a){
printf("Tengo %d manzanas.\n", a);
}
void mostrar2(int a, int b){
printf("Tengo %d manzanas y vos %d.\n", a, b);
}
int main(void) {
int x = 60;
hola();
mostrar1(18);
mostrar1(20);
mostrar1(x);
mostrar2(20,25);
mostrar2(25,20);
mostrar2(x,x);
mostrar2(x,100);
return 0;
}
Escribir un programa tiempo.c que tenga una función void mostrar_anho(int a)
, para que muestre:
Estamos en el 2000!
Estamos en el 2016!
Estamos en el 2999!
Queremos que 2000, 2016, 2999 sean parametros reales en el main
cuando llamamos mostrar_anho
.
Ver en el apunte "Aprenda C", el uso de la palabra-clave return
.
#include <stdio.h>
int cuadrado(int a){
return a*a;
}
int pi(void){
return 3;
}
int main(void){
int x = 0;
x = pi();
x = cuadrado(5);
printf("x vale %d\n", x);
return 0;
}
En el lenguaje C se interpetan los valores enteros no nulos como "verdaderos" y nulos como "falsos".
Es decir, la condición siguente siempre es falsa:
if ( 0 ) {
...
}
Las condiciones siguientes siempre son verdaderas:
if ( 1 ) {
...
}
while ( 2 ) {
...
}
for ( ... ; 3 ; ... ){
...
}
Pero se suele usar el valor "1" para indicar "verdadero".
Escribir un programa bool.c que tenga el main siguiente:
int main(void){
int i;
for ( i = 0; i < 30 ; i = i + 1 ){
if ( divisible_por_3(i) ){
printf("%d es divisible por 3.\n", i);
}
}
return 0;
}
Completar este programa con la función int divisible_por_3(int a)
que devuelve el valor 1
(uno) si su argumento es divisible por 3 y 0
(cero) sino. Asegurarse que el programa es correcto.
Sobre papel, escribir una función de tipo int leer_entero(void)
que lea un entero ingresado por el usuario usando scanf y lo devuelve.
La compilación de un programa C ocurre en distintas etapas.
Podemos distinguir en este proceso 2 pasos consecutivos:
En nuestro código siempre usamos #include <stdio.h>
al principio. La palabra #include
es una instrucción para el preprocesador. Se encarga de incluir el archivo stdio.h
en nuestro archivo. Es decir, el preprocesador copia dentro de nuestro archivo el contenido del archivo stdio.h
. Ese último tiene las declaraciones de funciones de entrada y salida, como printf
y scanf
.
Si queremos, podemos usar #include
en cualquier lado de nuestro código fuente para copiar el contenido de otros archivos.
Vamos a usar la instrucción #define
del preprocesador para definir macros. Una macro es una palabra que va a ser substituida por algun valor fijo que definimos:
#define PI 3.14159
Por ejemplo:
#include <stdio.h>
#define PI 3.14159
int main(void){
printf("Si un circulo tiene un radio de %d cm,\n", 5);
printf("entonces su diametro es de %f cm\n", 5 * PI * 2);
printf("y su area es de %f cm2. \n", 5 * 5 * PI);
return 0;
}
Típicamente usamos una macro (en lugar de una variable) para valores que tienen que ser constantes e iguales en todo el programa. Permite definir una constante en un solo lugar (y modificarla en un solo lugar si hace falta) y usarla en todos lados.
Cuando usamos #define PI 3.14159
, el preprocesador busca todas las ocurrencias de la palabra PI
en nuestro programa y las reemplaza por 3.14159
. Luego ocurre la verdadera etapa de compilación.
Un arreglo (o vector, o lista) es una variable que almacena varios valores dispuestos succesivamente en la memoria y accesibles por su posición.
Por ejemplo, si declaramos un arreglo de enteros de tamaño 10 con valores iniciales, escribimos:
int arr[10] = {18,17,20,17,23,23,25,22,23,20};
Esta declaración tiene el efecto de definir la variable arr
, y un espacio en la memoria donde se guardan los 10 valores del arreglo:
+----+----+----+----+----+--..--+----+----+
arr: | 18 | 17 | 20 | 17 | 23 | .. | 23 | 20 |
+----+----+----+----+----+--..--+----+----+
indice: 0 1 2 3 4 8 9
Para referirse a valores individuales de un arreglo, usamos los corchetes. En el caso presente, el valor de arr[0]
es 18, el de arr[1]
es 17, etc. El último valor, arr[9]
es 20.
¡Cuidado con los índices! Empiezan con 0. Por lo cual si un arreglo es de tamaño n
, su último elemento es de indice n-1
.
En el lenguaje C se puede trabajar con arreglos de tamaño fijo o variable. Sin embargo es más simple trabajar con arreglos de tamaño fijo, porque no necesitamos pedir memoria al sistema operativo para trabajar con esos, se hace automáticamente. En Programación 2 (segundo cuatrimestre) sí vamos a ver arreglos de tamaño variable.
Una manera cómoda de recorrer los valores de un arreglo es usar un bucle for
:
int temperaturas[7] = {21,23,22,22,20,19,23};
int i;
for( i = 0; i < 7; i++){
printf("En el dia %d, hizo %d grados.\n", i + 1, temperatura[i]);
}
Tenemos esta constante 7
que aparece dos veces en nuestro programa. Si seguimos agregando instrucciones a nuestro código, tenemos que acordarnos del valor de esta constante, lo que puede ser propenso a errores. Para evitar eso, definamos una macro:
#define DIAS 7
int temperaturas[DIAS] = {21,23,22,22,20,19,23};
int i;
for( i = 0; i < DIAS; i++){
printf("En el dia %d, hizo %d grados.\n", i + 1, temperatura[i]);
}
Podemos modificar los elementos de un arreglo:
#define DIAS 7
int temperaturas[DIAS] = {21,23,22,22,20,19,23};
int i;
for( i = 0; i < DIAS; i++){
printf("En el dia %d, hizo %d grados.\n", i + 1, temperatura[i]);
}
/* oh no! el calentamiento global no para! */
for( i = 0; i < DIAS; i++){
temperaturas[i] = temperaturas[i] + 2; /* va a hacer 2 grados mas de calor! */
}
En un archivo temperatura.c, declarar un arreglo de tamaño 7 con valores enteros de su elección.
En un bucle for, calcular el valor máximo de ese arreglo. Mostrarlo.
Calcular el valor mínimo de ese arreglo. Mostrarlo.
Hasta ahora siempre hemos trabajado con variables de tipo entero int
. Podemos trabajar con variables de tipo "flotante" o "coma flotante" que permiten representar valores decimales.
#include <stdio.h>
int main(void){
float x = 1.0 / 3;
/* escribimos 1.0 en lugar de 1 para que la división se
haga sobre valoes flotantes, y no enteros
*/
printf("x == %f\n", x);
return 0;
}
Una variable de tipo float
puede tener errores de aproximación. Por ejemplo no se puede representar el verdadero valor de 1/3 ( 0.333333...) porque la representación en la computadora tiene que ser truncada (un float
tiene solo un espacio finito para representar valores).
Modificar el programa temperatura.c para calcular y mostrar la temperatura promedia.
Con el lenguaje C, es posible que un programa compile sin errores ni warnings, pero que tenga un error cuando se ejecuta.
Si tratan de acceder a un elemento de un arreglo que está fuera del rango posible es probable que el programa le tire el error Segmentation Fault
, en castellano "violación de segmento".
El segmento violado en ese caso es un segmento de memoria. El error significa que intentaron acceder a una parte de la memoria que no está autorizada para su programa.
Pueden agregar el flag -g
a tcc
para tener más información cuando se encuentran con un Segmentation Fault:
$ tcc -g -run programa.c
Modificar temperatura.c para pedir al principio, que el usuario ingrese los valores del arreglo de temperaturas.
Mandar temperatura.c.