5.Introducción al lenguaje C.

5.1.Características.
5.2.Funciones.
5.3.Variables y constantes.
5.4.Identificadores.
5.5.Sentencias.
5.6.Indentación.
5.7.Bloques de sentencias.
5.8.Comentarios.
5.9.El preprocesador.
5.10.Las librerías.
5.11.El compilado.
5.12.El linkado.
5.13.Generación del código ejecutable.
5.14.Ejemplos.
5.15.Ejercicios.

Inroducción.

El lenguaje de programación C está caracterizado por ser de uso general, con una sintaxis sumamente compacta y de alta portabilidad.

Es común leer que se lo caracteriza como un lenguaje de “bajo nivel”. No debe confundirse el término “bajo” con “poco”, ya que el significado del mismo es en realidad “profundo”, en el sentido que C maneja los elementos básicos presentes en todas las computadoras: caracteres, números y direcciones.

Esta particularidad, junto con el hecho de no poseer operaciones de entrada-salida, manejo de caracteres, de asignación de memoria, etc. , puede al principio parecer un grave defecto; sin embargo el hecho de que estas operaciones se realicen por medio de llamadas a Funciones contenidas en Librerías externas al lenguaje en sí, es el que confiere al mismo su alto grado de portabilidad, independizándolo del “Hardware” sobre el cual corren los programas, como se irá viendo a lo largo de los siguientes capítulos.

La descripción del lenguaje se realiza siguiendo las normas del ANSI C (American National Standars Institute), por lo tanto, todo lo expresado será utilizable con cualquier compilador que se adopte; sin embargo en algunos casos particulares se utilizan funciones dependientes del Compilador o Sistema Operativo, expresándose en estos casos la singularidad de las mismas.

5.1.Características.

Este lenguaje ha tenido mucho éxito, lo que ha hecho que se haya extendido rápidamente y que sea fácil encontrar compiladores para distintas máquinas y entornos. Esto se debe a sus características ya que es compacto, estructurado, portable, flexible y de tipo medio.

5.1.1.Compacto.

Se dice que es compacto por su reducido número de palabras reservadas, sólo 32 de acuerdo con el estándar ANSI C:

auto double int
struct break else
long switch case
enum register typedef
char extern return
union const float
short unsigned continue
for signed void
default goto sizeof
volatile do if
static while

Además se utilizan símbolos para representar las operaciones algebraicas, lógicas y relacionales de las matemáticas convencionales y propias de la programación.

Se puede decir que cualquier programa se puede escribir utilizando exclusivamente las palabras reservadas y operadores, pero sería muy laborioso y requeriría un profundo conocimiento de la máquina con la que se está trabajando.

5.1.2.Estructurado.

Se basa en el empleo de funciones, bloques programados para realizar tareas simples y que, unidas entre sí, consiguen programas más complejos y de alto nivel.

Las funciones pueden verse como programas reducidos con datos privados e independientes del programa del que forman parte y que pueden utilizarse múltiples veces, realizando operaciones simples.

Además, en C, se pueden crear bloques de código formando una unidad lógica.

En lenguaje C se pueden emplear sentencias de decisión e iteración propias de lenguajes de alto nivel. Incluso posee la instrucción goto, aunque se desaconseja su utilización (está mal visto entre los programadores de C).

5.1.3.Portable.

El código fuente no depende del compilador ni de la máquina en que se ha escrito, por lo que el mismo código fuente puede ser compilado en distintas máquinas y distintos entornos, utilizando las librerías adecuadas.

5.1.4.Flexible.

El programador de C tiene pocas restricciones y de él dependen prácticamente todas las decisiones de control. Esto hace que el lenguaje C sea muy flexible. El inconveniente es que a veces no se producen mensajes de error cuando el programa no funciona correctamente.

5.1.5.Lenguaje de tipo medio.

