curso de programación en c++ apuntes de clase

Click here to load reader

Post on 30-Dec-2016

227 views

Category:

Documents

2 download

Embed Size (px)

TRANSCRIPT

  • Curso de programacin en C++EUI (UPV)

    Valencia, 17 al 28 de Julio de 1995

    Apuntes de clase

    Sergio Talens Oliag

  • iii

    Contenidos

    BASES TERICAS. INTRODUCCIN A LA POO.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

    INTRODUCCIN...............................................................................................................................1PARADIGMAS DE PROGRAMACIN.....................................................................................................1PROGRAMACIN IMPERATIVA ..........................................................................................................2

    Tipos de datos .............................................................................................................................2Operadores y expresiones...............................................................................................................3Algoritmos y estructuras de control .................................................................................................4Funciones y procedimientos...........................................................................................................4Constantes y variables ..................................................................................................................5

    PROGRAMACIN MODULAR .............................................................................................................6TIPOS ABSTRACTOS DE DATOS..........................................................................................................6PROGRAMACIN ORIENTADA A OBJETOS ...........................................................................................7

    Objetos y mensajes ......................................................................................................................7Clases........................................................................................................................................7Herencia y polimorfismo...............................................................................................................7Programacin con objetos..............................................................................................................7

    EL LENGUAJE C++. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

    INTRODUCCIN...............................................................................................................................9CONCEPTOS BSICOS......................................................................................................................9

    Estructura de los programas............................................................................................................9Tipos de datos y operadores .......................................................................................................... 10Estructuras de control.................................................................................................................. 11Funciones................................................................................................................................. 12Soporte a la programacin modular................................................................................................ 12Soporte a los Tipos de Datos Abstractos......................................................................................... 13Soporte a la programacin Orientada a Objetos ................................................................................ 13

    TIPOS DE DATOS, OPERADORES Y EXPRESIONES................................................................................. 13Tipos de datos ........................................................................................................................... 13Tipos elementales ...................................................................................................................... 13Tipos enumerados ...................................................................................................................... 14Tipos derivados.......................................................................................................................... 15Tipos compuestos ...................................................................................................................... 16Constantes (literales) .................................................................................................................. 18Variables.................................................................................................................................. 19Conversiones de tipos................................................................................................................. 20Operadores y expresiones............................................................................................................. 21

    ESTRUCTURAS DE CONTROL ........................................................................................................... 24Estructuras de seleccin............................................................................................................... 24Estructuras de repeticin.............................................................................................................. 26Estructuras de salto..................................................................................................................... 27

    FUNCIONES.................................................................................................................................. 28Declaracin de funciones.............................................................................................................. 28Definicin de funciones............................................................................................................... 28Paso de parmetros..................................................................................................................... 29Parmetros array ........................................................................................................................ 29Retorno de valores...................................................................................................................... 30Sobrecarga de funciones............................................................................................................... 30Parmetros por defecto ................................................................................................................ 30Parmetros indefinidos ................................................................................................................ 31Recursividad.............................................................................................................................. 32Punteros a funciones................................................................................................................... 33La funcin main() ...................................................................................................................... 33

    VARIABLES DINMICAS................................................................................................................. 34Punteros y direcciones................................................................................................................. 34El puntero NULL....................................................................................................................... 35Punteros void............................................................................................................................ 35Aritmtica con punteros .............................................................................................................. 36Punteros y parmetros de funciones ............................................................................................... 37

  • iv

    Punteros y arrays........................................................................................................................37Operadores new y delete ...............................................................................................................38Punteros y estructuras .................................................................................................................39Punteros a punteros ....................................................................................................................39

    PROGRAMACIN EFICIENTE............................................................................................................40Estructura de los programas..........................................................................................................40El preprocesador.........................................................................................................................42Funciones inline ........................................................................................................................43Inclusin de rutinas en ensamblador ...............................................................................................43Eficiencia y claridad de los programas.............................................................................................44

    CLASES........................................................................................................................................44Introduccin ..............................................................................................................................44Clases y miembros .....................................................................................................................45Mtodos estticos y funciones amigas ............................................................................................50Construccin y destruccin...........................................................................................................51

    HERENCIA Y POLIMORFISMO...........................................................................................................56Clases derivadas o subclases .........................................................................................................56Clases abstractas ........................................................................................................................60Herencia mltiple.......................................................................................................................61Control de acceso .......................................................................................................................63Gestin de memoria....................................................................................................................64

    SOBRECARGA DE OPERADORES .......................................................................................................64Funciones operador.....................................................................................................................64Conversiones de tipos .................................................................................................................66Operadores y objetos grandes ........................................................................................................67Asignacin e inicializacin...........................................................................................................67Subndices ................................................................................................................................68Llamadas a funcin.....................................................................................................................68Dereferencia...............................................................................................................................69Incremento y decremento..............................................................................................................69Sobrecarga de new y delete ...........................................................................................................69Funciones amigas o mtodos........................................................................................................70

    TEMPLATES..................................................................................................................................70Genericidad................................................................................................................................70Funciones genricas....................................................................................................................71Clases genricas.........................................................................................................................72

    MANEJO DE EXCEPCIONES..............................................................................................................73Programacin y errores................................................................................................................73Tratamiento de excepciones en C++ (throw - catch - try)....................................................................73

    ENTRADA Y SALIDA.......................................................................................................................76Introduccin ..............................................................................................................................76Objetos Stream..........................................................................................................................76Entrada y salida..........................................................................................................................76Ficheros ...................................................................................................................................79

    PROGRAMACIN EN C++................................................................................................................80El proceso de desarrollo ...............................................................................................................80Mantenibilidad y documentacin....................................................................................................80Diseo e implementacin.............................................................................................................81Eleccin de clases.......................................................................................................................81Interfaces e implementacin..........................................................................................................81

    LIBRERAS DE CLASES....................................................................................................................81Diseo de libreras......................................................................................................................82Clases Contenedor......................................................................................................................82Clases para aplicaciones...............................................................................................................83Clases de Interface ......................................................................................................................83Eficiencia temporal y gestin de memoria .......................................................................................83Estandarizacin ..........................................................................................................................84

    RELACIN C/C++..........................................................................................................................84No se puede usar en ANSI C ........................................................................................................84Diferencias entre C y C++ ...........................................................................................................85

  • 5

    Bibliografa bsica Brian W. Kernighan, Dennis M. Ritchie, The C Programming Language, Second Edition,Prentice Hall, 1988

    Bjarne Stroustrup, The C++ Programming Language, Second Edition, Addison-Wesley,1991

    Enrique Hernndez Orallo, Jos Hernndez Orallo, Programacin en C++, Paraninfo, 1993

  • 1

    Bases tericas. Introduccin a la POO.

    INTRODUCCINPara comenzar a estudiar cualquier lenguaje de programacin se debe conocer cuales son losconceptos que soporta, es decir, el tipo de programacin que vamos a poder realizar con l.Como el C++ incorpora caractersticas nuevas respecto a lenguajes como Pascal o C, en primerlugar daremos una descripcin a los conceptos a los que este lenguaje da soporte, repasando losparadigmas de programacin y centrndonos en la evolucin desde la programacin Funcional ala programacin Orientada a Objetos. Ms adelante estudiaremos el lenguaje de la mismamanera, primero veremos sus caractersticas funcionales (realmente la parte que el lenguajehereda de C) y despus estudiaremos las extensiones que dan soporte a la programacinorientada a objetos (el ++ de C++).

    PARADIGMAS DE PROGRAMACINSegn los conceptos en que se basa un lenguaje de programacin tenemos distintas maneras deaproximarnos a la resolucin de los problemas y diferentes estilos de programacin. Podemosclasificar los lenguajes de programacin en varios tipos:

    Imperativos

    Orientados a Objetos

    Funcionales

    Lgicos

    Las dos primeras opciones se basan en la abstraccin de los tipos de datos. Bsicamente se tratade representar las caractersticas variables de los objetos mediante tipos que el ordenador puedatratar, como por ejemplo nmeros enteros o caracteres alfanumricos. Nuestro programa seruna coleccin de algoritmos que opere sobre los datos que hemos modelado. La diferencia entrelas dos aproximaciones se ver en puntos posteriores.

    Los lenguajes funcionales, al contrario que los imperativos, eliminan totalmente la idea de tipode datos, se limitan a tratar todos los datos como smbolos y hacen hincapi en las operacionesque podemos aplicar sobre estos smbolos, agrupados en listas o rboles. Es importante indicarque en estos lenguajes se emplea nicamente el concepto de funcin aplicado a smbolos, siendouna de sus caractersticas principales el empleo de las funciones recursivas. Como ejemplo deeste tipo de lenguajes podramos citar el LISP.

  • 2

    Los lenguajes lgicos son los que trabajan directamente con la lgica formal, se trata derepresentar relaciones entre conjuntos, para luego poder determinar si se verifican determinadospredicados. El lenguaje lgico ms extendido es el Prolog.

    PROGRAMACIN IMPERATIVAComo ya hemos mencionado anteriormente, la programacin imperativa trata con tipos de datosy algoritmos, los primeros representan la informacin utilizada por los programas, mientras quelos segundos se refieren a la manera en que tratamos esa informacin.

    En los puntos que siguen revisaremos de forma breve los conceptos fundamentales de laprogramacin imperativa clsica, tambin llamada programacin procedural. La idea bsica deesta aproximacin es la de definir los algoritmos o procedimientos ms eficaces para tratar losdatos de nuestro problema.

    Tipos de datos

    Cuando nos planteamos la resolucin de problemas mediante computador lo ms usual es quequeramos tratar con datos que son variables y cuantificables, es decir, que toman un conjuntode valores distintos entre un conjunto de valores posibles, adems de poder almacenar losvalores de estos datos en alguna forma aceptable para el computador (ya sea en la memoria o enperifricos de almacenamiento externo).

    En un lenguaje de programacin el concepto de tipo de datos se refiere al conjunto de valoresque puede tomar una variable. Esta idea es similar a la que se emplea en matemticas, dondeclasificamos las variables en funcin de determinadas caractersticas, distinguiendo entrenmeros enteros, reales o complejos. Sin embargo, en matemticas, nosotros somos capaces dediferenciar el tipo de las variables en funcin del contexto, pero para los compiladores estoresulta mucho ms difcil. Por este motivo debemos declarar explcitamente cada variable comoperteneciente a un tipo. Este mecanismo es til para que el computador almacene la variable dela forma ms adecuada, adems de permitir verificar que tipo de operaciones se pueden realizarcon ella.

    Se suelen diferenciar los tipos de datos en varias categoras:

    Tipos elementales, que son aquellos cuyos valores son atmicos y, por tanto, nopueden ser descompuestos en valores ms simples. Entre las variables de estos tipossiempre encontramos definidas una serie de operaciones bsicas: asignacin de un valor,copia de valores entre variables y operaciones relacionales de igualdad o de orden (por lotanto, un tipo debe ser un conjunto ordenado).

    Los tipos ms caractersticos son:

    booleanos = {verdadero, falso}

    enteros = { -2, -1, 0, +1, +2, }

    reales = { -1.0, , 0.0, , +1.0, }

    caracteres = { 'a', 'b', , 'Z', }

    Generalmente existen mecanismos para que el usuario defina nuevos tipos elementales porenumeracin, es decir, definiendo el conjunto de valores explcitamente. Por ejemplopodramos definir el tipo da como {lunes, martes, mircoles, jueves, viernes, sbado,domingo}, las variables definidas como da slo podran tomar estos valores.

    Por ltimo mencionaremos otro tipo de datos elemental de caractersticas especiales, elpuntero, que es el tipo que almacena las direcciones de las variables (la direccin dememoria en la que se almacena su valor). Analizaremos este tipo ms adelante.

  • 3

    Tipos compuestos o estructurados, que son los tipos formados a partir de loselementales. Existen varias formas de agrupar los datos de tipos elementales:

    La ms simple es la estructura indexada, muy similar a los vectores o matrices dematemticas, en donde lo que hacemos es relacionar unos ndices (pertenecientes a un tipode datos) con los valores de un tipo determinado. Sobre estas estructuras se puedenrealizar las operaciones de consulta o asignacin de un valor (a travs de su ndice).

    Otra estructura compuesta muy importante es el registro, que no es ms que una sucesinde elementos de distintos tipos, denominados campos, que llevan asociados unidentificador. Sobre estos tipos se definen las operaciones de asignacin y de acceso a uncampo. Algunos lenguajes tambin soportan la operacin de asignacin para toda laestructura (la copia de todos los campos en un solo paso).

    El tipo cadena de caracteres es un caso especial de tipo de datos, ya que algunos lenguajeslo incorporan como tipo elemental (con un tamao fijo), mientras que en otros lenguajesse define como un vector de caracteres (de longitud fija o variable) que es una estructuraindexada. Como se ve, los campos de un registro pueden ser de otros tipos compuestos,no slo de tipos elementales.

    Tipos recursivos, que son un caso especial de tipos compuestos, introduciendo laposibilidad de definir un tipo en funcin de s mismo.

    Para terminar nuestro anlisis de los tipos de datos, hablaremos de la forma en que los lenguajesde programacin relacionan las variables con sus tipos y las equivalencias entre distintos tipos.

    Hemos dicho que el empleo de tipos de datos nos sirve para que el computador almacene losdatos de la forma ms adecuada y para poder verificar las operaciones que hacemos con ellos.Sera absurdo que intentramos multiplicar un carcter por un real pero, si el compilador nocomprueba los tipos de los operandos de la multiplicacin, esto sera posible e incluso nosdevolvera un valor, ya que un carcter se representa en binario como un nmero entre 0 y 255.Para evitar que sucedan estas cosas los compiladores incorporan mecanismos de chequeo detipos, verificando antes de cada operacin que sus operandos son de los tipos esperados. Elchequeo se puede hacer esttica o dinmicamente. El chequeo esttico se realiza en tiempo decompilacin, es decir, antes de que el programa sea ejecutable. Para realizar este chequeo esnecesario que las variables y los parmetros tengan tipos fijos, elegidos por el programador. Elchequeo dinmico se realiza durante la ejecucin del programa, lo que permite que las variablespuedan ser de distintos tipos en tiempo de ejecucin.

    Por ltimo sealaremos que existe la posibilidad de que queramos realizar una operacindefinida sobre un tipo de datos, por ejemplo reales, aplicada a una variable de otro tipo, porejemplo entera. Para que podamos realizar esta operacin debe de existir algn mecanismo paracompatibilizar los tipos, convirtiendo un operando que no es del tipo esperado en ste, porejemplo transformando un entero en real, aadiendo una parte decimal nula, o transformando unreal en entero por redondeo.

    Operadores y expresiones

    Como ya hemos dicho con los datos de un tipo podemos realizar determinadas operacionespero, cmo las expresamos en un lenguaje de programacin? Para resolver este problemaaparecen lo que llamamos operadores. Podemos decir que un operador es un smbolo oconjunto de smbolos que representa la aplicacin de una funcin sobre unos operandos.Cuando hablamos de los operandos no slo nos referimos a variables, sino que hablamos decualquier elemento susceptible de ser evaluado en alguna forma. Por ejemplo, si definimos unavariable entera podremos aplicarle operadores aritmticos (+, -, *, /), de asignacin (=) orelacionales (>,

  • 4

    Los operadores estn directamente relacionados con los tipos de datos, puesto que se definen enfuncin del tipo de operandos que aceptan y el tipo del valor que devuelven. En algunos casoses fcil olvidar esto, ya que llamamos igual a operadores que realizan operaciones distintas enfuncin de los valores a los que se apliquen, por ejemplo, la divisin de enteros no es igual quela de reales, ya que la primera retorna un valor entero y se olvida del resto, mientras que la otradevuelve un real, que tiene decimales.

    Un programa completo est compuesto por una serie de sentencias, que pueden ser de distintostipos:

    declarativas, que son las que empleamos para definir los tipos de datos, declarar lasvariables o las funciones, etc., es decir, son aquellas que se emplean para definir de formaexplcita los elementos que intervienen en nuestro programa,

    ejecutables, que son aquellas que se transforman en cdigo ejecutable, y

    compuestas, que son aquellas formadas de la unin de sentencias de los tiposanteriores.

    Llamaremos expresin a cualquier sentencia del programa que puede ser evaluada y devuelve unvalor. Las expresiones ms simples son los literales, que expresan un valor fijo explcitamente,como por ejemplo un nmero o una cadena de caracteres. Las expresiones compuestas sonaquellas formadas por una secuencia de trminos separados por operadores, donde los trminospueden ser literales, variables o llamadas a funciones (ya que devuelven un resultado).

    Algoritmos y estructuras de control

    Podemos definir un algoritmo de manera general como un conjunto de operaciones o reglas biendefinidas que, aplicadas a un problema, lo resuelven en un nmero finito de pasos. Si nosreferimos slo a la informtica podemos dar la siguiente definicin:

    Un procedimiento es una secuencia de instrucciones que pueden realizarsemecnicamente. Un procedimiento que siempre termina se llama algoritmo.

    Al disear algoritmos que resuelvan problemas complejos debemos emplear algn mtodo dediseo, la aproximacin ms sencilla es la del diseo descendente (top-down). El mtodoconsiste en ir descomponiendo un problema en otros ms sencillos (subproblemas) hasta llegara una secuencia de instrucciones que se pueda expresar en un lenguaje de alto nivel. Lo queharemos ser definir una serie de acciones complejas y dividiremos cada una en otras mssimples. Para controlar el orden en que se van desarrollando las acciones, utilizaremos lasestructuras de control, que pueden ser de distintos tipos:

    condicionales o de seleccin, que nos permiten elegir entre varias posibilidades enfuncin de una o varias condiciones,

    de repeticin (bucles), que nos permiten repetir una serie de operaciones hasta que severifique una condicin o hayamos dado un nmero concreto de vueltas, y

    de salto, que nos permiten ir a una determinada lnea de nuestro algoritmodirectamente.

    Funciones y procedimientos

    En el punto anterior hemos definido los algoritmos como procedimientos que siempre terminan,y procedimiento como una secuencia de instrucciones que pueden realizarse mecnicamente,aqu consideraremos que un procedimiento es un algoritmo que recibe unos parmetros deentrada, y una funcin un procedimiento que, adems de recibir unos parmetros, devuelve unvalor de un tipo concreto. En lo que sigue emplear los trminos procedimiento y funcinindistintamente.

  • 5

    Lo ms importante de estas abstracciones es saber como se pasan los parmetros, ya que segnel mecanismo que se emplee se podr o no modificar sus valores. Si los parmetros se pasanpor valor, el procedimiento recibe una copia del valor que tiene la variable parmetro y por lotanto no puede modificarla, sin embargo, si el parmetro se pasa por referencia, elprocedimiento recibe una referencia a la variable que se le pasa como parmetro, no el valor quecontiene, por lo que cualquier consulta o cambio que se haga al parmetro afectar directamentea la variable.

    Por qu surgieron los procedimientos y las funciones? Sabemos que un programa segn elparadigma clsico es una coleccin de algoritmos pero, si los escribiramos todos seguidos,nuestro programa sera ilegible. Los procedimientos son un mtodo para ordenar estosalgoritmos de alguna manera, separando las tareas que realiza un programa. El hecho de escribirlos algoritmos de manera independiente nos ayuda a aplicar el diseo descendente; podemosexpresar cada subproblema como un procedimiento distinto, viendo en el programa cual ha sidoel refinamiento realizado. Adems algunos procedimientos se podrn reutilizar en problemasdistintos.

    Por ltimo indicaremos que el concepto de procedimiento introduce un nivel de abstraccinimportante en la programacin ya que, si queremos utilizar un procedimiento ya implementadopara resolver un problema, slo necesitamos saber cules son sus parmetros y cul es elresultado que devuelve. De esta manera podemos mejorar o cambiar un procedimiento sinafectar a nuestro programa, siempre y cuando no cambie sus parmetros, haciendo mucho msfcil la verificacin de los programas, ya que cuando sabemos que un procedimiento funcionacorrectamente no nos debemos volver a preocupar por l.

    Constantes y variables

    En los puntos anteriores hemos tratado las variables como algo que tiene un tipo y puede serpasado como parmetro pero no hemos hablado de cmo o dnde se declaran, de cmo sealmacenan en memoria o de si son accesibles desde cualquier punto de nuestro programa.

    Podemos decir que un programa est compuesto por distintos bloques, uno de los cuales ser elprincipal y que contendr el procedimiento que ser llamado al comenzar la ejecucin delprograma. Sern bloques el interior de las funciones, el interior de las estructuras de control,etc.

    Diremos que el campo o mbito de un identificador es el bloque en el que ha sido definido. Si elbloque contiene otros bloques tambin en estos el identificador ser vlido. Cuando hablo deidentificador me refiero a su sentido ms amplio: variables, constantes, funciones, tipos, etc.Fuera del mbito de su definicin ningn identificador tiene validez.

    Clasificaremos las variables en funcin de su mbito de definicin en globales y locales. Dentrode un bloque una variable es local si ha sido definida en el interior del mismo, y es global si seha definido fuera de el bloque pero podemos acceder a ella.

    Como es lgico las variables ocupan memoria pero, como slo son necesarias en el interior delos bloques donde se definen, durante la ejecucin del programa sern creadas al entrar en sumbito y eliminadas al salir de l. As, habr variables que existirn durante todo el programa (sison globales para todos los bloques) y otras que slo existan en momentos muy concretos. Estemecanismo de creacin y destruccin de variables permite que los programas aprovechen almximo la memoria que les ha sido asignada.

    Todo lo dicho anteriormente es vlido para las variables declaradas estticamente, pero existeotro tipo de variables cuya existencia es controlada por el programador, las denominadasvariables dinmicas. Ya hablamos anteriormente de los punteros y dijimos entonces que eran lasvariables empleadas para apuntar a otras variables, pero a qu nos referimos con apuntar?Sabemos que las variables se almacenan en memoria, luego habr alguna direccin de memoriaen la que encontremos su valor (que puede ocupar uno o varios bytes). Los punteros no sonms que variables cuyo contenido es una direccin de memoria, que puede ser la de la posicindel valor de otra variable.

  • 6

    Cuando deseamos crear variables de tipo dinmico el lenguaje de programacin nos sueleproporcionar alguna funcin estndar para reclamarle al S.O. espacio de memoria paraalmacenar datos, pero como no hemos definido variables que denoten a ese espacio, tendremosque trabajar con punteros. Es importante sealar que el espacio reservado de esta forma seconsidera ocupado durante todo el tiempo que se ejecuta el programa, a menos que elprogramador lo libere explcitamente, pero los punteros que contienen la direccin de eseespacio si son variables estticas, luego dejan de existir al salir de un campo. Si salimos de uncampo y no hemos liberado la memoria dinmica, no podremos acceder a ella (a menos quealguno de los punteros fuera global al mbito abandonado), pero estaremos ocupando unespacio que no ser utilizable hasta que termine nuestro programa.

    Para terminar slo dir que existen variables constantes (que ocupan memoria). Son aquellasque tienen un tipo y un identificador asociado, lo que puede ser til para que se hagan chequeosde tipos o para que tengan una direccin de memoria por si algn procedimiento requiere unpuntero a la constante.

    PROGRAMACIN MODULARCon la programacin procedural se consigue dar una estructura a los programas, pero nodiferenciamos realmente entre los distintos aspectos del problema, ya que todos los algoritmosestn en un mismo bloque, haciendo que algunas variables y procedimientos sean accesiblesdesde cualquier punto de nuestro programa.

    Para introducir una organizacin en el tratamiento de los datos apareci el concepto de mdulo,que es un conjunto de procedimientos y datos interrelacionados. Aparece el denominadoprincipio de ocultacin de informacin, los datos contenidos en un mdulo no podrn sertratados directamente, ya que no sern accesibles desde el exterior del mismo, slopermitiremos que otro mdulo se comunique con el nuestro a travs de una serie deprocedimientos pblicos definidos por nosotros. Esto proporciona ventajas como podermodificar la forma de almacenar algunos de los datos sin que el resto del programa sea alteradoo poder compilar distintos mdulos de manera independiente. Adems, un mdulo biendefinido podr ser reutilizado y su depuracin ser ms sencilla al tratarlo de maneraindependiente.

    TIPOS ABSTRACTOS DE DATOSCon los mecanismos de definicin de tipos estructurados podamos crear tipos de datos mscomplejos que los primitivos, pero no podamos realizar ms que unas cuantas operacionessimples sobre ellos. Sin embargo, los procedimientos nos permiten generalizar el concepto deoperador. En lugar de limitarnos a las operaciones incorporadas a un lenguaje, podemos definirnuestros propios operadores y aplicarlos a operandos que no son de un tipo fundamental (porejemplo, podemos implementar una rutina que multiplique matrices y utilizarla como si fuera unoperador sobre variables del tipo matriz). Adems, la estructura modular vista en el apartadoanterior nos permite reunir en un solo bloque las estructuras que componen nuestro tipo y losprocedimientos que operan sobre l. Surgen los denominados Tipos Abstractos de Datos(TAD).

    Un TAD es una encapsulacin de un tipo abstracto de datos, que contiene la definicin del tipoy todas las operaciones que se pueden realizar con l (en teora, algn operando o el resultadode las operaciones debe pertenecer al tipo que estamos definiendo). Esto permite tener localizadatoda la informacin relativa a un tipo de datos, con lo que las modificaciones son mucho mssencillas, ya que desde el resto del programa tratamos nuestro TAD como un tipo elemental,accediendo a l slo a travs de los operadores que hemos definido.

    El problema de esta idea est en que los lenguajes que soportan mdulos pero no estnpreparados para trabajar con TAD slo permiten que definamos los procedimientos de formaindependiente, es decir, sin asociarlos al TAD ms que por la pertenencia al mdulo. Las

  • 7

    variables del tipo nicamente se podrn declarar como estructuras, por lo que losprocedimientos necesitarn que las incluyamos como parmetro. La solucin adoptada por losnuevos lenguajes es incorporar mecanismos de definicin de tipos de usuario que se comportancasi igual que los tipos del lenguaje.

    PROGRAMACIN ORIENTADA A OBJETOSLa diferencia fundamental entre la programacin pocedural y la orientada a objetos est en laforma de tratar los datos y las acciones. En la primera aproximacin ambos conceptos son cosasdistintas, se definen unas estructuras de datos y luego se define una serie de rutinas que operansobre ellas. Para cada estructura de datos se necesita un nuevo conjunto de rutinas. En laprogramacin orientada a objetos los datos y las acciones estn muy relacionadas. Cuandodefinimos los datos (objetos) tambin definimos sus acciones. En lugar de un conjunto derutinas que operan sobre unos datos tenemos objetos que interactuan entre s.

    Objetos y mensajes

    Un Objeto es una entidad que contiene informacin y un conjunto de acciones que operan sobrelos datos. Para que un objeto realice una de sus acciones se le manda un mensaje. Por tanto, laprimera ventaja de la programacin orientada a objetos es la encapsulacin de datos yoperaciones, es decir, la posibilidad de definir Tipos Abstractos de Datos.

    De cualquier forma la encapsulacin es una ventaja mnima de la programacin orientada aobjetos. Una caracterstica mucho ms importante es la posibilidad de que los objetos puedanheredar caractersticas de otros objetos. Este concepto se incorpora gracias a la idea de clase.

    Clases

    Cada objeto pertenece a una clase, que define la implementacin de un tipo concreto de objetos.Una clase describe la informacin de un objeto y los mensajes a los que responde. Ladeclaracin de una clase es muy parecida a la definicin de un registro, pero aqu los campos sellaman instancias de variables o datos miembro (aunque utilizar el trmino atributo, que nosuena tan mal en castellano). Cuando le mandamos un mensaje a un objeto, este invoca unarutina que implementa las acciones relacionadas con el mensaje. Estas rutinas se denominanmtodos o funciones miembro. La definicin de la clase tambin incluye las implementacionesde los mtodos.

    Se puede pensar en las clases como plantillas para crear objetos. Se dice que un objeto es unainstancia de una clase. Tambin se puede decir que un objeto es miembro de una clase.

    Herencia y polimorfismo

    Podemos definir clases en base a otra clase ya existente. La nueva clase se dice que es unasubclase o clase derivada, mientras que la que ya exista se denomina superclase o clase base.Una clase que no tiene superclase se denomina clase raz.

    Una subclase hereda todos los mtodos y atributos de su superclase, adems de poder definirmiembros adicionales (ya sean datos o funciones). Las subclases tambin pueden redefinir(override) mtodos definidos por su superclase. Redefinir se refiere a que las subclase respondeal mismo mensaje que su superclase, pero utiliza su propio mtodo para hacerlo.

    Gracias al mecanismo de redefinicin podremos mandar el mismo mensaje a objetos dediferentes clases, esta capacidad se denomina polimorfismo.

    Programacin con objetos

    A la hora de programar con objetos nos enfrentamos a una serie de problemas: Qu clases debocrear?, Cundo debo crear una subclase? Qu debe ser un mtodo o un atributo?

  • 8

    Lo usual es crear una jerarqua de clases, definiendo una clase raz que da a todos los objetos uncomportamiento comn. La clase raz ser una clase abstracta, ya que no crearemos instanciasde la misma. En general se debe definir una clase (o subclase de la clase raz) para cadaconcepto tratado en la aplicacin. Cuando necesitemos aadir atributos o mtodos a una clasedefinimos una subclase. Los atributos deben ser siempre privados, y deberemos proporcionarmtodos para acceder a ellos desde el exterior. Todo lo que se pueda hacer con un objeto debeser un mtodo.

  • 9

    El lenguaje C++

    INTRODUCCINEn este bloque introduciremos el lenguaje de programacin C++. Comenzaremos por dar unavisin general del lenguaje y despus trataremos de forma prctica todos los conceptosestudiados en el bloque anterior, viendo como se implementan en el C++.

    Trataremos de que el tema sea fundamentalmente prctico, por lo que estos apuntes se debenconsiderar como una pequea introduccin al lenguaje, no como una referencia completa. Losalumnos interesados en conocer los detalles del lenguaje pueden consultar la bibliografa.

    CONCEPTOS BSICOSComenzaremos estudiando el soporte del C++ a la programacin imperativa, es decir, la formade definir y utilizar los tipos de datos, las variables, las operaciones aritmticas, las estructurasde control y las funciones. Es interesante remarcar que toda esta parte est heredada del C, porlo que tambin sirve de introduccin a este lenguaje.

    Estructura de los programas

    El mnimo programa de C++ es:

    main() { }

    Lo nico que hemos hecho es definir una funcin (main) que no tiene argumentos y no hacenada. Las llaves { } delimitan un bloque en C++, en este caso el cuerpo de la funcin main.Todos los programas deben tener una funcin main() que es la que se ejecuta al comenzar elprograma.

    Un programa ser una secuencia de lneas que contendrn sentencias, directivas de compilaciny comentarios.

    Las sentencias simples se separan por punto y coma y las compuestas se agrupan en bloquesmediante llaves.

    Las directivas sern instrucciones que le daremos al compilador para indicarle que realice algunaoperacin antes de compilar nuestro programa, las directivas comienzan con el smbolo # y nollevan punto y coma.

  • 10

    Los comentarios se introducirn en el programa separados por /* y */ o comenzndolos con //.Los comentarios entre /* y */ pueden tener la longitud que queramos, pero no se anidan, esdecir, si escribimos /* hola /* amigo */ mo */, el compilador interpretar que el comentariotermina antes de mo, y dar un error. Los comentarios que comienzan por // slo son vlidoshasta el final de la lnea en la que aparecen.

    Un programa simple que muestra todo lo que hemos visto puede ser el siguiente:

    /* Este es un programa mnimo en C++, lo nico que hace es escribir una frase en la pantalla*/

    #include

    int main(){ cout

  • 11

    int i;double d;char c;

    Sobre los tipos elementales se pueden emplear los siguientes operadores aritmticos:

    + (ms, como signo o como operacin suma)- (menos, como signo o como operacin resta)* (multiplicacin)/ (divisin)% (resto)

    Y los siguientes operadores relacionales:

    == (igual)!= (distinto)< (menor que)> (mayor que)= (mayor o igual que)

    El operador de asignacin se representa por =.

    En la bibliografa del C++ se suelen considerar como tipos derivados los construidos mediantela aplicacin de un operador a un tipo elemental o compuesto en su declaracin. Estosoperadores son:

    * Puntero& Referencia[] Vector (Array)() Funcin

    Los tipos compuestos son las estructuras (struct), las uniones (unin) y las clases (class).

    Estructuras de control

    Como estructuras de control el C++ incluye las siguientes construcciones:

    condicionales:

    if instruccin de seleccin simple

    switch instruccin de seleccin mltiple

    bucles:

    do-while instruccin de iteracin con condicin final

    while instruccin de iteracin con condicin inicial

    for instruccin de iteracin especial (similar a las de repeticin con contador)

    de salto:

    break instruccin de ruptura de secuencia (sale del bloque de un bucle o instruccincondicional)

    continue instruccin de salto a la siguiente iteracin (se emplea en bucles para saltar a laposicin donde se comprueban las condiciones)

    goto instruccin de salto incondicional (salta a una etiqueta)

    return instruccin de retorno de un valor (se emplea en las funciones)

  • 12

    Veremos como se manejan todas ellas en el punto dedicado a las estructuras de control

    Funciones

    Una funcin es una parte con nombre de un programa que puede ser invocada o llamada desdecualquier otra parte del programa cuando haga falta. La sintaxis de las funciones depende de silas declaramos o las definimos.

    La declaracin se escribe poniendo el tipo que retorna la funcin seguido de su nombre y de unalista de parmetros entre parntesis (los parmetros deben ser de la forma tipo-param[nom_param], donde los corchetes indican que el nombre es opcional), para terminar ladeclaracin ponemos punto y coma (recordar que una declaracin es una sentencia).

    Para definir una funcin se escribe el tipo que retorna, el nombre de la funcin y una lista deparmetros entre parntesis (igual que antes, pero aqu si que es necesario que los parmetrostengan nombre). A continuacin se abre una llave, se escriben las sentencias que se ejecutan enla funcin y se cierra la llave.

    Un ejemplo de declaracin de funcin sera:

    int eleva_a_n (int, int);

    Y su definicin sera:

    int eleva_a_n (int x, int n){ if (n

  • 13

    Soporte a los Tipos de Datos Abstractos

    Para soportar los tipos de datos se proporcionan mecanismos para definir operadores yfunciones sobre un tipo definido por nosotros y para restringir el acceso a las operaciones a losobjetos de este tipo. Adems se proporcionan mecanismos para redefinir operadores e inclusose soporta el concepto de tipos genricos mediante las templates (plantillas).

    Tambin se define un mecanismo para manejo de excepciones que permite que controlemos deforma explcita los errores de nuestro programa.

    Soporte a la programacin Orientada a Objetos

    Para soportar el concepto de programacin orientada a objetos se incluyen diversosmecanismos:

    declaracin de clases (usando la palabra class)

    de paso de mensajes a los objetos (realmente son llamadas a funciones)

    proteccin de los mtodos y atributos de las clases (definicin de mtodos privados,protegidos y pblicos)

    soporte a la herencia y polimorfismo (incluso se permite la herencia mltiple, es decir,la definicin de una clase que herede caractersticas de dos clases distintas)

    Es interesante sealar que el soporte a objetos complementa a los mecanismos de programacinmodular, encapsulando aun ms los programas.

    TIPOS DE DATOS, OPERADORES Y EXPRESIONES

    Tipos de datos

    Para declarar una variable ponemos el nombre del tipo seguido del de la variable. Podemosdeclarar varias variables de un mismo tipo poniendo el nombre del tipo y las variables a declararseparadas por comas:

    int i, j,k;

    Adems podemos inicializar una variable a un valor en el momento de su declaracin:

    int i=100;

    Cada tipo definido en el lenguaje (o definido por el usuario) tiene un nombre sobre el que sepueden emplear dos operadores:

    sizeof, que nos indica la memoria necesaria para almacenar un objeto del tipo, y

    new, que reserva espacio para almacenar un valor del tipo en memoria.

    Tipos elementales

    El C++ tiene un conjunto de tipos elementales correspondientes a las unidades dealmacenamiento tpicas de un computador y a las distintas maneras de utilizarlos:

    enteros:

    charshort intintlong int

  • 14

    reales (nmeros en coma flotante):

    floatdoublelong double

    La diferencia entre los distintos tipos enteros (o entre los tipos reales) est en la memoria queocupan las variables de ese tipo y en los rangos que pueden representar. A mayor tamao,mayor cantidad de valores podemos representar. Con el operador sizeof podemos saber cuantoocupa cada tipo en memoria.

    Para especificar si los valores a los que se refieren tienen o no signo empleamos las palabrassigned y unsigned delante del nombre del tipo (por ejemplo unsigned int para enteros sinsigno).

    Para tener una notacin ms compacta la palabra int se puede eliminar de un nombre de tipo dems de una palabra, por ejemplo short int se puede escribir como short, unsigned esequivalente a unsigned int, etc.

    El tipo entero char es el que se utiliza normalmente para almacenar y manipular caracteres en lamayora de los computadores, generalmente ocupa 8 bits (1byte), y es el tipo que se utilizacomo base para medir el tamao de los dems tipos del C++.

    Un tipo especial del C++ es el denominado void (vaco). Este tipo tiene caractersticas muypeculiares, ya que es sintcticamente igual a los tipos elementales pero slo se emplea junto alos derivados, es decir, no hay objetos del tipo void Se emplea para especificar que una funcinno devuelve nada o como base para punteros a objetos de tipo desconocido (esto lo veremos alestudiar los punteros). Por ejemplo:

    void BorraPantalla (void);

    indica que la funcin BorraPantalla no tiene parmetros y no retorna nada.

    Tipos enumerados

    Un tipo especial de tipos enteros son los tipos enumerados. Estos tipos sirven para definir untipo que slo puede tomar valores dentro de un conjunto limitado de valores. Estos valorestienen nombre, luego lo que hacemos es dar una lista de constantes asociadas a un tipo.

    La sintaxis es:

    enum booleano {FALSE, TRUE}; // definimos el tipo booleano

    Aqu hemos definido el tipo booleano que puede tomar los valores FALSE o TRUE. Enrealidad hemos asociado la constante FALSE con el nmero 0, la constante TRUE con 1, y sihubiera ms constantes seguiramos con 2, 3, etc. Si por alguna razn nos interesa dar unnmero concreto a cada valor podemos hacerlo en la declaracin:

    enum colores {rojo = 4, azul, verde = 3, negro = 1};

    azul tomar el valor 5 (4+1), ya que no hemos puesto nada. Tambin se pueden usar nmerosnegativos o constantes ya definidas.

    Para declarar un variable de un tipo enumerado hacemos:

    enum booleano test; // sintaxis de ANSI Cbooleano test; // sintaxis de C++

    En ANSI C los enumerados son compatibles con los enteros, en C++ hay que convertir losenteros a enumerado:

    booleano test = (booleano) 1; // asigna TRUE a test (valor 1)

  • 15

    Si al definir un tipo enumerado no le damos nombre al tipo declaramos una serie de constantes:

    enum { CERO, UNO, DOS };

    Hemos definido las constantes CERO, UNO y DOS con los valores 0, 1 y 2.

    Tipos derivados

    De los tipos fundamentales podemos derivar otros mediante el uso de los siguientes operadoresde declaracin:

    * Puntero& Referencia[] Vector (Array)() Funcin

    Ejemplos:

    int *n; // puntero a un enteroint v[20]; // vector de 20 enterosint *c[20]; // vector de 20 punteros a enterovoid f(int j); // funcin con un parmetro entero

    El problema ms grave con los tipos derivados es la forma de declararlos: los punteros y lasreferencias utilizan notacin prefija y los vectores y funciones usan notacin postfija. La idea esque las declaraciones se asemejan al uso de los operadores de derivacin. Para los ejemplosanteriores haramos lo siguiente:

    int i; // declaracin de un entero ii = *n; // almacenamos en i el valor al que apunta ni = v[2] // almacenamos en i el valor de el tercer elemento de v // (recordad que los vectores empiezan en 0)i = *v[2] // almacenamos en i el valor al que apunta el tercer puntero de vf(i) // llamamos a la funcin f con el parmetro i

    Hay que indicar que otra fuente de errores es la asociacin de operadores, ya que a veces esnecesario el uso de parntesis. Por ejemplo, en la declaracin de c anterior hemos declarado unvector de punteros, pero para declarar un puntero a un vector necesitamos parntesis:

    int *c[20]; // vector de 20 punteros a enteroint (*p)[20] // puntero a vector de 20 enteros

    Al declarar variables de tipos derivados, el operador se asocia a la variable, no al nombre deltipo:

    int x,y,z; // declaracin de tres variables enterasint *i, j; // declaramos un puntero a entero (i) y un entero (j)int v[10], *p; // declaramos un vector de 10 enteros y un puntero a entero

    Este tipo de declaraciones deben evitarse para hacer ms legibles los programas.

    A continuacin veremos los tipos derivados con ms detalle, exceptuando las funciones, a lasque dedicaremos un punto completo del bloque ms adelante.

    Punteros

    Para cualquier tipo T, el puntero a ese tipo es T*. Una variable de tipo T* contendr la direccinde un valor de tipo T. Los punteros a vectores y funciones necesitan el uso de parntesis:

    int *pi // Puntero a enterochar **pc // Puntero a puntero a carcterint (*pv)[10] // Puntero a vector de 10 enterosint (*pf)(float) // Puntero a funcin que recibe un real y retorna un entero

  • 16

    La operacin fundamental sobre punteros es la de indireccin (retornar el valor apuntado por l):

    char c1 = 'a'; // c1 contiene el carcter 'a'char *p = &c1; // asignamos a p la direccin de c1 (& es el operador referencia)char c2 = *p; // ahora c2 vale lo apuntado por p ('a')

    Veremos ms ampliamente los punteros al hablar de variables dinmicas.

    Vectores

    Para un tipo T, T[n] indica un tipo vector con n elementos. Los ndices del vector empiezan en0, luego llegan hasta n-1. Podemos definir vectores multidimensionales como vectores devectores:

    int v1[10]; // vector de 10 enterosint v2[20][10]; // vector de 20 vectores de 10 enteros (matriz de 20*10)

    Accedemos a los elementos del vector a travs de su ndice (entre []):

    v1[3] = 15; // el elemento con ndice 3 vale 15v2[8][3] = v1[3]; // el elemento 3 del vector 8 de v2 vale lo mismo que v[3]

    El compilador no comprueba los lmites del vector, es responsabilidad del programador. Parainicializar un vector podemos enumerar sus elementos entre llaves. Los vectores de caracteres seconsideran cadenas, por lo que el compilador permite inicializarlos con una constante cadena(pero les aade el carcter nulo). Si no ponemos el tamao del vector al inicializarlo elcompilador le dar el tamao que necesite para los valores que hemos definido.

    Ejemplos:

    int v1[5] = {2, 3, 4, 7, 8};char v2[2][3] = {{'a', 'b', 'c'}, {'A', 'B', 'C'} }; // vect. multidimensionalint v3[2] = {1, 2, 3, 4}; // error: slo tenemos espacio para 2 enteroschar c1[5] = {'h','o','l','a','\0'}; // cadena "hola"char c2[5] = "hola"; // lo mismochar c3[] = "hola"; // el compilador le da tamao 5 al vectorchar vs[3][] = {"uno", "dos", "tres"} // vector de 3 cadenas (3 punteros a carcter)

    Referencias

    Una referencia es un nombre alternativo a un objeto, se emplea para el paso de argumentos y elretorno de funciones por referencia. T& significa referencia a tipo T.

    Las referencias tienen restricciones:

    1. Se deben inicializar cuando se declaran (excepto cuando son parmetros por referenciao referencias externas).

    2. Cuando se han inicializado no se pueden modificar.

    3. No se pueden crear referencias a referencias ni punteros a referencias.

    Ejemplos:

    int a; // variable enteraint &r1 = a; // ref es sinnimo de aint &r2; // error, no est inicializadaextern int &r3; // vlido, la referencia es externa (estar inicializada en otro // mdulo)int &&r4=r1; // error: referencia a referencia

    Tipos compuestos

    Existen cuatro tipos compuestos en C++:

  • 17

    EstructurasUnionesCampos de bitsClases

    Estructuras

    Las estructuras son el tipo equivalente a los registros de otros lenguajes, se definen poniendo lapalabra struct delante del nombre del tipo y colocando entre llaves los tipos y nombres de suscampos. Si despus de cerrar la llave ponemos una lista de variables las declaramos a la vez quedefinimos la estructura. Si no, luego podemos declarar variables poniendo struct nomtipo(ANSI C, C++) o nomtipo (C++).

    Ejemplo:

    struct persona { int edad; char nombre[50];} empleado;

    struct persona alumno; // declaramos la variable alumno de tipo persona (ANSI C)persona profesor; // declaramos la variable profesor de tipo personapersona *p; // declaramos un puntero a una variable persona

    Podemos inicializar una estructura de la misma forma que un array:

    persona juan= {21, "Juan Prez"};

    Para acceder a los campos de una estructura ponemos el nombre de la variable, un punto y elnombre del campo. Si trabajamos con punteros podemos poner -> en lugar de dereferenciar elpuntero y poner un punto (esto lo veremos en el punto de variables dinmicas):

    alumno.edad = 20; // el campo edad de alumno vale 20 p->nombre = "Pepe"; // el nombre de la estructura apuntada por p vale "Pepe" (*p).nombre = "Pepe"; // igual que antes

    Empleando el operador sizeof a la estructura podemos saber cuantos bytes ocupa.

    Uniones

    Las uniones son idnticas a las estructuras en su declaracin (poniendo union en lugar destruct), con la particularidad de que todos sus campos comparten la misma memoria (el tamaode la unin ser el del campo con un tipo mayor).

    Es responsabilidad del programador saber que est haciendo con las uniones, es decir, podemosemplear el campo que queramos, pero si usamos dos campos a la vez uno machacar al otro.

    Ejemplo:

    union codigo {int i;float f;} cod;

    cod.i = 10; // i vale 10cod.f = 25e3f; // f vale 25 * 1000, i indefinida (ya no vale 10)

    Por ltimo diremos que podemos declarar uniones o estructuras sin tipo siempre y cuandodeclaremos alguna variable en la definicin. Si no declaramos variables la estructura sin nombreno tiene sentido, pero la unin permite que dos variables compartan memoria.

    Ejemplo:

    struct {

  • 18

    int i; char n[20]} reg; // Podemos usar la variable reg

    union { int i; float f;}; // i y f son variables, pero se almacenan en la misma memoria

    Campos de bits

    Un campo de bits es una estructura en la que cada campo ocupa un numero determinado de bits,de forma que podemos tratar distintos bits como campos independientes, aunque estn juntos enuna misma palabra de la mquina.

    Ejemplo:

    struct fichero { :3 // nos saltamos 3 bits unsigned int lectura : 1; // reservamos un bit para lectura unsigned int escritura : 1; unsigned int ejecucin : 1; :0 // pasamos a la siguiente palabra unsigned int directorio: 8;} flags;

    flags.lectura = 1; // ponemos a 1 el bit de lectura

    Los campos siempre son de tipo discreto (enteros), y no se puede tomar su direccin.

    Clases

    Las clases son estructuras con una serie de caractersticas especiales, las estudiaremos enprofundidad en un punto del bloque.

    Constantes (literales)

    Hay cuatro tipos de literales en C++:

    Literales enteros

    Octales (en base ocho), si empiezan por cero, p. ej. 023 equivale a 10011 en binario o a19 en decimal

    Hexadecimales (en base diecisis), si empiezan por 0x, p.ej. 0x2F que equivale a 101111en binario o a 47 en decimal. En hexadecimal los valores del 10 al 15 se representan porA, B, C, D, E, y F (en maysculas o minsculas).

    Decimales, que son los que no empiezan por 0.

    A cada uno de estos literales les podemos aadir un sufijo para indicar que son sin signo (sufijou o U) o para forzar a que sean de tipo long (sufijo l o L), por ejemplo 23L es el entero 23 de tipolong, 0xFu es el entero 15 sin signo. Tambin podemos mezclar los sufijos: 12Lu entero 12 sinsigno de tipo long.

    Literales reales

    Una constante en coma flotante se escribe con la parte entera y la decimal separadas por punto,y opcionalmente se puede escribir la letra e o E y un exponente.

    El tipo de constante depende del sufijo:

    Sin sufijo: double

  • 19

    f, F : floatl, L : long double

    Ejemplos:

    1.8e3 // 1.8 * 103 == 1800 de tipo double0.1L // valor 0.1 long double-1e-3f // -0.001 float4. // 4.0 double.12 // 0.12 double

    Literales carcter

    Los caracteres se delimitan entre dos apstrofes ''. Dentro de los apstrofes slo podemosescribir un carcter, excepto cuando son caracteres especiales, que se codifican mediante elcarcter de escape \ seguido de otro carcter .

    Ejemplos:

    'a' // carcter a' ' // espacio en blanco (es un carcter)'\\' // carcter \ (es un carcter especial)'' // error: debe haber un carcter entre los apstrofes'ab' // error: pero slo uno

    Caracteres especiales ms utilizados:

    \n // salto de lnea\t // tabulador horizontal\v // tabulador vertical\b // retroceso\r // retorno de carro\f // salto de pgina\a // alerta (campana)\\ // carcter \\? // interrogante\' // comilla simple\" // comilla doble\ooo // carcter ASCII dado por tres dgitos octales (ooo sern dgitos)\xhh // carcter ASCII dado por dos dgitos hexadecimales (hh sern dgitos)\0 // carcter nulo

    Literales cadena

    Una cadena es un a secuencia de caracteres escrita entre comillas dobles y terminada con elcarcter nulo (\0).

    Ejemplos:

    "hola" // equivale a 'h','o','l','a','\0'"" // equivale a '\0'"'" // equivale a '\'', '\0'"\'" // equivale a '\'', '\0'""" // error, para escribir " dentro de una cadena lo correcto sera "\"""ho""la" // se concatenan, equivale a 'h','o','l','a','\0'

    Variables

    Alcance o mbito de las variables

    Las variables existen slo dentro del bloque en el que se definen, es decir, se crean cuando seentra en el bloque al que pertenecen y se destruyen al salir de l.

  • 20

    Para acceder a variables que se definen en otros mdulos la declaramos en nuestro mduloprecedida de la palabra extern.

    Si queremos que una variable sea local a nuestro mdulo la definimos static, de manera que esinaccesible desde el exterior de nuestro mdulo y adems permanece durante todo el tiempo quese ejecute el programa (no se crea al entrar en el mdulo ni se destruye al salir, sino quepermanece todo el tiempo) guardando su valor entre accesos al bloque.

    Si queremos que una variable no pueda ser modificada la declaramos const, tenemos queinicializarla en su declaracin y mantendr su valor durante todo el programa. Estas variables seemplean para constantes que necesitan tener una direccin (para pasarlas por referencia).

    El operador ::

    Dentro de un bloque podemos emplear el operador :: para acceder a variables declaradas en unbloque superior. Este operador slo es til cuando en un bloque interno tenemos una variablecon un nombre igual a otro externo (la variable accesible ser la interna, pero con :: accederemosa la externa). Veremos que el operador :: se usa fundamentalmente para clases.

    Ejemplo:

    main () { int v; { char v; v = 5; // asigna 5 a la variable char (interna) ::v=9 + v; // asigna 9 + 5 (valor de v interna) a la variable int ms externa }}

    Variables voltiles

    Si queremos que una variable sea comprobada cada vez que la utilicemos la declararemosprecedida de la palabra volatile, esto es til cuando definimos variables que almacenan valoresque no slo modifica nuestro programa (por ejemplo una variable que utiliza el Hardware o elSO).

    Variables register

    Podemos intentar hacer ms eficientes nuestros programas indicndole al compilador quevariables usamos ms a menudo para que las coloque en los registros. Esto se hace declarandola variable precedida de la palabra register. No tenemos ninguna garanta de que el compiladornos haga caso, depende del entorno de desarrollo que empleemos.

    Conversiones de tipos

    Conversiones implcitas

    Cuando trabajamos con tipos elementales podemos mezclarlos en operaciones sin realizarconversiones de tipos, ya que el compilador se encarga de aproximar al valor de mayorprecisin. De cualquier forma debemos ser cuidadosos a la hora de mezclar tipos, ya que laconversin que realiza el compilador puede no ser la que esperamos.

    Conversiones explcitas (casting)

    Para indicar la conversin explcita de un tipo en otro usamos el nombre del tipo, por ejemplosi tenemos i de tipo int y j de tipo long, podemos hacer i=(long)j (sintaxis del C, vlida enC++) o i=long(j) (sintaxis del C++). Hay que tener en cuenta que hay conversiones que notienen sentido, como pasar un long a short si el valor que contiene no cabe, o convertir unpuntero a entero, por ejemplo.

  • 21

    Ms adelante veremos que para los tipos definidos por nosotros podemos crear conversores aotros tipos.

    Operadores y expresiones

    El C++ tiene gran cantidad de operadores de todo tipo, en este punto veremos de formaresumida todos ellos, para luego dar una tabla con su precedencia y su orden de asociatividad.Antes de pasar a listar los operadores por tipos daremos unas definiciones tiles para ladescripcin de la sintaxis de los operadores:

    Operandos LValue (left value)

    Son aquellos operandos que cumplen las siguientes caractersticas:

    Pueden ser fuente de una operacin.

    Pueden ser destino de una operacin.

    Se puede tomar su direccin.

    En definitiva un LValue es cualquier operando que este almacenado en memoria y se puedamodificar.

    Expresiones

    Como ya dijimos en el bloque anterior, una expresin es cualquier sentencia del programa quepuede ser evaluada y devuelve un valor.

    Lista de operadores segn su tipo

    Operadores aritmticos:

    + Suma- Resta* Producto/ Divisin: entera para escalares, real para reales% Mdulo: retorna el resto de una divisin entre enteros-(unario) Cambio de signo+(unario) No hace nada

    Operadores de incremento y decremento:

    ++ incremento en uno del operando LValue al que se aplica.-- decremento en uno del operando LValue al que se aplica.

    Estos operadores pueden ser prefijos o postfijos. Si son prefijos el operando se incrementa(decrementa) antes de ser evaluado en una expresin, si son postfijos el operando se incrementa(decrementa) despus de la evaluacin.

    Operadores relacionales:

    > Mayor< Menor>= Mayor o igual

  • 22

    && AND lgico|| OR lgico! NOT lgico

    Toman expresiones como operandos, retornando verdadero o falso como en los operadoresrelacionales

    Operadores de bit:

    & Producto binario de bits (AND).| Suma binaria de bits (OR).^ Suma binaria exclusiva de bits (XOR). Puntero selector de miembro o campo. Selector de miembro o campo[] Subndice->* Puntero selector de puntero a miembro.* Selector de puntero a miembro

    Los usos de estos operadores que an no hemos visto se estudiarn ms adelante

  • 23

    Operador condicional:

    ?: Expresin condicional

    Este operador es equivalente a una expresin condicional, lo que hacemos es evaluar el primeroperando y si es cierto retornamos el segundo operando, en caso contrario retornamos el terceroperando.

    Ejemplo:

    max = (a>b) ? a : b; // si a es mayor que b max vale a, sino max vale b

    Operadores sizeof:

    sizeof var Nos da el tamao de una variablesizeof (tipo) Nos da el tamao de un tipo de datos

    Estos operadores nos devuelven el tamao en bytes.

    Precedencia, asociatividad y orden de evaluacin

    La precedencia de los operadores nos permite evitar el uso de parntesis (que es lo que msprecedencia tiene) en expresiones sencillas. Veremos la precedencia de los operadores enfuncin del orden de la tabla, los primeros bloques sern los de mayor precedencia.

    Tambin indicaremos en la tabla el orden en que se asocian los operandos (si se puedenasociar).

    Operador Sintaxis Descripcin Asociatividad::::

    nom_clase::miembro::nombre

    resolucin de camposoperador de campo

    NONO

    .->[]()()sizeofsizeof

    estructura.miembropuntero->miembropuntero[expr]nom_funcion()tipo (expr)sizeof exprsizeof (tipo)

    selector de miembropuntero a miembrosubndicellamada a funcinconversin de tipostamao de un objetotamao de un tipo

    Izquierda a derechaIzquierda a derechaIzquierda a derechaIzquierda a derechaNONONO

    ++++----~!-+&*newdeletedelete[]()

    lvalue ++++ lvaluelvalue ---- lvalue~ expr! expr- expr+ expr& lvalue* exprnew tipodelete punterodelete [] puntero(tipo) expr

    postincrementopreincrementopostdecrementopredecrementocomplementonegacinnegativopositivodireccinindireccincrear objetoborrar objetoborrar arrayconversin de tipo

    NONONONONONONONONONONONONODerecha a izquierda

    .*->*

    objeto.ptr_miembroptr->ptr_miembro

    seleccin miembropuntero miembro

    Izquierda a derechaIzquierda a derecha

    */%

    expr * exprexpr / exprexpr % expr

    multiplicacindivisinresto

    Izquierda a derechaIzquierda a derechaIzquierda a derecha

    +-

    expr + exprexpr - expr

    sumaresta

    Izquierda a derechaIzquierda a derecha

    >

    expr > expr

    desplazamiento izquierdadesplazamiento derecha

    Izquierda a derechaIzquierda a derecha

    =

    expr < exprexpr exprexpr >= expr

    menor quemenor o igual quemayor quemayor o igual que

    Izquierda a derechaIzquierda a derechaIzquierda a derechaIzquierda a derecha

  • 24

    ==!=

    expr == exprexpr != expr

    igual quedistinto que

    Izquierda a derechaIzquierda a derecha

    & expr & expr AND a nivel de bits Izquierda a derecha^ expr ^ expr XOR a nivel de bits Izquierda a derecha| expr | expr OR a nivel de bits Izquierda a derecha&& expr && expr AND lgico Izquierda a derecha|| expr || expr OR lgico Izquierda a derecha?: expr ? expr : expr expresin condicional Derecha a izquierda=*=/=%=+=-==&=|=^=

    lvalue = exprlvalue *= exprlvalue /= exprlvalue %= exprlvalue += exprlvalue -= exprlvalue = exprlvalue &= exprlvalue |= exprlvalue ^= expr

    asignacin simpleproducto y asignacindivisin y asignacinresto y asignacinsuma y asignacinresta y asignacindespl. izq. y asignacindespl. der. y asignacinAND y asignacinOR y asignacinXOR y asignacin

    Derecha a izquierdaDerecha a izquierdaDerecha a izquierdaDerecha a izquierdaDerecha a izquierdaDerecha a izquierdaDerecha a izquierdaDerecha a izquierdaDerecha a izquierdaDerecha a izquierdaDerecha a izquierda

    , expr, expr coma (secuencia) Derecha a izquierda

    Para terminar con los operadores indicaremos que el orden de evaluacin de los operandos noest predefinido, excepto en los casos siguientes:

    a || b Si se cumple a no se evala ba && b Si no se cumple a no se evala b, La coma evala de izquierda a derechaa ? b : c Si se cumple a se evala b, sino se evala c

    ESTRUCTURAS DE CONTROLEl C++, como todo lenguaje de programacin basado en la algortmica, posee una serie deestructuras de control para gobernar el flujo de los programas. Aqu estudiaremos lasestructuras de control de la misma manera que las vimos en el bloque anterior, es decir,separando entre estructuras condicionales o de seleccin, de repeticin y de salto.

    Antes de comenzar debemos recordar que la evaluacin de una condicin producir comoresultado un cero si es falsa y un nmero cualquiera distinto de cero si es cierta, este hecho esimportante a la hora de leer los programas, ya que una operacin matemtica, por ejemplo, esuna condicin vlida en una estructura de control.

    Estructuras de seleccin

    Dentro de las estructuras de seleccin encontramos dos modelos en el C++, las de condicinsimple (sentencias if else) y las de condicin mltiple (switch). A continuacin estudiaremosambos tipos de sentencias.

    La sentencia if

    Se emplea para elegir en funcin de una condicin. Su sintaxis es:

    if (expresin) sentencia 1else sentencia 2

    Los parntesis de la expresin a evaluar son obligatorios, la sentencia 1 puede ser una solainstruccin (que no necesita ir entre llaves) o un bloque de instrucciones (entre llaves pero sinpunto y coma despus de cerrar). El else es opcional, cuando aparece determina las acciones atomar si la expresin es falsa.

    El nico problema que puede surgir con estas sentencias es el anidamiento de if y else: Cadaelse se empareja con el if ms cercano:

  • 25

    if (expr1) if (expr2) accin 1 else // este else corresponde al if de expr 2 accin 2else // este corresponde al if de expr1 accin 3

    Para diferenciar bien unas expresiones de otras (el anidamiento), es recomendable tabularcorrectamente y hacer buen uso de las llaves:

    if (expr1) { if (expr2) accin 1} // Notar que la llave no lleva punto y coma despus, si lo pusiramos // habramos terminado la sentencia y el else se quedara sueltoelse // Este else corresponde al if de expr1 accin 3

    Por ltimo indicaremos que cuando anidamos else - if se suele escribir:

    if (e1) a1else if (e2) a2else if (e3) a3else an

    de esta manera evitamos el exceso de tabulacin.

    La sentencia switch

    Esta sentencia nos permite seleccionar en funcin de condiciones mltiples. Su sintaxis es:

    switch (expresin) { case valor_1: sentencia 11; sentencia 12; sentencia 1n; break; case valor_2: sentencia 21; sentencia 22; sentencia 2m; break; default: sentencia d1; sentencia d2; sentencia dp}

    El parntesis en la expresin es obligatorio. El funcionamiento es el siguiente, si al evaluar laexpresin se obtiene uno de los valores indicados por case valor_i se ejecutan todas lassentencias que encontremos hasta llegar a un break (o al cierre de las llaves). Si no se verificaningn case pasamos a las sentencias default, si existe (default es opcional) y si no existe nohacemos nada.

    Indicaremos que si queremos hacer lo mismo para distintos valores podemos escribir los caseseguidos sin poner break en ninguno de ellos y se ejecutar lo mismo para todos ellos.

    Ejemplo:

    void main() { int i;

  • 26

    cin >> i; switch (i) { case 0: case 2: case 4: case 6: case 8: cout

  • 27

    En el siguiente ejemplo veremos como esto se puede interpretar fcilmente como una repeticincon contador:

    int i;for (i=0; i

  • 28

    El goto slo se puede usar dentro de la funcin donde se define la etiqueta y no se puede ponerantes de una declaracin de variables.

    La sentencia return

    Esta sentencia se emplea en las funciones, para retornar un valor. En el punto en el que apareceel return la funcin termina y devuelve el valor. Si una funcin no devuelve nada podemosponer return sin parmetros para terminar (si no lo ponemos la funcin retorna al terminar subloque de sentencias).

    Ejemplo:

    int min (int a, int b) { if (a

  • 29

    Es decir, una lista de parmetros no es una declaracin de variables.

    Si no deseamos usar algn parmetro podemos indicarlo no ponindole nombre en la definicinde la funcin.

    Dentro del cuerpo de la funcin podemos declarar variables, pero no funciones, es decir, no sepermiten funciones anidadas.

    Paso de parmetros

    En C++ todos los parmetros se pasan por valor, es decir, se hace una copia de los parmetroscuando llamamos a la funcin. En la llamada, antes de hacer la copia, se chequea que losparmetros actuales (los valores o variables especificados en la llamada) son del mismo tipo quelos parmetros formales (los que declaramos en la lista de parmetros de la declaracin de lafuncin). Si los tipos son iguales o existe una conversin implcita la llamada puede realizarse,si no son iguales deberemos realizar conversiones explcitas.

    Veamos un ejemplo de paso de parmetros:

    #include

    void f (int val, int& ref) { val++; ref++;}

    main (){ int i=1; int j=1;

    f(i.j);

    cout

  • 30

    El problema est en la forma de tratar los vectores del C++, ya que el nombre de un vector ouna matriz es en realidad un puntero al primer elemento de la misma, y utilizando el operador []lo que hacemos es sumarle a ese puntero el tamao de los elementos del array multiplicado porel valor entre corchetes. Esta es la razn de que los vectores comiencen en 0, ya que el primerelemento es el apuntado por el nombre del vector.

    Todo esto implica que realmente su hayamos copiado el parmetro, slo que el parmetro es elpuntero al primer elemento, no el contenido del vector, y por tanto las modificaciones delcontenido se hagan sobre los valores de la matriz pasada como parmetro.

    Veremos en el punto dedicado a variables dinmicas que realmente los tipos vector y punteroson equivalentes (podremos usarlos indistintamente).

    Retorno de valores

    Para retornar valores una funcin emplea la instruccin return, que como ya vimos se puedecolocar en cualquier punto de la misma y ms de una vez. Cuando se ejecuta un return lafuncin sale.

    Hay que indicar que tambin se chequea el tipo de los retornos, es decir, lo que retornemosdebe ser del mismo tipo (o convertible implcitamente) que el declarado como de retorno para lafuncin.

    Cuando una funcin se declara de manera que retorna algo, es un error no poner ningn returnen la misma.

    Sobrecarga de funciones

    Una de las caractersticas ms interesantes del C++ en cuanto a funciones se refiere es laposibilidad de definir distintas funciones con el mismo nombre aunque con distintosparmetros.

    Esta capacidad se denomina sobrecarga de funciones y es til para llamar de la misma forma afunciones que realizan operaciones similares pero sobre operandos distintos. En est frasehemos dado una clave para la definicin de los TAD en C++, los operadores son funciones ycomo tales tambin pueden ser sobrecargadas. Este aspecto se estudiar una vez hayamos vistolas clases, ya que tienen su mayor aplicacin en estas.

    El tipo de retorno debe ser igual, ya que de lo contrario se pueden provocar ambigedades comoque llamemos a una funcin esperando un real y tengamos dos funciones idnticas, una queretorna reales y otra enteros, Cul debemos usar? Si no hubiera conversiones implcitas estaraclaro, pero podemos querer usar la que retorna enteros y que se transforme en real. La solucines no permitir retornos diferentes, lo nico que debemos hacer es darles nombres diferentes alas funciones.

    Parmetros por defecto

    Algunas veces una funcin necesita determinados parmetros en condiciones excepcionales peroestos suelen tener unos valores fijos en los casos normales. Para no tener que dar estosparmetros en los casos normales el C++ permite el uso de parmetros por defecto. La sintaxises muy simple, al declarar una funcin ponemos lo mismo que antes slo que los parmetrospor defecto van al final y se escriben no slo poniendo el tipo sino tambin un signo igual y unvalor:

    tipo nom_funcion (lista_param, lista_param_por_defecto);

    lista_param_por_defecto = tipo_pd_1 = vd1, , tipo_pd_n = vd_n

    Para usar la funcin podemos llamarla especificando slo los parmetros indefinidos oponiendo estos y algunos parmetros por defecto con un valor.

  • 31

    Ejemplo:

    void imprime_int (int valor, int base = 10);// tambin se puede declarar como// void imprime_int (int , int = 10);// los nombres no importan

    void imprime_int (int valor, int base) { switch (base) { case 8: cout

  • 32

    el tipo y nmero de parmetros variables es pasarle a la funcin una cadena de caracteres con lostipos.

    Veamos como se usa con un ejemplo:

    #include #include // macros parmetros variables#include // funcin strlen

    void param_test (char * ...);

    void param_test (char *tipos ...) { int i; va_list ap; // ap es la lista de parmetros

    va_start (ap, tipos); // inicializacin lista de param. i = strlen (tipos); // la longitud de la cadena es el n de param

    // nuestra funcin reconoce tipos enteros y tipos reales (los reales slo de tipo// double).

    for (int j=0; j

  • 33

    despus de una llamada recursiva (por ejemplo una variable temporal para intercambios), aldeclararla esttica no tenemos que reservar espacio para ella en cada llamada (las llamadasrecursivas consumen menos pila).

    Aunque comento esto para funciones recursivas, la verdad es que esto se cumple para todas lasfunciones, luego podemos tener una variable esttica que se use para contar el nmero de vecesque se llama a una funcin (por ejemplo).

    Punteros a funciones

    Con las funciones slo podemos hacer dos cosas, llamarlas u obtener su direccin, es decir,podemos definir punteros a funciones (que luego nos sirven para llamarlas).

    La declaracin de un puntero a funcin se hace:

    tipo_retorno (*nom_var) (lista_tipos_argumentos);

    El parntesis es necesario, ya que el operador de funcin tiene ms preferencia que el puntero,por lo que si escribimos:

    tipo_retorno *nom_var (lista_tipos_argumentos);

    el compilador interpretar que tenemos una funcin que retorna un puntero a un elemento detipo tipo_retorno.

    Para llamar a la funcin slo tenemos que escribir:

    (*nom_var) (param_actuales);

    si ponemos:

    nom_var (param_actuales);

    el compilador seguramente identificar que nom_var es una funcin y llamar correctamente a lafuncin, aunque es mejor no fiarse de eso.

    Para asignar valor a un puntero a funcin slo tenemos que escribir:

    nom_var= &nom_funcion;

    donde nom_funcin corresponde a una funcin con parmetros y retorno idnticos a los definidosen el puntero a funcin.

    La funcin main()

    Para terminar con las funciones hablaremos de la funcin principal de los programas de C++, lafuncin main().

    La funcin main() se puede definir de varias formas distintas:

    1. void main (); // no recibe parmetros ni retorna nada2. int main (); // no recibe parmetros y retorna un entero al SO (un cdigo de // error (generalmente negativo) o 0 si no hay errores) main (); // igual que la anterior3. void main (int argc, char *argv[]); // recibe un array con 'argc' cadenas de // caracteres y no retorna nada4. int main (int argc, char *argv[]); // igual que la anterior pero retorna un // cdigo de error al SO

    La tercera y cuarta formas reciben parmetros desde la lnea de comandos en SistemasOperativos como UNIX o MS-DOS. Es decir, cuando en MS-DOS escribimos un comandocomo:

  • 34

    C:\> COPY A:\MIO\PROGRAM.C C:

    lo que en realidad hacemos es llamar al programa COPY pasndole una serie de parmetros. Loque recibe la funcin main() es la lnea de comandos, es decir, el nombre de la funcin seguidode los parmetros, cada palabra ser una de las cadenas del array argv[]. Para el ejemplo, main()recibir:

    argc = 3argv[1] = "COPY"argv[1] = "A:\MIO\PROGRAM.C"argv[2] = "C:"

    Por ltimo, para salir de un programa en C++ tenemos dos opciones, retornando un valor al SOen la funcin main() (o cuando esta termine si no retorna nada) o empleando la funcin exit(),declarada en la cabecera estndar :

    void exit (int);

    El entero que recibe la funcin exit() ser el valor que se retorne al SO. Generalmente la salidacon exit() se utiliza cuando se produce un error.

    VARIABLES DINMICASEn la mayora de los lenguajes de alto nivel actuales existe la posibilidad de trabajar convariables dinmicas, que son aquellas que se crean en tiempo de ejecucin. Para soportar elempleo de estas variables aparecen los conceptos de puntero y referencia que estn ntimamenterelacionados con el concepto de direccin fsica de una variable.

    Punteros y direcciones

    Ya hemos mencionado que el C++ es un lenguaje que pretende acercarse mucho al nivel demquina por razones de eficiencia, tanto temporal como espacial. Por est razn el C++ nospermite controlar casi todos los aspectos de la ocupacin y gestin de memoria de nuestrosprogramas (sabemos lo que ocupan las variables, podemos trabajar con direcciones, etc.).

    Uno de los conceptos fundamentales en este sentido es el de puntero. Un puntero es unavariable que apunta a la direccin de memoria donde se encuentra otra variable. La clave aquest en la idea de que un puntero es una direccin de memoria.

    Pero, cmo conocemos la direccin de una variable declarada en nuestro programa? Lasolucin a esto est en el uso del operador de referencia (&), ya mencionado al hablar de losoperadores de indireccin. Para obtener la direccin de una variable solo hay aplicarle eloperador de referencia (escribiendo el smbolo & seguido de la variable), por ejemplo:

    int i = 2;int *pi = &i; // ahora pi contiene la direccin de la variable i.

    El operador de indireccin slo se puede ser aplicado a variables y funciones, es decir, aLValues. Por tanto, sera un error aplicarlo a una expresin (ya que no tiene direccin).

    Por otro lado, para acceder a la variable apuntada por un puntero se emplea el operador deindireccin (*) poniendo el * y despus el nombre del puntero:

    int j = *pi; // j tomara el valor 2, que es el contenido de la variable i anterior

    Para declarar variables puntero ponemos el tipo de variables a las que va a apuntar y el nombredel puntero precedido de un asterisco. Hay que tener cuidado al definir varios punteros en unamisma lnea, ya que el asterisco se asocia al nombre de la variable y no al tipo. Veamos esto conun ejemplo:

    char *c, d, *e; // c y e son punteros a carcter, pero d es una variable carcter

  • 35

    Como los punteros son variables podemos emplearlos en asignaciones y operaciones, pero hayque diferenciar claramente entre los punteros como dato (direcciones) y el valor al que apuntan.Veremos esto con un ejemplo, si tenemos los punteros:

    int *i, *j;

    La operacin:

    i= j;

    hace que i y j apunten a la misma direccin de memoria, pero la operacin:

    *i = *j;

    hace que lo apuntado por i pase a valer lo mismo que lo apuntado por j, es decir, los punterosno han cambiado, pero lo que contiene la direccin a la que apunta i vale lo mismo que lo quecontiene la direccin a la que apunta j. Es decir, si i y j apuntaran a las variables enteras a y brespectivamente:

    int a, b;int *i = &a;int *j = &b;

    lo anterior sera equivalente a:

    a= b;

    Por ltimo indicaremos que hay que tener mucho cuidado para no utilizar punteros sininicializar, ya que no sabemos cul puede ser el contenido de la direccin indefinida quecontiene una variable puntero sin inicializar.

    El puntero NULL

    Siempre que trabajamos con punteros solemos necesitar un valor que nos indique que el punteroes nulo (es decir, que no apuntamos a nada). Esto se consigue dndole al puntero el valor 0 oNULL. NULL no es una palabra reservada, sino que se define como una macro en lascabeceras estndar y , y por tanto ser necesario incluirlas para usarlo. Sino queremos usar las cabeceras podemos definirlo nosotros de alguna de las siguientes formas:

    #define NULL (0)#define NULL (0L)#define NULL ((void *) 0)

    la primera y segunda formas son vlidas porque 0 y 0L tienen conversin implcita a puntero, yla tercera es vlida porque convertimos explcitamente el 0 a puntero void. Una forma adecuadade definir NULL es escribiendo:

    #ifndef NULL #define NULL ((void *) 0)#endif

    que define NULL slo si no est definido (podra darse el caso de que nosotros noincluyramos las cabeceras que definen NULL, pero si se hiciese desde alguna otra cabeceraque si hemos incluido).

    Cualquier indireccin al puntero NULL se transforma en un error de ejecucin.

    Punteros void

    Ya hemos mencionado que el C++ define un tipo especial denominado void (vaco), queutilizbamos para indicar que una funcin no retorna nada o no toma parmetros. Adems eltipo void se emplea como base para declarar punteros a variables de tipo desconocido.

  • 36

    Debemos recordar que no se pueden declarar variables de tipo void, por lo que estos punt