You are on page 1of 48

Programacin C++

Adolfo J. Milln

1.7.4 Eventos
1 Sinopsis Como sealbamos en la Introduccin a la POO ( 1.1), los componentes bsicos de los programas actuales son los objetos, que representan abstracciones y tienen dos tipos de componentes: propiedades y mtodos. Las propiedades representan magnitudes que representan a su vez "propiedades" del objeto (valga la redundancia). Por ejemplo, una propiedad puede representar el color de fondo de una ventana; el saldo de una cuenta, o el estado de una lnea de comunicacin. Por su parte los mtodos representan "acciones" que se ejecutan sobre el objeto, cuyo resultado puede ser de cualquier tipo, incluyendo devolver un valor. Por ejemplo, devolver el valor de una propiedad (saldo de una cuenta), alterarlo (cambiar el color del fondo de una ventana) o cerrar un dispositivo de comunicacin. En general la sucesin de acciones (invocacin de mtodos) que se realiza a lo largo de un programa, viene determinada por la estructura de su cdigo. Pero la totalidad de los programas que corren en un sistema moderno son interactivos, en el sentido que su comportamiento puede ser influido desde el exterior (aunque sea para abortar su ejecucin). El exterior inmediato del programa est representado por el Sistema Operativo que lo alberga en su seno. El exterior lejano puede ser el operador que acta sobre el Sistema a travs de un dispositivo (un teclado o un ratn) o un dispositivo que acta sin intervencin de ningn operador. Por ejemplo, una lnea de comunicaciones que cambia de estado. En el lenguaje de los Sistemas Operativos a estos sucesos captados por el Sistema se los denomina eventos. Segn su tipo los eventos pueden ser procesados ntegramente por el SO o trasladados a los programas que corren bajo su control en forma de mensajes. Estos mensajes son interpretados por el programa como una peticin para que ejecute algunos de sus mtodos. Precisamente la estructura de un programa Windows moderno se basa en un bucle en el que el programa interroga constantemente al Sistema a la espera de mensajes, y en una larga cadena de sentencias condicionales (del tipo if ... else) en la que toma diversas acciones segn el mensaje recibido. Segn su origen, los eventos se dividen en dos grandes categoras: Eventos de usuario Eventos de Sistema

Con independencia de su denominacin, BC++ comprueba si se ha asignado algn cdigo para manejar ese evento. Si se ha asignado, se ejecuta dicho cdigo, en caso contrario no ocurre nada.

2 Eventos de usuario Los eventos de usuario son acciones que tienen su origen en el usuario del programa. Ejemplos de este tipo son OnClick (el usuario pulsa el botn del ratn), OnKeyPress (el usuario pulsa una tecla del teclado) y OnDblClick (el usuario pulsa dos veces el botn del ratn), Etc. Este tipo de eventos estn siempre relacionados con alguna accin del usuario.

3 Evento de Sistema Este tipo de eventos son aquellos que se inician en el Sistema Operativo. Por ejemplo, OnTimer (el temporizador puede generar uno de estos eventos a intervalos de tiempo determinados), el evento OnCreate (un componente ha sido creado), OnPaint (un componente o ventana necesita ser redibujado), Etc. Por lo general los eventos de Sistema no tienen su origen directo en ninguna accin del usuario.

4 Corolario Desde el punto de vista de la programacin C++, el tratamiento de eventos no es una cuestin del lenguaje, sino de la programacin C++ "para" un sistema Operativo concreto. Por ejemplo Linux o Windows; razn por la cual no ahondaremos aqu en un tema que en cualquier caso no corresponde a un curso general de C++, sino a otro manual que podramos denominar "Programacin C++ para Windows, Linux, etc". Al estudiante del lenguaje C++ le basta saber que en el caso de los programas C++, estos mensajes entre el Sistema y la aplicacin se reciben en ciertas funciones muy curiosas, denominadas exportables o "callback", que tienen la peculiaridad de que adems de la propia aplicacin, tambin pueden ser invocadas por el Sistema, que puede de este modo pasar a la aplicacin informacin sobre los eventos que le conciernen ( 1.4.4b2a).

1.7.5 Programacin Windows


1 Sinopsis Lo que podramos denominar programacin Windows, es decir, la redaccin de programas destinados a correr en los Sistemas Operativos de Microsoft, no es un asunto exclusivo de C++. De hecho, estas aplicaciones pueden ser escritas en muchos otros lenguajes [1]. Sin embargo, la programacin que podramos llamar "nativa" de Windows, la que maneja directamente la API, es C. En realidad, y por razn de sus orgenes, la API est escrita y estructurada para ser utilizada desde el lenguaje de K&R, aunque tambin puede utilizarse C++ para este menester [2]. El resto de lenguajes de alto nivel utilizados en aplicaciones Windows, utilizan una capa ("Layer") de software ms o menos gruesa, interpuesta entre la APIy el lenguaje en s. Esta ltima aproximacin tiene la ventaja de que los detalles sucios y prolijos de la programacin a bajo nivel, que exige tratar con la API, quedan ms o menos ocultos al programador. De esta forma la programacin de aplicaciones resulta ms cmoda y rpida. Sin embargo, en determinados casos la ventaja se transforma en dificultad. Sobre todo, cuando se pretende

realizar ciertas operaciones, o controlar determinados detalles cuyo soporte no est del todo previsto, o lo est de forma deficiente en el lenguaje utilizado [7]. Nota: la posicin al respecto puede sintetizarse en las palabras de Mark Finocchio, ingeniero de Microsoft: "While it's more convenient to program the controls using the Microsoft Foundation Classes (MFC) or Visual Basic, you must know what's happening behind the scenes to really understand how the controls work. SDK programming is more time-consuming, but it gives you power, speed, understanding, and flexibility " . Microsoft System Journal Julio 1998 "Control Spy Exposes the Clandestine Life of Windows Common Controls". En lo que sigue comentaremos brevemente los aspectos ms notables del esqueleto de una aplicacin C/C++ para Windows en su forma nativa. Es decir, utilizando directamente los recursos de la API del Sistema.

2 Un programa mnimo El equivalente C/C++ para Windows del conocido "Hola mundo" podra ser algo as: #include <windows.h> int WINAPI WinMain (HINSTANCE hT, HINSTANCE hP, LPSTR lp, int nF) { MessageBox(NULL, "Hola mundo!", "Mi primer programa", MB_OK); return 0; } 2.1 Compilacin Antes de entrar en detalles sobre el programa, comentaremos brevemente el proceso de compilacin. Los detalles concretos para construir el ejecutable, dependen del compilador ( 1.4.0). En nuestro caso supondremos que tenemos Borland C++ 5.5 para Window 32 en la unidad E: con el siguiente esquema de directorios: E:\BorlandCPP\Bin

Ficheros binarios (.exe y .dll)

E:\BorlandCPP\Include Ficheros de cabecera (.h) E:\BorlandCPP\Lib

Libreras (.obj y .lib)

Suponiendo que el fuente anterior lo tenemos en D:\LearnC\main.cpp, utilizando una ventana DOS de Windows, nos situamos en el directorio de trabajo (donde reside el fuente): C:\Windows>D: D:\>cd LearnC D:\LearnC> A continuacin establecemos el camino de bsqueda ("Path"), de forma que nuestras rdenes encuentren los binarios correspondientes:

D:\LearnC>set PATH=E:\BorlandCPP\Bin;C:\WINDOWS;C:\WINDOWS\COMMAND;%path% Hecho esto, ya podemos compilar con la orden: bcc32 -IE:\BorlandCPP\Include -LE:\BorlandCPP\Lib -P -RT -c main.cpp bcc32.exe es el compilador; el significado de los argumentos es el siguiente [3]: -P Compilar como C++ con independencia de la extensin del fuente (.c; .cpp etc) -c Solo compilar -RT Incluir informacin RTTI. Despus de algunos mensajes de aviso, anunciando que los parmetros hT, hP, lp y nF de WinMain no son utilizados, se produce el objeto correspondiente (main.obj) en el directorio de trabajo. La orden al enlazador para que construya un ejecutable Windows32 es la siguiente: ilink32 -LE:\BorlandCPP\Lib -c -Gn -aa -Tpe c0w32.obj main.obj, , , import32.lib cw32.lib ilink32.exe es el enlazador. El significado de los argumentos [4]: /aa Construir una aplicacin Windows 32-bit /c Interpretar maysculas/minsculas ("case") como significativo en los smbolos /Gn Desabilitar enlazado incremental /Tpe Construir un ejecutable .EXE El resultado es la creacin del fichero c0w32.exe en el directorio de trabajo con nuestra aplicacin. Al ejecutarlo, aparece en el escritorio una ventana como la de la figura adjunta. Pulsando sobre el botn OK, el proceso termina y se cierra la ventana.

Fig. 1
2.2 Comentario En los entornos grficos, como pueden ser Windows de Microsoft, KDE de Linux, o Mac OS de Apple, un icono o una ventana, representan la metfora de un proceso. En el caso de la ventana, se trata siempre de un proceso en ejecucin, que en el caso del escritorio (la ventana maestra), representa el proceso que controla la interaccin (interfaz) del usuario con el Sistema. Esta ventana es creada automticamente al arrancar el Sistema y sirve de base para las ventanas del resto de aplicaciones. Todas las dems son "hijas" de este proceso maestro. Por lo general, cada aplicacin de usuario (procesador de textos, hoja de clculo, cliente de correo, etc. etc.) crea su propia ventana, que deriva del escritorio ("main window" de la aplicacin), que a su vez puede crear otras ventanas-hijas (aqu se denominan "child windows") de las que existen tipos muy diversos. Las aplicaciones Windows suelen incluir distintas ventanas-hijas, algunas de las cuales reciben nombres especiales. Por ejemplo, la "main window" de una aplicacin suele incluir las siguientes: barra de ttulo ("title bar"); barra de men; ventana de men ("system menu"); botones de

minimizar, maximizar; restaurar y cerrar; barras de desplazamiento horizontal y vertical ("scroll bars") y rea de cliente ("cliente area"). Nota: en realidad, en Windows, casi cualquier cosa se materializa en una ventana. Por ejemplo, en la figura 1, el botn etiquetado "OK" es una child window de la ventana principal. Otra cuestin destacable respecto a las ventanas, es que pueden ser clasificadas en dos grandes grupos segn su comportamiento respecto a la ventana ascendiente o propietaria (que las ha creado); se denominan respectivamente ventanas modales y no modales ("modeless"). Lasventanas modales deben ser cerradas para que la aplicacin anfitriona pueda continuar su ejecucin. Diramos que retienen el foco hasta que son cerradas. Son, por ejemplo, esos mensajes de aviso que no dejan hacer nada ms en la aplicacin hasta que se han cerrado. En cambio, lasventanas no modales (modeless), permiten cambiar el foco a cualquier otra ventana, incluyendo su propia ascendiente, antes de que ellas mismas sean terminadas. Por ejemplo, esas ventanas de encontrar/reemplazar en los editores, que permiten escribir en el texto original mientras la ventana aparece superpuesta. Nota: existe una variedad de las modales, las denominadas modales de sistema ("System modal"), que no permiten hacer nada ms, ni siguiera pasar a otra aplicacin, mientras que se han cerrado. Seran por ejemplo esas ventanas de aviso de situaciones crticas, que deben ser cerradas para poder seguir usando el sistema.

Adems de su tradicional funcin de "salida" de datos, propia de las aplicaciones modo texto (de consola), la ventana de las aplicaciones grficas es tambin un dispositivo de entrada de datos para el proceso correspondiente. Esta entrada puede realizarse con auxilio del ratn; con un lpiz (sealador), o directamente con el dedo en el caso de las pantallas tctiles [5]. Esta neva forma de interaccin, ha desarrollado nuevos paradigmas que son ya de dominio pblico. Por ejemplo, el de apuntar y marcar ("Point and click"), o el de arrastrar y soltar ("Drag and drop"). En nuestro caso, debido al diseo esqueltico de la aplicacin, la funcionalidad de su ventana es mnima. Se reduce a la posibilidad de arrastrarla a cualquier punto del escritorio, y a cerrarla (terminar la aplicacin) pulsando con el ratn en su nico botn. Desde el punto de vista de la programacin C/C++, el primer punto a destacar, es el fichero de cabecera empleado: <windows.h> [6]. Es tpico de las aplicaciones Windows y bsicamente se encarga de incluir otros ficheros de cabecera adicionales. Sus nombres pueden variar segn el compilador, pero por ejemplo, son comunes <stdarg.h>; <windef.h>; <winbase.h>; <wincon.h>; <wingdi.h>; <winuser.h>; <winnls.h>; <winver.h> entre otros. La siguiente singularidad es la inexistencia de funcin main ( 4.4.4). En su lugar se utiliza WinMain con el mismo propsito. Los programas que deban correr bajo Windows utilizando la API de su interfaz grfica (GUI), requieren que el mdulo de inicio invoque una funcin con este nombre en sustitucin de la tradicional main (en realidad, es un "capricho" de los diseadores de Redmond). La funcin WinMain, que representa el punto de entrada a estas aplicaciones, acepta un cierto nmero de parmetros que tampoco se corresponden con los usuales de main. Por ejemplo, el primer argumento no es "argument count", ni el segundo una matriz de punteros a carcter . Naturalmente esto se aparta del Estndar C++, y representa otra de las peculiaridades establecidas por Microsoft para su Sistema Operativo.

Nota: estos parmetros son los mismos en las aplicaciones Windows de 16 bits que en las de 32 bits. Al programador habitual de C/C++ estndar, tambin le llaman de inmediato la atencin la cantidad de "tipos" particulares que aparecen en el fuente. En nuestro ejemplo encontramos 3 de ellos: WINAPI; HINSTANCE y LPSTR. Se les identifica fcilmente porque, como es usual en C/C++, estn en maysculas (WINAPI no es un "tipo" sino una convencin de llamada para la funcin 4.4.6a). El asunto es que la programacin Windows ha consagrado su propio estilo de notacin con dos particularidades: la primera es la notacin hngara para las variables ( 3.2.2). Aunque su adopcin no es obligatoria, representa una gran ayuda una vez habituados a ella. La segunda es la utilizacin de sus propios identificadores para los tipos, mediante los correspondientes typedef y #define incluidos en los ficheros de cabecera ( Ejemplos). Es igualmente caracterstica de la programacin Windows la profusin de constantes manifiestas ( 1.4.1a). Se identifican porque tambin estn en maysculas, y porque su tercer o cuarto carcter suele ser el guin bajo ("underscore"); en nuestro caso es MB_OK. Tales constantes se suelen emplear como argumentos de funciones que, como es el caso de MessageBox, que representan la invocacin de utilidades y funcionalidades de la GUI. Estas funciones se encuentran alojadas en libreras dinamicas (.dll) que son enlazadas junto con la aplicacin. En la mayora de los casos estas constantes representan valores numricos enteros, y su nomenclatura se ajusta a ciertas pautas, de forma que las del mismo tipo tienen el mismo prefijo. A continuacin se muestran algunas:

Prefijo Uso
CS_ CW_ DT_

Definicin de estilo de ventana Opciones de ventana Opcin de dibujo de texto

IDI_ Tipo de icono IDC_ Tipo de cursor MB_ SB_ WM_ WS_

Opciones de ventana de mensaje Eventos ocurridos en las barras de deslizamiento ("Scroll Bars") Mensaje del Sistema (Windows) a la aplicacin Estilo de ventana

Por ejemplo, el ltimo argumento de MessageBox indica el estilo de la ventana, incluyendo las imgenes que pueden incluirse; los botones; cual de ellos estar activado por defecto (caso de haber ms de uno) y otros detalles. Por ejemplo, respecto a MessageBox, el manual de la GUI seala lo siguiente (es un resumen del original ingls):

Valores relativos a los botones: MB_ABORTRETRYIGNORE The message box contains three push buttons: Abort, Retry, and Ignore. MB_OK The message box contains one push button: OK. This is the default. MB_OKCANCEL The message box contains two push buttons: OK and Cancel. MB_RETRYCANCEL The message box contains two push buttons: Retry and Cancel. MB_YESNO The message box contains two push buttons: Yes and No. MB_YESNOCANCEL The message box contains three push buttons: Yes, No, and Cancel. Valores relativos a los iconos que se incluirn en la ventana: MB_ICONEXCLAMATION An exclamation-point icon appears in the message box. MB_ICONINFORMATION, An icon consisting of a lowercase letter i in a circle appears in the message box. MB_ICONQUESTION A question-mark icon appears in the message box. MB_ICONSTOP, A stop-sign icon appears in the message box. Valores relativos al botn por defecto: MB_DEFBUTTON1 The first button is the default button. MB_DEFBUTTON2 The second button is the default button. MB_DEFBUTTON3 The third button is the default button. MB_DEFBUTTON4 The fourth button is the default button. Etc. En ocasiones, como la presente, estos valores no son excluyentes, de forma que pueden combinarse para conseguir el comportamiento deseado. Esto se realiza componiendo el valor resultante mediante una expresin OR inclusivo de los valores individuales ( 4.9.3). En nuestro caso hemos Fig. 2 utilizado un solo argumento (MB_OK) que adems es el valor por defecto. Pero podramos utilizar una valor compuesto. Por ejemplo, utilizar la siguiente invocacin: MessageBox(NULL, "Hola mundo!", "Mi primer programa", MB_YESNOCANCEL | MB_ICONSTOP | MB_DEFBUTTON3); Cambiando la invocacin a MessageBox en el fuente original y compilando de nuevo, se produce la ventana de la figura 2.

1.8 Estructura de la informacin


1 Introduccin

En su aspecto ms general, el arte de la programacin de ordenadores ( 1.4) tiene mucho que ver con eso que llamamos la "inteligencia" humana; los procesos de abstraccin; la capacidad de imaginar un problema y sus posibles soluciones (hemos dicho que programar es formular la solucin de un problema). El proceso suele ir de lo general a lo particular y viceversa (de las ideas abstractas a los detalles concretos), en un proceso que se realimenta constantemente. En una primera fase, el programador concibe una imagen del problema (el primer paso es "comprender el problema"), sin embargo, para formular la solucin, se necesita un vehculo o soporte sobre el que construirla. En nuestro caso conocer un lenguaje de programacin, lo que en el fondo tiene un doble sentido: el primero y ms importante, es conocer que herramientas ofrece. Estas herramientas funcionan como ideas-soporte; como ladrillos con los que construir la solucin como si fuese una construccin material. Esto significa sobre todo, que el programador piensa en funcin de las herramientas disponibles. Sin ellas es incapaz de imaginarse ninguna solucin concreta. El segundo significado es mucho menos importante (conceptualmente hablando); supone el conocimiento de una serie de reglas formales de utilizacin de los elementos del lenguaje. Sera la fase de mera codificacin, tarea para la que existen herramientas cada vez ms eficaces. Por ejemplo, la amplia coleccin de herramientas RAD [1] que componen las modernas "suites" de desarrollo. La situacin es comparable a la de un hipottico Robinsn que en una isla desierta tuviese que resolver el problema de su alojamiento. Tiene conciencia del problema y de su solucin en abstracto: "un refugio". Sin embargo, para pensar algo concreto necesita antes explorar la isla, conocer que posibilidades ofrece. Existen cuevas naturales?, Madera?, Restos de naufragios? Algo que pueda adaptarse? etc. Evidentemente la forma mental de su refugio depender de los medios disponibles; posteriormente, la construccin en s, ser cuestin de detalle y de su propia habilidad manual.

2 Datos y algoritmos "Mustreme su cdigo y esconda sus estructuras de datos, y continuar intrigado. Mustreme sus estructuras de datos y generalmente no necesitar ver su cdigo; resultar evidente". Eric S. Raymond "La Catedral y el Bazar" es.wikisource.or En informtica, las ideas-soporte a que aludamos son principalmente de dos tipos: Relativas a la informacin y a su manipulacin (los datos y losalgoritmos respectivamente). En lo que concierne a los primeros (los datos), existen multitud de formas de organizarlos; a estas formas las denominamos estructuras de datos. En cuanto a los segundos, existen un nmero casi infinito de algoritmos, pero en lo que aqu nos ocupa, tienen especial importancia los relacionados con el acceso a la informacin, es decir, los relacionados con su almacenamiento y recuperacin. Algoritmos que Shildt denominamecanismos de datos ( 2). Generalmente se considera que estos mecanismos realizan tres tipos de operaciones: Insercin, borrado ybsqueda de la informacin en la estructura correspondiente. Nota: La denominada STL ("Standar Template Library"), que es parte esencial de la Librera C++ Estndar ( 5.1) es en realidad un conjunto fascinante de estructuras de datos (aqu llamados contenedores) y de algoritmos para su manejo. Con su ayuda se han construido las aplicaciones ms grandes y exigentes que se hayan utilizado nunca en informtica [5].

Las estructuras y mecanismos de datos han sido muy estudiados; constituyen en s mismos dos

mundos dentro de la informtica, y dado que son las herramientas para construir un programa, adems de la experiencia, es conveniente disponer del conjunto ms completo posible de ellas (en este aspecto la programacin se parece al bricolaje). Por ejemplo, si nos referimos a los algoritmos, los mtodos de ordenacin ("Sort") o de construccin de ndices (que viene a ser equivalente), han sido muy estudiados, de forma que se conoce cuales son los ms eficientes para cada caso (algunos incluso patentados). Si el lenguaje no los tiene preconstruidos, tendremos que fabricarlos manualmente con los medios disponibles. En este aspecto, un lenguaje es tanto mejor cuanto ms abstractas sean las herramientas que nos ofrezca (estructuras y mecanismos de datos). Lo que significa que estarn ms cercanas a la idea que tiene en mente el programadorhumano y ms alejadas de la forma concreta que adoptarn en la mquina. Este es precisamente el significado de la expresin "Lenguaje de alto o bajo nivel", el mayor o menor grado de proximidad que ofrezcan sus herramientas con las ideas (abstracciones) en la mente humana. Al abordar un problema y decidirse por una estructura o mecanismo de datos concreto, hay un aspecto importante que debe ser conocido y tenido en cuenta por el programador. Es el hecho de que unas estructuras son ms adecuadas para determinados mecanismos que otras. Dicho en otras palabras: las relaciones entre las estructuras de datos y los algoritmos que las manipulan son muy significativas. Por ejemplo: determinadas estructuras son muy adecuadas para operaciones de insercin y recuperacin, de forma que los algoritmos que realizan estas operaciones son muy simples y rpidos. En cambio estas mismas estructuras pueden ser inadecuadas para buscar informacin en su interior. Resulta por tanto, que la relacin de cada tipo de estructura de datos con los mecanismos bsicos, insercin, borrado y bsqueda, es muy diferente, y debemos pensar detenidamente que relacin tiene nuestra estructura con los mecanismos bsicos (como la usaremos). Tanto las estructuras como los mecanismos de datos son importantes. De hecho, en el diseo de programas caben dos enfoques, segn las consideraciones iniciales consideren prioritarias a unas u otros. En algunos casos la eleccin de la estructura de datos es el primer considerando del diseo, ya que la experiencia ha indicado que el trabajo total de desarrollo y la calidad del resultado dependen grandemente de la idoneidad de las estructuras utilizadas. Una vez elegidas, la eleccin del mecanismo es una consecuencia directa de la decisin anterior. En otros casos la lnea de razonamiento sigue el camino inverso; se deciden las estructuras porque ciertas operaciones crticas utilizan algoritmos que funcionan mejor en esas estructuras. La preponderancia de uno u otro criterio se deja sentir incluso en el diseo de los lenguajes de programacin e incluso de los sistemas operativos [2]. Los lenguajes orientados a objetos (como C++) estn diseados alrededor del concepto estructura de los datos, mientras en otros, por ejemplo Lisp, el diseo se centra en el aspecto algortmico. Al tratar de las plantillas ("Templates"), se comenta ms ampliamente la relacin entre datos y algoritmos ( 4.12). Nota: Tanto en la programacin procedural (tradicional) como en la POO, disear un programa supone construir un modelo. Este modelo goza de la propiedad de ser "ejecutable", mostrando un comportamiento distinto en cada ocasin segn las condiciones de partida o las suministradas durante la ejecucin. El proceso de diseo comienza identificando ciertos elementos que son considerados piezas elementales del modelo, a los que denominamos "Datos". A estos datos se les aade cierta funcionalidad que les es propia. En la POO, este proceso conduce a la definicin de las clases que compondrn el modelo. El resto del diseo consiste en establecer las relaciones de estos elementos individuales entre s, y con respecto a las condiciones de entrada.

En el captulo 5 dedicado a la Librera Estndar, se tratarn estos asuntos de forma ms detallada, concretando cuales son los puntos de vista del C++ y las potentes herramientas que ofrece al respecto; tanto para albergar informacin como para su manipulacin.

3 Estructura Fsica y estructura Lgica Al tratar de las estructuras y contenedores de datos, es conveniente tener algunas ideas bsicas claras y precisas sobre los mecanismos involucrados. La estructura lgica se corresponde con la idea que en principio tiene el programador sobre como estn organizados los datos, y coincide aproximadamente con la forma en que son manipulados los datos por el programa de alto nivel. En la concepcin de la estructura lgica, el programador puede razonar ms o menos en los siguientes trminos: "Voy a crear un fichero de clientes donde los datos de cada cliente estarn agrupados en un registro. Posteriormente acceder los registros por nmero de cliente (que ser nico) o por nombre, para lo que estarn ordenados alfabticamente (construir un ndice con el cdigo de cliente y otro de nombres)...". Si est habituado a la programacin de bases de datos con herramientas de alto nivel, quizs su razonamiento sea el siguiente: "Voy a crear una tabla de clientes donde incluir los datos de cada cliente, comenzando por una columna para el cdigo que ser el ndice principal (ser un INT UNSIGNED). Tambin crear un campo "nombre" que ser un VCHAR NOT NULL UNIQUE...". En uno u otro caso, la estructura (se llame "fichero" o "tabla") es una unidad lgica que se compone una multitud de elementos individuales (se llamen "registros" o "filas" -segn la cultura del programador-). La estructura as concebida tiene un orden, ya que sus elementos estarn conceptualmente uno detrs de otro. Este orden ser numrico, si el acceso se realiza por cdigo de cliente, o alfabtico de nombres si el acceso se realiza por nombre. A su vez, esta estructura lgica se divide an ms finamente: cada elemento se puede considerar dividido en multitud decampos. Aparte de los ya mencionados para cdigo de cliente y nombre, pueden existir muchos mas: direccin, telfono, saldo, clasificacin financiera, fecha ltima compra, vendedor asignado, etc. etc. Por su parte, la estructura fsica corresponde a la forma en que estn contenidos los datos en la mquina, de la que existen dos versiones: una corresponde a la que adoptan los datos en memoria; la otra a su almacenamiento externo (disco). Ambos esquemas son distintos. Resulta evidente que la estructura fsica de datos en los almacenamientos externos no se corresponde exactamente con estructura lgica. En principio, el fichero o tabla de clientes antes mencionado, puede estar representado fsicamente por varios ficheros que pueden ser multivolumen. Es decir: ocupar ms de un volumen lgico ( H8.1.2c1) en la mquina que los alberga. Si son aplicaciones de red, pueden estar incluso en mquinas remotas, distintas de la que ejecuta la aplicacin. Adems, aunque nos figuramos la estructura lgica es un todo continuo (suponemos que despus de un cliente sigue otro), sabemos que la estructura fsica correspondiente, incluso si se trata solo de un fichero, est compuesta por trozos "clusters" que pueden estar dispersos en el disco. La estructura lgica est ordenada (por nmeros o por nombres en nuestro ejemplo). En cambio, la estructura fsica puede estar construida simplemente por el orden "natural" es decir, de creacin de los propios registros. Generalmente, la "apariencia" de ordenacin es el resultado de un proceso complejo que utiliza ndices, tablas y punteros, para proporcionarnos un acceso ordenado a una estructura mucho ms catica. Como queda dicho, los datos son manejados por el programador y el programa (que es la expresin concreta de las ideas de aquel) en trminos de esta estructura lgica. En lo tocante a este aspecto, las herramientas que ofrezca el lenguaje o entorno de programacin, sern de mayor nivel cuanto mayor sea la distancia con que pueda ser manejada la estructura lgica de datos respecto de su verdadera estructura fsica. Precisamente el manejo de tales estructuras