El lenguaje C combina elementos y características de alto nivel (sentencias muy potentes) y características de lenguajes de bajo nivel como ensamblador (permite el control de la CPU a nivel de registros, e incluso de bits), con plena disponibilidad de memoria y puertos.

5.2.Funciones.

La función es la unidad primaria de programación, es decir, los programas se construyen a partir de funciones. Son bloques de código independientes que se comunican con la función principal recibiendo y devolviendo datos.

La forma genérica de una función en C es:


tipo_devuelto nombre_función (lista_de_parámetros)

{

cuerpo de la función:

declaraciones, sentencias,

otras funciones, etc.

}



Siendo:

  • tipo_devuelto el tipo de dato que la función devuelve al punto en que fue llamada,
  • nombre_función el nombre del bloque de código
  • lista_de_parámetros es una relación de los argumentos con los que se llama a la función para que realice las operaciones necesarias.

Dentro de la función se incluyen las declaraciones, sentencias y proposiciones necesarias para desarrollar las actividades para las que ha sido diseñada.

5.3.Variables y constantes.

No son más que posiciones de memoria que se identifican por un nombre. Las variables pueden cambiar de valor a lo largo de la ejecución de un programa, o bien en ejecuciones distintas de un mismo programa. Además de variables, un programa utiliza también constantes, es decir, valores que siempre son los mismos. Un ejemplo típico es el número PI, que vale 3.141592654. Este valor, con más o menos cifras significativas, puede aparecer muchas veces en las sentencias de un programa.

En C existen distintos tipos de variables y constantes:

  • Numéricas. Son valores numéricos, enteros o reales. Se permiten también octales (números enteros en base 8) y hexadecimales (base 16).
  • Caracteres. Cualquier carácter individual encerrado entre apóstrofos (tal como ‘a’, ‘Y’, ‘)’, ‘+’, etc.) es considerado por C como una constante carácter, o en realidad como un número entero pequeño (entre 0 y 255, o entre -128 y 127, según los sistemas). Existe un código, llamado código ASCII, que establece una equivalencia entre cada carácter y un valor numérico correspondiente.
  • Cadenas de caracteres. Un conjunto de caracteres alfanuméricos encerrados entre comillas es también un tipo del lenguaje C, como por ejemplo: “espacio”, “Esto es una cadena de caracteres”, etc. En realidad son tratados como arrays de caracteres, finalizados con un carácter nulo.
  • Constantes simbólicas. Las constantes simbólicas tienen un nombre (identificador) y en esto se parecen a las variables. Sin embargo, no pueden cambiar de valor a lo largo de la ejecución del programa.

5.4.Identificadores.

Los identificadores o etiquetas son los nombres con el que se hace referencia a una variable, constante o función. Cada lenguaje tiene sus propias reglas respecto a las posibilidades de elección de nombres para las funciones y variables. En ANSI C estas reglas son las siguientes:

  • Un identificador se forma con una secuencia de letras (minúsculas de la a a la z; mayúsculas de la A a la Z) y dígitos (del 0 al 9).
  • El carácter subrayado o underscore (_) se considera como una letra más.
  • Un identificador no puede contener espacios en blanco, ni otros caracteres distintos de los citados, como por ejemplo (*,;.:-+, etc.).
  • El primer carácter de un identificador debe ser siempre una letra o un (_), es decir, no puede ser un dígito.
  • Se hace distinción entre letras mayúsculas y minúsculas. Así, Masa es considerado como un identificador distinto de masa y de MASA.
  • No son válidas las palabras reservadas, pero estas están en minúsculas.
  • ANSI C permite definir identificadores de hasta 31 caracteres de longitud.

Ejemplos de identificadores válidos son los siguientes:


tiempo, distancia1, caso_A, PI, velocidad_de_la_luz.


Por el contrario, los siguientes nombres no son válidos:


1_valor, tiempo-total, dolares$, %final.


