Sie sind auf Seite 1von 90

Curso de cPP Resumen de Contenido

http://www.zator.com/Cpp/E_Cr.htm Prlogo o o o o o o o o o o o o o o o o o o o o o o o o o o o o o Resumen de Contenido (esta pgina) ndice Convenciones y notacin 0.1 El Ordenador Electrnico Digital 0.2 El Sistema Operativo 0.3 El Hardware 1.1 Introduccin a la POO 1.2 El lenguaje C++ 1.3 Estructura de un programa 1.4 Proceso de creacin de un programa 1.5 Secuencia de ejecucin 1.6 Tratamiento de excepciones 1.7 Programacin actual 1.8 Estructura de la informacin 2.1 Atributos 2.2 Tipos de datos 3.1 Comentarios 3.2 Tokens 4.1 Declaraciones 4.2 Punteros 4.3 Matrices 4.4 Funciones 4.5 Estructuras 4.6 Campos de bits 4.7 Uniones 4.8 Enumeraciones 4.9 Operadores 4.10 Sentencias 4.11 Clases

0 Introduccin

1 Programacin C++

2 Variables

3 Elementos lxicos

4 Estructura del lenguaje

o o o o o o o

4.12 Plantillas 4.13 Tecnicismos 5.1 STL 5.2 Internacionalizacin 5.3 Entradas/salidas 5.5 Librera clsica 6.1 Reglas de lectura

5. Librera Estndar

6 Apndices 7. Bibliografa 9. Librera de ejemplos

A modo de prlogo
"... Creo que sera tan extravagante actuar decentemente en poltica que podra llegar a ser rentable. Y si no lo fuera, al menos nos respetaramos a nosotros mismos. Que no es poco". Antonio Robles en "Ciudadanos de Catalua y VidalQuadras" [7]. Artculo aparecido en el peridico on-line Libertad Digital

Todo esto puedes saltrtelo, se trata solo de justificarme a m mismo... Ms que "curso", tal vez deberamos decir apuntes, chuleta, traduccin o chapuza (para los ms exigentes). En principio son, mejor debera decir "nacieron", simplemente como unos apuntes personales para ponerme al da; para refrescar los conocimientos sobre C/C++, que tena bastante oxidados, pues los nicos pinitos al respecto que haba en mi "Currculum" fueron lo sucinto para hacer un pequesimo programa que leyera y escribiera en determinadas posiciones de memoria en un PC bajo MS-DOS; se trataba entonces de controlar una tarjeta de adquisicin analgico-digital especfica. La herramienta fue el compilador C 5.1 de Microsoft que an conservo. Ahora, unos 15 aos ms tarde, me veo en la necesidad de volver a utilizar el C; mientras tanto he odo, ledo y utilizado algo la programacin orientada a objetos, de forma que me pareca lo natural hacerlo en C++, as que lanza en ristre como D. Quijote, descargo el magnfico compilador C++ Builder de Borland-Imprise (que es gratis total), saco los viejos libros de C, y sobre todo, me bajo todas las ayudas que hay sobre el tema en el "site" de Borland. Adems, aunque conservo un librito de un tal Bjarne Stroustrup: "The C++ programming language", que vena de regalo con un compilador que compr entonces (1989): "Zortech C++ Compiler" (con el que confieso que no llegu a hacer gran cosa) y del que ahora me entero que el tal Stroustrup, adems de tener un nombre impronunciable, es nada menos que el inventor del C++. Bueno, a lo que iba: me pareca que el librito era poca cosa, as que encargo el nuevo y actualizado; un "tocho" de ms de mil pginas, que cuesta un @ y que es el no va ms sobre el tema [1]. Adems descargo algunas cosas que encuentro por ah sobre C++ que me parecen interesantes, algunas de las cuales encontrareis en el captulo de bibliografa (perdn si se me olvida citar alguna).

La primera sorpresa que me encuentro, al empezar a hincarle el diente a todo mi flamante bagaje informativo, es que aunque el viejo C de K&R [3] sigue estando bajo la piel del nuevo C++, el lenguaje ha evolucionado. Hace poco, mi hermano que es precisamente profesor de informtica, me dijo que el C era un lenguaje muy pequeo y fcil "Ni siguiera las E/S forman parte de l"; puede que eso sea verdad, creo que s [4]. Pero de lo que no me cabe duda, es que pertenezcan o no las rutinas de E/S al propio lenguaje (al fin y al cabo, salvo que hagamos un programa "autista", tendremos que utilizarlas), el pequeo beb ha crecido hasta convertirse en el monstruo que es ahora. Miro los ejemplos y ni siquiera entiendo la notacin... Lo que pensaba que sera un paseo militar, empieza a convertirse en algo a lo que tengo que dedicar muchas (muchsimas) horas, as que decido pasar muy despacito desde el principio hasta el final, y no se me ocurre mejor manera que ir haciendo mi propio libro de C++ por el sistema de ir cortando, pegando y traduciendo los diversos captulos del manual de ayuda "C++ Builder Languaje Guide" [2]. En algunos puntos voy incluyendo mis propias explicaciones o entresacados de otros textos que me parecen reveladores. Adems de enterarme, lo que pretendo es llegar a tener un texto donde yo mismo pueda encontrar lo que quiero sin que ocurra lo de siempre: "Lo he ledo en algn sitio pero no recuerdo donde...", con todos los ndices, tablas y referencias cruzadas que estime convenientes; como veris estoy describiendo mi propio mtodo de estudio cuando algo me interesa. El siguiente paso es bastante obvio: Porqu no ponerlo en la Red por si puede servirle a alguien ms?. Ya se que en la red hay mucho y bueno, pero casi todo en ingls; adems, pienso que si algn estudiante o programador hispano-hablante saca de aqu, aunque solo sea una idea o un concepto, habr cumplido su cometido. Dicho todo esto, solo me queda volver a advertiros que no se trata del docto trabajo de un sper experto en el tema. Se trata simplemente del trabajo de un programador "patatero" (que ha pelado muchsimas patatas) [5]. Si hay algn error es porque yo mismo no lo tengo claro, y por supuesto os agradecera cualquier puntualizacin, crtica o aportacin al respecto. Entiendo que a ms de uno le parezca un atrevimiento hacer unos apuntes, traduccin, etc sobre C++ admitiendo el propio desconocimiento; lleva razn, es atrevido, por eso he intentado explicaros el origen y la intencin. Adems, a fin de cuentas se ven por ah cosas peores; conozco a uno que ha puesto en su pgina personal el "careto" de su perro... Nada ms. Que sea leve!. Antes de despedirme, solo contaros un pequeo chiste que circula por las escuelas de informtica. Viene a decir que Stroustrup se mostr muy extraado del xito de su C++, y que en "petit comit" haba reconocido que lo nico que pretendi era que le subieran el sueldo a los programadores de los laboratorios de AT&T, y que lamentaba que algunas empresas hubieran ido a la bancarrota intentando pasar sus programas a C++...[6] Greetings (que dicen los Yanquis) Adolfo J. Milln Comienzo: Cdiz (Espaa), Agosto 2.000 Inicio.

[1] Casi todo el mundo est de acuerdo en que no es un libro para estudiar C++, sino la suprema referencia, "La Biblia" del C++, y que para entenderlo es imprescindible haber estudiado C++ previamente ("To read this book, you will need tons of C++ & OOP knowledge, even if you are an ace C programmer"). Ms datos sobre este libro en la Bibliografa ( comentarios sobre el mismo en Amazon ( www.amazon.com). Stroustrp 2000), extensos

[2] As pues, los derechos de autor corresponden principalmente a Borland-Imprise, pues originalmente se trata de una traduccin "No autorizada" de dicho manual. Espero que no me demanden por ello; el resto del copyright y los errores son mos. [3] K&R. Siglas con que se conoce a Brian W. Kernighan y Dennis M. Ritchie, creadores del lenguaje C. [4] Kernighan y Ritchie parece que tambin estn de acuerdo: "El lenguaje C no es grande y no le est bien un gran libro".... "Puesto que C es relativamente pequeo, se puede describir en un pequeo espacio y aprender con rapidez. En verdad, un programador puede razonablemente esperar conocer, entender y utilizar la totalidad del lenguaje" ( [5] Bueno... tambin tengo mi culturilla universitaria. [6] Mucho tiempo despus de escribir este prlogo, un amable lector me envi un divertidsimo email con una versin apcrifa del chiste aludido. Est en forma de una supuesta entrevista con Stroustrup, en la que este explica las razones de la invencin del lenguaje. Incluyo su trascripcin literal ( 0.Pw1) para que el lector tenga una idea aproximada de lo que le espera :-)) K&R).

[7] S. Ya se que no tiene nada que ver con el C++ o con la Informtica, as que perdonadme. Es que acabo de leerlo y me ha parecido tan hermoso que no he podido resistir la tentacin de ponerlo en algn sitio (que no solo de pan vive El Hombre!!).

1 Convenciones y notacin

Las notas a pi de pgina se han sealado con numeracin arbiga entre corchetes con un hipervnculo al lugar de la cita [1]. Las palabras clave y los identificadores que tienen un sentido especfico en C++, se han sealado en negrita y color negro. Por ejemplo: "auto, extern y register no son permitidos, s en cambio

static"
Cuando queremos destacar alguna palabra, smbolo o frase, utilizamos cuatro sistemas: resaltar el fondo; en negrita color azul, o simplemente en color rojo. Cuando queremos resaltar una idea (prrafo) utilizamos una lmpara .

Para los textos de ejemplos y explicaciones, tal como se escribiran en el cdigo fuente, se ha utilizado el tipo courier de espacio fijo con un fondo distinto y un sangrado a la izquierda Cuando va dentro de una frase de texto normal como aqu, adems del cambio de tipo y el fondo, se ha utilizado un color negro para resaltar la diferencia.

2 Referencias
A lo largo del texto existen innumerables referencias a otros epgrafes, con sus correspondientes hipervnculos, donde se comenta un concepto relacionado. El hipervnculo est entre parntesis con un pequeo icono ( o ). Por ejemplo: "La coma se usa tambin como un operador en las expresiones con coma ( 4.10.5)". En estos casos, y indican que se trata de una referencia en esta misma publicacin. Cuando el asunto referenciado est en una posicin anterior o posterior de la misma pgina, se utilizan los iconos y respectivamente. y hacen subir

Estas referencias estn siempre asociadas a los correspondientes hipervnculos.

y bajar en la misma pgina. El smbolo conduce a la pgina correspondiente, mientras que indica que se abrir una ventana auxiliar mostrando el asunto sealado. En estos casos se trata de una nota o ejemplo complementario al contenido de la pgina actual. Cuando la referencia se refiere a un libro tradicional (en papel), como los citados en la bibliografa, el icono utilizado es un libro abierto: . Cuando se trata de un artculo, libro o publicacin disponible .

en la Web en formato electrnico, el icono es

Finalmente, cuando la referencia se refiere a un artculo de revista o publicacin peridica tradicional, el icono es un montn de hojas . Este recurso se ha intentado utilizar al mnimo, para evitar al lector la frustracin de tener una referencia quizs inaccesible.

Ejemplo:
Una secuencia de declaraciones de propiedades de cualquier tipo (por ejemplo int capacidad;), incluyendo enumeraciones, campos de bits etc; as como declaracin y definicin de mtodos. Todos ellos con especificadores opcionales de acceso y de tipo de almacenamiento (auto, extern y

register no son permitidos, si en cambio static

4.11.7). Los elementos as definidos se denominan miembros de la clase; hemos dicho que son de dos tipo: propiedades de clase y mtodos de clase. Ejemplo: class vuelo { char nombre[30]; int capacidad; public: // // // // vuelo es la clase por defecto es privado capacidad es una propiedad a partir de aqu todo es pblico

char char void void }; Inicio.

origen[8]; destino[8]; despegue(&operacion}; crucero(&operacion);

// despegue es un mtodo

[1] Esto es una nota a pi de pgina. Si en ocasiones ves aparecer en el texto la nota [2] antes que la [1] no te preocupes; es que he tenido que incluir la segunda nota en una posicin anterior a la [1] que ya estaba colocada. De momento no he descubierto un sistema cmodo para renumerarlas al estilo de los procesadores de texto (FrontPage no tiene todava esta opcin).

Introduccin al C++
... appalled at the monstrous messes that computer scientists can produce under the name of improvements. It is to efforts such as C++ that I here refer. These artefacts are filled with frills and features but lack coherence, simplicity, understandability and implementability. If computer scientists could see that art is at the root of the best science, such ugly creatures could never take birth. R.P.Mody "C in Education and Software Engineering", ACM SIGCSE Bulletin Vol.23 No. 3 September 1991.

1 Presentacin del lenguaje C++


Con independencia de las explicaciones ms tcnicas que se incluyen en el captulo 1, digamos aqu que el lenguaje C++ es el resultado de una "larga" evolucin (informticamente hablando). Las cosas no nacieron de improviso como son ahora; se ha ido puliendo y completando a lo largo del tiempo. Adems de importar conceptos de lenguajes anteriores. Por ejemplo, de Simula67 ( 0.Iw1) y

Algol68 ( Stroustrup 1987), para lo bueno y para lo malo [1], el lenguaje C++ incorpora muchas caractersticas heredadas del C, su ancestro ms directo, el cual recoge a su vez influencias anteriores: B, BCPL ( 0.Iw2), etc. ( K&R).

Nota: es mucho lo que puede encontrarse en la red sobre los orgenes del C y sus influencias previas, pero uno de los mejores documentos, con la autoridad que le confiere ser precisamente de uno de sus creadores, es: "The development of the C language" ( Dennis M. Ritchie).

Para los que estudian C++ como una herramienta de trabajo, aunque en realidad su profesin no es la informtica, sino otra ms "cientfica", una advertencia: como todos los lenguajes de programacin (obra de los ltimos cinco segundos de la evolucin del hombre), C++ es muy "artificial", y aunque los informticos son gente bastante lgica, las cosas son as porque s. No se le puede pedir el tipo de lgica que encontramos en las Matemticas o en la Fsica por ejemplo. El resultado de todo esto es que C++ est repleto de conceptos y detalles inter-relacionados; reglas que son as por "definicin"; porque a su inventor le pareci que eran la mejor forma de hacerlas o porque vienen heredadas [3]. Cuestiones que podran quizs ser de otro modo, pero son as por

compatibilidad (con el C); otras reglas tienen sus excepciones tambin por tradicin o por herencia; etc. Para el comn de los mortales es imposible hacerse una idea exacta con una primera lectura, pues muchos conceptos solo cobran su verdadera dimensin cuando se entienden otros a los que no se ha llegado todava [1a]. Hace tiempo le sobre un personaje histrico del que decan que tena tal capacidad, que lea los libros por el sistema de ir arrancando y tirando las pginas ledas. Desde luego no es el caso del C+ +; es ms que posible que cualquier libro de C++ requiera mltiples relecturas, cada una de las cuales nos proporcionar una mejor y ms detallada perspectiva del lenguaje, de sus enormes posibilidades e incluso de los niveles de refinamiento y sofisticacin que pueden alcanzarse con l [2]. El propio inventor del lenguaje afirma al respecto: "Don't panic!. All will become clear in time" [2a]. Se me ocurre que una buena analoga seran esas imgenes Web que aparecen progresivamente y que solo se ven con nitidez cuando se ha terminado su descarga [4]. Las referencias a otros puntos hace que constantemente tengamos que saltar de un sitio a otro (por fortuna los documentos HTML y el navegador vienen que ni pintados para el caso, podemos saltar a una cita y volver inmediatamente el punto de partida con un par de clic de ratn). Est fuera de toda duda que C++ es un lenguaje difcil y spero; podramos citar al menos una decena de "lindezas" que se han dicho acerca de l (hemos incluido aqu alguna con objeto de que el estudiante sepa a que se enfrenta). Sin embargo, nuestro nimo no es disuasorio sino todo lo contrario; considere que simplemente debe dedicarle una especial atencin y esfuerzo, en la seguridad de que el lenguaje lo merece. Tengo un amigo al que le gusta decir que hay dos clases de "informticos": Los que saben C++ y los que no merecen llamarse informticos. Seguramente es exagerado, pero estoy convencido que su estudio constituye la base de la informtica actual. Su rastro puede verse por doquier, incluso en lenguajes tan de moda y actuales como Java, php o JavaScript. De forma que su conocimiento le da al estudiante no ocasional de informtica una inmejorable posicin de partida para adentrarse en otras materias. En mi opinin el estudio de C++ en las Escuelas de Informtica sera comparable al estudio de anatoma en las de Medicina. Seguramente necesitar bastantes horas para llegar a dominar C++, pero es con diferencia "El Rey" de los lenguajes de programacin. Habr merecido la pena!.

2 El C++ real y el C++ Estndar


Al hablar de lenguajes no privados [5] tan universales como C++, es un Comit Internacional el que decide como es (o debe ser) el lenguaje ( E1[2]). Posteriormente los fabricantes de compiladores intentan adecuar sus productos a las directrices del Estndar, aunque en ocasiones incluyen por su cuenta caractersticas y funcionalidades especficas (principalmente en las libreras que acompaan al compilador en forma de herramientas). Esto significa que existen tantas versiones de C++ como plataformas distintas, ya que existen compiladores C++ para virtualmente cada combinacin de hardware y Sistema Operativo conocidos. Las diferencias entre estos C++ reales y el C++ Estndar (o de Stroustrup) como lo denomin algn autor [6], es por supuesto variable en funcin del grado de adecuacin que haya logrado cada fabricante. Adems, el Estndar es bastante tolerante y permite a los implementadores decidir por su cuenta ciertas cuestiones de detalle. Todos estos factores hacen que en ocasiones, dos

compiladores distintos aplicados al mismo cdigo conduzcan a resultados diferentes. Por supuesto, no nos referimos a que 2 + 2 dejen de ser 4, sino a errores y avisos de cosas que son o no permitidas en segn qu plataforma. A las consideraciones anteriores hay que aadir que los ordenadores son finitos, lo que exige que las aplicaciones que corren en ellos sean necesariamente finitas. En consecuencia, los fabricantes de compiladores se ven obligados a imponer ciertas condiciones y lmites a sus productos. Por ejemplo: el Estndar dice que los bloques, zonas de programa englobadas en llaves { }, pueden ser anidados (bloques dentro de otros bloques). Sin embargo las implementaciones pueden sealar un lmite mximo de anidamiento para estos casos. Naturalmente los lmites y condiciones pueden variar para cada compilador. El Estndar solo exige que estas limitaciones estn debidamente documentadas. Nota: En esta obra hemos utilizado los tres compiladores C++ de uso ms popular en el mundo de la informtica personal y empresarial: El compilador Borland C++ de Imprise. El Visual C++ de Microsoft, y el C++ de la Open Software Foundation (GNU Cpp). Los dos primeros son para la plataforma Wintel. El ltimo para Linux. Desafortunadamente, la versin que dispongo de "Visual" es bastante antigua (1998). Como comprobar el lector a lo largo de estas pginas, aunque por fortuna los tres compiladores son bastante consistentes y se aproximan al Estndar, esta concordancia no siempre es perfecta y los resultados no siempre coinciden en algunos rincones del lenguaje. En aquellas ocasiones en que hemos detectado disparidades se han incluido las observaciones pertinentes. Tenga en cuenta que estas se refieren siempre a versiones concretas de cada compilador y que las divergencias pueden o no manifestarse si se utilizan otros compiladores u otras versiones.

Tanto si se va a acometer un nuevo proyecto, como si se debe mantener el cdigo de aplicaciones ya existentes (que los anglosajones denominan "legacy code"), es importante tener claras algunas cuestiones relativas a la estandarizacin de lenguaje y al grado de adaptacin de cada plataforma o compilador concreto. Estas cuestiones aparecen con cierta regularidad en los foros de debate, y aunque no conciernen estrictamente a nefito, en cambio s son importantes para el profesional que se enfrenta a situaciones del mundo real. Son las siguientes:

2.1 Adecuacin al Estndar


