Вы находитесь на странице: 1из 52

UNIDAD 1: REGISTROS: 1.1 CONCEPTOS GENERALES.

LENGUAJE DE PROGRAMACIN:

Es un conjunto de smbolos junto a un conjunto de reglas para combinar dichos smbolos que se usan para expresar programas. Constan de un lxico, una sintaxis y una semntica. Qu conoces tu por lxico, sintaxis y semntica? Lxico: Conjunto de smbolos permitidos o vocabulario Sintaxis: Reglas que indican cmo realizar las construcciones del lenguaje Semntica: Reglas que permiten determinar el significado de cualquier construccin del lenguaje. Tipos de lenguajes: Atendiendo al nmero de instrucciones necesarias para realizar una tarea especfica podemos clasificar los lenguajes informticos en dos grandes bloques: bajo nivel alto nivel Lenguaje de bajo nivel Es el tipo de lenguaje que cualquier computadora es capaz de entender. Se dice que los programas escritos en forma de ceros y unos estn en lenguaje de mquina, porque esa es la versin del programa que la computadora realmente lee y sigue. Lenguajes de alto nivel Son lenguajes de programacin que se asemejan a las lenguas humanas usando palabras y frases fciles de entender. En un lenguaje de bajo nivel cada instruccin corresponde a una accin ejecutable por el ordenador, mientras que en los lenguajes de alto nivel una instruccin suele corresponder a varias acciones.

1.2 CONCEPTO DE CAMPO:

Hay varios campos de estudio que o bien caen dentro de la teora de lenguajes de programacin, o bien tienen una profunda influencia en ella; muchos de estos se superponen considerablemente. Teora de los compiladores es la base formal sobre la escritura de compiladores (o ms generalmente traductores); programas que traducen un programa escrito en un lenguaje a otra forma. Las acciones de un compilador se dividen tradicionalmente en anlisis sintctico (escanear y parsear), anlisis semntico (determinando que es lo que debera de hacer un programa), optimizacin (mejorando el rendimiento indicado por cierta medida, tpicamente la velocidad de ejecucin) y generacin de cdigo (generando la salida de un programa equivalente en el lenguaje deseado; a menudo el set de instrucciones de una CPU). La Teora de tipos es el estudio de sistemas de tipos, que son "mtodos sintcticos tratables para proveer la ausencia de ciertos comportamientos de programa mediante la clasificacin de frases segn los tipos de valores que

computan." (Types and Programming Languages, MIT Press, 2002). Muchos lenguajes de programacin se distinguen por las caractersticas de sus sistemas de tipos. La Semntica formal es la especificacin formar del comportamiento de programas de ordenador y lenguajes de programacin. La Transformacin de programas es el proceso de transformar un programa de una forma (lenguaje) a otra forma; el anlisis de programas es problema general de examinar un programa mediante la determinacin de sus caractersticas clave (como la ausencia de clases de errores de programa). Sistemas en tiempo de ejecucin se refiere al desarrollo de entornos runtime para lenguajes de programacin y sus componentes, incluyendo mquinas virtuales, recoleccin de basura, e interfaces para funciones externas. Anlisis comparativo de lenguajes de programacin busca clasificar los lenguajes de programacin en diferentes tipos basados en sus caractersticas; amplias categoras de diferentes lenguajes de programacin se conocen frecuentemente como paradigmas de computacin. Metaprogramacin es la generacin de programas de mayor orden que, cuando se ejecutan, producen programas (posiblemente en un lenguaje diferente, o en un subconjunto del lenguaje original) como resultado. Lenguajes dedicados son lenguajes construidos para resolver problemas en un dominio de problemas en particular de manera eficiente.

Adems, PLT hace uso de muchas otras ramas de las matemticas, ingeniera del software, lingstica, e incluso ciencias cognitivas

1.3 CONCEPTO DE ESTRUCTURAS:

Qu es una estructura? Una estructura es un tipo de dato definido por el usuario, al utilizar una estructura Usted tiene la habilidad para definir un nuevo tipo de dato considerablemente ms complejo que los tipos que hemos utilizado hasta ahora. Una estructura es una combinacin de varios tipos de datos previamente definidos, incluyendo otras estructuras que hayamos definido previamente. Una definicin simple es, "una estructura es un grupo de datos relacionados en una forma conveniente al programador y/o al usuario del programa". Como es costumbre, un ejemplo nos clarifica los conceptos:

#include <stdio.h> struct { char inicial; /* Letra inicial del apellido */ int edad; /* Edad */ int calificacion; /* Aprovechamiento */ } chico, chica; int main() { chico.inicial = 'R'; chico.edad = 15; chico.calificacion = 75; chica.edad = chico.edad - 1; /* Ella es un ao menor que l */ chica.calificacion = 82;

chica.inicial = 'H'; printf("%c tiene %d anos y su calificacion es de %d\n", chica.inicial, chica.edad, chica.calificacion); printf("%c tiene %d anos y su calificacion es de %d\n", chico.inicial, chico.edad, chico.calificacion); } return 0;

El programa empieza definiendo una estructura utilizando la palabra clave struct seguida de tres variables sencillas encerradas entre llaves, las cuales son los componentes de la estructura, despues de la llave de cierre tenemos enlistadas dos variables llamadas chico y chica. De acuerdo a la definicin de una estructura, chico es una variable compuesta de tres elementos, inicial, edad y, calificacion. Cada uno de los tres campos estn asociados a chico y cada uno almacena una variable de su respectivo tipo, lo mismo se puede decir para chica pero sus variables son diferentes por lo tanto tenemos 6 variables agrupadas en dos, de tipo struct. 1.4 MANIPULACIN DE ESTRUCTURAS (CON EJEMPLO): El siguiente programa es bsicamente el mismo que el anterior, pero esta vez definimos un array de 12 variables llamadas chicos, est claro que ste programa contiene 12 veces 3=36 variables sencillas cada una de las cuales puede almacenar un tem de dato siempre y cuando sea del tipo adecuado, se define adems una variable comn llamada indice para utilizarla en los bucles, estudie el cdigo:

#include <stdio.h> struct { char inicial; int edad; int calificacion; } chicos[12]; int main() { int indice; for (indice = 0; indice < 12; indice++) { chicos[indice].inicial = 'A' + indice; chicos[indice].edad = 16; chicos[indice].calificacion = 84; } chicos[3].edad = chicos[5].edad = 17; chicos[2].calificacion = chicos[6].calificacion = 92; chicos[4].calificacion = 57; /* Asignacion de estructura solo en compiladores ANSI-C */

chicos[10] = chicos[4]; for (indice = 0; indice < 12; indice++) printf("%c tiene %d anos y una calificacion de %d\n", chicos[indice].inicial, chicos[indice].edad, chicos[indice].calificacion); return 0; }

1.5 MANIPULACIN DE ESTRUCTURAS (CON EJEMPLO): Para asignar un valor a cada uno de los campos utilizamos un bucle for, en cada ciclo del bucle se asignan todos los valores para uno de los chicos, en una situacin real sta podra no ser la mejor manera de asignar datos, pero un bucle puede leer los datos de un archivo y almacenarlos en la correcta ubicacin en un programa real, considere ste ejemplo como un inicio burdo a una base da datos, pues eso es justamente nuestro ejemplo. El cdigo resulta fcil de entender, solo har un comentario respecto a la lnea 26 en donde podemos ver una asgnacin de estructura, en ste enunciado los tres campos de chicos[4] son copiados en los respectivos campos de chicos{10], esto no siempre est permitido en el lenguaje C, solo en los compiladores que cumplen con la norma ANSI-C, si su compilador no es ANSI-C encierre en comentarios la lnea 26. El resultado de la ejecucin delprograma es el siguiente:

UNIODAD II: ARCHIVO:

2.1 CONCEPTOS GENERALES CAMPO, ESTRUCTURA, ARCHIVO:

Qu es un campo? Para finalizar la presente leccin estudiaremos el concepto de campo de bits, en el siguiente cdigo podemos ver la manera de definirlo y utilizarlo, en el programa tenemos una unin de una variable sencilla de tipo int en la lnea 5 y la estructura definida en las lneas 6 a la 12:

#include <stdio.h> union { int indice; struct { unsigned int x : 1; unsigned int y : 2; unsigned int z : 2; } bits; } numero; int main() { for (numero.indice = 0; numero.indice < 20; numero.indice++) { printf("indice = %3d, bits = %3d%3d %3d\n", numero.indice, numero.bits.z, numero.bits.y, numero.bits.x); } } return 0;

La estructura est compuesta de tres campos de bits llamados x, y, y z. La variable llamada x es de un solo bit, la variable y es de dos bits y es adyacente a la variable x, y la variable z es de dos bits y adyacente a la variable y. Como la unin causa que los bits sean almacenados en la misma ubicacin en memoria que la variable indice, la variable x es el bit menos significante de la variable indice, y conforma los siguientes dos bits, y z es almacenado en los siguientes dos bits de indice. Compile y ejecute el programa y ver que al ser incrementada la variable indice en cada ciclo del bucle, ver los campos de bits incrementarse en sus respectivas ubicaciones. Una cosa debemos sealar, los campos de bits deben definirse como partes de un tipo unsigned int de lo contrario el compilador marcar error. El resultado de la ejecucin del programa es:

2.2 ARCHIVOS DE TEXTO: INTRODUCCIN, DECLARACIN, APERTURA Y MANIPULACIN (CON EJEMPLO): ARCHIVOS DE TEXTO. Tambin conocidos como (Slream File) son utilizados para almacenar documentos que consisten en texto; En ellos, cada registro es un solo smbolo o cdigo de control. El leer estos archivos recibimos la informacin en orden secuencial en el que aparece cuando lo vemos en un monitor. Los archivos de texto son una secuencia de lneas separadas por marcas de fin de lnea. Rudimentos de los archivos de textos; El usuario escribe los archivos de textos mediante un procesador de palabras que le permitir almacenar la informacin pero no estrictamente en forma secuencial. El procesador tambin nos permite desplazarnos por todo el bloque de informacin y permitirnos realizar modificaciones. Mientras el usuario avance rpidamente en la lectura de registro lograra ver mas archivos. Lectura de un archivo de texto Crea el siguiente archivo de texto uitlizando un editor de texto cualquiera: 1.2 2512 2.4 1324 3.2 547 Escribe un programa en C que lea este archivo y calcule la suma de los productos de los nmeros de la primera columna por los de la segunda.

1.2 * 2512 + 2.4 *1324 + 3.2 * 547 El programa debe valer para cualquier archivo con este formato y escribir el resultado en el monitor. Utiliza el depurador para comprobar el orden en que se van leyendo los datos del archivo. El orden es (elige una respuesta): 1. 2. 3. 4. De arriba hacia abajo y De arriba hacia abajo y De abajo hacia arriba y De abajo hacia arriba y de izquierda a derecha (1.2 -> 2512 -> 2.4 -> 1324 ...) de derecha a izquierda (2512 -> 1.2 -> 1324 -> 2.4 ...) de derecha a izquierda de izquierda a derecha

A continuacin puedes estudiar tres soluciones ligeramente diferentes, dependiendo de cmo se utiliza la funcin fscanf. Puedes comprobar que el nmero de formatos en el segundo argumento debe coincidir con el de variables. Solucin 1

#include <stdio.h> void main () { FILE * f; int a2, a4, a6; double a1, a3, a5, suma; f = fopen ("numeros.txt", "r"); // Un formato y una variable fscanf (f, fscanf (f, fscanf (f, fscanf (f, fscanf (f, fscanf (f, "%lf", &a1); "%d", &a2); "%lf", &a3); "%d", &a4); "%lf", &a5); "%d", &a6);

fclose (f); suma = a1*a2 + a3*a4 + a5*a6; printf ("Suma = %.0lf\n", suma); }

Nombre ReadAllText(String) ReadAllText(String, Encoding)

Descripcin Abre un archivo de texto, lee todas sus lneas y, a continuacin, cierra el archivo. Abre un archivo, lee todas sus lneas con la codificacin especificada y, a continuacin, cierra el archivo

2.3 ARCHIVO DE ESTRUCTURAS: INTRODUCCIN, DECLARACIN, APERTURA Y MANIPULACIN (CON EJEMPLO):

ESTRUCTURA: Un archivo es el mdulo bsico de informacin manejado por el Sistema Operativo. El Sistema Operativo es un conjunto de programas cuya funcin es administrar los recursos del Sistema de Cmputo. Por ejemplo, un programa fuente es almacenado como un archivo. Primero es introducido en la memoria RAM por medio de un programa editor, y despus es almacenado como un archivo de texto en un medio de almacenamiento permanente (cinta, disco flexible, disco duro). Una vez que el programa fuente ha sido compilado, el programa resultante de la compilacin viene a ser un archivo binario. En Pascal, un archivo es una secuencia de elementos que pertenecen al mismo tipo o estructura, esto es que un archivo puede ser una secuencia de caracteres, nmeros o registros, por lo que su representacin lgica puede hacerse como una secuencia de mdulos del mismo tamao, tal como se presenta en la siguiente figura.