Además de lo anterior hay una serie de recomendaciones que simplifican enormemente la tarea de programación y, sobre todo, de corrección y mantenimiento de los programas:

  • En general es muy aconsejable elegir los nombres de las funciones y las variables de forma que permitan conocer a simple vista qué tipo de variable o función representan, utilizando para ello tantos caracteres como sean necesarios. Es cierto que los nombres largos son más laboriosos de teclear, pero en general resulta rentable tomarse esa pequeña molestia.
  • Las funciones creadas por el programador pueden comenzar por una letra mayúscula, para distinguirlas de las definidas en el compilador.
  • Los identificadores de constantes suelen escribirse en mayúsculas.

5.5.Sentencias.

Una sentencia es un conjunto de identificadores símbolos y palabras reservadas que se escriben en una línea. En C las sentencias terminan con un punto y coma ‘;’.

Pueden ir en cualquier posición de la línea, seguidas o en líneas diferentes, es decir, no se tienen en cuenta los espacios vacíos ni los finales de línea.

5.6.Indentación.

Es el sangrado de las líneas del programa, su misión es, exclusivamente, facilitar la lectura y escritura de los programas, ya que es ignorada por el compilador.

A la hora de establecer la indentación, el programador se atiene a criterios personales, pero estos deben ser fijos y estables para que den una idea clara de la subordinación entre sentencias.

5.7.Bloques de sentencias.

Son conjuntos de sentencias agrupadas entre llaves “{ }” que forman una unidad lógica inseparable y que, a todos los efectos, son como una única sentencia.

5.8.Comentarios.

El lenguaje C permite que el programador introduzca comentarios en los ficheros fuente. La misión de los comentarios es servir de explicación o aclaración sobre cómo está hecho el programa, de forma que pueda ser entendido por una persona diferente (o por el propio programador algún tiempo después).

Tienen las siguientes características:

  • Los caracteres (/*) se emplean para iniciar un comentario; el comentario termina con los caracteres (*/).
  • No se puede introducir un comentario dentro de otro.
  • Todo texto introducido entre los símbolos de comienzo y final de comentario son ignorados por el compilador.

Por ejemplo:


var_1 = var_2; /* En esta línea se

asigna a var_1 el

valor contenido en

var_2 */



Una fuente frecuente de errores al programar en C, es el olvidarse de cerrar un comentario que se ha abierto previamente. Sería un error como el siguiente:


var_1=var_2 /*Asigno valor

a var_1

variable_3=55 /*Asigno valor a

variable_3*/