("Databases"), ha originado toda una rama de la industria del software que ha alcanzado un alto nivel de sofisticacin y especializacin. En proyectos grandes es usual manejar los datos a travs de estas herramientas. En estos casos el lenguaje C++ las utilizara a travs de interfaces. Por ejemplo, interfaces con motores relacionales (SQL). Sin embargo, es rara la aplicacin en que el programador no deba manejar uno o varios ficheritos (por ejemplo con parmetros de configuracin), a un nivel "relativamente" bajo, haciendo uso de las herramientas (relativamente simples) que ofrece la Librera Estndar. Tambin es usual que deba manejar, tambin a bajo nivel, alguna estructura de datos en memoria, por ejemplo una matriz, mediante tcnicas totalmente distintas de las que se utilizaran con un fichero de disco. Como resumen, podemos afirmar que el programador, al menos el programador C++, puede concentrarse en la estructura lgica, pero sin olvidar de vez en cuando mirar la estructura fsica con el rabillo del ojo. Como hemos sealado antes, existen distintos tipos de estructuras de datos (lgicas y fsicas) que se diferencian grandemente en su grado de adecuacin a diversas formas de almacenamiento y recuperacin de la informacin, por lo que es conveniente que el programador tenga ciertas nociones al respecto. Inicio.

[1] RAD ("Rapid Application Development") Herramienta de programacin rpida de aplicaciones. Se caracterizan por poseer entornos grficos en los que se dispone de gran cantidad de objetos predefinidos, componentes y controles necesarios para el diseo de las aplicaciones. Estos elementos pueden estar en las denominadas paletas de componentes (Delphi), Caja de herramientas (Visual Basic y Visua C++), etc. Adems permiten la gestin integrada de grandes proyectos software, encargndose de todos los detalles relativos a su construccin (compilacin selectiva, enlazado incremental, etc). Su punto fuerte es poder disear las interfaces (una de las partes ms tediosas de la programacin de aplicaciones) con simples operaciones de arrastrar y soltar. Tambin cuentan con componentes o mdulos que realizan tareas completas, lo que reduce el tiempo que el programador tiene que dedicar a esta parte de la aplicacin. Sin embargo esto tiene su penalizacin o contrapartida, que se manifiesta en un cierto alejamiento del cdigo. [2] La propia Microsoft califica la interfaz de usuario ("Shell") de sus sistemas Windows como de diseo "datacntrico". Es decir, que en vez de estar orientado a las aplicaciones, su diseo se focaliza en los datos y a las operaciones relacionadas con su manipulacin. Como resultado, la interfaz permite al usuario recorrer datos y documentos, incluso editarlos, sin que previamente haya tenido que seleccionar la aplicacin adecuada. La razn aducida es que este diseo, permite al usuario concentrarse en la informacin y en lo que quiere hacer con ella, antes que en las aplicaciones que sern necesarias y en como lo harn. [5] Adems de los recursos de la Librera Estndar, las grandes suites de programacin C++ (Borland y MS por ejemplo) incluyen sus propias herramientas. En especial, MS VC++ dispone de una serie de clases predefinidas en su MFC ("Microsoft Foundation Class -Library-") que permiten manejar fcilmente diversos tipos de estructuras de datos. Algunos programadores las consideran mejores que las correspondientes de STL (es una cuestin de gustos), pero el programador o entidad que deba acometer un proyecto medianamente importante no debe olvidar tres cuestiones: las herramientas de la MFC son exclusivamente para programar en Windows; no son fcilmente portables, y no son estndar.

1.8 Estructura de la informacin (II)

4 Estructuras lgicas Al pensar en un "contenedor" de informacin la idea ms simple es la de un saco que lo contenga todo, pero es fcil intuir que esta forma no es demasiado adecuada para recuperar la informacin. El cajn de sastre puede ser cmodo para almacenar, no para recuperar. Desechada la anterior, la segunda idea sera tratar de almacenar juntos datos homogneos (aunque no hay inconveniente terico para que los tales datos sean todo lo complejos que se desee). Por ejemplo, en una aplicacin real se almacenaran separadamente los datos de clientes; de proveedores, de artculos, etc. A su vez cada uno de estos almacenamientos tendran informacin compleja aunque relacionada. Por ejemplo, el fichero o tabla de clientes contendra nombre, domicilio, telfono, direccin, e-mail, web, etc de cada cliente. Lo mismo con los proveedores, artculos, etc. A estos conjuntos de datos que se almacenan juntos, los denominamos unidades de almacenamiento (generalmente este es el enfoque utilizado). Por ejemplo, siguiendo con el supuesto anterior, almacenamos juntos los datos de clientes, y cada cliente es una unidad de almacenamiento. Aunque pueda estar constituido a su vez por un conjunto muy grande de datos, se graban o borran los datos de un cliente cada vez, esta unidad no es divisible (no puede existir medio cliente, aunque algunos de sus registros si pueden estar vacos). Nota: La unidad de almacenamiento corresponde con el concepto tradicional de registro, o con el de fila, si se utiliza la terminologa de las bases de datos relacionales.

Respecto como estn relacionadas entre s estas unidades de almacenamiento, las estructuras de datos comnmente utilizadas son cuatro: Colas; Pilas; Listas enlazadas y rboles [4] que comentamos en este captulo, y que con variaciones ms o menos sofisticadas dan origen a todas las dems. Nota: Se considera que las tres primeras pertenecen a un grupo denominado estructuras lineales, en el que existen otros tipos, por ejemplo matrices ( 4.3), tablas hash y deques ( 5.1.1). Los rboles pertenecen al grupo de los grafos en el que existen varios subtipos.

4.1 Colas: Las colas ("Queues") son sucesiones de registros [2] contiguos dispuestos de forma que es fcil aadir un nuevo elemento (que se coloca despus del ltimo) y/o acceder o eliminar el primero. La forma en que estn construidas las hace parecerse a una tubera, el primer agua que entra es la primera que sale. Esta forma de acceder a la informacin se denomina FIFO ("First In First Out") primero en entrar primero en salir. Estas entidades corresponden a lo que en matemticas se conoce como lneas de espera, y su estudio terico, conocido como teora de colas, es muy importante en transporte y telecomunicacin (una modalidad de transporte). A ttulo de curiosidad podemos citar que incluso existe un lenguaje de programacin denominado Oroogu, cuyo nico tipo de datos es una cola. Sus caractersticas bsicas pueden sintetizarse cuatro palabras: datos contiguos, ordenacin FIFO.

4.2 Pilas: Las pilas ("Stacks") son igualmente sucesiones de registros contiguos. Podemos imaginar que se van "apilando" sucesivamente uno sobre el otro (de ah su nombre). Esta disposicin hace que sea fcil aadir un nuevo elemento al final, accederlo o eliminarlo. Esta forma de acceso a la informacin se denomina LIFO ("Last In First Out") ltimo en entrar primero en salir. Podemos imaginar que tanto en las colas como en las pilas, insertar o eliminar un elemento intermedio, es un proceso complicado si no imposible.

Sus caractersticas se resumiran en: datos contiguos, ordenacin LIFO.

4.3 Listas enlazadas Las listas enlazadas ("Linked list") son conjuntos de registros conceptualmente contiguos pero que fsicamente no tienen porqu estarlo (aunque lo normal es que si lo estn); su orden lgico no tiene nada que ver con el orden fsico de los elementos en el conjunto. El orden lgico se consigue porque cada elemento de la lista dispone de un puntero que seala al prximo elemento. De esta forma la lista se mantiene ordenada, y es fcil recorrerla en sentido ascendente. Para aadir un nuevo elemento solo hay que establecer en el ltimo un puntero que seale a la posicin del nuevo elemento, que queda de este forma transformado en el ltimo. En la figura anterior se ha representado una de estas listas denominadas simplemente enlazadas. Una variedad de la anterior la constituyen las listas doblemente enlazadas. En este caso, cada elemento dispone de dos punteros, uno al elemento siguiente y otro al anterior. De esta forma la lista puede ser fcilmente recorrida en ambos sentidos, ascendente y descendente. En este tipo de arreglos es muy sencillo insertar o eliminar un elemento en cualquier posicin, al principio, al final o intermedio, solo hay que reorganizar los punteros adecuadamente segn se ve en las figuras. Lo normal es que los punteros acompaen a la informacin contenida en los propios elementos, con lo que evidentemente, en cada elemento, adems de la informacin pertinente, segn el tipo de lista, debe existir espacio adecuado para uno o dos punteros. Las listas simple y doblemente enlazadas son ampliamente utilizadas. Por ejemplo, los sistemas de ficheros de disco utilizan esta tcnica para dar

apariencia de continuidad a trozos (clusters) fsicamente dispersos en la superficie del disco que componen una sola unidad lgica (fichero) [6]. Como se ha sealado, estas estructuras de datos son adecuadas cuando la informacin debe mantenerse ordenada, y ser accedida de forma secuencial con posibilidad de insertar y eliminar elementos en cualquier posicin. El tipo de ordenacin puede ser cualquiera; desde la denominada "natural", que es simplemente la forma en que se han creado y destruido los elementos de la lista (los jvenes al final, los ms viejos al principio), a cualquier otra basada en otro criterio. Por ejemplo alfabtico, segn un campo alfanumrico que suponemos existe en cada elemento. En este caso, antes de insertar un nuevo elemento hay que localizar la posicin que le corresponde; esto solo puede hacerse recorriendo secuencialmente la lista hasta encontrar la posicin adecuada al criterio de ordenacin utilizado. En cuanto a su idoneidad para buscar un elemento en su interior, el caso ms desfavorable supone tener que recorrer la totalidad de la lista antes de localizarlo, pero si utilizamos un nmero suficientemente grande de datos aleatorios, el nmero de pasos necesario tiende a n/2, lo que significa que por trmino medio debe recorrerse la mitad de los elementos de la lista antes de encontrar el elemento [3].

1.8 Estructura de la informacin (III)


4.4 rboles Los rboles son estructuras parecidas a las listas enlazadas ( 1.8), en el sentido que tienen punteros que sealan a otros elementos, pero no tienen una estructura lgica de tipo "lineal" o secuencial como aquellas, sino ramificada. Tienen aspecto de rbol, de ah su nombre (ver figura ). Su estudio desde el punto de vista matemtico pertenece a la teora de grafos; desde el punto de vista informtico son estructuras de datos, lo que significa que cada elemento, denominado nodo u hoja, contiene uno o ms valores. Su estudio corresponde a la teora de bases de datos, y en esta terminologa, los nodos que "cuelgan" de otros, se denominan hijos ("child nodes"). Cada hoja puede tener un mximo de hijos; es lo que se denomina grado mximo del rbol ("maximun degree"). Si no tiene ninguno, se dice que es un nodo terminal. Son especialmente interesantes y tiles los rboles ordenados (denominados B-trees). Esto significa que para su construccin, los nodos que se van agregando no se colocan al azar, colgando de cualquier nodo existente, sino segn un criterio que tiene en consideracin el "valor" de la hoja. Este tipo de estructura se usa extensivamente en las bases de datos [3] y en los sistemas de ficheros [1]. En los b-trees se distinguen varios parmetros que son determinantes en cuanto a su idoneidad como estructuras de datos. El primero es el mximo nmero de hijos (y datos) que puede tener cada hoja; es lo que se denomina grado mximo del rbol ("maximun degree"). El nmero de hijos de una hoja o nodo, puede variar desde ninguno (nodos terminales) al mximun degree. Otro parmetro importante es el nmero mnimo de datos que puede contener un nodo,grado mnimo ("minimun degree"). Este valor es utilizado en los procesos de insercin de nuevos datos, y determina la forma en que se desdoblan los nodos existentes para acomodar los nuevos valores (el conjunto debe permanecer ordenado).

Generalmente cada hoja de un rbol es en s misma una estructura de datos (en el sentido C++ del trmino 4.5). Uno o varios los campos de esta estructura se utilizan para la ordenacin (campos-ndice), y desde luego se exige que exista un criterio de ordenacin para los valores de estos campos. Es decir: que se establezca una regla por la que se pueda determinar de forma inequvoca si dos valores son iguales, o desiguales, y en este ltimo caso cual precede en el orden (este orden suele ser numrico o alfabtico [2]).

4.4.1 rboles binarios Existen varios tipos de rboles, pero con mucho, los ms utilizados son los denominados rboles binarios. Son un caso particular de los B-trees en los que cada nodo puede contener dos datos y tener dos hijos como mximo. Comparten la caracterstica de las listas doblemente enlazadas de que cada elemento tiene dos punteros que sealan a otros dos elementos como mximo (aunque puede no utilizar ninguno o solo uno); comparten tambin la facilidad de insercin de elementos en cualquier posicin, y que la informacin puede mantenerse ordenada, pero aventajan a las listas en que la ordenacin es ms fcil, ya que existen algoritmos muy rpidos para encontrar la posicin de un dato y no es necesario modificar los punteros existentes para insertar un nuevo dato, aunque su eliminacin puede resultar ms problemtica. Aunque el caso tericamente ms desfavorable tambin supone tener que recorrer la totalidad del rbol, para datos aleatorios el nmero de pasos necesario tiende a Log2 n, siendo n el nmero de elementos del rbol. Como se ver a continuacin, las listas simplemente enlazadas pueden considerarse casos extremos de rboles binarios (rboles degenerados). Generalmente, el nmero de pasos necesario para encontrar un dato en una estructura se expresa mediante la denominadaexpresin O mayscula ("Big O notation" en la literatura inglesa). Una expresin como O(n) significa que el nmero de pasos es una expresin lineal del nmero n de elementos de la estructura, mientras que O(log(n)) representa que el nmero de pasos es proporcional al logaritmo de n. Por ejemplo, en una estructura de 1M de nodos, la bsqueda en una pila o cola puede suponer un milln de pasos, mientras que en un rbol pueden ser solo 6 (logaritmo de 1.000.000). Tenga en cuenta que en la prctica, los rboles utilizados no suelen ser binarios, sino que su grado mximo es mayor que 2. En estos casos, la Big O notations indica el nmero de pasos hasta alcanzar el primer encuentro aproximado. A partir de ah suele ser necesaria una bsqueda secuencial sobre un pequeo nmero de nodos hasta encontrar el elemento buscado.

En la figura 7 se muestra un rbol binario de 6 elementos y la nomenclatura utilizada. Como puede verse, adems de los datos, cada elemento tiene dos enlaces: derecho Ed, e izquierdo Ei, que

pueden estar o no ocupados. Los nodos terminales son los que tienen a cero sus dos enlaces (no ocupados).

Por lo general los nodos suelen ser estructuras que adems de otros miembros conteniendo informacin til, tiene dos punteros a estructuras, que son utilizados como enlaces a los otros nodos. Por ejemplo, el diseo C++ de un nodo puede ser el siguiente: struct Nodo { tipoX contenido-de-nodo; Nodo* enlace-izquierdo; Nodo* enlace-derecho; }; En el manejo de rboles es muy comn el empleo de funciones recursivas; en el captulo 4 se muestran algunos ejemplos concretos ( 4.5.8Estructuras auto-referenciadas).