En el vocabulario de manejo de archivos, a cada elemento de un archivo se le llama registro. En Pascal, la numeracin de los registros empieza con el nmero CERO , por lo que al elemento_1 se le llamar registro 0, al elemento_2 registro 1, y as sucesivamente hasta llegar a la marca de fin de archivo EOF. Turbo Pascal difiere significativamente de Pascal estndar por la forma en que maneja los archivos. En Pascal estndar, los archivos son formalmente definidos independientemente del medio en que residan. Este mtodo de definicin fue inspirado por los archivos de tarjetas perforadas y cintas magnticas, las cuales eran los medios de almacenamiento comnmente usados cuando Pascal fue definido por primera vez. Como resultado, todo acceso a cualquier archivo en Pascal estndar es secuencial( registro por registro ) tal como se realiza en las tarjetas perforadas y cintas magnticas. En Turbo Pascal los archivos son definidos como archivos de disco. Los discos son actualmente los dispositivos de almacenamiento ms utilizados en las microcomputadoras. Los mecanismos de acceso secuencial proporcionados por Pascal estndar son algunas veces inconvenientes e insuficientes para los archivos basados en discos de acceso aleatorio, por lo que Turbo Pascal provee nuevas estructuras y mecanismos de acceso a los archivos. La primera gran diferencia entre Turbo Pascal y Pascal estndar, es la forma en que enlazan los archivos a un programa. En Pascal estndar, se abren los archivos referenciando su nombre de archivo en el encabezado del programa, y se cierran cuando el programa termina. En Turbo Pascal, los archivos de disco deben enlazarse a una variable de archivo particular con el procedimiento: Assign(variable_archivo,nombre_archivo);

y deben ser preparados para procesarse ( abiertos ) con: reset(variable_archivo) o rewrite(variable_archivo) antes de ser utilizados. Adems, los archivos deben ser explcitamente cerrados por medio de close(variable_archivo), despus de que han sido utilizados, o se perdern los datos que estn en la memoria auxiliar (variable_archivo) . variable_archivo es el nombre de la memoria auxiliar (buffer), por medio de la cual el programa manejar los datos hacia o desde el archivo en disco. nombre_archivo es el nombre que identifica al archivo en el disco. reset abre un archivo existente para procesamiento y coloca el apuntador de registro en el primer registro (0). rewrite crea un nuevo archivo (o sobre-escribe en uno existente) y lo abre para procesamiento con el apuntador de registro colocado en el registro 0. En el caso de un archivo de tipo text, reset har que el archivo slo pueda ser usado para operaciones de lectura , mientras que rewrite slo permitir operaciones de escritura. Los nombres de archivo vlidos son cadenas de 1 a 8 caracteres seguidos por una extensin opcional consistente de un punto y hasta tres caracteres. A estos nombres tambin se les llama "nombres de archivo externo", puesto que son los nombres con que se graban en el disco.

Cita: typedef enum TSTADO{SOLTERO,CASADO,VIUDO}Tstado; typedef struct TCLIENTE{ int edad ; char nombre[51]; float saldo; Tstado estado; }TCliente;

Escritura: Cita: int escribir_bin(int fin,TCliente *clte){ FILE *archivo; int nex=0; archivo=fopen("DatosBanco.dat","wb");

if (archivo!=NULL) { nex+=fwrite(clte,sizeof(TCliente),fin+1,archivo); fclose(archivo); return nex; } return -1; }

Lectura: Cita: int leer_bin(int fin, TCliente *vector){ FILE *archivo; int nex=0; archivo=fopen("DatosBanco.dat","rb"); if (archivo!=NULL) { fseek(archivo,0,SEEK_SET); nex+=fread(vector,sizeof(TCliente),fin+1,archivo); fclose(archivo); return nex; } else return -1; }

#include <stdio.h> //ahora debemos de incluir nuestra 02 estructura // 0 //para este ejemplo usaremos una estructura 3 llamada albail 0 4 0 //la cual contiene los siguientes datos 5 0 //nombre, folio, RFC, direccion, mail, horas trabajasdas, activida 6 realizada y su tipo de pago 0 7 0 struct 8 albanil { 0 char

9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 2 0 2 1 2 2 2 3 2 4 2 5 2 6 2 7 2 8 2 9 3 0 3 1 3 2 3 3 3 4 3 5 3 6 3

nombre[50]; char folio[10]; char RFC[11]; char calle[20]; char CP[6]; char colonia[20]; char mail[50]; char horas[2]; char actividad[50]; char pago[4]; };struct albanil albanil;

//ahora dentro de nuestro main

