15 dic 2011

Introduccion a C

Esta es la primera entrega de tutoriales de C. Trataré de cubrir la mayor cantidad de conocimientos en este lenguaje; cabe aclarar que este tutorial está pensado para novatos 100%, para aquellos que no han tendio ni el más mínimo contacto con C y que desean crear sus propios programas. Estos tutoriales servirán como base para programar en cualquier plataforma, aunque estarán centrados en Windows por su sencillez, ideal para los novatos.
Esta serie de tutoriales, ha sido una grandiosa elección empezar a programar en C. Si no tienes ni idea de qué es eso, te informaré un poco:
C es un lenguaje de programación (Creo que eso es obvio), sucesor de B, creado en 1972. Se caracteriza por su inigualable potencia y aplicación a sistemas operativos, especialmente aquellos basados en Unix.
C es elegido por gran cantidad de personas que buscan un perfecto equilibrio entre eficacia y facilidad de aprendizaje. Al ser un lenguaje considerado de medio nivel, posee carcaterísticas comparables al lenguaje humano al igual que otras que lo acerca al lenguaje de máquina, de aquí su perfecto equilibrio.
Si no te convences aún, esto debería hacerlo: Los sistemas operativos Linux, está hechos casi en su totalidad en C.
Basta ya de tanta teoría, seguramente estas ansioso por empezar. De cualquier forma, dejo un link por si te interesa saber más sobre la historia de C.

C es simple, pero requiere un buen entorno de desarrollo si quieres lograr algo, o simplemente no aburrirte. Con entorno de desarrollo me refiero a un programa que te simplificará varias tareas, desde escribir el código fuente, hasta la tarea de compilar, todo en uno. He probado varios IDE (Entornos de desarrollo), pero ninguno me convenció tanto como Dev-C++ ya que es ideal para aquellos novatos, sobre todo al momento de compilar. No requiere nada más que instalar el programa y ejecutarlo, también trae librerías (o biblotecas) precargadas.

¡¿Compi-qué?!

Com-pi-lar, debes de acostumbrarte a utilizar esta palabra. ¿Alguna vez te has preguntado cómo se hacen los *.exe? Si eres curioso deberías de abrir con el Bloc de Notas un ejecutable. Lo que verás son miles de líneas de código binario. En reailidad es lo mismo que se escribe en un código fuente, pero traducido a un lenguaje que la máquina pueda entender. Es prácticamente imposible programar directamente en binario, es por eso que nosotros lo hacemos a través de comandos y operaciones que podemos etender (Código Fuente o Source Code).
El compilador transforma nuestro código fuente, fácilmente comprendido, en un ejecutable (En el caso de Windows) capaz de ser comprendido por una computadora.
Y esta es otra característica que le brinda un gran poder a C, en vez de ser interpretado como otros lenguajes (Lua, HTML, etc.) es compilado.


Antes de empezar sería conveniente saber la estructura básica de C, te evitarás muchos dolores de cabeza si sabes ésta.
  • Siempre al principio de todo programa en C, se deben de incluir las Directivas (No te preocupes mucho por los nombres).
  • Todo programa en C, debe de tener por lo menos una función llamada main.
  • Todos los comandos en C, se separan por un punto y coma ;
  • C distingue entre mayúsculas y minúsculas.
  • Puedes usar todo el espacio en blanco que desees para darle una mejor vista al programa, excepto al momento de declarar directivas.

Creo que ya tuviste suficiente introducción, ya sabeslo suficiente para hacer el primer programa de todo programador: el archiconocido Hola mundo

Hola Mundo

Ya estas listo para hacer tu primer programa en C. No es nada del otro mundo, pero servirá enormemente paraque te des una idea de qué es programar y las particularidades del lenguaje. Estoy hablando del famosísimo Hola Mundo, el primer programa por excelencia, no llegarás muy lejos sin él.
Vamos a empezar. Abre tu IDE preferido, en mi caso es Dev-C++ e inicia un nuevo documento. Esto me lo pude haber ahorrado, pero es que hay cada despistado, me incluyo.
Voy a escribir aquí todo el programa, posteriormente explicaré línea por línea éste. Escribe el siguiente código, no copies y pegues, es mejor que lo escribas tú msimo, favorece el aprendizaje.

