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

Programacin en C++ con C++Builder

Versin de borrador N6 Mayo - 2005

Angel A. Zeitoune
(azeitoune@yahoo.com.ar)

y Ricardo A. Rettore
(ricadorettore@yahoo.com.ar)

Esta es una versin borrador, cualquier duda o sugerencia por favor escribir a cualquiera de los autores. Este libro sufre continuas modificaciones y ampliaciones, de acuerdo a la disponibilidad de los autores. La ltima versin la podrn encontrar en la pgina Web: http://www.angelzeitoune.com.ar/cpp/libro_cpp.html

Programacin en C++ con C++Builder

Licencia
Este libro se distribuye bajo esta licencia de Creative Commons ReconocimientoNoComercial-SinObraDerivada 2.0 (http://creativecommons.org/licenses/by-nc-nd/2.0/). Presentamos un resumen ms legible de esta licencia. Usted es libre de: copiar, distribuir y comunicar pblicamente la obra

Bajo las condiciones siguientes: Reconocimiento. Debe reconocer y citar al autor original.

No comercial. No puede utilizar esta obra para fines comerciales.

Sin obras derivadas. No se puede alterar, transformar o generar una obra derivada a partir de esta obra. Al reutilizar o distribuir la obra, tiene que dejar bien claro los trminos de la licencia de esta obra. Alguna de estas condiciones puede no aplicarse si se obtiene el permiso del titular de los derechos de autor

Los derechos derivados de usos legtimos u otras limitaciones no se ven afectados por lo anterior.

Programacin en C++ con C++Builder

ndice
ndice............................................................................................................................................. 3 Introduccin.................................................................................................................................. 5 Captulo 1: Entorno de desarrollo. ............................................................................................... 6 Creando un proyecto. ................................................................................................................. 7 Conociendo los componentes...................................................................................................... 8 Primera aplicacin.................................................................................................................... 12 Captulo 2: Programacin Orientada a Objetos (POO)............................................................. 17 Clases (class)............................................................................................................................ 17 Diagrama de clase. ................................................................................................................... 21 Constructor. ............................................................................................................................. 21 Destructor. ............................................................................................................................... 22 Resumen de conceptos importantes:.......................................................................................... 23 Cundo y porque modelamos una clase..................................................................................... 23 Encapsulamiento ...................................................................................................................... 24 Herencia................................................................................................................................... 24 Clases contenedoras. ................................................................................................................ 28 Diferencia entre Registros y Clases........................................................................................... 31 Captulo 3: Lgica de control ..................................................................................................... 33 Expresin lgica....................................................................................................................... 33 Estructura condicional if ....................................................................................................... 34 Estructura condicional switch................................................................................................ 36 Captulo 4: Estructuras Repetitivas ........................................................................................... 38 Ciclo for................................................................................................................................... 38 Ciclo while............................................................................................................................... 40 Ciclo do-while.......................................................................................................................... 41 Instrucciones break y continue.................................................................................................. 42 Captulo 5: Vectores y Matrices ................................................................................................. 44 Declaracin.............................................................................................................................. 44 Ejemplo. .................................................................................................................................. 45 Captulo 6: Cadenas de caracteres ............................................................................................. 56 char.......................................................................................................................................... 56 c-string..................................................................................................................................... 56 c++ string................................................................................................................................. 57 AnsiString................................................................................................................................ 57 Ejemplos.................................................................................................................................. 59 Captulo 7: Archivos de Texto. ................................................................................................... 62 Creacin del objeto................................................................................................................... 62 Apertura del archivo. ................................................................................................................ 63 Cierre del archivo. .................................................................................................................... 64 Manipulacin del archivo. ........................................................................................................ 64

Programacin en C++ con C++Builder

Ejemplos.................................................................................................................................. 70 ANEXO I: Tabla de caracteres ASCII ....................................................................................... 72 ANEXO II: funciones.................................................................................................................. 73 Conversiones de tipo ................................................................................................................ 73 Funciones matemticas............................................................................................................. 73

Programacin en C++ con C++Builder

Introduccin.
Esta obra nace con la necesidad de contar con un libro que permitiese aprender a programar en C++ al mismo tiempo que ensease a utilizar como herramienta a Borland C++Builder, y dada su carencia en el mercado, decidimos desarrollarlo. C++Builder es una herramienta de desarrollo rpido de aplicaciones (RAD, rapid application development) para Windows, en lenguaje de C++, que posee varias caractersticas importantes, lo cual facilita el desarrollo de aplicaciones grficas. Queremos aclarar que en este curso, slo presentaremos una breve introduccin al uso de la herramienta de programacin C++Builder y conocimientos mnimos para lograr el aprendizaje del lenguaje. A lo largo de este libro nos introduciremos al entorno de desarrollo, presentando sus caractersticas, su utilizacin y algunos componentes bsicos. Posteriormente concentraremos en la programacin orientada a objetos, diseo e implementacin, resaltando los conceptos en todo momento, para permitir al lector formarse con una base slida. Desarrollaremos las estructuras de programacin bsica, lgica de control, estructuras repetitivas, y manipulacin de vectores y matrices estticas. Expondremos diferentes formas de manipular las cadenas de caracteres, para lograr generar una idea global sobre el tema, concentrndonos sobre la clase AnsiString propia de Borland. Culminaremos con manipulacin de archivos de texto, cuyo uso es sumamente frecuente para almacenar informacin, intentando proveer un amplio abanico de ejemplos con sutiles diferencias para evaluar su funcionamiento. Esperamos que les guste y sobre todo les sea til. Angel Zeitoune y Ricardo Rettore

Programacin en C++ con C++Builder

Captulo 1: Entorno de desarrollo.


Una vez iniciado el programa, nos presentar su IDE (integrated development environment, entorno de desarrollo integrado), que provee todas las herramientas necesarias para disear, desarrollar, testear y compilar aplicaciones. Se observa lo siguiente:

Entre los elementos que forman el IDE, se puede nombrar: Formulario (Form): representa la ventana de aplicacin, que a su vez puede contener a otros objetos componentes (objetos). Editor de Cdigo (Code Editor): aparece, inicialmente, atrs del formulario. Es un editor de texto avanzado que contiene el cdigo fuente del programa. Ventana Principal (main window): Contiene la barra de ttulo, el men principal, barra de acceso rpido (SpeedBar), y la paleta de componentes (Component palette). Inspector de Objetos (Object Inspector): esta dividido en dos pginas, propiedades y eventos, las cuales estn asociadas al componente seleccionado. Programacin en C++ con C++Builder 6

Creando un proyecto.
Al iniciarse, C++Builder, esta listo para comenzar un nuevo proyecto. Si estabamos en el entrono y queremos crear uno nuevo existen dos formas de hacerlo: En el men principal File/New Application. En el men principal File/New, donde se nos presenta una ventana de new item, donde seleccionamos Application.

Un nuevo proyecto esta formado (por defecto) por los archivos de proyecto, y un formulario con su respectiva unit. Tambin podremos incluir a nuestro proyecto, nuevos formularios, units, mdulos de datos, archivos de texto, etc. con la opcin File/New. Lo primero que realizaremos, es grabar nuestro proyecto con nombres significativos al programa que estemos realizando en una carpeta especialmente destinada a nuestro proyecto. Sugerencia: Al nombre del archivo de proyecto le antepondremos una P (por ej. PNombre.bpr) y al nombre de la unit asociada al formulario le antepondremos una F (por ej. FNombre.cpp), y a una unit sin formulario con una U (por ej. UNombre.cpp).

Si analizamos un poco, los archivos que se encuentran en esta carpeta podremos observar una serie de archivos extras al que nosotros grabamos. Podemos distinguir estos archivos segn sus extensiones:

Extensin .h .cpp

Contenido
Archivo de cabecera. Contiene la declaracin de la clase. Archivo fuente de C++. Implementacin del archivo .h, Usualmente tenemos uno por cada unit y uno por el proyecto principal.

Programacin en C++ con C++Builder

.dfm .bpr .exe .res .obj .tds

Archivos del formulario. Es un archivo de texto que contiene caractersticas de los elementos visuales. Archivo de proyecto Programa ejecutable. Archivo de recursos. Se guardan en este archivo el icono de nuestra aplicacin entre otras cosas. Archivo objeto. Es un archivo binario que produce el compilador de nuestro proyecto antes de armar el ejecutable. Tabla simblica de depuracin.

.~h .~cpp .~dfm Archivos temporales de los anteriores

Conociendo los componentes.


C++Builder, nos presenta una serie de componentes previamente definidos, en una paleta de componentes, agrupados en un conjunto de pginas de acuerdo con las finalidades de los mismos. Para insertarlos en un formulario, existen tres maneras: Haciendo click sobre el mismo y luego sobre el formulario. Hiendo doble click sobre el componente. Haciendo click sobre el componente y luego manteniendo presionando el botn izquierdo del mouse sobre el formulario, dando el tamao deseado al mismo.

El inspector de objetos nos presenta las propiedades y eventos asociados a los elementos que componen la interfaz grfica. Avanzado: Los componentes, estn conformados en una biblioteca visual de componentes (Visual Component Library), llamada VCL, que se basa en modelo de propiedades, mtodos y eventos (PME). La VCL es una jerarqua de clases escrita en Object Pascal asociada al IDE de C++Buider. Analizaremos las propiedades, mtodos y eventos ms importantes de los principales componentes:

Form:
El formulario representa la ventana de una aplicacin. Un formulario, a su vez, puede contener otros componentes, como Button, Label, CheckBox, etc. Propiedades:

Programacin en C++ con C++Builder

Name: Representa el nombre lgico con el que se referencia al componente. Caption: permite modificar el texto del ttulo del formulario. Font: modifica el tipo de letra (fuente, estilo de fuente, tamao, etc.) de los componentes que estn contenidos en el formulario. Position: especifica la posicin del formulario. Puede ser por diseo, en el centro de la pantalla, centro del escritorio, etc. Height y Width: representan el alto y ancho del formulario en pixeles. Left y Top: posicin izquierda y superior del extremo superior izquierdo del formulario en pixeles. Eventos: OnCreate: este evento ocurre cuando el formulario se crea. OnShow: ocurre cuando el formulario es mostrado (cuando el propiedad Visible es True). OnActivate: ocurre cuando se activa el formulario (cuando el formulario recibe el foco). OnPaint: ocurre cuando el formulario es redibujado (redraw). Nota: al crearse un formulario, la creacin de este sigue esta secuencia de eventos mencionados, OnCreate, OnShow, OnActivate y On Paint. OnClose: ocurre cuando el formulario se cierra.

Button, BitBtn y SpeedButton:


Button es un botn estndar de Windows, mientras los que los otros amplan sus funcionalidades como permitir incluir un bitmap. Propiedades: Name: Representa el nombre lgico con el que se referencia al componente. Caption: permite modificar el texto del botn. Font: modifica el tipo de letra (fuente, estilo de fuente, tamao, etc.) del caption. Height y Width: representan el alto y ancho del botn en pixeles. Left y Top: posicin izquierda y superior del extremo superior izquierdo del botn relativa al del formulario en pixeles. Enabled: Habilita o deshabilita la respuesta del botn a eventos.

Programacin en C++ con C++Builder

Hint: es un pequeo texto que aparecer sobre el botn cuando el usuario coloque el mouse sobre el botn. Para que aparezca el Hint debe colocarse la propiedad ShowHint en valor True. Estas propiedades se encuentran en la mayora de los componentes visuales. Visible: determina cuando el botn aparece en el formulario. Glyph (slo en BitBtn y SpeedButton): permite especificar el bitmap que aparece en el botn. Kind (slo en BitBtn): determina el tipo de algunos bitmap predefinidos. Flat (slo en SpeedButton): hace desaparecer el efecto 3D de los botones. Down (slo en SpeedButton): especifica cuando el botn est presionado. Para quedar presionado la propiedad GroupIndex debe ser distinta de cero. TabOrder: especifica el orden en el que los componentes tendrn el foco. Sugerencia: probar cambiar el color de la fuente en todos los botones. Eventos: OnClick: ocurre cuando se hace click sobre el botn. OnMouseMove: ocurre cuando se mueve el mouse sobre el botn. Mtodos: SetFocus: coloca el foco en el botn.

Label:
Componente que permite mostrar texto en un formulario. Es usado para mostrar resultados e informacin al usuario, debido a que l no puede editarlo. No puede contener el foco en una aplicacin. Propiedades: Name: Representa el nombre lgico con el que se referencia al componente. Caption: permite modificar el texto del label (etiqueta). Font: modifica el tipo de letra (fuente, estilo de fuente, tamao, etc.) del caption. Alignment: permite especificar la alineacin del texto. Puede ser hacia la derecha, izquierda o centrada.

Edit:
Caja de edicin, que permite editar un texto de una sola lnea. Se utiliza para que el usuario introduzca informacin. Propiedades: Programacin en C++ con C++Builder 10

Name: Representa el nombre lgico con el que se referencia al componente. Text: es el texto asociado al edit. Font: modifica el tipo de letra (fuente, estilo de fuente, tamao, etc.) del caption. CharCase: permite especificar los caracteres en mayscula o minscula. MaxLength: cantidad mxima de caracteres que se pueden introducir. ReadOnly: especifica que el texto es de solo lectura. Eventos: OnChange: ocurre cuando le texto es modificado.

CheckBox y RadioButton:
Son componentes de seleccin. Se diferencian en que el primero permite seleccionar varias opciones simultneamente, mientras el segundo slo permite la seleccin de un nico elemento dentro de un mismo grupo. De ahora en adelante slo veremos las propiedades, mtodos y eventos que caracterizan a los componentes. Propiedades: Checked: especifica cuando el componente est seleccionado. Investigar: cmo puedo especificar diferentes grupos de RadioButton, de manera que me permitan seleccionar una opcin de cada grupo?

ListBox:
Es un componente que permite visualizar y manipular una lista de elementos (items). Propiedades: Items: contiene los elementos del ListBox; es del tipo TStrings (lista de strings). Esta clase, a su vez, contiene mtodos que permiten manipular elementos como agregar (Add), insertar (insert), eliminar (delete) y mover (move). Columns: especifica el nmero de columnas. MultiSelect: permite seleccionar varios elementos al mismo tiempo. Sorted: ordena automticamente los elementos alfabticamente. Mtodos: Clear: Borra todos los elementos del ListBox.

Programacin en C++ con C++Builder

11

Memo:
Es un componente estndar de Windows, que permite manipular texto multilnea, tanto para el ingreso por parte del usuario como informar textos de gran longitud. Propiedades: Lines: contiene los lneas de texto que estn contenida en el Memo; es del tipo TStrings (lista de strings), al igual que los tems del ListBox. ScrollBars: determina cuales barras de desplazamientos se van a mostrar. Mtodos: Clear: Borra el contenido del Memo.

Otros:
Una vez experimentado con estos componentes, se sugiere continuar investigando, otros como: MainMenu. ComboBox. Panel. StringGrid. Image. StatusBar. Timer.

Primera aplicacin
A continuacin, comenzaremos el acercamiento al programa con un clsico ejemplo sencillo y didctico (el viejo y conocido Hola Mundo) para explicar y mostrar qu parte de cdigo debemos escribir nosotros y qu parte de cdigo implementa por defecto C++Builder, y que por lo tanto no debemos escribir ni alterar. El objetivo del siguiente programa, es muy simple, solo mostrar en pantalla la frase Hola Mundo en el instante en que oprimamos el botn oprimir. En principio, veremos que al ejecutar una nueva aplicacin, automticamente se crea un formulario y una unit, la cual est asociada al formulario, por ello, cualquier cambio

Programacin en C++ con C++Builder

12

que hagamos al formulario, se reflejar en la unit asociada donde veremos que se ha agregado cdigo ante cualquiera de estas modificaciones. Los pasos iniciales: + Abrir una nueva Aplicacin. + Guardar el Proyecto: File/Save Project As, ubicar la carpeta donde ir guardado el proyecto, y guardar la Unit1 (asociada al formulario) con el nombre fHolaMundo (f para hacer referencia al formulario), y el Project1 con el nombre pHolaMundo. En el caso que nuestro programa requiera de una unit adicional, la misma se guardar con el nombre uNombreDelPrograma, donde u hace referencia a que la unit fue creada por el usuario. Los pasos para hacer el formulario son: 1. Formulario. a. Cambiar el Name a Hola. b. Cambiar el Caption del formulario por Hola Mundo. 2. Botn que muestra el Cartel a. Colocar un Botn (BitBtn). i. Cambiarle el Tamao. ii. Cambiar el Name a Boton. iii. Cambiar la Propiedad Kind seleccionando bkAll. iv. Cambiar la Propiedad Caption, sin borrar el carcter &, escribir Oprimir. El & subraya la letra que sigue a continuacin, esto habilita al botn a ejecutarse con las teclas Alt + o (letra subrayada). 3. Botn que Cierra el Programa. a. Colocar un Botn (BitBtn). i. Cambiarle el Tamao. ii. Cambiar el Name a Salir. iii. Cambiar la Propiedad Kind seleccionando bkClose. iv. Cambiar la Propiedad Caption, sin borrar el carcter &, escribir Salir. El & subraya la letra que sigue a continuacin, esto habilita al botn a ejecutarse con las teclas Alt + s (letra subrayada). 4. Etiqueta que mostrar el cartel. a. Colocar un Label. i. Cambiar el Name a Etiqueta.

Programacin en C++ con C++Builder

13

ii. Cambiar Font Name a Georgia y Font Size a 20. iii. Borrar el Caption. Para codificar los que harn los botones al oprimirse, hacer doble clic sobre los mismos, automticamente se genera el evento onclick del botn, es all donde debemos escribir. Ahora pasemos directamente a ver el cdigo. Lo que est escrito en azul es lo que Builder genera slo y en rojo lo que nosotros agregamos. Este es el fHolaMundo.h //----------------------------------------------------------#ifndef fHolaMundoH #define fHolaMundoH //----------------------------------------------------------#include <Classes.hpp> #include <Controls.hpp> #include <StdCtrls.hpp> #include <Forms.hpp> #include <Buttons.hpp> //----------------------------------------------------------class THola : public TForm { __published: // IDE-managed Components TBitBtn *Boton; TLabel *Etiqueta; TBitBtn *Salir; void __fastcall BotonClick(TObject *Sender); void __fastcall SalirClick(TObject *Sender); private: public: }; //----------------------------------------------------------Programacin en C++ con C++Builder 14 // User declarations // User declarations __fastcall TForm1(TComponent* Owner);

extern PACKAGE THola *Hola; //----------------------------------------------------------#endif Como podemos apreciar en este archivo no realizamos ninguna modificacin. Ahora veremos el fHolaMundo.cpp //----------------------------------------------------------#include <vcl.h> #pragma hdrstop #include "fHolaMundo.h" //----------------------------------------------------------#pragma package(smart_init) #pragma resource "*.dfm" THola *Hola; //----------------------------------------------------------__fastcall THola::THola(TComponent* Owner) : TForm(Owner) { } //----------------------------------------------------------void __fastcall THola::BotonClick(TObject *Sender) { Etiqueta->Caption="Hola Mundo"; } //----------------------------------------------------------void __fastcall THola::SalirClick(TObject *Sender) { Close();

Programacin en C++ con C++Builder

15

} //----------------------------------------------------------Como vemos en este archivo solo agregamos dos lneas y ya tenemos nuestro primer programa funcionando. A continuacin veremos cmo queda el formulario una vez ejecutado el programa y oprimido el botn Oprimir.

