SlideShare una empresa de Scribd logo
1 de 47
Descargar para leer sin conexión
Programación en C++ con C++Builder 1
Programación en C++
con
C++Builder
Versión de borrador N°3
Año 2004
Angel A. Zeitoune
(azeitoune@yahoo.com.ar)
y
Ricardo A. Rettore
(ricadorettore@yahoo.com.ar)
* Esta es una versión borrador, cualquier duda o sugerencia por favor escribir a cualquiera
de los autores.
Programación en C++ con C++Builder 2
Introducción.
Este curso es fruto de la experiencia profesional y la acción pedagógica de varios
años de docencia de los autores. Es por esta última, que luego de una incansable búsqueda
de algún libro que permitiese aprender a programar en C++ al mismo tiempo que enseñase
a utilizar como herramienta a C++Builder, y dada su carencia en el mercado, decidimos
desarrollarlo.
C++Builder es herramienta de desarrollo rápido de aplicaciones (RAD, rapid
application development) para Windows, en lenguaje de C++, que posee varias
características importantes, lo cual facilita el desarrollo de aplicaciones gráficas.
Queremos aclarar que en este curso, no se pretende la enseñanza a fondo de las
herramientas de programación C++Builder. Se presenta una breve introducción a su uso y
conocimientos mínimos para lograr el aprendizaje del lenguaje.
Programación en C++ con C++Builder 3
Capítulo 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 diseñar, 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 aplicación, que a su vez puede
contener a otros objetos componentes (objetos).
Editor de Código (Code Editor): aparece, inicialmente, atrás del formulario. Es un
editor de texto avanzado que contiene el código fuente del programa.
Programación en C++ con C++Builder 4
Ventana Principal (main window): Contiene la barra de título, el menú principal,
barra de acceso rápido (SpeedBar), y la paleta de componentes (Component palette).
Inspector de Objetos (Object Inspector): esta dividido en dos páginas, propiedades
y eventos, las cuales están asociadas al componente seleccionado.
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.
También podremos incluir a nuestro proyecto, nuevos formularios, units, módulos
de datos, archivos de texto, etc. con la opción 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.
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 según sus extensiones:
Extensión
Contenido
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).
Programación en C++ con C++Builder 5
.h Archivo de cabecera. Contiene la declaración de la clase.
.cpp Archivo fuente de C++. Implementación del archivo .h,
Usualmente tenemos uno por cada unit y uno por el proyecto
principal.
.dfm Archivos del formulario. Es un archivo de texto que contiene
características de los elementos visuales.
.bpr Archivo de proyecto
.exe Programa ejecutable.
.res Archivo de recursos. Se guardan en este archivo el icono de
nuestra aplicación entre otras cosas.
.obj Archivo objeto. Es un archivo binario que produce el
compilador de nuestro proyecto antes de armar el ejecutable.
.tds Tabla simbólica de depuración.
.~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 páginas 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 botón
izquierdo del mouse sobre el formulario, dando el tamaño deseado al mismo.
El inspector de objetos nos presenta las propiedades y eventos asociados a los
elementos que componen la interfaz gráfica.
Analizaremos las propiedades, métodos y eventos más importantes de los
principales componentes:
Avanzado: Los componentes, están conformados en una biblioteca visual de
componentes (Visual Component Library), llamada VCL, que se basa en modelo de
propiedades, métodos y eventos (PME). La VCL es una jerarquía de clases escrita en
Object Pascal asociada al IDE de C++Buider.
Programación en C++ con C++Builder 6
Form:
El formulario representa la ventana de una aplicación. Un formulario, a su vez,
puede contener otros componentes, como Button, Label, CheckBox, etc.
Propiedades:
Name: Representa el nombre lógico con el que se referencia al componente.
Caption: permite modificar el texto del título del formulario.
Font: modifica el tipo de letra (fuente, estilo de fuente, tamaño, etc.) de los
componentes que están contenidos en el formulario.
Position: especifica la posición del formulario. Puede ser por diseño, 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: posición 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).
OnClose: ocurre cuando el formulario se cierra.
Button, BitBtn y SpeedButton:
Button es un botón estándar de Windows, mientras los que los otros amplían sus
funcionalidades como permitir incluir un bitmap.
Propiedades:
Name: Representa el nombre lógico con el que se referencia al componente.
Caption: permite modificar el texto del botón.
Font: modifica el tipo de letra (fuente, estilo de fuente, tamaño, etc.) del caption.
Height y Width: representan el alto y ancho del botón en pixeles.
Nota: al crearse un formulario, la creación de este sigue esta secuencia de eventos
mencionados, OnCreate, OnShow, OnActivate y On Paint.
Programación en C++ con C++Builder 7
Left y Top: posición izquierda y superior del extremo superior izquierdo del botón
relativa al del formulario en pixeles.
Enabled: Habilita o deshabilita la respuesta del botón a eventos.
Hint: es un pequeño texto que aparecerá sobre el botón cuando el usuario coloque el
mouse sobre el botón. Para que aparezca el Hint debe colocarse la propiedad ShowHint en
valor “True”. Estas propiedades se encuentran en la mayoría de los componentes visuales.
Visible: determina cuando el botón aparece en el formulario.
Glyph (sólo en BitBtn y SpeedButton): permite especificar el bitmap que aparece en
el botón.
Kind (sólo en BitBtn): determina el tipo de algunos bitmap predefinidos.
Flat (sólo en SpeedButton): hace desaparecer el efecto 3D de los botones.
Down (sólo en SpeedButton): especifica cuando el botón está presionado. Para
quedar presionado la propiedad GroupIndex debe ser distinta de cero.
TabOrder: especifica el orden en el que los componentes tendrán el foco.
Eventos:
OnClick: ocurre cuando se hace click sobre el botón.
OnMouseMove: ocurre cuando se mueve el mouse sobre el botón.
Métodos:
SetFocus: coloca el foco en el botón.
Label:
Componente que permite mostrar texto en un formulario. Es usado para mostrar
resultados e información al usuario, debido a que él no puede editarlo. No puede contener
el foco en una aplicación.
Propiedades:
Name: Representa el nombre lógico 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, tamaño, etc.) del caption.
Alignment: permite especificar la alineación del texto. Puede ser hacia la derecha,
izquierda o centrada.
Sugerencia: probar cambiar el color de la fuente en todos los botones.
Programación en C++ con C++Builder 8
Edit:
Caja de edición, que permite editar un texto de una sola línea. Se utiliza para que el
usuario introduzca información.
Propiedades:
Name: Representa el nombre lógico con el que se referencia al componente.
Text: es el texto asociado al edit.
Font: modifica el tipo de letra (fuente, estilo de fuente, tamaño, etc.) del caption.
CharCase: permite especificar los caracteres en mayúscula o minúscula.
MaxLength: cantidad máxima 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 selección. Se diferencian en que el primero permite seleccionar
varias opciones simultáneamente, mientras el segundo sólo permite la selección de un único
elemento dentro de un mismo grupo.
De ahora en adelante sólo veremos las propiedades, métodos y eventos que
caracterizan a los componentes.
Propiedades:
Checked: especifica cuando el componente está seleccionado.
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 métodos que permiten manipular elementos como agregar
(Add), insertar (insert), eliminar (delete) y mover (move).
Columns: especifica el número de columnas.
MultiSelect: permite seleccionar varios elementos al mismo tiempo.
Sorted: ordena automáticamente los elementos alfabéticamente.
Investigar: cómo puedo especificar diferentes grupos de RadioButton, de manera
que me permitan seleccionar una opción de cada grupo?
Programación en C++ con C++Builder 9
Métodos:
Clear: Borra todos los elementos del ListBox.
Memo:
Es un componente estándar de Windows, que permite manipular texto multilínea,
tanto para el ingreso por parte del usuario como informar textos de gran longitud.
Propiedades:
Lines: contiene los líneas de texto que están 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.
Métodos:
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.
Programación en C++ con C++Builder 10
Capítulo 2: Programación Orientada a Objetos (POO)
La idea básica que soporta el enfoque OO es muy simple, percibimos al mundo
como una variedad de objetos: televisores, lámparas y otros, pero cuando se enciende el
televisor no se distingue entre sus elementos físicos (tubo de pantalla, antena, etc.) y su
comportamiento. Sólo lo encendemos y seleccionamos un canal.
Los objetos modelan las características y el comportamiento de los elementos del
mundo en que vivimos, son la abstracción de los datos más 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 más estables ya que los datos tienen una vida útil mayor que las
funciones.
En la POO las variables son activas, es decir, además de tener propiedades tienen
comportamiento y es el comportamiento el que hace que la variable sea activa en lugar de
estar esperando que algún código la manipule como las variables tradicionales.
La POO encapsula los datos (atributos) y el comportamiento (métodos) en paquetes
llamados clases, las cuales son el la unidad básica.
Hay tres propiedades principales que caracterizan un lenguaje de POO, las cuales
iremos describiendo más adelante:
• Encapsulamiento
• Herencia.
• Polimorfismo.
La POO permite el ahorro de tiempo en el desarrollo de programas, promueve la
reutilización de código 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.
• Fácil mantenimiento
• Simple extensibilidad.
Clases (class).
Una clase es una abstracción, que modela las características y comportamientos de
un objeto, la cual debe incluir funcionalidades que permitan informar o modificar el estado
de esa entidad, como así también, realizar diversas acciones para las cual fue diseñado.
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 interacción.
Programación en C++ con C++Builder 11
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 definición de una clase se divide en dos partes, la declaración de la cabecera y la
implementación (implementación de los métodos).
La declaración de la cabecera se realiza mediante la palabra reservada class. Una
clase esta dividida en diferentes secciones, de acuerdo a la característica determinante de
sus miembros. Cada sección esta encabezada por especificadotes de sección, las cuales
pueden ser:
• private: indica que los miembros pertenecientes podrán ser accedidos solamente
dentro de la clase.
• public: indica que los miembros pertenecientes podrán ser accedidos tanto dentro de
la clase como por otras clases.
• protected: indica que los miembros pertenecientes podrán ser accedidos dentro de la
clase y por sus descendientes, pero son privados para otras clases.
• published: los miembros pertenecientes, son idénticos a public, pero además 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);
};
Las palabras reservadas private y public son especificadores de acceso
privado y publico respectivamente, es decir, todos los métodos declarados en el área
publica podrán ser accedidos por cualquier clase, mientras los privados sólo por la misma
clase. Otros especificadores de acceso son protected, published, y automated.
Se puede observar en esta estructura, que hemos declarado en la sección privada una
variable global y dos métodos en la sección pública.
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. También puede ser un tipo de
dato definido por el programador. Además una variable posee un nombre lógico que la
representa variable1.
En la declaración de los métodos, vemos que en el primer método llamado
Metodo1 se antepone la palabra reservada void la cual hace referencia que este método
Programación en C++ con C++Builder 12
no devuelve un ningún valor. Luego del nombre aparece encerrado entre paréntesis la
palabra reservada void que representa que el método no recibe ningún valor como
parámetro.
El Metodo2, al igual que el anterior, no devuelve ningún valor, mientras que este
recibe un parámetro un variable llamada variable2 del tipo de dato tipo.
Para el Metodo3, este método devuelve un valor del tipo de dato tipo, mientras
no recibe ningún parámetro.
Para la implementación de los métodos, se debe anteponer al nombre del método el
nombre de la clase con doble dos puntos (::) entre ellos, luego se encierra entre llaves ({
...}) el código que se va a ejecutar cuando sea llamado este método. Podemos observar la
implementación del Metodo1:
void NombreDeLaClase::Metodo1(void)
{
// código
}
Para aclarar este concepto vamos a diseñar una clase que modele un rectángulo a la
cual llamaremos TRectangulo, la cual debe poder calcular su superficie a partir de los
lados.
Primero debemos pensar que elementos caracterizan un rectángulo, con lo cual
encontramos el ancho, el alto y la superficie. Luego, necesitamos métodos que nos permitan
manipular estos datos, para ello tenemos debemos incorporar los datos mediante los
métodos IngresarAncho e IngresarAlto, un método que calcule la superficie
llamado CalcularSup y por último uno que devuelva o informe el valor de la superficie
llamado InformarSup.
La declaración de la cabecera clase se escribe como sigue:
class TRegtangulo {
private:
float Ancho, Alto;
float Superficie;
public:
void IngresarAncho(float Anchoi);
void IngresarAlto (float Altoi);
void CalcularSup(void);
float InformarSup(void);
Observación: el modelado de una clase puede variar de un programador a otro, por
lo que no existe una única solución posible, ni una sola solución correcta.
Programación en C++ con C++Builder 13
};
La implementación de los métodos 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 método CalcularSup se observa que se realiza la asignación de las
variables recibidas como parámetro a los atributos de la clase.
En el método CalcularSup realizamos el cálculo de la superficie que la
almacenamos en el atributo Superficie.
Por último en el método InformarSup, devolvemos o retornamos el valor de
superficie que hemos calculado, mediante la palabra reservada return.
Diagrama de clase.
Un modelo sencillo, que nos ayuda a esquematizar una clase para acelerar su diseño,
es el diagrama de clase. A su vez, nos permite interpretar rápidamente el diseño de una
clase con una rápida lectura, con la particularidad de ser independiente del lenguaje con que
se implemente la clase.
Observación: toda expresión debe terminar con un punto y coma (;).
Programación en C++ con C++Builder 14
Como observamos, el diagrama de clase se representa mediante un rectángulo,
dividido en tres secciones: NombreDeLaClase, Atributos y Métodos.
Para el ejemplo anterior, el diseño se observa en el diagrama de la derecha.
Constructor.
El método constructor es un método especial de la clase que permite inicializar
atributos u otras variables necesarias de la clase. Este método es invocado automáticamente
cuando se crea un objeto de esta clase. Posee algunas características importantes como:
• No retorna ningún valor (ni siquiera void).
• Puede recibir parámetros de cualquier tipo con excepción de la misma clase (si un
puntero).
• Para su declaración 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 rectángulo con los valores 10 y 20 respectivamente, y que
realice el cálculo de la superficie para estos valores.
La declaración del constructor se realiza en la parte pública, como se observa:
class TRegtangulo {
private:
float Ancho, Alto;
float Superficie;
public:
TRectangulo(void);
Programación en C++ con C++Builder 15
void IngresarAncho(float Anchoi);
void IngresarAlto (float Altoi);
void CalcularSup(void);
float InformarSup(void);
};
La implementación del constructor, para realizar lo pedido es:
TRectangulo::TRectangulo(void)
{
Ancho = 10;
Alto = 20;
// las dos expresiones anteriores
// también se podrían escribir como
// IngresarDatos(10, 20);
CalcularSup(void);
}
Destructor.
También se trata de un método 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 características importantes como:
• No retorna ningún valor (ni siquiera void).
• No recibe parámetros.
• Para su declaración se utiliza el símbolo ~ seguido por el mismo nombre que la clase.
La declaración del constructor se realiza en la parte pública, como se observa:
class TRegtangulo {
private:
float Ancho, Alto;
float Superficie;
public:
TRectangulo(void);
~TRectangulo(void);
void IngresarAncho(float Anchoi);
void IngresarAlto (float Altoi);
void CalcularSup(void);
float InformarSup(void);
Programación en C++ con C++Builder 16
};
La implementación del constructor, para realizar lo pedido sería:
~TRectangulo::TRectangulo(void)
{
// no es necesario realizar nada para nuestro ejemplo
}
Resumen de conceptos importantes:
Clase: es una abstracción, que modela las características 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 estímulos.
Atributo: es una propiedad, cualidad o característica 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 cómo 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 específica de una clase.
Evento: es un cambio en el entorno de una aplicación, las cuales pueden ser
capturadas por una aplicación. Algunos eventos pueden ser: mover el mouse, presionar una
tecla, hacer click o con doble click con el mouse, etc.
Cuándo y porque modelamos una clase.
Un error común, después de haber terminado de estudiar la POO, es creer que toda
implementación o cálculo debe ir dentro de una clase. En vez de ello se pueden declarar
simplemente funciones que realicen acciones específicas.
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 métodos.
Entonces, cómo distinguimos cuando debemos modelar una clase? No es una
pregunta que se pueda contestar fácilmente. Por ejemplo, si queremos saber la hora actual
del sistema no es necesario crear una objeto para que lo realice, sino simplemente
implementar una función que llame al sistema preguntando la hora, como lo realiza la
función Now(). Esta clase de acciones son directas y de vida corta. Recordemos que la
creación de un objeto siempre es más lento y consume mayor cantidad de recursos que la
simple llamada de una función.
Programación en C++ con C++Builder 17
Entonces…, para que construimos clases? Una clase es en esencia una estructura
compleja cuya vida es dinámica, en la cual sus atributos van cambiando con el tiempo, pero
siempre realizando una acción específica. Por ejemplo, podríamos 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 leído un nuevo
dato, etc. Vemos que las obligaciones de esta clase son complejas, pero con una acción
específica.
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
través de sus interfaces bien definidas, pero no conocer como se encuentran implementadas.
Aunque podríamos conocer los detalles de su implementación de una clase, no debe
escribirse código que dependa de ello, esto significa que la implementación 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 más importantes entre clases es la herencia. Es uno de los
pilares fundamentales de la POO, mediante la cual se produce la transmisión de atributos y
funcionalidades de una clase a otra, lo cual trae aparejado grandes ventajas como la de
reutilización de código en la que se crean nuevas clases a partir de clases ya existentes por
medio de la absorción de sus atributos y comportamientos, sobreponiéndolos o
mejorándolos con las capacidades que las nuevas clases requieran.
La herencia, nos permite definir una clase modificando una o más clases ya
existentes. Estas modificaciones pueden consistir en añadir nuevos atributos y
funcionalidades a la clase que se está definiendo, aunque también 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 más nuevas clases
derivadas. Creándose de esta manera, una jerarquía de clases.
Para especificar el uso de la herencia, después 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:
// …
Programación en C++ con C++Builder 18
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 Miembros clase hija Miembros clase madre
private protected
public
private
protected protected
public
protected
public protected
public
protected
public
Los miembros private de la clase base son siempre inaccesibles para los métodos
de la clase derivada a menos que se declare explícitamente que es un miembro friend en
la clase base. No se tratará sobre miembros friend en este texto.
Vamos a diseñar una clase que modele el volumen de un prisma a la cual
llamaremos TPrisma. Para esta modelización recurriremos a la herencia que nos permitirá
reutilizar código fuete ya existente.
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 diseñada.
Programación en C++ con C++Builder 19
Si analizamos tridimensionalmente un prisma, podríamos pensarlo como una caja,
la cual consta de una base rectangular y posee una altura asociada, con la cual genera su
volumen. Matemáticamente podríamos 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 diseñada TRectangulo, la cual utilizaremos
como clase base. A continuación diseñaremos la clase hija.
Diseñando el diagrama de clase:
class TPrisma : public TRectangulo{
private:
float Altura;
float Volumen;
public:
void IngresarAltura(float Alturai);
void CalcularVolumen(void);
Programación en C++ con C++Builder 20
float InformarVolumen(void);
};
La implementación de los métodos es:
void TPrisma::IngresarAltura(float Alturai);
{
Altura = Alturai;
}
void TPrisma::CalcularVolumen(void);
{
CalcularSup(); // Aquí llamamos al método 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 relación de herencia publica, la clase
hija hereda automáticamente 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 sólo se
puede acceder a través de sus métodos.
Veremos a continuación, un segmento de código que ejemplifica la implementación
del evento click de un botón del formulario, en el cual declaramos la instancia u objeto
particular de la clase TPrisma.
void __fastcall TForm1::BotonClick(TObject *Sender)
{
TPrisma Prisma;
Nota: en la instanciación, sólo hacemos referencia a la clase hija, no se instancia la
clase madre.
Programación en C++ con C++Builder 21
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
también es llamada composición.
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 péndulo de un reloj
bidimensional, como la conjunción de un rectángulo (brazo
del péndulo) y un círculo (peso del péndulo), al cual
queremos calcular el área.
La clase contenedora TPendulo, contendrá a las
clases miembro TRectangulo y TCirculo. Para
continuar con el concepto de reutilización de código,
utilizaremos a la clase TRectangulo antes definida y
sólo diseñaremos a la clase TCirculo y modelaremos la
clase TPendulo.
Modelo bidimensional
del péndulo de un reloj
class TCirculo {
private:
float Radio;
float Superficie;
public:
void IngresarRadio(float Radioi);
void CalcularSup(void);
float InformarSup(void);
};
La implementación de los métodos es:
Programación en C++ con C++Builder 22
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 implementación de los métodos es:
void TPendulo::IngresarRadioPeso(float Radioi)
{
Circ.IngresarRadio(Radioi);
}
void TPendulo::IngresarLargoBrazo(float Largoi)
{
Rect.IngresarLargo(Largoi);
Programación en C++ con C++Builder 23
}
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 contención se instanció las clases miembro en la parte privada
de la clase (también se puede realizar en la parte publica, pero varia su implementación). Se
implementaron métodos 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 método CalcularSup(), se llamó a los métodos CalcularSup() de
cada una de las clases contenidas para que realicen el cálculo de su superficie y dispongan
su valor, para realizar la suma de ambas superficies.
Registros (struct).
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 declaración. Un ejemplo de
esta definición:
struct Tiempo {
int hora;
int minutos;
Avanzado: Los objetos miembro se construyen en el orden en el que se declaran.
Programación en C++ con C++Builder 24
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 evolución 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 declaración 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;
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 declaración inicial. El ejemplo es el mismo que
para el struct de C, sólo 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 público (public).
Programación en C++ con C++Builder 25
Definición de otros tipos
Programación en C++ con C++Builder 26
Capítulo 3: Lógica de control
En la programación, son necesarias herramientas que nos permitan hacer elecciones
o tomar decisiones durante el proceso de ejecución 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
expresión lógica permitirá tomar una decisión.
Expresión lógica.
Una expresión lógica es una combinación de constantes, variables y funciones
lógicas, con operadores lógicos y relacionales.
Para comenzar a entender su uso, podemos definir una variables lógicas como una
variable que puede contener sólo dos valores posibles: verdadero (trae o 1) o falso (false o
0). En C++ este tipo de variable se llama bool.
Los operadores lógicos son aquellos que nos permiten concatenar o modificar
expresiones lógicas, resultando un valor lógico. Ellos son:
Operador Nombre Operación lógica
! not negación
&& and y lógico
|| or o lógico
Para entender mejor su uso, vamos a ver como trabajan a traves de un ejemplo.
Supongamos que tenemos dos variables lógicas A y B.
A !A
0 1
1 0
A B A && B
0 0 0
0 1 0
1 0 0
1 1 1
A B A || B
Programación en C++ con C++Builder 27
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 lógico. Ellos son:
Operador Nombre Operación lógica
> mayor mayor que
< menor menor que
<= menor o igual menor o igual que
>= mayor o igual mayor o igual que
!= distinto distinta que
== igual igual que
Vamos a ver como trabajan a través de un ejemplo. Supongamos que tenemos tres
variables A=5, B=5 y C=7.
Expresión Resultado
A>B 0
A>=B 1
A<=C 1
A!=B 0
A!=C 1
A==B 1
A==C 0
Estructura condicional “ if ”
Es una estructura simple que permite ejecutar una instrucción o un bloque de
instrucciones sólo si se cumple una expresión lógica, es decir, se ejecuta sólo si el resultado
de la expresión lógica es verdadero.
if (expresión_lógica)
{acción;};
Observación: No hay que confundir el operador ==, con el operador =, dado que
el primero significa comparación, mientras el segundo asignación. declaran.
Programación en C++ con C++Builder 28
Si la expresión lógica es verdadera (o 1) la acción se ejecuta, si es falsa se ignora la
acción y se continua con la instrucción siguiente a la estructura condicional. Si se quiere
ejecutar una sola acción el uso de las llaves es opcional.
Esta estructura también permite ejecutar una acción si no se cumple (else) la
expresión lógica. Su estructura sería:
if (expresión_lógica)
{acción_1;}
else
{acción_2;};
En este caso, si la expresión lógica es verdadera (o 1) la se ejecuta la acción_1, si
es falsa se ejecuta la acción_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 lógica,
supongamos A, con la cual queremos realizar una acción sólo si su valor es verdadero. En
este caso se puede utilizar directamente esta variable como una expresión lógica y no es
necesario realizar la comparación con true, por ejemplo:
if (A == true)
C = A - B;
if (A)
C = A - B;
La expresión se evalúa 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
automáticamente por C++, reconociendo como falso al valor 0 y como verdadero a distinto
de 0.
Obsérvese en los ejemplos anteriores que el operador de igualdad tiene un doble
signo de igual (==), en tanto que el operador de asignación sólo tiene uno (=). Uno de los
errores comunes es el empleo del operador de asignación cuando se quiere utilizar el de
igualdad. Por ejemplo, si escribimos:
if (x = 20) {acción};
En este caso se asigna a x el valor 20 y, como la operación tendrá éxito, la
expresión será evaluada como true. Un error como este, aunque aparentemente obvio,
puede ser difícil de localizar.
Programación en C++ con C++Builder 29
Las instrucciones if se pueden anidar en caso de ser necesario. Anidar no es más
que emplear una instrucción if como acción de seguida de una o más instrucciones if
adicionales:
if (x > 10)
if (x < 20)
{acción};
Estructura condicional “ switch ”
La instrucción switch se prodría considerar como una extención de la instrucción
if. Permitiendo ejecutar múltiples acciones evaluando una sola variable de control a la
cual llamaremos selector, que de acuerdo a su valor en el instante que se evalúa
corresponderá la acción 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
expresión; siempre y cuando cumplan con la condición.
Cada uno de los valores de los casos para los cuales hemos definido una acción,
deben corresponder a un valor que pertenece al tipo de dato del selector.
Esta estructura también permite la definición de una acción que se ejecutará por
defecto si ninguno de los casos anteriores se cumple. Pero su definición es opcional.
En el caso de que un caso se cumpla, se ejecuta la acción definida para este caso
hasta que se encuentra con la instrucción break, que es una instrucción que permite salir
del bloque de código que se esta ejecutando, en este caso del bloque switch. Si no lo
encuentra, se seguirán ejecutando las acciones de los casos siguientes hasta terminar todos
los casos o hasta encontrarse con un break.
Debe notarse que la instrucción switch sólo funciona cuado existe una igualdad
entre el selector y alguno de los case, por lo que no será de utilidad en el caso de situación
Programación en C++ con C++Builder 30
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 número ingresado por el usuario, almacenando en una variable lógica (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 división por 2 sólo
puede tomar estos valores.
El mismo ejemplo se podría haber resuelto de tres formas más sencillas 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 la vocal a”; break;}
case ‘b’: {Resultado = “es la vocal b”; break;}
case ‘c’: {Resultado = “es la vocal c”; break;}
case ‘d’: {Resultado = “es la vocal d”; break;}
case ‘e’: {Resultado = “es la vocal e”; break;}
default:
{Resultado = “no es vocal”;}
}
Programación en C++ con C++Builder 31
Capítulo 4: Estructuras Repetitivas: "CICLOS"
Normalmente dentro de un programa, es necesario realizar acciones de forma
repetida, por ejemplo, imaginemos que queremos ejecutar 100 veces una acción, podríamos
escribir 100 veces la misma línea o bien indicar que ejecute 100 veces la misma línea.
Para ello, se creó en el lenguaje de programación, las estructuras for, while, y
do while, que son las que nos permitirán codificar ciclos o bucles según sea necesario.
Primero, debemos saber que todo ciclo, tiene una condición inicial, que inicia el
ciclo, una condición final, que, cuando se cumple, el bucle finaliza, y un cuerpo o bloque de
código que el ciclo realizará.
El cuerpo contiene la instrucción que se ejecuta cada vez por medio del ciclo y
puede incluir cualquier código válido en C++.
Revisemos cada ciclo por separado:
Ciclo for.
La estructura for (“durante”), se utiliza para realizar, generalmente, una acción
cierta cantidad determinada y definida de veces. Para ello, consta de tres parámetros que
debemos definir:
• Inicialización,
• Condición de salida
• Incremento
En la inicialización, se procede a declarar una variable auxiliar, llamada variable de
control, cuyo ámbito de existencia y trabajo es dentro del ciclo, dándole un valor inicial,
por ejemplo el valor uno.
Para establecer la condición de salida, se debe saber cuántas 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 finalización sería i == 10 (en este caso el ciclo se ejecutará si
la condición es false), pero es preferente determinarle el rango de 1 a 10 haciendo i <
= 10, mientras esta condición se mantenga en true, el ciclo realizará la acción que el
cuerpo determine, al momento de no cumplirse la condición de salida, el programa sigue
ejecutando la sentencia que sigue inmediatamente al cuerpo del ciclo.
En síntesis, si como condición de salida especifico un rango de la variable de
control, el ciclo se ejecutará mientras esta condición 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.
Programación en C++ con C++Builder 32
También, debo determinar la manera de incrementar la variable de control, es decir,
especificar si i varía 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 (inicialización; condición de salida; incremento)
{acción;};
Ejemplo: a continuación, implementaremos una función, en la que se reproducirá la
función pow incluida en la librería 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,
evaluándose siempre primero la condición de salida, y en cada paso del ciclo, las variables
puestas en juego toman los siguientes valores:
Condición
Finalización
i Resultado
Antes de entrar
al for
----- No existe 1
Primer paso true 1 Base
Segundo paso true 2 Base^2
Tercer paso true 3 Base^3
true ...
exponente paso true exponente Base^exponente
Saliendo del for false No existe Base^exponente
Condición if No existe Depende del signo
del exponente
Nota: La utilización 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.
Programación en C++ con C++Builder 33
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 sólo una sentencia, de manera tal que si se
requiere realizar más de una acción, debemos encerrar todo el bloque de código del ciclo
entre llaves (sentencia compuesta), por ejemplo:
for (int i=10; i>=0; i--)
{ acción_1;
acción_2;
.
.
acción_n;
}
Ciclo while
El ciclo while ("mientras") difiere del ciclo for en que sólo contiene una condición
de prueba, que se verifica al principio de cada iteración. Mientras la condición sea true el
ciclo continúa funcionando. La sintáxis correspondiente es:
while (expresión_lógica) {acción_1;
acción_2;
.
.
acción_n;};
En la misma, la acción se realiza mientras la expresión lógica sea verdadera (valor
distinto de cero). Es de vital importancia que la acción tenga alguna forma de modificar el
valor de la expresión lógica, para que, en algún momento, sea falsa y el ciclo finalice. Si de
entrada la expresión lógica da falsa, la acción del ciclo nunca se realiza.
Veamos un ejemplo de la utilización de esta estructura, supongamos que obtener la
potencia a la cual hay que elevar el número 2 para obtener el valor 1024.
Programación en C++ con C++Builder 34
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 prácticamente igual al while. Sin embargo, la diferencia entre los dos
es importante, ya que el ciclo while evalúa la expresión condicional al principio del ciclo;
en el caso de do-while ("hacer – mientras"), la expresión se evalúa al final del
propio ciclo. La sintaxis de este bucle es:
do {acción;} while (exprlógica);
Debido a la manera como funciona el ciclo do-while, el código en el cuerpo del
ciclo se ejecuta al menos una vez, sin importar el valor de la condición de prueba (ya que se
evalúa al final del ciclo). En el caso del while, la condición se evalúa al principio, por lo
que es posible que nunca se ejecute el cuerpo del ciclo.
También en este caso, la modificación de la expresión lógica debe ser explícita en el
bloque de código, para que el ciclo finalice en algún momento, cuando la expresión
condicional resulte falsa.
Un ejemplo sería:
int x = 1024;
int n;
do {x = x / 2;
n++;}
while (x > 1);
Programación en C++ con C++Builder 35
Donde n, guarda nuevamente la potencia a la que hay que elevar el valor 2 para
obtener el número 1024.
Es un error común, que se trate de realizar una acción 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 acción imposible
tal como el la división por cero, por ejemplo.
Para ver más gráficamente el error, analizaremos un código erróneo para
ejemplificar.
float x = 0;
float y;
do {y = 512 / x; //error al tratar de dividir por cero!!!
x = x + 2.0;} //acumulo en x el valor anterior de x más 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 ejecución del ciclo en el programa.
La instrucción continue se emplea para forzar la ejecución del programa hasta el
final del ciclo, saltando cualquier expresión situada después de continue.
La instrucción break se usa para detener la ejecución de un ciclo antes de que se
cumpla la condición 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 programación en C++ para descubrir todos los
posibles usos de estas dos instrucciones.
De todas maneras, a continuación veremos la utilización 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 confirmación de que podemos leer los 8 bits de
data. Utilizaremos dos funciones genéricas (estas funciones no están implementadas, son
sólo a modo de ejemplo) una para leer un bit del control a la que llamaremos
LeerBitControl (suponemos que esta función devuelve true si se puede leer el puerto
data), y una que nos permitirá leer el data, que llamaremos LeerDato(suponemos que esta
función devuelve el valor entero del dato leído).
Programación en C++ con C++Builder 36
for(;;){
if(LeerBitControl())break;
}
int x = LeerDato();
En este caso, el for se utiliza a modo de delay o retardo hasta que llegue la
confirmación de lectura del puerto.
En el caso que consideremos usar un bit de status para que haga comenzar o detenga la
adquisición del dato, según sea true o false.
int x=0;
for(;;){
if(LeerBitStatus())break;
for(;;){
if(LeerBitControl())break;
}
x += LeerDato();
}
Para ejemplificar el uso de la instrucción continue, podemos considerar el caso
anterior, haciendo la salvedad de que el siguiente ejemplo es un ciclo infinito, y es sólo a
modo de ejemplo.
int x=0;
while(!detener){
if(LeerBitStatus())continue;
for(;;){
if(!LeerBitControl())break;
}
x += LeerDato();
}
Avanzado: verificar que si al for le falta alguno o varios de sus parámetros,
también funciona, si utilizamos la sentencia break.
Programación en C++ con C++Builder 37
Capítulo 5: Vectores y Matrices
Se hace evidente que a lo largo de un programa, necesitamos guardar información, o
bien, trabajar con información que debemos almacenar en distintas estructuras. De esta
necesidad, surgen un tipo de estructura de datos llamados genéricamente como arreglo
(array). De esta manera, surgen los vectores que son arreglos unidimensionales y las
matrices que son arreglos multidimensionales.
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 dimensión, 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 número entre corchetes indica la cantidad de valores del tipo que se
indican, NO es el subíndice del mayor elemento. Además todos los subíndices comienzan
en cero, es decir el primer valor del vector es en la posición cero, y el último es en n-1 (en
el caso anterior, n-1=5-1=4).
Observemos de manera esquemática como sería la asignación de memoria
por parte del compilador:
Vector[0] Vector[1] Vector[2] Vector[3] Vector[4]
Valor int A Valor int B Valor int C Valor int D 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 análoga, para la matriz
bidimensional, asignamos memoria para M*N números 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 n-
dimensionales se requieren tantos subíndices como dimensiones tenga el espacio en el que
estemos trabajando.
Programación en C++ con C++Builder 38
Hay que prestar atención especial a no sobreescribir el final de un arreglo. Una
característica poderosa de C++ es el acceso directo a memoria; debido a ella, C++ no nos
impide escribir a una ubicación determinada de la memoria, aunque sea una posición a la
que se supone que no debe tener acceso el programa que estamos elaborando. El siguiente
código es válido, pero producirá la detención del programa:
int vector[5];
vector[5]=31;
Este es un error que se comete frecuentemente, dado que los arreglos tienen base 0.
Podríamos pensar que el último elemento del arreglo es 5, cuando en realidad es 4.
Es posible solicitar que, automáticamente, se verifique que los índices se encuentren
dentro del rango de la definición del arreglo, activando la directiva de compilación $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 posición del vector marcada por el
índice, que puede ser de cualquier tipo (entero, flotante, booleano, etc.).
Programación en C++ con C++Builder 39
Capítulo 6: Cadenas de caracteres
Una cadena de caracteres se puede definir como una secuencia o un vector de
caracteres, que están 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 carácter de la tabla ASCII (Anexo I). Esta
tabla es una tabla de correspondencia entre un caracter y un número 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 definición es heredada del lenguaje “c” aunque su
uso ha disminuido. Pero conserva algunas ventajas como son su simpleza y el menor
recurso ocupado. Se definición 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”;
También se puede realizar la asignación a cada caracter:
Cadena[2] = ‘n’;
Nota: es importante diferenciar cuando se asigna un carácter a una variable se
utiliza comillas simple (‘A’), mientras para las cadenas se utilizan comillas dobles
(“Computación”)
Programación en C++ con C++Builder 40
Cadena[3] = ‘P’; // ahora cadena vale “ConPutación”
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 métodos para su
manipulación. Para su utilización no es necesario especificar la longitud en la definición,
dado que se puede modificar en forma dinámica con la asignación de una nueva cadena.
string Cadena = “Bioingenieria”;
Esta clase es muy flexible y práctica aunque no la vamos a desarrollar dado que
C++Buider posee su propia definición de cadena de caracteres que veremos a
continuación.
AnsiString
Es una clase especialmente diseñada para la manipulación de cadenas de caracteres
definida por Borland®. Su definición tiene la forma:
AnsiString Cadena = “Bioingenieria”;
Esta clase define varios métodos que facilitan la manipulación 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 posición (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”
Nota: es importante diferenciar que en la cadena c++string el subíndice del primer
caracter es el 0 (cero), mientras que para AnsiString es el 1 (uno).
Programación en C++ con C++Builder 41
Length()
Devuelve la longitud (el número de bytes) de la cadena
int Longitud = Cadena.Length(); // Longitud = 13
Insert(subcadena, pos)
Inserta una subcadena en nuestra cadena en la posición 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
posición 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 posición 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 posición del primero.
int posicion = Candena.Pos(“in”); // posicion = 4
LowerCase()
Devuelve la cadena en minúscula.
AnsiString cad = Cadena.LowerCase(); // cad = “bioingenieria”
UpperCase();
Devuelve la cadena en mayúscula.
AnsiString cad = Cadena.UpperCase(); // cad = “BIOINGENIERIA”
Programación en C++ con C++Builder 42
Capítulo 7: Archivos de Texto.
Hasta ahora hemos visto cómo procesar información, y hemos mantenido el flujo de
entrada / salida de información a través de componentes visuales. Pero muchas veces la
información necesaria, de entrada o salida, se presentará en estructuras de datos llamadas
archivos, almacenadas en nuestro disco rígido.
Es por ello, que en este capítulo nos centraremos en el manejo del flujo de entrada /
salida de información desde y hacia el HD.
Los archivos de texto tienen la capacidad de almacenar caracteres de la tabla ASCII,
y su nombre físico (nombre con el cuál está almacenado en el HD) tiene el mismo formato
que cualquier otro archivo, a saber:
NombreFísico.extensión, por ejemplo el archivo de texto “Leame.txt”, su nombre es
Leame y su extensión es txt (de texto). No necesariamente el archivo de texto debe tener la
extensión txt, puede poseer cualquier otra extensión.
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 línea y el caracter de fin de archivo
(EOF, end of file)
Para manipular los archivos, C++ nos presenta una jerarquía de clases
especialmente diseñadas 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 básicas que se realizan sobre los archivos, estas son:
• Creación del objeto.
• Apertura del archivo.
• Manipulación del archivo.
• Cierre del archivo.
Creación del objeto.
Para la creación 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;
Programación en C++ con C++Builder 43
Apertura del archivo.
La apertura de un archivo establece la conexión entre el nombre lógico y el nombre
físico de nuestro archivo, abre el archivo y lo prepara para su manipulación.
Esto se puede realizar de dos maneras, la primera es a través del método open:
void open(const char *nombre_archivo, openmode modo);
Este método puede recibir dos parámetros, el primero es una cadena de caracteres
que representa el nombre físico del archivo que será abierto, y opcionalmente puede recibir
un segundo parámetro que representa al modo que se abrirá.
Puede ser alguna de las siguientes opciones:
ios::in Abre el archivo para lectura
ios::out Abre el archivo para escritura
ios::ate Abre un archivo existente y se posiciona al final
ios::app Abre un archivo de salida para agregar al final
ios::nocreate Abre un archivo sólo si ya existe.
ios::noreplace Abre un archivo sólo si no existe.
ios::trunc Abre un archivo, si ya existe borra todo su contenido
ios::binary 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 parámetro opcional del
método, dado que de acuerdo a la clase hayamos creado el objeto, posee un modo de
apertura por defecto. Estos son:
Clase Modo por defecto
ofstream ios::out | ios::trunc
ifstream ios::in
fstream ios::in | ios::out
La segunda manera de abrir un archivo, es combinándola con la creación del objeto.
Esto se puede realizar gracias a que el constructor de estas clases puede recibir el nombre
del archivo físico como parámetro y realiza internamente la llamada al método open.
ifstream ArchivoEnt(“datos.txt”);
Programación en C++ con C++Builder 44
Cierre del archivo.
Como se abra dado cuenta nos salteamos, el apartado correspondiente a la
manipulación del archivo. Esto lo hacemos dado que es la parte más compleja, y preferimos
dejarlo para el final.
Al terminar la manipulación del archivo, se debe cerrar el vínculo que hemos creado
con nuestro archivo físico, para liberarlo y permitir que otros programas (o procesos)
puedan usarlo. A demás se realizan otras acciones internas como liberar la memoria de un
buffer creado, terminar de escribir sobre el archivo (dado que esta acción se realiza de a
bloques), etc.
Esta acción se realiza mediante la llamada al método close().
ArchivoEnt.close();
Una vez cerrado el archivo, este objeto esta disponible para abrir nuevamente otro
archivo o ser destruido.
El cierre del archivo también se realiza de forma automática 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 método close().
Manipulación del archivo.
Con este término nos referimos, a la acción 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 métodos.
Operadores de lectura / escritura
Existen dos operadores:
1. Operador de inserción: <<
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 conversión de
tipo de forma automática. Vamos a ver algunos ejemplos:
Código ejemplo Contenido archivo
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
Programación en C++ con C++Builder 45
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 separación de un carácter de espacio que se realiza de forma
automática. Al final de cada renglón agregamos endl para insertar un caracter de fin de
línea, para movernos a la siguiente línea.
String Texto = “Hola”;
ArchivoSal << Texto << “1” << endl;
ArchivoSal << Texto << “ 2” << endl;
Hola1
Hola 2
Ahora vemos que podemos también realizar la inserción del contenido una variable
entera, cuyo contenido se convierte de forma automática en una cadena de caracteres. A
demás se puede observar otra forma de insertar el caracter de fin de línea agregando n
int num = 1;
ArchivoSal << num << “Holan”;
Num++;
ArchivoSal << num << “ Holan”;
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;
ofstream Archi("datos.txt");
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
Programación en C++ con C++Builder 46
2. Operador de extracción: >>
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 línea. Similar al anterior, el texto puede ser una cadena de
caracteres o no, gracias a que estas clases saben realizar la conversión de tipo de forma
automática, la conversión se realizará de acuerdo al tipo de dato de la variable que
definamos. Vamos a ver algunos ejemplos:
Contenido archivo
Código ejemplo
variables
En este primer ejemplo vemos como extrae una simple cadena de caracteres de un
archivo de texto tipo ifstream llamado ArchivoEnt.
alumnostring Texto;
ArchivoEnt >> Texto; Texto = “alumno”
En este par de ejemplos, vemos como el mismo código permite leer cadenas de
caracteres sucesivos independientes que estén separadas por un caracter de espacio o de fin
de línea.
alumno1 alumno2string Texto1, Texto2;
ArchivoSal >> Texto1 >> Texto2; Texto1 = “alumno1”
Texto2 = “alumno2”
alumno1
alumno2
string Texto1, Texto2;
ArchivoSal >> Texto1 >> Texto2;
Texto1 = “alumno1”
Texto2 = “alumno2”
Ahora vemos que también podemos extraer la información independiente de que
este sea un entero. Dado que la segunda extracción la hacemos sobre una variable del tipo
int, la conversión se realiza automáticamente. Hay que tener cuidado que el dato a leer
sea un entero, dado que C++ realiza la lectura igualmente pudiéndose obtener información
errónea.
alumno 1int num;
string Texto;
ArchivoSal >> Texto >> num;
Texto = “alumno”
num = 1
Programación en C++ con C++Builder 47
Métodos de lectura / escritura
Como dijimos anteriormente, la lectura y escritura de datos también se puede
realizar mediante llamadas a métodos de la clase. Veamos cuales son:
• get() y getline():
Estos métodos permiten realizar la lectura de toda una línea, hasta que encuentra un
caracter de terminación.
Reciben tres parámetros. El primero es un puntero a un vector de caracteres (buffer),
el segundo el tamaño del vector, y el tercero (opcional) el caracter de terminación. Por
defecto este caracter es el “n”, llamado caracter de fin de línea.
Si el primer caracter de la línea es el carácter de terminación, devuelven un vector
de longitud cero. Pero su gran diferencia radica, en que el método get() se detiene, y una
segunda llamada al método devuelve el mismo resultado, hasta que se cambie el caracter de
terminación. En cambio, una segunda llamada al método getline() devuelve la
siguiente línea, por lo que normalmente se utiliza este método.
Otra diferencia radica en que el método get() puede ser llamado sin ningún
parámetro. En este caso devuelve el caracter siguiente..
Métodos especiales
• eof()
Es uno de los métodos más importantes. Devuelve true si se llegó al final de
archivo. Encontró el carácter EOF.
• is_open()
Este método devuelve true si se abrió correctamente el archivo.
• good()
Este método devuelve true si no ocurrió ningún error.
• bad()
Este método devuelve true si ocurrió algún error con el buffer.
• fail()
Este método devuelve true si ocurrió algún error que no afecte al buffer.

Más contenido relacionado

La actualidad más candente

Pseudocódigo
PseudocódigoPseudocódigo
Pseudocódigo
coldclean
 
Ejercicio 2 diagrama de flujo
Ejercicio 2 diagrama de flujoEjercicio 2 diagrama de flujo
Ejercicio 2 diagrama de flujo
lisvancelis
 
Ejemplos de Algoritmos
Ejemplos de AlgoritmosEjemplos de Algoritmos
Ejemplos de Algoritmos
Pepe Xdsasda
 
Diagramas de paquetes
Diagramas de paquetesDiagramas de paquetes
Diagramas de paquetes
Moises Cruz
 
Programacion orientada a objetos y programacion orientada a eventos
Programacion orientada a objetos y programacion orientada a eventosProgramacion orientada a objetos y programacion orientada a eventos
Programacion orientada a objetos y programacion orientada a eventos
Josue Ivan Turcios
 

La actualidad más candente (20)

Diseño a Nivel de Componentes
Diseño a Nivel de ComponentesDiseño a Nivel de Componentes
Diseño a Nivel de Componentes
 
Pseudocódigo
PseudocódigoPseudocódigo
Pseudocódigo
 
Algoritmos computacionales y programación: 3
Algoritmos computacionales y programación: 3Algoritmos computacionales y programación: 3
Algoritmos computacionales y programación: 3
 
Presentación Introducción al lenguaje HTML
Presentación Introducción al lenguaje HTMLPresentación Introducción al lenguaje HTML
Presentación Introducción al lenguaje HTML
 
PROGRAMAS EN DEV C++
PROGRAMAS EN DEV C++PROGRAMAS EN DEV C++
PROGRAMAS EN DEV C++
 
Mapa conceptual de Java
Mapa conceptual de JavaMapa conceptual de Java
Mapa conceptual de Java
 
Programacion Orientada a Objetos
Programacion Orientada a ObjetosProgramacion Orientada a Objetos
Programacion Orientada a Objetos
 
Windows forms c# visual basic .net ejercicios
Windows forms c# visual basic .net ejerciciosWindows forms c# visual basic .net ejercicios
Windows forms c# visual basic .net ejercicios
 
ALGORITMO RESUELTOS EN PSEINT
ALGORITMO RESUELTOS EN PSEINTALGORITMO RESUELTOS EN PSEINT
ALGORITMO RESUELTOS EN PSEINT
 
Diagrama de dominio armando
Diagrama de dominio armandoDiagrama de dominio armando
Diagrama de dominio armando
 
Qué es uml, PARA QUE SIRVE, PASOS
Qué es uml, PARA QUE SIRVE, PASOSQué es uml, PARA QUE SIRVE, PASOS
Qué es uml, PARA QUE SIRVE, PASOS
 
Ejercicio 2 diagrama de flujo
Ejercicio 2 diagrama de flujoEjercicio 2 diagrama de flujo
Ejercicio 2 diagrama de flujo
 
Ejemplos de Algoritmos
Ejemplos de AlgoritmosEjemplos de Algoritmos
Ejemplos de Algoritmos
 
Introducción a la Programación :: Unidad 01 :: Parte 01
Introducción a la Programación :: Unidad 01 :: Parte 01Introducción a la Programación :: Unidad 01 :: Parte 01
Introducción a la Programación :: Unidad 01 :: Parte 01
 
Ejercicios if en c#
Ejercicios if en c#Ejercicios if en c#
Ejercicios if en c#
 
Diagramas de paquetes
Diagramas de paquetesDiagramas de paquetes
Diagramas de paquetes
 
C++ y sus librerias
C++ y sus libreriasC++ y sus librerias
C++ y sus librerias
 
Lambdas y API Stream - Apuntes de Java
Lambdas y API Stream - Apuntes de JavaLambdas y API Stream - Apuntes de Java
Lambdas y API Stream - Apuntes de Java
 
elementos tipicos de las interfaces graficas de usuario
elementos tipicos de las interfaces graficas de usuarioelementos tipicos de las interfaces graficas de usuario
elementos tipicos de las interfaces graficas de usuario
 
Programacion orientada a objetos y programacion orientada a eventos
Programacion orientada a objetos y programacion orientada a eventosProgramacion orientada a objetos y programacion orientada a eventos
Programacion orientada a objetos y programacion orientada a eventos
 

Similar a Programación en C++ con C++ Builder

Manual visualc
Manual visualcManual visualc
Manual visualc
Israel Mc
 

Similar a Programación en C++ con C++ Builder (20)

Instructivo para utilizar_c_
Instructivo para utilizar_c_Instructivo para utilizar_c_
Instructivo para utilizar_c_
 
Instructivo para utilizar_c++
Instructivo para utilizar_c++Instructivo para utilizar_c++
Instructivo para utilizar_c++
 
Manual visualc
Manual visualcManual visualc
Manual visualc
 
Manual visualc
Manual visualcManual visualc
Manual visualc
 
Presentación de visual studio (1)
Presentación de visual studio (1)Presentación de visual studio (1)
Presentación de visual studio (1)
 
Apuntes builder
Apuntes builderApuntes builder
Apuntes builder
 
Apuntes builder
Apuntes builderApuntes builder
Apuntes builder
 
Apuntes builder
Apuntes builderApuntes builder
Apuntes builder
 
Diseño de Interfaces Mediante .NET
Diseño de Interfaces Mediante .NETDiseño de Interfaces Mediante .NET
Diseño de Interfaces Mediante .NET
 
Pre practica 3
Pre practica 3Pre practica 3
Pre practica 3
 
10 Herramientas Visual Basic
10 Herramientas Visual Basic 10 Herramientas Visual Basic
10 Herramientas Visual Basic
 
Apuntes vb6
Apuntes vb6Apuntes vb6
Apuntes vb6
 
Fundamentos de Visual Basic
Fundamentos de Visual BasicFundamentos de Visual Basic
Fundamentos de Visual Basic
 
Visual Basic 6.0
Visual Basic 6.0Visual Basic 6.0
Visual Basic 6.0
 
Tutorial visual c_(2)
Tutorial visual c_(2)Tutorial visual c_(2)
Tutorial visual c_(2)
 
Sesión5 applets
Sesión5 appletsSesión5 applets
Sesión5 applets
 
CODEBLOCKS
CODEBLOCKSCODEBLOCKS
CODEBLOCKS
 
CODEBLOCKS
CODEBLOCKSCODEBLOCKS
CODEBLOCKS
 
CODEBLOCKS
CODEBLOCKSCODEBLOCKS
CODEBLOCKS
 
Manual sobre code
Manual sobre codeManual sobre code
Manual sobre code
 

Más de Andy Juan Sarango Veliz

Criptología de empleo en el Esquema Nacional de Seguridad
Criptología de empleo en el Esquema Nacional de SeguridadCriptología de empleo en el Esquema Nacional de Seguridad
Criptología de empleo en el Esquema Nacional de Seguridad
Andy Juan Sarango Veliz
 
Alfabetización Informática - 2. Test de Conceptos Básicos
Alfabetización Informática - 2. Test de Conceptos BásicosAlfabetización Informática - 2. Test de Conceptos Básicos
Alfabetización Informática - 2. Test de Conceptos Básicos
Andy Juan Sarango Veliz
 
Software Defined Radio - Capítulo 5: Modulación Digital I
Software Defined Radio - Capítulo 5: Modulación Digital ISoftware Defined Radio - Capítulo 5: Modulación Digital I
Software Defined Radio - Capítulo 5: Modulación Digital I
Andy Juan Sarango Veliz
 
Software Defined Radio - Capítulo 4: Modulación FM
Software Defined Radio - Capítulo 4: Modulación FMSoftware Defined Radio - Capítulo 4: Modulación FM
Software Defined Radio - Capítulo 4: Modulación FM
Andy Juan Sarango Veliz
 
Software Defined Radio - Capítulo 3: Modulación AM
Software Defined Radio - Capítulo 3: Modulación AMSoftware Defined Radio - Capítulo 3: Modulación AM
Software Defined Radio - Capítulo 3: Modulación AM
Andy Juan Sarango Veliz
 
Software Defined Radio - Capítulo 2: GNU Radio Companion
Software Defined Radio - Capítulo 2: GNU Radio CompanionSoftware Defined Radio - Capítulo 2: GNU Radio Companion
Software Defined Radio - Capítulo 2: GNU Radio Companion
Andy Juan Sarango Veliz
 
Software Defined Radio - Capítulo 1: Introducción
Software Defined Radio - Capítulo 1: IntroducciónSoftware Defined Radio - Capítulo 1: Introducción
Software Defined Radio - Capítulo 1: Introducción
Andy Juan Sarango Veliz
 
Los cuatro desafíos de ciberseguridad más críticos de nuestra generación
Los cuatro desafíos de ciberseguridad más críticos de nuestra generaciónLos cuatro desafíos de ciberseguridad más críticos de nuestra generación
Los cuatro desafíos de ciberseguridad más críticos de nuestra generación
Andy Juan Sarango Veliz
 

Más de Andy Juan Sarango Veliz (20)

Examen final de CCNA Routing y Switching Academia OW
Examen final de CCNA Routing y Switching  Academia OWExamen final de CCNA Routing y Switching  Academia OW
Examen final de CCNA Routing y Switching Academia OW
 
Criptología de empleo en el Esquema Nacional de Seguridad
Criptología de empleo en el Esquema Nacional de SeguridadCriptología de empleo en el Esquema Nacional de Seguridad
Criptología de empleo en el Esquema Nacional de Seguridad
 
Alfabetización Informática - 3. Navegador Web
Alfabetización Informática - 3. Navegador WebAlfabetización Informática - 3. Navegador Web
Alfabetización Informática - 3. Navegador Web
 
Alfabetización Informática - 2. Test de Conceptos Básicos
Alfabetización Informática - 2. Test de Conceptos BásicosAlfabetización Informática - 2. Test de Conceptos Básicos
Alfabetización Informática - 2. Test de Conceptos Básicos
 
Alfabetización Informática - 1. Conceptos Básicos
Alfabetización Informática - 1. Conceptos BásicosAlfabetización Informática - 1. Conceptos Básicos
Alfabetización Informática - 1. Conceptos Básicos
 
Gestión y Operación de la Ciberseguridad
Gestión y Operación de la CiberseguridadGestión y Operación de la Ciberseguridad
Gestión y Operación de la Ciberseguridad
 
Tecnologías de virtualización y despliegue de servicios
Tecnologías de virtualización y despliegue de serviciosTecnologías de virtualización y despliegue de servicios
Tecnologías de virtualización y despliegue de servicios
 
3. wordpress.org
3. wordpress.org3. wordpress.org
3. wordpress.org
 
2. wordpress.com
2. wordpress.com2. wordpress.com
2. wordpress.com
 
1. Introducción a Wordpress
1. Introducción a Wordpress1. Introducción a Wordpress
1. Introducción a Wordpress
 
Redes de Computadores: Un enfoque descendente 7.° Edición - Capítulo 9
Redes de Computadores: Un enfoque descendente 7.° Edición - Capítulo 9Redes de Computadores: Un enfoque descendente 7.° Edición - Capítulo 9
Redes de Computadores: Un enfoque descendente 7.° Edición - Capítulo 9
 
Análisis e Implementación de una Red "SDN" usando controladores "Open Source"
Análisis e Implementación de una Red "SDN" usando controladores "Open Source"Análisis e Implementación de una Red "SDN" usando controladores "Open Source"
Análisis e Implementación de una Red "SDN" usando controladores "Open Source"
 
Software Defined Radio - Capítulo 5: Modulación Digital I
Software Defined Radio - Capítulo 5: Modulación Digital ISoftware Defined Radio - Capítulo 5: Modulación Digital I
Software Defined Radio - Capítulo 5: Modulación Digital I
 
Software Defined Radio - Capítulo 4: Modulación FM
Software Defined Radio - Capítulo 4: Modulación FMSoftware Defined Radio - Capítulo 4: Modulación FM
Software Defined Radio - Capítulo 4: Modulación FM
 
Software Defined Radio - Capítulo 3: Modulación AM
Software Defined Radio - Capítulo 3: Modulación AMSoftware Defined Radio - Capítulo 3: Modulación AM
Software Defined Radio - Capítulo 3: Modulación AM
 
Software Defined Radio - Capítulo 2: GNU Radio Companion
Software Defined Radio - Capítulo 2: GNU Radio CompanionSoftware Defined Radio - Capítulo 2: GNU Radio Companion
Software Defined Radio - Capítulo 2: GNU Radio Companion
 
Software Defined Radio - Capítulo 1: Introducción
Software Defined Radio - Capítulo 1: IntroducciónSoftware Defined Radio - Capítulo 1: Introducción
Software Defined Radio - Capítulo 1: Introducción
 
MAE-RAV-ROS Introducción a Ruteo Avanzado con MikroTik RouterOS v6.42.5.01
MAE-RAV-ROS Introducción a Ruteo Avanzado con MikroTik RouterOS v6.42.5.01MAE-RAV-ROS Introducción a Ruteo Avanzado con MikroTik RouterOS v6.42.5.01
MAE-RAV-ROS Introducción a Ruteo Avanzado con MikroTik RouterOS v6.42.5.01
 
Los cuatro desafíos de ciberseguridad más críticos de nuestra generación
Los cuatro desafíos de ciberseguridad más críticos de nuestra generaciónLos cuatro desafíos de ciberseguridad más críticos de nuestra generación
Los cuatro desafíos de ciberseguridad más críticos de nuestra generación
 
ITIL Foundation ITIL 4 Edition
ITIL Foundation ITIL 4 EditionITIL Foundation ITIL 4 Edition
ITIL Foundation ITIL 4 Edition
 

Último

INFORME de pregrado ingenieria de vias.pdf
INFORME de pregrado ingenieria de vias.pdfINFORME de pregrado ingenieria de vias.pdf
INFORME de pregrado ingenieria de vias.pdf
octaviosalazar18
 
UC Fundamentos de tuberías en equipos de refrigeración m.pdf
UC Fundamentos de tuberías en equipos de refrigeración m.pdfUC Fundamentos de tuberías en equipos de refrigeración m.pdf
UC Fundamentos de tuberías en equipos de refrigeración m.pdf
refrielectriccarlyz
 

Último (20)

ATS-FORMATOa.pdf PARA MANTENIMIENTO MECANICO
ATS-FORMATOa.pdf PARA MANTENIMIENTO MECANICOATS-FORMATOa.pdf PARA MANTENIMIENTO MECANICO
ATS-FORMATOa.pdf PARA MANTENIMIENTO MECANICO
 
Manual deresolucion de ecuaciones por fracciones parciales.pdf
Manual deresolucion de ecuaciones por fracciones parciales.pdfManual deresolucion de ecuaciones por fracciones parciales.pdf
Manual deresolucion de ecuaciones por fracciones parciales.pdf
 
libro de ingeniería de petróleos y operaciones
libro de ingeniería de petróleos y operacioneslibro de ingeniería de petróleos y operaciones
libro de ingeniería de petróleos y operaciones
 
INTEGRATED PROJECT DELIVERY.pdf (ENTREGA INTEGRADA DE PROYECTOS)
INTEGRATED PROJECT DELIVERY.pdf (ENTREGA INTEGRADA DE PROYECTOS)INTEGRATED PROJECT DELIVERY.pdf (ENTREGA INTEGRADA DE PROYECTOS)
INTEGRATED PROJECT DELIVERY.pdf (ENTREGA INTEGRADA DE PROYECTOS)
 
422382393-Curso-de-Tableros-Electricos.pptx
422382393-Curso-de-Tableros-Electricos.pptx422382393-Curso-de-Tableros-Electricos.pptx
422382393-Curso-de-Tableros-Electricos.pptx
 
Sistema de alumbrado.pptx fjhhgghrhgghhuughuh
Sistema de alumbrado.pptx fjhhgghrhgghhuughuhSistema de alumbrado.pptx fjhhgghrhgghhuughuh
Sistema de alumbrado.pptx fjhhgghrhgghhuughuh
 
INFORME de pregrado ingenieria de vias.pdf
INFORME de pregrado ingenieria de vias.pdfINFORME de pregrado ingenieria de vias.pdf
INFORME de pregrado ingenieria de vias.pdf
 
metodos de fitomejoramiento en la aolicacion de plantas
metodos de fitomejoramiento en la aolicacion de plantasmetodos de fitomejoramiento en la aolicacion de plantas
metodos de fitomejoramiento en la aolicacion de plantas
 
UC Fundamentos de tuberías en equipos de refrigeración m.pdf
UC Fundamentos de tuberías en equipos de refrigeración m.pdfUC Fundamentos de tuberías en equipos de refrigeración m.pdf
UC Fundamentos de tuberías en equipos de refrigeración m.pdf
 
Mecatronica Automotriz .pdf
Mecatronica Automotriz              .pdfMecatronica Automotriz              .pdf
Mecatronica Automotriz .pdf
 
Estadística Anual y Multianual del Sector Eléctrico Ecuatoriano
Estadística Anual y Multianual del Sector Eléctrico EcuatorianoEstadística Anual y Multianual del Sector Eléctrico Ecuatoriano
Estadística Anual y Multianual del Sector Eléctrico Ecuatoriano
 
G4 - CASO DE ESTUDIO - VOLUMEN DE UN RESERVORIO (1).pptx
G4 - CASO DE ESTUDIO - VOLUMEN DE UN RESERVORIO (1).pptxG4 - CASO DE ESTUDIO - VOLUMEN DE UN RESERVORIO (1).pptx
G4 - CASO DE ESTUDIO - VOLUMEN DE UN RESERVORIO (1).pptx
 
Trabajo practico N°14 - Despacho Economico de Cargas - Campus 2022.pdf
Trabajo practico N°14 - Despacho Economico de Cargas - Campus 2022.pdfTrabajo practico N°14 - Despacho Economico de Cargas - Campus 2022.pdf
Trabajo practico N°14 - Despacho Economico de Cargas - Campus 2022.pdf
 
Trabajos Preliminares en Obras de Construcción..pdf
Trabajos Preliminares en Obras de Construcción..pdfTrabajos Preliminares en Obras de Construcción..pdf
Trabajos Preliminares en Obras de Construcción..pdf
 
Arquitecto cambio de uso de suelo Limache
Arquitecto cambio de uso de suelo LimacheArquitecto cambio de uso de suelo Limache
Arquitecto cambio de uso de suelo Limache
 
Análisis de Costos y Presupuestos CAPECO
Análisis de Costos y Presupuestos CAPECOAnálisis de Costos y Presupuestos CAPECO
Análisis de Costos y Presupuestos CAPECO
 
dokumen.tips_311-determinacion-del-espacio-estatico.pptx
dokumen.tips_311-determinacion-del-espacio-estatico.pptxdokumen.tips_311-determinacion-del-espacio-estatico.pptx
dokumen.tips_311-determinacion-del-espacio-estatico.pptx
 
Matrices Matemáticos universitario pptx
Matrices  Matemáticos universitario pptxMatrices  Matemáticos universitario pptx
Matrices Matemáticos universitario pptx
 
CAPACITACIÓN EN AGUA Y SANEAMIENTO EN ZONAS RURALES
CAPACITACIÓN EN AGUA Y SANEAMIENTO EN ZONAS RURALESCAPACITACIÓN EN AGUA Y SANEAMIENTO EN ZONAS RURALES
CAPACITACIÓN EN AGUA Y SANEAMIENTO EN ZONAS RURALES
 
Presentación de Redes de alcantarillado y agua potable
Presentación de Redes de alcantarillado y agua potablePresentación de Redes de alcantarillado y agua potable
Presentación de Redes de alcantarillado y agua potable
 

Programación en C++ con C++ Builder

  • 1. Programación en C++ con C++Builder 1 Programación en C++ con C++Builder Versión de borrador N°3 Año 2004 Angel A. Zeitoune (azeitoune@yahoo.com.ar) y Ricardo A. Rettore (ricadorettore@yahoo.com.ar) * Esta es una versión borrador, cualquier duda o sugerencia por favor escribir a cualquiera de los autores.
  • 2. Programación en C++ con C++Builder 2 Introducción. Este curso es fruto de la experiencia profesional y la acción pedagógica de varios años de docencia de los autores. Es por esta última, que luego de una incansable búsqueda de algún libro que permitiese aprender a programar en C++ al mismo tiempo que enseñase a utilizar como herramienta a C++Builder, y dada su carencia en el mercado, decidimos desarrollarlo. C++Builder es herramienta de desarrollo rápido de aplicaciones (RAD, rapid application development) para Windows, en lenguaje de C++, que posee varias características importantes, lo cual facilita el desarrollo de aplicaciones gráficas. Queremos aclarar que en este curso, no se pretende la enseñanza a fondo de las herramientas de programación C++Builder. Se presenta una breve introducción a su uso y conocimientos mínimos para lograr el aprendizaje del lenguaje.
  • 3. Programación en C++ con C++Builder 3 Capítulo 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 diseñar, 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 aplicación, que a su vez puede contener a otros objetos componentes (objetos). Editor de Código (Code Editor): aparece, inicialmente, atrás del formulario. Es un editor de texto avanzado que contiene el código fuente del programa.
  • 4. Programación en C++ con C++Builder 4 Ventana Principal (main window): Contiene la barra de título, el menú principal, barra de acceso rápido (SpeedBar), y la paleta de componentes (Component palette). Inspector de Objetos (Object Inspector): esta dividido en dos páginas, propiedades y eventos, las cuales están asociadas al componente seleccionado. 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. También podremos incluir a nuestro proyecto, nuevos formularios, units, módulos de datos, archivos de texto, etc. con la opción 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. 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 según sus extensiones: Extensión Contenido 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).
  • 5. Programación en C++ con C++Builder 5 .h Archivo de cabecera. Contiene la declaración de la clase. .cpp Archivo fuente de C++. Implementación del archivo .h, Usualmente tenemos uno por cada unit y uno por el proyecto principal. .dfm Archivos del formulario. Es un archivo de texto que contiene características de los elementos visuales. .bpr Archivo de proyecto .exe Programa ejecutable. .res Archivo de recursos. Se guardan en este archivo el icono de nuestra aplicación entre otras cosas. .obj Archivo objeto. Es un archivo binario que produce el compilador de nuestro proyecto antes de armar el ejecutable. .tds Tabla simbólica de depuración. .~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 páginas 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 botón izquierdo del mouse sobre el formulario, dando el tamaño deseado al mismo. El inspector de objetos nos presenta las propiedades y eventos asociados a los elementos que componen la interfaz gráfica. Analizaremos las propiedades, métodos y eventos más importantes de los principales componentes: Avanzado: Los componentes, están conformados en una biblioteca visual de componentes (Visual Component Library), llamada VCL, que se basa en modelo de propiedades, métodos y eventos (PME). La VCL es una jerarquía de clases escrita en Object Pascal asociada al IDE de C++Buider.
  • 6. Programación en C++ con C++Builder 6 Form: El formulario representa la ventana de una aplicación. Un formulario, a su vez, puede contener otros componentes, como Button, Label, CheckBox, etc. Propiedades: Name: Representa el nombre lógico con el que se referencia al componente. Caption: permite modificar el texto del título del formulario. Font: modifica el tipo de letra (fuente, estilo de fuente, tamaño, etc.) de los componentes que están contenidos en el formulario. Position: especifica la posición del formulario. Puede ser por diseño, 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: posición 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). OnClose: ocurre cuando el formulario se cierra. Button, BitBtn y SpeedButton: Button es un botón estándar de Windows, mientras los que los otros amplían sus funcionalidades como permitir incluir un bitmap. Propiedades: Name: Representa el nombre lógico con el que se referencia al componente. Caption: permite modificar el texto del botón. Font: modifica el tipo de letra (fuente, estilo de fuente, tamaño, etc.) del caption. Height y Width: representan el alto y ancho del botón en pixeles. Nota: al crearse un formulario, la creación de este sigue esta secuencia de eventos mencionados, OnCreate, OnShow, OnActivate y On Paint.
  • 7. Programación en C++ con C++Builder 7 Left y Top: posición izquierda y superior del extremo superior izquierdo del botón relativa al del formulario en pixeles. Enabled: Habilita o deshabilita la respuesta del botón a eventos. Hint: es un pequeño texto que aparecerá sobre el botón cuando el usuario coloque el mouse sobre el botón. Para que aparezca el Hint debe colocarse la propiedad ShowHint en valor “True”. Estas propiedades se encuentran en la mayoría de los componentes visuales. Visible: determina cuando el botón aparece en el formulario. Glyph (sólo en BitBtn y SpeedButton): permite especificar el bitmap que aparece en el botón. Kind (sólo en BitBtn): determina el tipo de algunos bitmap predefinidos. Flat (sólo en SpeedButton): hace desaparecer el efecto 3D de los botones. Down (sólo en SpeedButton): especifica cuando el botón está presionado. Para quedar presionado la propiedad GroupIndex debe ser distinta de cero. TabOrder: especifica el orden en el que los componentes tendrán el foco. Eventos: OnClick: ocurre cuando se hace click sobre el botón. OnMouseMove: ocurre cuando se mueve el mouse sobre el botón. Métodos: SetFocus: coloca el foco en el botón. Label: Componente que permite mostrar texto en un formulario. Es usado para mostrar resultados e información al usuario, debido a que él no puede editarlo. No puede contener el foco en una aplicación. Propiedades: Name: Representa el nombre lógico 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, tamaño, etc.) del caption. Alignment: permite especificar la alineación del texto. Puede ser hacia la derecha, izquierda o centrada. Sugerencia: probar cambiar el color de la fuente en todos los botones.
  • 8. Programación en C++ con C++Builder 8 Edit: Caja de edición, que permite editar un texto de una sola línea. Se utiliza para que el usuario introduzca información. Propiedades: Name: Representa el nombre lógico con el que se referencia al componente. Text: es el texto asociado al edit. Font: modifica el tipo de letra (fuente, estilo de fuente, tamaño, etc.) del caption. CharCase: permite especificar los caracteres en mayúscula o minúscula. MaxLength: cantidad máxima 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 selección. Se diferencian en que el primero permite seleccionar varias opciones simultáneamente, mientras el segundo sólo permite la selección de un único elemento dentro de un mismo grupo. De ahora en adelante sólo veremos las propiedades, métodos y eventos que caracterizan a los componentes. Propiedades: Checked: especifica cuando el componente está seleccionado. 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 métodos que permiten manipular elementos como agregar (Add), insertar (insert), eliminar (delete) y mover (move). Columns: especifica el número de columnas. MultiSelect: permite seleccionar varios elementos al mismo tiempo. Sorted: ordena automáticamente los elementos alfabéticamente. Investigar: cómo puedo especificar diferentes grupos de RadioButton, de manera que me permitan seleccionar una opción de cada grupo?
  • 9. Programación en C++ con C++Builder 9 Métodos: Clear: Borra todos los elementos del ListBox. Memo: Es un componente estándar de Windows, que permite manipular texto multilínea, tanto para el ingreso por parte del usuario como informar textos de gran longitud. Propiedades: Lines: contiene los líneas de texto que están 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. Métodos: 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.
  • 10. Programación en C++ con C++Builder 10 Capítulo 2: Programación Orientada a Objetos (POO) La idea básica que soporta el enfoque OO es muy simple, percibimos al mundo como una variedad de objetos: televisores, lámparas y otros, pero cuando se enciende el televisor no se distingue entre sus elementos físicos (tubo de pantalla, antena, etc.) y su comportamiento. Sólo lo encendemos y seleccionamos un canal. Los objetos modelan las características y el comportamiento de los elementos del mundo en que vivimos, son la abstracción de los datos más 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 más estables ya que los datos tienen una vida útil mayor que las funciones. En la POO las variables son activas, es decir, además de tener propiedades tienen comportamiento y es el comportamiento el que hace que la variable sea activa en lugar de estar esperando que algún código la manipule como las variables tradicionales. La POO encapsula los datos (atributos) y el comportamiento (métodos) en paquetes llamados clases, las cuales son el la unidad básica. Hay tres propiedades principales que caracterizan un lenguaje de POO, las cuales iremos describiendo más adelante: • Encapsulamiento • Herencia. • Polimorfismo. La POO permite el ahorro de tiempo en el desarrollo de programas, promueve la reutilización de código 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. • Fácil mantenimiento • Simple extensibilidad. Clases (class). Una clase es una abstracción, que modela las características y comportamientos de un objeto, la cual debe incluir funcionalidades que permitan informar o modificar el estado de esa entidad, como así también, realizar diversas acciones para las cual fue diseñado. 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 interacción.
  • 11. Programación en C++ con C++Builder 11 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 definición de una clase se divide en dos partes, la declaración de la cabecera y la implementación (implementación de los métodos). La declaración de la cabecera se realiza mediante la palabra reservada class. Una clase esta dividida en diferentes secciones, de acuerdo a la característica determinante de sus miembros. Cada sección esta encabezada por especificadotes de sección, las cuales pueden ser: • private: indica que los miembros pertenecientes podrán ser accedidos solamente dentro de la clase. • public: indica que los miembros pertenecientes podrán ser accedidos tanto dentro de la clase como por otras clases. • protected: indica que los miembros pertenecientes podrán ser accedidos dentro de la clase y por sus descendientes, pero son privados para otras clases. • published: los miembros pertenecientes, son idénticos a public, pero además 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); }; Las palabras reservadas private y public son especificadores de acceso privado y publico respectivamente, es decir, todos los métodos declarados en el área publica podrán ser accedidos por cualquier clase, mientras los privados sólo por la misma clase. Otros especificadores de acceso son protected, published, y automated. Se puede observar en esta estructura, que hemos declarado en la sección privada una variable global y dos métodos en la sección pública. 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. También puede ser un tipo de dato definido por el programador. Además una variable posee un nombre lógico que la representa variable1. En la declaración de los métodos, vemos que en el primer método llamado Metodo1 se antepone la palabra reservada void la cual hace referencia que este método
  • 12. Programación en C++ con C++Builder 12 no devuelve un ningún valor. Luego del nombre aparece encerrado entre paréntesis la palabra reservada void que representa que el método no recibe ningún valor como parámetro. El Metodo2, al igual que el anterior, no devuelve ningún valor, mientras que este recibe un parámetro un variable llamada variable2 del tipo de dato tipo. Para el Metodo3, este método devuelve un valor del tipo de dato tipo, mientras no recibe ningún parámetro. Para la implementación de los métodos, se debe anteponer al nombre del método el nombre de la clase con doble dos puntos (::) entre ellos, luego se encierra entre llaves ({ ...}) el código que se va a ejecutar cuando sea llamado este método. Podemos observar la implementación del Metodo1: void NombreDeLaClase::Metodo1(void) { // código } Para aclarar este concepto vamos a diseñar una clase que modele un rectángulo a la cual llamaremos TRectangulo, la cual debe poder calcular su superficie a partir de los lados. Primero debemos pensar que elementos caracterizan un rectángulo, con lo cual encontramos el ancho, el alto y la superficie. Luego, necesitamos métodos que nos permitan manipular estos datos, para ello tenemos debemos incorporar los datos mediante los métodos IngresarAncho e IngresarAlto, un método que calcule la superficie llamado CalcularSup y por último uno que devuelva o informe el valor de la superficie llamado InformarSup. La declaración de la cabecera clase se escribe como sigue: class TRegtangulo { private: float Ancho, Alto; float Superficie; public: void IngresarAncho(float Anchoi); void IngresarAlto (float Altoi); void CalcularSup(void); float InformarSup(void); Observación: el modelado de una clase puede variar de un programador a otro, por lo que no existe una única solución posible, ni una sola solución correcta.
  • 13. Programación en C++ con C++Builder 13 }; La implementación de los métodos 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 método CalcularSup se observa que se realiza la asignación de las variables recibidas como parámetro a los atributos de la clase. En el método CalcularSup realizamos el cálculo de la superficie que la almacenamos en el atributo Superficie. Por último en el método InformarSup, devolvemos o retornamos el valor de superficie que hemos calculado, mediante la palabra reservada return. Diagrama de clase. Un modelo sencillo, que nos ayuda a esquematizar una clase para acelerar su diseño, es el diagrama de clase. A su vez, nos permite interpretar rápidamente el diseño de una clase con una rápida lectura, con la particularidad de ser independiente del lenguaje con que se implemente la clase. Observación: toda expresión debe terminar con un punto y coma (;).
  • 14. Programación en C++ con C++Builder 14 Como observamos, el diagrama de clase se representa mediante un rectángulo, dividido en tres secciones: NombreDeLaClase, Atributos y Métodos. Para el ejemplo anterior, el diseño se observa en el diagrama de la derecha. Constructor. El método constructor es un método especial de la clase que permite inicializar atributos u otras variables necesarias de la clase. Este método es invocado automáticamente cuando se crea un objeto de esta clase. Posee algunas características importantes como: • No retorna ningún valor (ni siquiera void). • Puede recibir parámetros de cualquier tipo con excepción de la misma clase (si un puntero). • Para su declaración 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 rectángulo con los valores 10 y 20 respectivamente, y que realice el cálculo de la superficie para estos valores. La declaración del constructor se realiza en la parte pública, como se observa: class TRegtangulo { private: float Ancho, Alto; float Superficie; public: TRectangulo(void);
  • 15. Programación en C++ con C++Builder 15 void IngresarAncho(float Anchoi); void IngresarAlto (float Altoi); void CalcularSup(void); float InformarSup(void); }; La implementación del constructor, para realizar lo pedido es: TRectangulo::TRectangulo(void) { Ancho = 10; Alto = 20; // las dos expresiones anteriores // también se podrían escribir como // IngresarDatos(10, 20); CalcularSup(void); } Destructor. También se trata de un método 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 características importantes como: • No retorna ningún valor (ni siquiera void). • No recibe parámetros. • Para su declaración se utiliza el símbolo ~ seguido por el mismo nombre que la clase. La declaración del constructor se realiza en la parte pública, como se observa: class TRegtangulo { private: float Ancho, Alto; float Superficie; public: TRectangulo(void); ~TRectangulo(void); void IngresarAncho(float Anchoi); void IngresarAlto (float Altoi); void CalcularSup(void); float InformarSup(void);
  • 16. Programación en C++ con C++Builder 16 }; La implementación del constructor, para realizar lo pedido sería: ~TRectangulo::TRectangulo(void) { // no es necesario realizar nada para nuestro ejemplo } Resumen de conceptos importantes: Clase: es una abstracción, que modela las características 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 estímulos. Atributo: es una propiedad, cualidad o característica 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 cómo 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 específica de una clase. Evento: es un cambio en el entorno de una aplicación, las cuales pueden ser capturadas por una aplicación. Algunos eventos pueden ser: mover el mouse, presionar una tecla, hacer click o con doble click con el mouse, etc. Cuándo y porque modelamos una clase. Un error común, después de haber terminado de estudiar la POO, es creer que toda implementación o cálculo debe ir dentro de una clase. En vez de ello se pueden declarar simplemente funciones que realicen acciones específicas. 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 métodos. Entonces, cómo distinguimos cuando debemos modelar una clase? No es una pregunta que se pueda contestar fácilmente. Por ejemplo, si queremos saber la hora actual del sistema no es necesario crear una objeto para que lo realice, sino simplemente implementar una función que llame al sistema preguntando la hora, como lo realiza la función Now(). Esta clase de acciones son directas y de vida corta. Recordemos que la creación de un objeto siempre es más lento y consume mayor cantidad de recursos que la simple llamada de una función.
  • 17. Programación en C++ con C++Builder 17 Entonces…, para que construimos clases? Una clase es en esencia una estructura compleja cuya vida es dinámica, en la cual sus atributos van cambiando con el tiempo, pero siempre realizando una acción específica. Por ejemplo, podríamos 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 leído un nuevo dato, etc. Vemos que las obligaciones de esta clase son complejas, pero con una acción específica. 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 través de sus interfaces bien definidas, pero no conocer como se encuentran implementadas. Aunque podríamos conocer los detalles de su implementación de una clase, no debe escribirse código que dependa de ello, esto significa que la implementación 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 más importantes entre clases es la herencia. Es uno de los pilares fundamentales de la POO, mediante la cual se produce la transmisión de atributos y funcionalidades de una clase a otra, lo cual trae aparejado grandes ventajas como la de reutilización de código en la que se crean nuevas clases a partir de clases ya existentes por medio de la absorción de sus atributos y comportamientos, sobreponiéndolos o mejorándolos con las capacidades que las nuevas clases requieran. La herencia, nos permite definir una clase modificando una o más clases ya existentes. Estas modificaciones pueden consistir en añadir nuevos atributos y funcionalidades a la clase que se está definiendo, aunque también 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 más nuevas clases derivadas. Creándose de esta manera, una jerarquía de clases. Para especificar el uso de la herencia, después 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: // …
  • 18. Programación en C++ con C++Builder 18 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 Miembros clase hija Miembros clase madre private protected public private protected protected public protected public protected public protected public Los miembros private de la clase base son siempre inaccesibles para los métodos de la clase derivada a menos que se declare explícitamente que es un miembro friend en la clase base. No se tratará sobre miembros friend en este texto. Vamos a diseñar una clase que modele el volumen de un prisma a la cual llamaremos TPrisma. Para esta modelización recurriremos a la herencia que nos permitirá reutilizar código fuete ya existente. 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 diseñada.
  • 19. Programación en C++ con C++Builder 19 Si analizamos tridimensionalmente un prisma, podríamos pensarlo como una caja, la cual consta de una base rectangular y posee una altura asociada, con la cual genera su volumen. Matemáticamente podríamos 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 diseñada TRectangulo, la cual utilizaremos como clase base. A continuación diseñaremos la clase hija. Diseñando el diagrama de clase: class TPrisma : public TRectangulo{ private: float Altura; float Volumen; public: void IngresarAltura(float Alturai); void CalcularVolumen(void);
  • 20. Programación en C++ con C++Builder 20 float InformarVolumen(void); }; La implementación de los métodos es: void TPrisma::IngresarAltura(float Alturai); { Altura = Alturai; } void TPrisma::CalcularVolumen(void); { CalcularSup(); // Aquí llamamos al método 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 relación de herencia publica, la clase hija hereda automáticamente 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 sólo se puede acceder a través de sus métodos. Veremos a continuación, un segmento de código que ejemplifica la implementación del evento click de un botón del formulario, en el cual declaramos la instancia u objeto particular de la clase TPrisma. void __fastcall TForm1::BotonClick(TObject *Sender) { TPrisma Prisma; Nota: en la instanciación, sólo hacemos referencia a la clase hija, no se instancia la clase madre.
  • 21. Programación en C++ con C++Builder 21 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 también es llamada composición. 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 péndulo de un reloj bidimensional, como la conjunción de un rectángulo (brazo del péndulo) y un círculo (peso del péndulo), al cual queremos calcular el área. La clase contenedora TPendulo, contendrá a las clases miembro TRectangulo y TCirculo. Para continuar con el concepto de reutilización de código, utilizaremos a la clase TRectangulo antes definida y sólo diseñaremos a la clase TCirculo y modelaremos la clase TPendulo. Modelo bidimensional del péndulo de un reloj class TCirculo { private: float Radio; float Superficie; public: void IngresarRadio(float Radioi); void CalcularSup(void); float InformarSup(void); }; La implementación de los métodos es:
  • 22. Programación en C++ con C++Builder 22 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 implementación de los métodos es: void TPendulo::IngresarRadioPeso(float Radioi) { Circ.IngresarRadio(Radioi); } void TPendulo::IngresarLargoBrazo(float Largoi) { Rect.IngresarLargo(Largoi);
  • 23. Programación en C++ con C++Builder 23 } 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 contención se instanció las clases miembro en la parte privada de la clase (también se puede realizar en la parte publica, pero varia su implementación). Se implementaron métodos 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 método CalcularSup(), se llamó a los métodos CalcularSup() de cada una de las clases contenidas para que realicen el cálculo de su superficie y dispongan su valor, para realizar la suma de ambas superficies. Registros (struct). 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 declaración. Un ejemplo de esta definición: struct Tiempo { int hora; int minutos; Avanzado: Los objetos miembro se construyen en el orden en el que se declaran.
  • 24. Programación en C++ con C++Builder 24 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 evolución 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 declaración 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; 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 declaración inicial. El ejemplo es el mismo que para el struct de C, sólo 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 público (public).
  • 25. Programación en C++ con C++Builder 25 Definición de otros tipos
  • 26. Programación en C++ con C++Builder 26 Capítulo 3: Lógica de control En la programación, son necesarias herramientas que nos permitan hacer elecciones o tomar decisiones durante el proceso de ejecución 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 expresión lógica permitirá tomar una decisión. Expresión lógica. Una expresión lógica es una combinación de constantes, variables y funciones lógicas, con operadores lógicos y relacionales. Para comenzar a entender su uso, podemos definir una variables lógicas como una variable que puede contener sólo dos valores posibles: verdadero (trae o 1) o falso (false o 0). En C++ este tipo de variable se llama bool. Los operadores lógicos son aquellos que nos permiten concatenar o modificar expresiones lógicas, resultando un valor lógico. Ellos son: Operador Nombre Operación lógica ! not negación && and y lógico || or o lógico Para entender mejor su uso, vamos a ver como trabajan a traves de un ejemplo. Supongamos que tenemos dos variables lógicas A y B. A !A 0 1 1 0 A B A && B 0 0 0 0 1 0 1 0 0 1 1 1 A B A || B
  • 27. Programación en C++ con C++Builder 27 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 lógico. Ellos son: Operador Nombre Operación lógica > mayor mayor que < menor menor que <= menor o igual menor o igual que >= mayor o igual mayor o igual que != distinto distinta que == igual igual que Vamos a ver como trabajan a través de un ejemplo. Supongamos que tenemos tres variables A=5, B=5 y C=7. Expresión Resultado A>B 0 A>=B 1 A<=C 1 A!=B 0 A!=C 1 A==B 1 A==C 0 Estructura condicional “ if ” Es una estructura simple que permite ejecutar una instrucción o un bloque de instrucciones sólo si se cumple una expresión lógica, es decir, se ejecuta sólo si el resultado de la expresión lógica es verdadero. if (expresión_lógica) {acción;}; Observación: No hay que confundir el operador ==, con el operador =, dado que el primero significa comparación, mientras el segundo asignación. declaran.
  • 28. Programación en C++ con C++Builder 28 Si la expresión lógica es verdadera (o 1) la acción se ejecuta, si es falsa se ignora la acción y se continua con la instrucción siguiente a la estructura condicional. Si se quiere ejecutar una sola acción el uso de las llaves es opcional. Esta estructura también permite ejecutar una acción si no se cumple (else) la expresión lógica. Su estructura sería: if (expresión_lógica) {acción_1;} else {acción_2;}; En este caso, si la expresión lógica es verdadera (o 1) la se ejecuta la acción_1, si es falsa se ejecuta la acción_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 lógica, supongamos A, con la cual queremos realizar una acción sólo si su valor es verdadero. En este caso se puede utilizar directamente esta variable como una expresión lógica y no es necesario realizar la comparación con true, por ejemplo: if (A == true) C = A - B; if (A) C = A - B; La expresión se evalúa 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 automáticamente por C++, reconociendo como falso al valor 0 y como verdadero a distinto de 0. Obsérvese en los ejemplos anteriores que el operador de igualdad tiene un doble signo de igual (==), en tanto que el operador de asignación sólo tiene uno (=). Uno de los errores comunes es el empleo del operador de asignación cuando se quiere utilizar el de igualdad. Por ejemplo, si escribimos: if (x = 20) {acción}; En este caso se asigna a x el valor 20 y, como la operación tendrá éxito, la expresión será evaluada como true. Un error como este, aunque aparentemente obvio, puede ser difícil de localizar.
  • 29. Programación en C++ con C++Builder 29 Las instrucciones if se pueden anidar en caso de ser necesario. Anidar no es más que emplear una instrucción if como acción de seguida de una o más instrucciones if adicionales: if (x > 10) if (x < 20) {acción}; Estructura condicional “ switch ” La instrucción switch se prodría considerar como una extención de la instrucción if. Permitiendo ejecutar múltiples acciones evaluando una sola variable de control a la cual llamaremos selector, que de acuerdo a su valor en el instante que se evalúa corresponderá la acción 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 expresión; siempre y cuando cumplan con la condición. Cada uno de los valores de los casos para los cuales hemos definido una acción, deben corresponder a un valor que pertenece al tipo de dato del selector. Esta estructura también permite la definición de una acción que se ejecutará por defecto si ninguno de los casos anteriores se cumple. Pero su definición es opcional. En el caso de que un caso se cumpla, se ejecuta la acción definida para este caso hasta que se encuentra con la instrucción break, que es una instrucción que permite salir del bloque de código que se esta ejecutando, en este caso del bloque switch. Si no lo encuentra, se seguirán ejecutando las acciones de los casos siguientes hasta terminar todos los casos o hasta encontrarse con un break. Debe notarse que la instrucción switch sólo funciona cuado existe una igualdad entre el selector y alguno de los case, por lo que no será de utilidad en el caso de situación
  • 30. Programación en C++ con C++Builder 30 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 número ingresado por el usuario, almacenando en una variable lógica (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 división por 2 sólo puede tomar estos valores. El mismo ejemplo se podría haber resuelto de tres formas más sencillas 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 la vocal a”; break;} case ‘b’: {Resultado = “es la vocal b”; break;} case ‘c’: {Resultado = “es la vocal c”; break;} case ‘d’: {Resultado = “es la vocal d”; break;} case ‘e’: {Resultado = “es la vocal e”; break;} default: {Resultado = “no es vocal”;} }
  • 31. Programación en C++ con C++Builder 31 Capítulo 4: Estructuras Repetitivas: "CICLOS" Normalmente dentro de un programa, es necesario realizar acciones de forma repetida, por ejemplo, imaginemos que queremos ejecutar 100 veces una acción, podríamos escribir 100 veces la misma línea o bien indicar que ejecute 100 veces la misma línea. Para ello, se creó en el lenguaje de programación, las estructuras for, while, y do while, que son las que nos permitirán codificar ciclos o bucles según sea necesario. Primero, debemos saber que todo ciclo, tiene una condición inicial, que inicia el ciclo, una condición final, que, cuando se cumple, el bucle finaliza, y un cuerpo o bloque de código que el ciclo realizará. El cuerpo contiene la instrucción que se ejecuta cada vez por medio del ciclo y puede incluir cualquier código válido en C++. Revisemos cada ciclo por separado: Ciclo for. La estructura for (“durante”), se utiliza para realizar, generalmente, una acción cierta cantidad determinada y definida de veces. Para ello, consta de tres parámetros que debemos definir: • Inicialización, • Condición de salida • Incremento En la inicialización, se procede a declarar una variable auxiliar, llamada variable de control, cuyo ámbito de existencia y trabajo es dentro del ciclo, dándole un valor inicial, por ejemplo el valor uno. Para establecer la condición de salida, se debe saber cuántas 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 finalización sería i == 10 (en este caso el ciclo se ejecutará si la condición es false), pero es preferente determinarle el rango de 1 a 10 haciendo i < = 10, mientras esta condición se mantenga en true, el ciclo realizará la acción que el cuerpo determine, al momento de no cumplirse la condición de salida, el programa sigue ejecutando la sentencia que sigue inmediatamente al cuerpo del ciclo. En síntesis, si como condición de salida especifico un rango de la variable de control, el ciclo se ejecutará mientras esta condición 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.
  • 32. Programación en C++ con C++Builder 32 También, debo determinar la manera de incrementar la variable de control, es decir, especificar si i varía 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 (inicialización; condición de salida; incremento) {acción;}; Ejemplo: a continuación, implementaremos una función, en la que se reproducirá la función pow incluida en la librería 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, evaluándose siempre primero la condición de salida, y en cada paso del ciclo, las variables puestas en juego toman los siguientes valores: Condición Finalización i Resultado Antes de entrar al for ----- No existe 1 Primer paso true 1 Base Segundo paso true 2 Base^2 Tercer paso true 3 Base^3 true ... exponente paso true exponente Base^exponente Saliendo del for false No existe Base^exponente Condición if No existe Depende del signo del exponente Nota: La utilización 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.
  • 33. Programación en C++ con C++Builder 33 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 sólo una sentencia, de manera tal que si se requiere realizar más de una acción, debemos encerrar todo el bloque de código del ciclo entre llaves (sentencia compuesta), por ejemplo: for (int i=10; i>=0; i--) { acción_1; acción_2; . . acción_n; } Ciclo while El ciclo while ("mientras") difiere del ciclo for en que sólo contiene una condición de prueba, que se verifica al principio de cada iteración. Mientras la condición sea true el ciclo continúa funcionando. La sintáxis correspondiente es: while (expresión_lógica) {acción_1; acción_2; . . acción_n;}; En la misma, la acción se realiza mientras la expresión lógica sea verdadera (valor distinto de cero). Es de vital importancia que la acción tenga alguna forma de modificar el valor de la expresión lógica, para que, en algún momento, sea falsa y el ciclo finalice. Si de entrada la expresión lógica da falsa, la acción del ciclo nunca se realiza. Veamos un ejemplo de la utilización de esta estructura, supongamos que obtener la potencia a la cual hay que elevar el número 2 para obtener el valor 1024.
  • 34. Programación en C++ con C++Builder 34 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 prácticamente igual al while. Sin embargo, la diferencia entre los dos es importante, ya que el ciclo while evalúa la expresión condicional al principio del ciclo; en el caso de do-while ("hacer – mientras"), la expresión se evalúa al final del propio ciclo. La sintaxis de este bucle es: do {acción;} while (exprlógica); Debido a la manera como funciona el ciclo do-while, el código en el cuerpo del ciclo se ejecuta al menos una vez, sin importar el valor de la condición de prueba (ya que se evalúa al final del ciclo). En el caso del while, la condición se evalúa al principio, por lo que es posible que nunca se ejecute el cuerpo del ciclo. También en este caso, la modificación de la expresión lógica debe ser explícita en el bloque de código, para que el ciclo finalice en algún momento, cuando la expresión condicional resulte falsa. Un ejemplo sería: int x = 1024; int n; do {x = x / 2; n++;} while (x > 1);
  • 35. Programación en C++ con C++Builder 35 Donde n, guarda nuevamente la potencia a la que hay que elevar el valor 2 para obtener el número 1024. Es un error común, que se trate de realizar una acción 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 acción imposible tal como el la división por cero, por ejemplo. Para ver más gráficamente el error, analizaremos un código erróneo para ejemplificar. float x = 0; float y; do {y = 512 / x; //error al tratar de dividir por cero!!! x = x + 2.0;} //acumulo en x el valor anterior de x más 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 ejecución del ciclo en el programa. La instrucción continue se emplea para forzar la ejecución del programa hasta el final del ciclo, saltando cualquier expresión situada después de continue. La instrucción break se usa para detener la ejecución de un ciclo antes de que se cumpla la condición 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 programación en C++ para descubrir todos los posibles usos de estas dos instrucciones. De todas maneras, a continuación veremos la utilización 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 confirmación de que podemos leer los 8 bits de data. Utilizaremos dos funciones genéricas (estas funciones no están implementadas, son sólo a modo de ejemplo) una para leer un bit del control a la que llamaremos LeerBitControl (suponemos que esta función devuelve true si se puede leer el puerto data), y una que nos permitirá leer el data, que llamaremos LeerDato(suponemos que esta función devuelve el valor entero del dato leído).
  • 36. Programación en C++ con C++Builder 36 for(;;){ if(LeerBitControl())break; } int x = LeerDato(); En este caso, el for se utiliza a modo de delay o retardo hasta que llegue la confirmación de lectura del puerto. En el caso que consideremos usar un bit de status para que haga comenzar o detenga la adquisición del dato, según sea true o false. int x=0; for(;;){ if(LeerBitStatus())break; for(;;){ if(LeerBitControl())break; } x += LeerDato(); } Para ejemplificar el uso de la instrucción continue, podemos considerar el caso anterior, haciendo la salvedad de que el siguiente ejemplo es un ciclo infinito, y es sólo a modo de ejemplo. int x=0; while(!detener){ if(LeerBitStatus())continue; for(;;){ if(!LeerBitControl())break; } x += LeerDato(); } Avanzado: verificar que si al for le falta alguno o varios de sus parámetros, también funciona, si utilizamos la sentencia break.
  • 37. Programación en C++ con C++Builder 37 Capítulo 5: Vectores y Matrices Se hace evidente que a lo largo de un programa, necesitamos guardar información, o bien, trabajar con información que debemos almacenar en distintas estructuras. De esta necesidad, surgen un tipo de estructura de datos llamados genéricamente como arreglo (array). De esta manera, surgen los vectores que son arreglos unidimensionales y las matrices que son arreglos multidimensionales. 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 dimensión, 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 número entre corchetes indica la cantidad de valores del tipo que se indican, NO es el subíndice del mayor elemento. Además todos los subíndices comienzan en cero, es decir el primer valor del vector es en la posición cero, y el último es en n-1 (en el caso anterior, n-1=5-1=4). Observemos de manera esquemática como sería la asignación de memoria por parte del compilador: Vector[0] Vector[1] Vector[2] Vector[3] Vector[4] Valor int A Valor int B Valor int C Valor int D 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 análoga, para la matriz bidimensional, asignamos memoria para M*N números 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 n- dimensionales se requieren tantos subíndices como dimensiones tenga el espacio en el que estemos trabajando.
  • 38. Programación en C++ con C++Builder 38 Hay que prestar atención especial a no sobreescribir el final de un arreglo. Una característica poderosa de C++ es el acceso directo a memoria; debido a ella, C++ no nos impide escribir a una ubicación determinada de la memoria, aunque sea una posición a la que se supone que no debe tener acceso el programa que estamos elaborando. El siguiente código es válido, pero producirá la detención del programa: int vector[5]; vector[5]=31; Este es un error que se comete frecuentemente, dado que los arreglos tienen base 0. Podríamos pensar que el último elemento del arreglo es 5, cuando en realidad es 4. Es posible solicitar que, automáticamente, se verifique que los índices se encuentren dentro del rango de la definición del arreglo, activando la directiva de compilación $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 posición del vector marcada por el índice, que puede ser de cualquier tipo (entero, flotante, booleano, etc.).
  • 39. Programación en C++ con C++Builder 39 Capítulo 6: Cadenas de caracteres Una cadena de caracteres se puede definir como una secuencia o un vector de caracteres, que están 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 carácter de la tabla ASCII (Anexo I). Esta tabla es una tabla de correspondencia entre un caracter y un número 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 definición es heredada del lenguaje “c” aunque su uso ha disminuido. Pero conserva algunas ventajas como son su simpleza y el menor recurso ocupado. Se definición 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”; También se puede realizar la asignación a cada caracter: Cadena[2] = ‘n’; Nota: es importante diferenciar cuando se asigna un carácter a una variable se utiliza comillas simple (‘A’), mientras para las cadenas se utilizan comillas dobles (“Computación”)
  • 40. Programación en C++ con C++Builder 40 Cadena[3] = ‘P’; // ahora cadena vale “ConPutación” 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 métodos para su manipulación. Para su utilización no es necesario especificar la longitud en la definición, dado que se puede modificar en forma dinámica con la asignación de una nueva cadena. string Cadena = “Bioingenieria”; Esta clase es muy flexible y práctica aunque no la vamos a desarrollar dado que C++Buider posee su propia definición de cadena de caracteres que veremos a continuación. AnsiString Es una clase especialmente diseñada para la manipulación de cadenas de caracteres definida por Borland®. Su definición tiene la forma: AnsiString Cadena = “Bioingenieria”; Esta clase define varios métodos que facilitan la manipulación 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 posición (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” Nota: es importante diferenciar que en la cadena c++string el subíndice del primer caracter es el 0 (cero), mientras que para AnsiString es el 1 (uno).
  • 41. Programación en C++ con C++Builder 41 Length() Devuelve la longitud (el número de bytes) de la cadena int Longitud = Cadena.Length(); // Longitud = 13 Insert(subcadena, pos) Inserta una subcadena en nuestra cadena en la posición 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 posición 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 posición 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 posición del primero. int posicion = Candena.Pos(“in”); // posicion = 4 LowerCase() Devuelve la cadena en minúscula. AnsiString cad = Cadena.LowerCase(); // cad = “bioingenieria” UpperCase(); Devuelve la cadena en mayúscula. AnsiString cad = Cadena.UpperCase(); // cad = “BIOINGENIERIA”
  • 42. Programación en C++ con C++Builder 42 Capítulo 7: Archivos de Texto. Hasta ahora hemos visto cómo procesar información, y hemos mantenido el flujo de entrada / salida de información a través de componentes visuales. Pero muchas veces la información necesaria, de entrada o salida, se presentará en estructuras de datos llamadas archivos, almacenadas en nuestro disco rígido. Es por ello, que en este capítulo nos centraremos en el manejo del flujo de entrada / salida de información desde y hacia el HD. Los archivos de texto tienen la capacidad de almacenar caracteres de la tabla ASCII, y su nombre físico (nombre con el cuál está almacenado en el HD) tiene el mismo formato que cualquier otro archivo, a saber: NombreFísico.extensión, por ejemplo el archivo de texto “Leame.txt”, su nombre es Leame y su extensión es txt (de texto). No necesariamente el archivo de texto debe tener la extensión txt, puede poseer cualquier otra extensión. 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 línea y el caracter de fin de archivo (EOF, end of file) Para manipular los archivos, C++ nos presenta una jerarquía de clases especialmente diseñadas 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 básicas que se realizan sobre los archivos, estas son: • Creación del objeto. • Apertura del archivo. • Manipulación del archivo. • Cierre del archivo. Creación del objeto. Para la creación 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;
  • 43. Programación en C++ con C++Builder 43 Apertura del archivo. La apertura de un archivo establece la conexión entre el nombre lógico y el nombre físico de nuestro archivo, abre el archivo y lo prepara para su manipulación. Esto se puede realizar de dos maneras, la primera es a través del método open: void open(const char *nombre_archivo, openmode modo); Este método puede recibir dos parámetros, el primero es una cadena de caracteres que representa el nombre físico del archivo que será abierto, y opcionalmente puede recibir un segundo parámetro que representa al modo que se abrirá. Puede ser alguna de las siguientes opciones: ios::in Abre el archivo para lectura ios::out Abre el archivo para escritura ios::ate Abre un archivo existente y se posiciona al final ios::app Abre un archivo de salida para agregar al final ios::nocreate Abre un archivo sólo si ya existe. ios::noreplace Abre un archivo sólo si no existe. ios::trunc Abre un archivo, si ya existe borra todo su contenido ios::binary 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 parámetro opcional del método, dado que de acuerdo a la clase hayamos creado el objeto, posee un modo de apertura por defecto. Estos son: Clase Modo por defecto ofstream ios::out | ios::trunc ifstream ios::in fstream ios::in | ios::out La segunda manera de abrir un archivo, es combinándola con la creación del objeto. Esto se puede realizar gracias a que el constructor de estas clases puede recibir el nombre del archivo físico como parámetro y realiza internamente la llamada al método open. ifstream ArchivoEnt(“datos.txt”);
  • 44. Programación en C++ con C++Builder 44 Cierre del archivo. Como se abra dado cuenta nos salteamos, el apartado correspondiente a la manipulación del archivo. Esto lo hacemos dado que es la parte más compleja, y preferimos dejarlo para el final. Al terminar la manipulación del archivo, se debe cerrar el vínculo que hemos creado con nuestro archivo físico, para liberarlo y permitir que otros programas (o procesos) puedan usarlo. A demás se realizan otras acciones internas como liberar la memoria de un buffer creado, terminar de escribir sobre el archivo (dado que esta acción se realiza de a bloques), etc. Esta acción se realiza mediante la llamada al método close(). ArchivoEnt.close(); Una vez cerrado el archivo, este objeto esta disponible para abrir nuevamente otro archivo o ser destruido. El cierre del archivo también se realiza de forma automática 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 método close(). Manipulación del archivo. Con este término nos referimos, a la acción 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 métodos. Operadores de lectura / escritura Existen dos operadores: 1. Operador de inserción: << 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 conversión de tipo de forma automática. Vamos a ver algunos ejemplos: Código ejemplo Contenido archivo 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
  • 45. Programación en C++ con C++Builder 45 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 separación de un carácter de espacio que se realiza de forma automática. Al final de cada renglón agregamos endl para insertar un caracter de fin de línea, para movernos a la siguiente línea. String Texto = “Hola”; ArchivoSal << Texto << “1” << endl; ArchivoSal << Texto << “ 2” << endl; Hola1 Hola 2 Ahora vemos que podemos también realizar la inserción del contenido una variable entera, cuyo contenido se convierte de forma automática en una cadena de caracteres. A demás se puede observar otra forma de insertar el caracter de fin de línea agregando n int num = 1; ArchivoSal << num << “Holan”; Num++; ArchivoSal << num << “ Holan”; 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; ofstream Archi("datos.txt"); 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
  • 46. Programación en C++ con C++Builder 46 2. Operador de extracción: >> 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 línea. Similar al anterior, el texto puede ser una cadena de caracteres o no, gracias a que estas clases saben realizar la conversión de tipo de forma automática, la conversión se realizará de acuerdo al tipo de dato de la variable que definamos. Vamos a ver algunos ejemplos: Contenido archivo Código ejemplo variables En este primer ejemplo vemos como extrae una simple cadena de caracteres de un archivo de texto tipo ifstream llamado ArchivoEnt. alumnostring Texto; ArchivoEnt >> Texto; Texto = “alumno” En este par de ejemplos, vemos como el mismo código permite leer cadenas de caracteres sucesivos independientes que estén separadas por un caracter de espacio o de fin de línea. alumno1 alumno2string Texto1, Texto2; ArchivoSal >> Texto1 >> Texto2; Texto1 = “alumno1” Texto2 = “alumno2” alumno1 alumno2 string Texto1, Texto2; ArchivoSal >> Texto1 >> Texto2; Texto1 = “alumno1” Texto2 = “alumno2” Ahora vemos que también podemos extraer la información independiente de que este sea un entero. Dado que la segunda extracción la hacemos sobre una variable del tipo int, la conversión se realiza automáticamente. Hay que tener cuidado que el dato a leer sea un entero, dado que C++ realiza la lectura igualmente pudiéndose obtener información errónea. alumno 1int num; string Texto; ArchivoSal >> Texto >> num; Texto = “alumno” num = 1
  • 47. Programación en C++ con C++Builder 47 Métodos de lectura / escritura Como dijimos anteriormente, la lectura y escritura de datos también se puede realizar mediante llamadas a métodos de la clase. Veamos cuales son: • get() y getline(): Estos métodos permiten realizar la lectura de toda una línea, hasta que encuentra un caracter de terminación. Reciben tres parámetros. El primero es un puntero a un vector de caracteres (buffer), el segundo el tamaño del vector, y el tercero (opcional) el caracter de terminación. Por defecto este caracter es el “n”, llamado caracter de fin de línea. Si el primer caracter de la línea es el carácter de terminación, devuelven un vector de longitud cero. Pero su gran diferencia radica, en que el método get() se detiene, y una segunda llamada al método devuelve el mismo resultado, hasta que se cambie el caracter de terminación. En cambio, una segunda llamada al método getline() devuelve la siguiente línea, por lo que normalmente se utiliza este método. Otra diferencia radica en que el método get() puede ser llamado sin ningún parámetro. En este caso devuelve el caracter siguiente.. Métodos especiales • eof() Es uno de los métodos más importantes. Devuelve true si se llegó al final de archivo. Encontró el carácter EOF. • is_open() Este método devuelve true si se abrió correctamente el archivo. • good() Este método devuelve true si no ocurrió ningún error. • bad() Este método devuelve true si ocurrió algún error con el buffer. • fail() Este método devuelve true si ocurrió algún error que no afecte al buffer.