/* Mi primer programa en C: Hello world
Tu nombre
La fecha */
 
#include <stdio.h>
 
int main()
{
    printf("Hola Mundo");
 
    return 0;
}

Ahora a analizar el programa parte por parte:

/* Mi primer programa en C: Hello world
Tu nombre
La fecha */
Esto es un comentario. Se usa para describir el programa, señalar su autor o describir alguna función, son ideales si un proyecto se prolonga mucho, con ayuda de ellos podrás identificar facilmente fragmentos de código, incluso si no has revisado el código por años. Un comentario siempre debe empezar con /* y u prterminar con */, aunque hay otras formas de hacerlos. Es importante aclarar que el compilador no los toma en cuenta, por eso no alterarán tu programa.
Si escribieramos:
Mi primer programa en C: Hello world
Tu nombre
La fecha 
 El compilador marcaría un error ya que trataría de interpretar estas líneas y no sabría que hacer con ellas.Debes cuidar que el comentario se cierre correctamente, si quitáramos el */ al ejemplo anterior, tendriamos como resultado sólo un comentario, todo tu programa quedaría convertido en un comentario y el compilador marcaría un error.
Nunca intentes poner comentarios dentro de los argumentos de una función o dentro de una palabra clave, el compilador marcaría un error.
Pasemos a la siguiente parte.

#include <stdio.h>

Esto es una directiva. Al llamar a una directiva, estaremos indicando al compilador que incluya esta librería (En este caso stdio.h) en el programa. En las librerías se incluyen funciones ya definidas, así, sólo basta con llamarlas. Es el ejemplo estamos llamando a stdio.h que contiene la función printf, que utilizamos en el programa.
Un programa puede contener cuantas directivas decida su autor.

int main()

Esto es la función principal. Todo programa debe de tener una función principal, en ella se específica qué es lo que hará el programa, en el ejemplo imprimirá un "Hola Mundo" en pantalla. El int, viene de Interger o Entero. Más adelante explicaré más a fondo los tipos de datos (int, float, void, etc.) y el main, simplementeindica que es la función principal. Recuerda poner los paréntesis () y siempre debe de estar delimitada por corchetes {}.

{
    printf("Hola Mundo");
Esto es el cuerpo del programa. El corchete { indica que ahí empieza la función. printf es una función definida en stdio.h, ésta muestra información por pantalla. C distingue entre mayúsculas y minúsculas, por lo tanto cuida no escribir Printf en vez de printf. Después de llamar a la función, se establecen sus argumentos ("Hola Mundo") esta es la expresíon más simple de printf, simplemente contiene entre comillas "" el texto que se mostrará en pantalla. Fíjate que después de los argumentos hay un punto y coma ; en C son utilizados para separar los comandos, cuida ponerlos, es un error muy común y dificil de encontrar.

return 0;
}

Este es un comando que forma parte de tu programa, es recomendable que siempre lo utilices. Aquí se define cuál será el valor que regresará la función en caso de que se haya llevado a cabo correctamente. De nuevo, separamos el comando con ;. Y finalmente cerramos los corchetes }.

Es muy probable, sobre todo si usas Windows, que al ejecutar el programa sólo aparezca una ventana y se cierre inmediatamente. Para evitar esto puedes añadir lo siguiente, antes del return 0;:

getchar();
Esta función se incluye en stdio.h, lo que hace es esperar a que se presione una tecla para cerrar el programa.

Ya que entiendes el código, por qué no lo pruebas, escribe el programa de ejemplo en tu editor y después compilalo. En Dev-C++ bastará con presionar la tecla F9.

¿Ques es eso de programar?

