Como primer ejemplo de un programa en C, vamos a considerar el programa "Jalisco". Este programa le pregunta al usuario un número, para después ganarle diciendo el sucesor. La pantalla muestra la salida del programa:
Por favor ingresa un número: 4944
Lo siento, te gano con el 4945
Este programa podría escribirse en muchos lenguajes distintos, cómo C, C++, Pascal, Turing, Smalltalk, etc. Nosotros usaremos como lenguaje de programación C. Una vez que uno aprende un lenguaje, se hace muy fácil aprender lenguajes que tengan un paradigma similar.
El programa Jalisco, escrito en C, es el siguiente
/* Jalisco nunca pierde */
main ()
{
/* Variables */
int n;
printf ("Por favor ingresa un número:");
scanf (%d,&n);
printf ("Lo siento, te gano con el ");
printf (%d \n,n+1);
}
Por ahora, nos concentraremos en la parte principal del programa, es decir, en las líneas 3 a la 10. El significado y utilidad de las otras líneas vamos a analizarlos más adelante.
Línea |
Ejecución |
4
|
Un comentario sirve para ayudarle al programador a recordar qué hace cada parte de un programa. Todos los comentarios empiezan con /* y terminan con */ |
5
|
Esta instrucción declara una variable para guardar número enteros (int) cuyo identificador es n. Puedes imaginarte una variable como un cajón en la memoria donde se puede guardar un valor (que puede ir cambiando durante el transcurso del programa, de ahí el nombre "variable"). Esto se puede esquematizar de la siguiente forma: n _____ |
6
|
El programa escribe en la pantalla un mensaje para el usuario: Por favor ingresa un número: Para mostrar un mensaje se utiliza el método printf, el cual escribe su argumento (lo que va entre paréntesis) en pantalla |
7
|
Esta instrucción le asigna a n un número entero que se lee desde teclado. Para avisarle al usuario que se está esperando el ingreso de un número, C muestra un pequeño cuadrado parpadeante llamado cursor: Por favor ingresa un número: C espera a que el usuario escriba el número y presione la tecla Enter. Cuando esto sucede, C le asigna el número que leyó a la variable de nombre n. Supongamos que el usuario ingresa el número 512 y presiona Enter: Por favor ingresa un número: 512 En la variable n se almacena este número n _512_ |
8
|
Esta instrucción muestra un nuevo mensaje en la pantalla: Por favor ingresa un número: 512 Lo siento, te gano con el |
9
|
Finalmente, C calcula cuál es el número que sigue a n y lo muestra en la pantalla Por favor ingresa un número: 512 Lo siento, te gano con el 513 |
En C uno puede guardar información en elementos llamados variables. Cada variable tiene un tipo, que indica qué es lo que se guardará en ella. Existen varios tipos numéricos, entre los cuales se encuentran los números enteros (int) y los números reales (double).
Las variables en C son declaradas de la siguiente forma:
tipo identificador;
Por ejemplo,
int alumnos;
double temperatura;
La declaración tiene que preceder el uso de la variable en un programa. Por ejemplo, es incorrecto:
|
Una vez que la variable ha sido declarada, su tipo no puede cambiarse. También es incorrecto:
int manzanas;
manzanas=7;
printf ("Hay %d manzanas\n",manzanas);
printf ("Me como media");
float manzanas;
manzanas=6.5;
printf ("Ahora hay %f manzanas\n",manzanas);
Pon tus conocimientos a prueba Escribe un programa en C que calcule el área y perímetro de un círculo. La siguiente pantalla muestra el diálogo del programa: |
Ingresa el radio del círculo (cm): 3.1
El perímetro del círculo es 19.477
El área del círculo es 30.191
Solución
El programa es el siguiente:
/* Área y perímertro de círculo */
main ()
{
float radio, pi=3.141592654;
printf ("Ingresa el radio:");
scanf (%f,&radio);
printf ("El área es ");
printf (%f\n,pi*radio*radio);
printf ("El perímetro es");
printf (%f\n,2*pi*radio);
}
Analicemos qué sucede durante la ejecución del programa:
Línea |
Ejecución |
23
|
Esta instrucción declara una variable para guardar número reales (double) cuyo identificador es radio. radio _____ |
24
|
El programa escribe en la pantalla un mensaje para el usuario: Ingresa el radio: |
25
|
Se le asigna a radio un número real que se lee desde teclado. Ingresa el radio: 3.0 radio _3.0_ |
26
|
Esta instrucción muestra un nuevo mensaje en la pantalla: Ingresa el radio:3.0 El área es: |
27
|
C calcula cuál es el área del círculo, es decir, el producto de la constante pi y el cuadrado de radio. Ingresa el radio:3.0 El área es: 28.274 |
28
|
C muestra un nuevo mensaje en la pantalla Ingresa el radio:3.0 El área es: 28.274 El perímetro es: |
29
|
Para finalmente calcular el perímetro y mostrarlo Ingresa el radio:3.0 El área es: 28.274 El perímetro es: 18.8495 |
Las variables de tipos numéricos pueden ser combinados mediante operadores aritméticos para formas expresiones.
Los operadores aritméticos se ven en la siguiente tabla:
Símbolo |
Operador |
+ |
suma |
- |
resta |
* |
multiplicación |
/ |
división |
% |
módulo |
Las precedencia son iguales a las del álgebra:
expresiones entre paréntesis
multiplicación y división
suma y resta
En caso de dos o más operadores de igual precedencia, se evalúa de izquierda a derecha.
Ejemplos:
Expresión |
Escrita correctamente |
Escrita incorrectamente |
|
(a-b)/(2*c) (a-b)/2/c |
a-b/2*c (a-b)/2*c |
|
a+b*c a+(b*c) |
(a+b)*c |
En caso de dudas, siempre se puede usar paréntesis, total son gratis.
Para conocer el tipo de una expresión, se puede utilizar la siguiente regla:
Expresión |
Tipo |
Ejemplo |
Simple |
double si x o y es double
int si ambos son int |
9/2.0=4.5 8/2.0=4.0 9/2=4 8/2=4 |
Compuesta |
según la precedencia de los operadores se aplica la regla anterior
|
Si d es una variable double y t una variable int, entonces (d/1000) / (t/3600) (double/int) / (int/int) double / int double |
En C existe un operador muy útil llamado módulo, muy relacionado con la división y que se denota por %. El módulo entre dos números enteros a y b es el resto de la división entera entre ambos.
Por ejemplo,
7/2 ® 3
7%2 ® 1
¿Qué hace el siguiente programa?
int s,minutos,segundos;
printf ("Ingresa la cantidad de segundos transcurridos");
scanf(%d,&s);
printf ("Eso equivale a ");
minutos=s/60;
printf (%d,minutos);
printf (" minutos y ");
segundos=s%60;
printf (%d\n,segundos);
El almacenamiento de valores en las variables se lleva a cabo mediante la asignación (=). Una variable puede ser asignada reiteradas veces. Por ejemplo,
int dolar;
dolar=480;
printf ("El valor del dólar es %d\n",dolar);
dolar=500;
printf ("El nuevo valor del dólar es %d\n".dólar);
No solo se puede asignar valores numéricos fijos, también expresiones
double g=9.87,t,v;
printf ("Cuanto tiempo ha transcurrido desde que se soltó el objeto?\n");
scanf(%f,&t);
v=g*t;
printf ("La velocidad es de %f\n",v);
Una de las cosas que no siempre se puede hacer es asignar una expresión de un tipo a una variable de otro tipo. Por ejemplo, el siguiente código es incorrecto
int superficie=3.1416*radio*radio;
Ya que se está tratando de guardar un número real en una variable que ha sido declarada como real. Es como tratar de guardar pelotas de tenis en un envase de pelotas de ping-pong.
Una vez que una variable ha sido asignada, su valor no se modifica hasta que se le vuelva a hacer una asignación |
Una variable no puede ser usada en una expresión hasta que se le ha dado un valor. Se llama inicialización a la primera asignación de una variable.
double pi;
pi=3.14159;
Como ya hemos visto, C permite inicializar una variable en la misma instrucción en la que se le declara:
double pi=3.14159;
Asignaciones con la variable asignada en la expresión
C permite realizar asignaciones donde la variable asignada aparece en la expresión de la derecha:
int conejos=5;
conejos=conejos+1;
C evalúa primero la expresión de la derecha y luego asigna ese valor a la variable. En este caso C calcula cuánto vale conejos+1. Recién cuando sabe que el valor es 6, lo asigna a conejos.
El incremento de una variable, es decir, una asignación del tipo
n=n+1;
se ven tan a menudo en C que existe una notación abreviada para ella
n++;
Lo mismo para el decremento:
n--; es lo mismo que n=n-1;
"Swap" del valor de dos variables
Imagina que tienes dos variables enteras, x e y, que son inicializadas con el valor 5 y con un número leído desde el teclado, como se ve en el código X
int x=5;
int y;
scanf(%d,&y);
¿Cómo harías para intercambiar el valor de ambas variables?
Una solución que puede parecer correcta es
x=y;
y=x;
Sin embargo lo que hace realmente C es dejar en x e y el valor original de y, ya que primero se le asigna el valor de y a x, con esto el valor de x se pierde. Después se le asigna este valor a y, que no se ve modificado, pues x tiene el valor original de y.
Una solución consiste en usar una variable auxiliar. Hay variables que no se ocupan para guardar valores en forma temporal, generalmente para facilitar la realización de un cálculo o tarea. Estas variables reciben el nombre de variables auxiliares.
En este caso vamos a usar una variable auxiliar para guardar el valor original de x
int auxiliar=x;
x=y;
y=auxiliar;
Al igual que las calculadoras científicas, C trae incorporado una gran gama de funciones en la librería math.h, entre las que se encuentran las siguientes:
sqrt(x) |
raíz cuadrada de x |
abs(x) |
valor absoluto de x |
pow(x,y) |
x "elevado a" y |
exp(x) |
exponencial de x |
log(x) |
logaritmo natural de x |
sin(x) |
seno de x (radianes) |
cos(x) |
coseno de x (radianes) |
tan(x) |
tangente de x (radianes) |
asin(x) |
arcoseno de x (radianes) |
acos(x) |
arcocoseno de x (radianes) |
atan(x) |
arcotangente de x (radianes) |
round(x) |
x redondeado. Por ejemplo, round (3.6) es 4, round(3.4) es 3 |
floor(x) |
piso de x. Por ejemplo, floor (3.6) es 3, al igual que floor (3.4) |
ceil(x) |
techo de x. ceil (3.6) y ceil (3.4) es 4 |
trunc(x) |
devuelve la parte entera de x (el tipo de la función es int) |
Por ejemplo, para calcular el área de un círculo cuyo radio es radio la expresión en C es
double area=3.1416*pow(radio,2);
Para guardar en una variable entera los grados del arcotangente de (0.3) se puede usar
int grados=trunc(180.0*atan(0.3)/3.1416);
Problema 1: Maquina reversadora de cifras Haz un programa que reciba un numero de 5 digitos (suponga que lo ingresan bien) y muestre el número en forma reversa: |
Maquina reversadora de numeros
Ingrese un numero: ? 12345
Su numero en forma normal es 12345
Su numero al reves es 54321
Solución:
int numero, digito1, digito2, digito3, digito4, digito5, alreves;
printf("Maquina reversadora de numeros");
printf("Ingrese un numero: ? ");
scanf(%d,&numero);
/* desmenuzamos el numero */
digito1= numero / 10000;
digito2= (numero % 10000) / 1000;
digito3= (numero % 1000) / 100;
digito4= (numero % 100) / 10;
digito5= (numero % 10);
/* lo armamos de nuevo */
alReves= digito5 * 10000 + digito4 * 1000 + digito3 * 100 + digito2 * 10 + digito1;
// mostramos el resultado
printf("Su numero en forma normal %d \n ", numero);
println("Su numero al reves es %d \n", alReves);
Problema 2: Calculo de distancias
Haga un programa que pregunte por las coordenadas de dos puntos en el plano y calcule la distancia (euclidiana) entre ellos.
Calculo de distancia entre dos puntos
Coordenadas x y del primer punto ? 10.2 4.5
Coordenadas x y del segundo punto ? 7.5 -3.5
Solución:
double x1,y1,x2,y2,distancia;
printf ("Calculo de distancia entre dos puntos \n");
printf("Coordenadas x y del primer punto ? ");
scanf(%f,&x1);
scanf(%f,&y1);
print("Coordenadas x y del segundo punto ? ");
scanf(%f,&x2);
scanf(%f,&y2);
distancia = sqrt( pow((x1-x2),2) + pow ((y1-y2),2) );
printf ("La distancia euclidiana entre %f,%f y %f,%f es %f \n ,x1,y1,x2,y2,distancia );
Total a pagar: 7823
El cliente paga: 10000
Vuelto = 2177
Desglosado en:
0 billete(s) de 10000
0 billete(s) de 5000
2 billete(s) de 1000
0 billete(s) de 500
1 moneda(s) de 100
1 moneda de 50
2 moneda(s) de 10
1 moneda de 5
2 moneda(s) de 1
2. ¿Qué escribe el siguiente programa en la pantalla?
int a=5,b=3,c=1;
printf ("Los valores de las variables son %d %d %d",a,b,c);
a=b;
b++;
printf ("Los valores de las variables son %d %d %d",a,b,c);
c--;
a=c;
printf ("Los valores de las variables son %d %d %d",a,b,c);
c--;
a=2*c-b;
printf ("Los valores de las variables son %d %d %d",a,b,c);
3. ¿Cómo harías un swap de dos variables sin usar una variable auxiliar? Este problema de ingenio es realmente difícil. Intenta resolverlo.
Entre los errores más comunes detectados en el primer control de Computación I destacan los siguiente: |
Ocupar una variable sin declararla
Ocupar una variable sin inicializarla
Ocupar nombres cortos de variables: si bien esto no es un error, en un programa largo puede inducir a errores. Es una mala técnica tratar de "ahorrar tiempo" acortando el identificador de una variable. Para almacenar el radio de una figura es mucho mejor usar una variable radio en vez de una variable p.
Asignar un double a un int sin usar la función de conversión trunc ( ). Esto error es detectado en tiempo de compilación.
Inventar operadores o notaciones:
Notación "inventada" por alumno |
C (correcto) |
|
area=3.1416*radio*radio; |
|
radio=diametro/3.1416; ó radio=diámetro/pi; (si pi ha sido declarado) |
Recuerda siempre que los lenguajes de programación son sumamente extrictos con respecto a la sintáxis (cómo se escriben las cosas)! |
Hasta ahora los programas que hemos visto consisten en una serie de instrucciones que se van ejecutando una tras otra en forma secuencial, como se ve en la figura 1:
|
|
Figura 1 Figura 2
Sin embargo hay ocasiones en las que uno puede querer que una instrucción se ejecute sólo si se cumple una condición determinada, como se ve en la figura 2.
En C esto se lleva a cabo gracias a la sentencia "if", que permite ejecutar una instrucción (o bloque de instrucciones) dependiendo del valor de verdad de una expresión lógica.
En el siguiente programa se muesta el uso de if para calcular el máximo de dos números:
int a,b,maximo;
printf ("Ingresa dos números");
scanf(%d %d,&a,&b);
máximo=a;
if (b>a)
máximo=b;
printf("El máximo es %d",máximo);
Línea(s) |
Ejecución |
1-3 |
Se pide al usuario que escriba dos números desde el teclado |
4 |
Se inicializa la variable máximo con el valor de a |
5,6 |
Si b es mayor que a entonces el valor de b se le asigna a máximo |
7 |
Se escribe el máximo en la pantalla |
La instrucción if más simple consiste en la palabra if seguida de una condición entre paréntesis y la instrucción que se debe ejecutar si la condición es verdadera:
if (condición)
instrucción;
Si la condición no se cumple, entonces la instrucción no se ejecuta y se pasa a la siguiente instrucción.
Una condición es una expresión que tiene un valor verdadero o falso o una combinación de ellas. En este capítulo analizaremos las expresiones en las que comparamos expresiones aritméticas entre sí.
Operadores de relación, su significado y un ejemplo:
Operador |
Significado |
Ejemplo |
== |
igual a |
(x==10) |
< |
menor que |
(x<y) |
> |
mayor que |
(x+5>y) |
<= |
menor o igual a |
(2*x<=-4) |
>= |
mayor o igual a |
(valorAntiguo>=valorNuevo) |
!= |
distinto de |
(x!=18/y) |
Las condiciones compuestas se forman a partir de condiciones simples unidas mediante los operadores lógicos O, Y y negación:
Operador |
Significado |
Ejemplo |
|| |
O lógico |
(total<=0 or total>=100) |
&& |
Y lógico |
(puntaje==600 && lugar<500) |
! |
negación |
(!(lugar<minimo)) |
Muchas veces, lo que nos interesa es ejecutar una instrucción si se cumple una determinada condición y ejecutar otra si no se cumple. Esquemáticamente:
Por ejemplo,
int a;
printf ("Ingresa el año:");
scanf(%d,&a);
if (a%4==0 && a%100!=0)
printf ("El año es bisiesto\n");
else
printf ("El año es normal\n");
Línea(s) |
Ejecución |
10...12 |
Se pide un año y se guarda en la variable año |
13 |
Se evalúa la condición "¿es el año divisible por 4 y no por 100?" |
14 |
Si la condición es verdadera se escribe "El año es bisiesto en la pantalla" |
15-16 |
Si la condición es falsa, se muestra el mensaje "El año es normal" |
Si uno quiere que se ejecute más de una instrucción si la condición del if se cumple uno puede agrupar las instrucciones en un bloque:
float a,b,c,d;
printf ("Ingresa los coeficientes a, b y c");
scanf (%f %f %f,&a,&b,&c);
d=b*b-4*a*c;
if (d>0) {
float x1, x2;
printf ("Las soluciones son reales y valen");
x1=(-b+sqrt(d))/(2*a);
x2=(-b-sqrt(d))/(2*a);
print ("%f y %f\n",x1,x2);
} if (discriminante==0) {
float x;
printf ("Existe una sola solución real ");
x=(-b+ sqrt(d))/(2*a);
printf (%f\n,x);
} else {
float real, imaginario;
printf ("Las soluciones son complejas y valen");
imaginario=sqrt(-d))/(2*a);
real=-b/(2*a);
printf (%f + %fi y,real,imaginario);
printf (%f - %fi \n,real,imaginario);
}
Sigamos la ejecución:
Línea(s) |
Ejecución |
17-19 |
Se leen desde el teclado los coeficientes de la ecuacion ax2+bx+c=0 |
20 |
Se calcula el discriminante |
21-26 |
Si el determinante es mayor que 0, entonces se muestran las dos soluciones reales |
27-31 |
Si el determinante es igual a 0, entonces se muestra la única solución real Nota: En la práctica no es buena idea comparar un número de tipo double con otro número de tipo double por problemas de representación interna. |
33-38 |
Si ninguna de las dos condiciones anteriores se ha cumplido, entonces se escribe el valor de las dos soluciones complejas |
Un bloque de instrucciones es un conjunto de instrucciones que actúan como si fueran una sola. Por lo general, C permite colocar un bloque de instrucciones en el contexto donde se puede colocar una instrucción. Un bloque de instrucciones comienza con un paréntesis { y termina con un paréntesis }.
Problema 1: Suma de fracciones La suma de dos números racionales se define como |
Escribe un programa que lea dos número racionales y escriba el resultado. Si el resultado es un número entero, escríbelo de esa forma tambíen. Fíjate que los denominadores sean distintos de 0. Si no es así, en vez de escribir el resultado escribe una advertencia que diga que el resultado es erróneo
Solución:
int num1,den1,num2,den2,num,den;
/* Preguntar los numeradores y denominadores */
printf ("Ingresa el numerador de la primera fraccion: ");
scanf(%d,&num1);
printf ("Ingresa el denominador de la primera fraccion: ");
scanf(%d,&den1);
printf ("Ingresa el numerador de la segunda fraccion: ");
scanf(%d,&num2);
printf ("Ingresa el denominador de la segunda fraccion: ");
scanf(%d,&den2);
num=num1*den2+num2*den1
den=den1*den2
if (den==0)
printf ("Uno de los dos denominadores ingresados es 0\n");
else
printf("El resultado es %d/%d",num,den);
if (num%den==0)
printf("Lo que es equivalente a %d",num/den);
Un error común es agregar una clausula else que no hace nada. Aunque esto no es erroneo el código se vuelve más complicado de entender. Por ejemplo, la clausula else del siguiente programa está demás. Esta trata de representar "si la velocidad supera los 50 kilometros por hora, entonces hay que subir el cambio, si no, el cambio se mantiene" |
if (velocidad>50)
cambio=cambio+1;
else
cambio=cambio;
Lo correcto es
if (velocidad>50)
cambio=cambio+1;