TEMA 1 : Conceptos básicos 

1.0 Introducción

        En este segundo tema se describirá la estructura  básica  de
un programa en lenguaje C así  como la forma de visualizar distintos
tipos de datos  en pantalla. Se introducirán los  conceptos de tipos
de datos básicos y su utilidad.

1.1 El programa HOLA MUNDO

        Este programa se  ha convertido en un clásico  dentro de los
libros de  programación. Simplemente muestra en  pantalla el mensaje
HOLA  MUNDO, esto  que puede  parecer muy  tonto es algo fundamental
puesto que  si no sabemos imprimir  mensajes ó datos en  la pantalla
difícilmente nuestro programa se podrá  comunicar con el usuario que
lo utilice.

        Mostraremos el programa y  a continuación describiremos cada
una de las instrucciones que lo forman.

        /* Programa : HOLA MUNDO */
        #include <stdio.h>

        main()
        {
                printf ("\nHola mundo");
        }

        Como podemos observar se trata  de un programa muy sencillo.
La primera línea es lo que  se conoce como un comentario, un mensaje
que el programa añade al código del programa para explicar o aclarar
su funcionamiento o el de una parte de él. Los comentarios se pueden
situar en  cualquier parte de  nuestro código y  se considerará como
comentarios cualquier mensaje que  se encuentre entre los caracteres
/* y */.

        Los "/*" y "*/" no son caracteres, sino símbolos o banderas.

        La siguiente  línea es lo  que se conoce  como directiva del
preprocesador,  todos   los  compiladores  de   C  disponen  de   un
preprocesador, un programa que examina el código antes de compilarlo
y que  permite  modificarlo  de  cara  al  compilador  en  distintos
sentidos.  En  temas  posteriores  trataremos  en  profundidad estas
directivas del  preprocesador, pero para el  desarrollo de los temas
anteriores a  este debemos conocer  al menos la  directiva #include.
Las directivas se  caracterizan por comenzar con el  carácter # y se
deben incluir  al comienzo de la  línea aunque es probable  que esto
dependa  de  la  implementación  del  compilador  con el que estemos
trabajando.  La directiva  include permite  añadir a  nuestro código
algún fichero de texto, de tal  forma que la directiva es sustituida
por  el  texto  que  contiene  el  fichero  indicado. En general los
ficheros que  acompañan a esta  directiva son ficheros  .H (Header -
Cabecera),  en los  que se  incluyen definiciones  de funciones  que
deseamos  utilizar   en  nuestros  programas,   constantes  o  tipos
complejos de datos.

        La  librería stdio.h  (STandarD Input/Output)  con tiene las
funciones  estándar de  entrada salida,  y en  ella se  encuentra la
función printf  que utilizamos en nuestro  programa. Como se observa
en el  código el nombre  de la función  a incluir debe  ir entre los
caracteres <...>. A medida que  vayan surgiendo iremos indicando las
funciones estándar que deberían  incorporar todos los compiladores C
y cual es su fichero de definición .H.

        En  la  siguiente  línea  nos  encontramos  con main(). Esto
indica  que  aquí  comienza  nuestro  programa,  en realidad estamos
definiendo una función  (esto se indica con los  paréntesis al final
de  la línea)  pero esto  lo discutiremos  en temas  posteriores. La
función main (principal en inglés)  siempre debe existir y contendrá
el programa principal.

        Finalmente  nos  encontramos   el  programa  principal,  una
sentencia printf  entre llaves ({,  }). Las llaves  en C representan
bloques, y  encierran un conjunto de  sentencias o instrucciones (lo
que  el computador  ejecutará),  considerando  todas ellas  como una
sola, permitiendo una definición  homogénea de los distintos bloques
que constituyen el programa. En  nuestro caso tenemos un sólo bloque
que no es ni más ni menos  que el programa principal, que en nuestro
caso está compuesto por una sola sentencia (la línea que contiene el
printf).  Como se  observa en  el código  las sentencias  en C deben
terminar con un punto y coma (;), #include <stdio.h> y main() no son
sentencias, dan información sobre la  estructura del programa, y por
tanto no finalizan con un punto y coma.

      NOTA: La  razón de que la  línea "main()" no tenga  un punto y