El lenguaje ANSI C permite también otro tipo de comentarios, tomado del C++. Todo lo que va en cualquier línea del código detrás de la doble barra (//) y hasta el final de la línea, se considera como un comentario y es ignorado por el compilador. Para comentarios cortos, esta forma es más cómoda que la anterior, pues no hay que preocuparse de cerrar el comentario (el fin de línea actúa como cierre). Como contrapartida, si un comentario ocupa varias líneas hay que repetir la doble barra (//) en cada una de las líneas.

Con este segundo procedimiento de introducir comentarios, el último ejemplo podría ponerse en la forma:


var_1 = var_2; // En esta línea se

// asigna a var_1 el

//valor contenido en

//variable_2



5.9.El preprocesador.

El preprocesador es un componente característico de C, que no existe en otros lenguajes de programación. El preprocesador actúa sobre el programa fuente, antes de que empiece la compilación propiamente dicha, para realizar ciertas operaciones. Una de estas operaciones es, por ejemplo, la sustitución de constantes simbólicas. Así, es posible que un programa haga uso repetidas veces del valor 3.141592654, correspondiente al número PI. Es posible definir una constante simbólica llamada PI que se define como 3.141592654 al comienzo del programa y se introduce luego en el código cada vez que hace falta. En realidad PI no es una variable con un determinado valor: el preprocesador chequea todo el programa antes de comenzar la compilación y sustituye el texto PI por el texto 3.141592654 cada vez que lo encuentra. Las constantes simbólicas suelen escribirse completamente con mayúsculas, para distinguirlas de las variables.

El preprocesador realiza muchas otras funciones que se irán viendo a medida que se vaya explicando el lenguaje. Lo importante es recordar que actúa siempre por delante del compilador (de ahí su nombre), facilitando su tarea y la del programador.

5.10.Las librerías.

Con objeto de mantener el lenguaje lo más sencillo posible, muchas sentencias que existen en otros lenguajes, no tienen su correspondiente contrapartida en C. Por ejemplo, en C no hay sentencias para entrada y salida de datos. Es evidente, sin embargo, que ésta es una funcionalidad que hay que cubrir de alguna manera. El lenguaje C lo hace por medio de funciones preprogramadas.

Estas funciones están agrupadas en un conjunto de librerías de código objeto, que constituyen la llamada librería estándar del lenguaje. La llamada a dichas funciones se hace como a otras funciones cualesquiera, y deben ser declaradas antes de ser llamadas por el programa (más adelante se verá cómo se hace esto por medio de la directiva del preprocesador #include).

El estándar ANSI C especifica un conjunto mínimo de funciones que debe proporcionar todo compilador, con un nombre y características idénticas. Los compiladores suelen incluir muchas más pero que no son estándar.

5.11.El compilado.

El compilador es el elemento más característico del lenguaje C. Como ya se ha dicho anteriormente, su misión consiste en traducir a lenguaje de máquina (código objeto) el programa C contenido en uno o más ficheros fuente. El compilador es capaz de detectar ciertos errores durante el proceso de compilación, enviando al usuario el correspondiente mensaje de error.

5.12.El linkado.

Es la segunda etapa se realiza para la obtención del programa. Es el proceso de montaje (linkado) del programa, consistente en producir un programa ejecutable en lenguaje de máquina, en el que están ya incorporados todos los otros módulos que aporta el sistema sin intervención explícita del programador: funciones de librería (archivos *.LIB), recursos del sistema operativo, etc.).

En un PC con sistema operativo Windows (DOS) el programa ejecutable se guarda en un fichero con extensión (*.exe). En otros sistemas operativos existe un atributo del fichero que lo hace ejecutable. Este fichero es cargado por el sistema operativo en la memoria RAM cuando el programa va a ser ejecutado.

El código máquina de los ficheros objeto y de las librerías están en formato reubicable, es decir, no tienen asignadas direcciones de memoria reales, es el proceso de linkado el que las asigna, para que el programa ejecutable se sitúe correctamente en la memoria del ordenador.

5.13.Generación del código ejecutable.

Pasos a seguir para obtener el fichero ejecutable de un programa en C:

Creación del fichero fuente con un editor de texto.

Compilación del programa para obtener los ficheros objeto (*.obj u .o).

Enlazado o linkado de los ficheros objeto y las funciones de biblioteca para obtener el fichero ejecutable.

En la mayoría de los compiladores, la compilación y el linkado, se realizan en una sola operación, puesto que utilizan entornos de programación que integran todos los recursos y utilidades necesarias para: editar, compilar, linkar y depurar el programa.

Cuando se trata de un proyecto grande, el programa se divide en varios archivos, que pueden compilarse por separado y enlazarse todos ellos juntos para obtener el ejecutable final.

5.14.Ejemplos.

A continuación se muestra uno de los programas más sencillos:


/* Primer programa*/

/*Fichero hola.c*/

#include <stdio.h>

main() /*Función principal*/

{

printf("Hola Caracola.\n");

}


La primera línea es una directiva al preprocesador que añade el fichero stdio.h al fichero fuente. En este fichero se encuentran las declaraciones y definiciones de las funciones estándar de entrada/salida, entre ellas printf().

La función principal (main()), debe existir siempre en todos nuestros programas. En este caso incluye una única sentencia, finalizada por ‘;’. Esta sentencia es una llamada a la función printf(), a la que pasa como argumento una cadena de texto para que sea mostrada en pantalla.

La secuencia que comienza por la barra invertida sirve para representar caracteres no imprimibles, en este caso ‘\n’ es igual a retorno de carro y avance de línea (RETURN).

Se ha incluido un comentario entre los símbolos ‘/*’ y ‘*/’.

Programa que permite convertir grados Fahrenheit en grados Celsius:


/* Conversión de Fahrenheit a Celsius*/

/* Fichero fahren1.c */

#include <stdio.h>

void main(void)

{

int fahren, celsius; /*Variables enteras*/


printf("Conversión de ºF a ºC:\n"); /*Mensaje de presentación*/

fahren=100;

celsius=5*(fahren-32)/9; /*Fórmula de conversión*/


printf("%d ºF = %d ºC\n",fahren, celsius); /*Mostrar el resultado*/

}



Se puede observar la declaración de dos variables de tipo entero antes de su utilización.

En este caso se utiliza la función printf(), no solo para mostrar mensajes de texto en pantalla, sino también para mostrar los valores de las variables fharen y celsius. Se utiliza para ello el símbolo ‘%’ seguido de un carácter que indica el tipo de dato que se desea representar, en este caso ‘d’ (entero).

Ampliaremos el programa para poder introducir la temperatura por teclado:


/* Conversión de Fahrenheit a Celsius*/

/* Fichero fahren2.c */


#include <stdio.h>


void main(void)

{

int fahren, celsius; /*Variables enteras*/


printf("Conversión de ºF a ºC:\n");

printf("Introduce la temperatura fahrenheit:");

scanf("%d",&fahren); /*Introducción de datos

por teclado*/

celsius=5*(fahren-32)/9; /*Fórmula de conversión*/


printf("%d ºF = %d ºC\n",fahren, celsius); /*Resultado*/

}



La lectura se realiza por medio de la función scanf(), que se encarga de leer del teclado un número entero (“%d”) y almacenarlo en la variable fahren. Es necesario el símbolo ‘&’ delante de la variable para que la función realice correctamente la lectura. Esto se aclarará en más adelante, cuando se estudie la función scanf().

La conversión no se realiza con precisión debido a que estamos utilizando variables enteras, el programa mejoraría si utilizásemos números reales.


/* Conversión de Fahrenheit a Celsius*/

/* Fichero fahren3.c */

#include <stdio.h>

void main(void)

{

float fahren, celsius; /*Variables reales*/

printf("Conversión de ºF a ºC:\n");

printf("Introduce la temperatura fahrenheit:");

scanf("%f",&fahren); /*Introducción de datos

por teclado*/

celsius=5*(fahren-32)/9; /*Fórmula de conversión*/

printf("%f ºF = %f ºC\n",fahren, celsius); /*Resultado*/

}



Hemos tenido que cambiar la declaración de las variables, así como los especificadores de formato utilizados por printf() y scanf() ( %f para números reales.

5.15.Ejercicios.

a)Escribir los programas mostrados como ejemplo añadiendo los comentarios convenientes para entender su funcionamiento. Obtener los ejecutables y comprobar su funcionamiento utilizando un entorno de programación. Observa el proceso de compilación y linkado.

b)Dentro del entorno de programación elegido, hacer diferentes pruebas y modificaciones en los ficheros anteriores, para aclarar las dudas que puedan surgir en la utilización del entorno. Probar las opciones de ejecución paso a paso, depuración, puntos de ruptura, visualización de variables, etc.

c)Realizar un programa que convierta de pesetas a euros.

d)Construir un programa que calcule la longitud de una circunferencia a partir de su radio.

e)Realizar un programa que tome dos números desde el teclado y muestre su suma, diferencia, producto y cociente.


Última modificación: martes, 13 de abril de 2010, 20:16