Observe que la declaracin de que un compilador o plataforma de desarrollo "sigue el Estndar", solo indica que la parte cuyo comportamiento est definido en la norma, se comporta exactamente segn lo indicado por esta, pero que lo anterior no es bice para que pueda contener extensiones especficas (no estndar), ni para que carezca de todas las caractersticas especificadas en la norma (lo que se denomina "100% conforme). Algunas funcionalidades sencillamente pueden faltar (no estar implementadas). Nota: en general las deficiencias o carencias se refieren a las partes ms modernas del lenguaje. Especialmente algunos aspectos del tratamiento de clases y funciones genricas ("templates"). En el momento de actualizar esta pgina (Diciembre 2006), solo un compilador que conozca, presume de ser 100% "compliant"; el resto presenta diverso grado de adecuacin. Desde las muy bajas, como son proverbialmente las antiguas versiones de Microsoft VC++,

hasta las modernas, en las que es del orden del 99%. De acuerdo con los expertos, los compiladores ms conformes por el momento son: la serie GNU c++ 4*; VC 2k3; VC 2k5; Intel C++ 8.0 y Comeau 4.2 (o versiones posteriores). Salvo casos de fuerza mayor, que se deba lidiar con "legacy code", el consejo de los expertos es no considerar siquiera cualquier compilador cuyo fabricante no lo haya actualizado en los ltimos cuatro aos.

2.2 Importancia de escribir cdigo estrictamente estndar


La cuestin es totalmente independiente de la anterior, aunque su planteamiento carece de sentido en el supuesto de que utilicemos un compilador que carece de extensiones particulares y sigue el estndar al 100%. Las posturas "relajadas" a este respecto se sintetizan en que debe primarse la rapidez en la puesta apunto de la aplicacin. Sus defensores argumentan que les importa ms completar rpidamente las aplicaciones, que la pureza conceptual o formal de su cdigo, y que a sus clientes solo les importa el precio final de las mismas. En consecuencia, debe utilizarse sin escrpulo cualquier caracterstica o recurso disponible en la plataforma. Las posturas estrictas argumentan que el costo de mantenimiento de las aplicaciones es tanto o ms importante que el de su desarrollo inicial, y que en consecuencia, debe seguirse escrupulosamente el Estndar. Sobre todo, teniendo en mente la posibilidad de que el usuario pueda migrar a otra plataforma en el futuro. En cuyo caso, la fidelidad al estndar pagar sus rditos. Las posturas extremas preconizan incluso utilizar solo aquel subconjunto del Estndar que sea universalmente soportado, intentando huir de "rincones oscuros" cuyo comportamiento exacto dependa del compilador.

3 Organizacin y plan de la obra


La propia naturaleza del lenguaje y las, ya sealadas, complejas inter-ralaciones entre sus partes, hacen que en principio sea difcil establecer un orden de exposicin, un "Plan de la obra" que diramos. En este caso el "Plan" no ha existido en absoluto, como se indic en el prlogo, comenc aproximadamente con el mismo orden que en "C++ Builder Languaje Guide", al que se han ido haciendo retoques. De todas formas, sea cual sea el plan de la obra, inevitablemente aparecern cuestiones para las que seguir su hilo argumental requerir un proceso de saltos de un sitio a otro, puesto que si se encadena la exposicin siguiendo un orden conceptual determinado, otros conceptos vendrn inevitablemente desordenados. Parece ser que la naturaleza del conocimiento es ms bien una suerte de inter-relaciones ms parecidas a las redes neuronales que a una cinta de casete. A lo largo de estas pginas me ha venido a la mente muchas veces lo desesperante que debe ser preparar un proyecto docente para esta asignatura que no pueda ser fcilmente discutido. En cualquier caso, la lectura de libros electrnicos como el presente (al menos para mi) presentan un cierto problema. No aparecen los captulos uno detrs de otro como en los libros clsicos "en papel", en los que hay un orden "natural"; un principio organizacin posicional y de orden de lectura. La ubicuidad del texto electrnico resulta molesta en cierto sentido. Tengo que reconocer que no estoy demasiado satisfecho de la "navegabilidad" en el formato actual, lo que no significa que no sea cmodo saltar de un sitio a otro (esto me pasa en general con todos los sistemas de ayuda on-line).

Si eres de los que prefieren tener la idea de un cierto orden, te aconsejo que utilices el ndice; est a una distancia de un solo clic de ratn de cualquier pgina en que te encuentres: [Indice] en la esquina superior derecha. Inicio. [1] Respecto a esta influencia, hay opiniones para todos los gustos. En el enlace adjunto puede encontrar una de ellas, "Why C++ Sucks" (en ingls). Originalmente el documento estaba en http://world.std.com/, sin embargo, a mediados de 2006 un lector me avis que el enlace estaba roto. No he podido volver a encontrar el documento original (parece como si se lo hubiese tragado la red). Sin embargo, afortunadamente conservo una copia en mi archivo histrico Why C++ Sucks.

[1a] "Then there are the many hidden features in C++ that you cannot reveal up front"... "There is a lot to learn after you learn the language. First you solo. Then you get your pilot's license. Then you learn how to fly. Learning C++ is a process of discovery". Al Stevens "C. Programming". Dr. Dobb's Journal. Sept. 1992. [2] Es frecuente que encontremos trozos de cdigo elegantsimos pero tambin difciles de desentraar en una primera lectura. Como botn de muestra, las dos sentencias que siguen son perfectamente correctas en c++: int z = *pt3+-*++pt3; void (_USERENTRY * _RTLENTRY _EXPFUNC32 signal(int __sig, void (_USERENTRY * __func)(int))) (int); [2a] Stroustrup TC++PL 2.9 [1]

[3] Los comits de estandarizacin tambin tienen mucho que decir al respecto, de forma que la versin "Estndar" de cualquier lenguaje es algo que se escapa de las manos y del control de su creador inicial. [4] Son las imgenes GIF entrelazadas o las JPEG progresivas. [5] "Not proprietary" que no son propiedad intelectual de ninguna empresa o institucin. De esta forma no existe un nico "fabricante" del lenguaje que decide sus caractersticas. En caso contrario, por ejemplo el de Java, propiedad de la compaa SUN, es esta ltima la que controla su desarrollo. [6] Desde su alumbramiento, el Dr. Stroustrup ha seguido muy de cerca la evolucin y desarrollo de su "criatura", aunque desde luego, actualmente la ltima palabra la tiene el comit encargado de elaborar el Estndar al que l mismo pertenece.

0.1 El Ordenador Electrnico Digital


"Calcular con nmeros es en s mismo una forma de razonamiento, y buena parte del razonamiento que las personas hacemos se puede considerar una forma de computacin... La computacin y el razonamiento lgico son en

realidad las dos caras de una misma moneda". Martin Davis "La Computadora Universal, de Leibniz a Turing". Editorial Debate S.A. Madrid 2002.

1 Presentacin:
Imaginamos sobradamente conocidos por cualquier estudiante de C++ los principios generales sobre los que se basan los ordenadores electrnicos digitales; las mquinas en las que probablemente se ejecutarn sus programas. Sin embargo, no est de ms un brevsimo repaso a fin de refrescar y traer al tiempo presente algunos conceptos. Nota: En muchos pases hispano-hablantes de cultura tcnica ms influenciada por USA, se utiliza el trmino "computadora" por ordenador; ms parecida a su equivalente ingls "Computer". Por su parte, la versin castellana deriva del francs "Ordinateur". Esta es tambin la razn por la que en hispano Amrica se dice "La PC", mientras que por aqu decimos "El PC", en referencia al ordenador (masculino).

2 Ordenador electrnico digital:


"Underlying our approach to this subject is our conviction that 'computer science' is not a science and that its significance has little to do with computers. The computer revolution is a revolution in the way we think and in the way we express what we think". Harol Abelson y otros. "Structure and Interpretation of Computer Programs". 2 Edicin 1999. The MIT Press Cambridge, Massachusetts. Cualquier dispositivo capaz de resolver problemas mediante proceso de la informacin en forma discreta. Recordemos que aqu, el trmino "digital" se usa en contraposicin a "analgico", y significa que la informacin se representa internamente en forma de nmeros. Por contra, en los dispositivos analgicos la informacin est representada por tensiones y/o intensidades si el dispositivo es electrnico. Aunque pueden existir dispositivos analgicos no elctricos. Por ejemplo, mecnicos, hidrulicos, pticos. etc. En estos ltimos la informacin est representada por la posicin o desplazamiento de ruedas o palancas; por la presin o circulacin de un fluido en un conducto, o por la propagacin de la luz en un circuito (que puede ser una fibra ptica). Mediante el recuento, comparacin y manipulacin de estos nmeros, de acuerdo con un conjunto de instrucciones almacenadas en su memoria, un ordenador electrnico digital puede realizar multitud de tareas: Realizar complejos clculos matemticos; reproducir una meloda o ganar una partida de ajedrez al campen mundial humano de la especialidad. La informacin se presenta en forma de datos e instrucciones (algoritmos) para su manipulacin y, como hemos sealado, est "digitalizada". Es decir, reducida a magnitudes numricas discretas (nmeros racionales) representados a su vez en formato binario. Este formato utiliza magnitudes que solo pueden adoptar dos valores mutuamente exclusivos (cierto y falso, cero o uno, encendido o apagado, Etc.) Por consiguiente, pueden representarse con solo dos smbolos (grficamente O y 1). En contraposicin, el formato decimal tiene diez dgitos (del 0 al 9 en el sistema arbigo). Esta forma de representacin es vlida no solo para la informacin textual, representada mediante el cdigo ASCII, Unicode, o cualquier otra convencin. Tambin las cantidades numricas, las imgenes, los colores, los sonidos y los algoritmos, estn almacenados en el ordenador en formato binario. Resulta

as, que el universo de las computadoras electrnicas digitales es un ocano de nmeros binarios que representan datos e instrucciones para su manipulacin. Nota: No confundir los conceptos: electrnico (basados en la electrnica); digital (utilizar magnitudes discretas representadas por nmeros) y binarios (utilizar este modo de representacin, una lgica y un lgebra de Boole Int Ap.K). Nada impide la existencia de ordenadores no electrnicos. Por ejemplo, mecnicos, pticos, biolgicos o basados en fluidos. Tambin han existido y existen ordenadores analgicos (no digitales) exclusivamente mecnicos. Por ejemplo, la humilde regla de clculo, o dispositivos ms sofisticados, como elementos de puntera y direccin de tiro de artillera. Tampoco existe inconveniente terico para la existencia de ordenadores digitales no binarios [9]. El hecho de que los actuales ordenadores electrnicos digitales sean binarios, se debe, entre otras razones, a que los circuitos elctricos estn especialmente adaptados al modo binario. Simplemente haciendo corresponder los dos posibles valores de la variable con dos estados fsicos de un circuito o dispositivo. Por ejemplo, con los estados de: conduccin no conduccin; tensin, sin tensin; magnetizado no magnetizado; con luz, sin luz; Etc. Como el lgebra de Boole [1] maneja variables que solo pueden tener dos estados ("cierto" y "falso"), es muy fcil representar y emular comportamientos y ecuaciones de este lgebra mediante circuitos electrnicos. As, construir un circuito electrnico que responda (que proporcione como salida) el OR, AND, NOR, XNOR, Etc. de ciertas variables de "entrada", es trivial desde el punto de vista de diseo de circuitos lgicos. Es relativamente fcil disear un circuito digital que responda a unas "Ecuaciones" lgicas (de Boole) por complejas que sean. Nota: Han existido intentos de construir ordenadores digitales en base a lgicas no binarias. Por ejemplo, "ternarias". Actualmente se empieza a hablar de la computacin cuntica, basada en algo distinto a dos estados mutuamente exclusivos.

3 Propiedades de los datos


Ms adelante ( 2) se incluyen algunas puntualizaciones sobre el asunto de datos e instrucciones (algunas casi filosficas), pero por ahora nos centraremos en los primeros (los datos) para aclarar algunos conceptos que, con frecuencia se confunden. Nota: Al ser este un manual o curso de C++, encontrar que la mayor parte de l se refiere a los algoritmos.

3.1 Los datos como colectivo


Aunque en ltimo extremo todo son nmeros, desde un punto de vista macroscpico, a los informticos les gusta referirse a los datos clasificndolos en dos grandes apartados que se corresponden mejor con la imagen que el humano tiene de ellos: numricos y textuales o alfanumricos . Cuando estos datos no estn en la memoria interna sino en dispositivos externos (generalmente discos magnticos u pticos), se agrupan en ficheros, de los que existen infinidad de tipos; aunque es frecuente agruparlos en dos grandes categoras: textuales y binarios [6].

Nota: En algunos Sistemas, por ejemplo Windows, es costumbre que los ficheros del mismo tipo (de la misma "familia") tengan nombres con la misma terminacin [10]. Tradicionalmente esta terminacin la componen tres letras despus del nombre separadas de l por un punto, lo que permite identificar fcilmente los ficheros de la misma familia. Existen tantos tipos como la imaginacin de los programadores y fabricantes de software han sido capaces de crear (.TXT; .DLL; .DOC; .ASP; Etc.) Generalmente el sistema operativo asocia cada fichero (no ejecutable) con una aplicacin (ejecutable) que es la encargada de su manejo [8]. A este proceso se le denomina asignacin de extensiones de nombres de archivo.

3.1a Datos textuales.


Se refieren a la idea que todos tenemos de aquella informacin que puede ser representada mediante la escritura. Tienen cuatro atributos o caractersticas que conviene matizar: Lengua natural [2] en que se haya representado, que puede ser cualquiera de las conocidas: Espaol, Francs, Ingls, Alemn, etc. Sistema de escritura utilizado. Existen dos: alfabticos e ideogrficos. Los primeros utilizan un conjunto reducido de smbolos (caracteres) para representar las palabras. Para nosotros es el denominado "Sistema occidental" que se basa en un alfabeto de raz latina, aunque naturalmente existen otros: rabe, Griego, Etc. Los sistemas ideogrficos utilizan smbolos (ideogramas) para representar ideas. Existen sistemas que son combinacin de ambos. Juego de caracteres. Es el conjunto de caracteres distintos que se utiliza en un documento. Por ejemplo, aunque el Espaol y el Francs utilizan un alfabeto de raz latina, algunos caracteres y signos de puntuacin son distintos, de forma que ambos idiomas utilizan distinto juego de caracteres ("Character set"). Sistema de codificacin empleado para traducir los grafos del alfabeto a nmeros. Se empez utilizando el US-ASCII, pero actualmente el sistema ms utilizado es Unicode ( 2.2.1a).

3.1b Datos binarios


La informtica trata cada vez ms con los tipos de datos denominados "Multimedia", sonidos e imgenes [3], en multitud de formas y calidades: Monoaural, estreo, Dolbi-digital, MP3, Etc. para los primeros; Estticas o en forma de flujo (stream), en color o en blanco y negro, Etc. para las segundas. Aunque tanto los sonidos como las imgenes son de naturaleza intrnsecamente analgica, los informticos han inventado sistemas para digitalizarlas (reducirlas a nmeros) con la menor prdida de calidad y de la forma ms comprimida posible. Aqu se habla de "codecs" para referirse a los diversos algoritmos que a la postre reducen los sonidos o imgenes a ficheros de nmeros, y posteriormente reconstruyen los sonidos e imgenes a partir de los nmeros. Estos ficheros son conocidos de forma genrica como "binarios".

3.2 Datos individuales


Desde la ptica de los lenguajes como C/C++, los datos son bsicamente de dos tipos: numricos y caracteres. Existen diversos subtipos de los primeros, el ms simple de los cuales es el entero corto sin signo unsigned

short. De los segundos existe menos variedad; bsicamente solo dos tipos: caracteres estrechos y anchos (char y wchar_t). En cambio presentan la ventaja de que pueden
agruparse en cadenas (arrays o matrices) de cualquier longitud. Son las denominadas "cadenas alfanumricas", en las que sus elementos (caracteres) pueden ser alfabticos (letras), numricos (guarismos) y signos de puntuacin (interrogacin, punto, coma, Etc.) Ambos tipos de datos, numricos y caracteres, son conocidos colectivamente como escalares. En ellos pueden distinguirse varios aspectos:

3.2a Representacin simblica


Corresponde a la representacin de los datos en el programa (fuente) y en la mente del programador. En lo que respecta a los primeros (magnitudes numricas), nuestra cultura "Occidental" utiliza para su representacin el denominado sistema de numeracin decimal con cero , inventado por la antigua cultura Indostnica. Sin embargo, la notacin que empleamos es arbiga [5]. La razn de que haya prevalecido frente al sistema latino (nmeros "romanos") es simplemente que es mucho ms adecuado para las operaciones aritmticas (una de las causas del escaso desarrollo de las matemticas en la Roma Clsica, fue precisamente lo inadecuado del sistema de numeracin que utilizaban). Para la representacin de caracteres utilizamos un alfabeto de raz latina que, aunque coincide en lo sustancial, presenta algunas diferencias entre los distintos idiomas occidentales. Como resultado de lo anterior, escribimos que la variable pi vale 3.1416 y la primera letra mayscula del alfabeto es A. Nota: Es tradicin informtica que algunas constantes numricas sean representadas en el fuente por una representacin distinta de la decimal. Por ejemplo, octal o hexadecimal .

3.2b Sistema de codificacin.


Se refiere a una regla por la que los caracteres son transformados en nmeros manipulables por el ordenador (los datos numricos ya lo estn). Existen dos formas de hacerlo: los sistemas de ancho constante y los de ancho variable. En ambos casos la estrategia consiste en ordenar el juego de caracteres (letras, guarismos y signos) en una tabla, y hacer corresponder un nmero con las posiciones sucesivas de la misma. La diferencia entre ambos sistemas es que los primeros utilizan representaciones numricas que ocupan siempre el mismo espacio en el interior de la mquina (generalmente 8 o 16 bits). Por contra, los sistemas de codificacin de ancho variable o multibyte, tratan los caracteres de forma parecida a lo que ocurre con los dato numricos. Es decir, que su representacin no ocupa siempre el mismo espacio. En estos sistemas existen caracteres cuya representacin puede abarcar 1, 2, 3 o incluso 4 bytes. La ms conocida y famosa de estas tablas es la US-ASCII, que tiene 127 posiciones y es de ancho constante. Aqu cada carcter se representa por un nmero cuya representacin ocupa siempre 8

bits ( 2.2.1a). La internacionalizacin de la informtica, que empez a manejar juegos de caracteres de otras culturas e idiomas distintos del ingls-americano, oblig a utilizar tablas ms extensas, en las que rpidamente se sobrepas la cantidad de 256 elementos (caracteres distintos), que es el mximo que puede expresarse con 8 bits (ver ms adelante ).

3.2c Representacin interna


Tambin denominado formato fsico. Se refiere a la forma en que estn representados los nmeros en el sistema binario, nico soportado por el ordenador. Aqu se siguen dos estrategias. La primera, ms simple y uniforme, se aplica a los caracteres. Estos se representan siempre por magnitudes binarias de igual longitud; 8 o 16 bits, segn se trate de caracteres normales (estrechos) o anchos. La segunda, ms compleja y elaborada, corresponde a la representacin de las magnitudes numricas, para las que se utiliza un sistema de ancho variable bastante sofisticado que incluye varios subtipos. La razn de esta complejidad es doble. La primera de economa de espacio, de forma que, a costa de no poder representar determinados valores, algunas representaciones utilizan menos espacio [7]. Por ejemplo, un unsigned short no puede ser negativo ni mayor que 65,535; a cambio puede ser almacenado en 16 bits. Por contra, los nmeros muy grandes o muy pequeos requieren mayores espacios de almacenamiento, hasta 80 bits ( 2.2.4).

Adems de la anterior, razones de precisin, y de poder representar cantidades positivas y negativas, ha motivado la aparicin de algunas variedades de representacin (binarias desde luego) a cuyos detalles dedicamos un captulo ( 2.2.4a).

Nota: Aunque hayamos sealado que existen sistemas de codificacin de ancho variable para los caracteres, como veremos a continuacin, la representacin interna de estos utiliza siempre un formato de ancho fijo, dejando la representacin de ancho variable para almacenamientos externos y comunicaciones.

3.2d Codificacin y representacin externas.


Con frecuencia los programas tienen que habrselas con el mundo exterior, con el que deben intercambiar informacin. Por ejemplo, determinados datos pueden ser ledos o escritos a un fichero de disco o a una lnea de comunicacin. Es muy frecuente que, tanto el sistema de codificacin como la representacin del fichero utilizadas por el dispositivo, sean distintas de las utilizadas internamente por el programa. El resultado es que debe efectuarse las correspondientes conversiones de cdigo y de formato durante las operaciones de E/S. Por ejemplo, mientras que en el programa, los caracteres estn siempre representados por magnitudes numricas de longitud fija (1 o 2 bytes), en los ficheros de disco y lneas de comunicacin suelen utilizarse sistemas de codificacin multibyte. En los que los caracteres ocupan distinto ancho segn el caso.

4 Sistemas de representacin numrica


En lo que sigue daremos un breve repaso a los distintos modos de representacin simblica utilizados para los datos numricos, haciendo hincapi en los aspectos informticos de la cuestin.

4.1 Sistema decimal


En cuanto al problema de representar internamente cantidades numricas, el sistema tradicional (el decimal con cero al que estamos acostumbrados), no es muy adecuado para los dispositivos electrnicos, puesto que aqu, al ser un sistema de base 10, las variables (las cifras), pueden tener diez valores distintos (los guarismos 0 al 9 si utilizamos el sistema arbigo de numeracin). Recordemos que en este sistema, una cantidad cualquiera, por ejemplo 1798, en realidad se lee como: 1 x 103 + 7 x 102 + 9 x 101 + 8 x 100 == 1 x 1000 + 7 x 100 + 9 x 10 + 8 x 1

Observe la diferencia entre los diversos conceptos involucrados: El nmero o cantidad "mil setecientos noventa y ocho", su representacin en el sistema decimal (1978) y las "cifras" o "guarismos" que componen su representacin en este "sistema de numeracin" (en este caso cuatro cifras: 1, 7, 8 y 9 colocadas en un cierto orden). Desde la escuela primaria sabemos que este en este sistema, el valor de las cifras viene complementado por su posicin en el conjunto (decimos que es posicional), de forma que el valor total de una expresin viene representado por el producto de su valor-base (0 a 9) multiplicado por la potencia de 10 que corresponda segn su posicin. Al final se suman los resultados parciales. Resulta as que en el sistema decimal, la cantidad mas alta que se puede representar mediante una cantidad de cuatro cifras, nnnn es, como mximo: 9 x 103 + 9 x 102 + 9 x 101 + 9 x 100 == 9999 (10.000 si le aadimos el cero).

Es fcil verificar que un nmero decimal de n dgitos puede representar como mximo una cantidad igual a 10n. En el caso del ejemplo, para 4 dgitos, 104 = 10000. Observe que el mismo concepto (la misma cantidad) puede ser representada utilizando distintos sistemas de numeracin, por ejemplo: MDCCXCVIII en nmeros romanos (como dijimos, un sistema muy poco adecuado para las matemticas).

4.2 Sistema binario


El sistema binario puede representar igualmente cualquier cantidad basndose en cifras que solo pueden tener dos valores, 0 y 1 ( ). El sistema es exactamente anlogo al decimal, con la diferencia de las potencias; de 2 que es la nueva base (en vez de 10 como en aquel caso). Por tanto, la cantidad binaria 11100000110 se lee: 1x210 + 1x29 + 1x28 + 0x27 + 0x26 + 0x25 + 0x24 + 0x23 + 1x22 + 1x21 + 0x20 Si el lector quiere "sacar la cuenta" ver que conduce igualmente a "mil setecientos noventa y ocho". Una magnitud que solo puede tener dos valores se denomina bit, abreviatura de "Binary digit" (dgito binario). Es la menor cantidad de informacin que puede concebirse. Su abreviatura es b. Por ejemplo: 10 Kb son 10.000 bits. Resulta as, que un interruptor que puede estar encendido o

apagado es (puede ser) un almacenamiento de 1 bit de informacin (basta con hacer corresponder "encendido" con uno de los valores y "apagado" con el otro). El asunto es que estas variables "binarias" (que solo pueden adoptar dos valores distintos), son mucho mas adecuadas para su representacin en dispositivos elctricos, magnticos y pticos que las "decimales", por lo que es este el "formato" elegido para la representacin y almacenamiento de datos numricos en los ordenadores electrnicos digitales. La capacidad de representacin de este sistema es sin embargo menor que en el decimal, as, una cantidad binaria de 4 dgitos puede representar como mximo: 1 x 23 + 1 x 22 + 1 x 21 + 1 x 20 == 15 (16 si aadimos el cero)

Es fcil verificar que, en este sistema de numeracin, un nmero de n dgitos puede representar como mximo una cantidad igual a 2n (en el caso del ejemplo, para 4 dgitos, 24 = 16). La tabla adjunta expresa las cantidades que se obtienen con la unidad, seguida de cierto nmero n de ceros en los sistemas decimal y binario. Lo que representa las potencias n de la base de numeracin. Es decir: 10n o 2n. Base 10 Nmero decimal Base 2 Nmero binario 100 101 102 103 104 105 106 107 108 109 1010 1 10 100 1000 10000 100000 1000000 10000000 100000000 1000000000 10000000000 20 21 22 23 24 25 26 27 28 29 210 1 10 100 1000 10000 100000 1000000 10000000 100000000 1000000000 10000000000 Equivalente decimal 1 2 4 8 16 32 64 128 256 512 1024

4.3 Sistema Unario


Del mismo modo que las cifras del sistema binario pueden tener dos valores, las cifras de este sistema solo pueden tener uno. Su representacin puede ser cualquiera, 1, *, x, Etc. Es el sistema de los hombres primitivos; el mtodo de representacin de una cantidad se limita pintar un palote en la pared o aadir una cuenta a un collar para cada unidad (es tambin el sistema de numeracin de los prisioneros de las pelculas en sus celdas). En este sistema las cantidades 3 y 4 se representaran: *** **** Podramos encontrar en cualquier texto una expresin como: 10110111 con la indicacin de que no es un nmero binario sino unario. En tal caso, sabemos que no es la representacin del decimal 183, sino la representacin de las cantidades 1, 2 y 3. La verdad es que este sistema no se utiliza en

informtica a excepcin de algunos supuestos tericos. Por ejemplo, en la mquina de Turing ( 0.1.1).

4.4 Otros sistemas de representacin numrica


Adems del decimal y el binario (este ltimo es el sistema "natural" del ordenador), en la literatura informtica y en los fuentes de los programas se utilizan otras formas de numeracin; sobre todo para representar valores constantes ( 2.2.4b) y BCD ( 0.1w1). 3.2.3b). Son los sistemas octal ( 2.2.4b); hexadecimal (

5 Almacenamiento interno
Tradicionalmente el almacenamiento interno de los ordenadores se organiza desde el punto de vista lgico en grupos de 8 (o mltiplos de 8) cifras binarias (bits). Estos conjuntos (octetos) son la menor cantidad de informacin que trata el ordenador con entidad propia; reciben el nombre de bytes y suele abreviarse con B. Por ejemplo, 16 Kb y 16 KB. Se refieren a 16000 bits y 128.000 bits respectivamente [4]. Nota: Hemos sealado que bit es abreviatura de Binary Digit, mientras que el nombre Byte fue acuado en la dcada de los 50 por Werner Bushholz de la IBM; la palabra proviene de una mutacin de "bit", hecha de forma que no hubiese confusin al pronunciarlas (bit y byte suenan muy distintas en ingls). En ocasiones, adems de los octetos, se utilizan agrupaciones de 4 bits, reciben el nombre de nibble. As que 2 nibbles == 1 Byte. Podemos usar un smil para entenderlo: aunque nuestro alfabeto tiene 26 caracteres no solemos utilizarlos aislados. Para que tengan significado se utilizan en grupos (palabras). Los ordenadores utilizan tambin palabras, solo que estas son siempre de la misma longitud (8, 16, 32 o 64 bits segn el modelo de procesador). Segn lo anterior, un octeto (una "palabra" de 8 bits), 1 Byte, puede contener un nmero de hasta 28 = 256, lo que deriva en que si reservamos una palabra de 8 bits para "describir" (contener) una variable, sabemos de antemano que dicha variable no va a poder adoptar ms de 256 estados distintos. Esto, unido al hecho de que la forma de representacin interna utiliza el sistema binario y los elementos y circuitos fsicos son igualmente binarios (pueden adoptar solo dos estados), hacen que las potencias de dos: 8, 16, 32, 64 Etc. sean "nmeros mgicos" en el mundo de las computadoras.

Temas relacionados: Tipos bsicos: Representacin interna y rango ( 2.2.4) 2.2.4a)