4.4.2 Proceso de creacin Hemos dicho que los rboles son estructuras de datos, generalmente ordenadas; aunque pueden no estarlo, la mayora de sus aplicaciones requieren que lo estn. Al igual que en las listas, el criterio de ordenacin puede ser cualquiera. Sin embargo, es importante sealar que la disposicin final de los nodos depende del orden de creacin. Una vez establecido el criterio de ordenacin que se utilizar, el proceso de construccin es el siguiente: El primer elemento se coloca como nodo raz; a continuacin se aade el segundo elemento, que colgar del puntero derecho Ed (rama derecha) si es mayor que el raz, y del izquierdo Ei en caso contrario (igual o menor). A continuacin se aade el tercero, que se colocar en la rama izquierda si es mayor que el raz y en la derecha si menor o igual. El proceso sigue indefinidamente hasta que se han colocado todos los elementos del rbol.

En la figura 8 se muestra el aspecto de un rbol de 6 elementos, suponiendo un orden de colocacin numrico. Se han colocado elementos con valores 6, 8, 9, 10, 12 y 14 en el orden de creacin siguiente: 10, 8, 9, 12, 6, 14. Si el orden de insercin hubiese sido ligeramente distinto, por ejemplo: 8, 9, 12, 6, 14, 10, el aspecto sera el de la figura 9.

A su vez, en la figura 10 se muestra el aspecto con un tercer orden de creacin, cambiando solo el orden del segundo y tercer elementos del caso anterior: 8, 12, 9, 6, 14, 10

En la figura 11 se muestra un caso extremo; el aspecto del rbol con un orden de creacin 6, 8, 9, 10, 12 y 14, es decir: cuando los

elementos han sido previamente ordenados.

Como puede observarse, con independencia de cual sea el orden de creacin, ocurre que en cualquier nodo del rbol binario ordenado, los elementos de la rama inferior derecha (caso de existir) son mayores que el elemento del nodo, y los de la rama inferior izquierda son menores o iguales (suponiendo tambin su existencia).

4.4.3 Equilibrio Como se ha indicado, la forma de un rbol binario ordenado depende exclusivamente del orden de introduccin de los datos. Cuando el rbol adopta la forma aproximada de la figura 8 se dice que est equilibrado; por el contrario, el de la figura 9 estdesequilibrado. A su vez, el caso representado en la figura 11 ha degenerado en una lista simplemente enlazada. Habr observado que el rbol ms desequilibrado (degenerado) se obtiene precisamente cuando se suministran los datos ordenados, y que los mejores resultados, en cuanto al equilibrio, se obtienen con un orden aleatorio. En realidad la cuestin del equilibrio no es de tipo esttico sino prctico. El nmero de saltos para para encontrar un dato en un rbol binario depende de su altura (nmero de niveles), que es menor cuanto ms equilibrado est. Como se ha sealado, en un rbol de n nodos este nmero tiende a Log2 n cuando est perfectamente equilibrado, y a n/2 en caso de que haya degenerado en una lista simplemente enlazada. Cuando se trata de rboles de cientos o miles de nodos en los que se repiten cientos o miles de accesos, las diferencias globales pueden ser muy significativas. Por ejemplo, para encontrar un dato en un rbol de 1.024 elementos los valores tericos medios oscilan entre 10 pasos si est equilibrado y 512 si degenera en una lista. Puede concluirse por tanto, que un rbol equilibrado es una buena estructura de datos desde la ptica de los mecanismos de acceso a la informacin.

4.4.4 Recorrido de un rbol binario

Suponiendo un rbol binario ordenado, como el de la figura 12, existen tres formas estndar de recorrer la totalidad de sus nodos: inorden, preorden y postorden. La diferencia est en el criterio seguido en uno y otro caso para recorrer las ramas. El primero es el que producira una salida ordenada de los valores de sus nodos.

La secuencia de los recorridos en los tres casos seran:

Inorden: ADEbegk Preorden: b D A E g e k Postorden: A E D e k g b


En el epgrafe dedicado a las Estructuras auto referenciadas se muestran ejemplos de los algoritmos recursivos utilizados en uno y otro caso ( 4.5.8).

2. Objetos y algoritmos
"Programmers have very well-honed senses of justice. Code either works, or it doesnt. Theres no sense in arguing whether a bug exists, since you can test the code and find out. The world of programming is very just and very strictly ordered and a heck of a lot of people go into programming in the first place because they prefer to spend their time in a just, orderly place, a strict meritocracy where you can win any debate simply by being right". Joel Spolsky en "A Field Guide to Developers" www.joelonsoftware.com.

1 Sinopsis Sin pretender ser demasiado rigurosos y en un sentido amplio del trmino, podemos decir que un programa tiene dos tipos de componentes: datos e instrucciones [1]. Los primeros representan el objeto pasivo de las transformaciones y manipulaciones que tienen lugar en la mquina. Los segundos representan las frmulas o recetas que definen como debe efectuarse la manipulacin. Para aclarar estos conceptos, quizs mejor que mis palabras sean las de Alexander Stepanov, creador de la Librera Estndar de Plantillas C++: "Things that have state and change their state are objects (datos). And then there are things that are not objects. A binary search is not an object. It is an algorithm" [3]. Aunque ambos conceptos son suficientemente simples e intuitivos como para no necesitar definicin, incluiremos algunas consideraciones adicionales al respecto. Debemos sealar tambin que este, como casi todos los criterios de clasificacin, incluye una dosis considerable de arbitrariedad. Aunque en la programacin tradicional (procedural 1.7) suele existir una clara diferenciacin entre los elementos pasivos del programa (datos), y los activos (algoritmos), que se agrupan en funciones, procedimientos -o bajo cualquier otro nombre-, existen circunstancias en las que los algoritmos pueden constituir la materia prima (datos) de otros algoritmos. Es el caso por ejemplo, de lenguajes que permiten escribir programas que sirven para manipular otros programas (intrpretes y compiladores).

2 Datos Algo que contiene informacin que no sea informacin sobre clasificacin o computacin (tambin denominados objetos); normalmente en forma de patrones de bits alojados en memora. Una caracterstica fundamental de los datos es que se puede afirmar de ellos que tienen un "valor" [2]. Los datos pueden tener muchas propiedades o atributos, pero una de las ms importantes es su capacidad de cambiar el "valor". Denominndoseconstantes ( 3.2.3) y variables, segn que su "valor" pueda ser modificado o no a lo largo del programa. Cuando en esta publicacin queramos referirnos a estos componentes "datos" (constantes y variables) utilizaremos el trmino objeto-dato para distinguirlos de los "objetos" a secas (instancias de las clases 4.11.5).

3 Instrucciones "An algorithm is a systematic method for solving problemsa recipe, if you will. The word itself is derived from the name of the Arab who invented algebra and was one of the greatest mathematicians of all time". Brian Overland en "Choosing the Right Algorithm in C++".

Tambin llamadas algoritmos. Informacin que se refiere a manipulaciones de los datos y/o los dispositivos fsicos del sistema (ordenador) que soporta el programa. Tambin adoptan la forma de patrones de bits alojados en memoria. Nota: Precisamente, esta caracterstica de que las instrucciones estn alojadas en la memoria de la propia mquina es lo que caracteriza a los ordenadores modernos como mquinas Von Neumann. Esto que hoy se nos antoja natural (como la cada de manzanas antes de Newton), supuso un salto conceptual importante en la ciencia informtica, ya que en los primitivos ordenadores (mejor diramos "mquinas"), los datos y las instrucciones eran tratados de forma diferente. A veces el "programa" estaba tan ntimamente relacionado con la mquina que cambiar de "programa" supona recablear el dispositivo si era elctrico, o cambiar piezas si era mecnico. Al tratar de la Estructura de la informacin ( 1.8), nos hemos referido a datos y algoritmos. En el epgrafe dedicado a la Librera Estndar de Plantillas STL ( 5.1), volveremos a encontrarnos con ellos, y veremos una forma muy general de tratarlos bajo la denominacin de contenedores(estructuras algebraicas que contienen datos) y algoritmos, unos operadores genricos que actan sobre ellas. 3.1 Como se ha sealado (Introduccin a la POO 1.1), precisamente uno de los paradigmas de la Programacin Orientada a Objetos es elencapsulamiento de datos e instrucciones en entidades a las que, de forma genrica, denominamos objetos. En este sentido, un objeto es una regin especfica de memoria que puede contener un conjunto de datos e instrucciones sobre su manipulacin. 3.2 En C clsico, las variables deben ser declaradas al principio de las funciones y antes que cualquier sentencia ejecutable, por el contrario, enC++ pueden ser declaradas en cualquier punto. A este tipo de declaraciones se las denomina de referencia, e introducen uno o ms identificadores en un programa, asocindolos con un tipo de variable. Ejemplos: int x, y; char c; short corto; long distancia; int * ptr;

Tema relacionado: Declaraciones y definiciones (

4.1.2)

2.1 Atributos de las entidades C++

1 Sinopsis Hemos sealado que, en un sentido amplio, un programa tiene dos tipos de entidades: datos e instrucciones, y que a su vez, los datos pueden ser constantes y variables. Una caracterstica importante de los datos (en especial los variables) es que pueden tener varios atributos, estos atributos o propiedades pueden ser relativas al tiempo de compilacin y/o al tiempo de ejecucin (runtime). En Declaraciones ( 4.1) se exponen estos conceptos de forma ms general. Por ahora consideremos que el objeto-dato puede tener los siguientes atributos: Identificador Tipo de dato Clase de almacenamiento Enlazado Direccin (Lvalue ) Valor (Rvalue )

Nota: estos atributos no son exclusiva de los objetos; las funciones (algoritmos) tambin tienen los atributos identificador, tipo , enlazado, direccin y valor (el que devuelven en su caso).

2 Identificador El identificador es el nombre con el que el programador reconoce un objeto-dato especfico, constante o variable [3] ( 3.2.2 Identificadores). En la prctica, el identificador puede ser un simple nombre o una expresin que represente unvocamente al objeto (un objeto se puede conocer por su direccin, sin que se sepa o preocupe su nombre). Ejemplo: int x = 5; x es el identificador de un miembro de la clase de los enteros de valor 5. char* ptr = "String"; ptres el identificador de un miembro de la clase de los punteros-a-carcter. Apunta a una constante de cadena de la que no conocemos su nombre, solo su direccin.

3 Tipo El tipo (tambin conocido como tipo de dato) define cuanta memoria es necesaria para almacenar el objeto, como se interpreta el datagrama de bits que hay en el lugar de almacenamiento del objeto; que rango de valores son posibles, y que operaciones les son permitidas a los objetos de dicho tipo. El concepto tipo de dato tiene una importancia capital en el mbito de la programacin y es la piedra angular sobre la que est construido el propio lenguaje C++ [1]. Es pues de suma importancia asimilar ntimamente el significado de este concepto para comprender y utilizar C++ con un mnimo de soltura.

Cada tipo de dato tiene un sentido particular para el compilador (y para e programador). El tipo puede considerarse como un conjunto de propiedades (dependiente a veces de la implementacin) que, junto con un conjunto de operaciones que les son permitidas y el rango de valores posibles, es asumido por los miembros de dicho tipo. Como se ver ms adelante, el compilador C++ deduce este atributo a partir del cdigo; bien de forma implcita, bien mediante declaraciones explcitas [4]. En C++ existen dos clases de tipos: los definidos intrnsecamente en el lenguaje (tipos preconstruidos en el lenguaje, fundamentales o bsicos), y los definidos por el usuario (tambin llamados abstractos). Precisamente esta capacidad de permitir al usuario "inventar" nuevos tipos a la medida de sus necesidades, es una de las caractersticas del lenguaje. En cuanto a los primeros, se suponen 5 tipos bsicos y muchos ms agregados. En realidad, los tipos constituyen en una estructura muy compleja que incluye 4 categoras bsicas con varias subcategoras ( 2.2 Tipos de datos). En mi opinin, nunca se insistir bastante en la importancia fundamental de entender bien el concepto tipo de dato en el estudio del C++; aparecer con frecuencia en muchas definiciones y explicaciones. De hecho, gran parte de la estructura del propio lenguaje y del sistema de seguridad y comprobacin del compilador gravitan sobre este concepto. Representa algo as como el "Who is who" de las entidades del universo C++ (por lo dems, una sociedad muy "clasista"). Nota: conviene recordar que C++ dispone de dos operadores especficos que permiten obtener informacin sobre los tipos en tiempo de ejecucin: sizeof ( 4.9.13), que permite averiguar el tamao en bytes de cualquier tipo estndar o definido por el usuario, y typeid ( 4.9.14), con el que pueden obtenerse algunos datos adicionales.

4 Clase La clase de almacenamiento ("storage class"), determina donde se guarda la informacin; su duracin (por cuanto tiempo), que puede ser toda la vida del programa o solo durante la ejecucin de ciertos bloques de cdigo, y algunos aspectos de la visibilidad y el mbito. Situacin; es el sitio donde se aloja el dato (constante o variable). Este atributo es significativo porque el programa dispone de varios sitios distintos donde guardar los objetos; sitio que se elige en funcin de ciertas caractersticas del objeto ( 1.3.2) Duracin ( 4.1.5 "Lifetime") es el periodo durante el que la variable tiene existencia real (datos fsicamente alojados en memoria). Es un atributo de tiempo de ejecucin. mbito ( 4.1.3), tambin llamado campo de accin o mbito lxico ("Lexical scope") es la parte del programa en que un objeto es conocido por el compilador. Es una propiedad de tiempo de compilacin. Visibilidad ( 4.1.4 ) es la regin de cdigo fuente desde la que se puede acceder a la informacin asociada a un objeto.

La clase de almacenamiento puede ser definida de forma explcita o implcita ( 4.1.8 Especificadores de clase de almacenamiento).

5 Enlazado

Como se ha indicado ( 1.4), enlazado es el proceso de creacin de un programa que sigue a la compilacin. Permite que a cada instancia de un identificador sea asociada correctamente con una funcin u objeto particular. Cada objeto tiene un tipo de enlazado que puede ser de dos clases: esttico y dinmico. A su vez, cada objeto tiene adems un atributo de enlazado; atributo que est estrechamente relacionado con el mbito, y que puede ser de tres clases: externo, interno y sin enlazado ( 1.4.4).