int main() { FILE *ptr; //inicializaremo una variable a archivo como apuntador char archivo[50];//y tendremos una cadena archivo para guardar el archiv con el nombre que sedessee printf("Como quieres que se llame tu archivo "); scanf("%s",&archivo); printf("Dime tu numero de folio "); scanf("%s",albanil.folio ); printf("Dime tu nombre "); scanf("%s",albanil.n ombre); printf("Dime tu RFC "); scanf("%s",albani l.RFC); printf("Dime tu direccion "); scanf("%s",albanil. calle); printf("Dime tu codigo

7 3 8 3 9 4 0 4 1 4 2 4 3 4 4 4 5 4 6 4 7 4 8 4 9 5 0 5 1 5 2 5 3 5 4 5 5 5 6 5 7 5 8 5 9 6 0 6 1

postal "); scanf("%s",albanil.CP ); printf("Dime tu colonia "); scanf("%s",albanil.c olonia); printf("Dime tu correo electronico "); scanf("%s",albanil.mail); printf("Dime cuantas horas trabajaste "); scanf("%s",albanil.horas); printf("Dime en que trabajaste "); scanf("%s",albanil.acti vidad); printf("Dime cuanto te van a pagar "); scanf("%s",albanil.pago); ptr=fopen(archivo,"a"); fprintf(ptr,"folio %s\n",albanil.folio); fprintf(ptr,"nombre %s\n",albanil.nombre); fprintf(ptr,"RFC %s\n",albanil.RFC); fprintf(ptr,"calle %s\n",albanil.calle); fprintf(ptr,"cp %s\n",albanil.CP); fprintf(ptr,"colona %s\n",albanil.colonia); fprintf(ptr,"correo %s\n",albanil.mail); fprintf(ptr,"horas %s\n",albanil.horas); fprintf(ptr,"actividad %s\n",albanil.actividad); fprintf(ptr,"pago %s\n",albanil.pago); fclose(ptr); retur n 0;

2.4 ARCHIVOS SIN TIPO:

Todos los archivos utilizados hasta ahora suponen algn tipo de estructura. Si no se conoce la estructura del registro se debe utilizar un archivo sin tipo. Los archivos sin tipo son canales de E/S de bajo nivel, principalmente utilizados

para acceso directo a cualquier archivo de disco con independencia del tipo y estructura. Cualquier archivo de disco puede ser declarado como sin tipo. Turbo Pascal permite tratar un archivo como una serie de bloques sin necesidad de conocer el tipo de datos que contiene. La declaracin de un archivo sin tipo omite el tipo de archivo : Var nombre: file; Usando la declaracin de archivos sin tipo, no importa como se haya escrito originalmente el archivo. Los archivos de texto, archivos binarios, archivos de programas o cualquier otro, pueden ser declarados y abiertos como archivos sin tipo. Los archivos sin tipo tienen una longitud de registro por defecto de 128 bytes, y se transfieren directamente entre la variable registro y el archivo. El formato de los procedimientos Reset y Rewrite en archivos sin tipo difiere del ya conocido para archivos de texto y con tipo. Reset (nombre,bloque) Rewrite(nombre, bloque) nombre variable de tipo archivo Bloque un nmero de tipo word

Ejemplo: Reset(archivo,1); Prepara a un archivo para ser ledo y especfica que la longitud de registro es de 1 byte. Acceso a los archivos (sin tipo) El acceso al los archivos se realiza con los siguientes procedimientos: BlockRe BlockWr ad ite Formatos: BlockRead

Transfiere un bloque de datos de un archivo sin tipo hacia un buffer. Formato: BlockRead(arch,buffer,bloq ues,resul) arch archivo sin tipo buffer variable de cualquier tipo de longitud suficiente para acoger los datos transferidos bloques expresin que corresponde al nmero de bloques de 128 bytes a transferir. resul parmetro opcional que indica el nmero de bloques que se leyeron o escribieron realmente.

BlockWrite Transfiere un buffer de datos hacia un archivo sin tipo. Los archivos sin tipo son ms rpidos, debido a que los datos no necesitan ser organizados en lneas o estructuras; son simplemente bloques que se transfieren entre el disco y un buffer. El siguiente ejemplo muestra una de las aplicaciones que se les puede dar a los archivos sin tipo. La funcin del siguiente ejemplo es el de copiar el contenido de un archivo a una ruta especfica (idntico al comando Copy de MS-DOS).

Ejemplo: Program Copiar; Var fuente,destino : file; {archivo sin tipo} buffer : array[1..512] of byte; temp : string; leidos : integer; begin if ((ParamCount<2)or (ParamCount>2)) then begin if (ParamCount<2)then WriteLn('Faltan prametros...') else WriteLn('Exceso de prametros...'); WriteLn('Ejemplo: Copiar [Nombre de archivo a copiar]', '[Ruta destino del archivo]'); WriteLn('//Copiar datos.doc a://');

Halt(1); end; Assign(fuente,ParamStr(1)); temp:=ParamStr(2)+ParamStr(1); {archivo destino con ruta} Assign(destino,temp); {$I-} Reset(fuente,1); {$I+} if IOResult <> 0 then begin WriteLn('Error en archivo fuente..'); Halt(1); end; {$I-} Rewrite(destino,1); {$I+} if IOResult <> 0 then begin WriteLn('Error en la ruta destino..'); Halt(1); end; BlockRead(fuente,buffer,SizeOf(buffer),leidos); while leidos>0 do begin BlockWrite(destino,buffer,SizeOf(buffer),leidos); BlockRead(fuente,buffer,SizeOf(buffer),leidos) end; close(fuente); close(destino) end.

UNIDAD III: APUNTADORES: 3.1 DIRECCIONES DE MEMORIA:

Obtencin de direccin de memoria. Operador & Para almacenar una referencia a un objeto en un puntero se puede aplicar al objeto el operador prefijo &, que lo que hace es devolver la direccin que en memoria ocupa el objeto sobre el que se aplica. Un ejemplo de su uso para inicializar un puntero es:

int x =10; int * px = &x; Este operador no es aplicable a expresiones constantes, pues stas no se almacenan en ninguna direccin de memoria especfica sino que se incrustan en las instrucciones. Por ello, no es vlido hacer directamente:

int px = &10; // Error 10 no es una variable con direccin propia

Tampoco es vlido aplicar & a campos readonly, pues si estos pudiesen ser apuntados por punteros se correra el riesgo de poderlos modificar ya que a travs de un puntero se accede a memoria directamente, sin tenerse en cuenta si en la posicin accedida hay algn objeto, por lo que mucho menos se considerar si ste es de slo lectura. Lo que es s vlido es almacenar en un puntero es la direccin de memoria apuntada por otro puntero. En ese caso ambos punteros apuntaran al mismo objeto y las modificaciones a ste realizadas a travs de un puntero tambin afectaran al objeto visto por el otro, de forma similar a como ocurre con las variables normales de tipos referencia. Es ms, los operadores relacionales tpicos (==, !=, <, >, <= y >=) se han redefinido para que cuando se apliquen entre dos punteros de cualesquiera dos tipos lo que se compare sean las direcciones de memoria que estos almacenan. Por ejemplo:

int x = 10; int px = &x; int px2 = px; // px y px2 apuntan al objeto almacenado en x Console.WriteLine( px == px2); // Imprime por pantalla True

En realidad las variables sobre las que se aplique & no tienen porqu estar inicializadas. Por ejemplo, es vlido hacer:

private void f() { int x; unsafe { int px = &x;} } Esto se debe a que uno de los principales usos de los punteros en C# es poderlos pasar como parmetros de funciones no gestionadas que esperen recibir punteros. Como muchas de esas funciones han sido programadas para inicializar los contenidos de los punteros que se les pasan, pasarles punteros inicializados implicara perder tiempo innecesariamente en inicializarlos. Acceso a contenido de puntero. Operador * Un puntero no almacena directamente un objeto sino que suele almacenar la direccin de memoria de un objeto (o sea, apunta a un objeto) Para obtener a partir de un puntero el objeto al que apunta hay que aplicarle al mismo el operador prefijo *, que devuelve el objeto apuntado. Por ejemplo, el siguiente cdigo imprime en pantalla un 10:

int x = 10; int * px= &x; Console.WriteLine(*px); Es posible en un puntero almacenar null para indicar que no apunta a ninguna direccin vlida. Sin embargo, si luego se intenta acceder al contenido del mismo a travs del operador * se producir generalmente una excepcin de tipo

NullReferenceException (aunque realmente esto depende de la implementacin del lenguaje) Por ejemplo:

int * px = null; Console.WriteLine(*px); // Produce una NullReferenceException No tiene sentido aplicar * a un puntero de tipo void * ya que estos punteros no almacenan informacin sobre el tipo de objetos a los que apuntan y por tanto no es posible recuperarlos a travs de los mismos ya que no se sabe cuanto espacio en memoria a partir de la direccin almacenada en el puntero ocupa el objeto apuntado y, por tanto, no se sabe cuanta memoria hay que leer para obtenerlo. 3.2 APUNTADORES: 1.-Un Apuntador es una variable que contiene una direccin de memoria, la cual corresponder a un dato o a una variable que contiene el dato. Los apuntadores tambin deben de seguir las mismas reglas que se aplican a las dems variables, deben tener nombre nicos y deben de declararse antes de usarse. Cada variable que se utiliza en una aplicacin ocupa una o varias posiciones de memoria. Estas posiciones de memoria se accesan por medio de una direccin.

3.3 APUNTADORES A ENTEROS:

int *p; int *p[10]; int (*p)[10]; int *p(void); int p(char *a); int *p(char *a); int (*p)(char *a); int (*p(char *a)) [10]; int p(char (*a)[]); int p(char *a[]); int *p(char a[]); int *p(char (*a)[]); int *p(char *a[]); int (*p)(char (*a)[]); int *(*p)(char (*a) []); int *(*p)(char *a[]); int(*p[10])(void); int (*p[10])(char * a); int *(*p[10])(char a);

p es un apuntador a un entero p es un arreglo de 10 apuntadores a enteros p es un apuntador a un arreglo de 10 enteros p es una funcin que devuelve un apuntador a entero p es una funcin que acepta un argumento que es un apuntador a carcter, devuelve un entero p es una funcin que acepta un argumento que es un apuntador a carcter, devuelve un apuntador a entero p es un apuntador a funcin que acepta un argumento que es un apuntador a carcter, devuelve un apuntador a entero p es una funcin que acepta un argumento que es un apuntador a carcter, devuelve un apuntador a un arreglo de 10 enteros p es un apuntador a funcin que acepta un argumento que es un apuntador a un arreglo de caracteres, devuelve un apuntador a entero p es un apuntador a funcin que acepta un argumento que es un arreglo de apuntadores a caracteres, devuelve un apuntador a entero p es una funcin que acepta un argumento que es un arreglo de caracteres, devuelve un apuntador a entero p es una funcin que acepta un argumento que es un apuntador a un arreglo de caracteres, devuelve un apuntador a entero p es una funcin que acepta un argumento que es un apuntador a un arreglo de apuntadores a caracteres, devuelve un apuntador a entero p es una funcin que acepta un argumento que es un apuntador a un arreglo de caracteres, devuelve un apuntador a entero p es un apuntador a una funcin que acepta un argumento que es un apuntador a un arreglo de apuntadores a caracteres, devuelve un apuntador a entero p es un apuntador a una funcin que acepta un argumento que es un arreglo de apuntadores a caracteres, devuelve un apuntador a entero p es una arreglo de 10 apuntadores a funcin, cada funcin devuelve un entero p es un arreglo de 10 apuntadores a funcin; cada funcin acepta un argumento que es un apuntador a carcter y devuelve un entero p es un arreglo de 10 apuntadores a funcin; cada funcin acepta un argumento que es un carcter, y devuelve un apuntador a entero

char *(*p[10])(char p es un arreglo de 10 apuntadores a funcin; cada funcin acepta un * a); argumentoque es un carcter, y devuelve un apuntador a carcter.

3.6 APUNTADORES A ARREGLOS Existe una estrecha relacin entre apuntadores y arreglos, tanto que pueden ser usados en forma casi indistinta. Una variable de tipo arreglo puede considerarse como un apuntadoral tipo del arreglo.

Los apuntadores pueden ser utilizados en cualquier operacin que involucre subndices de arreglos.

Ejemplo: #include <stdlib.h> #include <stdio.h> int main() { int tabla[10],i,x,*pt,*ptr; pt = &tabla[0]; x = *pt; for (i=0; i <10; i++) *(pt+i) = rand() % 100; ptr = tabla; for (i=0; i <10; i++) } printf(''%d \n'',*(ptr+i),tabla[i]);

Cuando se suma 1 a un apuntador el incremento se adecua al tamao en memoria del objeto apuntado. Un apuntador es una variable, por lo que operaciones como pa = a y pa++ son permitidas. Un nombre de un arreglo es una constante, no una variable, de ah que a = pa o a++ o p = a.

Arreglos de apuntadores

Los arreglos pueden contener apuntadores El uso ms comn es el de formar arreglos de cadenas de caracteres Cada entrada en el arreglo es un apuntador al primer caracter de la cadena Sea la declaracin: char * mensaje[4] = {''Hola'',''Adios'',''Bye'',''Salut''}

Cada cadena est almacenada en memoria como una cadena de caracteres terminada en NULL n0. En el arreglo no estan colocadas las cadenas, tan solo estn almacenados los apuntadores. Aunque el arreglo es de tamao fijo, permite el acceso a cadenas de caracteres de cualquier longitud.

3.6 ARREGLOS A ESTRUCTURAS: Punteros a estructuras Del mismo modo que ocurre con las funciones, las estructuras tienen una direccin, asumiendo que esta es el comienzo de su almacenamiento. Esto es especialmente cierto en C, donde las estructuras representan exclusivamente conjuntos de datos. En C++ las estructuras son cierto tipo de clases que pueden contener cdigo (funciones), pero incluso entonces, lo que realmente se almacena en el cuerpo de la estructura son punteros (datos) a las funciones correspondientes.

Nota: puesto que desde el punto de vista C++ las estructuras son un tipo de clases, les son aplicables los mismos principios y reglas que a aquellas. En concreto todo lo sealado respecto a punteros. Ver a este respecto "Punteros a clases" y "Punteros a miembros"

Veremos que los punteros a estructuras son de uso muy frecuente para el manejo de estas; en especial cuando se pasan como argumentos a funciones, o son devueltas por estas. Por ejemplo, la sentencia: struct punto {int x; int y;} pto = {3,4}, *ptr = &pto, arsp[10]; define un tipo de estructura denominado punto; una estructura (instancia) pto, y un puntero ptr a dicha instancia. Finalmente declara una matriz arsp de 10 estructuras tipo punto.

2 Sintaxis En general la sintaxis para declaracin de punteros a estructuras sigue la sintaxis general (Declaracin de punteros). <tipo_objeto> * <etiqueta_puntero> [ = <iniciador> ] En este caso, tipo_objeto es de la forma struct punto, con lo que la declaracin es: struct punto * ptr; Opcionalmente puede incluirse un iniciador como en el ejemplo anterior: struct punto * ptr = &pto;

en este caso, ptr es un puntero, y su indireccin *ptr, representa la estructura pto. Los miembros de la estructura pueden referenciarse mediante el operador de acceso: (*ptr).x == 3; (*ptr).y == 4; Los parntesis son necesarios, ya que el operador de acceso (.) tiene mayor precedencia que el de indireccin. Por esta razn, *ptr.x es interpretada como *(ptr.x), lo que es errneo, ya que ptr.x no es un puntero (en este caso es un entero).

3 La expresin: struct { int x1; char * str; long *arr[10]; } *ptr; Declara un puntero ptr a un tipo de estructura annima de tres componentes

Nota: aunque sintcticamente correcta y aceptable por el compilador, una declaracin como la anterior es prcticamente intil y muy peligrosa. Por ejemplo, la sentencia (*ptr).int = 30; puede producir una catstrofe. La razn es la misma que se apunt en Expresiones peligrosas

4 Los punteros son muy importantes para el manejo de matrices y estructuras, por lo que en este caso se ha previsto una notacin alternativa ms corta ptr->x == 3; ptr->y == 3;

Veamos las dos opciones de notacin para acceso de miembros en un ejemplo con estructuras anidadas: struct punto { int x; int y; }; struct line { struct punto p1; struct punto p2; } lin, *liptr = &lin; En las sentencias anteriores hemos definido dos tipos de estructuras; una instancia y un puntero a dicha instancia. En estas condiciones, las expresiones que siguen son equivalentes (1 y 6 son preferibles por legibilidad): lin.p1.x (lin.p1).x (*liptr).p1.x // L1.

((*liptr).p1).x liptr->p1.x (liptr->p1).x

// L6.

5 Ejemplo. float pi = 3.14159; struct { int x; char * str; float *arr[10]; struct punto pto; struct cuadro cuad; } str, *ptr = &str; Supuestas las declaraciones anteriores, a continuacin realizamos asignaciones a los miembros de str de dos formas: directamente y mediante expresiones del puntero ptr. Observe que segn lo indicado al respecto del espacio de nombres de estructuras, es perfectamente compatible el nombre str de estructura con el de uno de sus miembros (el puntero a carcter str.str). 5.1 Asignaciones directas: str.x = 30; str.str = "Hola mundo"; str.arr[0] = & pi; str.pto.x = 2; str.pto.y = 3; str.cuad.p1.x = 4; str.cuad.p1.y = 5; str.cuad.p2.x = 6; str.cuad.p2.y = 7; 5.2 Expresiones con puntero: ptr->x = 30; ptr->str = "Hola mundo"; ptr->arr[0] = & pi; ptr->pto.x = 2; str.pto.y = 3; ptr->cuad.p1.x = 4; ptr->cuad.p1.y = 5; ptr->cuad.p2.x = 6; ptr->cuad.p2.y = 7;

6 En el epgrafe relativo a la asociatividad y precedencia de operadores se ha sealado que los operadores: () [] -> . :: Llamada de funcin Subndices Acceso a miembro de estructura (mediante puntero) Acceso a miembro de estructura Acceso a miembro de clase

constituyen el orden ms alto en la jerarqua de precedencia, y que su asociatividad es de izquierda a derecha, por lo que hay que prestar especial atencin a las expresiones en que aparecen. Para resaltar la importancia de las reglas de precedencia, en los ejemplos que siguen se exponen algunas expresiones, referidas al ejemplo (5 como una explicacin de su significado. ++ptr->x Debido a la precedencia de operadores, equivale a ++(ptr->x). As pues, incrementa el miembro x, no el valor del puntero ptr. Resultado: str.x == 31 *ptr->x Del mismo modo, esta indireccin equivale a *(ptr->x), lo que resulta en un error, porque en el ejemplo indicado, ptr->x no es un puntero (es un int), y ya hemos visto [4.9.11] que el operando del operador de indireccin debe ser un puntero. *ptr->str En este caso, si es correcta la aplicacin del operador *; la expresin equivale a *(ptr>str), y ptr->str s es un puntero (a carcter); concretamente seala a la primera posicin de la cadena, es decir: *ptr->str == 'H' se puede evidenciar como sigue: printf("Letra \"%c\"\n", *ptr->str); // -> Letra "H" ++*ptr->str Se ha sealado que *ptr->str equivale a 'H'; ahora el compilador se enfrenta a la expresin: ++'H' == 'H'+1;. El resultado depende del contexto, por ejemplo, 'H' = 'H'+1; es un error ('H' no es un Lvalue). Sin embargo, la sentencia que sigue se compila correctamente y produce la salida indicada. printf("Letra \"%c\"\n", ++*ptr->str); // -> Letra "I" La explicacin es que el compilador pasa a printf el valor 'H'+1 (sin pretender ninguna otra asignacin), lo que, tras una conversin de tipo, se traduce en el carcter 'I' que sigue 'H' en la lista ASCII. *ptr++->str La expresin se traduce en: *((ptr++)->str). Si se utiliza la expresin que sigue, el resultado es el que se indica, pero cualquier posterior intento de utilizar ptr conduce a una catstrofe. printf("Letra \"%c\"\n", *ptr++->str); // -> Letra "H" ), as

La razn es que se enva a printf el valor *ptr->str, que produce la salida indicada y despus se produce el postincremento del puntero ptr, que queda apuntando a dios sabe donde, con lo que la utilizacin posterior seguramente producir el fallo del sistema por "Error grave". Nota: si str hubiese apuntado a una matriz de estructuras y la posicin actual no fuese la ltima, el efecto hubiese sido simplemente dejar str apuntando a la siguiente estructura de la matriz. *++ptr->str La expresin equivale a *(++ (ptr->str)). Nuevamente el resultado es correcto: ptr->str es un puntero p que seala al carcter 'H'; su incremento en 1 lo hace apuntar al segundo, por lo que si utilizamos la expresin que sigue se produce la salida indicada: printf("Letra \"%c\"\n", *++ptr->str); // -> Letra "o" *ptr->str++ Esta expresin equivale a (*(ptr->str))++. Es decir, 'H'++; nuevamente el resultado depende del contexto. En la expresin que nos viene sirviendo para control, produce la salida sealada, porque printf recibe como argumento un puntero a 'H' y el incremento se produce despus. printf("Letra \"%c\"\n", *ptr->str++); // -> Letra "H"

UNIDAD IV: UNIDADES. 4.1 SUBRUTINAS. Introduccin El movimiento del programa se basa en la llamada a etiquetas y a subrutinas. Esto nos da capacidad para decidir, temporizar o retardar, operar y/o ejecutar algoritmos. Por eso debemos de tener en cuenta las tcnicas ms comunes en la programacin de lenguaje ensamblador que nos permitirn hacer estas y muchas otras cosas. La mayora de los microcontroladores incluyen en su repertorio de instrucciones algunas que permiten saltar a una rutina y, cuando se completa su ejecucin, retornar al programa principal. El empleo de subrutinas aporta muchas ventajas entre las que se destacan las siguientes: Se pueden escribir como subrutinas secciones de cdigo y ser empleadas varias veces en el mismo programa. Dan a los programas un carcter modular, es decir, se pueden codificar diferentes mdulos para utilizarlos en cualquier programa. Se reduce notablemente el tiempo de programacin y la deteccin de errores, utilizando repetidamente una subrutina.

El cdigo es ms fcil de interpretar, dado que las instrucciones de las subrutinas no aparecen en el programa principal, slo figuran las llamadas (CALL).

Las instrucciones CALL y RETURN. Subrutinas La instruccin CALL (llamada a subrutina) consigue que la ejecucin del programa contine en la direccin donde se encuentra la subrutina a la que hace referencia. Es similar a GOTO pero coloca en la pila la direccin de la siguiente instruccin que se debe ejecutar despus de terminar con la subrutina. La subrutina finaliza con la instruccin RETURN (retorno de la subrutina) que retoma la direccin guardada en la pila y la coloca en el contador del programa PC continuando el flujo de control con la instruccin que sigue a CALL. En la familia PIC de gama media la pila tiene ocho niveles de memoria del tipo LIFO (Last In, First Out) (ltimo en entrar, primero en salir). Si se produce la llamada a una subrutina durante la ejecucin de otra subrutina, la direccin de retorno de esta segunda es colocada en la cima de la pila sobre la direccin anterior. Esta segunda direccin es la primera en salir de la pila mediante la instruccin RETURN. Con la pila de ocho niveles, una subrutina puede llamar a otra y sta, a su vez, llamar a otra hasta un mximo de ocho. Todo esto ya lo vimos anteriormente.

4.2 UNIDADES Y/O LIBRERIAS (CON EJEMPLO)

Para quienes estn interesados, les dejo una lista con el nombre de todas las libreras standard de C y las funciones que contiene cada una. Dej los ttulos de las libreras y las variables en ingls ya que quienes programamos nos llevamos mejor con ese idioma (al menos en el momento de la programacin en si) que con nuestro espaol de nacimiento. stdio.h ctype.h string.h math.h stdlib.h assert.h setjmp.h signal.h time.h

Input and Output: <stdio.h> FILE *fopen(const char *filename, const char *mode) FILE *freopen(const char *filename, const char *mode, FILE *stream) int fflush(FILE *stream) int fclose(FILE *stream) int remove(const char *filename) int rename(const char *oldname, const char *newname) FILE *tmpfile(void) char *tmpnam(char s[L_tmpnam]) int setvbuf(FILE *stream, char *buf, int mode, size_t size) void setbuf(FILE *stream, char *buf)

int fprint(FILE *stream, const char *format, ) int sprintf(char *s, const char *format, ) vprintf(const char *format, va_list arg) vfprintf(FILE *stream, const char *format, va_list arg) vsprintf(char *s, const char *format, va_list arg) int fscanf(FILE *stream, const char *format, ) int scanf(const char *format, ) int sscanf(char *s, const char *format, ) int fgetc(FILE *stream) char *fgets(char *s, int n, FILE *stream) int fputc(int c, FILE *stream) int fputs(const char *s, FILE *stream) int getc(FILE *stream) int getchar(void) char *gets(char *s) int putc(int c, FILE *stream) int putchar(int c) int ungetc(int c, FILE *stream) size_t fread(void *ptr, size_t size, size_t nobj, FILE *stream) size_t fwrite(const void *ptr, size_t size, size_t nobj, FILE *stream) int fseek(FILE *stream, long offset, int orogin) long ftell(FILE *stream) void rewind(FILE *stream) int fgetpos(FILE *stream, fpos_t *ptr) int fsetpos(FILE *stream, const fpos_t *ptr) void clearerr(FILE *stream) int feof(FILE *stream) int ferror(FILE *stream) void perror(const char *s)

Character Class Tests: <ctype.h> isalnum(c) isalpha(c) iscntrl(c) isdigit(c) isgraph(c) islower(c) isprint(c) ispunct(c) isspace(c) isupper(c) isxdigit(c)

String Functions: <string.h> char *strcpy(s , ct) char *strncpy(s , ct , n) char *strcat(s , ct) char *strncat(s , ct , n) int strcmp(cs , ct) int strncmp(cs , ct ,n) char *strchr(cs , c) char *strrchr(cs , c) size_t strspn(cs , ct)

size_t strcspn(cs , ct) char *strstr(cs , ct) size_t strlen(cs) char *strerror(n) char *strtok(s , ct)

Mathematical Functions: <math.h> sin(x) cos(x) tan(x) asin(x) acos(x) atan(x) atan2(x) sinh(x) cosh(x) tanh(x) exp(x) log(x) log10(x) pow(x,y) sqrt(x) ceil(x) floor(x) fabs(x) ldexp(x) frexp(x,double *ip) modf(x,double *ip) fmod(x,y)

Utility Functions: <stdlib.h> double atof(const char *s) int atoi(const char *s long atol(const char *s) double strrod(const char *s, char **endp) long strtol(const char *s, char **endp, int base) unsigned long strtoul(const char *s, char **endp, int base) int rand(void) void srand(unsigned int seed) void *calloc(size_t nobj, size_t size) void *malloc(size_t size) void *realloc(void *p, size_t size) void free(void *p) void abort(void) void exit(int status) int atexit(void (*fcn)(void)) int system(const char *s) char *getenv(const char *name) void *bsearch(const void *key, const void *base, size_t n, size_t size, int (*cmp)(const void *keyval, const void *datum)) void qsort(void *base, size_t n, size_t size, int (*cmp)(const void *, const void *)) int abs(int n)

long labs(long n) div_t div(int num, int denom) ldiv_t ldiv(long num , long denom)

Diagnostics: <assert.h> void assert(int expression)

Non-local Jumps: <setjmp.h> int setjmp(jmp_buf env) void longjmp(jmp_buf env, int val)

Signals: <signal.h> void (*signal(int sig, void (*handler)(int)))(int)

Data and Time Functions: <time.h> *tp) clock_t clock(void) time_t time(time_t , *tp) double difftime(time_t time2 , time_t time1) time_t mktime(struct tm *tp) char *asctime(const time_t *tp) char *ctime(const time_t *tp) struct tm *gmtime(const time_t *tp) struct tm *localtime(const time_t *tp) size_t strftime(char *s, size_t smax, const char *fmt, const struct tm

4.3 ENCABEZADO (CON EJEMPLO)

ENCABEZADOS (*.H) Encabezado LIBMOUSE.H TEC.H BLT.H Funcin Encabezado con las declaraciones y la mayora de las rutinas de manejo del mouse Encabezado con el escudo del Instituto Tecnolgico de Nuevo Laredo y el escudo de ISC Encabezado de con rutinas de ventanas, marcos y letreros

PROGRAMAS DE ARCHIVOS

Programa ARCHIVO1.CPP ARCHIVO2.CPP ARCHIVO3.CPP ARCHIVO4.CPP ARCHIVO5.CPP ARCHIVO6.CPP ARCHIVO7.CPP ARCHIVO8.CPP ARCHIVO9.CPP ARCHIV10.CPP ARCHIVOS.CPP REFERENC.CPP REFEREN2.CPP ALIAS.CPP ALIAS2.CPP ARCH_SEC_OBJ.CPP

Funcin Capturar caracteres del teclado y grabarlos en un archivo de texto Lee caracteres grabados en un archivo de texto y los despliega en pantalla Captura cadenas del teclado y las graba en un archivo de texto Lee cadenas grabadas en un archivo de texto y las despliega en pantalla Almacena variables de diversos tipos en un archivo de texto Lee variables de diversos tipos desde un archivo de texto Graba registros completos (incluyendo sus campos) en un archivo secuencial binario Lee secuencialmente (uno por uno) los registros de un archivo binario Graba registros completos (incluyendo sus campos) en un archivo binario de acceso directo Lee registros completos (incluyendo sus campos) de un archivo binario de acceso directo Archivar y cargar una imagen Transmisin de estructuras por referencia a una subrutina Envo por referencia de un alias de un archivo Inicializar 3 archivos de ndice mediante una sola rutina que acepte por referencia los alias de los archivos as como sus registros de control correspondientes. Control de archivo secuencial con programacin orientada a objetos

4.4 DECLARACION (CON EJEMPLO) Declaracin de funciones Antes de empezar a utilizar una funcin debemos declararla. La declaracin de una funcin se conoce tambin como prototipo de la funcin. En el prototipo de una funcin se tienen que especificar los parmetros de la funcin, as como el tipo de dato que devuelve. Los prototipos de las funciones que se utilizan en un programa se incluyen generalmente en la cabecera del programa y presentan la siguiente sintaxis:

En el prototipo de una funcin no se especifican las sentencias que forman parte de la misma, sino sus caractersticas. Por ejemplo:

En este caso se declara la funcin cubo que recibe como parmetro una variable de tipo entero (numero) y devuelve un valor del mismo tipo. En ningn momento estamos especificando qu se va a hacer con la variable numero, slo declaramos las caractersticas de la funcin cubo. Cabe sealar que el nombre de los parmetros es opcional y se utiliza para mejorar la comprensin del cdigo fuente. De esta manera, el prototipo de la funcin cubo podra expresarse de la siguiente manera:

Los prototipos de las funciones son utilizados por el compilador para verificar que se accede a la funcin de la manera adecuada con respecto al nmero y tipo de parmetros, y al tipo de valor de retorno de la misma. Veamos algunos ejemplos de prototipos de funciones:

Las funciones de biblioteca se declaran en lo que se conocen como ficheros de cabecera o ficheros .h (del ingls headers, cabeceras). Cuando deseamos utilizar alguna de las funciones de biblioteca, debemos especificar el fichero .h en que se encuentra declarada la funcin, al inicio de nuestro programa. Por ejemplo, si deseamos utilizar la funcin printf en nuestro programa, debemos incluir el fichero stdio.h que contiene el prototipo de esta funcin. 4.5 CUERPO (CON EJEMPLO)

Cuerpo principal del programa Tambin se le llama bloque del programa, y es junto con la cabecera, la nica seccin obligatoria en un programa Pascal. Debe comenzar y finalizar con las palabras reservadas begin y end respectivamente. Muy imortante: Despus de la palabra end, siempre tiene que ir un punto que indica el final del programa. Entre begin y end se escriben una o ms sentencias, ya sean simples o compuestas. Las sentencias pueden ser varias: asignaciones, llamadas a procedimientos y funciones, sentencias selectivas (sentencias if), sentencias iterativas (sentencias for, while). Veamos un pequeo ejemplo: ... begin i := 0; while i<10 do begin writeln('El valor de i es ',i); i := i + 1 end end. ...

El ejemplo es muy sencillo. Se trata de un bucle que escribe en pantalla lineas que consisten en la frase "El valor de i es" seguidas del valor que tiene en ese momento la variable i (0..9).

4.6 CREACION (CON EJEMPLO)

Proceso de creacin de un programa Regla de oro de la programacin: !! Nunca est terminado del todo

1 Sinopsis Programming is the art of expressing solutions to problems so that a computer can execute those solutions. Bjarne Stroustrup: "Programming: Principles and Practice Using C++". Escribir un programa es establecer el comportamiento de una mquina mediante una serie de algoritmos que definirn su funcionamiento . En el estado actual de la ciencia, este algoritmo se plasma por escrito utilizando un lenguaje artificial comprensible por el humano-programador. Generalmente estas instrucciones, que aqu se denominan cdigo fuente, vienen acompaadas de algunos datos en forma de texto o imgenes, contenidas en uno o varios ficheros denominados ficheros de recursos ("resources"). Sin embargo, las instrucciones y recursos solo pueden ser utilizadas por la mquina despus de un proceso de traduccin que es realizado por la propia mquina (puede ser distinta de la que ejecuta el programa). El proceso exige que el cdigo fuente sea transformado en una nueva secuencia de instrucciones segn un nuevo sistema de codificacin (el lenguaje mquina), y que los recursos adopten una disposicin particular. Este conjunto de instrucciones y datos, que constituyen el denominado ejecutable, corresponden a acciones concretas y datos, que pueden ser entendidas, ejecutadas y utilizados por la mquina. En general este comportamiento pretende modelar o mimetizar el comportamiento de una entidad del mundo real, o de una abstraccin que hemos imaginado; y es de tipo genrico. Se pretende que la mquina se comporte como una funcin que acepta un conjunto de condiciones de entrada y devuelve como salida un comportamiento concreto y predecible para cada combinacin de las condiciones de entrada.

2 Presentacin del problema Hay bastante literatura sobre programacin en general; a los acadmicos les gusta hablar de "Teora de la Programacin", y mucha gente se ha dedicado a especular sobre el tema. Incluso hay modas al respecto [4]. Es posible confeccionar una lista de las caractersticas que "debe" y "no debe" tener un buen programa (incluyendo la del Jefe, que solo tiene dos puntos: "Que est para ayer; que salga barato"). El propio Stroustrup ( TC++PL) compara las condiciones para escribir un buen programa con las de escribir buena prosa. Segn l, existen dos respuestas: "Saber que se quiere decir" y "Prctica. Imitar buenos escritores". Ms adelante nos recuerda que aprender a manejar bien un lenguaje puede constar tanto tiempo y esfuerzo como aprender a expresarse en un lenguaje natural o tocar un instrumento.

Por supuesto sera un atrevimiento por mi parte contradecir tan docta opinin, pero puestos a filosofar me gustara puntualizar que el verdadero problema est en el segundo punto de la segunda respuesta; la primera, aunque ciertamente importante, me parece la verdad de Perogrullo . Siempre me ha parecido que programar (programar bien) tiene mucho de arte. Me parece que debe ocurrir como con la msica; seguramente muchos pueden decir que debe tener una buena ejecucin de violn, pero imitar a Paganini debe ser harina de otro costal. Seguramente los profesores de armona saben que debe tener y no tener una buena sinfona, pero otra cosa debe ser imitar a Mozart. Bajando a la tierra; tampoco se trata aqu de hacer "Paganinis de la programacin C++" (ya me gustara para m); el mensaje que quisiera transmitir es doble: El contenido en un viejo Refrn Espaol: "La Universidad no presta lo que la naturaleza no da". Como suena un poco duro, aadir un consuelo para los que somos menos dotados; un proverbio que le hace tiempo, en lnea con la respuesta de Stroustrup: "Por el dinero del trabajo los Dioses lo venden todo". A continuacin se comentan brevemente los pasos imprescindibles en la creacin de un programa C++. Vaya por delante, que las anotaciones de los puntos 3, 4 y 5 son opinin del que suscribe basados en la propia experiencia, por tanto totalmente subjetivos y opinables.

3 Comprender el problema. "Custom development is that murky world where a customer tells you what to build, and you say, "are you sure?" and they say yes, and you make an absolutely beautiful spec, and say, "is this what you want?" and they say yes, and you make them sign the spec in indelible ink, nay, blood, and they do, and then you build that thing they signed off on, promptly, precisely and exactly, and they see it and they are horrified and shocked, and you spend the rest of the week reading up on whether your E&O insurance is going to cover the legal fees for the lawsuit you've gotten yourself into or merely the settlement cost. Or, if you're really lucky, the customer will smile wanly and put your code in a drawer and never use it again and never call you back". Joel on Software "Set Your Priorities" www.joelonsoftware.com

"As more became known about what people wanted to do with computer, it became clear that there would always be increasingly more complex problems to solve. A part of that realization is the realization that our ability to accurately describe the problem determines the ability for the problem to be solved. Most people are incapable of clearly and precisely articulating -- to the level necessary -- the problems that they're trying to solve. This is a problem that is

getting larger and not smaller". Robert Bogue (Jupitermedia Corp) en "Breaking Down Software Development Roles". "Often, a problem is only fully understood through the process of programming a solution for it". Bjarne Stroustrup: "Programming: Principles and Practice Using C++".

Esta es la tpica obviedad que a veces se pasa por alto. Hemos dicho que escribir un programa es establecer el comportamiento de una mquina; parece lo ms natural del mundo enterarse primero de cual es ese comportamiento. Tener una imagen mental lo ms clara posible de las caractersticas de lo que pretendemos modelar. Esta cuestin es lo que los tericos denominan el "espacio" del problema, "'What' domain" en la literatura inglesa. A esta fase se la suele denominar anlisis, y mi consejo particular es que despus de una primera toma de contacto, el segundo paso sea definir de la forma ms detallada posible el principio y el final del problema. Es decir: cual es la informacin de partida (incluyendo su formato y en que soporte se recibe) y cual es la informacin final y en que soporte se proporcionar; no es lo mismo mostrar una imagen que componer una factura o disparar un proceso si un sensor analgico-digital nos suministra una determinada seal (por citar algn ejemplo). Normalmente en ambas cuestiones tiene mucho que decir el cliente [2], es lo que se llama especificacin; el resto (lo que hay entre los datos de entrada y la salida), debe rellenarlo el programador. Generalmente si se tienen bien definidos ambos extremos, se tiene resuelta la mitad del problema; cuando se tengan diseados los ficheros se tendrn dos terceras partes -ver a continuacin-. Este sistema tiene adems la ventaja de poner inmediatamente de manifiesto las indefiniciones de partida; a veces los clientes no saben exactamente qu desean y hay que ayudarles a centrar el problema. Dentro de esta fase tiene especialsima importancia el tema de los lmites; esto se refiere al orden de magnitudes que se manejarn. De que rango sern las magnitudes numricas? Podrn adoptar valores negativos? Hay informacin alfanumrica? Como son de largas estas cadenas?. Especialmente si el programa implica diseo de archivos (como es casi seguro), Cual podr llegar a ser su tamao dentro de la vida del programa?. Si se manejan ficheros u objetos binarios, Como son de grandes? Que concepto tiene el cliente de los que sera "rpido" o "lento"? (milisegundos, minutos, horas?). En esta fase sea especialmente precavido y no se crea a pi juntillas todo lo que le digan (intente hacer de abogado del diablo). Como postre, disee las lneas maestras de una estrategia de recuperacin de errores de ejecucin, incluyendo que har con los no recuperables (errores fatales). Piense por ejemplo que si algn da lo llaman para ver "que ha pasado", quizs le interese disponer de un volcado de texto ASCII en el disco con una descripcin del estatus del programa como parte de las funciones de salida Hoy da, cuando se empieza a hablar de frigorficos que avisarn de que faltan provisiones o de lavadoras que avisarn al tcnico si se estropean, no estara de ms que sus programas estuviesen a la altura de las circunstancias.

4 Disear los ficheros y mdulos Si el programa debe utilizar ficheros que no vengan impuestos (ya existentes), y suponiendo que todo lo anterior est suficientemente claro, este es el momento de hacerlo. Ponga por escrito la especificacin de tales ficheros, incluyendo el nombre que dar a las variables y, en su caso, el que tendrn en el disco o almacenamiento externo. Esto puede concretarse quizs a la definicin de algunas estructuras. En esta fase es posible que tenga que repreguntar alguna cosa que se pas por alto. Teniendo ya una imagen ms o menos clara de lo que har su programa, si ste es mediano o grande, es posible que todava tenga que realizar una labor previa antes de ponerse a escribir el cdigo: disear a grandes rasgos cuales sern los mdulos del programa; mdulos que se correspondern aproximadamente con la distribucin del cdigo en ficheros fuente independientes. Quizs tenga que decidir tambin si algunas partes aparecern como libreras [1]. Recuerde lo indicado al respecto al tratar de los Subespacios de Nombres Esta fase es especialmente importante en el caso de programas muy grandes, cuyo desarrollo se reparte entre varios programadores que se encargan de uno o varios de estos mdulos. En estos casos, el anlisis, la especificacin, la subdivisin en partes (con sus especificaciones particulares), y la asignacin de estas como tareas a los programadores, lo habr realizado el jefe de programacin y desarrollo.

5 Escribir el cdigo Suponiendo cumplimentados los pasos anteriores, el programador est en condiciones de construir una imagen mental clara de como ser esa conexin entre la informacin de entrada y la salida, es lo que se denomina "espacio" de la solucin ("'How' domain"); su forma concreta es justamente el fuente del programa que se pretende. La codificacin consiste justamente trasportar a papel (en el lenguaje de programacin elegido) la imagen mental de esa conexin. Para escribir el cdigo fuente de un programa C++ solo se puede utilizar un subconjunto de 96 caracteres del juego total de caracteres US-ASCII). Son los siguientes:

Juego de caracteres imprimibles: abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789 _{}[]#()<>%:;.?*+ /^&|~!=,\" Caracteres no-imprimibles denominados separadores Espacio horizontal; Tabulacin horizontal (TAB); Tabulacin vertical (VT);

Salto de forma (FF); Nueva lnea (NL). Nota: Para escribir el cdigo solo hace falta un editor de texto plano, aunque las modernas "suites" de programacin incluyen editores especficos que estn conectados con el depurador, el compilador el enlazador (ver ms adelante) e incluso el sistema de ayudas, de forma que, por ejemplo, pueden mostrarnos automticamente la sentencia en la que se ha producido un error de compilacin, o la pgina correspondiente del manual si pulsamos en una palabra reservada y pedimos ayuda (F1 generalmente). Tambin muestran en diversos colores las palabras clave, los comentarios, Etc. Los ms avanzados disponen incluso de opciones que podramos calificar de "inteligentes", en el sentido que pueden prever cual ser nuestro prximo movimiento en funcin de la sentencia que estamos escribiendo (por ejemplo, ofrecernos una lista de las propiedades y mtodos de una clase si nos estamos refiriendo a ella).

Durante la fase de escritura no desdee dos puntos: Incluir la mayor cantidad de comentarios y aclaraciones posibles. Cuando se est muy "metido" en el programa todo parece evidente, pero piense que tiene que retocarlo dentro de unos aos, quizs entonces le parezca "Chino" y agradecer haber dejado la mayor cantidad de documentacin y aclaraciones al respecto. Incluso si es seguro que no volver a verlo, piense en el sufrido programador que le seguir si tiene que habrselas con su cdigo. En este sentido C++ no es precisamente COBOL, aunque afortunadamente permite incluir en el fuente comentarios todo lo extensos que se desee ( 3.1). No caiga tampoco en el error de pensar que esa informacin ya est en la documentacin escrita que le han obligado a entregar junto con los fuentes; posiblemente dentro de unos aos Usted mismo no encuentre esos documentos. Incluir la mayor cantidad posible de rutinas y condiciones de comprobacin de errores. Piense que el operador es un "manazas" o que los datos pueden venir con alguna corrupcin, error de transmisin, etc. Verifique constantemente que las condiciones son las esperadas

Una vez que se tiene el cdigo fuente (en uno o varios mdulos), el proceso de traducirlo a instrucciones comprensibles por el procesador (lenguaje mquina) puede hacerse siguiendo dos modelos: los intrpretes y los compiladores [3].En el caso de lenguajes compilados como C++, el fichero de texto plano (ASCII 2.2.1a) que contiene el fuente del programador (con la terminacin .C .CPP), es sometido a un proceso de varias fases que terminan en la obtencin del ejecutable.De forma genrica, todo este proceso se denomina "compilacin", aunque es una generalizacin un tanto incorrecta, ya que la compilacin propiamente dicha es solo una de las etapas intermedias. Sera ms correcto decir "construccin" del ejecutable, aunque por la extensin y generalizacin de su uso seguiremos utilizando el trmino genrico "compilacin" para referirnos a l. Los procesos de construccin del ejecutable se esquematizan en la figura que comentamos a continuacin:

6 Preproceso En la primera fase de la compilacin; un programa especial, denominado make, es encargado de iniciar el proceso llamando a los diversos mdulos que se encargan de la construccin del ejecutable se amplan detalles sobre esta parte del proceso). El primero de estos mdulos es el preprocesador. El preprocesador estudia el texto buscando directivas de preprocesado por ejemplo sentencias que pueden ser suprimidas, incluye los ficheros correspondientes a las directivas #include, sustituye los #define, elimina los comentarios y expande las macros encontradas en el fuente y en los propios ficheros incluidos. El resultado obtenido es lo que se denomina unidad de compilacin

7 Anlisis sintctico Puesto que el fichero fuente est escrito en un "lenguaje" (C++ en este caso) que tiene sus propias reglas de sintaxis (como los lenguajes naturales), el compilador debe comprobar que estas reglas se han respetado. Este anlisis ("Parsing") es realizado por el analizador sintctico [10]. En esta fase se realizan comprobaciones como que los parntesis estn cerrados, que no aparecen expresiones incompletas, etc. Para realizar esta labor, el "parser" debe identificar los tokens , de forma que el fuente es tokenizado, esto es, reducido a tokens y separadores. El fuente es escaneado, el analizador sintctico (parser) extrae los tokens, seleccionando el que coincida con la secuencia de caracteres ms larga posible dentro de la secuencia analizada [9]. Por ejemplo, la palabra clave external es reconocida como un solo token (identificador de clase de almacenamiento) en vez de seleccionar extern (una palabra reservada) y al (que sera un identificador). Los separadores (whitespaces) es el nombre genrico dado a los espacios (32), tabulaciones verticales VT (11), horizontales TAB (9) nueva linea NL (10) y retorno de carro CR (13). Los separadores sirven para indicar donde empiezan y terminan las palabras, pero despus de esto cualquier separador redundante es descartado. Por ejemplo, las dos secuencias: int i; float f; int i; float f; son lxicamente equivalentes y el resultado del anlisis son las seis palabras siguientes: int i ; float f ; El carcter ASCII espacio puede formar parte de cadenas literales (alfanumricas), en cuyo caso es protegido del proceso de anlisis, permaneciendo como parte de la cadena. Por ejemplo: char name[] = "Playa Victoria"; es reducido a siete tokens, incluyendo una cadena literal "Playa Victoria" char name [ ] = "Playa Victoria" ;

8 Anlisis semntico En lenguajes como el Ensamblador la comprobacin se limita al anlisis anteriormente sealado; con esto se garantiza que el fuente original es correcto (sintcticamente), es decir, es un escrito correcto desde el punto de vista del lenguaje, otra cosa es que tenga un sentido computacional correcto, o diga tonteras, incongruencias o sinsentidos [6]. Por supuesto la meta del compilador es conseguir descubrir con anticipacin (al runtime) el mximo de errores posibles. En los lenguajes de alto nivel, esto se consigue con una cierta comprobacin del "sentido" o "significado" del escrito, es el denominado anlisis semntico (anlisis del significado). La mejor baza de que dispone C++ para esta segunda comprobacin es la comprobacin esttica de tipos . Es decir, que las variables y las operaciones entre ellas se usan correctamente; esto supone verificar que las llamadas a funciones, los valores devueltos por estas y los operandos de las expresiones corresponden con el tipo que se les supone en cada caso. Por ejemplo: int x; char func(); .... x = func(); En este caso, la primera lnea declara que la variable x es tipo int (entero); la segunda declara que la funcin fun devuelve un carcter (char); si una lneas ms adelante se pretende igualar la variable x con el valor devuelto por la funcin, el analizador semntico estara en condiciones de asegurar que existe una incongruencia en las pretensiones del programador, generando el correspondiente mensaje de advertencia o error

9 Generador de cdigo Todos estos tokens identificados por el analizador sintctico, son organizados en una estructura como las hojas de un rbol. A continuacin, el generador de cdigo recorre este rbol traduciendo sus hojas directamente en cdigo de la mquina para la que se compila [11]. Si se solicita, el compilador tambin puede en esta fase generar un fichero en lenguaje macro ensamblador para su posible inspeccin por el programador (este cdigo es tambin dependiente de la mquina para la que se compila y fcilmente entendible por el humano; puede contener incluso comentarios para facilitar su lectura). Nota: Los compiladores modernos suelen incluir opciones que permiten generar cdigo optimizado para el tipo de procesador que se utilizar. Por ejemplo, el compilador Borland C++ dispone de opciones que permiten generar cdigo optimizado para procesadores Intel de modelos especficos (. Como cabra esperar, el compilador GNU c++ es el que ofrece ms posibilidades en este sentido, que

incluyen el tipo de procesador dentro de una larga lista de fabricantes, y dentro de estos diferentes modelos. En concreto, para la familias Intel i386 y x86-64, permite elegir entre 20 posibilidades diferentes!!.

A veces, despus del generador de cdigo puede ejecutarse un optimizador (peephole optmizer). Este generador de cdigo sera propiamente el compilador, es decir, el encargado de traducir algo entendible por el humano en cdigo mquina. En cualquier caso, el resultado es un fichero "objeto", generalmente con la terminacin .obj o .o. Tambin puede ordenarse al compilador que incluya en el "objeto", determinada informacin adicional que ser utilizada ms tarde por el depurador, por ejemplo los nmeros de lnea de las sentencias. Cuando se hace as, se habla de una compilacin "provisional" o de "depuracin"; distinta de la que se realiza para la versin definitiva (de campo) del programa en la que no se incluyen este tipo de informacin que ya no es necesaria.

10 Enlazado El ltimo paso en construir un ejecutable es el enlazado. Recibe este nombre el proceso de aglutinar todos los recursos en un solo fichero ejecutable. Estos recursos son desde luego los ficheros-objeto obtenidos en la compilacin de los diversos mdulos (ficheros .c) que componen el programa. Adems, si se han utilizado funciones o clases de librera [1] (como es casi seguro), el enlazador ("Linker") es el programa encargado de incluir los mdulos adecuados en el fichero ejecutable final. As pues, la funcin primordial del enlazador es resolver todas las referencias que puedan existir en el programa, es decir: que cada invocacin a un valor o a una funcin corresponda una direccin donde se encuentra el recurso correspondiente, y que estn todos contenidos en un solo fichero que pueda ser cargado y ejecutado por el Sistema Operativo. Eventualmente algunos recursos pueden estar en otros ficheros distintos del ejecutable, libreras de enlazado dinmico (en Windows se denominan DLLs). En cuyo caso el enlazador tambin incluir las direcciones y convenciones de llamada adecuadas para que puedan ser trados a ejecucin desde el programa principal. Por ltimo, el enlazador se encarga de insertar en el ejecutable un trozo de cdigo especial: el mdulo inicial, que es el encargado de iniciar la ejecucin. Hay que tener en cuenta que generalmente el enlazador puede producir diversos tipos de resultados:

10.1 Versin de depuracin Se trata de una versin en la que dentro del propio ejecutable, se incluye informacin adicional no estrictamente necesaria para la ejecucin sino para la depuracin (por

ejemplo los nmeros de lnea del cdigo fuente que corresponde a cada sentencia). Estos ejecutables permiten la ejecucin en un modo especial, en la que por ejemplo, pueden ejecutarse las sentencias paso a paso, o que el programa se detenga al llegar a diversos puntos establecidos de antemano; ver el contenido de las variables, el estado de la pila y otros aspectos internos muy tiles cuando se intentan depurar errores de tiempo de ejecucin. Esto se consigue porque el programa corre bajo control de otro programa que acta de controlador de la ejecucin, es el depurador ("Debugger"). Nota: El depurador puede ser en realidad un mdulo adicional al de inicio, inserto en el ejecutable, que se inicia antes que la propia funcin main de forma que puede controlar la ejecucin. Por esta razn entre otras, las versiones de depuracin son mayores (en tamao del fichero) que las definitivas o "de campo" [12].

10.2 Versin de publicacin Es la versin definitiva que saldr al pblico (se entregar al usuario). Se distingue de las versiones internas en que no incluye informacin para depuracin. Es buena prctica incluir en cada versin publicada informacin sobre el nmero de versin del programa y de compilacin (esto suele venir indicado en la siguiente forma: Versin xx.yy.zz build nnn). Generalmente los programas sufren muchas modificaciones a lo largo de su vida (correccin de errores, perfeccionamientos, versiones para diversas plataformas, etc), y es preciso identificarlos. Es costumbre hablar de "versiones", que se identifican por grupos de nmeros separados por puntos. Por ejemplo: Versin xx.yy.zz. Cada fabricante de software, grupo de trabajo o programador, utiliza una convencin, establecindose que tipo de cambios dan lugar a diferencias de versin en el grupo de cifras xx; en el yy o en el zz. Generalmente se acepta que los cambios de mayor nivel (xx) representan versiones totalmente nuevas del programa; que requieren incluso rescribir los manuales de uso. Los cambios menores corresponden a modificaciones en el grupo yy (por ejemplo utilizar otras versiones de las libreras o distinto compilador); finalmente los cambios de detalle representan modificaciones en el grupo zz. Viene a representar cambios mnimos, que no merecen una alteracin del ltimo grupo de cifras [7], pero cambios al fin y al cabo (cuando se recompila es porque algo ha cambiado, aunque sea un comentario en el fuente). Es tambin costumbre incluir un ltimo identificador: El nmero de compilacin o construccin ("build" en la literatura inglesa); es un nmero progresivamente creciente para cada compilacin distinta. A ttulo de ejemplo, en la pgina adjunta se muestra la clasificacin utilizada para las sucesiones versiones de los productos de un conocido fabricante.

10.3 Librera En las pginas siguientes veremos que como resultado de la "compilacin", no siempre se desea conseguir un ejecutable; al menos no en el sentido tradicional del trmino, sino una librera (de las que existen varios tipos), o un fichero objeto. En lo que respecta al lenguaje C++, existen dos tipos fundamentales: Estticas y Dinmicas. Las primeras son colecciones de ficheros precompilados, cuyo cdigo puede ser aadido a un ejecutable en el proceso de enlazado (los ficheros de la Librera Estndar que acompaan a los compiladores C++ son de este tipo). Las segundas son

autnticos ejecutables externos que son invocados desde otro ejecutable y devuelven el control a este cuando terminan su ejecucin. Ms detalles al respecto en:

11 Errores

Volver al principio (rescribir el cdigo)

La verdadera prueba de fuego del programador se presenta cuando lanza la orden de compilar y enlazar su programa. Todos los mdulos involucrados en los pasos anteriores, compilador, analizador sintctico y enlazador pueden detectar errores en nuestro cdigo y mostrar los mensajes correspondientes.

11.1 Tipos de errores En cuanto al momento en que se producen, son bsicamente de tres tipos: De tiempo de compilacin. Se engloban aqu los errores detectados por preprocesador, el analizador sintctico y el propio compilador. Los hay meramente sintcticos, por ejemplo un parntesis no cerrado; tambin de tipo lgico, por ejemplo la referencia a una variable no declarada previamente, etc. etc. De tiempo de enlazado. Son detectados por el enlazador. Por ejemplo una llamada a funcin cuya definicin no aparece por ninguna parte (el enlazador no es capaz de encontrarla en los directorios que tiene asignados como "normales" para buscar); tambin la inversa: dos funciones del mismo nombre situadas en dos mdulos (fuentes) distintos (la referencia aparece duplicada). De tiempo de ejecucin (runtime). Existe finalmente una ltima clase de errores: los que se producen cuando se ejecuta el programa; son precisamente los ms difciles de diagnosticar y verificar, sobre todo en aplicaciones grandes (los relativos a "prdidas misteriosas" de memoria y punteros descontrolados son especialmente temibles).

11.2 Gravedad de los errores Los errores producidos durante la compilacin son de dos tipos, segn su gravedad: Errores fatales ("Errors"): Son errores graves, el proceso no puede continuar y es detenido despus de mostrar la informacin pertinente. Advertencias ("Warnings"): No son errores graves pero si circunstancias sospechosas o inusuales de las que el compilador entiende que merecen una advertencia por si es algo que se nos ha escapado inadvertidamente (por ejemplo: Una variable declarada que no se utiliza para nada ms). En estos casos, el proceso continua y si no hay errores graves se construye un ejecutable.

En todos los casos el aviso incluye indicacin del fichero ("fuente" .C/.CPP), el nmero de lnea, y el nombre de la funcin donde se produce el error, as como una explicacin ms o menos clara de su motivo. En principio pueden ser cuestiones banales, como haber olvidado poner un punto y coma ; al final de una sentencia (muy corriente en los

que estamos acostumbrados a programar en otros lenguajes). En otros casos los mensajes son especialmente crpticos, sobre todo para el profano, pero poco a poco los entendemos mejor y podemos aprender mucho de ellos si prestamos la debida atencin y entendemos su "porqu". Recordar que todos los compiladores disponen de opciones para modificar el nmero y tipo de los errores y advertencias ("Warnings") que aparecen. Respecto a los primeros, puede instruirse al compilador para que suspenda la actividad al aparecer el primer error, o que contine hasta que aparezca un nmero determinado de ellos. Respecto a los avisos, puede ordenarse que no muestre ninguno, o que sea ms o menos benevolente en determinados aspectos. Por ejemplo, puede indicarse que la comprobacin siga estrictamente el estndar C++ y que avise de cualquier desviacin al respecto (los compiladores suelen permitir ciertas "peculiaridades" que no son estndar). Nota: La descripcin e informacin acerca del error o advertencia, dependen de la plataforma, pero hemos de sealar que existen notables diferencias en cuanto al grado de desarrollo de los diversos compiladores, en especial respecto a los "Warnings". Por ejemplo, en este sentido el Compilador Borland C++ 5.5 es mucho menos riguroso que el producto homlogo de Microsoft, cuyo sistema de verificacin es con mucho superior al del primero, de forma que no es infrecuente que advertencias ms o menos serias e incluso algunos errores advertidos por Visual C+ + 6.0 sean totalmente ignorados por Builder. A su vez los errores y advertencias sealados por el compilador GNU Cpp suelen ser ms explicativos que los sealados por Borland o Visual (que en este sentido son ms crpticos).

11.3 Generalidades sobre los errores de compilacin Respecto a los errores de compilacin, es importante hacer una advertencia al nefito: Con frecuencia el compilador nos informa de error en una lnea ms abajo de donde est verdaderamente. Por ejemplo, olvidar un punto y coma de final de sentencia puede dar lugar a que el compilador nos informe de un error incomprensible dos o tres lnea ms abajo.

Cuando se realizan modificaciones en fuentes grandes y no se tiene mucha prctica, es preferible realizar cambios pequeos y compilar sistemticamente despus de cada uno. As sabremos que el error corresponde a lo ltimo que hemos tocado. Hay veces en que quitar una simple coma en una sentencia produce una listado de 15 o 20 errores en lneas siguientes. !Sbitamente nada tiene sentido para el compilador !!. [5] En las asignaciones del tipo: Lvalue = Rvalue; en las que intentamos asignar un valor Rvalue 1 que puede ser el resultado de una expresin) a un Lvalue , son muy frecuentes los errores en que el compilador produce un mensaje del siguiente aspecto: Error .... Cannot convert 'xxxxx' to 'yyyyy'

. Nota: En el captulo dedicado a los tipos de datos ( in function ....

Lo importante a resear aqu, es que las expresiones xxxxx e yyyyy informan sobre el tipo de objeto que hay en cada lado de la expresin de asignacin 2.2) se describe detalladamente como el compilador clasifica los objetos segn su tipo. En las asignaciones, el Lvalue debe recibir un valor de su mismo tipo. Si el tipo del Rvalue no concuerda con l, el compilador puede intentar adecuarlo, pero si esto no es posible, se produce un error como el sealado. En l se nos indica que el tipo xxxxx, que corresponde al Rvalue (el resultado de la expresin a la derecha del operador = ), no puede ser convertido al tipo yyyyy del Lvalue. Hay que advertir que las expresiones xxxxx e yyyyy estn codificadas. Cada compilador utiliza un algoritmo interno para designar cada uno de los innumerables tipos que puede existir en C++. En concreto, la designacin utilizada en estos mensajes es la misma que utiliza en el operador typeid. En situaciones difciles, es mucha la informacin que puede obtenerse de estas expresiones si se observan detenidamente.

Aunque la comprobacin esttica de tipos, y del cumplimiento de las reglas sintcticas realizada por el compilador, resultan muy eficientes en lo que respecta a la deteccin de errores, en realidad, el trabajo dista de ser completo y suficiente. Existen multitud de circunstancias potencialmente errneas que son pasadas por alto. En especial las relacionadas con prdidas de memoria; existencia de punteros descolgados; bucles infinitos; objetos declarados pero no utilizados, y un largo etctera. Algunos de estos errores pueden permanecer agazapados en el cdigo y solo aparecer en circunstancias muy especiales, incluso despus de que la aplicacin haya sido rodada largo tiempo sin contratiempos. Muchas de estas circunstancias pueden evitarse, o al menos mitigarse, siguiendo ciertas pautas y recomendaciones "de buena prctica", muchas de las cuales estn contenidas en la obra TC++PL de Stroustrup; la mayora en forma de advertencias sobre cosas que "no" debe hacerse. Sin embargo, el problema persiste, mxime en un lenguaje como C++ plagados de peligros potenciales que acechan en el arcn, y con el que es posible "volarse la pierna completa". Para reforzar la calidad del cdigo y prevenir errores posteriores (de run-time), se han creado multitud de herramientas. Entre las ms conocidas se encuentran las siguientes: Lint, denominadas as en atencin a que tienen su origen en una utilidad de este nombre (lint) desarrollada inicialmente en el entorno Unix. Estas utilidades se ejecutan sobre el fuente sin compilar (no confundirlas con los depuradores "debugger" -de run-time-, aunque tambin sirven para "depurar" el cdigo); comprueban la sintaxis y errores en los tipos de datos de forma ms concienzuda y profunda que los compiladores C/C++, y avisan de gran cantidad de peligros potenciales; incorrecciones; desviaciones sobre las reglas universalmente aceptadas como de "buena prctica", etc. Actualmente han llegado a un elevado nivel de sofisticacin, de forma que un buen Lint puede evitarnos muchas horas de depuracin. En realidad es una herramienta que no debera faltar en el taller del programador profesional.

cb. Esta utilidad, originaria del SO AIX, reformatea el cdigo fuente contenido en un fichero y lo vuelca sobre el dispositivo estndar de salida (stdout 5.3) utilizando un formateo basado en sangrados y espaciados, que ayudan a interpretar la estructura del cdigo.

cflow. Esta utilidad, originaria del SO AIX, analiza el contenido de un fichero objeto C/C++ y proporciona en la salida estndar (stdout) un grfico de sus referencias externas. cxref. Esta utilidad, anloga a las anteriores, analiza los fuentes C/C++ y genera una tabla con todos los smbolos encontrados en cada fichero, incluyendo los nombres de los parmetros formales de las funciones (contenidos en la definicin de la funcin). La tabla es mostrada en el dispositivo estndar de salida (stdout), e incluye el sitio en que cada resuelto (suponiendo que la definicin est en el cdigo analizado).

referencia se ha Si est interesado en las caractersticas y posibilidades de estos productos, la mayora comerciales y algunos muy costosos, aparte de la correspondiente bsqueda en Google, existe un interesante artculo de Scott Meyers (uno de los "Gurus" del C++) y Martin Klaus titulado "A First Look at C++ Program Analyzers", en el que se repasan las cualidades y caractersticas de distintos paquetes, incluyendo una evaluacin de su comportamiento frente a lo que el autor considera deseable. Aparecido en el nmero de Febrero de 1997 del Dr. Dobb's Journal, existe una versin de pre-publicacin accesible on-line, que es incluso ms completa que el artculo publicado (probablemente debido a las exigencias de maquetacin de la revista Uno de los productos punteros y ms antiguos, es el de Gimpel Software; esta empresa dispone de dos versiones denominadas PC-Lint y FlexeLint. La primera para Windows, la segunda, ms general, para cualquier entorno que soporte un compilador C, incluyendo Unix y Linux. Si tiene inters en comprobar ms de cerca el tipo de informacin que proporcionan estas utilidades, en el sitio de este fabricante existe una seccin denominada Bug del mes ("Bug of the month") en la que se exponen ejemplos de cdigo, junto con el resultado del anlisis (despus de pulsar un botn). Adems de smamente instructivos, los casos propuestos pueden servirle para auto-evaluar sus conocimientos de C++ al respecto. A mi entender tambin pueden constituir una magnfica fuente de inspiracin para los enseantes que busquen material para ejemplo o evaluacin (sed piadosos en los exmenes porque algunos son realmente para niveles avanzados. No se puede pretender que despus de un semestre de estudio, el alumno est en condiciones de adivinar correctamente el "bug C/C++ del mes" :-)

11.4 Errores de ejecucin Para los errores de tiempo de ejecucin se requieren estrategias especiales. En principio, durante la fase de comprobacin inicial, se tienen las ofrecidas por el depurador. Prcticamente todos los entornos de desarrollo disponen de un depurador ms o menos potente y sofisticado. Puede afirmarse que el depurador es otra herramienta que no debe faltar en el arsenal de cualquier programador profesional, en especial porque hay errores que son prcticamente imposibles de diagnosticar y corregir sin su ayuda.

Como se ha indicado, el depurador incluye en el ejecutable un cdigo especial que realiza las funciones de depuracin deseadas, pero aparte de los que podramos denominar estndar (cuyos mdulos son incluidos en durante la fase de enlazado del ejecutable), existen herramientas especficas que analizan el ejecutable y son capaces de detectar determinados errores e inconsistencias. Estas herramientas realizan su trabajo durante la ejecucin, para lo que modifican el cdigo a analizar incluyendo determinados mdulos que les permiten controlar el desarrollo de la ejecucin (se dice que "instrumentan" el cdigo). La forma de realizar esta "instrumentacin" depende de la herramienta: puede realizarse durante la compilacin ("compile-time"), aadiendo cdigo que no aparece en el fuente; durante el enlazado ("link-time"); durante la carga ("load-time"), cuando el ejecutable es acomodado en memoria, o antes de la carga, sobre cualquier ejecutable listo para ser usado. Generalmente estas herramientas controlan la ejecucin, toman nota de las incidencias, y finalmente proporcionan un informe de las mismas cuando la ejecucin finaliza. Nota: no existe una denominacin unificada para este tipo de productos. Quizs el ms conocido es es BoundsChecker, de Numega (actualmente aparece como Compuware). Tambin puede intentar una bsqueda en Google bajo el epgrafe "Memory debugger".

Despus de todas las medidas preventivas ya reseadas, cuando finalmente, despus de las pruebas de "laboratorio" damos por bueno el programa, este queda merced a si mismo; a la calidad de su propio mecanismo de defensa. Como errar es humano, los diseadores del C++ pensaron que a pesar de la programacin ms cuidadosa, siempre pueden presentarse circunstancias excepcionales o imprevistas. Para poder hacerles frente, dotaron al lenguaje de opciones especiales con las que tratar este tipo de situaciones, de forma que pudiese seguir todo bajo control; estos recursos especficos se exponen con detalle en el captulo dedicado al Tratamiento de Excepciones.

12 Recursos Ya hemos sealado que para construir un programa C++ basta un editor de texto plano y un compilador C++ para la mquina y Sistema en que deba ejecutarse, y que en el trmino "Compilador" incluimos todas las herramientas auxiliares, enlazador, libreras, etc. Por supuesto que en este sentido, las plataformas comerciales, en especial las versiones denominadas "Enterprise", ofrecen unas prestaciones inigualables, incluyendo potentes depuradores, diseo grfico de elementos con capacidad de arrastrar y soltar ("dragg and drop") elementos, y conjuntos preconstruidos de clases que simplifican extraordinariamente la construccin de determinados aspectos de las aplicaciones. Por ejemplo, el manejo de bases de datos o comunicaciones. En esta categora podemos incluir productos como C++Builder de Borland o Visual C++ de Microsoft para el entorno Windows. En la pgina dedicada a los Compiladores encontrar algunas referencias. Si desea saber ms sobre aspectos relacionados con la compilacin, preproceso, anlisis sintctico y semntico, traduccin del cdigo, etc, mi consejo es que consulte "Compiladores y Procesadores de Lenguajes" [Jimnez-04]

Inicio. [1] En el argot de programacin, "funcin de librera" se refiere a un recurso prefabricado; trozos de cdigo, generalmente en forma de funciones o clases que otros han escrito, que incluimos en nuestro programa. La confeccin de programas se parece a la construccin de un edificio en el que cada vez ms se utilizan elementos preconstruidos (algunas veces normalizados), que facilitan y aceleran la construccin. Suelen ser de dos clases: incluidas en el compilador (lenguaje utilizado), que en caso del C++ estn incluidas en la denominada Librera Estndar, y de terceras partes; libreras especializadas en cuestiones muy concretas que pueden adquirirse para no tener que escribir por nosotros mismos rutinas que otros (que adems saben mucho sobre el tema), se han encargado de escribir y comprobar. Por ejemplo: libreras grficas, de comunicaciones, estadsticas, para escribir cdigos de barras en una impresora, Etc. Las modernas "suites" de programacin C++ incluyen completsimas libreras en las que estn resueltas la mayora de las situaciones que habitualmente se suelen presentar en la programacin normal. Precisamente el entorno C++Builder de Borland-Imprise es un claro ejemplo. El paquete estndar comprende un entorno grfico de programacin (IDE) para Windows, que incluye un potente conjunto de libreras en forma de "herramientas". Es un producto comercial con un precio determinado. En cambio, el compilador, el depurador y la Librera Estndar se suministran gratis. Es decir, se asume que el valor comercial est en el entorno grfico integrado y en las libreras adicionales. [2] Seguramente se me ocurre lo de "cliente" por deformacin profesional; por supuesto el cliente podemos ser nosotros mismos, el jefe, el profesor de la asignatura, Etc. [3] Con objeto de mejorar la velocidad de ejecucin (tradicionalmente lenta), algunos intrpretes, utilizan en realidad un modelo hbrido. Obtienen un seudo-ejecutable intermedio, mediante un preprocesado seguido de un "parsing", con lo que se obtiene un cdigo "tokenizado" que es el que se entrega realmente al intrprete. [4] A la hora de redactar estas lneas parece estar muy de moda una tcnica denominada Programacin Extrema (eXtreme programming), cuya filosofa se basa en 12 principios o mandamientos, alguno tan pintoresco como el de las "40 horas semanales", segn el cul la mejor manera de aumentar el rendimiento es que los programadores "solo" trabajen 40 horas a la semana, pues est cientficamente demostrado que un trabajador fresco produce cdigo de mejor calidad que uno cansado. A m particularmente, este tipo de consejos me recuerdan el de los libros de instrucciones americanos para el microondas: "No se aconseja utilizarlo para secar a su mascota" :-)) [5] Como consecuencia, despus de algunos aos de oficio, los programadores suelen (solemos) ser gente un poco "tocada de la azotea". No cabe duda que pasar aos viviendo en un mundo donde no da igual un punto que una coma en un milln de lneas de cdigo termina imprimiendo carcter. El resultado es que el resto de la gente "normal" no entiende muy bien porqu somos tan maniticos y puntillosos en algunos asuntos, ya que afortunadamente (?), el mundo real suele ser de lgica ms "borrosa" (a veces, tan borrosa que apenas se ve nada...). Nota: Esto de la lgica "Borrosa" viene a cuento y recuerdo de un amigo. Una persona de un gran talento natural que no ha tenido ocasin de recibir