Si estás interesado en la programación, o sencillamente siempre te has preguntado cómo se le dan órdenes a un ordenador, espero que este tutorial te sirva de ayuda. No voy a usar ningún tecnicismo más allá del realmente necesario, pretendo que esto sea una lectura amena, lo menos aburrida posible y que cuando termines, te haya quedado un poco más claro "qué es eso de la programación" y "cómo se le dicen las cosas a los ordenadores".
Antes de nada, hay que decir que el cerebro humano funciona de manera diferente al de una computadora. Tenemos este simple texto:
Que por mayo era, por mayo,
cuando hace la calor,
cuando los trigos encañan
y están los campos en flor (...)
Un ordenador, tendría que procesar cada carácter uno a uno, Q-u-e-(ESPACIO)-p-o-r-(ESPACIO)-m-(...). Una vez que tiene el texto recorrido, separará las palabras según los espacios: Que(ESPACIO)por(ESPACIO)mayo(...). Luego con cada palabra, buscará en un diccionario si se trata de un verbo, pronombre, hasta dar sentido a la frase.
Parece un método lento, pero todo esto se procesa tan rápido, en milisegundos, que da la sensación de que un ordenador lee "de golpe" como nosotros. Si aún dudas que nuestro cerebro no procesa las letras una a una, aquí tienes un ejemplo:
Sgeun un etsduio de una uivenrsdiad ignlsea, no ipmotra el odren en el
que  las ltears etsan ersciats, la uicna csoa ipormtnate es que la
pmrirea y la  utlima ltera esten ecsritas en la psiocion cocrrtea. El
rsteo peuden estar  ttaolmntee mal y aun pordas lerelo sin pobrleams.
Etso es pquore no lemeos cada ltera por si msima snio la paalbra cmoo un tdoo. 
¿Puedes leerlo verdad? :D.Lo mismo sucede cuando reconocemos una cara, no vamos "pixel a pixel", buscando un ojo, la nariz, la boca, para luego juntarlos igual que con las letras. Sino que miramos "un todo" de la cara y nuestro cerebro lo procesa de esta manera.
Bien, todo esto ha sido para que comprendas lo más importante: A UN ORDENADOR HAY QUE DECIRLE TODO PASO A PASO MEDIANTE UN "LENGUAJE DE PROGRAMACIÓN", no procesan la información como nosotros.
Un lenguaje de programación (LP) es "el idioma" que se usa para dar ordenes a una computadora. Hay muchísimos, seguramente os suenen algunos como "basic" o "c". Si estás pensando cual lenguaje es "el mejor", piensa en cada LP, como un tipo de zapatos. ¿Cómo puedes decir cual es el mejor zapato?. Hay que decir "para qué". Unas botas de trekking pueden ser las mejores para hacer senderismo, pero si lo que quieres es estar cómodo en casa, las pantuflas serían la mejor opción, es decir no hay "el mejor zapato", tan sólo el mejor para una situación determinada y aún así seguro que habrá más de una variedad y la decisión será difícil.
Por eso, hay LP que te facilitan mucho la tarea si estás usando gráficos tridimensionales y otros con los que seguramente será imposible, o para procesar una base de datos, etc. De momento, basta con que sepas que hay muchísimos lenguajes y unos son mejores para ciertas cosas que otros.
Antes de poner un ejemplo de programa, voy a decir las partes básicas que suele tener cualquier lenguaje de programación, que son:
  • variables.
  • sentencias de control y de bucle.
  • funciones, métodos o procedimientos
VARIABLES:
    Una variable, es una zona de la memoria, en la cual se guarda un dato o grupo de datos. Para acceder a esos datos, en vez de decir la posición de la memoria (como la posición 1289232), se usa lo que podríamos decir un nick o tag. Por ejemplo:
   
total = 37
    Esto crea una variable, que tiene nombre "total" y guarda el valor "37". Podría estar en la posición de memoria 1289232 o en la 58, eso da lo mismo porque el valor de una variable se averigua accediendo a su "nick", no a su posición de memoria. Este ejemplo imprimiría 37:
   
print total
    Imagináos un edificio que se llame "Edificio los claveles". Nosotros si conocemos su nombre, podemos ir a ese sitio, no hace falta usar un GPS e ir a la coordenada xxxx,yyyy, para ir al edificio y ver quién está dentro.
   
SENTENCIAS DE CONTROL Y DE BUCLE:
    Esto es el término que se suele usar para instrucciones que comprueban una determinada condición, o que ejecutan un bucle hasta que cierta condición se cumple. Un bucle es un "ciclo". Vamos a ver las más comunes:
   
*if then else (si entonces sino). Esta no necesita explicación, se puede ver con el ejemplo.
if total > 100 then
    print "El total supera los 100Euros"