6 Direccin (Lvalue) La direccin, localizacin, localizador o Lvalue del objeto-dato es una direccin de memoria donde comienza el almacenamiento. Puede ser expresada directamente por un valor (que represente una direccin de memoria en la arquitectura de la computadora utilizada) o una constante, variable, o expresin que pueda traducirse en una direccin. Cuando queramos referirnos especficamente a la direccin de un objeto-dato de nombre x utilizaremos la expresin Lvalue(x), aunque ms adelante veremos que C++ tienen su forma especfica para referirse a ella. El nombre viene histricamente de left value valor a la izquierda, en referencia a que legalmente puede estar a la izquierda (el extremo receptor) en una expresin de asignacin ( 4.9.2). Es decir, el miembro que "recibe" el valor involucrado en la asignacin. Esto tiene sentido porque en C++ una expresin del tipo x = 3; que definiramos coloquialmente como: hacer el valor de x igual a tres, puede enunciarse ms formalmente diciendo: poner un 3 en la direccin de memoria sealada por x, lo que tambin podramos expresar abreviadamente como [2]: Lvalue(x) 3 El Lvalue de un objeto puede ser fijo (constante) o variable. Un Lvalue modificable significa que la direccin puede ser accedida y su contenidolegalmente modificado. Por ejemplo: x = 4; es una expresin vlida si x es una variable de tipo entero; en su direccin puede ponerse un patrn de bits que significar un valor 4 para el compilador (precisamente porque asume que ah se aloja un int). En otro caso el mismo patrn de bits puede significar algo muy distinto. Un Lvalue constante significa lo contrario, por ejemplo, la expresin 4 = x no es correcta porque el Lvalue de 4 no es modificable. La expresina+b = 4 tampoco es correcta, porque a+b no tiene Lvalue (no es un "objeto", no puede interpretarse como una direccin de memoria). El Lvalue de las variables estticas se asigna en tiempo de compilacin, tienen una direccin fija y conocida desde el principio en una zona de memoria especial reservada para las variables estticas y globales ( 1.3.2). En las variables automticas (dinmicas) el Lvalue se asigna en tiempo de ejecucin, la direccin (y por supuesto el valor) se conocen solamente durante la ejecucin del bloque de cdigo correspondiente. Ocurre incluso, que cuando una funcin es llamada recursivamente, para cada activacin de la misma se crean distintos Lvalues para el mismo nombre.

7 Valor (Rvalue)

El Rvalue es la interpretacin que hace el programa del patrn de bits alojado en la direccin asignada al objeto-dato. Histricamente Rvalue es la abreviatura del ingls right value, valor a la derecha, en referencia a los valores que legalmente pueden estar a la derecha (extremo emisor) en una expresin de asignacin. Un Rvalue es una constante, variable, o expresin que pueda traducirse en un valor. Por ejemplo 4 + 3 es un Rvalue. Cuando queramos referirnos especficamente al Rvalue de un objeto de nombre x lo expresaremos: Rvalue(x). Las variables que no son constantes pueden modificar su Rvalue a lo largo del programa. Una expresin del tipo x = a; coloquialmente: hacer el valor de la variable x igual al valor de la variable (o constante) a, puede enunciarse ms formalmente: copiar el Rvalue de la variable cuyonemnico es a en la direccin de memoria (Lvalue) de la variable cuyo nemnico es x, lo que podramos expresar con: Lvalue(x) Rvalue(a)

8 Algunas ideas complementarias En C++ existen formas de referirse especfica y distintamente a la direccin ( Lvalue) y al valor (Rvalue) de un objeto. Incluso existen variables destinadas a contener los Lvalues (direcciones) de otras variables, es decir, variables cuyos Rvalues son los Lvalues de otras, son los denominadospunteros ( 4.2). Precisamente se dice que pnt es un puntero-a-x si: Rvalue(pnt) == Lvalue(x) pnt Nemnico que identifica una variable; suponemos que esta variable es de tipo puntero, y que en este caso apunta a una variable que llamaremos x. Entonces, por definicin de puntero: Rvalue(pnt) == Lvalue(x) *pnt El asterisco * es el operador de indireccin ( 4.9.11); el resultado de aplicarlo a un puntero es el objeto sealado por el puntero. En este caso sera el objeto apuntado por pnt; es decir: *pnt == x. La expresin *pnt solo tiene sentido si el Rvalue(pnt) == Lvalue(x), en otras palabras: Si el valor de pnt es la direccin de almacenamiento de un objeto, o lo que es lo mismo, si pnt es un puntero. Debe tenerse en cuenta, que *pnt devuelve el objeto apuntado por pnt a todos los efectos. Es decir, es un objeto con Rvalue y Lvalue, por lo que las dos expresiones de asignacin siguientes tienen sentido: X = *pnt; *pnt = Y; //equivale a: X = x // equivale a: x = Y

&pnt & es el operador de referencia ( 4.9.11); al aplicarlo a una variable, da como resultado la direccin (Lvalue) de la variable. En este caso sera la direccin de pnt, es decir: &punt es sinnimo de Lvalue(pnt). Esta expresin siempre tiene sentido si pnt es un objeto vlido, ya que por definicin, cualquier objeto tiene un almacenamiento. A la luz de lo dicho, es evidente que: Rvalue(pnt) == &x Precisamente la asignacin de un puntero es una expresin del tipo: int* pnt = &x; en este caso, int* pnt indica que pnt es un puntero-a-entero; despus se le asigna la direccin de la variable x (se asume por tanto que x es de tipo int). A partir de este momento se dice que pnt apunta o seala a x. Cuando * y & se utilizan en esta forma se denominan operadores de puntero. Tngase en cuenta, que el asterisco *, adems de ser el operador de indireccin, tambin puede ser especificador de tipo (de tipo puntero 4.2.1a) y operador de multiplicacin ( 4.9.1). Por su parte, &adems de operador de referencia, tambin puede ser el operador AND en operaciones de bits ( 4.9.3). Nota: Consecuencia inmediata es deducir que en C++ hay casos en que diferentes operadores comparten el mismo identificador. Podemos decir entonces que algunos operadores C++ estn sobrecargados ya de origen. Precisamente el compilador distingue de que operador concreto se trata en cada caso, por el tipo y nmero de los operandos involucrados. Ms informacin al respecto en 4.9 Operadores.

2.2 Los Tipos C++


1 Sinopsis Hemos sealado que los datos, entendidos como objetos que contiene informacin (que no sea sobre manipulaciones), se encuentran en forma de patrones de bits alojados en memora, y que tienen diversos atributos. A uno de estos atributos lo hemos denominado tipo (tipo de dato). Hemos indicado que pertenecer a un "tipo" determinado presupone una serie de caractersticas concretas (la hemos comparado con pertenecer a una casta de la sociedad C++), y hemos sealado que la "tipologa" es uno de los pilares fundamentales en que se asienta el lenguaje. En realidad sealar o definir un tipo de dato viene a significar conocer el comportamiento de los miembros de esta "casta", como se comportan (que operaciones les son permitidas); como interactan entre s y con los miembros de las dems castas que pueblan el universo de las entidades C++.

2 La cuestin de los "Tipos"

Todos los lenguajes de programacin tienen un sistema ms o menos complejo de clasificacin de los objetos en base a una caracterstica denominada "tipo". La caracterstica distintiva de cada tipo viene determinada por las operaciones que pueden efectuarse con sus integrantes; lo cual es bastante natural e intuitivo (es fcil entender que no pueden hacerse las misas cosas con una manzana que con un martillo). Se supone que existe una especie de jerarqua de tipos, desde los ms simples a los ms complejos, as como de las operaciones que se pueden realizar con ellos. Por ejemplo, un int (entero, al que haremos referencia ms adelante) es un tipo de dato simple (lo hemos llamado bsico 2.1); del mismo modo, las operaciones aritmticas que se pueden realizar con ellos son simples tambin. En el caso de C++, este tipo y sus operaciones estn predefinidas en el lenguaje. Sin embargo, un tipo de dato como las matrices cuadradas de nmeros enteros, y sus operaciones, como la inversin o el operador determinante (por citar dos ejemplos), se consideran de orden superior y en el caso del C++ ni siquiera est predefinidas en el lenguaje, aunque dispone de recursos -muy potentes- para que el programador pueda utilizarlas [1]. Una caracterstica de C++ es que el compilador asocia a cada objeto informacin suficiente para que pueda ser obtenido su tipo en runtime. En C++, la determinacin del tipo de un objeto puede efectuarse de dos maneras: la primera, que denominaremos "formal", se realiza cuando se declara expresamente el tipo al compilador. Por ejemplo, mediante la declaracin int x; el compilador sabe casi todo lo necesario acerca de la variable x (excepto su valor actual). En otros casos la interpretacin del tipo de objeto viene determinada por el contexto (expresin utilizada para acceder al objeto). Por ejemplo, en la expresin float y = 10.0/3; el valor 10.0/3 es interpretado por el compilador como un double, que posteriormente ser sometido a una conversin estrechante para convertirlo en un float. Segn la forma en que los lenguajes se comportan frente a los individuos de las diversas "castas", se clasifican de dos grupos: fuerte ydbilmente tipados. Como puede suponerse, los primeros son ms estrictos e intolerantes que lo segundos frente a la promiscuidad entre tipos [2], aunque caben todas las posturas intermedias. En los primeros (lenguajes fuertemente tipados) como C/C++, la tcnica consiste en que el tipo de objeto queda definido desde el principio de su existencia (por declaracin formal o por el contexto). A partir de aqu, quedan perfectamente establecidas las posibilidades del objeto, y estas posibilidades se utilizan como mecanismo de seguridad. Por ejemplo, si en la declaracin anterior, la variable y, que es un float, se utiliza como argumento de una funcin que espera un char, el compilador avisar con un mensaje de error. En el extremo opuesto estn otros lenguajes, tpicamente los denominados "dinmicos" (de tipo script) como JavaScript o Tcl, en los que el tipo de objeto no est completamente definido desde el principio. Es justamente su utilizacin posterior la que establece sus caractersticas. En estos lenguajes es posible establecer expresiones del tipo var z; (z es una variable sin ms indicacin de sus propiedades). Posteriormente es posible hacer z = 10 o z = "ABCD". Ser justamente la asignacin la que complete las caractersticas de la variable que se dejaron indeterminadas. C++ es un lenguaje fuertemente tipado desde el punto de vista esttico ("Strong static type checking"). Es decir, en tiempo de compilacin queda perfectamente definido el tipo de los objetos, y puede advertirnos de cualquier veleidad o error al respecto de tomar un tipo por otro o utilizarlo de forma inadecuada. Sin embargo, en tiempo de ejecucin se comporta a veces de forma muy permisiva porque el compilador proporciona algunas conversiones automticas de tipo (ver a continuacin). Tambin es posible que estas conversiones sean forzadas de forma explcita en el cdigo (en realidad el programador puede terminar haciendo casi lo que le venga en gana). Nota: La razn de que se haya puesto especial nfasis en la comprobacin esttica de tipos (en tiempo de compilacin) en detrimento de la comprobacin dinmica (en tiempo de ejecucin), se debe a que en C++ todas las premisas de diseo han estado encaminadas en favor de lograr la mxima velocidad de ejecucin.

3 Conversin de tipos Al llegar a este punto, conviene hacer una advertencia: a veces es necesario y conveniente que el programa permita un poco de "manga ancha" en la cuestin de los tipos. En el caso de C++ esto puede ocurrir de dos formas: Transformaciones realizadas espontneamente por el compilador . Transformaciones realizados voluntaria y explcitamente por el programador

3.1 Transformaciones realizadas automticamente por el compilador Son situaciones en las que el compilador se amolda a nuestros deseos. Es (entre otros) el caso de los "asimilables a enteros", con los que el compilador se comporta de forma muy permisiva (nos referiremos a ellos inmediatamente). Por ejemplo, las expresiones: char uno = '1'; int x = uno - 48; // uno es tipo caracter; '1' es el dgito 1 // x == valor numrico (decimal) del dgito 1

son perfectamente legales en C++, aunque la segunda sea desde luego bastante escandalosa desde el punto de vista formal. Esta posibilidad de transformacin, realizada muchas veces de forma automtica por el compilador, y que a la postre se traduce en una cierta "promiscuidad" con los tipos de datos, es precisamente uno de los reproches que le hacen a C++ sus detractores. En este sentido C++ es un lenguaje dbilmente tipado. En el apartado de Conversiones estndar ( 2.2.5) se incluye una continuacin de esta "cuestin de los tipos" desde el punto de vista de las conversiones que realiza el compilador de forma rutinaria. Es importante tener conciencia de esta ambigedad con que se comportan algunos tipos de datos en determinadas circunstancias. Como hemos visto en el ejemplo, un char puede ser en un momento un carcter, para a continuacin comportarse como un int, sin dejar por ello de seguir siendo un autntico char. Otro ejemplos (de los varios que se podran citar) de conversin automtica de tipos realizada por el compilador ocurre con los tipos bool ( 3.2.1b), y la realizada en la invocacin de funciones para ajustar el tipo de los parmetros actuales con los formales ( 4.4.6)

3.2 Transformaciones realizadas intencionadamente En otros casos, C++ dispone de operadores especficos que permiten saltarse (hasta cierto punto) las rigideces de la separacin de tipos que siempre subsiste en el compilador. Esta caracterstica distintiva de C++ es lo que se conoce como modelado de tipos (casting 4.9.9); la capacidad de aplicar un operador a un tipo de dato para obtener otro tipo como resultado. Naturalmente esta "adaptacin" no siempre es posible; se requiere una mnima similitud entre ambos. Nota: aunque hemos sealado que a veces es conveniente un poco de "manga ancha" en la cuestin de los tipos, y que esta permisividad se ve reforzada en C++ por el mecanismo de modelado, debemos advertir que la frecuente necesidad de "castings" es probable indicio de un mal diseo o de una tcnica de programacin deficiente.

4 Tipo esttico y dinmico El tipo esttico de una expresin es la que resulta de su anlisis del fuente sin que intervengan consideraciones de ejecucin. El tipo esttico solo depende de la redaccin del programa, y permanece inalterado durante la ejecucin del mismo. El tipo dinmico de una expresin que es un Rvalue, es su tipo esttico. El tipo dinmico de una expresin que es un Lvalue, es el tipo del objeto ms derivado a que se refiera la expresin (esto solo tiene sentido en jerarquas de clases). Ejemplo: Supongamos que [4]: B* p; S s; p = &s; // p es puntero-a-superclase B // s es objeto de subclase S derivada de B // Ok p seala a s

En este caso decimos que el tipo esttico de p es B* (puntero-a-superclase B), y que el tipo dinmico de la expresin *p (que es un Lvalue), esS.

2.2.1 Tipos bsicos