Programacin en C++ con C++Builder

16

Captulo 2: Programacin Orientada a Objetos (POO)


La idea bsica que soporta el enfoque OO es muy simple, percibimos al mundo como una variedad de objetos: televisores, lmparas y otros, pero cuando se enciende el televisor no se distingue entre sus elementos fsicos (tubo de pantalla, antena, etc.) y su comportamiento. Slo lo encendemos y seleccionamos un canal. Los objetos modelan las caractersticas y el comportamiento de los elementos del mundo en que vivimos, son la abstraccin de los datos ms acabada hasta el momento. En la POO el sistema se organiza alrededor de los atributos y no de las acciones, lo cual permite obtener sistemas ms estables ya que los datos tienen una vida til mayor que las funciones. En la POO las variables son activas, es decir, adems de tener propiedades tienen comportamiento y es el comportamiento el que hace que la variable sea activa en lugar de estar esperando que algn cdigo la manipule como las variables tradicionales. La POO encapsula los datos (atributos) y el comportamiento (mtodos) en paquetes llamados clases, las cuales son el la unidad bsica. Hay tres propiedades principales que caracterizan un lenguaje de POO, las cuales iremos describiendo ms adelante: Encapsulamiento Herencia. Polimorfismo.

La POO permite el ahorro de tiempo en el desarrollo de programas, promueve la reutilizacin de cdigo de alta calidad, probado y depurado, reduciendo as las posibilidades de errores. Como resumen podemos enunciar algunas de las grandes ventajas que posee Disminuye el tiempo de desarrollo de aplicaciones. Fcil mantenimiento Simple extensibilidad.

Clases (class).
Una clase es una abstraccin, que modela las caractersticas y comportamientos de un objeto, la cual debe incluir funcionalidades que permitan informar o modificar el estado de esa entidad, como as tambin, realizar diversas acciones para las cual fue diseado. Para el modelaje de esta clase, se debe determinar un conjunto de atributos que la definen, y un conjunto de funcionalidades que representan sus posibilidades de interaccin.

Programacin en C++ con C++Builder

17

Primero aprenderemos a definir una clase y luego veremos como podemos usarla creando un objeto, creando una clase derivada o como atributo de otra clase. La definicin de una clase se divide en dos partes, la declaracin de la cabecera y la implementacin (implementacin de los mtodos). La declaracin de la cabecera se realiza mediante la palabra reservada class. Una clase esta dividida en diferentes secciones, de acuerdo a la caracterstica determinante de sus miembros. Cada seccin esta encabezada por especificadotes de seccin, las cuales pueden ser: private: indica que los miembros pertenecientes podrn ser accedidos solamente dentro de la clase. public: indica que los miembros pertenecientes podrn ser accedidos tanto dentro de la clase como por otras clases. protected: indica que los miembros pertenecientes podrn ser accedidos dentro de la clase y por sus descendientes, pero son privados para otras clases. published: los miembros pertenecientes, son idnticos a public, pero adems toda propiedad ser visualizada en el inspector de objetos. La estructura es la siguiente: class NombreDeLaClase { private: tipo variable1; public: void Metodo1(void); void Metodo2(tipo variable2); tipo Metodo3(void); __property float Propiedad1 = {read = variable1, write = variable1}; }; Las palabras reservadas private y public son especificadores de acceso privado y publico respectivamente, es decir, todos los mtodos declarados en el rea publica podrn ser accedidos por cualquier clase, mientras los privados slo por la misma clase. Otros especificadores de acceso son protected, published, y automated. Se puede observar en esta estructura, que hemos declarado en la seccin privada una variable global y dos mtodos en la seccin pblica. Cada variable debe ser de un tipo, es decir, a un tipo de dato existente en C++Builder. Como puede ser float, double, int, etc. Tambin puede ser un tipo de dato definido por el programador. Adems una variable posee un nombre lgico que la representa variable1.

Programacin en C++ con C++Builder

18