else
    print "El total es igual o menor que 100Euros"
   
*while condition do (mientras condicion hacer). Se realiza un bucle o ciclo mientras se cumpla la condición.
while temperatura > 0 do {
    LeerTemperatura()
}
print "El agua se ha congelado"

Aquí realizamos un bucle, comprobamos que la temperatura sea mayor que cero, si es así, volvemos a leer la temperatura con una función (veremos las funciones más adelante). Cuando no se cumpla la condición, se saldrá del bucle y se imprimirá el mensaje de que se han congelado el agua.    *do while condition (hacer mientras condición). Esta es similar a la anterior, sólo que la comprobación se hace "al final" del bucle, no al principio. Lo que tiene es que al menos la primera vez se ejecuta el bucle aunque no se cumpla la condición, ya que se comprueba al final.
do {
    LeerTemperatura()
} while temperatura > 0
print "El agua se ha congelado"

*for valor_inicial to valor_final, incremento do (mientras valor_inicial hasta valor_final hacer): Esta quizás sea una de las más complicadas, se realiza un bucle en el que una variable toma un valor, en cada recorrido del bucle, ese valor aumenta "incremento" y se repite el bucle hasta que se llega o se pasa el valor_final. Aquí pongo un ejemplo, no te preocupes si no lo entiendes del todo.
for valor=1 to 10, +2 do {
    print valor
}
print "Hemos salido del bucle porque valor es >= 10"

Esto imprimiría
1
3
5
7
9
Hemos salido del bucle porque valor es >= 10
   
FUNCIONES, MÉTODOS O PROCEDIMIENTOS:
En realidad, es todo lo mismo, puede que según el lenguaje usado haya algunas diferencias, aquí voy a usar la palabra funciones. Una función, es un trozo de código que está aislado y puede "llamarse" para ejecutar sus intrucciones. Esta función, puede recibir datos, lo que se conoce como "pasar parámetros" y devolver ningún, uno o varios resultados. Lo normal en la mayoría de los lenguajes es uno o ninguno. Para que veas la utilidad de una función imagina el ejemplo de la temperatura del bucle while. Ahí usé una función llamada LeerTemperatura() (las funciones generalmente suelen llevar paréntesis al final). Imagina que para leer la temperatura hay que hacer una serie de pasos.
///Esto es lo que hay que hacer para leer la temperatura
abrir carcasa del sensor
sacar sensor
guardar lectura de sensor en variable "temperatura_tomada"
meter sensor
cerrar carcasa del sensor

Ahora tenemos un programa que lee la temperatura 3 veces:
///Aquí van 400 lineas de código
 
abrir carcasa del sensor
sacar sensor
guardar lectura de sensor en variable "temperatura_tomada"
meter sensor
cerrar carcasa del sensor
 
///Aquí tenemos otras 800 lineas de código
 
abrir carcasa del sensor
sacar sensor
guardar lectura de sensor en variable "temperatura_tomada"
meter sensor
cerrar carcasa del sensor
 
///Aquí 1000 lineas de código más
 
abrir carcasa del sensor
sacar sensor
guardar lectura de sensor en variable "temperatura_tomada"
meter sensor
cerrar carcasa del sensor
 
///2000 lineas más y acaba el programa

He omitido las otras lineas, pero fíjate que hemos repetido 3 veces las mismas intrucciones. Además si la rutina de leer la temperatura estuviera mal, por ejemplo, se ha descubierto que la carcasa cierra pronto y golpea al sensor, hay que hacer una pausa antes de cerrarlo.
///Lectura de temperatura con la pausa implementada
abrir carcasa del sensor
sacar sensor
guardar lectura de sensor en variable "temperatura_tomada"
meter sensor
esperar 3 segundos
cerrar carcasa del sensor

Se ha añadido una linea que espera 3 segundos antes de cerrar la carcasa, en el ejempo anterior, habría que buscar entre más de 4000 lineas y añadir esta instrucción donde se lea la temperatura. Explico esto para que veáis cual es el motivo de usar funciones, "divide y venceras". De nuevo el ejemplo usando funciones.
///Aquí se define la función
function LeerTemperatura() {
    abrir carcasa del sensor
    sacar sensor
    guardar lectura de sensor en variable "temperatura_tomada"
    meter sensor
    cerrar carcasa del sensor
}
 