1 Sinopsis Los tipos de datos bsicos o fundamentales de C++, se caracterizan porque no tienen "descomposicin", y tanto sus caractersticas y como las operaciones que se pueden realizar con ellos estn predefinidos en el lenguaje (la literatura especializada tambin suele referirse a ellos diciendo que estn "preconstruidos" o "intrnsecamente definidos" en el lenguaje). Nota: al tratar de los tipos abstractos veremos que en realidad, los tipos bsicos son considerados tambin por el compilador como un tipo especial de clases preconstruidas en el lenguaje ( 4.11.2d3). Se pueden clasificar en tres grandes grupos, y se designan por palabras clave especficas que, en estos casos, representan especificadores de tipo.

Asimilables a enteros: carcter char ( ) enteros int ( ) booleanos bool ( 3.2.1b) enumeraciones enum ( 4.7)

Son considerados tipos artimticos, porque en determinadas circunstancias pueden ser promovidos automticamente a enteros por el compilador [3]. Los enteros, carcter y booleanos son conocidos como "Integral types" en la literatura inglesa.

Fraccionarios: dos versiones: float y double ( Ausencia de dato, sin valor, void ( ).

Los asimilables a enteros y los fraccionarios son conocidos conjuntamente como tipos numricos. A excepcin de void, los tipos bsicos pueden tener modificadores opcionales ( 2.2.3), que se usan para alterar el significado del tipo base (en cuanto a rango de valores y espacio de almacenamiento), de forma que dan lugar a variantes que se adecuan a ciertas necesidades especficas. Estos modificadores indican: con signo, sin signo, largo y corto, y se aplican con las palabras clave que se sealan. largo (long) corto (short) con signo (signed) sin signo (unsigned)

2 Los especificadores de tipo, aislados o acompaados de uno o ms de los modificadores opcionales, definen completamente un identificador. Por ejemplo, pueden darse las siguientes variedades del tipo int: int i1; short int i2; long int i3; signed int i4; unsigned int i5; signed short int i6; unsigned short int i7; signed long int i8; unsigned long int i9; Estas declaraciones presuponen una definicin exacta de la cantidad de memoria necesaria para albergar el tipo de dato; como interpreta el programa el conjunto de bits que se almacena, y cuales son las operaciones permitidas con tales datos. La cuestin del almacenamiento es en muchos casos dependiente de la implementacin concreta, es decir, depende del compilador utilizado, porque el estndar ANSI C++ deja la cuestin un tanto en el aire. En cualquier caso, el operador sizeof ( 4.9.13) permite calcular el tamao en bytes de cualquier tipo de dato, ya sea de los tipos bsicos (pre-definidos en el lenguaje) o de los tipos complejos (definidos por el usuario). Observe que los modificadores opcionales aplicados a un tipo bsico definen un nuevo tipo, de forma que por ejemplo, short y unsigned shortson tipos distintos.

3 Enteros El especificador de tipo int, junto con sus variantes short y long en sus versiones signed y unsigned, identifican a los enteros. Sintaxis:

[signed|unsigned] int <identificador> ; Descripcin: El especificador int se utiliza para definir un dato tipo nmero entero. Junto con sus variantes short y long en sus versiones signed y unsigned, dan lugar a las combinaciones autorizadas que se indican en la tabla, los sinnimos se deben a los valores que (salvo indicacin en contrario) se suponen por defecto.

Especificadores de enteros (sinnimos en la misma lnea) int unsigned short unsigned short long unsigned long signed int unsigned int short int unsigned short int long int unsigned log int signed long int signed short int

En este cuadro observe que: signed y unsigned solo pueden usarse con int, short y long. La palabras clave signed y unsigned, usadas aisladamente, significan signed int y unsigned int. Con int solo pueden usarse long o short. Las palabras clave long y short usadas aisladamente significan long int y short int.

Los int fueron originariamente pensados para ser del tamao de la palabra "natural" del procesador, aunque muchos procesadores modernos pueden manejar con igual facilidad palabras de diverso tamao.

Por una larga tradicin de C, el especificador int poda omitirse en la mayora de los casos, ya que se supona por defecto. Adems, si no se indicaba otra cosa, se supona tambin signed int. Sin embargo, en C++ es necesario especificarlo siempre, ya que es un lenguaje que se preocupa ms de la integridad de los tipos utilizados (lo que puede prevenir muchos problemas). int x; unsigned x; short x; unsigned short x; long x; unsigned long x; // // // // // // signed int x unsigned int x short signed int x unsigned short int x long signed int x unsigned long int x ) y los enteros (int) eran

Nota: por una larga tradicin C, los tipos carcter (char intercambiables.

La longitud (bits) y rango son los indicados (para Borland C++). En cualquier caso, los rangos vienen indicados por las constantes que se sealan (incluidas en <limits.h>):

Tipo Tamao bits Rango 32 -2,147,483,648 <= X <= 2,147,483,647 int -32767 <= X <= 32767 signed short 16 0 <= X <= 65535 unsigned short 16

El Estndar C++ establece que los denominados enteros con signo ("Signed integer types") incluyen: signed char, short int, int y long int. Y que cada tipo debe tener almacenamiento suficiente para alojar al precedente en la lista anterior. Tambin establece otra categora: los enteros sin signo ("Unsigned integer types") que comprende: unsigned char, unsigned short int, unsigned int y unsigned long int, que deben tener el mismo almacenamiento y alineacin ( 4.6.1) que los correspondientes con signo.

4 Carcter El especificador char se utiliza para definir un dato tipo carcter. Se almacenan en 1 byte, es decir, siempre ocurre que sizeof(char) == 1. Esta es la definicin ANSI de byte en C/C++: la memoria requerida para almacenar un carcter [4]. Sintaxis: [signed|unsigned] char <nombre-de-variable> Descripcin: Un char puede ser con signo (signed), sin signo (unsigned), o no especificado; por defecto se suponen con signo. Los objetos declarados de tipo carcter (char) pueden contener cualquiera de los caracteres del juego de ASCII bsico. Son valores que pueden asimilarse fcilmente a losenteros; de hecho se pueden realizar con ellos operaciones aritmticas, el compilador los trata entonces como valores numricos. En estos casos puede pensarse en char como un nmero muy pequeo, por lo que pueden ser usados libremente en expresiones aritmticas, lo que proporciona considerable flexibilidad en cierto tipo de transformaciones con caracteres ( 2.2). Ms sobre los tipos carcter en general ( Ejemplos: char letra, caracter = 'x'; letra = 'a' // carcter es 'x' char s[]; // suponemos una matriz de caracteres s[i] - '0' /* valor numrico del carcter en s[] para las cifras del 0 al 9 */ 2.2.1a)

Especificadores de carcter (sinnimos en la misma lnea)

char unsigned char char signed char

signed char (si char es signed por defecto). unsigned char (si char es unsigned por defecto).

Como se ha sealado, C++ permite que char sea signed o unsigned; por defecto (si no se especifica otra cosa) es signed. Si el defecto se establece a unsigned, entonces la declaracin: char ch; declara ch como unsigned, y para modificar el valor por defecto es necesario consignar: signed char ch;. Anlogamente, si se ha establecido signed char por defecto, para declarar un unsigned char es necesario especificar explcitamente: unsigned char ch;. En C++Builder, el valor que se tomar por defecto puede ser establecido mediante un comando de compilacin: -K- establece signed; -Kestablece unsigned. En los ejecutables construidos con este compilador, el valor que se est tomando por defecto est descrito en una constante manifiesta ( 1.4.1a).

Adems de los tradicionales (heredados del C clsico), el ANSI C++ define un nuevo tipo de dato tipo carcter, el denominado carcter anchowchar_t ( 2.2.1a), adecuado para representar el juego de caracteres Unicode.

5 Fraccionarios Tambin llamados de coma flotante; son float y double. Solo se permite un modificador adicional (long), dando lugar a los long double, de forma que son en realidad tres tipos: float, double y long double ( 2.2.4 Tipos bsicos y representacin interna). Sintaxis: float <nombre-de-variable> [signed|unsigned] double <nombre-de-variable> Ejemplos: float x = 3.14; double y = 6.2; long double z = 66.01; Tanto el especificador float como el double son palabras clave que definen un identificador como de tipo numrico de coma flotante (fraccionario). La razn principal de usar floats es economizar espacio o tiempo, cuando se almacenan grandes arrays de nmeros en mquinas donde el uso dedouble es muy costoso en trminos de tiempo de computacin. En ciertos casos los tipos float pueden ser promovidos a double de forma automtica por el compilador ( 4.4.1a).

El almacenamiento interno y rango de los tipos fraccionarios es dependiente de la implementacin. Es decir, cada compilador C++ es libre de definirlos a su manera ( 2.2.4). El Estndar solo establece para ellos las siguientes condiciones [5]: El tipo double permitir al menos tanta precisin como el float. El tipo long double permitir al menos tanta precisin como el double. El rango de valores de float ser un subconjunto del rango de los double. El rango de valores de double ser un subconjunto del rango de los long double.

6 void void es palabra reservada, indicador de un tipo especial: ausencia de valor. Sintaxis: void identificador Es importante sealar que void es tratado por el compilador como un tipo, del mismo modo que pueden serlo int, char, double, etc. Aunque de tipo un poco especial (un tipo incompleto 4.1.2). El hecho de que signifique ausencia de valor no es inconveniente para que sea un tipo con todas sus caractersticas. Podramos suponer que representa al conjunto de los tipos lo que el cero al conjunto de los nmeros. La nica diferencia respecto a cualquier tipo normal es que tiene una sola instancia o representante; l mismo. Dicho en otras palabras: int entero; char caracter; void novalor; // Ok. entero es una instancia de la clase int // Ok. caracter es una instancia de la clase char // Error. uso no permitido.

En cambio si estn permitidas con l otras expresiones propias de los tipos: return void(0); void* puntero; void func(); // Ok. modelado de tipo // Ok. puntero es puntero-a-void // Ok. tipo devuelto por funcin

void se usa de varias formas: Para indicar que una funcin no devuelve ningn valor o no acepta ningn parmetro ( 4.4.7). Para crear punteros genricos ( 4.2.1d). Para modelado de tipo ( 4.9.9).

Ejemplos: int x; void* p; p = &x;

// define un puntero-a-nulo (genrico) // p seala a x (pasa a ser puntero-a-int)

Uso de void para sealar que una funcin no acepta ningn parmetro:

int main (void) { ... } Uso de void para para definir una funcin que no devuelve ningn valor [2]: void saludo(char *nombre) { printf("Hola, %s.",nombre); } Uso de void para devolver void (se trata en realidad de un modelado de tipo) void saludo(char *nombre) { printf("Hola, %s.",nombre); return (void)0; } Uso de void para modelado de tipo [1] #ifdef NDEBUG #define assert(p) ((void)0) #else #define assert(p) ((p) ? (void)0 : _assert(#p, __FILE__, __LINE__)) #endif

2.2.1a Los tipos carcter


1 Presentacin: En este captulo abordamos la importante cuestin de como son representados internamente los caracteres alfabticos y numricos (cifras), en los ordenadores en general y en el lenguaje C++ en particular. Describiremos los sistemas de codificacin utilizados ms frecuentemente, junto con una pequea introduccin a su historia (informtica) y evolucin, comenzando por el sistema ASCII por ser el ms conocido.

2 Juegos de caracteres Recuerde que cuando un texto informtico utiliza las expresiones juego de caracteres ("Character set") o codificacin de caracteres ("Character encoding"), se refiere siempre a una convencin (norma) para relacionar una secuencia de octetos con una secuencia de glifos (marcas o dibujos en un papel o en una pantalla) denominados genricamente caracteres, que corresponden a letras, smbolos, cifras o ideogramas de un sistema de escritura. En el interior de la mquina, esta correspondencia entre glifos y octetos, se materializan en una tabla denominada pgina de cdigos . Recuerde tambin que un determinado juego de caracteres se refiere generalmente a un idioma (aunque no siempre), y no tiene porqu contener todos los caracteres y signos del idioma.

Es interesante observar que desde el punto de vista de la codificacin de caracteres, la correspondencia entre octetos y glifos es muy genrica, en el sentido en que por ejemplo, un octeto determinado puede corresponder con la letra latina " A" mayscula, pero no contiene ninguna indicacin o detalle sobre su representacin, como tipo de letra a utilizar, tamao, color, o cualquier otra caracterstica tipogrfica que pudiera utilizarse en la representacin de dicho carcter. Esos detalles no corresponden a la capa de software encargada de la codificacin, sino a la que gobierna la interfaz hombre-mquina. Actualmente las diversas culturas vivas del mundo utilizan unos 30 juegos de caracteres distintos, algunos de los cuales sirven a ms de una lengua. Como el romano, utilizado en Europa occidental y otros pases del mundo, o el cirlico, utilizado en pases eslavos ( Juegos de caracteres). Bsicamente existen dos tipos: alfabticos e ideogrficos. Los primeros corresponden a lenguas en las que existe el concepto de palabras formadas por caracteres del alfabeto. En este caso, los caracteres se denominan letras, smbolos de puntuacin o cifras (segn representan). Los segundos corresponden a lenguas en las que una idea u objeto son descritos mediante un solo glifo, que en este caso se denomina ideograma. El tipo char naci en el primitivo C de K&R, y fue diseado para contener un tipo especial de dato: los cracteres alfanumricos del idioma ingls-americano. Teniendo en mente los caracteres que se utilizaban en la informtica de la poca, se consider suficiente asignarle un espacio de almacenamiento de 1 byte. Esta es precisamente la definicin ANSI de byte en C y C++: la memoria requerida para almacenar un carcter. En consecuencia, en estos idiomas siempre se cumple que sizeof(char) == 1 ( 4.9.13 ).

3 El cdigo ASCII Como su propio nombre indica, ASCII (American Standard Code for Information Interchange), tiene origen americano, en el instituto ANSI [1]. El ASCII es simplemente una convencin para codificar un conjunto de 128 caracteres (letras, nmeros y smbolos), numerados del 0 a 127. Este nmero 7 se debe a que emplea slo 7 bits (2 == 128), algo que pareca suficiente en la poca en que se propuso el estndar. Mucha gente cree que el cdigo ASCII tiene 256 caracteres (numerados del 0 al 255), que es la capacidad de los 8 bits de un Byte, pero lo cierto es el denominado "ASCII puro", tambin conocido como US-ASCII (tcnicamente es el ANSI X3.4-1968), se compone de slo 7 bits y 128 caracteres (rango 00h-7fh si lo expresamos en hexadecimal). El primero es el carcter nulo, y tiene el nmero 0; el ltimo es el 127. En los 128 caracteres del cdigo ASCII original se encuentran las letras del alfabeto ingls (maysculas y minsculas), los nmeros, y algunos signos comunes (espacio en blanco, parntesis, corchetes, suma y resta, dlar, porcentaje, etc.) adems de otros como retorno de carro, tabulador, campana, etc. Estos ltimos, que eran necesarios para controlar el funcionamiento de los antiguos teletipos, ocupan las 32 primeras posiciones y la ltima, y se denominan precisamente por eso caracteres de control o no imprimibles. Puesto que no representan ninguna letra ni signo de puntuacin, se designan mediante nemnicos (NULL, NAK, CR, NL, Etc. [5]). Ver nota a continuacin .

Juego de caracteres US-ASCII


0 1 2 3 4 5 6 7 8 9 A B C D E F

NUL SOH STX ETX EOT ENO ACK BEL BS TAB LF 0 0 1 2 3 4 5 6 7 8 9 10

VT 11

FF 12 FS 28 , 44 < 60 L 76 \ 92 l

CR 13 GS 29 45 = 61 M 77
]

SO 14 RS 30 . 46 > 62 N 78 ^ 94 n

SI 15 US 31 / 47 ? 63 O 79 _ 95 o

DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC 1 16 17 ! 2 32 0 3 48 @ 4 64 P 5 80 ` 6 96 p 7 97 q 98 r 81 a 82 b 83 c 84 d 85 e 86 f 87 g 88 h 89 i 90 j 91 k 65 Q 66 R 67 S 68 T 69 U 70 V 71 W 72 X 73 Y 74 Z 75 [ 49 A 50 B 51 C 52 D 53 E 54 F 55 G 56 H 57 I 58 J 59 K 33 1 34 2 35 3 36 4 37 5 38 6 39 7 40 8 41 9 42 : 43 ; 18 " 19 # 20 $ 21 % 22 & 23 ' 24 ( 25 ) 26 * 27 +

93 m

99 100 101 102 103 104 105 106 107 108 109 110 111 s t u v w x y z { | } ~ DEL

112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127

Leyenda: el valor Hexadecimal se encuentra entrando en la fila y columna. Por ejemplo, el carcter "A" est en fila 4 columna 1, luego su valor hexadecimal es 41 = 41h ( 2.2.4b). El valor decimal se ha incluido debajo de cada carcter (en color azul), para la "A" es 65. Los caracteres no representables se han indicado por sus nemnicos (en color verde). Al carcter "espacio" le corresponde el decimal 32 (20h). Nota: la tabla adjunta incluye los nombres completos y valor decimal de algunos acrnimos muy utilizados en textos informticos. La columna "Gen." seala la forma en que puede generarse el carcter de control desde el teclado.

Acrnimo Gen. NUL

Nombre completo

ASCII Comentario 0 Carcter nulo; un carcter como los dems, que puede ser definido mediante'\0'. No confundir con la constante NULL definida en muchos compiladores y libreras como el puntero nulo ( 4.2.1). Recuerde que NUL yNULL son tipos distintos. A su vez este ltimo no tiene ninguna relacin con elNULL utilizado en muchas bases de datos relacionales, donde se refiera a ausencia de valor o valor no definido.

Ctrl- Null @

SOH

Ctrl- Start of Header A Ctrl- Start of Text B Ctrl- End of Text C Ctrl- End of D Transmission Ctrl- Enquiry E Ctrl- Acknowledge F Ctrl- Bell G Ctrl- Back Space H Ctrl-I Horizontal Tab Ctrl- Line Feed/New J Line

STX

ETX

EOT

ENQ

ACK

BEL

Seal acstica que sonaba en los teletipos para recabar atencin del operador. Retroceso/retorno de carro

BS

HT LF/NL

9 10

Tabulacin horizontal Salto de lnea / Nueva lnea (espacio vertical). Representado por el dgrafo \nen la

mayora de lenguajes y textos informticos. VT Ctrl- Vertical Tab K Ctrl- Form Feed L Ctrl- Carriage Return M Ctrl- Shift Out N Ctrl- Shift In O Ctrl- Data Link P Escape Ctrl- Device Control Q 1 Ctrl- Device Control R 2 Ctrl- Device Control S 3 Ctrl- Device Control T 4 Ctrl- Negative U Acknowledge Ctrl- Synchronous V Idle Ctrl- End W Transmission Block 11 Tabulacin vertical

FF

12

Salto de pgina

CR

13

Retorno de carro de impresin. Tambin suele ser representado por el dgrafo\r

SO

14

SI

15

DLE

16

DC1

17

Tambin conocido como XON [6]

DC2

18

DC3

19

Tambin conocido como XOFF [6]

DC4

20

NAK

21

SYN

22

ETB

23

CAN

Ctrl- Cancel X Ctrl- End of Medium Y Ctrl- Substitute Z Ctrl- Escape [ Ctrl- File Separator \ Ctrl- Group ] Separator Ctrl- Record Ctrl Separator Ctrl- Unit Separator _ Space Delete / rubout Character

24

EM

25

SUB

26

ESC

27

FS

28

GS

29

RS

30

US

31

SP DEL CHAR CTL

32 127

Espacio horizontal

0 - 127 Cualquier carcter US-ASCII 0-31+ Cualquier carcter de control 127 65 - 90 Cualquier mayscula "A"..."Z"

UALPHA Ctrl Control LOALPHA

94 97 122

Representado por el smbolo ^ Cualquier minscula "a"..."z"

ALPHA

Cualquier letra, mayscula o minscula

DIGIT

48 - 57 Cualquie dgito "0"..."9"

3.1 El ASCII extendido Con la internacionalizacin de los ordenadores, se cay en la cuenta que los 128 caracteres del US-ASCII no eran suficientes para trabajar con los signos de otros idiomas (tildes; signos especiales como las interrogaciones o exclamaciones de apertura; letras como la ee, la cedilla y otras), de modo que los fabricantes comenzaron a usar un conjunto de caracteres ASCII ampliado de 8 bits (256 caracteres), que adems coincida con el tamao de palabra de los procesadores de la poca. Las 128 posiciones primeras seguan conteniendo el US-ASCII, pero en los 128 caracteres adicionales, que constituyen lo que se denomina ASCII extendido, aadieron todas las letras y signos especiales de uso comn en lenguas de Europa occidental, como el espaol, francs o alemn. Por desgracia, en aquel momento no se siguieron estndares nicos, ni hubo una decisin internacional al respecto. Cada fabricante de ordenadores y software us su propio cdigo seudoASCII en variaciones nacionales o de sistema operativo, construyendo sus propias pginas de cdigos (5 ) sin pensar en los problemas que esto acarreara a la informtica del futuro, con lo que se origin una pequea "Babel" de sistemas de codificacin de caracteres que perdura hasta hoy. Actualmente, el juego de caracteres ASCII extendido de los PC es distinto en MS-DOS y MSWindows, distinto a su vez del "ASCII Macintosh" y del ASCII Unix; del de algunos sistemas IBM, y desde luego de otros muchos sistemas operativos antiguos y modernos [2]. Algunas de estas versiones de ASCII extendido se han estandarizado. Ver a continuacin el Estndar ISO 8859 . Por su parte, en la poca del desarrollo del C original (la primera edicin del libro de K&R es de 1978), ya se utilizaba el ASCII extendido, y por supuesto, las 256 posibilidades de un byte eran suficientes para albergar los caracteres definidos en el Estndar, por lo que al tipo char se le asign 1 octeto.

3.2 Evolucin del ASCII De entre todos los sistemas ASCII de 8 bits (SBCS "Single Byte Character Sets"), los que han alcanzado mayor fortuna han sido dos: El que se incorpor por defecto en los PCs de IBM en la dcada de los 80, y posteriormente, el de los sistemas Windows 9x de MS. El juego de caracteres del PC, incorpor smbolos especiales para representar visualmente (en la pantalla) los caracteres de control que hasta entonces no tenan representacin grfica. El juego de caracteres extendido se muestra en la tabla adjunta.

4.2a Juego de caracteres extendidos ASCII-PC

En lo que respecta a Microsoft, el gigante de la informtica incorpor en sus sistemas Windows 9x un juego de caracteres bastante adaptado a la mayora de los alfabetos occidentales. Posteriormente implement en sus sistemas NT y sucesores, un sistema denominado Unicode que utiliza 16 bits para representar los caracteres; sus 65.537 posibilidades permiten representar los de todas las lenguas del mundo ( 2.2.1a2). Nota: en las pginas siguientes se detallan las caractersticas de los sistemas de codificacin multibyte, que representan el ltimo paso evolutivo de los sistemas SBCS.

3.2b El cojunto de caracteres ASCII extendido tal como se ven en un sistema Windows 9x (los caracteres marcados _, no tienen representacin grfica visible en MS Windows 98 con I. Explorer 5.50).

3.2c Juego de caracteres ASCII extendido tal como son generados en su computadora

8 9 A B C D E F

3.3 A continuacin se muestra una calculadora interactiva [4] para representar los caracteres ASCII y sus valores numricos correspondientes en los diversos sistemas: Decimal, Hexadecimal y Octal (Vlido para los navegadores Netscape 3+ y MS IE 4+):

Dec:

Hex:

Octal:

ASCII:

Escribir en la casilla correspondiente y pulsar TAB

4 Pgina de cdigos Los juegos de caracteres, ya sean ASCII, Unicode o de cualquier tipo, se materializan dentro de la mquina en unas tablas denominadas pginas de cdigos, que establecen la relacin entre cada glifo y su valor numrico [8]. Las pginas de cdigos pueden ser cualquiera, incluso construidas por el usuario, pero las utilizadas ms frecuentemente estn estandarizadas. Existen dos tipos: ACP ("ANSI Code Pages") Las que han sido estandarizadas por el Instituto de Estndares Americano. Por ejemplo: la pgina de cdigos ANSI 1252 corresponde al Ingls-Americano y a la mayora de lenguas de Europa occidental. OCP ("OEM Code Pages") Son propuestas por fabricantes u organizaciones no oficiales (OEM significa "Original Equipment Manufacturer"). Por ejemplo, la OEM 932 corresponde al juego Kanji de caracteres Japoneses ( 2.2.1a0), mientras que el OEM 949 representa un juego de caracteres Coreano.

Generalmente las pginas de cdigo son mantenidas por el Sistema Operativo, y existen en dos versiones: para caracteres normales y para caracteres anchos. Los programas C/C++ las utilizan

de dos modos: forma controlada explcitamente por el programador en runtime ( 5.2), o controlada por el propio compilador que selecciona unas pginas por defecto que son cargadas desde el Sistema anfitrin como parte de las rutinas de inicio. El MS-DOS, quizs el primer Sistema Operativo que lleg a ser verdaderamente universal, utiliz distintas pginas de cdigo con una nomenclatura propia para extender este Sistema a entornos distintos del Ingls-Americano. Por ejemplo: 437 Ingls-USA (del PC original IBM) 737 Griego 862 Hebreo 863 Franco-Canadiense 850 Multi-Lingual (Latn-1) 865 Nrdico 860 Portugus 852 Eslavo (Latn-2) A su vez, el Estndar ISO 8859 establece 15 pginas de cdigo, de las que se han reservado diez para las lenguas que utilizan un juego de caracteres de raz latina [7]:

ISO 8859-1 (Latin-1) Europa occidental ISO 8859-2 (Latin-2) Europa oriental (pases eslavos) ISO 8859-3 (Latin-3) Europa suroriental ISO 8859-4 (Latin-4) Europa septentrional ISO 8859-5 Cirlico ISO 8859-6 rabe ISO 8859-7 Griego ISO 8859-8 Hebreo

ISO 8859-9 (Latin-5) Europa oriental + Turqua ISO 8859-10 (Latin-6) ISO 8859-11 Latin/Thai ISO 8859-13 (Latin-7) ISO 8859-14 (Latin-8) Celta ISO 8859-15 (Latin-9) ISO 8859-16 (Latin-10)

Observe que un lenguaje natural utiliza siempre la misma pgina de cdigos (la que contiene todos sus caracteres y signos de puntuacin), pero una pgina de cdigos no tiene porqu estar relacionada nicamente con un lenguaje. Por ejemplo, la pgina ANSI 1252 puede ser utilizada por los lenguajes Ingls, Espaol y Francs porque contiene todos los caracteres utilizados en estas lenguas. Nota: Windows XP y Windows 2000 disponen de la utilidad charmap, que permite ver los caracteres disponibles en una fuente seleccionada, as como mostrar los juegos de caracteres: Windows, DOS y Unicode. Puede copiar caracteres individuales o un grupo de caracteres al Portapapeles y pegarlos en cualquier programa que pueda mostrarlos. Tambin permite buscar caracteres por el nombre de carcter Unicode o un subgrupo Unicode (por ejemplo, flechas u operadores matemticos).

Como se ha sealado anteriormente (4.1 ), las pginas de cdigo de caracteres normales tienen 256 posiciones, aunque la mayora comparte 128 posiciones con el juego de caracteres ASCII (el rango 0x00-0x7F). En cambio, las pginas de caracteres anchos son muy grandes (64 K entradas), aunque no suelen cargarse completas, solo las primeras 256 posiciones y ciertas zonas correspondientes a los rangos que utilizar el programa [3].

Como veremos al tratar de la internacionalizacin de los programas ( 5.2), muchas funciones de la Librera Estndar C++ para manipulacin de caracteres normales y caracteres anchos, adaptan su comportamiento a la pgina de cdigos correspondiente que haya sido cargada.

Recordar que la Librera Estndar C++ ( 5) dispone de funciones especiales para determinar ciertas caractersticas de cualquier carcter. Por ejemplo, si es imprimible (representable grficamente); si es un dgito o carcter alfabtico; si es ASCII, etc. Ver: isalpha(); isascii();iscntrl(); isdigit(); isgraph(); islower(); etc. Inicio.

2.2.1a0 Sistemas de codificacin


1 Evolucin de los sistemas de codificacin Adems de los problemas esbozados en el captulo anterior ( 2.2.1a), derivados de representar los caracteres de lenguas europeas distintas del ingls-americano, la difusin de la informtica a culturas de raz no latina puso rpidamente de manifiesto que 256 caracteres eran insuficientes para contener los grafos de todas las lenguas. Por ejemplo, el cirlico; el hebreo; el rabe; el griego, y el japons por citar algunas [1]. Se hizo evidente la necesidad un sistema con ms de 256 posibilidades, lo que condujo a establecer sistemas de codificacin en los que cada carcter ocupaba ms de un octeto (al menos ciertos caracteres), razn por la cual a estos sistemas se les conoce genricamente como de caracteres anchos. La solucin adoptada comprende dos grandes grupos: el sistema multibyte (2 ) y el sistema de caracteres anchos (3 ), de los que existen distintas variedades. Generalmente el primero se utiliza en representacin externa (almacenamiento) y comunicaciones, mientras que el segundo es preferido para representaciones internas.

2 Sistema multibyte Si se trata de representar juegos de ms de 256 caracteres en almacenamientos externos o en sistemas de transmisin, en los que es importante la economa de espacio y/o ancho de banda, la solucin ha consistido en utilizar sistemas de codificacin multibyte. Conocidos abreviadamente como MBCS ("Multibyte Character Set"). Como su nombre indica utilizan ms de un octeto, pero la anchura de los distintos caracteres es variable segn la necesidad del momento. Los caracteres multibyte son una amalgama de caracteres de uno y dos bytes de ancho que puede considerarse un superconjunto del ASCII de 8 bits. Por supuesto una convencin de este tipo exige una serie de reglas que permitan el anlisis ("Parsing") de una cadena de bytes para identificar cada carcter. Nota: el juego de caracteres ASCII suele ser un subset de todos los sistemas de codificacin multibyte, de forma que en cualquier pgina de cdigo ( 2.2.1a) MBCS, los caracteres en el rango 0x00-0x7F son idnticos a los del mismo valor en la pgina ANSI 1252.

Existen distintas versiones de este tipo de codificacin que se utilizan en distintas circunstancias: JIS ("Japanese Industrial Standar"). Es utilizado principalmente en comunicaciones, por ejemplo correo electrnico, porque utiliza solo 7 bits para cada carcter [2]. Usa secuencias de escape para conmutar entre los modos de uno y dos bytes por carcter y para conmutar entre los diversos juegos de caracteres. Shift-JIS. Introducido por Microsoft y utilizado en el sistema MS-DOS, es el sistema que soporta menos caracteres. Cada byte debe ser analizado para ver si es un carcter o es el primero de un do. EUC ("Extended Unix Code"). Este sistema es utilizado como mtodo de codificacin interna en la mayora de plataformas Unix. Acepta caracteres de ms de dos bytes, por lo que es mucho ms extensible que el Shift-JIS, y no est limitado a la codificacin del idioma japons. Resulta muy adecuado para el manejo de mltiples juegos de caracteres. UTF-8 ("Unicode transformation format"). En este sistema, cada carcter se representa mediante una secuencia de 1 a 4 bytes. Aunque en realidad, el nmero de bits destinados a representar el carcter se limita a un mximo de 21 (el resto son metadatos -informacin sobre informacin-). El objeto de estos metadatos es que la secuencia pueda ser interpretada a partir de cualquier posicin. Es decir, que de la simple inspeccin de un trozo, sea posible conocer donde comienza cada carcter y cuantos bytes lo componen. El esquema adoptado es el siguiente:

bytes bits de datos representacion interna 0xxxxxxx 1 7 2 3 4

11 16 21

110xxxxx 10xxxxxx 1110xxxx 10xxxxxx 10xxxxxx 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

Cada X representa un bit de datos (valor 0/1). En realidad puede decirse que UTF-8 es un sistema de codificacin que transforma un caracter multibite (entre 8 y 32 bits) en una secuencia de caracteres simples (8 bits), de ah su nombre. Es el esquema utilizado por Unicode ( 2.2.1a2) para almacenar sus caracteres anchos (de 16 bits). A su vez, los caracteres US-ASCII conservan su mismo esquema cuando se codifican en UTF-8, por lo que una cadena de caracteres US-ASCII conserva su mismo significado en ambos sistemas (en realidad UTF-8 fue diseado para ser compatible hacia atrs con el US-ASCII). El diseo adoptado hace que sea un sistema auto-sincronizado, lo que significa que de la simple inspeccin de la cadena puede deducirse cuando empieza y termina cada carcter. La regla es que si el primer bit es cero, se trata de caracteres de 1 byte de los que solo son significativos los 7 bits siguientes (puro US-ASCII). Si el primer bit es un uno sabemos que es un carcter multibyte. 2 bytes por carcter si la combinacin inicial es 110; tres si 1110, y cuatro bytes por carcter para 11110. Debido a los esfuerzos de homogenizacin realizados entre el consorcio Unicode y los comits ISO/IEC ("International Organization for Standardization"/"International Electrotechnical Commission"), el sistema UTF-8 y el ISO/IEC 10646-1:1993 son coincidentes. UTF-16 y UTF-32 son sistemas de codificacin Unicode similar al anterior, aunque en estos casos las secuencias son de 16 y 32 bits respectivamente. Puesto que en el mejor de los casos, un carcter codificado en UTF-8 utiliza 32 bits (4 Bytes), resulta claro que cualquier carcter codificado en UTF-8 requerir solo 1 grupo de bits si se codifica en UTF32 o dos, si lo es en UTF-16.

En particular, la palabra de dos bytes que componen una secuencia UTF-16 -que puede ser contenida en un caracter ancho de C/C++-, es capaz de contener todos los caracteres cuya representacin numrica ("code point") est entre 0 y 65.535 (h0000-hFFFF). Este conjunto, conocido como BMP ("Basic Multilingual Plane") permite representar los caracteres de la mayora de idiomas del mundo. Cuando la palabra anterior no es suficiente, se requiere otro conjunto de 16 bits adicionales para codificar el carcter. Se dice entonces que se utiliza un par subrogado ("surrogate pair"). Al primer grupo se le denomina subrogado alto ("high surrogate") y al segundo, subrogado bajo ("low surrogate"). Estas representaciones numricas ("code points") se denominan suplementarias -de las que utilizan 16 bits- y se supone que los caracteres correspondientes no estn en el BMP, sino en planos suplementarios. Si desea ms detalles sobre la forma concreta en que se realiza esta descomposicin de un "code point" en un par subrogado, puede consultar esta pgina de la Organizacin Unicode, donde encontrar incluso una rutina para codificar cualquier valor en UTF-16. Como punto a destacar, sealemos que UTF-16 es el mtodo empleado para la representacin interna de datos en la mayora de Sistemas Operativos. Por ejemplo, es el caso de Windows XP y Vista, y que al igual que en UTF-8, donde no toda la capacidad de representacin de un octeto se utiliza para representar los datos -en el mejor de los casos ser desaprovecha 1 bit (metadato)-, enUTF-16 tambin es necesario desaprovechar algo la capacidad de representacin de los 16 bits para representar metadatos y permitir que de la inspeccin de una secuencia, pueda saberse si una palabra corresponde a un par subrogado, o representa un caracter en s misma. El resultado es que para la mayora de idiomas no se requieren pares subrogados y que en C/C++, puede suponerse casi con seguridad que cada caracter ancho (grupo de 16 bits) codificado en UTF16 corresponde a un carcter, aunque no simpre cierto. De hecho, si se maneja esta codificacin, es necesario asegurarse que el carcter no forma parte de un par subrogado, lo que puede hacerse conociendo que en tal caso, el valor del subrogado alto est siempre comprendido entre los valores 55.296 y 56.319 (hD800-hDBFF), mientras que el subrogado bajo lo est entre 57.343 y 56320 (hDC00-hDFFF), lo que quiere decir que considerados aisladamente, los caracteres anchos comprendidos en este rango no tienen significado de forma aislada y deben ser interpretados con el adyacente como un solo caracter. Puesto que una palabra de 16 bits puede representar 2 = 65.536 valores distintos (65.537 si contamos el cero), observamos queUTF-16, utiliza 1.023 de ellas como metadatos para subrogados bajos (hDBFF - hD800) y otras 1.023 para los subrogados altos (hDFFF - hDC00). Lo que representa aproximadamente un 3.12% del total.
16

2.1 Codificacin JIS Como sugiere su nombre, fue diseado especficamente solventar los problemas de representacin de la escritura japonesa. En este sistema, una frase puede contener caracteres de hasta cuatro sistemas de escritura distintos: el sistema Kanji, que tiene decenas de miles de caracteres representados por dibujos basados en ideogramas chinos. Los sistemas Hiragana y katakana son silbicos; cada uno contiene aproximadamente 80 sonidos que son tambin representados por ideogramas. Finalmente el sistema Roman, que contiene 95 letras, dgitos y signos de puntuacin es lo ms parecido a la escritura simblica occidental (basada en letras). En la figura adjunta [3] se muestra una frase en japons que utiliza los cuatro sistemas de escritura sealados

Los distintos sistemas han sealado con distinto tono de fondo. Traduccin: "Los mtodos de codificacin como JIS pueden representar mezclas de texto Japons e Ingls". Existen diversos juegos de caracteres de este idioma (incluso se utilizan los caracteres ASCII). Aunque no existe un sistema de codificacin del japons que sea universalmente admitido, algunos son ms generales: JIS C 6226-1978; JIS X 0208-1983; JIS X 0208-1990; JIS X 0212-1990; JISROMAN (este ltimo es el juego de caracteres ASCII). Los sistemas JIS utilizan caracteres de uno y dos bytes de ancho; el paso de un tipo a otro se seala mediante una secuencia de escape que pertenece al esquema de codificacin y no forman parte del mensaje propiamente dicho. Ejemplo [3]:

Estado inicial: ASCII de 1 byte

Cambio a Kanji

Juego de caracteres Kanji. JIS X 0208-1983

Cambio a ASCII

Juego de caracteres ASCII de 1 byte

Las secuencias de escape, tambin denominadas "de control", no tienen representacin grfica, y obligan al analizador sintctico que examina el mensaje a mantener un control de estado, que es activado cada vez que encuentra una secuencia de control. En el ejemplo anterior el estado inicial es ASCII de 1 byte por carcter. Al encontrar la secuencia <ESC>$B es interpretada como cambio al sistema Kanji, de forma que a partir de ah cada dos bytes se interpretan como un carcter del conjunto JIS X 0208. A llegar a la secuencia <ESC>(B se interpreta como cambio al sistema ASCII de un byte por carcter, y as sucesivamente [4]. Estos sistemas de codificacin no son muy eficientes para almacenamiento interno o para proceso de la informacin, razn por la que suelen ser utilizados para almacenamiento externo y como medio de compartir informacin entre un programa y el mundo exterior. Puede ocurrir que si el mensaje incluye cambios muy frecuentes la informacin de codificacin supere a la del propio mensaje (cuando est en formato 2 bytes por carcter la secuencia de control ocupa 6 bytes). Adems tiene el inconveniente que no puede ser ledo en cualquier orden, por ejemplo del final al principio o comenzando en cualquier punto.

2.2 Codificacin Shift-JIS A pesar de su nombre este sistema no tiene ninguna conexin con el anterior. Aqu la informacin de codificacin acompaa a cada byte, de forma que l mismo indica si debe ser interpretado como un carcter aislado o el primero de un do, conocidos como byte de cabeza y de cola ("Lead" byte y "Trail" byte). La informacin est codificada en el propio valor porque el rango de valores posibles est distribuido en varios significados:

Rango

Hex.

Dec.

Significado

21-7E 33-126 Carcter de 1 byte del conjunto JIS Roman A1-DF 161-223 Carcter Katakana

81-9F 129-159 Byte de cabeza ("Lead") de un carcter ancho del conjunto JIS X 0208-1990. E0-EF 224-239 40-7E 64-126 Byte de cola ("Trail") del caso anterior. 80-FC 128-252
Este sistema de codificacin es ms compacto que el JIS, aunque no puede representar tantos caracteres como aqul. En concreto no puede representar el conjunto JIS X 0212-1990 que contiene ms de 6.000 caracteres.

2.3 Codificacin EUC Como sugiere su nombre, el sistema EUC ("Extended Unix Code") es utilizado como mtodo de codificacin interna en plataformas Unix. Fue desarrollado como un sistema general capaz de manejar mltiples sistemas de codificacin en cualquier flujo de datos, sin que est por tanto ligado necesariamente a la representacin de la escritura Japonesa. Es mucho ms extensible que el Shift-JIS, porque permite caracteres de ms de dos bytes de ancho. Aunque no est ligado necesariamente a la representacin de la escritura Japonesa sirve naturalmente para este propsito. A continuacin se muestra el esquema de codificacin utilizado por EUC para para esta lengua:

Rango
Hex. Dec. Significado 217E 33Carcter de 1 byte del conjunto JIS Roman 126

A1- 161- La mitad de un carcter del conjunto JIS X0208-1990. El segundo byte del carcter FE 254 debe estar en el mismo rango

8E 142 Cualquier byte de este valor debe estar seguido de un byte en el rango A1-DF, que
representa un carcter del conjunto Katakana.

8F 143 Cualquier byte de este valor debe ir seguido de dos bytes adicionales en el rango A1FE, que representan un carcter del conjunto JIS X 0212-1990, que como hemos indicado contiene ms de 6.000 caracteres.

Como puede verse en los dos ltimos casos, los caracteres 0x8E y 0x8F funcionan en cierta

manera como las secuencias de control del sistema JIS, en el sentido que introducen un cambio de codificacin, aunque se diferencian de aquellas en que estas deben preceder a cada carcter ancho del mensaje (no solo al primero de una secuencia). Por esta razn se considera que cada carcter multibyte del sistema EUC es auto-contenido y no depende de ningn control de estado.

3 Sistema de caracteres anchos Los sistemas de codificacin multibyte son bastante eficientes en cuanto al espacio de almacenamiento utilizado, pero son poco prcticos para su empleo como medio de almacenamiento en programas y cuando se daba realizar sobre ellos cualquier computacin. En estos casos es preferible utilizar un esquema en el que todos los caracteres tengan el mismo ancho, aun cuando esto suponga utilizar un cierto espacio adicional. Este sistema de codificacin es conocido como de caracteres anchos, del que existen dos versiones bsicas: sistemas que utilizan dos bytes, conocidos como DBCS ("Double Byte Character Set"), y sistemas que utilizan ms de dos.

ISO 10646.UCS-2 Caracteres de 16 bits (2 Bytes) ISO 10646.UCS-4 Caracteres de 32 bits (4 Bytes) ISO-10646-UCS-1 Caracteres de 16 bits (2 Bytes). Ms conocido como Unicode ( 2.2.1a2)

El sistema de caracteres anchos DBSC ha sido la solucin adoptada por los compiladores C y C++ para representar aquellos conjuntos de caracteres a los que no bastan las posibilidades del sistema ASCII extendido, aunque cabe destacar que la estrategias utilizadas en uno y otro lenguaje difieren ligeramente (ms detalles en 2.2.1a1). La representacin en el fuente es la siguiente: char ch = 'a'; char* str = "abc"; wchar_t wch = L'a'; wchar_t* wstr = L"abc"; // // // // constante cadena de constante cadena de carcter normal caracteres normales carcter-ancho caracteres anchos

You might also like