Representacin binaria de las cantidades numricas ( Orden de almacenamiento ( 2.2.6a).

Alineacin interna (

4.6.1)

Inicio. [1] George Boole (1815-1864). Matemtico ingls cuyos trabajos tericos sobre conjuntos de nmeros binarios (que solo pueden adoptar dos valores), ayud a establecer las bases de la moderna lgica simblica. Su lgebra de la lgica binaria es tambin denominada lgebra Booleana. [2] Nos referimos a las lenguas o lenguajes "Naturales" en contraposicin a los "Artificiales" utilizados en informtica. Los primeros han sido inventados espontneamente por el hombre (a excepcin del Esperanto) y son el resultado de mutaciones que se pierden en la noche de los tiempos. Los segundos han sido y estn siendo inventados por los informticos para comunicarse con los ordenadores (computadoras). [3] Ya se est experimentando con olores. Creo que incluso existe alguna patente al respecto. [4] Por supuesto byte puede escribirse con mayscula y minscula, pero es costumbre informtica utilizar la mayscula -Byte-, mientras que bit siempre con minscula. En mis tiempos -cuando la gente denominaba a estos cacharros "cerebros" electrnicos- era pecado mortal no hacerlo as, de forma que ante una expresin xxx KB o yyy Kb todo el mundo saba a que atenerse. [5] Ahora que el asunto parece estar de moda, digamos que no solo debemos a la cultura Islmica las cifras numricas, incluso muchos textos clsicos han llegado hasta nosotros a travs del Islam. Tambin conocimientos de astronoma y medicina. [6] Existe un tercer grupo de ficheros, los ejecutables, que se correspondera con lo que hemos denominado algoritmos (instrucciones) y que podran considerarse dentro del grupo de los binarios. Adems de los citados, pueden existir otros tipos, como directorios y ficheros de dispositivo. Estos ltimos son artificios utilizados por el Sistema Operativo. Los ficheros de directorio sirven para organizar el contenido del disco en carpetas y subcarpetas. Los ficheros de dispositivo representan la interfaz de los perifricos controlados por el SO. [7] Lo contrario obligara a reservar para "todos" los datos numricos, el espacio correspondiente al mayor de ellos (mxima entidad numrica soportada por el programa). [8] A menudo es un problema conocer la naturaleza de los ficheros que encontramos en nuestro sistema. Cuando esto no es posible, puede intentarse, al menos, conocer el tipo o familia a que pertenece un fichero determinado por su terminacin. Entre los sitios que podran citarse, recomendar dos: Filext y File-Extensions Org. Ambos contienen una extensa base de datos y toneladas de informacin al respecto. [9] Incluso en publicaciones muy autorizadas, es frecuente ver como se confunden los trminos digital y binario, tomndolos como sinnimos cuando en realidad no lo son (los dgitos no tienen porqu ser binarios). Como hemos sealado, pueden existir ordenadores digitales de lgica ternaria o de ms estados. Por ejemplo, decimal. ENIAC, considerado como el primer ordenador digital electrnico de clculo numrico ( A2.1), tena una arquitectura decimal, de forma que la representacin interna de los nmeros no era binaria.

[10] Lo anterior no es cierto en UNIX, donde tradicionalmente los ficheros no tienen terminacin especfica. En cuanto a Microsoft, los sistemas de archivo de sus Sistemas Operativos no reconocen diferencias entre Maysculas/minsculas en los nombres de ficheros, de forma que la tcnica de utilizar una terminacin de tres caracteres para determinar el tipo de un fichero -lo que se conoce como TLA "Tree Letter Acronym"- tiene el problema de que solo permite 17.576 ATL nicos suponiendo las letras del alfabeto ingls americano.

0.2 El Sistema Operativo


1 Presentacin:
Podramos repetir aqu lo indicado al tratar del Ordenador Electrnico Digital ( 0.1). Deberan ser igualmente conocidos por cualquier estudiante de C++ unos mnimos conceptos generales sobre los Sistemas Operativos, puesto que sin un mnimo "background" en la materia, difcilmente se puede ser un buen programador C++. Incluso dira ms; seguramente se necesite un conocimiento ms que mediano sobre la plataforma que utilice, y si es el caso de un Sistema "moderno" del tipo de MS Windows, este conocimiento es vital, ya que precisamente una de las caractersticas de estos entornos es que hay que acudir a los "servicios" del sistema virtualmente para cualquier cosa que queramos hacer ( 1.7).

El problema es que un sistema moderno como Windows es bastante complejo, y aunque es cierto que algunos lenguajes encapsulan los servicios del sistema mediante una capa de software aadido, que intenta enmascarar su complejidad, como dice Petzold ( complejidad saltar fuera y le morder la pierna". PW5E): "Antes o despus esta

El presente captulo incluye unas pinceladas generales sobre esta parte del software que controla el funcionamiento del ordenador, introduciendo algunos conceptos que son imprescindibles para entender otros relacionados con la multiprogramacin y multitarea, adems de ser fundamentales para entender como y porqu funcionan los programas C++ (o de cualquier otro lenguaje) en los entornos operativos actuales. Sus caractersticas las personalizaremos en el Sistema Windows de MS por ser el ms popular. Aunque este conocido sistema ha sufrido paulatinas mutaciones, nos referiremos a las que se implementan en las versiones actuales de 32 bits.

2 El Sistema Operativo
Desde el punto de vista funcional, el Sistema Operativo (SO) es el supervisor de cualquier actividad que se ejecuta en el ordenador. Me gusta decir que el SO viene a ser como el soplo de vida que hace funcionar la mquina. Sin l, el hardware se comparara a un ser humano en coma profundo; quizs con un gran potencial pero incapaz de ninguna accin. Nota: el trmino Sistema Operativo data, de finales de los 50. En toda esta obra nos referimos a l como el "Sistema" (con maysculas) o por su acrnimo "SO". Cuando utilicemos minsculas (el sistema) nos referimos al ordenador como conjunto.

En realidad el SO est constituido por un conjunto relativamente grande de programas; solo hay que considerar la ingente cantidad de espacio necesario para cargar un Sistema Windows actual; incluso en su configuracin mnima (el cdigo de Windows 3.11 tena aproximadamente 500.000 lneas de cdigo, el de Windows 2000 tiene 45 millones). Sin embargo, hablando con propiedad, muchos de estos mdulos no pertenecen al "Sistema", son programas de aplicacin y utilidades adicionales que no tienen que ver demasiado con aqul, sino con tcnicas comerciales y de mrketing. Pero esto... es ya otra historia.

3 Programas de aplicacin
Desde un punto de vista estructural, el software que controla el funcionamiento de un ordenador est organizado por capas ( 1.7a).De estas, el Sistema Operativo es una capa intermedia, situada entre los programas de aplicacin y los controladores de dispositivos ("drivers"). La capa superior, constituida por los programas de aplicacin, es la encargada de realizar tareas directamente utilizables por el usuario. Un procesador de textos, una hoja de clculo, un navegador Web, etc. Son el tipo de programa que, con ms probabilidad, ser objeto de atencin del programador C++ [2]. Una caracterstica de los programas de aplicacin es que estn compilados para un Sistema especfico [10]. Por ejemplo; un procesador de textos WordPefect para Linux correr en cualquier plataforma hardware que tenga cargado dicho sistema, con independencia de su configuracin concreta: Modelo de procesador; tipo de disco; tipo de bus interno; tipo de tarjeta grfica. etc.

4 Controladores de dispositivos
Por su parte, la capa inferior del Software est constituida por unos programas que actan de interfaz entre el hardware y el Sistema Operativo. Son los denominados controladores de dispositivos, porque son ellos los que controlan los dispositivos hardware. Nota: En la arquitectura PC, algunos de estos controladores de dispositivos E/S estn integrados en las rutinas de la BIOS ( H4).

Los "drivers" son especficos de cada elemento hardware y Sistema que deba manejarlo, de forma que para un determinado Sistema existen tantos drivers como dispositivos hardware deba soportar. A la inversa, cada fabricante de hardware, por ejemplo digitalizadores, impresoras, controladoras de disco etc. debe disponer de un controlador especfico para cada modelo y Sistema Operativo distinto con el que deba usarse el modelo en cuestin. Nota: los "drivers" instalables (que se pueden cargar como cualquier otro programa durante la carga inicial del Sistema) se materializan en ficheros [13] y permiten que el SO pueda configurarse segn las caractersticas particulares de la mquina o preferencias del usuario. Su introduccin constituy un factor de flexibilidad y progreso considerable para los SO's. En MSDOS este proceso es controlado con un fichero "Script" denominado CONFIG.SYS.

A principios de los 90 era frecuente que, junto con cada nuevo elemento hardware que se adquiriese, el fabricante aadiera un disquete con los "drivers" para los SOs ms conocidos, por ejemplo, Xenix, Windows 3.1, OS/2 etc. En la actualidad, todava se siguen incluyendo estos programas en forma de disquete o CD. El propio Windows incluye cientos de tales controladores para los modelos de hardware de los fabricantes ms conocidos (incluyendo algunos denominados "Genricos" o estndar); estos controladores son proporcionados a MS por los fabricantes [3].

Los controladores de dispositivo se suelen agrupar en alguna de las siguientes categoras o clases: Adaptadores de audio (tarjetas de sonido). Dispositivos de comunicacin (infrarrojos, mdems, etc). Dispositivos de visualizacin; pantallas (displays). Teclados. Ratn ("mouse" y otros sealadores grficos). Dispositivos multimedia. Dispositivos de Red. Impresoras. Almacenamiento

4 El ncleo
Como el resto del software, tambin el SO est construido por capas. Las interior, la que representa su parte ms ntima, el "Kernel" o ncleo [1], es un programa multihebra que reside permanentemente en memoria. Se ocupa bsicamente de tres tareas primordiales: Gestin de memoria. Gestin de E/S a disco. Control de las tareas en ejecucin.

Desde un punto de vista conceptual, quizs sea esta ltima su actividad principal, de forma que el kernel es antes que nada un gestor de tareas. Conceptualmente, la gestin del almacenamiento (ficheros de disco), denominada genricamente como sistema de ficheros ("File System"), no es una parte fundamental del Sistema. De hecho algunos SOs pueden utilizar ms de uno (o ninguno). Sin embargo desde un punto de vista funcional, la eficacia del "File System" es determinante en el rendimiento global del Sistema Operativo. Actualmente se estn haciendo importantes esfuerzos para mejorar este apartado, y algunos de los avances ms revolucionarios de los futuros SOs vendrn de esta direccin. A ttulo de ejemplo y

como pincelada al respecto, incluimos el principio de un artculo de Leander Kahney: "Searching for the Perfect OS", aparecido en Wired News www.wired.com en Julio del 2004:

It may sound idiotically simple, but according to technology's leading seer, Apple CEO Steve Jobs, searching for information -- not sorting it -- is the wave of the future. At Apple's Worldwide Developers Conference in San Francisco this week, Jobs declared that searching for information on a hard drive, rather than sorting into files and folders, is the future of computing. "We all have a million file folders and you can't find anything," Jobs said during his keynote speech introducing Tiger, the next iteration of Mac OS X, due next year. "It's easier to find something from among a billion Web pages with Google than it is to find something on your hard disk," he added. The solution, Jobs said, is a system-wide search engine, Spotlight, which can find information across files and applications, whether it be an e-mail message or a copyright notice attached to a movie clip. "We think it's going to revolutionize the way you use your system," Jobs declared. In Jobs' scheme, the hierarchy of files and folders is a dreary, outdated metaphor inspired by office filing. In today's communications era, categorized by the daily barrage of new e-mails, websites, pictures and movies, who wants to file when you can simply search? What does it matter where a file is stored, as long as you can find it?

3 La mquina virtual
La descripcin "oficial" de Windows nos dice que es un Sistema grfico, multiprograma y multihebra. Dejando aparte los aspectos grficos, su caracterstica ms notoria para el usuario es su capacidad de multiprogramacin; lo que permite que puedan ejecutarse de forma simultanea y sin interferencias diversas aplicaciones. Para implementar esta capacidad, Windows crea un entorno de ejecucin propio e independiente para cada tarea; es como si cada aplicacin corriese en una mquina independiente, que por esta razn se denomina mquina virtual (MV). Puesto que los dispositivos fsicos son nicos y adems pueden ser distintos en cada mquina, se crean tambin unos dispositivos virtuales (designados de forma genrica como VDs, "Virtual devices") que representan, de forma ideal y normalizada, el "hardware" de las mquinas virtuales. De esta forma se consigue que las MV utilicen un hardware virtual que es independiente del hardware real [4].

Las mquinas virtuales se materializan en una tarea en la que se ejecuta una aplicacin y un determinado software de soporte (los controladores virtuales de dispositivo ), que proporcionan a la aplicacin una simulacin prcticamente perfecta del ambiente que pretenden recrear. La

aplicacin dispone de todos los posibles dispositivos y servicios como si fuesen reales, incluyendo controlador de interrupciones programable PIC ("Programmable interrupt controller" vectores de interrupcin ( servicios de BIOS ( H2.4); servicios de E/S ( H2.4.1); acceso directo a memoria (DMA H2.3), etc. H2); tabla de H3.2); H2.1); memoria; registros de UCP (

Las implicaciones prcticas son trascendentales, porque a fin de cuentas, cualquier programa Windows est pensado para correr en una de estas mquinas virtuales, lo que le hace realmente independiente del hardware. Se consigue tambin que los servicios del sistema, encapsulados en libreras .DLL ( 1.4.4b), puedan escribirse igualmente para un entorno independiente del hardware, ya que proporcionan servicios a mquinas virtuales.

El artificio de la mquina virtual no es nuevo. Los mainframes han utilizado desde siempre tcnicas anlogas para soportar multiprogramacin, pero su aplicacin de forma segura en la informtica personal solo pudo realizarse, cuando a partir del Intel 80386, los microprocesadores dispusieron de determinadas capacidades hardware. Es lo que se conoce como funcionamiento en modo protegido ( H5.1), que presenta una doble ventaja: Simplificar la gestin de estas tareas, que son manejadas por el hardware del procesador en vez de utilizar recursos estrictamente software (el procesador garantiza de forma segura la independencia entre las diversas tareas). Realizar gran parte del control con recursos hardware preconstruidos en el procesador, lo que acelera el rendimiento global del sistema.

4 Dispositivos virtuales
La mquina virtual utiliza recursos virtuales; estos recursos pueden ser elementos hardware o software, aunque de forma genrica los denominamos dispositivos virtuales (VDs). Los VDs son utilizados mediante controladores de dispositivo tambin virtuales VxDs. Observe que los VDs no existen, son en realidad una abstraccin conceptual. Lo que si tiene existencia real son estos controladores virtuales VxDs, representados por ficheros de terminacin .VXD. Estas piezas de software "virtualizan" los mencionados dispositivos, de forma que se comportan hacia la mquina virtual como si estuviese dialogando con un dispositivo hardware real y le proporcionan los mismos servicios que si los dispositivos fsicos estuviesen realmente disponibles. La particularidad es que este hardware es ideal, en el sentido que es normalizado. Por ejemplo, para una aplicacin que corre en una mquina virtual, la controladora de video es siempre la misma, con independencia de cual sea el modelo realmente conectado. As pues, aunque son conceptos distintos, a efectos prcticos los VDs y los VxDs pueden tomarse como sinnimos. Los primeros son abstracciones y los segundos son ejecutables que simulan (virtualizan) dicha abstraccin de forma que parezca que las MVs disponen de ciertos recursos (hardware o software) estndar. Aunque la mayora de los VxDs manejan dispositivos hardware (sus

E/S), otros manejan o reemplazan determinados recursos software, por ejemplo rutinas de ROM BIOS.

Estos dispositivos virtuales son nicos, y compartidos por todas las mquinas virtuales que los necesitan en cada momento. Cualquier dispositivo hardware puede ser utilizado sucesivamente por diversas MVs, de forma que si su estado puede ser alterado al cambiar de una mquina virtual a otra, el dispositivo debe ser utilizado a travs de un controlador virtual, que se encarga de restablecer el estatus a los valores correspondientes. Muchos dispositivos hardware utilizan interrupciones para avisar que los datos estn listos o que ellos mismos lo estn [11]. Los dispositivos virtuales raramente interceptan estas interrupciones por s mismos. En su lugar utilizan el Controlador programable de interrupciones virtual VPICD ello instalan un procedimiento callback ( interrupcin hardware. . Para 1.4.4b2a) que es utilizado por VPICD cuando ocurre una

Como el lector puede suponer, no existe limitacin terica en cuanto a la cantidad o funcionalidad de los VxDs. Los Sistemas Operativos Windows incluyen VxDs que soportan los dispositivos hardware y software ms usuales; adems disponen de las herramientas necesarias para que el usuario pueda crear los que necesite para atender las caractersticas especiales de nuevos dispositivos o modificar los existentes [7]. La realidad es que en ltima instancia, los VxDs de Windows manejan absolutamente todos los dispositivos, desde el sistema de archivos a las tarjetas de sonido y dispositivos de red, ya que proporcionan soporte a un software bsico como son los servicios del sistema (encapsulados en las DLLs). A continuacin se relacionan los que actualmente pueden considerarse como estndar, junto con el acrnimo por el que son conocidos y los servicios que proporcionan: Dispositivo de acceso directo a memoria ("Virtual Direct Memory Access Device" VDMAD) Este dispositivo virtualiza los accesos directos a memoria DMAs ("Direct Memory Access"). El fichero fuente es VDMAD.VXD. Controlador MS-DOS ("DOS manager" DOSMGR) Controlador de dispositivo que virtualiza un Sistema MS-DOS. Intercambiador de pginas de memoria (PAGEFILE y PAGESWAP) Controlador de dispositivo encargado de manejar memoria virtual mediante un mecanismo de intercambio de pginas (page swapping). El fichero fuente es DYNAPAGE.VXD. Controlador programable de interrupciones virtual ("Virtual PIC Device" VPICD) Controlador de dispositivo que virtualiza el controlador programable de interrupciones PIC ("Programmable interrupt controller" H2.4).

Controlador de memoria virtual (V86MMGR) Controlador de dispositivo que virtualiza los modelos de memoria XMS (Extendida) y EMS (Expandida) para aplicaciones que corren en una mquina virtual x86 (V86).

Cargador virtual de dispositivos ("Virtual x Device Loader" VXDLDR) Este controlador es en realidad un servicio para el funcionamiento de las mquinas virtuales, ya que permite cargar y descargar dinmicamente (en tiempo de ejecucin) los propios controladores virtuales (VxDs).

Cache virtual ("Virtual CACHE" VCACHE) Controlador virtual que proporciona servicios de cach ( H5.2).

Coprocesador matemtico virtual ("Virtual Math Coprocessor" VMCPD) Controlador que virtualiza el coprocesador matemtico.

Dispositivo virtual de energa ("Virtual Power Device" VPOWERD) Este dispositivo virtualiza los servicios de ahorro de energa que son estndar en muchos dispositivos actuales. Por ejemplo, placas-base, controladores de disco, etc.

Shell virtual ("Virtual Shell Device" SHELL) Controlador de dispositivo que virtualiza servicios de shell ( 1.7.3). En este caso, el SHELL se refiere a servicios de envo y visualizacin de mensajes, monitorizacin de las propiedades de las mquinas virtuales y comunicacin con otras aplicaciones, en especial con libreras de enlazado dinmico (DLLs).

Interfaz virtual para el temporizador ("Virtual Timer API" VTDAPI) Controlador de dispositivos que virtualiza servicios de temporizado.

Temporizador virtual ("Virtual Timer Device" VTD) Controlador que virtualiza el reloj del sistema.

Servicios virtuales de Windows-32 ("VWIN32 Services" VWIN32) Este controlador que virtualiza servicios de VxDs de Windows 32.

4 Gestor de mquinas virtuales


Con las premisas anteriores, resulta evidente que, en cada momento, deben existir tantas de estas mquinas virtuales como aplicaciones distintas estn en ejecucin. Esta tarea de mantenimiento, sincronizacin, creacin y destruccin de las MV, es realizada por un programa supervisor, el denominado VMM ("Virtual machine manager"), fichero VMM32.VXD en un Sistema Windows 32. El VMM trabaja con libreras de enlazado dinmico de 32 bits que proporcionan las funciones y recursos grficos que necesitan las aplicaciones Windows. Trabaja tambin con dispositivos virtuales a travs de controladores virtuales; todo ello en modo protegido, lo que permite a los dispositivos virtuales interceptar interrupciones y fallos, de forma que se puede controlar el acceso a los dispositivos y al software instalado por parte de las aplicaciones que corren en las MVs.

4.1 En realidad, este gestor de mquinas virtuales es el corazn del Sistema Operativo. Su tarea principal es crear, correr y controlar las MVs en las que corren las aplicaciones. Para ello ofrece un servicio de multiprograma preemptivo de tarea nica (single-threaded) en el que el tiempo de UCP se comparte entre las diversas mquinas virtuales. Cuando el VMM arranca, la primera mquina virtual que crea es la Mquina Virtual del Sistema SVM ("System virtual machine"), capaz de contener aplicaciones Windows de 16 bits [5], aunque tambin pueden crearse MVs para programas Win32 y aplicaciones MS-DOS si son necesarias. La SVM puede tener varias hebras de ejecucin, las dems solo pueden tener una. El proceso es como sigue: Inicialmente, el programa WIN.COM carga el fichero VMM32.VXD que contiene el VMM y los controladores virtuales por defecto. El VMM se carga en memoria extendida utilizando un controlador virtual; se inicializa a s mismo y a los controladores virtuales. A continuacin conmuta a un modo de ejecucin protegido [12]. El resultado es que el VMM y los controladores virtuales corren en un espacio contiguo de direcciones de 32 bits (flat model address space) denominado anillo 0 (ring 0). A partir del 80386, los procesadores Intel que "motorizan" los PC's tienen 4 niveles de proteccin interna en forma niveles de privilegio denominados anillos ("Rings") numerados de 0 a 3. El anillo 3 es donde residen las aplicaciones Windows; el anillo 0 es donde reside el cdigo con mayores privilegios. Por ejemplo el kernel del SO y los programas VxDs que pueden manejar directamente los puertos de E/S ( H2.5). Un cdigo del anillo 0 no solo puede interceptar directamente las E/S de cualquier puerto fsico, tambin redireccionarlas en caso necesario, lo que le permite virtualizar o emular cual

0.3 El Hardware
Esta pgina ha sido movida.

Toda la seccin dedicada al Hardware ha sido reestructurada. Consulte la seccin "Tecnologa del PC" en la seccin de Tutoriales de la pgina inicial ( Tutoriales).

1 Programacin C++
"No programming language can be all things to all programers. No matter how many features a language has, there's always someone who wants just one more". Dan Saks "C/C++ Users Journal" Enero 1990.

1 Observaciones y comentarios sobre los lenguajes C/C++


Se ha dicho: "C++ es un lenguaje potente, pero a veces no es precisamente un paseo por el parque... De acuerdo, de acuerdo, es orientado a objetos. Correcto. Yo personalmente conozco gente que ha trabajado toda una semana en herencia mltiple, para retirarse completamente frustrado a Carolina del Norte a limpiar cochineras". Joshua Trupin: MSDN Magazine, Septiembre 2000 www.msdn.microsoft.com/msdnmag/default.asp "C hace fcil dispararse en los propios pies; C++ lo hace ms difcil, pero cuando lo haces, te vuela la pierna completa". Stroustrup. C++ es un lenguaje difcil en el que puede existir una lnea muy tenue entre una caracterstica y un 'bug' ". Programming in C++: Rules and Recommendations, Ellemtel Telecommunication Systems Laboratories, Sweden. "Para nuestro gusto C++ ya es demasiado largo y complicado". Comit de estandarizacin del C++. "Tiene una sintaxis compleja, semntica sutil y una temible reputacin". Steve Donovan "Scripting C++". InformIT Marzo 2002 "Todos los hombres ascienden en la escala hasta alcanzar su mximo nivel de ineficacia". Dr. Laurence J. Peter. "La pirmide de Peter". Ed. Plaza & Janes S.A. Barcelona [5]. Creo que C++ es un magnfico ejemplo de que lo anterior es aplicable tambin a los lenguajes de programacin. En efecto, C++ es una muestra de como las cosas pueden seguir mejorndose hasta llegar a un nivel de complejidad que las hace prcticamente inutilizables por el comn de los mortales, a no ser que les dediquen un mnimo de 500 horas para empezar a entenderlas [9]. Como botn de muestra, incluyo un comentario encontrado en Amazon [1] sobre el libro "The C++ Programming Language" (TC++PL para los ntimos) del ya citado Stroustrup: "Estoy en mi tercer ao de aprendizaje de C++ (s, se tarda un tiempo en conocer el C++, en conocerlo realmente), todava lo leo una y otra vez, y cada vez encuentro ms y ms cosas tiles y consejos importantes", Caliv Nir (Israel).

Afortunadamente parece que las cosas vuelven a su cauce. Hace poco tiempo que algunos se dieron cuenta que el asunto haba empezado a desmadrarse, as que empezaron a quitarle cosas y a simplificarlo..., Estaba naciendo Java! (es tambin la explicacin "oficial" de Microsoft para inventar el C# ;-) Nota: Esta es la situacin por el momento, pero no os preocupis. Vemos como Java se est perfeccionando a marchas rpidas, con lo que a no tardar ser tan complejo como C++ y habr que volver a inventar algo ms sencillo...[4] En cuanto al C#: Sea bienvenida cualquier mejora!!. Aunque se me ocurre que no estara de ms aquello de mantener una cierta "diversidad gentica" en la informtica, mucho me temo que al paso que vamos acabemos todos vestidos de gris con el "Libro Rojo" en el bolsillo :-( [6]

2 Resea histrica
Desde un punto de vista histrico, el C es anterior al C++, aunque el estndar C++ fuera publicado antes que el de C [2], de modo, que paradjicamente el hijo influy en el estndar del padre. As pues, la propuesta de ANSI C recogi algunas de las normas del C++. Ambos nacieron en los prestigiosos laboratorios Bell de la AT&T (American Telephone and Telegraph) en Murray Hill (New Jersey USA) [3]. El primero de la mano de Brian W. Kernighan y Dennis M. Ritchie (la "K" y la "R" de K&R, siglas con las que se les conoce), el segundo es de Bjarne Stroustrup. La primera edicin del libro: "El lenguaje de programacin C" de K&R es de 1978. Por su parte la primera edicin de: "El lenguaje de programacin C++" de Stroustrup es de 1986. El propio Stroustrup reconoce que comenz a trabajar en su diseo en 1979; justo un ao despus de la publicacin del clsico de K&R. Las primeras versiones en uso del lenguaje (bajo el nombre de "C con clases") en el entorno de los departamentos de investigacin de la AT&T se remontan a 1980. La primera utilizacin del lenguaje fuera del entorno de investigacin data de Agosto de 1983. La designacin actual C++ fue acuada en el verano de 1.983 por Rick Mascitti. El primer compilador comercial fue lanzado en Octubre de 1985. Como todos los lenguajes (naturales y de programacin), el C++ es un resultado de la evolucin; de forma que recoge influencia de sus ancestros, algunos de los cuales ya se han sealado ( 0.1). Adems es en s mismo un producto en evolucin. Las ltimas aportaciones datan de los 80, y se refieren principalmente al mecanismo de excepciones y a las plantillas ("Templates"). Sin duda la mejor fuente de informacin sobre la historia y evolucin de este lenguaje es su propio inventor, de modo que remitimos al lector a sus propias palabras D&EC++.

2.1 Situacin actual


Despus de dcadas de aparente inactividad por parte del Comit Internacional encargado de elaborar el estndar, el 25 de Marzo de 2011, los medios especializados de todo el mundo, se hacan eco de que finalmente, el comit ISO para el C++ haba sido aprobado el ltimo borrador del nuevo estndar en su reunin de primavera en Madrid. Esta versin, en la que se haba estado trabajando intensamente, era conocida como C++09 porque se supona que sera aprobada en el 2009. Sin embargo, el proceso sufri sucesivos retrasos, de forma que finalmente era conocido -quizs un poco humorsticamente- como C++0x, en relacin a que no se saba cuando aparecera. Finalmente, si las

cosas discurren como es de suponer, la aprobacin ocurrir dentro de este ao, as que el prximo estndar ser el C++2011. Nota: a la hora de escribir estas lneas, la ltima revisin publicada lo era bajo el ttulo ISO_C0x_final_draft. Un documento .PDF de nada menos que 11 MB.

Podra decirse que despus de vivir una poca dorada, la popularizacin y uso del C++ haba sufrido una cierta ralentizacin en favor de nuevas modas y nuevos lenguajes, y que incluso su desarrollo y evolucin haban quedado estancados desde los aos 70. Sin embargo, esta aparente "inactividad" ha estado lejos de ser real y el nuevo estndar incluye un sinnmero de avances conceptuales y materiales -en forma de nuevas libreras- que lo colocan de nuevo en una posicin puntera dentro del mundo de la programacin, en especial en lo que respecta a grandes sistemas. Precisamente, la razn principal de los retrasos ocurridos en el proceso de aprobacin del nuevo estndar, tienen mucho que ver con la magnitud, nmero y calado de las nuevas extensiones y libreras. Con independencia de que los cambios se hagan oficiales, muchas de las nuevas herramientas ya estaban en la calle de forma ms o menos oficial, de la mano de los fabricantes de compiladores. De forma que se habla incluso de un "renacimiento" del C++ como herramienta y concepto. En este sentido, es interesante la entrevista de Craig Symonds y Mohsen Agsen, dos profesionales que sin duda gozan de una buena perspectiva del mundo de la programacin actual: "C++ Renaissance" o este otro comentario: "C++ Renaissance: First Symptoms of Contagion in Traditionally Non-Native Teams".

3 Estudiar C++
"C++ should not be for beginners, as it is better to learn the principles from a clearer language than be confused by what all the syntactic knobs and dials, and superfluous constructs do in C++. As for courses, C++ has proven so difficult to learn that you need lots of courses". Ian Joyner "C++??" ( [Joyner-96]).

Para tener una perspectiva histrica parece natural estudiar primero C y despus C++, con lo que se empiezan a ver las diferencias y salvedades entre uno y otro. Este es el enfoque de algunos libros; de hecho el ya comentado manual de ayuda "C++ Builder Languaje Guide" sigue ms o menos esta pauta. Dedica muchos comentarios a las diferencias entre C y C++, y al final dedica un captulo a los asuntos que son exclusivos de este ltimo. Algunos de estos libros incluso hacen comentarios curiosos, que ya solo tienen sentido desde un punto de vista histrico. Por ejemplo, citan que los ficheros fuente de los programas C deben tener nombres con terminacin ".c" y los de C++ terminaciones ".cc" o ".cpp", lo que es superfluo para los compiladores actuales. Por ejemplo, Borland C++Builder puede compilar perfectamente fuentes .c como C o como C++ con un simple indicador (-P) en la orden de llamada. Nota: Otros, como los compiladores GNU C/C++, permiten utilizar ambos criterios. Adems de poder utilizar una directiva explcita, pueden distinguir el tipo de compilacin por la terminacin de los fuentes. Por ejemplo, las terminaciones .c son tratadas y compiladas como fuentes C, mientras que los sufijos .C; .Cpp; .C++; .cc son compilados como C++. Otros compiladores C+

+ Unix como Solaris de SUN o HP-UX pueden compilar fuentes con terminaciones .C, .c, .cc, .cpp o .cxx.

C++ no naci como un lenguaje orientado a objetos puro. Ms bien se trataba de aadirle "objetos" al clsico C de K&R, ya que el nuevo paradigma de programacin "con objetos", se mostraba como un paso adelante en el arte de la programacin. De hecho, aunque C++ introduce nuevas palabras clave y operadores para manejo de clases, algunas de sus extensiones tienen aplicacin fuera del contexto de programacin con objetos (fuera del mbito de las clases). Esta es tambin la causa de que C++, junto con las magnficas cualidades del C, arrastre algunas de sus deficiencias. Sigue siendo permisivo (aunque menos) "intentando hacer algo razonable con lo que se haya escrito", solo que a veces, sin que nos demos cuenta, se pasa de listo. Por supuesto, con ambos lenguajes resulta cierto el viejo aforismo informtico: "Un programa no hace lo que queremos que haga, sino lo que le hemos dicho que haga". En el caso del C++ quizs tendramos que aadir: "Mas lo que l decide por su cuenta"... :-) Cuando se trata de programas sencillos, que no requieren necesariamente de las caractersticas "++" de la POO, surge inmediatamente la cuestin si ser mejor hacerlo en C o en C++, Cual es mas rpido? Cual proporciona un cdigo ms compacto? Segn dicen los expertos, con los actuales compiladores el resultado est en tablas. Las diferencias se mantienen en un margen de 5% y por lo general los resultados se encuentran a la par. Sin embargo, en cuanto se trata de escribir programas algo ms complicados que mostrar el consabido "Hola mundo", las diferencias de productividad son notables, con una indiscutible ventaja a favor del C++. Nota: En cierta forma esta discusin, usar C++ o C, es un poco bizantina, dado que a efectos prcticos el segundo es un subconjunto del primero (de hecho, los compiladores GNU C y C++ estn integrados en un solo producto). Ms bien cabra discutir si, utilizando C++, merece o no la pena usar los recursos de la POO.

Dicho esto queda una cuestin: Aunque estudiar C++ a partir de C proporciona una perspectiva histrica, una visin del desarrollo del lenguaje, de como fueron sucediendo las cosas. En mi opinin, hacerlo de esta forma no solo es innecesario sino quizs contraproducente para el estudiante normal. No digo que est de ms, solo que es un camino innecesariamente farragoso. Me parece que se trata de una situacin parecida a la de alguien que quisiera aprender Espaol empezando por aprender Latn. Por supuesto no estara de ms si tiene tiempo y gana, si se es un lingista. Se tendr un mayor conocimiento del lenguaje y su evolucin; se comprender mejor el porqu de ciertas cosas. Pero para el extranjero que simplemente necesita entenderse en Espaol, es evidentemente innecesario. Digo esto, porque al ser la POO un paso superior de abstraccin respecto de los primeros sistemas de "traslacin de frmulas". Un paso en la evolucin de los lenguajes de programacin, con un cuerpo de doctrina ya suficientemente consolidado y coherente, las cosas pueden explicarse partiendo directamente del estudio de C++ y aprovechando todas sus posibilidades desde el principio. Incluso dira que intentando "olvidarse" del viejo C que an pervive en su interior. Es perfectamente factible introducir el concepto general de clase y objeto, para decir despus que las estructuras son una "clase" especial que tiene estas y las otras propiedades (todas sus propiedades son pblicas), sin necesidad de introducir el concepto tradicional de "estructura" C, para luego decir que en C++ son un tipo especial de clase... Esto tendr la ventaja adicional de permitir al nefito empezar a pensar "en objetos" con ms rapidez.

Nota: Tena ya una gran cantidad de material recopilado cuando me di cuenta de esta realidad, as que tuve que volver a rehacer una parte de la estructura de este "libro", volviendo a empezar directamente con el C++, e intentando hacer la menor cantidad de referencias al viejo C. A la hora de escribir estas lneas todava no est terminado el trabajo (no se si lo estar algn da), pero esta es la intencin, de forma que si cuando caiga en manos del lector quedan referencias al viejo C, que no sean meramente histricas o comparativas, sepa que se debe simplemente a un trabajo inacabado. Inicio. [1] Ya sabis que esta tienda on-line tiene una caracterstica (que se va extendiendo a otras muchas): Los lectores pueden incluir comentarios y opiniones personales sobre los libros. Tiene la ventaja de que no son comentarios interesados de la editorial. Si sabemos leer entre lneas, esta posibilidad puede ser de mucha ayuda a la hora de evaluar el libro. Sin embargo, la mejor fuente de informacin (en ingls) sobre C++, incluyendo evaluacin de libros, es la Asociacin de usuarios C y C++ ACCU (The Association of C and C++ Users), seccin "Book reviews".

[2] El instituto ANSI (American National Standards Institute) estableci en 1.989 el comit denominado J16 para estandarizar el C++. Paralelamente, la organizacin internacional encargada de los estndares ISO (International Standards Organization www.iso.ch), haba creado el comit WG14 que trabajaba en el mismo sentido. Finalmente, el comit americano recomend que se adoptara el estndar ISO como estndar americano. La primera versin del Estndar data de principios de 1997; la ltima (por el momento) se ratific en Marzo de 1998, y se public en Septiembre del mismo ao por el ANSI y el ISO. De forma que el "Estndar C++" es la norma ISO/IEC 14882 (IEC es acrnimo de "International Electrotechnical Commission", uno de los grupos de trabajo del ANSI). La Norma est disponible para descarga en un documento .PDF de 2.794 KB y 732 pginas, previo pago de unos 18 $ US: National Committee for Information Technology Standards (puede pagarse con tarjeta de crdito). La versin impresa es mucho ms cara!!. Tambin puede descargarse gratis uno de los ltimos borradores conocidos como DWPs ("Draft Working Papers"): ftp://ftp.research.att.com/dist/c++std/WP/CD2. Hay que advertir no obstante, que la Norma dista mucho de ser un texto adecuado para aprender C++. [3] "Bell Labs"; durante mucho tiempo los mayores y mejores laboratorios de investigacin industrial del mundo. Adems del origen de los lenguajes C y C++, entre otras "naderas", fueron tambin la cuna del transistor; del Sistema Operativo UNIX, y de las primeras clulas fotovoltaicas con utilidad prctica. [4] Mucho despus de escribir esta nota, he encontrado esta confirmacin: "I predicted the growth of Java complexity and don't condemn it, I consider complexity an inevitable consequence of serving a large community". Bjarne Stroustrup "The State of the Languaje".

[5] Como lectura complementaria tambin recomendara: "La Ley de Murphy", de Arthur Bloch. Ed. Temas de Hoy S.A. Madrid. Una de mis lecturas favoritas y sin duda un buen libro "de cabecera" para los programadores C++.

[6] Si no entiendes la referencia no te preocupes... Sencillamente eres demasiado joven!. [9] Hace poco lea el comentario del directivo de una gran multinacional, quejndose que el tiempo de entrenamiento estimado para que un programador C++ fuese verdaderamente eficiente era de tres aos, mientras que la NASA estimaba en 18 meses el tiempo de preparacin de un astronauta.

1.1 Introduccin a la POO


1 Qu es eso de los "Objetos"?
En la programacin tradicional exista una clara diferenciacin entre los datos y su manipulacin, es decir, el conjunto de algoritmos para manejarlos. Los tipos de datos eran muy simples; todo lo ms nmeros de diverso tipo y caracteres (aislados o agrupados en cadenas o matrices), pero nunca elementos heterogneos. La situacin para el programador era que el lenguaje pareca decirle: estos son los posibles contenedores para la informacin que debes manejar (los tipos de datos soportados por el lenguaje) y aqu aparte, las operaciones que puedes realizar con ellos (las operaciones definidas para dichos datos). Por ejemplo, si son datos numricos las operaciones aritmticas, las comparaciones, las asignaciones, etc. Con estas herramientas el programador construa su cdigo, y para poner un poco de orden en la maraa de algoritmos solo tena el recurso de agruparlo en funciones. Si se tena que hacer un programa de gestin comercial, la informacin correspondiente a un concepto ms o menos real, por ejemplo un "cliente", tena que ser desmenuzada en una serie de datos aislados: nombre, domicilio, poblacin, provincia, telfono, condiciones de compra, saldo, tipo de descuento, nmero de vendedor asignado, fecha de ltima compra, etc. etc. Luego, para hacer una factura, todos estos elementos eran tomados y procesados individualmente. Un primer intento de construir tipos de datos ms complejos, que se parecieran a las situaciones del mundo real y que pudieran ser tratados (ms o menos) como una unidad, lo constituyen, entre otros, las "estructuras" del C clsico ("registros" en otros lenguajes). Una estructura es una agregacin de datos de diverso tipo construida a criterio del programador mediante la agrupacin de elementos ya incluidos en el lenguaje (bsicamente los antedichos nmeros y caracteres). Esto supuso un paso en el nivel de abstraccin de los datos, aunque las herramientas para manipularlos seguan siendo elementos totalmente diferenciados. En esta etapa ya poda crearse una estructura "cliente" que albergara toda la informacin antes dispersa, pero aparte de leer y escribir la informacin en un solo bloque, poco ms poda hacerse, los datos tenan que seguir siendo procesados individualmente con expresiones parecidas a: cliente->fecha_ult_compra = date(); tot_factura = suma * cliente->descuento cliente->saldo = cliente->saldo + tot_factura; etc. Ante esta situacin surge una nueva idea: crear nuevos tipos de datos agrupando los tipos tradicionales en entidades ms complejas que reciben el nombre genrico de clases. Las clases son conjuntos de datos definidos por el programador, parecidos a las mencionadas "estructuras", pero

con la importante novedad de incluir tambin las herramientas necesarias para su manipulacin; es decir: operadores y funciones de la programacin tradicional. Dicho de otro modo: los nuevos tipos de datos pueden ir acompaados de su "lgebra"; de las operaciones que se pueden realizar con ellos [3]. La idea es construir una especie de caja negra que incluya no solo los datos, tambin los algoritmos necesarios para su manipulacin (sus operaciones), de forma que pueda ser vista desde el exterior (el programador que las usa) como un ente al que se le envan preguntas u rdenes y responde con el resultado [2]. Este comportamiento de la clase frente al mundo exterior es lo que se llama su interfaz o protocolo. Cmo es el detalle de su interior no le interesa al usuario-programador en absoluto, solo le interesa conocer la forma de "comunicarse" con ella y que posibilidades le ofrece. El hecho de empaquetar juntos datos y funcionalidad, dejando visible al exterior solo lo estrictamente necesario, se denomina encapsulamiento y es otro de los distintivos de la POO. Para ilustrar la idea en un caso concreto consideremos un ejemplo clsico: Supongamos que en un programa tradicional hay que manejar nmeros complejos. La solucin es definir dos variables fraccionarias (de coma flotante) R e Y para representar respectivamente las partes reales e imaginaria de cada complejo. Luego para obtener, por ejemplo la suma (Rr, Yr), de dos complejos (R1, Y1), (R2, Y2), tenemos que codificar: Rr = R1 + R2 Yr = Y1 + Y2 para calcular el valor del mdulo m tenemos que hacer: m = SQRT( (Rr * Rr) + ( Yr * Yr) )

as sucesivamente para cualquier manipulacin que queramos efectuar. Supongamos ahora que tenemos esta posibilidad de "construir" un nuevo tipo de variable, que denominaremos la clase de los complejos (la designamos por Cc), y que hemos incluido en dicha clase la informacin necesaria para realizar todas las operaciones permitidas en el lgebra de los nmeros complejos. No solo la suma, tambin la asignacin, la comparacin, el clculo del mdulo, etc. Incluso los procedimientos para crear elementos nuevos (complejos) y para destruirlos (eliminarlos de la memoria). Ahora el funcionamiento sera algo parecido a: Cc x = (R1, Y1); Cc y = (R2, Y2);

Estamos declarando que x e y son objetos de la nueva clase y les estamos asignando los valores correspondientes. Fjese que estos objetos son casos concretos del nuevo tipo, la clase de los complejos (en el mismo sentido que un 5 es un caso concreto del concepto genrico de "nmero entero"). En el ejemplo suponemos que R1, Y1, R2, Y2 siguen siendo nmeros fraccionarios tradicionales, los mismos que en el ejemplo anterior. Fjese tambin que la asignacin x = (R1, Y1) supone que el compilador sabe que al ser x un complejo, el smbolo "=" no representa aqu la misma operacin que en el caso de, por ejemplo, z = 6; tambin supone que el compilador sabe que significa exactamente la expresin (R1, Y1) a la derecha.

Si ahora queremos calcular el resultado de la suma de los dos complejos y el valor de su mdulo, solo tenemos que hacer: Cc z = x + y; float m = z.mod();

Observe que en la primera lnea el operador "+" no es exactamente el mismo que cuando se utiliza con enteros (por ejemplo, en 3 + 5). Esto lo deduce el compilador, porque sabe que x e y son complejos (dentro de la nueva clase hemos definido la operacin "suma" entre sus elementos y le hemos asignado el operador "+"). Por otra parte, en la segunda lnea solo tenemos que mandarle al complejo z el mensaje mod() - calcula el mdulo -; la sintaxis es la sealada: z.mod(). Ya sabemos que el resultado es un escalar y lo asignamos al nmero fraccionario m. Fjese tambin que en ambas lneas el operador de asignacin "=" no representa la misma operacin. En la primera se trata de una asignacin entre complejos; en la segunda es la tradicional asignacin entre nmeros fraccionarios. Esta capacidad "camalenica" de los operadores es tpica de la POO, y se conoce como sobrecarga [4] (veremos que tambin puede haber sobrecarga de funciones). El compilador sabe en cada momento que operador debe utilizar de toda la panoplia disponible aunque estn bajo el mismo smbolo; lo sabe por el contexto (por la naturaleza de los operandos involucrados). En la POO es frecuente que mtodos anlogos de clases distintas se referencien utilizando las mismas etiquetas. Es decir: supongamos que tenemos tres clases: los Complejos, los Vectores y los Racionales. Puede ocurrir que, por ejemplo, el mtodo para calcular el mdulo se denomine mod() en las tres clases. Aunque el resultado sea un nmero racional positivo en los tres casos, naturalmente su operatoria es distinta si se aplica a racionales, vectores o matrices. Sin embargo, no existe posibilidad de confusin en el programa porque cuando apliquemos el mtodo en cada caso concreto, el compilador sabe a cual de ellos nos estamos refiriendo en base a los objetos involucrados. Esta caracterstica de la POO, da origen a lo que se llama polimorfismo. El nombre es bastante descriptivo de su significado, y la posibilidad resulta ser de gran utilidad, pues simplifica la lectura del cdigo. Cada vez que encontremos una invocacin al mtodo mod tenemos una imagen mental del resultado con independencia del objeto concreto al que se aplique. Llegados a este punto, introduciremos algn vocabulario especfico para adaptarnos a la terminologa, algo especial, que utiliza la POO: En vez de "variables" como en la programacin clsica, los datos contenidos en las clases (y en los objetos concretos) se denominan propiedades, de forma que en el ejemplo anterior, nos referiremos a las partes real R1 e imaginaria Y1 del complejo x como las propiedades R e Y de x (los complejos siguen teniendo una parte "real" y otra "imaginaria" incluso en la POO). Por su parte las operaciones de manipulacin contenidas en las clases (bajo la forma de funciones) reciben el nombre de mtodos. Siguiendo con el ejemplo anterior, en vez de referirnos a funcin mod(), que calcula el mdulo, diremos que mod es un mtodo de la clase de los complejos. En lenguajes como C++, que puede tener elementos de ambos mundos, de la programacin tradicional y de la POO, poder utilizar indistintamente los vocablos "funcin" o "mtodo" es una ventaja, ya que nos permite distinguir en cada caso a que nos estamos refiriendo, si a funciones tradicionales o a funciones pertenecientes a clases.

En uno de los prrafos anteriores hemos dicho: "... estos objetos son casos concretos del nuevo tipo, la clase de los complejos..."; utilizando la terminologa correcta diramos: "... estos objetos son instancias de la clase de los complejos...". Como puede verse, instancia significa una sustanciacin concreta de un concepto genrico (la clase). En el mismo sentido podramos decir que el nmero 5 (un objeto), una instancia de la clase de los nmeros enteros, que tiene a su vez determinados mtodos; en este caso las conocidas operaciones aritmticas: suma, resta, multiplicacin..., as como las operaciones de asignacin, la comparacin, etc. Siguiendo este criterio, la expresin: Cc x = (R1, Y1) no se dice: "declaracin de x como objeto de la nueva clase". Es ms correcto sealar: "x es una instancia de la clase de los complejos". Al hecho de sustanciar un objeto concreto de una clase se le denomina instanciar dicho objeto. Esta operacin (crear un objeto) est encomendada a un tipo especial de mtodos denominados constructores. Siguiendo con nuestro ejemplo, podemos suponer que la expresin: Cc c1(1, 3); crea un complejo c1 cuyas partes real e imaginaria valen respectivamente 1 y 3, y que este objeto ha sido creado por una funcin (mtodo) de Cc cuya misin es precisamente crear objetos segn ciertos parmetros que son pasados como argumentos de la funcin. En ocasiones, cuando se quiere distinguir entre los valores y funcionalidades genricos (de las clases) y los concretos (de los objetos), se suelen emplear las expresiones: propiedades de clase y mtodos de clase para las primeras, y propiedades de instancia y mtodos de instancia para los segundos. As mismo, cuando se quiere distinguir entre una funcin normal (de la programacin tradicional) y una funcin perteneciente a una clase (un mtodo de la clase), se suele emplear para esta ltima la expresin funcin miembro (se sobreentiende "funcin miembro_de_una_clase") [1]. Como puede suponerse, el encapsulamiento, junto con la capacidad de sobrecarga, constituyen en si mismos una posibilidad de abstraccin para los datos mayor que la que facilitaba la programacin tradicional. Ya s puede pensarse en un complejo como algo que tiene existencia "real" dentro de nuestro cdigo ya que lo tratamos (manipulamos) como ente independiente con caractersticas propias; de forma parecida a la imagen que de l tenemos en nuestra mente. Con ser lo anterior un paso importante, sin embargo, las mejoras de la POO respecto de la programacin clsica no terminan aqu. Los Lenguajes Orientados a Objeto como el C++, adems de los tipos de datos tradicionales, incluyen algunas clases pre-construidas, pero debido al hecho de que la "construccin" de un nuevo tipo de variable (como la clase Cc de los complejos en el ejemplo anterior) requiere un cierto trabajo de programacin inicial para disear la clase, se pens que sera estupendo poder aprovechar el trabajo realizado en determinados diseos para, a partir de ellos, obtener otros nuevos de caractersticas ms o menos parecidas. Se trataba en suma de intentar reutilizar el cdigo dentro de lo posible; en el mismo sentido que lo hacemos cuando tenemos que escribir una carta circular y buscamos en el ordenador si hay alguna anterior parecida para utilizarla junto con el procesador de textos, como punto de comienzo para la nueva. Para esto se dot al lenguaje de dos nuevas capacidades: la Herencia y la Composicin.

Por herencia ("Inheritance") se entiende la capacidad de poder crear nuevas clases a partir de alguna anterior, de forma que las nuevas "heredan" las caractersticas de sus ancestros (propiedades y mtodos). Se trata por tanto de la capacidad de crear nuevos tipos de datos a partir de los anteriores. Una caracterstica especial de la herencia es que si se cambia el comportamiento de la clase antecesora (tambin llamada padre, base o super), tambin cambiar el comportamiento de las clases derivadas de ella (descendientes). Como puede deducirse fcilmente, la herencia establece lo que se llama una jerarqua de clases del mismo aspecto que el rbol genealgico de una familia. Se entiende tambin que estos conceptos representan niveles de abstraccin que permiten acercar la programacin a la realidad del mundo fsico tal como lo concebimos. Por ejemplo, entendemos que un motor elctrico deriva de la clase general de los motores, de la cual derivan tambin los de gasolina, diesel, vapor, etc. y que, sin dejar de ser motores, cada subclase tiene sus caractersticas peculiares. Por supuesto que no tendra ningn sentido utilizar la herencia para crear simplemente un clnico de la clase base. En realidad, como en el ejemplo de la carta circular, la herencia se emplea como un primer paso (partir de algo existente) para a continuacin, perfilar los comportamientos o datos que queremos pulir en la nueva versin de la clase. Como lo que principalmente interesa al usuario de una clase es su interfaz, son justamente algunos aspectos de esta interfaz los que se modifican, al objeto de adecuar la nueva subclase a las necesidades especficas del caso. Por lo general esta modificacin de la interfaz se consigue de dos formas: 1. Aadiendo propiedades y/o mtodos que no existan en la clase base 2. Sobrescribiendo propiedades del mismo nombre con distintos comportamientos (sobrecarga y/o polimorfismo).

Aunque la herencia es uno de los pilares de la POO, tiene tambin sus inconvenientes. Por ejemplo, dado que el compilador debe imponer ciertas caractersticas en tiempo de compilacin sobre las clases creadas por herencia, esto resulta en cierta rigidez posterior. Sin embargo, como hemos visto, una de sus ventajas es la reutilizacin del cdigo.

La composicin (tambin llamada herencia mltiple) es la segunda va para crear nuevas clases a partir de las existentes. Por composicin se entiende la capacidad que presenta la POO de ensamblar un nuevo tipo (clase) cuyos elementos o piezas son otras clases. Es posible declarar clases derivadas de las existentes especificando que heredan los miembros de una o ms clases antecesoras. Siguiendo con el smil de la carta circular, la composicin equivaldra a escribirla reutilizando trozos de cartas anteriores. Es clsico el ejemplo de sealar que podramos crear una clase "coche" declarando que tiene un motor y cuatro ruedas, bastidor, aire acondicionado, etc, elementos estos pertenecientes a la clase de los motores, de las ruedas, los bastidores y los sistemas de climatizacin respectivamente. Este sistema tiene tambin sus ventajas e inconvenientes, pero es muy flexible, ya que incluso pueden cambiarse los componentes en tiempo de ejecucin.

2 Resumen:
Como resumen de este rpido repaso, podemos sealar que la Programacin Orientada a Objetos (POO) tiene sus propios paradigmas y ventajas, entre las que destaca la reutilizacin del cdigo. A los acadmicos les gusta decir que se sustenta en cuatro columnas a las que ya hemos hecho referencia: Encapsulamiento: Poder separar la interfaz de una clase de su implementacin, o dicho en otras palabras: no es necesario conocer los detalles de cmo estn implementadas las propiedades para poder utilizarlas. Los objetos funcionan a modo de caja negra en la que estn empaquetados los datos y las instrucciones para su manipulacin, de las que conocemos solo lo necesario para utilizarla. Herencia Crear nuevos elementos a partir de los existentes de forma que heredan las propiedades de sus ancestros. Existen dos clases de herencia: simple y mltiple. Sobrecarga: Posibilidad de crear diferentes mtodos dentro de una clase que comparten el mismo nombre, pero que aceptan argumentos diferentes y se comporten de forma distinta segn la naturaleza de estos argumentos ( 4.4.1a).

Polimorfismo Es una caracterstica que resulta de gran ayuda en programacin pues facilita la claridad y consistencia del cdigo, aunque es un concepto bastante genrico (y frecuentemente malinterpretado). Se conoce con este nombre el hecho de que un mtodo tiene el mismo nombre y resulta en el mismo efecto bsico pero est implementado de forma distinta en las distintas clases de una jerarqua.

3 Bibliografa:
Para una ms detallada exposicin sobre los conceptos involucrados en la POO y su relacin con el C++, sugerimos dos referencias: "Thinking in C++" ( Bruce Eckel) y "What is Object-Oriented Programming?" ( Stroustrup), aunque desafortunadamente ambas en ingls. La primera bastante didctica enfocada a los aspectos "++" del C; la segunda algo ms terica pero con la autoridad que le confiere ser del inventor del C++. Inicio. [1] Si en principio le parece confusa toda esta terminologa no se preocupe; lo esencial son los conceptos, puede seguir pensando en trminos de "variables" y "funciones". Poco a poco los nuevos vocablos "propiedades", "mtodos", "instancias", etc. irn fluyendo por s solos. En cualquier caso, tenga en cuenta que la terminologa utilizada en la POO es utilizada a veces de forma no demasiado consistente, lo que puede inducir a confusin durante el trnsito de la programacin tradicional a la POO. En otras ocasiones, en especial en algunos textos universitarios, se cuidan en exceso el rigor y el formalismo con lo que se tienen textos elegantsimos e irreprochables con los que es casi imposible enterarse de que se trata.

[2] Por esta razn, en la literatura forense pueden encontrarse frases como las siguiente: "Un mensaje es una peticin que se hace a un objeto para que aplique uno de sus mtodos". En realidad es la otra forma de decir que se invoca una funcin de una clase desde una de sus instancias (un objeto). Debemos reconocer que esta forma de expresar el comportamiento de los objetos, cuando se explican sus funciones miembro refirindose a ellas como "mensajes" que se lanzan a los objetos, es muy del gusto de los partidarios de la POO, de forma que Bruce Eckel ( Thinking in C++) llega a afirmar que: "La POO puede resumirse en una sola frase: Enviar mensajes a objetos", y que cuando se ha asumido esto, el uso de C++ resulta sorprendentemente sencillo. Gran parte de esta terminologa proviene en realidad de Smalltalk. Uno de los primeros lenguajes orientados a objeto desarrollado en el hoy legendario PARC "Palo Alto Research Center" de Xerox en California, donde nacieron muchas de las ideas que hoy pueblan el mundo de la informtica. [3] Precisamente el hecho de poder incluir funciones en las estructuras es la sntesis del avance que supuso C++ frente al C clsico ( 0.Iw1). 4.9).

[4] En realidad los operadores C++ son funciones disfrazadas (

1.2 El lenguaje C++


"Learn not just the hows, but the whys too". Greg Comeau [7].

1 Generalidades
C++ es un lenguaje imperativo orientado a objetos derivado del C [1]. En realidad un superconjunto de C, que naci para aadirle cualidades y caractersticas de las que careca. El resultado es que como su ancestro, sigue muy ligado al hardware subyacente, manteniendo una considerable potencia para programacin a bajo nivel, pero se la han aadido elementos que le permiten tambin un estilo de programacin con alto nivel de abstraccin. Nota: estrictamente hablando, C no es un subconjunto de C++; de hecho es posible escribir cdigo C que es ilegal en C++. Pero a efectos prcticos, dado el esfuerzo de compatibilidad desplegado en su diseo, puede considerarse que C++ es una extensin del C clsico. La definicin "oficial" del lenguaje nos dice que C++ es un lenguaje de propsito general basado en el C, al que se han aadido nuevos tipos de datos, clases, plantillas, mecanismo de excepciones, sistema de espacios de nombres, funciones inline, sobrecarga de operadores, referencias, operadores para manejo de memoria persistente, y algunas utilidades adicionales de librera (en realidad la librera Estndar C es un subconjunto de la librera C++). Respecto a su antecesor, se ha procurando mantener una exquisita compatibilidad hacia atrs por dos razones [2]: poder reutilizar la enorme cantidad de cdigo C existente, y facilitar una transicin lo ms fluida posible a los programadores de C clsico, de forma que pudieran pasar sus programas a C++ e ir modificndolos (hacindolos ms "++") de forma gradual. De hecho, los primeros compiladores C++ lo que hacan en realidad era traducir (preprocesar) a C y compilar despus [3] (las consecuencias se dejan sentir todava en el lenguaje 1.4.2).

Por lo general puede compilarse un programa C bajo C++, pero no a la inversa si el programa utiliza alguna de las caractersticas especiales de C++. Algunas situaciones requieren especial cuidado. Por ejemplo, si se declara una funcin dos veces con diferente tipo de argumentos, el compilador C invoca un error de "Nombre duplicado", mientras que en C++ quizs sea interpretado como una sobrecarga de la primera funcin (que sea o no legal depende de otras circunstancias). Como se ha sealado, C++ no es un lenguaje orientado a objetos puro (en el sentido en que puede serlo Java por ejemplo), adems no naci como un ejercicio acadmico de diseo. Se trata simplemente del sucesor de un lenguaje de programacin hecho por programadores (de alto nivel) para programadores, lo que se traduce en un diseo pragmtico al que se le han ido aadiendo todos los elementos que la prctica aconsejaba como necesarios, con independencia de su belleza o purismo conceptual ("Perfection, in some language theoretical sense, is not an aim of C++. Utility is" [6]). Estos condicionantes tienen su cara y su cruz; en ocasiones son motivo de ciertos "reproches" por parte de sus detractores, en otras, estas caractersticas son precisamente una cualidad. De hecho, en el diseo de la Librera Estndar C++ ( 5.1) se ha usado ampliamente esta dualidad (ser mezcla de un lenguaje tradicional con elementos de POO), lo que ha permitido un modelo muy avanzado de programacin extraordinariamente flexible (programacin genrica). Aunque C++ introduce nuevas palabras clave y operadores para manejo de clases, algunas de sus extensiones tienen aplicacin fuera del contexto de programacin con objetos (fuera del mbito de las clases), de hecho, muchos aspectos de C++ que pueden ser usados independientemente de las clases [5].

Del C se ha dicho: "Por naturaleza, el lenguaje C es permisivo e intenta hacer algo razonable con lo que se haya escrito. Aunque normalmente esto es una virtud, tambin puede hacer que ciertos errores sean difciles de descubrir" ( Shildt). Respecto al C++ podramos decir otro tanto, pero hemos de reconocer que su sistema de deteccin de errores es mucho ms robusto que el de C, por lo que algunos errores de este sern rpidamente detectados. Desde luego, C++ es un lenguaje de programacin extremadamente largo y complejo; cuando nos adentramos en l parece no acabar nunca. Justo cuando aprendemos un significado descubrimos que una mano negra ha aadido otras dos o tres acepciones para la misma palabra. Tambin descubrimos que prcticamente no hay una regla sin su correspondiente excepcin. Cuando aprendemos que algo no se puede hacer, hay siempre algn truco escondido para hacerlo, y cuando nos dicen que es un lenguaje fuertemente tipado ("Strong type checking"), resulta completamente falso. A pesar de todo, ha experimentado un extraordinario xito desde su creacin. De hecho, muchos sistemas operativos [4], compiladores e intrpretes han sido escritos en C++ (el propio Windows y Java). Una de las razones de su xito es ser un lenguaje de propsito general que se adapta a mltiples situaciones. Para comprobar el xito e importancia de los desarrollos realizados en C++ puede darse una vuelta por la pgina que mantiene el Dr. Stroustrup al respecto: www.research.att.com. Tanto sus fervientes defensores como sus acrrimos detractores han hecho correr ros de tinta ensalzando sus cualidades o subrayando sus miserias, aunque todo el mundo parece estar de

acuerdo en que es largo y complejo. Ha servido de justificacin para el diseo de otros lenguajes que intentan eliminar sus inconvenientes al tiempo que mantener sus virtudes (C# y Java por ejemplo), y una de sus ltima incorporaciones, las plantillas ( paradigma de programacin (metaprogramacin). 4.12), ha sido origen de un nuevo

En mi opinin, cualquier lenguaje de propsito general que como C++, permita tocar ambos mundos, la programacin de bajo nivel y altos niveles de abstraccin, resultar siempre e inevitablemente complejo. Ocurre lo mismo con los lenguajes naturales que son tambin extraordinariamente complejos (esto lo saben bien los gramticos). Cualquier comunicacin entre humanos presupone una ingente cantidad de conocimientos y suposiciones previas entre los interlocutores. A pesar de lo cual, la comunicacin exacta y sin ambigedades entre dos personas no resulta fcil.

2 Consejos para mejorar el rendimiento


Lo mismo que en su ancestro, en el diseo del C++ prim sobre todo la velocidad de ejecucin del cdigo [4]. Tanto uno como otro representan los ejecutables ms rpidos que se pueden construir para una mquina y circunstancias determinadas. En este sentido, la nica alternativa de mejora es la codificacin manual, el "pulido" de determinadas rutinas (o de todo el cdigo) en ensamblador, aunque evidentemente esto es impracticable para aplicaciones medianamente grandes, a no ser que se disponga de todos los recursos y tiempo del mundo. Con todo, a pesar de ser un lenguaje intrnsecamente rpido, y de que los compiladores modernos son bastante "inteligentes" en este sentido (adoptan automticamente las decisiones que resultan en el cdigo de ejecucin ms eficiente), es mucho lo que puede hacer el programador para favorecer esta rapidez con solo adoptar algunas sencillas precauciones. Estos son los consejos: Use enteros (int) con preferencia sobre cualquier otro tipo de variable numrica. En especial en los contadores de bucles. Las operaciones con enteros son del orden de 10 a 20 veces ms rpidas que las de nmeros en coma flotante. Use operadores incremento y decremento ++/-- ( 4.9.1) Use variables de registro, en especial en los bucles crticos, sobre todo si son anidados ( 4.1.8b). Use aritmtica de punteros frente a subndices de matrices ( 4.2.2). En problemas de computacin numrica recuerde que el clculo de funciones trascendentes es por lo general muy lento. Use referencias para argumentos y valores devueltos en funciones, antes que objetos "por valor" ( 4.2.3) 1.4.4; 4.11.8a), as como los Al definir clases utilice al mnimo las funciones virtuales (

punteros a funciones-miembro ( 4.2.1g) o Tenga en cuenta lo sealado respecto al rendimiento al tratar de: o Sustituciones inline en funciones definidas por el usuario ( 5.1 Funciones y macros) 4.4.6b) Preste atencin al modo de uso de aquellas funciones de librera que se presentan en dos versiones (

Los compiladores modernos permiten fijar que criterio de optimizacin ser dominante: La velocidad de ejecucin o el tamao. Tanto Borland C++ ( 1.4.3) como MS Visual C++ utilizan la misma

convencin de llamada para este propsito (opciones -O2 o -O1 respectivamente). Por su parte, GNU gcc dispone de varias opciones de optimizacin. En particular, la opcin -Os adopta las medidas tendentes a reducir el tamao del cdigo resultante. Nota: Aparte de las decisiones de optimizacin que puedan adoptar automticamente los compiladores y las reglas de precaucin anteriores, las modernas "suites" ofrecen herramientas de anlisis que permiten conocer de forma objetiva como es la utilizacin de recursos dentro del programa, de forma que se puedan adoptar precauciones en las zonas que resulten ms costosas, y concentrar nuestros esfuerzos de optimizacin en la zonas donde resulten ms provechosos. El compilador GNU cpp dispone de la utilidad gcov, que ofrece estadsticas para analizar el rendimiento del cdigo. Entre otros datos: Cmo se ejecuta cada lnea de cdigo Qu lnea se est ejecutando actualmente. Cuanto tiempo consume cada seccin de cdigo Posibilidad de anlisis a nivel de fichero o de funcin

Inicio. [1] Los lenguajes imperativos son aquellos en los que se especifica cmo conseguir los objetivos que se persiguen. C; C++; Javascript y Perl, entre otros muchos, pertenecen a esta categora. Por contra, los lenguajes declarativos son aquellos en los que se especifica que objetivo se persigue, sin preocuparse por el cmo. SQL y HTML son quizs los ejemplos ms representativos de esta categora. [2] El propio Stroustrup reconoce en el prlogo de su primer libro sobre C++: "Se ha dado gran importancia a mantener compatibilidad con C .... C++ debe la mayor parte a C. C es mantenido como un subconjunto" ( Stroustrup 1987).

[3] De hecho, el mentado compilador Zortech C++, se ofreca como: "The World's first 'TRUE' C++ compiler for MS-DOS". [4] Stroustrup seala que una de las razones que llevaron a K&R a disear el C fue no tener que programar en ensamblador (*), y que en el diseo de C++ se cuid no perder las ventajas ganadas en este sentido. Precisamente comenz a desarrollar C++ como un lenguaje que le ayudara en el trabajo de diseo de un Sistema Operativo distribuido. (*) En ocasiones, C ha sido considerado como un "lenguaje ensamblador de alto nivel". [5] "You are not doing OO just because you are compiling with C++" Ian Joyner "C++??" ( [6] Bjarne Stroustrup. Entrevista con Al Stevens en Dr. Dobb's Journal Sept. 1992. [7] Entrevista en "C++ Pointers and Dynamic Memory Management" de Michael C. Daconta. Edit. John Wiley & Sons, Inc. ISBN 0-471-04998-0 7).

1.3 Estructura de un programa


"The input of computation is energy and information; the output is order, structure, extropy" Kevin Kelly: "God Is the Machine" en Wired Magazine www.wired.com

1 Sinopsis
La estructura de un programa es una cuestin que puede ser abordada desde varios puntos de vista, en este captulo consideramos solo dos: Componentes lgicos: se refiere a los diversos elementos que componen una aplicacin, desde los ms complejos hasta los ms simples. Si comparamos un programa con un edificio, los elementos iran desde el edificio como un todo, a los ladrillos (sus elementos ms pequeos) 1.3.1. Almacenamiento: se refiere a como estn alojadas sus partes en la mquina que lo ejecuta. Esta cuestin puede ser abordada desde dos perspectivas: Organizacin lgica. Comprende las caractersticas de los diversos tipos de almacenamiento que se distinguen en un programa C++ ( 1.3.2).

Organizacin fsica. Toma en consideracin los diversos dispositivos fsicos utilizados por el programa para alojarse l mismo y sus datos ( 2.2.6).

1.4 Proceso de creacin de un programa


Regla de oro de la programacin: !! Nunca est terminado del todo

1 Sinopsis
Programming is the art of expressing solutions to problems so that a computer can execute those solutions. Bjarne Stroustrup: "Programming: Principles and Practice Using C++". Escribir un programa es establecer el comportamiento de una mquina mediante una serie de algoritmos que definirn su funcionamiento . En el estado actual de la ciencia, este algoritmo se plasma por escrito utilizando un lenguaje artificial comprensible por el humano-programador. Generalmente estas instrucciones, que aqu se denominan cdigo fuente, vienen acompaadas de algunos datos en forma de texto o imgenes, contenidas en uno o varios ficheros denominados ficheros de recursos ("resources"). Sin embargo, las instrucciones y recursos solo pueden ser utilizadas por la mquina despus de un proceso de traduccin que es realizado por la propia mquina (puede ser distinta de la que ejecuta el programa). El proceso exige que el cdigo fuente sea transformado en una nueva secuencia de instrucciones segn un nuevo sistema de codificacin (el lenguaje mquina), y que los recursos adopten una disposicin particular. Este conjunto de

instrucciones y datos, que constituyen el denominado ejecutable, corresponden a acciones concretas y datos, que pueden ser entendidas, ejecutadas y utilizados por la mquina. En general este comportamiento pretende modelar o mimetizar el comportamiento de una entidad del mundo real, o de una abstraccin que hemos imaginado; y es de tipo genrico. Se pretende que la mquina se comporte como una funcin que acepta un conjunto de condiciones de entrada y devuelve como salida un comportamiento concreto y predecible para cada combinacin de las condiciones de entrada.

2 Presentacin del problema


Hay bastante literatura sobre programacin en general; a los acadmicos les gusta hablar de "Teora de la Programacin", y mucha gente se ha dedicado a especular sobre el tema. Incluso hay modas al respecto [4]. Es posible confeccionar una lista de las caractersticas que "debe" y "no debe" tener un buen programa (incluyendo la del Jefe, que solo tiene dos puntos: "Que est para ayer; que salga barato"). El propio Stroustrup ( TC++PL) compara las condiciones para escribir un buen programa con las de escribir buena prosa. Segn l, existen dos respuestas: "Saber que se quiere decir" y "Prctica. Imitar buenos escritores". Ms adelante nos recuerda que aprender a manejar bien un lenguaje puede constar tanto tiempo y esfuerzo como aprender a expresarse en un lenguaje natural o tocar un instrumento. Por supuesto sera un atrevimiento por mi parte contradecir tan docta opinin, pero puestos a filosofar me gustara puntualizar que el verdadero problema est en el segundo punto de la segunda respuesta; la primera, aunque ciertamente importante, me parece la verdad de Perogrullo . Siempre me ha parecido que programar (programar bien) tiene mucho de arte. Me parece que debe ocurrir como con la msica; seguramente muchos pueden decir que debe tener una buena ejecucin de violn, pero imitar a Paganini debe ser harina de otro costal. Seguramente los profesores de armona saben que debe tener y no tener una buena sinfona, pero otra cosa debe ser imitar a Mozart. Bajando a la tierra; tampoco se trata aqu de hacer "Paganinis de la programacin C++" (ya me gustara para m); el mensaje que quisiera transmitir es doble: El contenido en un viejo Refrn Espaol: "La Universidad no presta lo que la naturaleza no da". Como suena un poco duro, aadir un consuelo para los que somos menos dotados; un proverbio que le hace tiempo, en lnea con la respuesta de Stroustrup: "Por el dinero del trabajo los Dioses lo venden todo". A continuacin se comentan brevemente los pasos imprescindibles en la creacin de un programa C++. Vaya por delante, que las anotaciones de los puntos 3, 4 y 5 son opinin del que suscribe basados en la propia experiencia, por tanto totalmente subjetivos y opinables.

3 Comprender el problema.
"Custom development is that murky world where a customer tells you what to build, and you say, "are you sure?" and they say yes, and you make an absolutely beautiful spec, and say, "is this what you want?" and they say yes, and you make them sign the spec in indelible ink, nay, blood, and they do, and

then you build that thing they signed off on, promptly, precisely and exactly, and they see it and they are horrified and shocked, and you spend the rest of the week reading up on whether your E&O insurance is going to cover the legal fees for the lawsuit you've gotten yourself into or merely the settlement cost. Or, if you're really lucky, the customer will smile wanly and put your code in a drawer and never use it again and never call you back". Joel on Software "Set Your Priorities" www.joelonsoftware.com

"As more became known about what people wanted to do with computer, it became clear that there would always be increasingly more complex problems to solve. A part of that realization is the realization that our ability to accurately describe the problem determines the ability for the problem to be solved. Most people are incapable of clearly and precisely articulating -- to the level necessary -- the problems that they're trying to solve. This is a problem that is getting larger and not smaller". Robert Bogue (Jupitermedia Corp) en "Breaking Down Software Development Roles". "Often, a problem is only fully understood through the process of programming a solution for it". Bjarne Stroustrup: "Programming: Principles and Practice Using C++".

Esta es la tpica obviedad que a veces se pasa por alto. Hemos dicho que escribir un programa es establecer el comportamiento de una mquina; parece lo ms natural del mundo enterarse primero de cual es ese comportamiento. Tener una imagen mental lo ms clara posible de las caractersticas de lo que pretendemos modelar. Esta cuestin es lo que los tericos denominan el "espacio" del problema, "'What' domain" en la literatura inglesa. A esta fase se la suele denominar anlisis, y mi consejo particular es que despus de una primera toma de contacto, el segundo paso sea definir de la forma ms detallada posible el principio y el final del problema. Es decir: cual es la informacin de partida (incluyendo su formato y en que soporte se recibe) y cual es la informacin final y en que soporte se proporcionar; no es lo mismo mostrar una imagen que componer una factura o disparar un proceso si un sensor analgico-digital nos suministra una determinada seal (por citar algn ejemplo). Normalmente en ambas cuestiones tiene mucho que decir el cliente [2], es lo que se llama especificacin; el resto (lo que hay entre los datos de entrada y la salida), debe rellenarlo el programador. Generalmente si se tienen bien definidos ambos extremos, se tiene resuelta la mitad del problema; cuando se tengan diseados los ficheros se tendrn dos terceras partes -ver a continuacin-. Este sistema tiene adems la ventaja de poner inmediatamente de manifiesto las indefiniciones de partida; a veces los clientes no saben exactamente qu desean y hay que ayudarles a centrar el problema. Dentro de esta fase tiene especialsima importancia el tema de los lmites; esto se refiere al orden de magnitudes que se manejarn. De que rango sern las magnitudes numricas? Podrn adoptar valores negativos? Hay informacin alfanumrica? Como son de largas estas cadenas?. Especialmente si el programa implica diseo de archivos (como es casi seguro), Cual podr llegar a ser su tamao dentro de la vida del programa?. Si se manejan ficheros u objetos binarios, Como

son de grandes? Que concepto tiene el cliente de los que sera "rpido" o "lento"? (milisegundos, minutos, horas?). En esta fase sea especialmente precavido y no se crea a pi juntillas todo lo que le digan (intente hacer de abogado del diablo). Como postre, disee las lneas maestras de una estrategia de recuperacin de errores de ejecucin, incluyendo que har con los no recuperables (errores fatales). Piense por ejemplo que si algn da lo llaman para ver "que ha pasado", quizs le interese disponer de un volcado de texto ASCII en el disco con una descripcin del estatus del programa como parte de las funciones de salida ( 1.5). Hoy da, cuando se empieza a hablar de frigorficos que avisarn de que faltan provisiones o de lavadoras que avisarn al tcnico si se estropean, no estara de ms que sus programas estuviesen a la altura de las circunstancias.

4 Disear los ficheros y mdulos


Si el programa debe utilizar ficheros que no vengan impuestos (ya existentes), y suponiendo que todo lo anterior est suficientemente claro, este es el momento de hacerlo. Ponga por escrito la especificacin de tales ficheros, incluyendo el nombre que dar a las variables y, en su caso, el que tendrn en el disco o almacenamiento externo. Esto puede concretarse quizs a la definicin de algunas estructuras ( pas por alto. 4.5). En esta fase es posible que tenga que repreguntar alguna cosa que se

Teniendo ya una imagen ms o menos clara de lo que har su programa, si ste es mediano o grande, es posible que todava tenga que realizar una labor previa antes de ponerse a escribir el cdigo: disear a grandes rasgos cuales sern los mdulos del programa; mdulos que se correspondern aproximadamente con la distribucin del cdigo en ficheros fuente independientes. Quizs tenga que decidir tambin si algunas partes aparecern como libreras [1]. Recuerde lo indicado al respecto al tratar de los Subespacios de Nombres ( 4.1.11).

Esta fase es especialmente importante en el caso de programas muy grandes, cuyo desarrollo se reparte entre varios programadores que se encargan de uno o varios de estos mdulos. En estos casos, el anlisis, la especificacin, la subdivisin en partes (con sus especificaciones particulares), y la asignacin de estas como tareas a los programadores, lo habr realizado el jefe de programacin y desarrollo.

5 Escribir el cdigo
Suponiendo cumplimentados los pasos anteriores, el programador est en condiciones de construir una imagen mental clara de como ser esa conexin entre la informacin de entrada y la salida, es lo que se denomina "espacio" de la solucin ("'How' domain"); su forma concreta es justamente el fuente del programa que se pretende. La codificacin consiste justamente trasportar a papel (en el lenguaje de programacin elegido) la imagen mental de esa conexin.

Para escribir el cdigo fuente de un programa C++ solo se puede utilizar un subconjunto de 96 caracteres del juego total de caracteres US-ASCII ( 2.2.1a). Son los siguientes [8]:

Juego de caracteres imprimibles: a y A Y 0 _ = b z B Z 1 { , c d e f g h i j k l m n o p q r s t u v w x C D E F G H I J K L M N O P Q R S T U V W X 2 3 4 5 6 7 8 9 } [ ] # ( ) < > % : ; . ? * + \ "

/ ^ & | ~ !

Caracteres no-imprimibles denominados separadores Espacio horizontal; Tabulacin horizontal (TAB); Tabulacin vertical (VT); Salto de forma (FF); Nueva lnea (NL). Nota: Para escribir el cdigo solo hace falta un editor de texto plano, aunque las modernas "suites" de programacin incluyen editores especficos que estn conectados con el depurador, el compilador el enlazador (ver ms adelante) e incluso el sistema de ayudas, de forma que, por ejemplo, pueden mostrarnos automticamente la sentencia en la que se ha producido un error de compilacin, o la pgina correspondiente del manual si pulsamos en una palabra reservada y pedimos ayuda (F1 generalmente). Tambin muestran en diversos colores las palabras clave, los comentarios, Etc. Los ms avanzados disponen incluso de opciones que podramos calificar de "inteligentes", en el sentido que pueden prever cual ser nuestro prximo movimiento en funcin de la sentencia que estamos escribiendo (por ejemplo, ofrecernos una lista de las propiedades y mtodos de una clase si nos estamos refiriendo a ella). Durante la fase de escritura no desdee dos puntos: Incluir la mayor cantidad de comentarios y aclaraciones posibles. Cuando se est muy "metido" en el programa todo parece evidente, pero piense que tiene que retocarlo dentro de unos aos, quizs entonces le parezca "Chino" y agradecer haber dejado la mayor cantidad de documentacin y aclaraciones al respecto. Incluso si es seguro que no volver a verlo, piense en el sufrido programador que le seguir si tiene que habrselas con su cdigo. En este sentido C++ no es precisamente COBOL, aunque afortunadamente permite incluir en el fuente comentarios todo lo extensos que se desee ( 3.1). No caiga tampoco en el error de pensar que esa informacin ya est en la documentacin escrita que le han obligado a entregar junto con los fuentes; posiblemente dentro de unos aos Usted mismo no encuentre esos documentos. Incluir la mayor cantidad posible de rutinas y condiciones de comprobacin de errores. Piense que el operador es un "manazas" o que los datos pueden venir con alguna corrupcin, error de transmisin, etc. Verifique constantemente que las condiciones son las esperadas ( 1.4.5).

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

6 Preproceso
En la primera fase de la compilacin; un programa especial, denominado make, es encargado de iniciar el proceso llamando a los diversos mdulos que se encargan de la construccin del ejecutable (en 1.4.0 se amplan detalles sobre esta parte del proceso). El primero de estos mdulos es el preprocesador. El preprocesador ( 1.4.1) estudia el texto buscando directivas de preprocesado ( 4.9.10), por ejemplo sentencias que pueden ser suprimidas, incluye los ficheros correspondientes a las directivas

#include, sustituye los #define, elimina los comentarios y expande las macros encontradas en

el fuente y en los propios ficheros incluidos. El resultado obtenido es lo que se denomina unidad de compilacin ( 1.4.2).

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

name [ ] = "Playa Victoria" ;

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

9 Generador de cdigo
Todos estos tokens identificados por el analizador sintctico, son organizados en una estructura como las hojas de un rbol. A continuacin, el generador de cdigo recorre este rbol traduciendo sus hojas directamente en cdigo de la mquina para la que se compila [11]. Si se solicita, el compilador tambin puede en esta fase generar un fichero en lenguaje macro ensamblador para su posible inspeccin por el programador (este cdigo es tambin dependiente de

la mquina para la que se compila y fcilmente entendible por el humano; puede contener incluso comentarios para facilitar su lectura). Nota: Los compiladores modernos suelen incluir opciones que permiten generar cdigo optimizado para el tipo de procesador que se utilizar. Por ejemplo, el compilador Borland C++ dispone de opciones que permiten generar cdigo optimizado para procesadores Intel de modelos especficos ( 1.4.3a). Como cabra esperar, el compilador GNU c++ es el que ofrece ms posibilidades en este sentido, que incluyen el tipo de procesador dentro de una larga lista de fabricantes, y dentro de estos diferentes modelos. En concreto, para la familias Intel i386 y x86-64, permite elegir entre 20 posibilidades diferentes!!.

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

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

Hay que tener en cuenta que generalmente el enlazador puede producir diversos tipos de resultados:

10.1 Versin de depuracin


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

10.2 Versin de publicacin


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

10.3 Librera
En las pginas siguientes veremos que como resultado de la "compilacin", no siempre se desea conseguir un ejecutable; al menos no en el sentido tradicional del trmino, sino una librera (de las que existen varios tipos), o un fichero objeto.

En lo que respecta al lenguaje C++, existen dos tipos fundamentales: Estticas y Dinmicas. Las primeras son colecciones de ficheros precompilados, cuyo cdigo puede ser aadido a un ejecutable en el proceso de enlazado (los ficheros de la Librera Estndar 5 que acompaan a los compiladores C++ son de este tipo). Las segundas son autnticos ejecutables externos que son invocados desde otro ejecutable y devuelven el control a este cuando terminan su ejecucin. Ms detalles al respecto en: ( 1.4.4a).

11 Errores

Volver al principio (rescribir el cdigo)

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

11.1 Tipos de errores


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

11.2 Gravedad de los errores


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

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

11.3 Generalidades sobre los errores de compilacin


Respecto a los errores de compilacin, es importante hacer una advertencia al nefito: Con frecuencia el compilador nos informa de error en una lnea ms abajo de donde est verdaderamente. Por ejemplo, olvidar un punto y coma de final de sentencia puede dar lugar a que el compilador nos informe de un error incomprensible dos o tres lnea ms abajo. Cuando se realizan modificaciones en fuentes grandes y no se tiene mucha prctica, es preferible realizar cambios pequeos y compilar sistemticamente despus de cada uno. As sabremos que el error corresponde a lo ltimo que hemos tocado. Hay veces en que quitar una simple coma en una sentencia produce una listado de 15 o 20 errores en lneas siguientes. !Sbitamente nada tiene sentido para el compilador !!. [5] En las asignaciones del tipo: Lvalue = Rvalue; en las que intentamos asignar un valor Rvalue ( 2.1 que puede ser el resultado de una expresin)

a un Lvalue ( 2.1), son muy frecuentes los errores en que el compilador produce un mensaje del siguiente aspecto:

Error .... Cannot convert 'xxxxx' to 'yyyyy' in function .... Lo importante a resear aqu, es que las expresiones xxxxx e yyyyy informan sobre el tipo de objeto que hay en cada lado de la expresin de asignacin. Nota: En el captulo dedicado a los tipos de datos ( compilador clasifica los objetos segn su tipo. 2.2) se describe detalladamente como el

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

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

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

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

Si est interesado en las caractersticas y posibilidades de estos productos, la mayora comerciales y algunos muy costosos, aparte de la correspondiente bsqueda en Google, existe un interesante artculo de Scott Meyers (uno de los "Gurus" del C++) y Martin Klaus titulado "A First Look at C++ Program Analyzers", en el que se repasan las cualidades y caractersticas de distintos paquetes, incluyendo una evaluacin de su comportamiento frente a lo que el autor considera deseable. Aparecido en el nmero de Febrero de 1997 del Dr. Dobb's Journal, existe una versin de prepublicacin accesible on-line, que es incluso ms completa que el artculo publicado (probablemente debido a las exigencias de maquetacin de la revista): www.aristeia.com.

Uno de los productos punteros y ms antiguos, es el de Gimpel Software www.gimpel.com; esta empresa dispone de dos versiones denominadas PC-Lint y FlexeLint. La primera para Windows, la segunda, ms general, para cualquier entorno que soporte un compilador C, incluyendo Unix y Linux. Si tiene inters en comprobar ms de cerca el tipo de informacin que proporcionan estas utilidades, en el sitio de este fabricante existe una seccin denominada Bug del mes ("Bug of the month") en la que se exponen ejemplos de cdigo, junto con el resultado del anlisis (despus de pulsar un botn). Adems de smamente instructivos, los casos propuestos pueden servirle para auto-evaluar sus conocimientos de C++ al respecto. A mi entender tambin pueden constituir una magnfica fuente de inspiracin para los enseantes que busquen material para ejemplo o evaluacin (sed piadosos en los exmenes porque algunos son realmente para niveles avanzados. No se puede pretender que despus de un semestre de estudio, el alumno est en condiciones de adivinar correctamente el "bug C/C++ del mes" :-)

11.4 Errores de ejecucin


Para los errores de tiempo de ejecucin se requieren estrategias especiales. En principio, durante la fase de comprobacin inicial, se tienen las ofrecidas por el depurador . Prcticamente todos los entornos de desarrollo disponen de un depurador ms o menos potente y sofisticado. Puede afirmarse que el depurador es otra herramienta que no debe faltar en el arsenal de cualquier programador profesional, en especial porque hay errores que son prcticamente imposibles de diagnosticar y corregir sin su ayuda. Como se ha indicado, el depurador incluye en el ejecutable un cdigo especial que realiza las funciones de depuracin deseadas, pero aparte de los que podramos denominar estndar (cuyos

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

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

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

Si desea saber ms sobre aspectos relacionados con la compilacin, preproceso, anlisis sintctico y semntico, traduccin del cdigo, etc, mi consejo es que consulte "Compiladores y Procesadores de Lenguajes" [Jimnez-04] Inicio.

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

("Fuzzy logic"). Das despus conversaba l con otras personas y me sorprendi como introduca el concepto de la lgica difusa con total oportunidad y como si fuese una cosa sabida de toda la vida. Solo haba cambiado una palabra; "borrosa" en lugar de difusa. [6] Las circunstancias son exactamente idnticas a las que se presentan en los lenguajes naturales. Tambin en estos es posible construir frases sintcticamente correctas pero carentes de sentido (los polticos saben mucho de esto). [7] En esta nomenclatura, una versin 2.4.10 es anterior a la 2.13.0, que a su vez es anterior a la 12.3. [8] Para resolver el problema de que algunos de estos smbolos no aparecen en los teclados de determinados idiomas (por ejemplo, la tilde ~ en los teclados espaoles) se recurri a representarlos mediante ternas de otros caracteres, los denominados trigrafos ( 3.2.3e).

[9] Esta regla de anlisis es conocida como de Max Munch; en realidad no es ningn personaje real, sino un convenio adoptado por los integrantes del primer Comit de Estandarizacin del lenguaje. [10] En general, un "parser" es un programa diseado para analizar un documento. [11] "On average, each line of code in a system programming language translates to about five machine instructions, compared to one instruction per line in assembly language (in an informal analysis of eight C files written by five different people, I found that the ratio ranged from about 3 to 7 instructions per line; in a study of numerous languages Capers Jones found that for a given task, assembly languages require about 3-6 times as many lines of code as system programming languages). Programmers can write roughly the same number of lines of code per year regardless of language, so system programming languages allow applications to be written much more quickly than assembly language". John K. Ousterhout. "Scripting: Higher Level Programming for the 21st Century" www.tcl.tk

[12] Como botn de muestra, sealar que en una aplicacin C++ tpica Windows, cuyo ejecutable resultaba de 631 KBytes en su versin "de campo", la inclusin de la informacin necesaria para depuracin hizo aumentar su tamao hasta 3.257 KBytes (Compilador GNU gcc-g++ 3.4.2 para Windows -incluido en Dev-C++ -)

1.5 Secuencia de ejecucin de un programa


Desde que es invocado por su entorno (normalmente el Sistema Operativo) hasta que termina, la ejecucin de un programa C++ recorre las siguientes etapas:

1 Se ejecuta el mdulo inicial. Durante la fase de enlazado de la compilacin, el enlazador aade a cualquier programa C++ un mdulo especial, de inicio, que es realmente el punto de entrada a la ejecucin del programa [2].

Este mdulo realiza diversas tareas, entre ellas iniciar todas las variables estticas o globales (ver nota), controlar la ejecucin de posibles funciones opcionales de inicio (ver punto siguiente) y finalmente, invocar la funcin main ( 4.4.4).

Nota: cuando se compila cualquier mdulo, en el objeto resultante existe un segmento denominado _INIT_ que contiene una referencia ("Init entry") al constructor de cada objeto global que deba ser inicializado, as como un orden de prioridad. Ms tarde, cuando el enlazador construye un ejecutable, estas entradas se agrupan en una tabla, la tabla de inicio ("Init table") que contiene ordenadamente todas las entradas de los constructores de los objetos que existen en los mdulos que componen el programa. Finalmente, esta tabla es utilizada por el mdulo de inicio cuando el programa es iniciado.

2 Se ejecutan las funciones de inicio. Algunos compiladores permiten al programador la opcin de que se invoquen determinadas funciones, antes que se realice la llamada a main. Estas funciones representan tareas preparatorias adicionales, que queremos realizar antes de que se inicie la ejecucin. Esto se consigue con la directiva de inicio #pragma

startup (

4.9.10i).

3 Se invoca la funcin main() Despus de lo anterior, el control pasa a una funcin que debe responder al nombre de main y le pasa algunos argumentos en base a datos que ha recibido a su vez del Sistema Operativo ( 4.4.4). As pues, en ausencia de funciones particulares de inicio, main representa el punto de la ejecucin a partir del cual el programador toma control de la ejecucin. El cuerpo de esta funcin representa la ejecucin del programa, su "carga til".

4 Se ejecutan las funciones de salida. Algunos compiladores permiten la opcin de llamar determinadas funciones antes que se alcance el final del programa, justo antes de su terminacin. Estas funciones, que representan tareas adicionales que queremos realizar antes de que el programa devuelva el control a su entorno de ejecucin. Se establecen con la directiva

#pragma exit (

4.9.10i).

La Librera Estndar C++ tambin proporciona una funcin especial: atexit() que permite la opcin de ejecutar un cdigo especfico en la terminacin ( 1.5.1).

5 Finalizacin
Un programa C++ puede terminar por varios motivos:

Se termine la funcin main(). Bien porque se alcance el corchete de cierre "}", bien porque se encuentra una sentencia return; esto ltimo es lo deseable (aunque no imprescindible), ya que el estndar define que main debe devolver un int a su entorno de ejecucin ( 4.4.4).

Se encuentra una invocacin a la funcin exit(), una funcin de la Librera Estndar ( 1.5.1). Se encuentra una invocacin a la funcin abort(), otra funcin Librera Estndar ( Se lanza una excepcin que no encuentra su manejador ("handler") correspondiente ( 1.6.3 Excepciones imprevistas). 1.5.1).

En el apartado 1.5.1 se incluye la descripcin de algunas de las funciones relativas a la terminacin de un programa [1]. Hay que recordar que en un programa C++ todos los objetos globales se mantienen activos hasta que se han ejecutado todas las funciones de salida. Las variables locales, incluyendo las declaradas en la funcin main son destruidas a medida que quedan fuera de mbito. Al final de un programa C++ Builder el orden de ejecucin es como sigue: Las funciones de salida son ejecutadas en el mismo orden que fueron insertadas por atexit. Las funciones declaradas en #pragma prioridad.

exit son ejecutadas en orden a sus cdigos de

Se llama al destructor de variables globales.

Ver algunos comentarios adicionales sobre un caso concreto: Inicio.

2.2.6.

[1] Aunque en rigor su descripcin debera estar incluida en el captulo 5 dedicado a la Librera Estndar, mientras no implemente completamente dicha parte en el presente "Libro", mantendremos aqu la descripcin de estas funciones. [2] El Estndar indica que tanto este mdulo como el de terminacin son dependientes de la implementacin (pueden ser diferentes para cada compilador).

1.6 Tratamiento de excepciones


'La respuesta real es hacer copias de seguridad de todo, con mucho cuidado y muy frecuentemente, ponindose en lo peor, ya que la definicin informtica de "lo peor" es "solo cuestin de tiempo"'. Paul Somerson "PC Magazine: DOS Powers Tools".

1 Introduccin
El problema de la seguridad es uno de los clsicos quebraderos de cabeza de la programacin. Los diversos lenguajes han tenido siempre que lidiar con el mismo problema: Qu hacer cuando se presenta una circunstancia verdaderamente imprevista? (por ejemplo un error). El asunto es especialmente importante si se trata de lenguajes para escribir programas de "Misin crtica"; digamos por ejemplo controlar los ordenadores de una central nuclear o de un sistema de control de trfico areo. Antes que nada, digamos que en el lenguaje de los programadores C++ estas "circunstancias imprevistas" reciben el nombre de excepciones, por lo que el sistema que implementa C++ para resolver estos problemas recibe el nombre de manejador de excepciones. As pues, las excepciones son condiciones excepcionales que pueden ocurrir dentro del programa durante su ejecucin. Por ejemplo, que ocurra una divisin por cero, se agote la memoria disponible, Etc. que requieren recursos especiales para su control. En este captulo trataremos del manejador de excepciones C++; una serie de tcnicas que permiten formas normalizadas de manejar los errores, intentando anticiparse a los problemas potenciales previstos e imprevistos. As como permitir al programador reconocerlos, fijar su ubicacin y corregirlos.

2 Manejo de excepciones en C++


El manejo de excepciones C++ se basa en un mecanismo cuyo funcionamiento tiene tres etapas bsicas: 1: Se intenta ejecutar un bloque de cdigo y se decide qu hacer si se produce una circunstancia excepcional durante su ejecucin. 2: Se produce la circunstancia: se "lanza" una excepcin (en caso contrario el programa sigue su curso normal). 3: La ejecucin del programa es desviada a un sitio especfico donde la excepcin es "capturada" y se decide que hacer al respecto.

Pero que es eso de "lanzar" y "capturar" una excepcin"? En general la frase se usa con un doble sentido: Por un lado es un mecanismo de salto que transfiere la ejecucin desde un punto (que "lanza" la excepcin) a otro dispuesto de antemano para tal fin (que "captura" la excepcin). A este ltimo se le denomina manejador o "handler" de la excepcin. Adems del salto -como un goto-, en el punto de lanzamiento de la excepcin se crea un objeto, a modo de mensajero, que es capturado por el "handler" (como una funcin que recibe un argumento). El objeto puede ser cualquiera, pero lo normal es que pertenezca a una clase especial definida al efecto, que contiene la informacin necesaria para que el receptor sepa qu ha pasado; cual es la naturaleza de la circunstancia excepcional que ha "lanzado" la excepcin [6]. Para las tres etapas anteriores existen tres palabras clave especficas: try, detalle del proceso es como sigue.

throw y catch. El

2.1 Intento ( try ).


En sntesis podemos decir que el programa se prepara para cierta accin, decimos que "lo intenta". Para ello se especifica un bloque de cdigo cuya ejecucin se va a intentar ("try-block") utilizando la palabra clave try. try { ... } // bloque de cdigo-intento

El juego consiste en indicar al programa que si existe un error durante el "intento", entonces debe lanzar una excepcin y transferir el control de ejecucin al punto donde exista un manejador de excepciones ("handler") que coincida con el tipo lanzado. Si no se produce ninguna excepcin, el programa sigue su curso normal. De lo dicho se deduce inmediatamente que se pueden lanzar excepciones de varios tipos y que pueden existir tambin receptores (manejadores) de varios tipos; incluso manejadores "universales", capaces de hacerse cargo de cualquier tipo de excepcin. A la inversa, puede ocurrir que se lance una excepcin para la que no existe manejador adecuado, en cuyo caso... (la solucin ms adelante). As pues, try es una sentencia que en cierta forma es capaz de especificar el flujo de ejecucin del programa. Un bloque-intento debe ser seguido inmediatamente por el bloque manejador de la excepcin.

2.2 Se lanza una excepcin ( throw ).


Si se detecta una circunstancia excepcional dentro del bloque-intento, se lanza una excepcin mediante la ejecucin de una sentencia throw. Por ejemplo: if (condicion) throw "overflow"; Es importante advertir que, salvo los casos en que la excepcin es lanzada por las propias libreras C++ (como consecuencia de un error 1.6.1a), estas no se lanzan espontneamente. Es el programador el que debe utilizar una sentencia (generalmente condicional) para, en su caso, lanzar la excepcin. El lenguaje C++ especifica que todas las excepciones deben ser lanzadas desde el interior de un bloque-intento y permite que sean de cualquier tipo. Como se ha apuntado antes, generalmente son un objeto (instancia de una clase) que contiene informacin. Este objeto es creado y lanzado en el punto de la sentencia throw y capturado donde est la sentencia catch. El tipo de informacin contenido en el objeto es justamente el que nos gustara tener para saber que tipo de error se ha producido. En este sentido puede pensarse en las excepciones como en una especie de correos que transportan informacin desde el punto del error hasta el sitio donde esta informacin puede ser analizada.

2.3 La excepcin es capturada en un punto especfico del programa ( catch ).


Esta parte del programa se denomina manejador ("handler"); se dice que el "handler" captura la excepcin. El handler es un bloque de cdigo diseado para manejar la excepcin precedido por la palabra catch. El lenguaje C++ requiere que exista al menos un manejador inmediatamente despus de un bloque try. Es decir, se requiere el siguiente esquema: try { // bloque de cdigo que se intenta ... } catch (...) { // bloque manejador de posibles excepciones ... } ... // continua la ejecucin normal

El "handler" es el sitio donde continua el programa en caso de que ocurra la circunstancia excepcional (generalmente un error) y donde se decide qu hacer. A este respecto, las estrategias pueden ser muy variadas (no es lo mismo el programa de control de un reactor nuclear que un humilde programa de contabilidad). En ltimo extremo, en caso de errores absolutamente irrecuperables, la opcin adoptada suele consistir en mostrar un mensaje explicando el error. Puede incluir el consabido "Avise al proveedor del programa" o bien generar un fichero texto (por ejemplo: error.txt) con la informacin pertinente, que se guarda en disco con objeto de que pueda ser posteriormente analizado y corregido en sucesivas versiones de la aplicacin [2]. Llegados a este punto debemos recordar que, como veremos en los ejemplos, las excepciones generadas pueden ser de diverso tipo (segn el tipo de error), y que tambin pueden existir diversos manejadores. De hecho se debe incluir el manejador correspondiente a cada excepcin que se pueda generar.

3 Resumen
Hemos dicho que try es una sentencia que en cierta forma es capaz de especificar el flujo de ejecucin del programa; en el fondo el mecanismo de excepciones de C++ funciona como una especie de sentencia if

... then .... else, que tendra la forma:

If { este bloque se ejecuta correctamente } then


seguir la ejecucin normal de programa

else // tres acciones sucesivas.


a. Crear un objeto con informacin del suceso (excepcin) b. Transferir el control de ejecucin al "handler" correspondiente c. Recibir el objeto para su anlisis y decisin de la accin a seguir en este caso la sintaxis utilizada es la siguiente:

try { // bloque de cdigo que se intenta ... } catch (...) { // captura de excepciones ... } ... // continua la ejecucin normal

El diseo del mecanismo de excepciones C++, someramente expuesto, tiene la ventaja de permitir resolver una situacin muy frecuente: el bloque en que se detecta el error no sabe que hacer en tal caso (cuando se presenta el error o excepcin); la accin depende en realidad de un nivel anterior, el mdulo que invoc la operacin. Como decimos, esta situacin es muy frecuente ( ), entre otras razones porque si un mdulo pudiera anticipar un error por si mismo, tambin podra evitarlo, con lo que no habra necesidad de mecanismo de excepciones. Esta circunstancia es especialmente patente en el caso de libreras, en las que el autor generalmente no sabe ni puede hacer nada al respecto de ciertos errores a excepcin de informar al usuario. Lo anterior no es bice para que, como buena prctica de programacin, se intente la captura sistemtica de errores lo ms prximo posible a su identificacin, dejando el mecanismo de excepciones para las situaciones realmente imprevisibles. Por ejemplo, siempre que sea posible: if (b == 0) { /* alguna accin... */; } else x = a/b;

4 Precauciones
Cuando se plantean este tipos de cuestiones de seguridad surge inevitablemente una pregunta: Que sucede si se producen errores (circunstancias excepcionales) durante el proceso de control de excepciones?. La respuesta ms honesta es que el sistema perfecto e invulnerable no existe. Aunque el sistema de excepciones de C++ es una formidable herramienta para controlar imprevistos, que permite hasta cierto punto, controlar imprevistos dentro de imprevistos. A pesar de ello, nada puede sustituir a una programacin cuidadosa. El propio Stroustrup advierte: "Aunque las excepciones se pueden usar para sistematizar el manejo de errores, cuando se adopta este esquema, debe prestarse atencin para que cuando se lance una excepcin no cause ms problemas de los que pretende resolver. Es decir, se debe prestar atencin a la seguridad de las excepciones. Curiosamente, las consideraciones sobre seguridad del mecanismo de excepciones conducen frecuentemente a un cdigo ms simple y manejable". Comentarios sobre la idoneidad del mecanismo de excepciones ( 1.6W2).

5 Tipos de excepciones
Durante la ejecucin de un programa pueden existir dos tipos de circunstancias excepcionales: sncronas y asncronas. Las primeras son las que ocurren dentro del programa. Por ejemplo, que se agote la memoria o cualquier otro tipo de error. Son a estas a las que nos hemos estado

refiriendo. En la introduccin (1 ) hemos indicado: "las excepciones son condiciones excepcionales que pueden ocurrir dentro del programa..." y las nicas que se consideran. Las excepciones asncronas son las que tienen su origen fuera del programa, a nivel del Sistema Operativo. Por ejemplo que se pulsen las teclas Ctrl+C. Generalmente las implementaciones C++ solo consideran las excepciones sncronas, de forma que no se pueden capturar con ellas excepciones tales como la pulsacin de una tecla. Dicho con otras palabras: solo pueden manejar las excepciones lanzadas con la sentencia throw. Siguen un modelo denominado de excepciones sncronas con terminacin, lo que significa que una vez que se ha lanzado una excepcin, el control no puede volver al punto que la lanz. Nota: El "handler" no puede devolver el control al punto de origen del error mediante una sentencia return. En este contexto, un return en el bloque catch supone salir de la funcin que contiene dicho bloque.

El sistema Estndar C++ de manejo de excepciones no est diseado para manejar directamente excepciones asncronas, como las interrupciones de teclado, aunque pueden implementarse medidas para su control. Adems las implementaciones ms usuales disponen de recursos para menejar las excepciones del Sistema Operativo. Por ejemplo, C++ Builder dispone de los mecanismos adecuados para manejar excepciones de Windows-32 (asncronas) a travs de su librera VCL [1] ( 1.6w1).

6 Secuencia de ejecucin
Como puede verse, la filosofa C++ respecto al manejo de excepciones no consiste en corregir el error y volver al punto de partida. Por el contrario, cuando se genera una excepcin el control sale del bloque-intento try que lanz la excepcin (incluso de la funcin), y pasa al bloque catch cuyo manejador corresponde con la excepcin lanzada (si es que existe). A su vez el bloque catch puede hacer varias cosas: Relanzar la misma excepcin ( 1.6.1).

Saltar a una etiqueta ( 1.6.2) Terminar su ejecucin normalmente (alcanzar la llave } de cierre).

Si el bloque-catch termina normalmente sin lanzar una nueva excepcin, el control se salta todos los bloques-catch que hubiese a continuacin y sigue despus del ltimo. Puede ocurrir que el bloque-catch lance a su vez una excepcin. Lo que nos conduce a excepciones anidadas. Esto puede ocurrir, por ejemplo, cuando en el proceso de limpieza de pila ("Stack unwinding") que tienen lugar tras una excepcin, un destructor lanza una excepcin .

Como se ver en los ejemplos, adems del manejo y control de errores, las excepciones C++ pueden utilizarse como un mecanismo de return o break multinivel, controlado no por una

circunstancia excepcional, sino como un acto deliberado del programador para controlar el flujo de ejecucin [5]. Ejemplos: ( 4.5.8).

7 Constructores y destructores en el manejo de excepciones


Cuando en el lanzamiento de excepciones se utilizan objetos por valor, throw llama al constructor copia ( 4.11.2d4). Este constructor inicializa un objeto temporal en el punto de lanzamiento.

Si ocurren errores durante la construccin de un objeto, los constructores pueden lanzar excepciones [3]. Si un constructor lanza una excepcin, el destructor del objeto no es llamado necesariamente. Cada vez que desde dentro de un bloque-try se lanza una excepcin y el control sale fuera de bloque, tiene lugar un proceso de bsqueda y desmontaje descendente en la pila hasta encontrar el manejador ("Catcher") correspondiente. Durante este proceso, denominado "Stack unwinding", todos los objetos de duracin automtica que se crearon hasta el momento de ocurrir la excepcin, son destruidos de forma controlada mediante llamadas a sus destructores. Si uno de los destructores invocados provoca a su vez una excepcin que no tiene un "handler" adecuado, se produce una llamada a la funcin terminate ( 1.6.3).

Nota: Observe que no se menciona para nada la destruccin de objetos persistentes que se hubiesen creado entre el inicio del bloque try y el punto de lanzamiento de la excepcin. Esto origina una difcil convivencia entre el mecanismo de excepciones y el operador new. Para resolver los problemas potenciales deben adoptarse precauciones especiales ( 4.9.20).

La invocacin a los destructores de los objetos automticos, se realiza solo para aquellos objetos que hubiesen sido construidos totalmente a partir de la entrada en el bloque-intento (objetos cuyos constructores hubiesen finalizado satisfactoriamente). Si los objetos tienen sub-objetos, la invocacin solo se realiza para los destructores de la clase-base. Tema relacionado: Control de recursos ( 4.1.5a)

Nota: En el caso del C++Builder, los destructores son llamados por defecto, pero puede evitarse mediante la opcin -xd- del compilador como se indica a continuacin. Esta opcin, como otras de este tipo, est gobernada por el valor de una constante global ( 1.4.1a).

8 Establecer opciones de manejo de excepciones


Los compiladores suelen disponer de comandos de compilacin ( 1.4.3) para determinar el tratamiento que seguir el manejo de excepciones. A ttulo de ejemplo se muestran algunos: Opcin Compilador Descripcin Borland C++ Deshabilitar el manejo de excepciones C++ (habilitado por defecto).

-x-

-xd

Nota: la eliminacin del mecanismo de excepciones en nuestro cdigo no impide que estas puedan ser utilizadas en aquellas funciones de librera que lo tienen habilitado y sean enlazadas con nuestro ejecutable. Por ejemplo, las rutinas de tiempo real de Borland. Borland C++ Habilita limpieza total. Llamada a los destructores para todos los objetos declarados automticos (locales) entre el mbito del capturador (catch) y el lanzador (throw) de la excepcin cuando es lanzada la excepcin (activo por defecto). Si se activa esta opcin, tambin hay que activar la opcin RT ( 4.9.14).

-xp

Borland C++ Habilita informacin sobre las excepciones. Posibilita identificacin de excepciones en tiempo de ejecucin mediante la inclusin en el objeto del nmero de lneas del cdigo fuente. Esto permite al programa interrogar el fichero y nmero de lnea donde ha ocurrido una excepcin utilizando los identificadores globales __ThrowFileName y __ThrowLineNumber. Deshabilitar el mecanismo de excepciones. Nota: los compiladores gcc deshabilitan esta opcin por defecto para aquellos lenguajes que normalmente no utilizan excepciones (C por ejemplo), pero lo habilitan por defecto para los que, como C++, suelen utilizarlo.

GNU c++ -fnoexceptions

Inicio. [1] Parte de las libreras de C++Builder, la denominadas VCL "Visual Component Library" ( 4.11.8b), han sido desarrolladas en Pascal, y no forman parte de su Librera Estndar C++. Son extensiones particulares de este compilador. [2] Una opcin muy bonita sera que llegado a este punto, el programa pudiera mandar un mensaje e-mail al programador o supervisor avisando del fallo (hoy da esto es trivial desde el punto de vista tcnico). [3] El mecanismo de excepciones fue introducido en C++ en 1989. De hecho, una de las razones de su inclusin fue la dificultad para detectar y controlar los errores ocurridos en los constructores, ya que por definicin estos mtodos no devuelven nada. [5] El Dr. Stroustrup admite que, adems de servir para el control de errores, las excepciones pueden servir como estructura de control en situaciones que no sean necesariamente errneas TC++PL 14.5 "Alternatively, one migth think of the exception-handling mechanisms as simply another control structure". Stroustrup & Ellis: ACRM 15.1 "This design assumes that exceptions are to be used primarily for error handling. Alternative uses, such as loop termination and alternate 'normal' return paths form functions, are clearly possible, but are considered secondary".

[6] Se recomienda utilizar una subclase (definida al efecto) de la superclase exception definida en la librera Estndar ( 1.6.1a).

1.7 Programacin actual


"However, pease remember that the aims are simplicity, regularity, and performance. You don't prove that you are clever by producing the most complicated code". Bjarne Stroustrup en "The State of the Language".

1 Introduccin
Loque podamos llamar "programacin tradicional", por ejemplo la que se utilizaba (utiliza?) en la confeccin de programas para los primitivos PCs bajo MS-DOS, o en los actuales Win-32 bajo una "ventana" DOS, es un concepto un tanto ambiguo, pero podemos intentar una definicin diciendo que se basa en algunas premisas y caractersticas bastante definidas. Estas caractersticas pueden coexistir juntas o faltar alguna, pero en general se dan simultneamente. En este captulo intentaremos mostrar una visin sinptica de las diferencias entre esta y la programacin "moderna" [1], a la que seguramente tendr que adaptarse el programador C++. Sin embargo, advertiremos desde ahora que la mentada "programacin tradicional" mezcla conceptos distintos e independientes, cuyas diferencias es importante tener claras antes de adentrarnos en la programacin actual. Por ejemplo, la programacin para Windows-32; asunto este que desde luego va ms all que la simple utilizacin de "objetos". Este captulo se ha redactado teniendo en mente la multitud de problemas con que se enfrenta el programador "tradicional" que se ve abocado a trabajar para un SO moderno (Windows inevitablemente?). Intentaremos dentro de lo posible clarificar algunas ideas de ese cmulo de nuevos conceptos que con demasiada frecuencia producen ms de una "indigestin" inicial [2].

2 Sinopsis
Para situarse correctamente en el asunto, es fundamental entender que las diferencias entre la programacin tradicional y la actual tienen su origen inmediato en la evolucin de los Sistemas Operativos, evolucin que ha sido posible a su vez por la evolucin del hardware. Por ejemplo, mquinas capaces de direccionar ms memoria. Tambin por la evolucin de las herramientas de programacin (lenguajes). Las caractersticas y diferencias de la programacin tradicional frente a la actual pueden resumirse en el siguiente cuadro:

Programacin tradicional
Representacin en modo texto Trabajo en mono-programa Trabajo en mono-tarea Ejecucin controlada por el programa Programacin de tipos fijos

Programacin actual
Representacin en modo grfico Trabajo en multi programacin Trabajo en multi-tarea

Ejecucin controlada por el Sistema Programacin orientada a objetos

3 Caractersticas de la "Programacin Tradicional" 3.1 Representacin en modo texto


Se trabaja en un entorno de texto (no grfico), el programa en ejecucin controla la informacin representada en la totalidad de la pantalla (no hay "ventanas"); el control de esta se realiza en trmino de filas y columnas (generalmente 24 x 80) y un surtido muy limitado de 256 caracteres (ASCII char set 2.2.1a). Los nicos atributos que pueden tener los caracteres suelen ser: Color de tinta y de papel (trazo y fondo); subrayado y parpadeo. Cuando se trabaja en entornos grficos, este tipo de aplicaciones no-grficas se denominan "de Consola". En la nomenclatura Windows a este tipo de aplicaciones se las conoce como CUI ("Console User Interface") en contraposicin con las de interfaz grfica GUI ("Graphical User Interface") que comentamos ms adelante ( 4.1) .

3.2 Trabajo en mono-programa


El SO. no admite multiprogramacin, es decir, solo corre una aplicacin cada vez. Cuando ejecutamos nuestro programa no tiene que compartir recursos con ningn otro (por ejemplo, nuestras rdenes de impresin pueden ser dirigidas directamente al "puerto" de impresora). Esto hace que en general podamos utilizar rutinas y llamadas de "bajo nivel" sin peligro alguno de interferir con nada. La totalidad de los recursos, tales como el procesador, la memoria, los puertos E/S etc. estn a nuestra disposicin exclusiva.

3.3 Trabajo en mono-tarea


El programa solo tiene una va, hilo o hebra ("Thread") de ejecucin, decimos que es mono-hebra. Coloquialmente podemos decir que solo hace una cosa cada vez.

3.4 Ejecucin controlada por el programa


Desde su concepcin, el programador decide que ocurre exactamente en cada momento de la ejecucin del programa, de forma que las vas de actuacin pueden ser previstas de antemano. Desde un punto de vista funcional, esto significa que, por ejemplo, se puede decidir en que momento se atender una llamada del teclado o en que momento atender la UART del puerto serie para atender la llegada o envo de datos. Desde el punto de vista del cdigo, el programa (suponemos que es C) se inicia en la funcin main y termina cuando esta termina. main puede llamar a otras funciones (que pueden llamar a su vez a otras funciones), pero siempre es el programa el que decide cual es la va de accin en cada caso; que funciones se invocan y cuando.

En el fondo, esta caracterstica es consecuencia de que el programa controla ms o menos directamente sus propios procesos de entrada/salida. Puede por ejemplo "leer" el teclado o "escribir" directamente en el puerto de impresora, por lo que las decisiones pueden tomarse "desde dentro" del programa.

3.5 Programacin "procedural"


Aqu utilizamos el trmino "procedural" [3] para indicar que generalmente no se utilizan lenguajes orientados a objetos (POO). Los lenguajes empleados adoptan una fuerte compartimentacin entre los tipos de datos disponibles y las operaciones posibles con ellos, que son fijas e incluidas en el propio lenguaje. No existen las clases como nuevos tipos que encapsulan el dato y sus operaciones ( 1.1), las entidades de mayor nivel de abstraccin que pueden utilizarse son las estructuras o uniones del C clsico y similares.

4 Caractersticas de la Programacin "Moderna"


Debemos recalcar de nuevo que se trata de conceptos generales e independientes. Por ejemplo, un programa "moderno" puede ser multiprogramacin pero en modo texto, o no orientado a objetos; sin embargo, la mayora de las caracterstica se dan juntas. En especial si se trata de programas que utilizan la interfaz grfica de los SOs ms conocidos.

4.1 Representacin en modo grfico


El usuario dispone de una interfaz grfica GUI ("Graphical User Interface") para trabajar en la aplicacin. Este tipo de programas controlan la informacin representada en su "canvas" [7], un trozo (ventana) de la pantalla cuyo tamao puede controlar el usuario la mayora de las veces. La representacin se realiza en pixels [8], y se dispone de un amplsimo surtido de herramientas y parmetros de representacin; no solo un amplio juego caracteres ("Fonts") con todos sus atributos, tambin un pincel ("Brush"), una pluma ("Pen"), as como iconos e imgenes preconstruidas de todo tipo. La posibilidad de multiprograma reseada a continuacin , junto con las nuevas posibilidades grficas, hacen que la pantalla pueda contener mltiples "ventanas", representativas de otros tantos procesos en ejecucin. El resultado es lo que se ha dado en llamar "Metfora de un escritorio" ("Desktop metaphor"). A su vez la pantalla se convierte en otro dispositivo de entrada (no solo el teclado); puede arrastrarse, cortarse y copiarse informacin de un punto a otro. Incluso entre aplicaciones diferentes. Ni que decir tiene que la programacin de un entorno grfico es muchsimo ms compleja que para un entorno de texto, aunque afortunadamente los entornos de desarrollo actuales ofrecen multitud de soluciones preconstruidas (clases) y libreras que facilitan la labor, de forma que si un programador quiere insertar, por ejemplo, un botn en un formulario, no tiene que preocuparse en "dibujar" el botn y su posible etiqueta. Simplemente indicar su tamao; el texto o dibujo de su etiqueta; su posicin en el "canvas", y las acciones a tomar cuando en dicho objeto se produzcan determinados "eventos": que pase por encima el cursor; que reciba foco; que se haga clic sobre l, etc.).

Desde el punto de vista de la interfaz que percibe el usuario, existen dos tipos de aplicaciones: SDI y MDI. SDI significa "Single Document interface". Son aplicaciones que se desarrollan en una sola ventana. Por su parte, MDI ("Multiple Document Interface") supone que la interfaz de la aplicacin es una ventana maestra ("Frame window"), que puede contener mltiples ventanas hijas o "documentos" abiertos simultneamente. Estas ventanas descendientes coinciden con la ventana madre cuando son maximizadas, y se cierran cuando se termina el proceso principal (que abri la ventana maestra).

4.2 Trabajo en multi-programa


El SO admite multiprogramacin ("multiprogramming") es decir, se ejecutan mltiples aplicaciones a la vez. De hecho, incluso en un sencillo ordenador personal, el propio Sistema puede mantener en ejecucin simultanea seis u ocho aplicaciones para s mismo, adems de los programas de aplicacin del usuario. Esta operacin se ejecuta de forma preemptiva. Lo que significa que el SO tiene un control continuo sobre el procesador y los diversos programas en ejecucin. Por ejemplo, el SO puede abortar, suspender o asignar tiempos de ejecucin a cualquiera de ellos. Nota: La ejecucin no preemptiva se denomina cooperativa, y es propia de sistemas multiprograma antiguos. El control es copado por el programa en ejecucin, que debe terminar por s mismo para que pueda ejecutarse otra aplicacin. En estas condiciones, si una aplicacin no termina por s misma puede bloquear el Sistema, razn por la que se necesita la "cooperacin" de la aplicacin para que el Sistema funcione correctamente [9].

El usuario puede estar ejecutando diversos programas simultneamente, siendo muy fcil saltar de uno a otro. Por ejemplo, puede estar escribiendo un documento con un procesador de texto y simultneamente, estar consultando ciertos datos que necesita en el Navegador de Internet o en una hoja de clculo. Incluso puede estar ejecutando al mismo tiempo diversas activaciones de un mismo programa. En estas condiciones, cuando ejecutamos nuestro programa, debe compartir recursos con todas las dems aplicaciones en ejecucin. Por ejemplo, nuestras rdenes de impresin no estn ya directamente dirigidas al "puerto" de impresora; en cambio se "lanza" una tarea a un programa (monitor de tareas) que recibe la peticin y la encola en un proceso batch que es el que en realidad gobierna la impresin. Esto hace que en general no sea ya posible utilizar rutinas y operaciones E/S de "bajo nivel", pues estos asuntos son controlados directamente por el Sistema Operativo, todo lo ms que se puede hacer es realizar "peticiones" al sistema de determinados servicios siguiendo las convenciones (a veces muy complejas) establecidas en cada caso. Tenga en cuenta que por ejemplo, en un programa Windows, los datos de la propia ventana en la que corre el programa estn en una zona de memoria gobernada por el Sistema, y que esta informacin queda oculta al programa, que debe limitarse a manejar los mensajes que le llegan desde aquel. Nota: En el captulo dedicado al SO Windows ( 0.7) puede verse un punto de vista complementario, como maneja este Sistema las aplicaciones que corren en l.

La totalidad de los recursos, tales como el procesador, la memoria, los puertos E/S etc. no estn ya a nuestra disposicin. Es el SO el que los controla, procurando que nuestro programa no haga algo equivocado que pueda daar el resto de las aplicaciones. Cuando por error un programa intenta salir del mbito que se le ha asignado (por ejemplo escribiendo en una zona de memoria equivocada), es el SO el que nos alerta. Puede tratarse del clsico mensajito: Este programa ha realizado una operacin no vlida y ser interrumpido. Si el problema persiste consulte con el proveedor del programa (Horror, si soy yo mismo...). Como puede suponerse, las implicaciones para el programador que trabaja sobre uno de estos entornos son enormes, puesto que adems del conocimiento de un lenguaje de programacin adecuado (C++ por ejemplo), se exige el conocimiento de la interfaz; lo que se denomina la API (Application Programmer Interface) del sistema ( 1.7.1). El resultado de que sea el propio SO el que controla las E/S del programa, es que el funcionamiento de este es en realidad un dilogo continuo con el Sistema, del que recibe determinada informacin (entradas), y del que solicita determinados servicios (salidas).

4.3 Trabajo en multi-tarea:


El programa puede tener ms de una va, hilo o hebra (thread) de ejecucin secuencial; es multihebra ("multithread"). Coloquialmente decimos que puede hacer varias cosas al mismo tiempo. Esto significa que el programa puede recorrer diversas vas de ejecucin simultanea (a cada una de estas vas o caminos de ejecucin lo denominamos una "tarea"). El programador debe controlar dos o ms vas de ejecucin paralela que pueden estar o no sincronizadas entre si ( 1.7.2).

En rigor solo los equipos multiprocesador son capaces de realizar una autntica multitarea; los dotados de un solo procesador son capaces de realizar una suerte de simulacin de tiempo compartido, siempre que el SO y el lenguaje utilizado estn habilitados para ello, aunque desde el punto de vista de la lgica de la aplicacin este detalle sea inapreciable. Aunque el hardware sea adecuado, no todos los Sistemas Operativos son capaces de soportar este tipo de ejecucin. Por ejemplo, Windows 95 solo simula la multitarea, incluso si el hardware es adecuado. Ver algunos comentarios a estos conceptos: Multiprograma & multitarea ( 1.7b).

4.4 Control de ejecucin orientado a "Eventos"


Aparte de los otros tpicos que se mencionan en este captulo, la forma en que se controla la ejecucin de un programa para un entorno "moderno" (tipo Windows-32) es bastante distinta de la utilizada en los entornos "clsicos". Este cambio es el que suele provocar mayor desconcierto inicial, y sobre el que quizs encuentre menos informacin (existen muchos libros sobre Programacin Orientada a Objetos y comparativamente pocos sobre Programacin Orientada a Eventos). Es en mi opinin, la adaptacin mental ms trabajosa. El programador clsico se ve obligado a "cambiar el chip" por otro radicalmente distinto. En contra de lo que ocurre en la programacin "tradicional", en la que es el propio programa el que decide que se hace y cuando, en la programacin orientada a eventos la ejecucin est controlada

por el SO. El programa se parece a un bucle que espera continuamente la recepcin de mensajes del Sistema y responde en consecuencia ejecutando determinados procesos. Los procesos pueden incluir peticiones de nueva informacin, o solicitud de determinados servicios. Los mensajes del Sistema tienen su origen en eventos (sucesos) de etiologa muy distinta. Por ejemplo, una interrupcin del teclado; del ratn, que puede hacer clic o doble clic en cualquier rea de la ventana de la aplicacin, o simplemente pasar sobre una zona determinada. Incluso la terminacin del programa ocurre cuando se recibe una peticin del sistema en este sentido (porque se ha hecho clic en el botn de cerrar la aplicacin, o por cualquiera de los otros procedimientos tpicos en las aplicaciones grficas). Ver algunas matizaciones a estos conceptos en "Controlar un programa" ( 1.7a).

4.5 Programacin Orientada a Objetos


Los lenguajes empleados utilizan los recursos de esta tcnica de programacin ( 1.1). Las principales ventajas, aparte de un mejor encapsulamiento de los datos y sus operaciones, son la herencia; la sobrecarga, y el polimorfismo. Virtualmente no existe lmite a la complejidad de los "nuevos" tipos de datos que pueda crear el programador, ni de sus operaciones. Aparte de las ventajas genricas antes enunciadas, la POO est especialmente indicada para la programacin en los nuevos entornos operativos, porque los nuevos paradigmas de programacin para entornos distribuidos (Redes) conciben las aplicaciones, y sus relaciones con el mundo exterior, como un mundo de objetos que dialogan y transaccionan ( 1.7.1). Un mundo del que solo es necesario conocer las reglas de dilogo y transaccin, y este es justamente uno de los paradigmas de la POO. Inicio. [1] La verdad es que el trmino "moderno" me produce un cierto rubor. Al paso que van la ciencia y tecnologa informticas, lo "moderno" de hoy seguramente nos producir una sonrisa de conmiseracin dentro de muy pocos aos. [2] Se trata solo de una "pincelada" sobre el tema, dado que para programar en un entorno actual como Windows-32, no solo es necesario conocer un lenguaje dotado de un compilador para 32 bits (a ser posible orientado a objetos, como C++), tambin un montn de otros conceptos que desgraciadamente no estn en un solo libro. El resultado es que el programador proveniente de un entorno "tradicional" (modo texto naturalmente), se enfrenta a algo que no se parece a nada que haya visto anteriormente. [3] Aunque se utiliza con frecuencia el trmino "procedural" para referirse a la programacin clsica (no orientada a objetos) y no encontramos una descripcin mejor, ni nos gusta ni nos parece acertada la palabra. Preferiramos decir Programacin orientada a tipos (de datos) predefinidos y operaciones fijas (Fixed Type Oriented Programming FTOP?). [6] Evidentemente la MFC no es la nica librera para programar en Windows; solo tiene la ventaja de ser del mismo fabricante (que no es poco) y de que es constantemente actualizada para recoger

las implementaciones introducidas en estos SOs. Actualmente comprende unas 200 clases que encapsulan la prctica totalidad de la API de Windows; adems va ms all de ser una simple coleccin de clases preconstruidas. Constituye en s misma un completo entorno de desarrollo. [7] "Canvas": Espacio grfico que representa un objeto en pantalla. Es una abstraccin utilizada en la programacin de aplicaciones de interfaz grfica (como Windows) que encapsula el contenido del dispositivo grfico. [8] El dibujo ms pequeo que puede representarse en pantalla: un punto. Puede ser monocromo (un color o ausencia de l); de escala de grises, desde el blanco a negro pasando por diversos tonos de gris, o en color. En este ltimo caso el pixel est realmente constituido de tres puntos, cada uno de un color bsico (rojo verde y azul). [9] En los entornos Windows de 16 bits (W-95) quedan vestigios de este funcionamiento cooperativo; son los momentos en que el cursor se transforma en un reloj de arena y no podemos hacer nada hasta que termina cierto proceso. En los entornos Windows de 32 bits, en los que el funcionamiento es preemptivo, sigue saliendo el reloj de arena cuando un proceso est ocupado, pero puede darse foco a otra aplicacin con un clic de ratn.

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 los algoritmos 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 denomina mecanismos de datos ( 2). Generalmente se considera que estos mecanismos realizan tres tipos de operaciones: Insercin, borrado y bsqueda 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 programador-humano 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 de campos. 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.

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". Denominndose constantes ( "valor" pueda ser modificado o no a lo largo del programa. 3.2.3) y variables, segn que su

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
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 el encapsulamiento 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, en C++ 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 ( Inicio.

4.1.2)

[1] El en un sentido estricto, el "programa" solo contiene instrucciones; aunque desde luego pueden existir mltiples puntos de vista. Por ejemplo, para Stroustrup y Ellis un programa es mramente uno o ms ficheros enlazados juntos, y un fichero consiste en una secuencia de declaraciones" ( [2] Formalmente denominado Rvalue ( 2.1) 1.3.1)

[3] Al Stevens: "Entrevista a Alexander Stepanov" Dr. Dobbs's Journal. Marzo 1995.

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 ( datos). 2.2 Tipos de

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 4.9.14), el tamao en bytes de cualquier tipo estndar o definido por el usuario, y typeid ( 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 ( Especificadores de clase de almacenamiento).

4.1.8

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 contenido legalmente 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 expresin a+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 cuyo nemnico 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 denominados punteros ( 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 4.9.3). operador de referencia, tambin puede ser el operador AND en operaciones de bits (

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 Inicio. [1] C++, al igual que muchos de los actuales lenguajes de programacin "orientados a objetos", obedecen a un diseo centrado principalmente en el "dato", aunque tambin existen lenguajes en los que se pone mayor nfasis en el algoritmo. [2] Utilizamos el smbolo para indicar una asignacin de derecha a izquierda (en C++ el smbolo del operador de asignacin simple es = 4.9.2); utilizaremos == como indicador de igualdad (este si es el smbolo C++ del operador relacional "igual que" 4.9.12). Finalmente utilizaremos el smbolo para sealar que lo que sigue se deduce o es "consecuencia de" lo anterior (smbolo de inferencia). 4.9 Operadores.

[3] El identificador no es solo privativo de los datos, tambin las instrucciones pueden tener un identificador. Por ejemplo, las funciones y los operadores. En el caso de las funciones el identificador se dice que es el "nombre" de la funcin; en el caso de los operadores, el identificador se dice que es el "smbolo" del operador. [4] El tipo de dato en los lenguajes de programacin se corresponde con el concepto matemtico de "dominio". Ms concretamente, en la teora de conjuntos.

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 y dbilmente 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 4.4.6) funciones para ajustar el tipo de los parmetros actuales con los formales (

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), es S. Inicio. [1] C++ es un lenguaje de propsito general que no ha sido especialmente diseado para la computacin numrica, por lo que de forma nativa no dispone de tipos de datos de alto nivel, ni por consiguiente, de sus operaciones. Sin embargo, su velocidad de ejecucin lo hace muy dotado para todo tipo de aplicaciones de clculo, adems dispone de recursos muy potentes al respecto en su Librera Estndar ( 5).

[2] El tratamiento que hacen de los "Tipos" los diferentes lenguajes si es muy variado. Frente a los fuertemente tipados, como C/C++, existen otros prcticamente sin tipo definido ("Tipeless"), mientras que otro grupo presenta una posicin intermedia con una tipologa muy simple y permisiva ("Loosely typed"). Un caso extremo est representado por BCPL ( 0.Iw2), uno de los ancestros de C, y una posicin intermedia estara representada por JavaScript, que cuenta solo con cinco tipos distintos y una gran capacidad de adaptacin automtica entre ellos. En este punto cabe hacer otra observacin; en atencin a su capacidad de adaptacin, ms que lenguajes sin tipo ("Tipeless"), algunos autores prefieren decir que se trata de lenguajes con tipos dinmicos o tolerantes ("Dynamic types" o "Tolerant types"). [3] Ms detalles respecto a estos constructores para los tipos bsicos en el captulo dedicado al operador new ( 4.9.20).

[4] Para comprender cabalmente el ejemplo debe consultarse el epgrafe Punteros en jerarquas de clases ( 4.11.2b1).

[5] Utilizaremos indistintamente nombre-de-tipo o su acrnimo ingls type-id.

Das könnte Ihnen auch gefallen