formacin acadmica (es mecnico y apenas ha ido a la escuela). En cierta ocasin delante de unas cervezas intent explicarle las diferencias entre la lgica binaria y la difusa ("Fuzzy logic"). Das despus conversaba l con otras personas y me sorprendi como introduca el concepto de la lgica difusa con total oportunidad y como si fuese una cosa sabida de toda la vida. Solo haba cambiado una palabra; "borrosa" en lugar de difusa. [6] Las circunstancias son exactamente idnticas a las que se presentan en los lenguajes naturales. Tambin en estos es posible construir frases sintcticamente correctas pero carentes de sentido (los polticos saben mucho de esto). [7] En esta nomenclatura, una versin 2.4.10 es anterior a la 2.13.0, que a su vez es anterior a la 12.3. [8] Para resolver el problema de que algunos de estos smbolos no aparecen en los teclados de determinados idiomas (por ejemplo, la tilde ~ en los teclados espaoles) se recurri a representarlos mediante ternas de otros caracteres, los denominados trigrafos. [9] Esta regla de anlisis es conocida como de Max Munch; en realidad no es ningn personaje real, sino un convenio adoptado por los integrantes del primer Comit de Estandarizacin del lenguaje. [10] En general, un "parser" es un programa diseado para analizar un documento. [11] "On average, each line of code in a system programming language translates to about five machine instructions, compared to one instruction per line in assembly language (in an informal analysis of eight C files written by five different people, I found that the ratio ranged from about 3 to 7 instructions per line; in a study of numerous languages Capers Jones found that for a given task, assembly languages require about 36 times as many lines of code as system programming languages). Programmers can write roughly the same number of lines of code per year regardless of language, so system programming languages allow applications to be written much more quickly than assembly language". John K. Ousterhout. "Scripting: Higher Level Programming for the 21st Century" [12] Como botn de muestra, sealar que en una aplicacin C++ tpica Windows, cuyo ejecutable resultaba de 631 KBytes en su versin "de campo", la inclusin de la informacin necesaria para depuracin hizo aumentar su tamao hasta 3.257 KBytes (Compilador GNU gcc-g++ 3.4.2 para Windows -incluido en Dev-C++ -) 4.7 Declaracin y definicin dentro de un programa (con ejemplo) Las funciones son un conjunto de instrucciones que realizan una tarea especfica. En general toman ciertos valores de entrada, llamados parmetros y proporcionan un valor de salida o valor de retorno; aunque en C++, tanto unos como el otro son opcionales, y pueden no existir. Tal vez parezca un poco precipitado introducir este concepto tan pronto en el curso. Sin embargo, las funciones son una herramienta muy valiosa, y como se usan en todos los programas C++, creo que debemos tener, al menos, una primera nocin de su uso. A fin de cuentas, todos los programas C++ contienen, como mnimo, una funcin. Prototipos de funciones