///Aquí van 400 lineas de código
 
LeerTemperatura()
 
///Aquí tenemos otras 800 lineas de código
 
LeerTemperatura()
 
///Aquí 1000 lineas de código más
 
LeerTemperatura()
 
///2000 lineas más y acaba el programa

Las ventajas son evidentes, muchas menos lineas y cuando pongamos la instrucción "esperar 3 segundos", tan sólo tenemos que ir a la parte donde se definió la función, no buscar entre miles de lineas. Espero que esto no haya sido muy aburrido, ni muy técnico, creo que es necesario para que comprendas el ejemplo de programa que voy a poner. Vamos a hacer un programa que durante 24 horas, realice mediciones de temperatura, una vez cada hora. Si la temperatura está por debajo de 0, se muestra un mensaje y el programa termina, si está subiendo desde la última medición o está bajando, se muestra un mensaje en consecuencia. Así de simple :D.
Cuando se trata de comunicarle a un ordenador, hay que acordarse que hay que ir paso a paso, y "plantearselo" bien, o lo que es lo mismo, decirle las variables, datos y funciones que vamos a usar. En este caso, vamos a usar nuestra función "LeerTemperatura()", otra que llamaremos "EsperarUnaHora()", que se queda detenida durante una hora y las siguientes variables, que usará para guardar temporalmente distintos datos:
lecturas ///Contendrá las cantidad de lecturas realizadas
temperatura_actual  ///La temperatura leída actualmente
temperatura_anterior ///La temperatura anterior.

1  Function LeerTemperatura() {
 2      abrir carcasa del sensor
 3      sacar sensor
 4      guardar lectura de sensor en variable "temperatura_tomada"
 5      meter sensor
 6      esperar 3 segundos
 7      cerrar carcasa del sensor
 8      devolver el valor de "temperatura_actual"
 9  }
10
11  lecturas = 1
12  t_actual
13  t_anterior
14  while lecturas <= 24 {
15      t_actual = LeerTemperatura()
16      if t_actual < 0 then
17          print "Por debajo del punto de congelación, se termina la medición"
18          end_of_program
19      if lecturas == 1 then
20          t_anterior = t_actual
21      if t_anterior < t_actual then
22          print "La temperatura está subiendo"
23      if t_anterior > t_actual then
24          print "La temperatura está bajando"
25      t_anterior = t_actual
26      lecturas = lecturas + 1
27      if lecturas <= 24 then
28          EsperarUnaHora()
29  }

   
Voy a explicar el código un poco por encima para que veas que hasta la cosa más simple, requiere una serie de pasos estructurados para comunicarle a un computador lo que queremos que haga. No te preocupes si no lo entiendes del todo, la intención de este tutorial es que comprendas que a los ordenadores hay que darle las instrucciones muy desglosadas y que funcionan procesando dichas intrucciones una a una. Entre la linea 1 y 9, está la definición de la función LeerTemperatura(), sólo que en la linea 8, le he añadido que devuelva el valor leído.
En las linea 11, definimos una variable contador, que llevará las lecturas realizadas, comenzamos con el valor 1 que es la primera lectura que vamos a hacer. en 12 y 13, tenemos t_actual y t_anterior, que llevarán las temperatura que se acaba de leer y la leída en la hora anterior respectivamente. No se inicializan con ningún valor como el contador lecturas, esto se hará en el programa.
En 14 creamos un bucle, que se cumplira mientras el núm. de lecturas sea menor o igual a 24. En 15, guardarmos en la variable t_actual la temperatura leída. Si está por debajo de cero, termina el programa, y si es la primera lectura, como no tenemos una lectura anterior todavía, igualamos ambas, es decir, la anterior y la actual, son la misma.
Las lineas hasta la 25 creo que están claras, en 25 la temperatura anterior, pasa a ser la actual, así en la próxima lectura, ya estará guardada.
En 26, incrementamos en uno el número de lecturas. Por último en 27, esperamos una hora para realizar la siguiente medición, excepto la última vez, que no hace falta esperar, terminará el "bucle while" y acabará el programa