En la declaracin de los mtodos, vemos que en el primer mtodo llamado Metodo1 se antepone la palabra reservada void la cual hace referencia que este mtodo no devuelve un ningn valor. Luego del nombre aparece encerrado entre parntesis la palabra reservada void que representa que el mtodo no recibe ningn valor como parmetro. El Metodo2, al igual que el anterior, no devuelve ningn valor, mientras que este recibe un parmetro un variable llamada variable2 del tipo de dato tipo. Para el Metodo3, este mtodo devuelve un valor del tipo de dato tipo, mientras no recibe ningn parmetro. Para la implementacin de los mtodos, se debe anteponer al nombre del mtodo el nombre de la clase con doble dos puntos (::) entre ellos, luego se encierra entre llaves ({ ...}) el cdigo que se va a ejecutar cuando sea llamado este mtodo. Podemos observar la implementacin del Metodo1: void NombreDeLaClase::Metodo1(void) { // cdigo } Por ltimo, la Propiedad1 tiene la misma funcionalidad que los mtodos que son capaces de escribir o leer valores en o desde los atributos de la clase, con la ventaja que no se tiene que implementar. Para definir qu variable va a leer o escribir, se debe escribir entre llaves las palabras reservadas read o write seguido del igual y el nombre del atributo sobre el que va a actuar. A continuacin, vamos a disear una clase que modele un rectngulo a la cual llamaremos TRectangulo, la cual debe poder calcular su superficie a partir de los lados. Primero debemos pensar que elementos caracterizan un rectngulo, con lo cual encontramos el ancho, el alto y la superficie. Luego, necesitamos mtodos que nos permitan manipular estos datos, para ello tenemos debemos incorporar los datos mediante los mtodos IngresarAncho e IngresarAlto, un mtodo que calcule la superficie llamado CalcularSup y por ltimo uno que devuelva o informe el valor de la superficie llamado InformarSup. Observacin: el modelado de una clase puede variar de un programador a otro, por lo que no existe una nica solucin posible, ni una sola solucin correcta. La declaracin de la cabecera clase se escribe como sigue: class TRegtangulo { private: float Ancho, Alto; float Superficie;

Programacin en C++ con C++Builder

19

public: void IngresarAncho(float Anchoi); void IngresarAlto (float Altoi); void CalcularSup(void); float InformarSup(void); }; La implementacin de los mtodos es: void TRegtangulo::IngresarAncho(float Anchoi); { Ancho = Anchoi; } void TRegtangulo::IngresarAlto (float Altoi); { Alto = Altoi; } void TRegtangulo::CalcularSup(void) { Superficie = Ancho * Alto; } float TRegtangulo::InformarSup(void) { return Superficie; } Para el mtodo CalcularSup se observa que se realiza la asignacin de las variables recibidas como parmetro a los atributos de la clase. Observacin: toda expresin debe terminar con un punto y coma (;).

En el mtodo CalcularSup realizamos el clculo de la superficie que la almacenamos en el atributo Superficie. Por ltimo en el mtodo InformarSup, devolvemos o retornamos el valor de superficie que hemos calculado, mediante la palabra reservada return.

Programacin en C++ con C++Builder

20

Diagrama de clase.
Un modelo sencillo, que nos ayuda a esquematizar una clase para acelerar su diseo, es el diagrama de clase. A su vez, nos permite interpretar rpidamente el diseo de una clase con una rpida lectura, con la particularidad de ser independiente del lenguaje con que se implemente la clase. Como observamos, el diagrama de clase se representa mediante un rectngulo, dividido en tres secciones: NombreDeLaClase, Atributos y Mtodos.

Para el ejemplo anterior, el diseo se observa en el diagrama de la derecha.

Constructor.
El mtodo constructor es un mtodo especial de la clase que permite inicializar atributos u otras variables necesarias de la clase. Este mtodo es invocado automticamente cuando se crea un objeto de esta clase. Posee algunas caractersticas importantes como: No retorna ningn valor (ni siquiera void). Puede recibir parmetros de cualquier tipo con excepcin de la misma clase (si un puntero). Para su declaracin se utiliza el mismo nombre que la clase.