En C++ es obligatorio usar prototipos. Un prototipo es una declaracin de una funcin. Consiste en una presentacin de la funcin, exactamente con la misma estructura que la definicin, pero sin cuerpo y terminada con un ";". La estructura de un prototipo es: [extern|static] <tipo_valor_retorno> [<modificadores>] <identificador>(<lista_parmetros>); En general, el prototipo de una funcin se compone de las siguientes secciones: Opcionalmente, una palabra que especifique el tipo de almacenamiento, puede ser extern o static. Si no se especifica ninguna, por defecto ser extern. No te preocupes de esto todava, de momento slo usaremos funciones externas, lo menciono porque es parte de la declaracin. El tipo del valor de retorno, que puede ser void, si no necesitamos valor de retorno. En C, si no se establece, ser int por defecto, aunque en general se considera una mala tcnica de programacin omitir el tipo de valor de retorno de una funcin. En C++ es obligatorio indicar el tipo del valor de retorno. Modificadores opcionales. Tienen un uso muy especfico, de momento no entraremos en este particular, lo veremos en captulos posteriores. El identificador de la funcin. Es costumbre, muy til y muy recomendable, poner nombres que indiquen, lo ms claramente posible, qu es lo que hace la funcin, y que permitan interpretar qu hace el programa con slo leerlos. Cuando se precisen varias palabras para conseguir este efecto se puede usar alguna de las reglas ms usuales. Una consiste en separar cada palabra con un "_". Otra, que yo prefiero, consiste en escribir la primera letra de cada palabra en mayscula y el resto en minsculas. Por ejemplo, si hacemos una funcin que busque el nmero de telfono de una persona en una base de datos, podramos llamarla "busca_telefono" o "BuscaTelefono". Una lista de declaraciones de parmetros entre parntesis. Los parmetros de una funcin son los valores de entrada (y en ocasiones tambin de salida). Para la funcin se comportan exactamente igual que variables, y de hecho cada parmetro se declara igual que una variable. Una lista de parmetros es un conjunto de declaraciones de parmetros separados con comas. Puede tratarse de una lista vaca. En C es preferible usar la forma "func(void)" para listas de parmetros vacas. En C++ este procedimiento se considera obsoleto, se usa simplemente "func()".