coma ";"  al final es  debido a  que  la sentencia en  sí termina al
cerrar el  corchete, no en  que dicha línea  proporcione información
sobre  la  estructura  del  programa.   De  hecho,  si  el  "main()"
constituyese una línea de prototipo tendría un ";" al final.

        La  función printf  permite visualizar  datos formateados en
pantalla, es decir, permite indicar un formato como si de un impreso
o formulario  se tratase  indicando donde  se deben  visualizar cada
uno. En el siguiente tema cuando se introduzcan los tipos básicos de
datos se comprenderá mejor ésto. Por ahora sólo nos interesa conocer
que printf visualiza mensajes en pantalla.

        El mensaje debe ir entre comillas dobles (") y dentro de las
comillas  se puede  mostrar  cualquier  secuencia de  caracteres. El
formato de esta función para este segundo tema será:

        printf ("mensaje");

        En el  siguiente tema, cuando expliquemos  en profundidad la
instrucción, ampliaremos esta definición.

        En nuestro  programa observamos que el  mensaje de texto que
visualiza  la instrucción  printf  comienza  con los  caracteres \n.
Estos  caracteres  nos  permiten  algunas  funciones especiales para
controlar la forma  de visualizar los mensajes, la  más utilizada en
\n que significa nueva línea,  así nuestra sentencia printf ("\nHOLA
MUNDO");  moverá  el  cursor  (la  posición  de  la  pantalla  donde
actualmente se visualizan los datos)  a una nueva línea situándolo a
la izquierda de la pantalla y visualizará el mensaje HOLA MUNDO.

        Para  finalizar con  este punto  se indicará  las secuencias
antecedidas por \ que se pueden incluir en una instrucción printf:

      +-------------------------+------+
      | Nueva línea             | \n   |
      | Tabulador horizontal    | \t   |
      | Tabulador vertical      | \v   |
      | Backspace (<-)          | \b   |
      | Retorno de carro        | \r   |
      | Avance de página        | \f   |
      | Pitido (alerta)         | \a   |
      | Caracter \              | \\   |
      | Caracter ?              | \?   |
      | Caracter '              | \'   |
      | Caracter "              | \"   |
      | Número Octal (ooo)      | \ooo |
      | Número Hexadecimal (hh) | \xhh |
      +-------------------------+------+

        Algunos comentarios sobre estos  códigos. En primer lugar el
primer  grupo  (hasta  carácter  \),  eran  utilizados para mover el
cursor en terminales.  Los terminales podían ser una  pantalla o una
impresora, esta  es la razón por  la que nos encontramos  cosas como
avance de  página o retorno  de carro.  Los  caracteres \ ?  ' " son
especiales puesto  que se utilizan  dentro del mensaje  a visualizar
para indicar como se visualiza, o sea, si escribimos \ el compilador
buscará el siguiente  carácter y si es alguno  de los anteriores los
visualiza sino corresponde con ninguno simplemente lo ignora, con lo
cual no  podríamos visualizar el  carácter \. Otro  tanto sucede con
las comillas puesto que para  C, las comillas representan una cadena
de caracteres, si escribimos " en nuestro mensaje se considerará que
éste termina  ahí con lo que  lo que se encuentre  después no tendrá
sentido para el compilador.

        Por  último Número  octal y  Número hexadecimal  nos permite
introducir directamente  el código numérico  en octal o  hexadecimal
del  carácter  que  deseemos  visualizar,  dependiendo  del que esté
activo en  nuestro computador. En  general el código  utilizado para
representar internamente  los caracteres por los  computadores es el
código ASCII (American Standard Code for Information Interchange).

        En este  segundo tema hemos  aprendido a escribir  programas
que visualicen  en pantalla mensajes utilizando  la función estándar
de la librería stdio. Antes  de terminar unos breves comentarios. El
lenguaje  C diferencia  entre mayúsculas  y minúsculas  con lo  cual
main,   MAIN,  MaIn,   serían  identificadores   distintos  para  el
compilador, en general  en C se suele escribir  todo en minúsculas a
excepción  de  los  mensajes  a  visualizar  (cuyo  uso  depende del
programador) y de las constantes, esto  no tiene por que hacerse así
pero digamos que se trata de  una tradición de la programación en C.
Las  separaciones entre  líneas también  son arbitrarias  y su única
función  es  facilitar  la  legibilidad  del  código,  sirviendo  de
separadores entre  fragmentos de programa  relacionados entre sí.  Y
esto es todo por ahora.


1.2 Tipos de datos básicos del C

        La   mayoría  de   los  programas   realizan  algo   útil  y
generalmente para ello es  necesario trabajar con grandes cantidades
de  datos,  si  queremos  realizar  un  programa  que nos calcule un
sistema de ecuaciones tenemos que  indicar cuales son las ecuaciones
para  que el  programa las  resuelva. Por  tanto un  programa estará
constituido  por una  serie de  datos y  una serie  de sentencias  o
instrucciones que  le dicen lo que  tiene que hacer con  esos datos.
Los  lenguajes de  programación disponen  de una  serie de  tipos de
datos básicos, y proporcionan  herramientas para crear estructuras a
medida que faciliten el acceso a la información. Así en nuestro caso
ficticio de resolver un sistema  de ecuaciones podemos almacenar los
coeficientes de cada ecuación con  lo que utilizaríamos como tipo de
dato  los números,  si planteásemos  el problema  desde un  punto de
vista matricial nos  interesaría tener un tipo de  datos matriz y lo
ideal  sería  tener  un  tipo  de  datos  ecuación. En este apartado
describiremos  los tipos  básicos que  proporciona el  lenguaje C  y
dejaremos para temas posteriores la declaración de tipos complejos.

        Estos tipos básicos son los siguientes:

      +--------+---------------------------------------+
      | int    | Representa números enteros.           |
      | float  | Representa números decimales.         |
      | double | Representa números decimales de mayor |
      |        | precisión.                            |
      | char   | Representa caracteres.                |
      +--------+---------------------------------------+

        Aunque el tipo char  represente caracteres internamente para
el computador no es más que un  número comprendido entre 0 y 255 que
identifica  un caracter  dentro de  el código  especificado para tal
propósito  en el  sistema en  el que  nos encontremos trabajando. El
código más utilizado para este tipo de representación es el ASCII ya
mencionado anteriormente.

      NOTA: Según la máquina, el  compilador empleado y las opciones
de compilación  activas, "char" puede interpretarse  con signo o sin
signo. Esto es,  de -128 a 127 o  desde 0 a 255. Si  se requiere una
representación que no dependa de  las opciones del compilador, etc.,
se puede poner "signed char" o "unsigned char", según el caso.

        Como  decíamos antes  el ordenador  debe de  disponer de los
datos necesarios para  resolver el problema para el  que lo queramos
programar. Difícilmente se podría  resolver un sistema de ecuaciones
si no se dispone de éstas.  Para ello podemos definir variables. Las
variables  almacenan  valores  de  un  tipo  especificado y en ellas
almacenamos los  datos de nuestro  problema, se denominan  variables
por  que  su  valor  puede  cambiar  a  lo  largo del programa. Para
referenciar una  variable especificada es  necesario que la  podamos
identificar para ello se utiliza un nombre o identificador que no es
más  que  una  secuencia  de  caracteres,  esta  secuencia  no puede
contener caracteres  españoles (acentos y  eñes), ni caracteres  que
tengan  alguna  función  especial  en  el  C  como  por  ejemplo los
caracteres  que representan  operaciones matemáticas  +, -,  etc...,
tampoco  pueden contener  espacios por  lo que  se suele utilizar el
carácter subrayado (_) si el  identificador que deseamos asignarle a
nuestra variable  está formado por varias  palabras, pero en general
con  los caracteres  y números  tenemos suficiente  para dar nombres
autoexplicativos, aunque los números no pueden comenzar el nombre de
una variable.  Las variables se suelen  escribir con letra minúscula
aunque no  es necesario y es  aconsejable que los nombres  sean auto
explicativos  para que  resulte más  sencillo leer  el programa  (es
mejor llamar resultado a una variable que x).

        Las variables se declaran indicando  el tipo que van a tener
seguido de  su identificador y  terminando la línea  con un punto  y
coma. Algunos ejemplos:

        int   numero;   /* número no sería un nombre válido */
        float mi_variable;
        char  letra;

        Si necesitamos declarar varias variables de un mismo tipo se
pueden  incluir en  la misma  línea todos  los nombres  que deseemos
separándolos por una coma:

        int    numero1,numero2,numero3;
        float  coordenada_x,coordenada_y;

        El  compilador tiene  que conocer  las variables  que va  ha
utilizar cada bloque para reservarles  sitio, por ello las variables
se suelen  declarar al principio de  cada bloque. Puesto que  aún no
sabemos como  definir funciones nuestro programa  sólo dispone de un
bloque (el main()) con lo que nuestras variables deben de declararse
al comienzo del main() dentro del bloque, es decir, inmediatamente a
continuación de la llave abierta ({). Un ejemplo:

      NOTA: Aunque  el párrafo anterior  da a entender  que se puede
declarar  una  variable  en  cualquier  momento,  el estándar ANSI C
obliga a realizar las declaraciones  al principio de cada bloque. En
el  caso se  variables globales  la sintaxis  es más  flexible, para
poder utilizar el "Scope" en nuestro provecho.

        main()
        {
        int numero;

        numero =20;
        }

        Podemos también declarar variables  fuera del bloque main().
Estas  variables  se  conocen  como  variables  globales y cualquier
función puede acceder a ellas,  como sólo tenemos una función (main)
en este caso  nos daría igual declarar las  variables dentro o fuera
de main.

        De poco nos servirían estos datos numéricos si no pudiésemos
realizar operaciones  con ellos, el lenguaje  C permite realizar las
operaciones básicas con estas variables de tipo numérico, estas son:

      +---+---------------------------------------------+
      | + | para indicar suma                           |
      | - | para indicar resta                          |
      | * | para indicar producto                       |
      | / | para indicar división                       |
      | % | para indicar módulo (resto división entera) |
      +---+---------------------------------------------+

        Podemos  combinar  estas  operaciones  en  la  forma que nos
plazca  con variables  o  constantes  (podemos operar  variables con
números  fijos) y  utilizar los  paréntesis, caracteres  ( y  ) para
indicar  precedencia  de  las  operaciones  como  lo haríamos en una
expresión  matemática  normal.  En  principio  sólo podemos realizar
operaciones con variables que sean del mismo tipo, aunque en general
podemos  operar los  tipos float  y double  con tipos  int o incluso
char, en principio no podríamos  almacenar un valor float (un número
real)  en  una  variable  int  (entera),  para  ello  tendríamos que
convertir  ese  número  real  en  entero  de  alguna  forma. Podemos
convertir tipos básicos utilizando la  facilidad del C conocida como
cast. Esta  facilidad simplemente consiste  en indicar antes  de una
variable  o constante  el tipo  al que  lo deseamos  convertir entre
paréntesis y el compilador se encargará del resto. Un ejemplo :

      NOTA: El C también define la conversión automática de tipos.

        float   a;
        int     b;

        b=30;
        a=(float)b;

        Para ejemplificar todo esto vamos a realizar un programa que
nos calcule el espacio recorrido por un móvil con velocidad uniforme
durante un tiempo determinado. El programa sería algo así:

        #include <stdio.h>

        main()
        {
        float   e,v,t;

        v = 30; /* Velocidad del móvil en Km/h */
        t = 5;  /* Tiempo durante el cual se mueve */

        e = v*t;
        printf ("\nVelocidad : %f\nTiempo : %f",v,t);
        printf ("\nEspacio recorrido : %f",e);
        }

        Este programa  calcula el espacio recorrido  por un móvil en
movimiento  uniforme a  una velocidad  indicada por  la variable  v,
durante un tiempo indicado por la  variable t. Lo más interesante de
este  programa  es  que  hemos  utilizado  la  función  printf  para
visualizar valores de variables.

        Como   decíamos  más   arriba  la   función  printf  permite
visualizar  mensajes   formateados,  es  decir,  en   la  cadena  de
caracteres entre comillas dentro del  paréntesis nos indica la forma
en la que  se visualizarán los datos. Ya  hablamos de los caracteres
especiales como \n, ahora nos  ocuparemos de la visualización de las
variables.

        Cuando deseamos visualizar una variable debemos indicarlo en
la cadena  de formateo (la  secuencia de caracteres  entre comillas)
mediante el caracter % seguido de un caracter que nos indica el tipo
de dato a visualizar. Estos tipos son los siguiente:

      +-----+------------------------------------------------+
      | d,i | Entero en notación decimal con signo.          |
      |  o  | Entero notación octal sin signo.               |
      | x,X | Entero en notación hexadecimal sin signo.      |
      |  u  | Entero en notación decimal sin signo.          |
      |  c  | Entero como caracter simple.                   |
      |  s  | Cadena de caracteres.                          |
      |  f  | Tipo double (ó float) de la forma [-]mmmm.ddd. |
      | e,E | Tipo double (ó float) en notación científica o |
      |     | exponencial [-]m.dddde+-xx ó [-]m.ddddE+-xx.   |
      |  p  | Tipo puntero.                                  |
      +-----+------------------------------------------------+

        Podemos así mismo indicar el  número de cifras a visualizar,
intercalando entre el % y la letra que identifica el tipo de dato un
número. Si indicamos  dos números separados por un  punto, el primer
número  indica  el  número  total  de  caracteres  a visualizar y el
segundo el número de cifras  decimales que queremos que se muestren,
obviamente este formato  sólo se utilizará con tipo  float o double.
Algunos ejemplos:

        printf ("%f",numero);
        Visualiza un número real en  el formato normal, parte entera
y parte decimal separadas por un punto.

        printf ("%5.2f",numero);
        Visualiza  un  número  entero  en  el  mismo  formato que la
anterior,  pero sólo  visualizando 5  cifras y  siendo dos  de ellas
reservadas para la parte decimal.

        Hasta ahora  hemos visto como  decir a la  función printf el
formato en el que debe visualizar  los datos, pero no le hemos dicho
que datos debe visualizar. Lo que  se escribirá en el lugar indicado
por el %  está especificado a continuación de  la cadena de formateo
entre comillas, separando  cada una de ellas por  comas. El primer %
coincide con el primer parámetro después de las comillas, el segundo
con el segundo  y así sucesivamente. De esta  forma un programa como
este:

        #include <stdio.h>

        main()
        {
        int    i;
        float  a,b;

        i = 10;
        a = 30.456;
        b = 678.12;

        printf ("\nvar1:%d var2:%6.2f var3:%6.1f",i,a,b);
        }

        tendrá como salida:

        var1:10 var2:30.46 var3:678,1

        Como  se  puede  observar  en  el  ejemplo  si  la precisión
especificada  en la  cadena de  formateo es  menor que  la real  del
número, la función printf aproxima a la precisión especificada.


1.3 Entrada de datos por teclado

        El programa anterior para el  cálculo de el espacio funciona
correctamente, pero cada vez que  deseemos calcular un nuevo espacio
debemos  dar valores  a las  variables v  y t  y recompilar  nuestro
programa.  Sería estupendo  poder leer  por teclado  los datos de la
velocidad y  del tiempo y  así permitir a  nuestro programa trabajar
con cualquier valor  de velocidad y tiempo. Aquí  es donde realmente
se comprende de donde viene el nombre de variables.

        Para leer los datos por  teclado se utiliza la función scanf
cuya  definición  se  encuentra  también  en  el fichero stdio.h. El
formato es idéntico  al de printf utilizando una  cadena de formateo
con los caracteres  % y la letra que indica  el tipo, ahora del dato
que vamos a  leer, seguido de la variable en  la que deseamos que se
lea  antecedida por  el carácter  &. Nuestro  programa del  móvil se
convierte ahora en:

        #include <stdio.h>

        main()
        {
        float   v,t,e;

        printf ("\nDime la velocidad de el móvil:");
        scanf  ("%f",&v);
        printf ("\Dime el tiempo :");
        scanf  ("%f",&t);
        e = v*t;

        printf ("\nUn móvil desplazándose a %5.2f Km/h durante
%5.2f horas, recorre una distancia de %5.2f Km",v,t,e);
        }

        Ahora  cada vez  que el  programa se  ejecute nos pedirá que
introduzcamos  los  valores  de  la  velocidad  y  el  tiempo  y nos
proporcionará el  espacio que recorreríamos, evitando  de esta forma
la  necesidad  de  recompilar  el  programa  cada  vez  que deseemos
realizar un nuevo cálculo.