Para continuar con el ejemplo anterior, supongamos que deseamos inicializar los valores del ancho y alto del rectngulo con los valores 10 y 20 respectivamente, y que realice el clculo de la superficie para estos valores. La declaracin del constructor se realiza en la parte pblica, como se observa: class TRegtangulo {

Programacin en C++ con C++Builder

21

private: float Ancho, Alto; float Superficie; public: TRectangulo(void); void IngresarAncho(float Anchoi); void IngresarAlto (float Altoi); void CalcularSup(void); float InformarSup(void); }; La implementacin del constructor, para realizar lo pedido es: TRectangulo::TRectangulo(void) { Ancho = 10; Alto = 20; // las dos expresiones anteriores // tambin se podran escribir como // IngresarDatos(10, 20); CalcularSup(void); }

Destructor.
Tambin se trata de un mtodo especial de una clase, pero que es invocado cuando se destruye un objeto de esta clase. En l se debe liberar toda memoria o recurso especial que se halla pedido la clase. Posee algunas caractersticas importantes como: No retorna ningn valor (ni siquiera void). No recibe parmetros. Para su declaracin se utiliza el smbolo ~ seguido por el mismo nombre que la clase. La declaracin del constructor se realiza en la parte pblica, como se observa: class TRegtangulo { private: float Ancho, Alto; float Superficie; public: TRectangulo(void); Programacin en C++ con C++Builder 22

~TRectangulo(void); void IngresarAncho(float Anchoi); void IngresarAlto (float Altoi); void CalcularSup(void); float InformarSup(void); }; La implementacin del constructor, para realizar lo pedido sera: ~TRectangulo::TRectangulo(void) { // no es necesario realizar nada para nuestro ejemplo }

Resumen de conceptos importantes:


Clase: es una abstraccin, que modela las caractersticas y el comportamiento de un conjunto de elementos del mundo real. Incluye informaciones relevantes sobre el estado de esa entidad, y las diversas reacciones que la misma puede desarrollar frente a estmulos. Atributo: es una propiedad, cualidad o caracterstica que define el estado de una clase. Usualmente, las clases poseen varios atributos, cuyos valores pueden cambiar con el tiempo. Funcionalidad o servicio de una clase: determina cmo la misma actuar o reaccionar bajo diversas solicitaciones. Encapsulamiento: es el agrupamiento de atributos y servicios dentro de una clase. Instancia u objeto: es una ocurrencia particular de una clase, es decir, es una instancia especfica de una clase. Evento: es un cambio en el entorno de una aplicacin, las cuales pueden ser capturadas por una aplicacin. Algunos eventos pueden ser: mover el mouse, presionar una tecla, hacer click o con doble click con el mouse, etc.

Cundo y porque modelamos una clase.


Un error comn, despus de haber terminado de estudiar la POO, es creer que toda implementacin o clculo debe ir dentro de una clase. En vez de ello se pueden declarar simplemente funciones que realicen acciones especficas. En C++Builder, existen funciones definidas que no pertenecen a ninguna clase (como IntToStr, FormatFloat, etc.) y existen funciones definidas dentro de clases, a las cuales llamamos mtodos. Entonces, cmo distinguimos cuando debemos modelar una clase? No es una pregunta que se pueda contestar fcilmente. Por ejemplo, si queremos saber la hora actual Programacin en C++ con C++Builder 23

del sistema no es necesario crear una objeto para que lo realice, sino simplemente implementar una funcin que llame al sistema preguntando la hora, como lo realiza la funcin Now(). Esta clase de acciones son directas y de vida corta. Recordemos que la creacin de un objeto siempre es ms lento y consume mayor cantidad de recursos que la simple llamada de una funcin. Entonces, para que construimos clases? Una clase es en esencia una estructura compleja cuya vida es dinmica, en la cual sus atributos van cambiando con el tiempo, pero siempre realizando una accin especfica. Por ejemplo, podramos tener una clase que se encargue de manejar el puerto serie. Entonces esta clase deber saber como abrir el puerto, configurarlo, leer y escribir datos en l, generar un mensaje cuando halla ledo un nuevo dato, etc. Vemos que las obligaciones de esta clase son complejas, pero con una accin especfica.

Encapsulamiento
Como definimos antes, el encapsulamiento es el agrupamiento de atributos y servicios dentro de una clase. Esto significa, que podemos comunicarnos con una clase a travs de sus interfaces bien definidas, pero no conocer como se encuentran implementadas. Aunque podramos conocer los detalles de su implementacin de una clase, no debe escribirse cdigo que dependa de ello, esto significa que la implementacin de una clase en particular puede ser modificada o reemplazada sin afectar al resto del sistema, siempre y cuando no cambie la interfaz public y published;

Herencia.
Una de las relaciones ms importantes entre clases es la herencia. Es uno de los pilares fundamentales de la POO, mediante la cual se produce la transmisin de atributos y funcionalidades de una clase a otra, lo cual trae aparejado grandes ventajas como la de reutilizacin de cdigo en la que se crean nuevas clases a partir de clases ya existentes por medio de la absorcin de sus atributos y comportamientos, sobreponindolos o mejorndolos con las capacidades que las nuevas clases requieran. La herencia, nos permite definir una clase modificando una o ms clases ya existentes. Estas modificaciones pueden consistir en aadir nuevos atributos y funcionalidades a la clase que se est definiendo, aunque tambin se pueden redefinir funcionalidades ya existentes. A partir de lo anterior, se deduce que existe una clase primitiva (ya existente) de la que partimos, a la cual llamaremos clase base o clase padre, y una nueva clase que definiremos, a la cual llamaremos clase derivada o clase hija. Esta clase hija, puede ser, a su vez, la clase padre de una o ms nuevas clases derivadas. Crendose de esta manera, una jerarqua de clases.

Programacin en C++ con C++Builder

24

Para especificar el uso de la herencia, despus del nombre de la clase hija, se agrega el operados dos puntos (:), seguido por un especificador de acceso y luego el nombre de la clase padre, como se observa: class NombreClaseHija: public NombreClasePadre { private: // public: // }; El especificador de acceso (en este caso public), describe la forma de acceso a los miembros heredados de la o las clases padres. Puede ser: Public: todos los miembros public de la clase base son miembros public de la clase derivada. Miembros protected de la clase base son miembros protected de la clase derivada. Miembros private de la clase base permanecen privados a la clase base. Protected: tanto los miembros public y protected de la clase base son miembros protected de la clase derivada. Miembros private de la clase base permanecen privados a la clase base. Private: tanto los miembros public y protected de la clase base son miembros private de la clase derivada. Miembros private de la clase base permanecen privados a la clase base. Resumiendo en una tabla: Identificador private protected public Miembros clase madre protected public protected public protected public Miembros clase hija private protected protected public

Nota: si no se especifica, por defecto el especificador de acceso es private. Nota: Cabe destacar que la clase base no debe ser modificada y esta debe modelar el objeto del problema para el cual fue diseada.

Programacin en C++ con C++Builder

25

Los miembros private de la clase base son siempre inaccesibles para los mtodos de la clase derivada a menos que se declare explcitamente que es un miembro friend en la clase base. No se tratar sobre miembros friend en este texto. Vamos a disear una clase que modele el volumen de un prisma a la cual llamaremos TPrisma. Para esta modelizacin recurriremos a la herencia que nos permitir reutilizar cdigo fuete ya existente. Si analizamos tridimensionalmente un prisma, podramos pensarlo como una caja, la cual consta de una base rectangular y posee una altura asociada, con la cual genera su volumen. Matemticamente podramos calcular su volumen (V) como el producto de la superficie de la base (S) por su altura (h). V=S*h Partimos as de tomar la clase antes diseada TRectangulo, la cual utilizaremos como clase base. A continuacin disearemos la clase hija. Diseando el diagrama de clase:

Programacin en C++ con C++Builder

26

class TPrisma : public TRectangulo{ private: float Altura; float Volumen; public: void IngresarAltura(float Alturai); void CalcularVolumen(void); float InformarVolumen(void); }; La implementacin de los mtodos es: void TPrisma::IngresarAltura(float Alturai); { Altura = Alturai; } void TPrisma::CalcularVolumen(void); { CalcularSup(); // Aqu llamamos al mtodo que calcula // la superficie de la base // perteneciente a la clase padre Volumen = InformarSup() * Altura; } float TPrisma::InformarVolumen(void); { return Volumen; } Es muy importante tener en cuenta que en la relacin de herencia publica, la clase hija hereda automticamente todo el contenido declarado en la parte publica en la clase madre y por ende puede utilizarla como si fuesen propios, pero a la parte privada slo se puede acceder a travs de sus mtodos. Veremos a continuacin, un segmento de cdigo que ejemplifica la implementacin del evento click de un botn del formulario, en el cual declaramos la instancia u objeto particular de la clase TPrisma.

Programacin en C++ con C++Builder

27

Nota: en la instanciacin, slo hacemos referencia a la clase hija, no se instancia la clase madre. void __fastcall TForm1::BotonClick(TObject *Sender) { TPrisma Prisma; Prisma.IngresarAncho = StrToFloat(Edit1->Text); Prisma.IngresarAlto = StrToFloat(Edit1->Text); Prisma.IngresarAltura = StrToFloat(Edit1->Text); Prisma.CalcularVolumen(); Label1->Caption = FloatToStr(Prisma.InformarVolumen()); }

Clases contenedoras.
El uso de clases contenedoras se centra en la idea que los objetos pueden estar formados (o contienen) a otros objetos, llamados objetos miembro. Los objetos miembro se convierten en atributos de nuestra nueva clase. Esta capacidad de contener a otros objetos tambin es llamada composicin. Llevando este concepto a la vida real, podemos pensar a los objetos como formados por piezas de distinta naturaleza que contribuyen a un mismo fin. Este es el caso del objeto auto, el cual esta compuesto por otros objetos que son parte integra de l, como son el objeto motor, rueda, volante, etc. Imaginemos ahora, un pndulo de un reloj bidimensional, como la conjuncin de un rectngulo (brazo del pndulo) y un crculo (peso del pndulo), al cual queremos calcular el rea. La clase contenedora TPendulo, contendr a las clases miembro TRectangulo y TCirculo. Para continuar con el concepto de reutilizacin de cdigo, utilizaremos a la clase TRectangulo antes definida y slo disearemos a la clase TCirculo y modelaremos la clase TPendulo. class TCirculo { private: float Radio; float Superficie;

Modelo bidimensional del pndulo de un reloj

Programacin en C++ con C++Builder

28

public: void IngresarRadio(float Radioi); void CalcularSup(void); float InformarSup(void); }; La implementacin de los mtodos es: void TCirculo::IngresarRadio(float Radioi); { Radio = Radioi; } void TCirculo::CalcularSup(void) { Superficie = M_PI * pow(Radio,2); } float TCirculo::InformarSup(void) { return Superficie; } Ahora implementamos la clase TPendulo: class TPendulo { private: TRectangulo Rect; TCirculo Circ; float Superficie; public: void IngresarRadioPeso(float Radioi); void IngresarLargoBrazo(float Largoi); void IngresarAnchoBrazo(float Anchoi); void CalcularSup(void); float InformarSup(void); }; La implementacin de los mtodos es:

Programacin en C++ con C++Builder

29

void TPendulo::IngresarRadioPeso(float Radioi) { Circ.IngresarRadio(Radioi); } void TPendulo::IngresarLargoBrazo(float Largoi) { Rect.IngresarLargo(Largoi); } void TPendulo::IngresarAnchoBrazo(float Anchoi) { Rect.IngresarAncho(Anchoi); } void TPendulo::CalcularSup(void) { Rect.CalcularSup(); Circ.CalcularSup(); Superficie = Rect.InformarSup() + Circ.InformarSup(); } float TPendulo::InformarSup(void) { return Superficie; } En este ejemplo de contencin se instanci las clases miembro en la parte privada de la clase (tambin se puede realizar en la parte publica, pero varia su implementacin). Se implementaron mtodos para ingresar los atributos, los cuales no se almacenaron en variables pertenecientes a esta clase, sino, se asignaron directamente a la clase contenida correspondiente. En el mtodo CalcularSup(), se llam a los mtodos CalcularSup() de cada una de las clases contenidas para que realicen el clculo de su superficie y dispongan su valor, para realizar la suma de ambas superficies.Registros (struct). Avanzado: Los objetos miembro se construyen en el orden en el que se declaran.

Programacin en C++ con C++Builder

30

Los registros son los predecesores de las clases. Permiten definir tipos de datos agregados que se construyen empleando elementos de otros tipos, es decir, una estructura es un conjunto de diferentes datos agrupados bajo una nica declaracin. Un ejemplo de esta definicin: struct Tiempo { int hora; int minutos; int segundos; }; En este ejemplo vemos que la palabra reservada struct define la estructura, que permitir crear instancias de ella. La palabra Tiempo es el nombre del tipo de estructura. Ahora podemos declarar instancias de esta estructura, de la forma: Tiempo Inicio; Y podemos asignar valores a sus elementos usando el nombre de la instancia seguido por . (punto), luego el nombre del elemento, igual como vimos su uso en clases, dado que las clases son una evolucin de las estructuras. Inicio.hora = 10; Inicio.minutos = 35; Inicio.segundos = 21;

Diferencia entre Registros y Clases.


Existe diferencia entre el uso de estructuras en C y C++, dado que en C, struct es un registro, es decir una estructura que permite almacenar datos de todo tipo y que permite crear distintas estructuras que almacenaran distintos datos. Ejemplo: siguiendo con la declaracin anterior del struct Tiempo, creamos dos struct diferentes, es decir dos estructuras de datos distintas y le asignamos valores distintos: Tiempo TInicial; Tiempo TFinal; TInicial.hora = 10; TInicial.minutos = 35; TInicial.segundos = 21; TFinal.hora = 15; TFinal.minutos = 10; TFinal.segundos = 59;

Programacin en C++ con C++Builder

31

En el caso de C++, los struct siguen existiendo, pero en ves de ser estructuras de datos o registros, fueron implementadas como clases, las cuales permiten ser instanciadas para crear objetos distintos partiendo de la declaracin inicial. El ejemplo es el mismo que para el struct de C, slo con una diferencia de concepto, es decir en C es un registro de datos y en C++ es una clase en donde todos sus elementos son de uso pblico (public).

Programacin en C++ con C++Builder

32

Captulo 3: Lgica de control


En la programacin, son necesarias herramientas que nos permitan hacer elecciones o tomar decisiones durante el proceso de ejecucin de nuestro programa, permitiendo seleccionar un camino entre una, dos o mas posibilidades diferentes. Para este uso, es que se hace uso de estructuras condicionales, que de acuerdo a una expresin lgica permitir tomar una decisin.

Expresin lgica.
Una expresin lgica es una combinacin de constantes, variables y funciones lgicas, con operadores lgicos y relacionales. Para comenzar a entender su uso, podemos definir una variables lgicas como una variable que puede contener slo dos valores posibles: verdadero (true o 1) o falso (false o 0). En C++ este tipo de variable se llama bool. Los operadores lgicos son aquellos que nos permiten concatenar o modificar expresiones lgicas, resultando un valor lgico. Ellos son: Operador ! && || Nombre not and or Operacin lgica negacin y lgico o lgico

Para entender mejor su uso, vamos a ver como trabajan a traves de un ejemplo. Supongamos que tenemos dos variables lgicas A y B. A 0 1 A 0 0 1 1 A B 0 1 0 1 B !A 1 0 A && B 0 0 0 1 A || B

Programacin en C++ con C++Builder

33

0 0 0 0 1 1 1 0 1 1 1 1 Los operadores relacionar relacionales son aquellos que nos permiten comparar dos valores, resultando un valor lgico. Ellos son: Operador > < <= >= != == Nombre mayor menor menor o igual mayor o igual distinto igual Operacin lgica mayor que menor que menor o igual que mayor o igual que distinta que igual que

Observacin: No hay que confundir el operador ==, con el operador =, dado que el primero significa comparacin, mientras el segundo asignacin. Vamos a ver como trabajan a travs de un ejemplo. Supongamos que tenemos tres variables A=5, B=5 y C=7. Expresin A>B A>=B A<=C A!=B A!=C A==B A==C Resultado 0 1 1 0 1 1 0

Estructura condicional if
Es una estructura simple que permite ejecutar una instruccin o un bloque de instrucciones slo si se cumple una expresin lgica, es decir, se ejecuta slo si el resultado de la expresin lgica es verdadero. if (expresin_lgica) {accin;}; Programacin en C++ con C++Builder 34

Si la expresin lgica es verdadera (o 1) la accin se ejecuta, si es falsa se ignora la accin y se continua con la instruccin siguiente a la estructura condicional. Si se quiere ejecutar una sola accin el uso de las llaves es opcional. Esta estructura tambin permite ejecutar una accin si no se cumple (else) la expresin lgica. Su estructura sera: if (expresin_lgica) {accin_1;} else {accin_2;}; En este caso, si la expresin lgica es verdadera (o 1) la se ejecuta la accin_1, si es falsa se ejecuta la accin_2. Ejemplificando: if (A > B) C = A - B; else C = A + B; En este ejemplo, de acuerdo al valor de A y B realizamos acciones diferentes. Muchas veces queremos comprobar el valor que posee una variable lgica, supongamos A, con la cual queremos realizar una accin slo si su valor es verdadero. En este caso se puede utilizar directamente esta variable como una expresin lgica y no es necesario realizar la comparacin con true, por ejemplo: if (A == true) C = A - B; if (A) C = A - B;

La expresin se evala como true, siempre y cuando la variable contenga cualquier valor distinto de cero. Esto se conoce como fundido de tipos (type casting), y es realizado automticamente por C++, reconociendo como falso al valor 0 y como verdadero a distinto de 0. Obsrvese en los ejemplos anteriores que el operador de igualdad tiene un doble signo de igual (==), en tanto que el operador de asignacin slo tiene uno (=). Uno de los errores comunes es el empleo del operador de asignacin cuando se quiere utilizar el de igualdad. Por ejemplo, si escribimos: if (x = 20) {accin}; En este caso se asigna a x el valor 20 y, como la operacin tendr xito, la expresin ser evaluada como true. Un error como este, aunque aparentemente obvio, puede ser difcil de localizar. Programacin en C++ con C++Builder 35

Las instrucciones if se pueden anidar en caso de ser necesario. Anidar no es ms que emplear una instruccin if como accin de seguida de una o ms instrucciones if adicionales: if (x > 10) if (x < 20) {accin};

Estructura condicional switch


La instruccin switch se podra considerar como una extensin de la instruccin if. Permitiendo ejecutar mltiples acciones evaluando una sola variable de control a la cual llamaremos selector, que de acuerdo a su valor en el instante que se evala corresponder la accin a ejecutar. Su sintaxis es: switch (selector) { case valor_1: {accion_1; break;} case valor_2: {accion_2; break;} ... case valor_n: {accion_n; break;} default: {accion_por_defecto;} } El selector debe ser una variable ordinal, es decir, una variable que posea una secuencia definida (ordenada) y acotada (finitas posibilidades), como puede ser una variable del tipo int, bool, cualquier tipo definido por el usuario, o el resultado de una expresin; siempre y cuando cumplan con la condicin. Cada uno de los valores de los casos para los cuales hemos definido una accin, deben corresponder a un valor que pertenece al tipo de dato del selector. Esta estructura tambin permite la definicin de una accin que se ejecutar por defecto si ninguno de los casos anteriores se cumple. Pero su definicin es opcional. En el caso de que un caso se cumpla, se ejecuta la accin definida para este caso hasta que se encuentra con la instruccin break, que es una instruccin que permite salir del bloque de cdigo que se esta ejecutando, en este caso del bloque switch. Si no lo encuentra, se seguirn ejecutando las acciones de los casos siguientes hasta terminar todos los casos o hasta encontrarse con un break. Debe notarse que la instruccin switch slo funciona cuado existe una igualdad entre el selector y alguno de los case, por lo que no ser de utilidad en el caso de situacin

Programacin en C++ con C++Builder

36

que impliquen desigualdad (> o <), tampoco para datos de tipo flotante dato que no poseen un secuencia bien definida. Vamos a ver dos ejemplos de su uso. En el primero queremos analizar la paridad de un nmero ingresado por el usuario, almacenando en una variable lgica (bool) llamada par: switch (num%2) { case 0: {par = true; break;} case 1: {par = false; break;} }; Se analizan solamente los casos 0 y 1 dado a que el resto de la divisin por 2 slo puede tomar estos valores. El mismo ejemplo se podra haber resuelto de tres formas ms sencillas, que dejamos ac para analizar: if (num%2 == 0) par = true; else par = false; if (!num%2) par = true; else par = false;

par = !bool(num%2)

Para el segundo ejemplo queremos determinar si un caracter es un vocal o no, y si es una vocal determinar cual. Vamos a analizar una variable caracter del tipo de dato llamado char que corresponde a un caracter, y devolveremos el resultado en una cadena de caracteres del tipo de datos AnsiString llamada Resultado: switch (caracter) { case a: {Resultado = es case e: {Resultado = es case i: {Resultado = es case o: {Resultado = es case u: {Resultado = es default: {Resultado = no es vocal;} }

la la la la la

vocal vocal vocal vocal vocal

a; e; i; o; u;

break;} break;} break;} break;} break;}

Programacin en C++ con C++Builder

37

Captulo 4: Estructuras Repetitivas


Normalmente dentro de un programa, es necesario realizar acciones de forma repetida, por ejemplo, imaginemos que queremos ejecutar 100 veces una accin, podramos escribir 100 veces la misma lnea o bien indicar que ejecute 100 veces la misma lnea. Para ello, se cre en el lenguaje de programacin, las estructuras for, while, y do while, que son las que nos permitirn codificar ciclos o bucles segn sea necesario. Primero, debemos saber que todo ciclo, tiene una condicin inicial, que inicia el ciclo, una condicin final, que, cuando se cumple, el bucle finaliza, y un cuerpo o bloque de cdigo que el ciclo realizar. El cuerpo contiene la instruccin que se ejecuta cada vez por medio del ciclo y puede incluir cualquier cdigo vlido en C++. Revisemos cada ciclo por separado:

Ciclo for.
La estructura for (para), se utiliza para realizar, generalmente, una accin cierta cantidad determinada y definida de veces. Para ello, consta de tres parmetros que debemos definir: Inicializacin, Condicin de salida Incremento

En la inicializacin, se procede a declarar una variable auxiliar, llamada variable de control, cuyo mbito de existencia y trabajo es dentro del ciclo, dndole un valor inicial, por ejemplo el valor uno. Para establecer la condicin de salida, se debe saber cuntas veces el ciclo debe ser repetido, y se procede a darle a la variable de control un valor final, siendo preferente determinarle el rango de trabajo, es decir, si deseo que la variable de control llegue al valor final diez, la sentencia de finalizacin sera i == 10 (en este caso el ciclo se ejecutar si la condicin es false), pero es preferente determinarle el rango de 1 a 10 haciendo i < = 10, mientras esta condicin se mantenga en true, el ciclo realizar la accin que el cuerpo determine, al momento de no cumplirse la condicin de salida, el programa sigue ejecutando la sentencia que sigue inmediatamente al cuerpo del ciclo. En sntesis, si como condicin de salida especifico un rango de la variable de control, el ciclo se ejecutar mientras esta condicin se mantenga en true, en cambio si especifico un valor preciso para la variable de control, el ciclo se ejecutar mientras sta se mantenga en false.

Programacin en C++ con C++Builder

38

Tambin, debo determinar la manera de incrementar la variable de control, es decir, especificar si i vara de uno en uno, dos en dos, u otra forma de incrementar. Estamos entonces en condiciones de presentar la estructura codificada de este ciclo. for (inicializacin; condicin de salida; incremento) {accin;}; Ejemplo: a continuacin, implementaremos una funcin, en la que se reproducir la funcin pow incluida en la librera math. int Potencia(int base, int exponente) { int resultado = 1; for (int i=1; i<=abs(exponente); i++) resultado = resultado * base; if(exponente < 0) resultado = 1/resultado; return resultado; } En este caso, es ciclo se ejecuta exponente cantidad de veces en forma repetitiva, evalundose siempre primero la condicin de salida, y en cada paso del ciclo, las variables puestas en juego toman los siguientes valores: Condicin Finalizacin ----true true true true true false i No existe 1 2 3 ... exponente No existe No existe Resultado 1 Base Base^2 Base^3 Base^exponente Base^exponente Depende del signo del exponente

Antes de entrar al for Primer paso Segundo paso Tercer paso exponente paso Saliendo del for Condicin if

Nota: La utilizacin de la variable i tiene su origen en el lenguaje FORTRAN y es tradicional en los ciclos for. Naturalmente, podemos usar cualquier nombre de variable, para la variable de control.

Programacin en C++ con C++Builder

39

Si fuera necesario contar o realizar el ciclo en forma descendente, se puede utilizar el conteo hacia abajo, como por ejemplo: int Potencia(int base, int exponente) { int resultado = 1; for (int i=abs(exponente); i>=1; i--) resultado = resultado * base; if(exponente < 0) resultado = 1/resultado; return resultado; } Es bueno recordar que el ciclo for acepta slo una sentencia, de manera tal que si se requiere realizar ms de una accin, debemos encerrar todo el bloque de cdigo del ciclo entre llaves (sentencia compuesta), por ejemplo: for (int i=10; i>=0; i--) { accin_1; accin_2; . . accin_n; }

Ciclo while
El ciclo while ("mientras") difiere del ciclo for en que slo contiene una condicin de prueba, que se verifica al principio de cada iteracin. Mientras la condicin sea true el ciclo contina funcionando. La sintxis correspondiente es: while (expresin_lgica) {accin_1; accin_2; . . accin_n;}; En la misma, la accin se realiza mientras la expresin lgica sea verdadera (valor distinto de cero). Es de vital importancia que la accin tenga alguna forma de modificar el valor de la expresin lgica, para que, en algn momento, sea falsa y el ciclo finalice. Si de entrada la expresin lgica da falsa, la accin del ciclo nunca se realiza. Veamos un ejemplo de la utilizacin de esta estructura, supongamos que obtener la potencia a la cual hay que elevar el nmero 2 para obtener el valor 1024.

Programacin en C++ con C++Builder

40

Hacemos: int x = 1024; int n; while (x >= 2){ n++; //n lo utilizo de contador x = x / 2; } Ahora, n guarda el valor de la potencia de 2 para obtener el valor 1024. Notamos nuevamente que el valor de la variable de control x, cambia dentro del propio ciclo, evitando que el ciclo se haga infinitamente.

Ciclo do-while.
Este ciclo es prcticamente igual al while. Sin embargo, la diferencia entre los dos es importante, ya que el ciclo while evala la expresin condicional al principio del ciclo; en el caso de do-while ("hacer mientras"), la expresin se evala al final del propio ciclo. La sintaxis de este bucle es: do {accin;} while (exprlgica); Debido a la manera como funciona el ciclo do-while, el cdigo en el cuerpo del ciclo se ejecuta al menos una vez, sin importar el valor de la condicin de prueba (ya que se evala al final del ciclo). En el caso del while, la condicin se evala al principio, por lo que es posible que nunca se ejecute el cuerpo del ciclo. Tambin en este caso, la modificacin de la expresin lgica debe ser explcita en el bloque de cdigo, para que el ciclo finalice en algn momento, cuando la expresin condicional resulte falsa. Un ejemplo sera: int x = 1024; int n; do {x = x / 2; n++;} while (x > 1);

Programacin en C++ con C++Builder

41

Donde n, guarda nuevamente la potencia a la que hay que elevar el valor 2 para obtener el nmero 1024. Es un error comn, que se trate de realizar una accin en el do que no se pueda realizar, es decir, hay que tener en cuenta que como el ciclo siempre se ejecuta al menos una vez, no debemos por ejemplo implementar en el cuerpo del do, una accin imposible tal como el la divisin por cero, por ejemplo. Para ver ms grficamente el error, analizaremos un cdigo errneo para ejemplificar. float float do {y x x = 0; y; = 512 / x; //error al tratar de dividir por cero!!! = x + 2.0;} //acumulo en x el valor anterior de x ms 2 //x en este caso es un acumulador while (y != 1);

Instrucciones break y continue


Antes de terminar el tema de los ciclos, haremos referencia a dos palabras clave que ayudan a controlar la ejecucin del ciclo en el programa. La instruccin continue se emplea para forzar la ejecucin del programa hasta el final del ciclo, saltando cualquier expresin situada despus de continue. La instruccin break se usa para detener la ejecucin de un ciclo antes de que se cumpla la condicin de prueba normal del ciclo. Existen muchas situaciones cuando las instrucciones continue y break son tiles. Al igual que gran parte de los temas desarrollados, requerir cierta experiencia de programacin en C++ para descubrir todos los posibles usos de estas dos instrucciones. De todas maneras, a continuacin veremos la utilizacin de la palabra clave break en un ciclo for, el cual utilizaremos de modo particular, y el condicional if. Para ello, es necesario saber que el puerto paralelo, posee tres partes: data, control y status, y, supongamos que en nuestro programa, necesitamos leer un pin (bit) del control de nuestro puerto paralelo, que nos dar la confirmacin de que podemos leer los 8 bits de data. Utilizaremos dos funciones genricas (estas funciones no estn implementadas, son slo a modo de ejemplo) una para leer un bit del control a la que llamaremos LeerBitControl (suponemos que esta funcin devuelve true si se puede leer el puerto data), y una que nos permitir leer el data, que llamaremos LeerDato(suponemos que esta funcin devuelve el valor entero del dato ledo). Programacin en C++ con C++Builder 42

for(;;){ if(LeerBitControl())break; } int x = LeerDato(); En este caso, el for se utiliza a modo de delay o retardo hasta que llegue la confirmacin de lectura del puerto. Avanzado: verificar que si al for le falta alguno o varios de sus parmetros, tambin funciona, si utilizamos la sentencia break.

En el caso que consideremos usar un bit de status para que haga comenzar o detenga la adquisicin del dato, segn sea true o false. int x=0; for(;;){ if(LeerBitStatus())break; for(;;){ if(LeerBitControl())break; } x += LeerDato(); } Para ejemplificar el uso de la instruccin continue, podemos considerar el caso anterior, haciendo la salvedad de que el siguiente ejemplo es un ciclo infinito, y es slo a modo de ejemplo. int x=0; while(!detener){ if(LeerBitStatus())continue; for(;;){ if(!LeerBitControl())break; } x += LeerDato(); }

Programacin en C++ con C++Builder

43

Captulo 5: Vectores y Matrices


Se hace evidente que a lo largo de un programa, necesitamos guardar informacin, o bien, trabajar con informacin que debemos almacenar en distintas estructuras. De esta necesidad, surgen un tipo de estructura de datos llamados genricamente como arreglo (array). De esta manera, surgen los vectores que son arreglos unidimensionales y las matrices que son arreglos multidimensionales.

Declaracin
Para declarar vectores y matrices, la sintaxis es la siguiente, primero se define el tipo de dato que almacenar este arreglo, luego el nombre que le asignaremos a dicho arreglo y entre corchetes la cantidad de elementos de cada dimensin, si el arreglo es un vector, la sintaxis es: int NombreDelVector[5]; En cambio si el arreglo es bidimensional, o matriz de dos dimensiones, la sintaxis es: int NombreDeLaMatriz[45][20]; El nmero entre corchetes indica la cantidad de valores del tipo que se indican, NO es el subndice del mayor elemento. Adems todos los subndices comienzan en cero, es decir el primer valor del vector es en la posicin cero, y el ltimo es en n-1 (en el caso anterior, n-1=5-1=4). Observemos de manera esquemtica como sera la asignacin de memoria por parte del compilador: Vector[0] Valor int A Vector[1] Valor int B Vector[2] Valor int C Vector[3] Valor int D Vector[4] Valor int E

Teniendo en cuenta que cada int requiere 4 bytes de almacenamiento, el arreglo completo ocupar 20 bytes en la memoria. De manera anloga, para la matriz bidimensional, asignamos memoria para M*N nmeros enteros (en total 4*45*20 = 3600 bytes). Para referirse a cada elemento de un vector unidimensional se utiliza un ndice, recordando que el primer elemento tiene ndice [0]. Para las matrices o arreglos ndimensionales se requieren tantos subndices como dimensiones tenga el espacio en el que estemos trabajando.

Programacin en C++ con C++Builder

44

Hay que prestar atencin especial a no sobreescribir el final de un arreglo. Una caracterstica poderosa de C++ es el acceso directo a memoria; debido a ella, C++ no nos impide escribir a una ubicacin determinada de la memoria, aunque sea una posicin a la que se supone que no debe tener acceso el programa que estamos elaborando. El siguiente cdigo es vlido, pero producir la detencin del programa: int vector[5]; vector[5]=31; Este es un error que se comete frecuentemente, dado que los arreglos tienen base 0. Podramos pensar que el ltimo elemento del arreglo es 5, cuando en realidad es 4. Es posible solicitar que, automticamente, se verifique que los ndices se encuentren dentro del rango de la definicin del arreglo, activando la directiva de compilacin $R, accediendo a Project options/Pascal/Range checking. Hay una diferencia notable entre el ndice de un elemento de un vector (que es siempre de tipo entero), y el valor contenido en la posicin del vector marcada por el ndice, que puede ser de cualquier tipo (entero, flotante, booleano, etc.).

Ejemplo. Ejemplo 1.
Se desea crear un objeto que contenga una matriz cuadrada de 23 elementos lgicos, llenada al azar. La matriz debe poder ser visualizada en pantalla y tambin se debe poder intercambiar los 1 lgicos por la letra T y los 0 lgicos por la letra F. Veremos el cdigo del archivo uMatriz.h. class TDeterminar { private: bool m[23][23]; public: void Generar(void); bool Informar(int i, int j); };

//uMatriz.cpp

Programacin en C++ con C++Builder

45

void TDeterminar::Generar(void) { int i, j; randomize(); for(i=0; i<24;i++) for(j=0; j<24;j++) m[i][j]=random(2); } bool TDeterminar::Informar(int i, int j) { return m[i][j]; } Ahora veremos los archivos asociados al formulario. // fMatriz.h class TDeterminacion : public TForm { __published: // IDE-managed Components TStringGrid *Grilla; TBitBtn *BitBtn1; TBitBtn *BitBtn2; TBitBtn *BitBtn3; void __fastcall BitBtn1Click(TObject *Sender); void __fastcall BitBtn2Click(TObject *Sender); void __fastcall BitBtn3Click(TObject *Sender); void __fastcall FormDestroy(TObject *Sender); private: public: // User declarations // User declarations TDeterminar D; //Aqu instanciamos la clase __fastcall TDeterminacion(TComponent* Owner); }; // fMatriz.cpp

Programacin en C++ con C++Builder

46

__fastcall TDeterminacion::TDeterminacion(TComponent* Owner) : TForm(Owner) { Grilla->Visible=false; } //----------------------------------------------------------void __fastcall TDeterminacion::BitBtn1Click(TObject *Sender) { D.Generar(); Grilla->Visible=True; int i,j; for(i=0;i<24;i++) for(j=0;j<24;j++) Grilla->Cells[i][j]=IntToStr(D.Informar(j,i)); } //----------------------------------------------------------void __fastcall TDeterminacion::BitBtn2Click(TObject *Sender) { int i,j; for(i=0;i<24;i++) for(j=0;j<24;j++) if(D.Informar(i,j)) Grilla->Cells[j][i]='T'; else Grilla->Cells[j][i]='F'; } //----------------------------------------------------------void __fastcall TDeterminacion::BitBtn3Click(TObject *Sender) { Close(); }

Programacin en C++ con C++Builder

47

//----------------------------------------------------------El uso de randomize() y random() estn explicado en el apndice.

Ejemplo 2.
Implemente una clase que contenga un vector de 3700 elementos reales. Implemente mtodos para ingresar los valores del vector y para poder mostrar un elemento particular del vector. A su vez, implemente un mtodo que permita llenar al azar el vector con valores entre 500 y 1000. Adems la clase debe poder informar el valor mximo y mnimo del vector y sus posiciones. Veamos el cdigo. //uVector.h //----------------------------------------------------------#ifndef uVectorH #define uVectorH //----------------------------------------------------------class TVector{ private: float v[3700]; float maximo; float minimo; int posi_maxi; int posi_mini; public: void llenar_vector(); void ingresar_valor(int i,float val); float ver_valor(int i); void search_max_min(); int largo_vector(); __property float ver_max={read=maximo}; __property float ver_min={read=minimo}; __property int pos_max={read=posi_maxi}; __property int pos_min={read=posi_mini};

Programacin en C++ con C++Builder

48

};

//uVector.cpp //----------------------------------------------------------#include <vcl.h> #pragma hdrstop #include "uVector.h" #include <math.h> //----------------------------------------------------------#pragma package(smart_init) void TVector::llenar_vector(){ randomize(); for (int i=0;i<sizeof(v)/sizeof(float);i++) v[i] = 500+500*random(RAND_MAX)*1.0/RAND_MAX; }; void TVector::ingresar_valor(int i,float val){ v[i]=val; }; void TVector::search_max_min(){ maximo=v[0]; minimo=v[0]; posi_maxi=0; posi_mini=0; for (int i=1;i<sizeof(v)/sizeof(float);i++){ if (v[i]>maximo) { maximo=v[i]; Programacin en C++ con C++Builder 49

posi_maxi=i; } if (v[i]<minimo) { minimo=v[i]; posi_mini=i; } } }; float TVector::ver_valor(int i) { return v[i]; }; int TVector::largo_vector() { return sizeof(v)/sizeof(float); }; //fVector.h //----------------------------------------------------------#ifndef fVectorH #define fVectorH //----------------------------------------------------------#include <Classes.hpp> #include <Controls.hpp> #include <StdCtrls.hpp> #include <Forms.hpp> #include <Buttons.hpp> #include <ComCtrls.hpp>

Programacin en C++ con C++Builder

50

#include <Grids.hpp> #include "uVector.h" //----------------------------------------------------------class TForm1 : public TForm { __published: // IDE-managed Components TBitBtn *IngresarValor; TBitBtn *VerValor; TEdit *Valor; TLabel *Label1; TLabel *Label2; TEdit *Posicion; TUpDown *UpDown1; TLabel *VisorValor; TBitBtn *LlenarAzar; TStringGrid *Grilla; TBitBtn *BuscarMaxMin; TMemo *Visor; TBitBtn *Salir; void __fastcall SalirClick(TObject *Sender); void __fastcall LlenarAzarClick(TObject *Sender); void __fastcall IngresarValorClick(TObject *Sender); void __fastcall VerValorClick(TObject *Sender); void __fastcall BuscarMaxMinClick(TObject *Sender); void __fastcall FormCreate(TObject *Sender); private: public: // User declarations // User declarations TVector vec; __fastcall TForm1(TComponent* Owner); }; //----------------------------------------------------------extern PACKAGE TForm1 *Form1;

Programacin en C++ con C++Builder

51

//-----------------------------------------------------#endif //fVector.cpp //----------------------------------------------------------#include <vcl.h> #pragma hdrstop #include "fVector.h" #include "uVector.h" //----------------------------------------------------------#pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; //----------------------------------------------------------__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //----------------------------------------------------------void __fastcall TForm1::SalirClick(TObject *Sender) { Close(); } //----------------------------------------------------------void __fastcall TForm1::LlenarAzarClick(TObject *Sender) { vec.llenar_vector(); for (int i=0;i<vec.largo_vector();i++) Grilla->Cells[1][i] = FormatFloat("###0.00",vec.ver_valor(i)); } //-----------------------------------------------------------

Programacin en C++ con C++Builder

52

void __fastcall TForm1::IngresarValorClick(TObject *Sender) { if(Valor->Text != "") { vec.ingresar_valor(StrToInt(Posicion->Text)-1, StrToFloat(Valor->Text)); Grilla->Cells[1][StrToInt(Posicion->Text)-1]=Valor->Text; } else ShowMessage(AnsiString("Ingrese un Valor")); } //----------------------------------------------------------void __fastcall TForm1::VerValorClick(TObject *Sender) { VisorValor->Caption=FormatFloat("###0.00", vec.ver_valor(StrToInt(Posicion->Text)-1)); } //----------------------------------------------------------void __fastcall TForm1::BuscarMaxMinClick(TObject *Sender) { Visor->Clear(); vec.search_max_min(); Visor->Lines->Add("El valor mnimo es " + FormatFloat("###0.00",vec.ver_min)); Visor->Lines->Add("en la posicin " +

IntToStr(vec.pos_min+1)); Visor->Lines->Add("");

Programacin en C++ con C++Builder

53

Visor->Lines->Add("El valor mximo es " + FormatFloat("###0.00",vec.ver_max)); Visor->Lines->Add("en la posicin } //----------------------------------------------------------void __fastcall TForm1::FormCreate(TObject *Sender) { for(int i=0;i<vec.largo_vector();i++) Grilla->Cells[0][i]=i+1; } //----------------------------------------------------------Por ltimo, veremos el formulario del programa ejecutndose. " +

IntToStr(vec.pos_max+1));

Programacin en C++ con C++Builder

54

Observacin.
Como vemos, hemos instanciado la clase en la parte pblica de la clase Tform1, lo cual nos permitir poder hacer uso de esa instancia en cualquiera de los bloques de cdigo del cpp, sin importar a qu botn o elemento visual pertenezca esa codificacin. Es decir el mbito de existencia esta instancia es todo el cpp, es una instancia global.

Programacin en C++ con C++Builder

55

Captulo 6: Cadenas de caracteres


Una cadena de caracteres se puede definir como una secuencia o un vector de caracteres, que estn agrupados bajo un mismo nombre. Existen varias formas de manipular las cadenas de caracteres, por que vamos a definir primeramente el tipo de datos char, lo cual nos va a permitir entender el resto de los tipos.

char
Es un tipo de dato que permite definir un carcter de la tabla ASCII (Anexo I). Esta tabla es una tabla de correspondencia entre un caracter y un nmero asociado al mismo entre 0 y 255. En este ejemplo definimos un variable llamada Caracter a la cual le asignamos el mismo caracter A de dos maneras diferentes: char Caracter = A; char Caracter = 65;

c-string
Es un arreglo de caracteres, es decir, es una cadena de caracteres que se define en forma de un vector de caracteres. Esta definicin es heredada del lenguaje c aunque su uso ha disminuido. Pero conserva algunas ventajas como son su simpleza y el menor recurso ocupado. Se definicin tiene la forma: Char Nombre[longitud]; Donde Nombre es el nombre de la variable que definimos y longitud es la cantidad de caracteres que va a contener. En este ejemplo, vemos que se permite asignarle toda una cadena de forma directa. char Cadena[12] = Computacion; Nota: es importante diferenciar cuando se asigna un carcter a una variable se utiliza comillas simple (A), mientras para las cadenas se utilizan comillas dobles (Computacin) Tambin se puede realizar la asignacin a cada caracter: Cadena[2] = n;

Programacin en C++ con C++Builder

56

Cadena[3] = P; // ahora cadena vale ConPutacin Hay que recordar que al igual que los vectores el primer elemento es el 0 (cero).

c++ string
Es una clase asociada a un arreglo de caracteres que posee mtodos para su manipulacin. Para su utilizacin no es necesario especificar la longitud en la definicin, dado que se puede modificar en forma dinmica con la asignacin de una nueva cadena. string Cadena = Bioingenieria; Esta clase es muy flexible y prctica, aunque no la vamos a desarrollar dado que C++Buider posee su propia definicin de cadena de caracteres que veremos a continuacin.

AnsiString
Es una clase especialmente diseada para la manipulacin de cadenas de caracteres definida por Borland. Su definicin tiene la forma: AnsiString Cadena = Bioingenieria; Nota: es importante diferenciar que en la cadena c++string el subndice del primer caracter es el 0 (cero), mientras que para AnsiString es el 1 (uno).

Esta clase define varios mtodos que facilitan la manipulacin de las cadenas, entre las cuales se destacan (los ejemplos son siempre sobre la cadena original Bioingenieria):

Delete(pos, cant) Permite borrar una cantidad (cant) de caracteres de la propia cadena a partir de una posicin (pos) Cadena.Delete(1, 3); // Cadena = ingenieria SubString(pos, cant) Devuelve una nueva cadena que es una subcadena de la propia. La subcadena contiene cant caracteres y comienza desde pos. Sub = Cadena.SubString(6, 2); // Sub = ge

Programacin en C++ con C++Builder

57

Length() Devuelve la longitud (el nmero de bytes) de la cadena int Longitud = Cadena.Length(); // Longitud = 13

Insert(subcadena, pos) Inserta una subcadena en nuestra cadena en la posicin pos. SubCad = Super; Cadena.Insert(Subcad, 1); // Cadena = SuperBioingenieria

SetLength(cant) Cambia la longitud de la cadena a la especificada por cant. Si la cant es menor que la longitud de la cadena, entonces la trunca, es decir, borra todos los caracteres desde la posicin cant+1 en adelante. Si cant es mayor a la longitud, el contenido de los caracteres restantes es incierto. Cadena.SetLength(10); // Cadena = Bioingenie

Pos(subcadena) Devuelve la posicin del inicio donde se encuentra la subcadena dentro de la cadena original. Si la cadena no posee la subcadena retorna el valor 0 (cero). Si la cadena posee repetida la subcadena dentro de ella, devuelve la posicin del primero. int posicion = Candena.Pos(in); LowerCase() Devuelve la cadena en minscula. AnsiString cad = Cadena.LowerCase(); // cad = bioingenieria UpperCase(); Devuelve la cadena en mayscula. AnsiString cad = Cadena.UpperCase(); // cad = BIOINGENIERIA // posicion = 4

Programacin en C++ con C++Builder

58

Ejemplos Ejemplo 1
Disear una funcin que informe si un nmero dado es capica o no. Para disear esta funcin, primero pensamos en que parmetros debe recibir y cuales debe informar. Como dice el enunciado de nuestro problema, debemos recibir un nmero entero (int) que vamos a analizar e informar una variable lgica (bool) que indique si es capica o no. Nuestra funcin quedara: bool EsCapicua (int numero); Existen varias formas de resolver este problema, vamos a desarrollar aqu una sencilla mediante el uso de cadenas de caracteres. La idea principal es convertir la el nmero de entrada en una cadena, luego en una cadena auxiliar vamos copiando carcter por carcter en forma inversa, y al final comparamos estas dos cadenas para ver si son iguales. bool EsCapicua (int numero) { bool capicua = false; AnsiString Num = IntToStr(numero); AnsiString NumInv = ; for (int i=Num.Length(); i>=1; i--) { NumInv += Num.SubString(i,1); } if (Num == NumInv) capicua = true; return capicua; }

Ejemplo 2
Disear una funcin que cuente la cantidad de palabras que se encuentran en una cadena de caracteres. De nuevo debemos pensar primero los parmetros de entrada y de salida de nuestra funcin. La entrada es una cadena de caracteres (AnsiString) y como salida un numero entero (int) que represente la cantidad de palabras.

Programacin en C++ con C++Builder

59

int CantidadPalabras (AnsiString cadena); Para resolver nuestro problema, pensemos en que cada palabra esta separada por un espacio, entonces contando la cantidad de espacios que hay en la cadena, representar la cantidad de palabras -1, es decir, a la cantidad de espacios hay que sumar 1. Para contar la cantidad de espacios realizamos un ciclo, mientras exista un espacio en blanco, incrementamos un contador y lo borramos. Para poder saber si existe un espacio en blanco, hacemos uso del mtodo pos de la clase AnsiString, dado que cuando la cadena contenga un espacio el valor devuelto ser mayor a cero. Veamos como se hace: int CantidadPalabras (AnsiString cadena) { int cant = 0; AnsiString cad = cadena; while (cad.Pos( ) > 0) { cant++; cad.Delete(cad.Pos( ), 1); } return ++cant; } En la funcin anterior se podra obviar la comparacin mayor a cero, dado que cualquier valor distinto de cero en la condicin ser considerado como verdadero, cuyo efecto es el mismo. La ltima sintaxis ++cant se realiza para de esta forma dado que queremos que primero se incremente la variable cant y luego se retorne. Si analizamos un poco mas profundo esta resolucin, veremos que tiene varios problemas al resolver casos especiales. Estos son: cuando la cadena de entrada esta vaca nos dice que tiene una palabra, si tenemos dos palabras separadas por dos espacios nos dice que tenemos tres palabras, si existe un espacio al principio o al final tambin cuanta estos como palabras. Como hacemos para eliminar estos espacios que no deberan ser contados? Para el primer debemos verificar si el primer carcter es un espacio si es as, lo borramos. Pero se debe hacer tantas veces como espacios en blancos contenga. Para eso implementamos un ciclo que, mientras el primer carcter sea igual al espacio en blanco, lo borre. Para los espacios del final, se resuelve de manera igual, mientras el ltimo carcter sea igual al espacio en blanco, lo borre. Para el caso de los espacios repetidos entre dos palabras, una vez encontrado la ubicacin del espacio, borramos en esa misma posicin hasta que no posea espacios en blanco en ese lugar.

Programacin en C++ con C++Builder

60

La implementacin queda as: int CantidadPalabras (AnsiString cadena) { int cant = 0; int posi; AnsiString cad = cadena; if (cad.Length()) { while (cad[1] == ' ') cad.Delete(1,1); while (cad[cad.Length()] == ' ') cad.Delete(cad.Length(),1); while (cad.Pos(' ')) { cant++; posi = cad.Pos(' '); cad.Delete(posi, 1); while (cad[posi] == ' ') cad.Delete(posi,1); } cant++; } return cant; }

Programacin en C++ con C++Builder

61

Captulo 7: Archivos de Texto.


Hasta ahora hemos visto cmo procesar informacin, y hemos mantenido el flujo de entrada / salida de informacin a travs de componentes visuales. Pero muchas veces la informacin necesaria, de entrada o salida, se presentar en estructuras de datos llamadas archivos, almacenadas en nuestro disco rgido. Es por ello, que en este captulo nos centraremos en el manejo del flujo de entrada / salida de informacin desde y hacia el HD. Los archivos de texto tienen la capacidad de almacenar caracteres de la tabla ASCII, y su nombre fsico (nombre con el cul est almacenado en el HD) tiene el mismo formato que cualquier otro archivo, a saber: NombreFsico.extensin, por ejemplo el archivo de texto Leame.txt, su nombre es Leame y su extensin es txt (de texto). No necesariamente el archivo de texto debe tener la extensin txt, puede poseer cualquier otra extensin. Los archivos de texto, poseen algunos caracteres especiales dentro de l, que normalmente no son visibles cuando se abre el archivo con un editor de texto, pero que nos permiten delimitarlo. Ellos son: el caracter de fin de lnea y el caracter de fin de archivo (EOF, end of file) Para manipular los archivos, C++ nos presenta una jerarqua de clases especialmente diseadas para ello. Donde nos concentraremos en dos de ellas: ifstream para manipular archivos de entrada de datos y ofstream para manipular archivos de salida de datos. Existen algunas operaciones bsicas que se realizan sobre los archivos, estas son: Creacin del objeto. Apertura del archivo. Manipulacin del archivo. Cierre del archivo.

Creacin del objeto.


Para la creacin del objeto debemos declarar una variable cuyo tipo es algunas de las clases nombradas. Por ejemplo, si queremos un trabajar con un archivo de entrada de datos, declaramos: ifstream ArchivoEnt; Si el archivo fuera de salida de datos, declaramos: ofstream ArchivoSal;

Programacin en C++ con C++Builder

62

Apertura del archivo.


La apertura de un archivo establece la conexin entre el nombre lgico y el nombre fsico de nuestro archivo, abre el archivo y lo prepara para su manipulacin. Esto se puede realizar de dos maneras, la primera es a travs del mtodo open: void open(const char *nombre_archivo, openmode modo); Este mtodo puede recibir dos parmetros, el primero es una cadena de caracteres que representa el nombre fsico del archivo que ser abierto, y opcionalmente puede recibir un segundo parmetro que representa al modo que se abrir. Puede ser alguna de las siguientes opciones: ios::in ios::out ios::ate ios::app ios::nocreate ios::noreplace ios::trunc ios::binary Abre el archivo para lectura Abre el archivo para escritura Abre un archivo existente y se posiciona al final Abre un archivo de salida para agregar al final Abre un archivo slo si ya existe. Abre un archivo slo si no existe. Abre un archivo, si ya existe borra todo su contenido Abre un archivo en modo binario. Por defecto es modo texto.

Estas opciones se pueden combinar utilizando el operador or |, pero no todas las combinaciones son posibles. Un ejemplo seria: ArchivoSal.open(datos.txt, ios::out | ios::app); Como dijimos anteriormente, el modo de apertura es un parmetro opcional del mtodo, dado que de acuerdo a la clase hayamos creado el objeto, posee un modo de apertura por defecto. Estos son: Clase ofstream ifstream fstream Modo por defecto ios::out | ios::trunc ios::in ios::in | ios::out

La segunda manera de abrir un archivo, es combinndola con la creacin del objeto. Esto se puede realizar gracias a que el constructor de estas clases puede recibir el nombre del archivo fsico como parmetro y realiza internamente la llamada al mtodo open. ifstream ArchivoEnt(datos.txt);

Programacin en C++ con C++Builder

63

Cierre del archivo.


Como se abra dado cuenta nos salteamos, el apartado correspondiente a la manipulacin del archivo. Esto lo hacemos dado que es la parte ms compleja, y preferimos dejarlo para el final. Al terminar la manipulacin del archivo, se debe cerrar el vnculo que hemos creado con nuestro archivo fsico, para liberarlo y permitir que otros programas (o procesos) puedan usarlo. A dems se realizan otras acciones internas como liberar la memoria de un buffer creado, terminar de escribir sobre el archivo (dado que esta accin se realiza de a bloques), etc. Esta accin se realiza mediante la llamada al mtodo close(). ArchivoEnt.close(); Una vez cerrado el archivo, este objeto esta disponible para abrir nuevamente otro archivo o ser destruido. El cierre del archivo tambin se realiza de forma automtica cuando el objeto es destruido. Esto se debe a que el destructor de la clase verifica si existe un archivo abierto, y si es as, llama al mtodo close().

Manipulacin del archivo.


Con este trmino nos referimos, a la accin de leer o escribir sobre un archivo. A pesar de que estas acciones son simples, se pueden armar estructuras complejas de acuerdo a la necesidad de cada problema. Estas acciones, se pueden realizar mediante operadores o llamadas a mtodos.

Operadores de lectura / escritura


Existen dos operadores: 1. Operador de insercin: << Este operador permite insertar o escribir dentro del archivo un texto. El texto puede ser una cadena de caracteres o no, gracias a que estas clases saben realizar la conversin de tipo de forma automtica. Vamos a ver algunos ejemplos: Cdigo ejemplo Archivo salida

En este primer ejemplo vemos como se inserta una simple cadena de caracteres a un archivo de texto tipo ofstream llamado ArchivoSal ArchivoSal << alumno; alumno

Programacin en C++ con C++Builder

64

En el siguiente ejemplo, vemos que podemos realizar el mismo efecto insertando el contenido de la variable Texto. string Texto = Hola ArchivoSal << Texto; Hola

En este ejemplo, vemos que se pueden realizar inserciones sucesivas de dentro de una misma fila, con la separacin de un carcter de espacio que se realiza de forma automtica. Al final de cada rengln agregamos endl para insertar un caracter de fin de lnea, para movernos a la siguiente lnea. string Texto = Hola; ArchivoSal << Texto << 1 << endl; ArchivoSal << Texto << 2 << endl; Hola1 Hola 2

Ahora vemos que podemos tambin realizar la insercin del contenido una variable entera, cuyo contenido se convierte de forma automtica en una cadena de caracteres. A dems se puede observar otra forma de insertar el caracter de fin de lnea agregando \n int num = 1; ArchivoSal << num << Hola\n; Num++; ArchivoSal << num << Hola\n; 1Hola 2 Hola

Por ltimo vamos a mostrar un ejemplo completo, con muchas combinaciones de guardado, para que analicen la salida. string Texto1 = "Hola"; string Texto2 = "Mundo"; int num = 1; Archi << Texto1 << Texto2 << endl; Archi << Texto1 << " " << Texto2 << endl; Archi << num << num++ << endl; Archi << num << " " << num++ << endl; Archi << num++ << " " << num << endl; Archi << Texto1 << num << "\n"; Archi << num++ << Texto2 << endl; HolaMundo Hola Mundo 21 3 2 3 3 Hola4 4Mundo

Programacin en C++ con C++Builder

65

2. Operador de extraccin: >> Este operador permite extraer el contenido de archivo un texto. Este operador extrae todo el contenido de la cadena y se lo asigna a nuestra variable hasta que encuentra un caracter de espacio o de fin de lnea. Similar al anterior, el texto puede ser una cadena de caracteres o no, gracias a que estas clases saben realizar la conversin de tipo de forma automtica, la conversin se realizar de acuerdo al tipo de dato de la variable que definamos. Vamos a ver algunos ejemplos: Archivo entrada variables

Cdigo ejemplo

En este primer ejemplo vemos como extrae una simple cadena de caracteres de un archivo de texto tipo ifstream llamado ArchivoEnt. string Texto; ArchivoEnt >> Texto; alumno Texto = alumno

En este par de ejemplos, vemos como el mismo cdigo permite leer cadenas de caracteres sucesivos independientes que estn separadas por un caracter de espacio o de fin de lnea. string Texto1, Texto2; ArchivoEnt >> Texto1 >> Texto2; string Texto1, Texto2; ArchivoEnt >> Texto1 >> Texto2; alumno1 alumno2 Texto1 = Texto2 = alumno1 alumno2 Texto1 = Texto2 = alumno1 alumno2

alumno1 alumno2

Ahora vemos que tambin podemos extraer la informacin independiente de que este sea un entero. Dado que la segunda extraccin la hacemos sobre una variable del tipo int, la conversin se realiza automticamente. Hay que tener cuidado que el dato a leer sea un entero, dado que C++ realiza la lectura igualmente pudindose obtener informacin errnea. int num; string Texto; ArchivoEnt >> Texto >> num; alumno 1 Texto = alumno num = 1

Programacin en C++ con C++Builder

66

Mtodos de lectura / escritura


Como dijimos anteriormente, la lectura y escritura de datos tambin se puede realizar mediante llamadas a mtodos de la clase. Veamos cuales son: get() y getline(): Estos mtodos permiten realizar la lectura de toda una lnea, hasta que encuentra un caracter de terminacin. Reciben tres parmetros. El primero es un puntero a un vector de caracteres (buffer), el segundo el tamao del vector, y el tercero (opcional) el caracter de terminacin. Por defecto este caracter es el \n, llamado caracter de fin de lnea. Si el primer caracter de la lnea es el carcter de terminacin, devuelven un vector de longitud cero. Pero su gran diferencia radica, en que el mtodo get() se detiene, y una segunda llamada al mtodo devuelve el mismo resultado, hasta que se cambie el caracter de terminacin. En cambio, una segunda llamada al mtodo getline() devuelve la siguiente lnea, por lo que normalmente se utiliza este mtodo. Otra diferencia radica en que el mtodo get() puede ser llamado sin ningn parmetro. En este caso devuelve el caracter siguiente. Para aclarar un poco el tema, vamos a ver algunos ejemplos: Cdigo ejemplo Archivo entrada Archivo salida

En este primer ejemplo vemos una simple lectura de una cadena de caracteres de un archivo llamado entrada.txt y su escritura en el archivo salida.txt. char buff[10]; alumno ifstream ArchiEnt("entrada.txt"); alumno ofstream ArchiSal("salida.txt"); ArchiEnt.getline(buff, 10); ArchiSal << buff << endl; Ahora la diferencia de leer el texto de una lnea que posee ms caracteres que los que pedimos leer. Veremos la diferencia de la implementacin con la funcin get() y con getline(). char buff[10]; ifstream ArchiEnt("entrada.txt"); ofstream ArchiSal("salida.txt"); ArchiEnt.getline(buff, 10); ArchiSal << buff << endl; ArchiEnt.getline(buff, 10); ArchiSal << buff << endl; Alumno que no piensa no aprueba Alumno qu Alumno qu

Programacin en C++ con C++Builder

67

char buff[10]; ifstream ArchiEnt("entrada.txt"); ofstream ArchiSal("salida.txt"); ArchiEnt.get(buff, 10); ArchiSal << buff << endl; ArchiEnt.get(buff, 10); ArchiSal << buff << endl;

Alumno que no piensa no aprueba Alumno qu e no pien

Ahora vemos que pasa cuando se tiene una lnea vaca. Aclaramos que en la salida del segundo ejemplo, hay dos lneas vacas. char buff[10]; ifstream ArchiEnt("entrada.txt"); ofstream ArchiSal("salida.txt"); for (int i=1; i<=3; i++) { ArchiEnt.get(buff, 10); ArchiSal << buff << endl; } char buff[10]; ifstream ArchiEnt("entrada.txt"); ofstream ArchiSal("salida.txt"); for (int i=1; i<=3; i++) { ArchiEnt.get(buff, 10); ArchiSal << buff << endl; } Alumno no aprueba Alumno no aprueb Alumno no aprueba Alumno

Ahora veremos como hacemos si queremos leer una lnea y asignrselo directamente a una variable del tipo string, no es tan simple como parece. Para resolver el problema hacemos uso de tres funciones de la clase string. La funcin begin() que nos devuelve un puntero al primer caracter de la cadena. Para especificar la cantidad de caracteres a leer podemos colocar simplemente un nmero que lo indica, si sabemos que las lneas del archivo no superan ese valor, o usar la funcin max_size() que nos devuelve la mxima cantidad de caracteres que soporta la clase string; a este valor hay que dividirlo por 2, dado que es el doble que el mximo valor del entero (int) que pide como parmetro la funcin. Por ltimo, hay que utilizar la funcin c_str() para que nos devuelva el valor de la cadena contenida. string Texto; ifstream ArchiEnt("entrada.txt"); ofstream ArchiSal("salida.txt"); ArchiEnt.getline(Texto.begin(), Alumno que no piensa Alumno que no piensa

Programacin en C++ con C++Builder

68

Texto.max_size()/2); ArchiSal << Texto.c_str() << endl; Hay que destacar que el mtodo getline, escribe directamente en una porcin de memoria del string, que contiene la cadena c_string sin modificar ninguna de las propiedades de la clase string. Es por ello, que al querer escribir en un archivo se debe especificar que se desea escribir el contenido c_str() del string, dado que si quiero escribir directamente el string, como no se modificaron sus propiedades, la longitud de la cadena es cero, y por lo tanto virtualmente la cadena esta vaca. Una forma de forzar a que se actualicen las propiedades del string, es realizar una asignacin de su propio contenido: string Texto; ifstream ArchiEnt("entrada.txt"); ofstream ArchiSal("salida.txt"); ArchiEnt.getline(Texto.begin(), Texto.max_size()/2); Texto = Texto.c_str(); ArchiSal << Texto << endl; Alumno que no piensa Alumno que no piensa

La verdad es que parece un poco complejo, y poco recomendable leer una simple lnea de longitud indeterminada con el mtodo anterior. Por suerte, existe una funcin llamada getline() que realiza este procedimiento de forma ms simple. Remarcamos que es una funcin y no un mtodo como el que vimos antes. Esta funcin recibe un primer parmetro que es un ifstring, el segundo es un string, y opcionalmente puede recibir un tercer parmetro que es el carcter de terminacin. Esta funcin esta especialmente diseada para leer string, por lo que no es necesario especificar el largo de la cadena. string Texto; ifstream ArchiEnt("entrada.txt"); ofstream ArchiSal("salida.txt"); getline(ArchiEnt, Texto); ArchiSal << Texto << endl; Alumno que no piensa Alumno que no piensa

Programacin en C++ con C++Builder

69

Mtodos especiales
eof() Es uno de los mtodos ms importantes. Devuelve true si se lleg al final de archivo. Encontr el carcter EOF (End Of File). is_open() Este mtodo devuelve true si se abri correctamente el archivo. good() Este mtodo devuelve true si no ocurri ningn error. bad() Este mtodo devuelve true si ocurri algn error con el buffer. fail() Este mtodo devuelve true si ocurri algn error que no afecte al buffer.

Ejemplos Ejemplo 1
Implementar una funcin que lea un archivo de texto llamado Datos.txt, que contiene un nmero indeterminado de nmeros ordenados en columna, y devuelva su promedio. Para resolverlo debemos realizar un ciclo que lea lnea por lnea cada uno de los nmeros, los vaya sumando y contando la cantidad de datos ledos, y por ltimo calcule e informe el resultado. float PromedioDatos() { float x, suma = 0; int cont = 0; ifstream Archivo(Datos.txt); while (!Archivo.eof()) { Archivo >> x; suma += x;

Programacin en C++ con C++Builder

70

cont++; } return suma/cont; }

Ejemplo 2
Implementar una funcin que lea un archivo de texto llamado Lineas.txt, que contiene un nmero indeterminado de renglones, que contiene frases, y devuelva la cantidad lneas que contienen la palabra casa. Para resolverlo debemos realizar un ciclo que lea lnea por lnea cada uno de los renglones, busque la palabra casa y los cuente, y por ltimo informe el resultado. float CantidadCasas() { int cont = 0; string s; AnsiString Linea; ifstream Archivo(Lineas.txt); while (getline(Archivo, s)) { Linea = s.c_str(); if (Linea.Pos(casa) cont++; } return cont; }

Programacin en C++ con C++Builder

71

ANEXO I: Tabla de caracteres ASCII

ASCII: American Standard Code for Information Interchange.

Programacin en C++ con C++Builder

72

ANEXO II: funciones


Dado que muchos de nuestros programas pueden requerir de acciones comunes (como conversin de tipo de datos o generar un numero al azar), C++ Builder provee una gran cantidad de funciones ya implementadas disponibles para su uso, ms una interfase a una gran cantidad de funciones del sistema operativo (API). A continuacin comentaremos algunas de las funciones ms comunes, agrupadas por la accin que realizan.

Conversiones de tipo
Este es el grupo ms utilizado, dado que permite convertir un tipo de dado a otro. IntToStr: permite convertir un nmero entero (int) a una cadena de caracteres (AnsiString). StrToInt: permite convertir una cadena de caracteres (AnsiString) a un nmero entero (int). FloatToStr: permite convertir un nmero flotante (float o double) a una cadena de caracteres (AnsiString). StrToFloat: permite convertir una cadena de caracteres (AnsiString) a un nmero flotante (float o double). FormatFloat: permite convertir un nmero flotante (float o double) a una cadena de caracteres (AnsiString) con un determinado formato. El formato permite especificar la cantidad de decimales, etc. AnsiString FormatFloat(AnsiString Fomato, Extended numero);

Funciones matemticas
pow: permite calcular la potencia de un nmero. double pow(double base, double exponente); random: permite generar un nmero al azar entre 0 y el nmero especificado menos uno. int random(int numero); randomize: permite inicializar el generador de nmeros aleatorios con un valor aleatorio. Esta funcin puede ser llamada al comenzar el programa o antes de comenzar a generar nmeros aleatorio con la funcin random. sqrt: permite calcular la raiz cuadrada de un nmero dado.

Programacin en C++ con C++Builder

73

double sqrt(double numero); floor: redondea un nmero flotante hacia abajo, es decir, el mayor nmero entero no mayor al nmero dado. double floor(double numero); ceil: redondea un nmero flotante hacia arriba, es decir, el menor nmero entero no menor al nmero dado. double ceil(double numero);

Programacin en C++ con C++Builder

74

Вам также может понравиться