Por ejemplo: int Mayor(int a, int b); Un prototipo sirve para indicar al compilador los tipos de retorno y los de los parmetros de una funcin, de modo que compruebe si son del tipo correcto cada vez que se use esta funcin dentro del programa, o para hacer las conversiones de tipo cuando sea necesario. En el prototipo, los nombres de los parmetros son opcionales, y si se incluyen suele ser como documentacin y ayuda en la interpretacin y comprensin del programa. El ejemplo de prototipo anterior sera igualmente vlido si se escribiera como: int Mayor(int, int); Esto slo indica que en algn lugar del programa se definir una funcin "Mayor" que admite dos parmetros de tipo int y que devolver un valor de tipo int. No es necesario escribir nombres para los parmetros, ya que el prototipo no los usa. En otro lugar del programa habr una definicin completa de la funcin.

Normalmente, los prototipos de las funciones se declaran dentro del fichero del programa, o bien se incluyen desde un fichero externo, llamado fichero de cabecera, (para esto se usa la directiva #include, que veremos en el siguiente captulo). Ya lo hemos dicho ms arriba, pero las funciones son extern por defecto. Esto quiere decir que son accesibles desde cualquier punto del programa, aunque se encuentren en otros ficheros fuente del mismo programa. En contraposicin las funciones declaradas static slo son accesibles dentro del fichero fuente donde se definen. Definicin de funciones ^ Al igual que hemos visto con las variables, las funciones deben declararse, para lo que usaremos los prototipos, pero tambin deben definirse. Una definicin contiene adems las instrucciones con las que la funcin realizar su trabajo, es decir, su cdigo. La sintaxis de una definicin de funcin es: [extern|static] <tipo_valor_retorno> [modificadores] <identificador>(<lista_parmetros>) { [sentencias] } Como vemos, la sintaxis es idntica a la del prototipo, salvo que se elimina el punto y coma final, y se aade el cuerpo de funcin que representa el cdigo que ser ejecutado cuando se llame a la funcin. El cuerpo de la funcin se encierra entre llaves "{}". La definicin de la funcin se hace ms adelante o ms abajo, segn se mire, es decir, se hace despus que el prototipo. Lo habitual es hacerlo despus de la funcin main. Una funcin muy especial es la funcin main, de la que ya hablamos en el captulo primero. Se trata de la funcin de entrada, y debe existir siempre, ya ser la que tome el control cuando se ejecute el programa. Los programas Windows usan la funcin WinMain como funcin de entrada, aunque en realidad esta funcin contiene en su interior la definicin de una funcin main, pero todo esto se explica en otro lugar. Existen reglas para el uso de los valores de retorno y de los parmetros de la funcin main, pero de momento la usaremos como int main() o int main(void), con un entero como valor de retorno y sin parmetros de entrada. El valor de retorno indicar si el programa ha terminado sin novedad ni errores retornando cero, cualquier otro valor de retorno indicar un cdigo de error. Estructura de un programa C++ ^ La estructura de un programa en C o C++ quedara as: [directivas del pre-procesador: includes y defines] [declaracin de variables globales]

[prototipos de funciones] [declaraciones de clases] funcin main [definiciones de funciones] [definiciones de clases] Tambin se puede omitir el prototipo si se hace la definicin antes de cualquier llamada a la funcin, es decir, en la zona de declaracin de prototipos. Esto se puede hacer siempre, sin embargo no es muy recomendable como veremos a lo largo del curso. Para no dejar las cosas "a medias", podemos ver una posible definicin de la funcin "Mayor", que podra ser la siguiente: int Mayor(int a, int b) { if(a > b) return a; else return b; } Estructuras ms complejas Los programas complejos se escriben normalmente usando varios ficheros fuente. Estos ficheros se compilan separadamente y se enlazan todos juntos. Esto es una gran ventaja durante el desarrollo y depuracin de grandes programas, ya que las modificaciones en un fichero fuente slo nos obligarn a compilar ese fichero fuente, y no el resto, con el consiguiente ahorro de tiempo. La definicin de las funciones y clases puede hacerse dentro de los ficheros fuente o tambin pueden enlazarse desde bibliotecas compiladas previamente. En C++ es obligatorio el uso funciones prototipo, y aunque en C no lo es, resulta altamente recomendable.

4.8 USO Y MANTENIMIENTO (CON EJEMPLO). El mantenimiento tambin es ms difcil y costoso que con lenguajes de ms alto nivel. El cdigo en C se presta a sentencias cortas y enrevesadas de difcil interpretacin. Aunque el lenguaje admite cdigo escrito de forma fcilmente legible, si no se siguen normas en el equipo de programacin algunos programadores pueden acabar escribiendo cdigo difcil de leer. Esto complica la revisin y el mantenimiento. C no dispone de sistemas de control automticos y la seguridad depende casi exclusivamente de la experiencia del programador. La mayor parte de los problemas de seguridad en los sistemas informticos actuales deriva de haber sido realizados en C. El fallo de seguridad clsico consiste en que algunas entradas de informacin al programa no se comprueban en longitud. Si un atacante introduce datos lo bastante grandes puede provocar la sobreescritura de cdigo en la pila del programa e incluso llegar a forzar la ejecucin de cdigo pernicioso. Los lenguajes de tipo dinmico cuentan con controles de gestin de memoria y de entrada de datos automticos. Por estas razones, los directores de desarrollo han de sopesar la ventaja en eficiencia de un buen programa en C frente a la mayor duracin del trabajo y los riesgos de seguridad y estabilidad. Han de tener en cuenta adems, que los equipos bajan de precio con el tiempo mientras que el coste de los programadores aumenta. En equipos de trabajo con poca experiencia en C, se desaconseja su uso porque el tipo de problemas y errores al

que el programador se enfrenta hace ms difcil aprender C sobre la marcha que en otros lenguajes.

Variantes Desde el inicio del lenguaje han surgido varias ramas de evolucin que han generado varios lenguajes: Objective-C es un primer intento de proporcionar soporte para la programacin orientada a objetos en C, de escasa difusin, pero actualmente usado en Mac OS X y GNUstep. C++ (pronunciado C Plus Plus) diseado por Bjarne Stroustrup fue el segundo intento de proporcionar orientacin a objetos a C y es la variante ms difundida y aceptada. Esta versin combina la flexibilidad y el acceso de bajo nivel de C con las caractersticas de la programacin orientada a objetos como abstraccin, encapsulacin y ocultacin.

Tambin se han creado numerosos lenguajes inspirados en la sintaxis de C, pero que no son compatibles con l: Java, que une una sintaxis inspirada en la del C++ con una orientacin a objetos ms similar a la de Smalltalk y Objective C. JavaScript, un lenguaje de scripting creado en Netscape e inspirado en la sintaxis de Java diseado para dar a las pginas web mayor interactividad. A la versin estandarizada se la conoce como ECMAScript. C# (pronunciado C Sharp) es un lenguaje desarrollado por Microsoft derivado de C/C++ y Java.

Proceso de compilacin La compilacin de un programa C se realiza en varias fases que normalmente son automatizadas y ocultadas por los entornos de desarrollo:

1. Preprocesado consistente en modificar el cdigo fuente en C segn una serie de


instrucciones (denominadas directivas de preprocesado) simplificando de esta forma el trabajo del compilador. Por ejemplo, una de las acciones ms importantes es la modificacin de las inclusiones (#include) por las declaraciones reales existentes en el archivo indicado. Compilacin que genera el cdigo objeto a partir del cdigo ya preprocesado. Enlazado que une los cdigos objeto de los distintos mdulos y bibliotecas externas (como las bibliotecas del sistema) para generar el programa ejecutable final.

2. 3.

[editar] Ejemplo de cdigo El siguiente programa imprime en pantalla la frase "Hola Mundo" (C99). # include <stdio.h> // necesario para utilizar printf() int main(void) { printf("Hola Mundo\n"); // return 0 implcito en C99 para main().

} El siguiente escribe "Hola Mundo" en C89 /* comentarios con '//' no permitidos en C89, s en C99 */ # include <stdio.h> /* necesario para utilizar printf */ main() /* tipo 'int' de retorno implcito */ { printf ("Hola Mundo\n") ; return