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

EEST N° 5 Amancio Willians 1

Prof. Abdala Achaval Pablo


Notas Preliminares 3
Introducción a la Programación en C++ 3
Estructura de un programa en “C” 5
Palabras reservadas en C++ 5
Tipos de datos en C++ 6
Tipos de datos numéricos reales 7
Caracteres en C++ 7
Identificadores en C++ 8
Literales en C++ 9
Literales enteros en base octal 9
Literales enteros en base hexadecimal 10
Literal numérico real en C++ 10
Literal de cadena de caracteres en C++ 11
Variables y constantes en C++ 11
Declaraciones de constantes en C++ 11
Operadores C++ 11
Operadores aritméticos 12
Operadores relacionales y lógicos 14
Operadores a nivel de bits 15
Operadores de asignación. 15
Operador condicional 16
Otros operadores 17
Operador de dirección 17
Operador de indirección 17
Operador referencia a 18
Operador global y de resolución de ámbito 18
Prioridad y orden de evaluación de los operadores en C++ 19
Casting. Conversión entre tipos de datos en C++ 19
Estructura de un programa C++ 21
using namespace std; 22
int main (void) 23
Salida con formato en C++. Manipuladores 23
Leer caracteres y cadenas de caracteres en C++ 25
Método get() para leer un carácter 26
Método getline() para leer una cadena de caracteres 27
Limpiar el Buffer del Teclado 29
Sentencias de iteración – Ciclos repetitivos 29 a
Sentencia For 31
Sentencia while
Sentencia do – while
Generar Números Aleatorios en C++ 31
Enum 33
Funciones en C++. 34 a
Ambito de una variable en C++ 47
Sobrecarga de Funciones en C++
Arrays / Vectores /Arreglos en C++ 47 a
Vectores Bidimensionales o Matrices 60
Ordenamiento de Vectores
Ordenamiento Por Selección (Selection Sort)
Ordenamiento BubbleSort o Burbuja o Intercambio Directo
Ordenamiento Por Inserción Directa
Método De Ordenamiento Por Inserción Binaria
Ordenamiento por el Método Shell
Ordenamiento Heap Sort
Búsqueda de elementos en un Vector

EEST N° 5 Amancio Willians 2


Prof. Abdala Achaval Pablo
Búsqueda binaria
Archivos 60 a
Archivos de entrada 62
Archivos de salida
Registros / Data Structures / Estructuras 62
Tratamiento de Cadenas CHAR como "arreglos o vector de char", "cadenas", o "cstring". 63
C++ String 75
Librería math.h 88
Punteros 90
Clases 104
Constructores. a
Destructores. 132
Herencia
Herencia Múltiple
Cadena de Herencia
Polimorfismo
Templates 132
Introducción a Visual C++ Builder de Embarcadero RAD Studio XE series 136 a
Conceptos básicos Visual. 167
Eventos o acciones (sobre un componente):
Conversión de tipos:
Ventanas de mensaje
Pedir datos al usuario en ventanas:
Ampliación llamadas a cuadros de diálogo:
Construcción de una aplicación con dos formularios. Mensajes
progressbar1 Timer
Uso de grilla StringGrid
Pizarra de dibujo
Eventos del Mouse: Dibujar en la Pizarra:
Uso del Timer y posición del objeto:
Eventos del teclado: dirección de nave.
Animación. Protector de pantalla
uso de componentes de texto. memo
uso de componentes de texto. richedit y actionlist
Labels.
Base de datos
Acceso con base de datos Acces desde FireDAC
Acceso a taboas utilizando ADO
Componentes de datos en el formulario principal
Acceso a base de datos SQlite desde una aplicación móvil. Lista de tareas.
Ejercicios / Guía de Trabajos Prácticos 168
Bibliografía 194

EEST N° 5 Amancio Willians 3


Prof. Abdala Achaval Pablo
Notas Preliminares

La Programación es el arte de dar soluciones a los problemas para que la computadora pueda ejecutarlas. La
gran parte del esfuerzo en programar es buscar soluciones y refinarlas. Este apunte es para alguien que nunca
ha programado antes, pero que está dispuesto a trabajar duro para aprender. Asimismo, le ayudará a
comprender los principios y adquirir los conocimientos prácticos de la programación usando el lenguaje de
programación C++.

¿Por qué C++? No se puede aprender a programar sin un lenguaje de programación, y C++ apoya
directamente los principales conceptos y técnicas que se utilizan en el mundo real del software. C++ es uno
de los lenguajes de programación más ampliamente utilizados. La mayoría de los conceptos de programación
pueden utilizarse directamente en otros lenguajes, como C#, Fortran, PhP y Java. Por último, C++ es
frecuente elegirlo como lenguaje para escribir código elegante y eficiente. La hipótesis fundamental es desear
escribir los programas para el uso de otros, y de hacerlo con responsabilidad, proporcionando un buen nivel
de calidad de todo el sistema, es decir, lograr un muy buen nivel de profesionalismo.

La programación se adquiere haciendo programas. En este tipo de programación es similar a la de otras


actividades con un componente práctico. Las personas no pueden aprender a nadar, a tocar un instrumento
musical, o conducir un coche solo con leer un libro. Todos debemos practicar. No se puede aprender a
programar sin leer y escribir bastante código. Se necesita hacer los ejercicios y acostumbrarse a las
herramientas para escribir, compilar y ejecutar los programas.

Introducción a la Programación en C++


a) Introducción Teórica

Creador:

Dennis Ritchie (Laboratorios Bell) en 1972, cuando trabajaba junto con Ken Thompson diseño del sistema
operativo UNIX.

El „C‟ se creó como herramienta para programadores, en consecuencia su principal objetivo es ser un lenguaje
útil.

C++ es un lenguaje de programación creado a mediados de los años 1980 por BJarne Stroustrup.
La intención de su creación fue extender al exitoso lenguaje de programación C con mecanismos que permitan
la manipulación de objetos.

Características:

El “C” es un lenguaje de programación de “alto nivel” (alto nivel quiere decir “próximo al lenguaje humano”),
pero con características de “bajo nivel” (bajo nivel= próximo al lenguaje máquina).

Es de ALTO NIVEL porque es racional, estructurado y fácil de aprender.

Es de BAJO NIVEL porque permite trabajar con “bits”, registros de la C.P.U. y posiciones de memoria.

¿Por qué el “C”?

El lenguaje „C‟ es poderoso y flexible: la mayor parte del sistema operativo UNIX fue escrito en „C‟.

Incluso están escritos en „C‟ los compiladores e intérpretes de otros lenguajes, como FORTRAN, APL,
PASCAL, LISP, LOGO y BASIC.

EEST N° 5 Amancio Willians 4


Prof. Abdala Achaval Pablo
El lenguaje „C‟ es “amistoso” porque es lo suficientemente estructurado para ejercer buenos hábitos de
programación. Es el lenguaje de programación más utilizado por el programador de sistemas.

Estructura de un programa en “C”:

El „C‟ es gráficamente:

CÓDIGO FUENTE: es el programa que nosotros escribimos, se graba con la extensión CPP

CÓDIGO OBJETO: es el programa fuente pero traducido a lenguaje máquina (sucesión de ceros y unos), se
graba con la extensión OBJ

PROGRAMA EJECUTABLE: es el programa objeto más las “librerías del C”, se graba con la extensión
EXE. Y no necesita el programa que hemos utilizado para crearlo, para poder ejecutarlo.

El código Objeto que genera un compilador de “C”, es casi tan eficiente (rápido) como si lo hubiéramos
escrito en lenguaje ENSAMBLADOR (lenguaje de programación más próximo al lenguaje máquina).

El presente apunte está orientado a la construcción de programas sobre el compilador Dev C++ y
Embaracdero XE8 C++ Rad Studio

Palabras reservadas en C++


Las palabras reservadas son identificadores predefinidos que tienen significados especiales y no pueden usarse
como identificadores creados por el usuario en los programas.

Las palabras reservadas de C++ pueden agruparse en 3 grupos.

El primero contiene las palabras de C y que C++ como evolución de C también contiene:

auto const double float int


short struct unsigned break continue
else for long signed switch
void case default enum goto
register sizeof typedef volatile char
do extern if return static
union while

Palabras que no provienen de C y que, por tanto, solo utiliza C++:

asm dynamic_cast namespace reinterpret_cast try bool explicit


new static_cast typeid catch false operator template
typename class friend private this using const_cast inline
public throw virtual delete mutable protected true wchar_t

EEST N° 5 Amancio Willians 5


Prof. Abdala Achaval Pablo
Las siguientes palabras reservadas se han añadido como alternativas para algunos operadores de C++ y hacen
los programas más legibles y fáciles de escribir:

and bitand compl not_eq or_eq xor_eq and_eq bitor not or xor

Tipos de datos en C++


Los tipos de datos en C++ se clasifican en primitivos y derivados.

Los tipos de datos primitivos son los que están definidos dentro del lenguaje.

Los tipos de datos derivados se forman a partir de los tipos primitivos.

En este tema veremos los tipos primitivos y en temas siguientes estudiaremos los tipos derivados.

Los tipos de datos primitivos en C++ son: numéricos enteros, numéricos reales, tipo lógico y tipo carácter
ampliado.

Tipos de datos C++ numéricos enteros


El tipo de dato numérico entero es un subconjunto finito de los números enteros del mundo real. Pueden ser
positivos o negativos.
En C++ los tipos de datos numéricos enteros son los siguientes:
Número de bytes
Tipo de Dato Descripción Rango
típico
short Entero corto 2 -32768 a 32767
int Entero 4 -2147483648 a +2147483647
long Entero largo 4 -2147483648 a +2147483647
char Carácter 1 -128 a 127
Con los tipos enteros pueden utilizarse los calificadores signed y unsigned. Estos calificadores indican si el
número tiene signo o no. Si se usan solos, sin indicar el tipo de dato se asume int.
Por ejemplo, las siguientes declaraciones son equivalentes:
unsigned int x; equivale a: unsigned x;
Usando estos calificadores podemos tener los siguientes tipos enteros:

Número de
Tipo de Dato Descripción Rango
bytes típico
signed short Entero corto 2 -32768 a 32767
unsigned short Entero corto sin signo 2 0 a 65535
signed int Entero 4 -2147483648 a +2147483647
unsigned int Entero sin signo 4 0 a 4294967295
signed long Entero largo 4 -2147483648 a +2147483647
unsigned long Entero largo sin signo 4 0 a 4294967295
signed char Carácter 1 -128 a 127
unsigned char Carácter sin signo 1 0 a 255

Podemos ver que los datos enteros de tipo signed son equivalentes a los enteros sin utilizar el calificador:

EEST N° 5 Amancio Willians 6


Prof. Abdala Achaval Pablo
signed int a; es equivalente a escribir int a;

Tipos de datos numéricos reales


El tipo de dato numérico real es un subconjunto finito de los números reales. Pueden ser positivos o negativos.
En C++ los tipos de datos numéricos reales son los siguientes:
Tipo de Número de
Descripción Rango
Dato bytes típico
Real (Número en coma Positivos: 3.4E-38 a 3.4E38
float 4
flotante) Negativos: -3.4E-38 a -3.4E38
Real doble(Número en
Positivos: 1.7E-308 a 1.7E308
double coma flotante de doble 8
Negativos: -1.7E-308 a -1.7E308
precisión)
Positivos: 3.4E-4932 a 1.1E4932
long
Real doble largo 10 Negativos: -3.4E-4932 a -1.1E4932
double

Tipo lógico
Los datos de este tipo sólo pueden contener dos valores: true ó false (verdadero ó falso).
Si se muestran como enteros, el valor true toma el valor 1 y false el valor 0.
Tipo de Número de
Descripción Rango
Dato bytes típico
bool Dato de tipo lógico 1 0, 1

Tipo carácter extendido


Este tipo se utiliza para representar caracteres UNICODE. Utiliza 2 bytes a diferencia del tipo char que solo
utiliza 1.
Tipo de Número de
Descripción Rango
Dato bytes típico
wchar_t Carácter Unicode 2 0 a 65535

Caracteres en C++
El conjunto de caracteres que se pueden usar en un programa C++ para dar nombre a variables, constantes,
funciones, clases, etc, etc son los siguientes:

- Letras mayúsculas y minúsculas de la A(a) a la Z(z) del alfabeto inglés.

- Dígitos del 0 al 9.

- El carácter subrayado o guión bajo _

- Caracteres especiales y signos de puntuación:


+ - * / = % & # ! ? ^ “ „ ~
\ | < > ( ) [ ] { } : ; . ,

EEST N° 5 Amancio Willians 7


Prof. Abdala Achaval Pablo
- Espacios en blanco: Se llaman espacios en blanco a todos los caracteres cuya misión es separar elementos
de un programa.

Los caracteres espacios en blanco que pueden aparecer en un programa C++ son los siguientes:

el espacio en blanco
tabulador horizontal
tabulador vertical
avance de página
nueva línea

- Secuencias de escape: Una secuencia de escape esta formada por una barra
inversa seguida de una letra o de una combinación de dígitos.

Una secuencia de escape siempre representa un solo carácter aunque se escriba con dos o más caracteres.

Se utilizan para realizar acciones como salto de línea o para usar caracteres no imprimibles.

Las secuencias de escape definidas en C++ son:

Identificadores en C++
Los identificadores son los nombres que se les da a los objetos de un programa.

Los identificadores en c++ están formados por letras y dígitos.


El primer carácter debe ser una letra, considerando en este caso el carácter guión bajo ( _ ) como una letra. No
pueden contener otros caracteres especiales.

Ejemplo Identificadores válidos en C++:

EEST N° 5 Amancio Willians 8


Prof. Abdala Achaval Pablo
X y12 suma_1 _nota nombres

area porc_imp TABLA

Ejemplo Identificadores no válidos en C++:

4numeros "x" orden-no

contador! nº $edad

Como norma general, un identificador debe tener los suficientes caracteres para que su significado se reconozca
fácilmente, pero se debe evitar un excesivo número de caracteres.
Un identificador puede tener cualquier número de caracteres, pero dependiendo del compilador utilizado, solo
son significativos los n primeros caracteres. Por tanto, dos identificadores son diferentes si difieren al menos en
uno de los n primeros caracteres.
No se permite el uso de la ñ ni de las tildes en los identificadores, aunque sí pueden ser utilizados en
comentarios.
C++ diferencia mayúsculas y minúsculas, por lo tanto, nombre y Nombre son identificadores diferentes.

Literales en C++

Un literal es cualquier valor numérico, carácter o cadena de caracteres que puede aparecer dentro de un
programa.
Por ejemplo, literales C++ válidos pueden ser: 150, 12.4, “JOSE”, etc.
Hay 4 tipos de literales en C++: numéricos enteros, numéricos reales, carácter y cadena de caracteres.
Literal numérico entero en C++
Un literal numérico entero en C++ puede expresarse en base decimal (base 10), base octal (base 8) y base
hexadecimal (base 16).
literales enteros en base decimal

Están formados por 1 o más dígitos del 0 al 9. El primer dígito debe ser distinto de cero.
Por ejemplo:
12
4303
4
El tipo del literal es int, unsigned int ó unsigned long int. Se toma como tipo, siguiendo ese orden, aquel en el
que su valor pueda ser representado.
También podemos usar los sufijos U, L, UL para indicar explícitamente el tipo del literal. U indica que es del tipo
unsigned int, L indica el tipo long y UL unsigned long. Por ejemplo:
1234 Tipo: int
1234U Tipo: unsigned int
1234L Tipo: long
1234UL Tipo: unsigned long

Literales enteros en base octal

Están formados por 1 o más dígitos del 0 al 7. El primer dígito debe ser cero.
Por ejemplo:
012

EEST N° 5 Amancio Willians 9


Prof. Abdala Achaval Pablo
0430
04
El tipo del literal entero en octal es int, unsigned int, long int ó unsigned long int. Se toma como tipo, siguiendo
ese orden, aquel en el que su valor pueda ser representado.
También podemos usar los sufijos U, L, UL para indicar explícitamente el tipo del literal.
Por ejemplo:
01234 Tipo: int
01234U Tipo: unsigned int
01234L Tipo: long
01234UL Tipo: unsigned long

Literales enteros en base hexadecimal

Están formados por 1 o más dígitos del 0 al 9 y letras de la A a la F. Estos literales deben comenzar por 0x ó 0X.
Por ejemplo:
0x1A2
0X430
0xF4
El tipo del literal entero en hexadecimal, si no se le ponen sufijos, sigue la misma regla que para los enteros
octales.
También podemos usar los sufijos U, L, UL para indicar explícitamente el tipo del literal.
Por ejemplo:
0x1A Tipo: int
0x1AU Tipo: unsigned int
0x1AL Tipo: long
0x1AUL Tipo: unsigned long

Literal numérico real en C++


Son números en base 10, que deben llevar un parte entera, un punto decimal y una parte fraccionaria. Si la parte
entera es cero, puede omitirse.
Por ejemplo:
12.2303
-3.44
+10.33
0.456
.96
También pueden representarse utilizando la notación científica. En este caso se utiliza una E (mayúscula o
minúscula) seguida del exponente.
Por ejemplo, el número en notación científica 14*10-3 se escribe: 14E-3
Más ejemplos de literales numéricos reales en C++:
2.15E2
.0007E4
-50.44
5e-10
El tipo de estos literales es siempre double, a no ser que se añada el sufijo F para indicar que es float.
Por ejemplo:
2.15 Tipo: double
2.15F Tipo: float

Literal de tipo carácter en C++


Contienen un solo carácter encerrado entre comillas simples.
Son de tipo char.

EEST N° 5 Amancio Willians 10


Prof. Abdala Achaval Pablo
Los caracteres posibles son todos los contenidos en la tabla ASCII.
Las secuencias de escape se consideran literales de tipo carácter.
Por ejemplo:
'a'
'4'
'\n'
'\x07'
Los literales de carácter ampliado (wchar_t) se forman utilizando el prefijo L.
Por ejemplo:
wchar_t car = L'k'

Literal de cadena de caracteres en C++


Están formados por 0 ó más caracteres encerrados entre comillas dobles. Pueden incluir secuencias de escape.
Por ejemplo:
“Esto es una cadena de caracteres”
“Pulsa \”C\” para continuar”
“T” (cadena de un solo carácter, es diferente a „t‟ que es un carácter)

Variables y constantes en C++

Declaraciones de variables en C++.

Una variable se debe declarar para poder utilizarla.


Una declaración de variable asocia un tipo de datos a la variable.
Una declaración está formada por un tipo de dato seguido de uno o más nombres de variables, finalizando con
un punto y coma.
Por ejemplo:
int unidades; //se declara una variable de tipo entero llamada unidades
float importe, longitud; //se declaran dos variables de tipo float
char opcion; //se declara una variable de tipo char
En la propia declaración se puede hacer una asignación de valores iniciales:
int num = 0;
char guion = '-';
float longitud = 6.25;

Declaraciones de constantes en C++.

Declarar una constante supone asociar un tipo de datos y un valor a la constante.


Este valor no podrá ser modificado durante la ejecución del programa.
La declaración de constantes es similar a la de una variable, anteponiendo la palabra reservada const.
Por ejemplo:
const double PI = 3.1416;
const int DIAS_SEMANA = 7;
const char letra_inicial = 'F';

Operadores C++

EEST N° 5 Amancio Willians 11


Prof. Abdala Achaval Pablo
Operadores aritméticos.
+ Suma
- Resta
* Multiplicación
/ División
% Módulo ó resto de la división entera
En C++ no hay operador de potenciación. Esta operación se realiza con la función pow.
El operador % obtiene el resto de la división entre enteros. Requiere que los operandos sean enteros y el
segundo operando no sea nulo. Cuando se aplica el operador % a operandos de distinto signo, la mayoría de las
versiones de C++ asignan al resultado el signo del primer operando.
El operador / requiere que el segundo operando no sea nulo. Si los dos operandos son enteros se obtiene como
resultado la parte entera (cociente truncado, sin decimales).
Ejemplo de operaciones:
int a = 10, b = 3;
double v1 = 12.5, v2 = 2.0;
char c1='P', c2='T'; //Según la tabla ASCII „P‟=80 „T‟=84 „5‟=53
Expresión Valor Expresión Valor Expresión Valor
a+b 13 v1+v2 14.5 c1 80
a-b 7 v1-v2 10.5 c1 + c2 164
a*b 30 v1*v2 25.0 c1 + c2 + 5 169
a/b 3 v1/v2 6.25 c1 + c2 + „5‟ 217
a%b 1

En aquellas expresiones en las que aparecen operandos de distinto tipo, C++ convierte los valores al tipo de
dato de mayor precisión de todos los datos que intervienen. Esta conversión es de forma temporal, solamente
para realizar la operación. Los tipos de datos originales permanecen igual después de la operación.
Por ejemplo:
int n = 10;
double v1 = 12.5, v2;
v2 = n + v1; // da como resultado 22.5
para realizar esta operación se convierte el valor de n a tipo double que es el tipo de v1. Realmente n no se
modifica, solo su valor es convertido para realizar la suma.
Más ejemplos:
int i = 7;
double f = 5.5;
char c = 'w'; // ASCII „w‟=119 „0‟=48

Expresión Valor Tipo


i+f 12.5 double
i+c 126 int
i + c – „0‟ 78 int

EEST N° 5 Amancio Willians 12


Prof. Abdala Achaval Pablo
(i + c) – (2 * f / 5) 123.8 double
En ocasiones resulta útil convertir el valor de una expresión a un tipo de datos diferente: esto se conoce como
casting o conversión de tipos que veremos más adelante.
En las expresiones en las que aparecen varios operadores aritméticos, el orden de ejecución es siempre de
mayor a menor prioridad y dentro de la misma prioridad de izquierda a derecha. Los operadores *, / y % tienen
entre ellos la misma prioridad, siendo mayor que la de + y –, que también tienen entre ellos la misma prioridad.
(Ver tabla al final de la entrada)
Operadores unitarios.
– + signos negativo y positivo
++ -- incremento y decremento
~ ó compl Complemento a 1
Estos operadores afectan a un solo operando.
El operador incremento ++ incrementa en 1 el valor de la variable.
Ejemplo:
int i = 1;
i++; // Esta instrucción incrementa en 1 la variable i.
// Es lo mismo que hacer i = i + 1; i toma el valor 2
El operador decremento –- decrementa en 1 el valor de la variable.
Ejemplo:
int i = 1;
i--; // decrementa en 1 la variable i.
// Es lo mismo que hacer i = i - 1; i toma el valor 0
Los operadores incremento y decremento pueden utilizarse como prefijo o sufijo, es decir, pueden aparecer
antes o después de la variable.
Por ejemplo:
i = 5;
i++; // i vale ahora 6
++i; // i vale ahora 7
Cuando estos operadores intervienen en una expresión, si preceden al operando (++i), el valor se modificará
antes de que se evalúe la expresión a la que pertenece.
En cambio, si el operador sigue al operando (i++), entonces el valor del operando se modificará después de
evaluar la expresión a la que pertenece.
Por ejemplo:
int x, i = 3;
x = i++;
En esta asignación a x se le asigna el valor 3 y a continuación i se incrementa, por lo tanto, después de
ejecutarla: x contiene 3, i contiene 4.
Si las instrucciones son:
int x, i = 3;
x = ++i;
En esta instrucción primero se incrementa i y el resultado se asigna a x. Por lo tanto, después de ejecutarla: x
contiene 4, i contiene 4.

Otro ejemplo:
int i = 1;

EEST N° 5 Amancio Willians 13


Prof. Abdala Achaval Pablo
cout << i << “ “;
cout << ++i << “ “;
cout << i << “ “;
Estas instrucciones mostrarán por pantalla:
122
En cambio, si se cambia la posición del operador:
int i = 1;
cout << i << endl;
cout << i++ << endl;
cout << i << endl;
Estas instrucciones mostrarán por pantalla:
1
1
2
El operador complemento a 1 ~ cambia de valor todos los bits del operando (cambia unos por ceros y ceros
por unos). Solo puede usarse con datos de tipo entero.
Puede usarse el carácter ~ (ASCII 126) ó el operador equivalente compl.
Por ejemplo:
int a = 1, b = 0, c = 0;
c = ~a;
b = compl a;

Operadores relacionales y lógicos.


Los operadores relacionales comparan dos operandos y dan como resultado de la comparación verdadero ó
falso.
Los operadores relacionales en C++ son:
< Menor que
> Mayor que
<= Menor o igual
>= Mayor o igual
!= ó not_eq Distinto
== Igual
Los operadores lógicos se utilizan con operandos de tipo lógico y dan como resultado verdadero o falso.
Los operadores lógicos en C++ son:
&& ó and
El resultado es verdadero si los dos operandos son verdaderos. El resultado el falso en caso contrario. Si el
primer operando es falso no se evalúa el segundo, ya que el resultado será falso.
|| ó or
El resultado es falso si los dos operandos son falsos. Si uno es verdadero el resultado es verdadero. Si el primer
operando es verdadero no se evalúa el segundo.
! ó not
Se aplica sobre un solo operando. Cambia el valor del operando de verdadero a falso y viceversa.

Los operadores relacionales se utilizan para construir expresiones lógicas, cuyo resultado es de tipo cierto o
falso.
En C++ toda expresión numérica con un valor distinto de cero (no sólo el 1) se considera como cierta y el
valor cero como falsa.

EEST N° 5 Amancio Willians 14


Prof. Abdala Achaval Pablo
Por ejemplo, en la siguiente tabla vemos una serie de expresiones lógicas y su valor:
int i = 7;
float f = 5.5F;
char c = „w‟;
Expresión Resultado
(i >= 6) && (c == „w‟) Cierto
(i >= 6) || (c == 119) Cierto
(f < 11) and (i > 100) Falso
(c != „p‟) or ((i + f) <= 10) Cierto
i + f <= 10 Falso
i >= 6 && c == „w‟ Cierto
c != „p‟ || i + f <= 10 Cierto

Las expresiones lógicas compuestas que constan de expresiones lógicas individuales unidas por los operadores
lógicos && y || se evalúan sólo hasta que se ha establecido el valor cierto o falso del conjunto.
Cuando, por ejemplo, una expresión va a ser seguro falsa por el valor que ha tomado uno de sus operandos,
C++ ya no evalúa el resto de expresión.

Operadores a nivel de bits


Operan con datos de tipo entero. Realizan con sus operandos las operaciones lógicas and, or, xor y
desplazamiento bit a bit.
Los operadores a nivel de bits en C++ son:
& ó bitand and a nivel de bits
| ó bitor or a nivel de bits
^ ó xor xor a nivel de bits
<< desplazamiento a la izquierda, rellenando con ceros a la derecha
>> desplazamiento a la derecha, rellenando con el bit de signo por la izquierda
Por ejemplo:
int a = 11, b = 7, c;
c = a & b; // 11 & 7, en binario: 1011 and 0111 = 0011 que es el 3 en decimal
cout << c << endl; // muestra 3
c = a | b;
cout << c << endl; // muestra 15
c = a ^ b;
cout << c << endl; // muestra 12
c = b << 1;
cout << c << endl; // muestra 14. Equivale a b * 2
c = b >> 1;
cout << c << endl; // muestra 3. Equivale a 3 / 2

Operadores de asignación.
Se utilizan para asignar el valor de una expresión a una variable.
= Asignación

EEST N° 5 Amancio Willians 15


Prof. Abdala Achaval Pablo
+= Suma y asignación
–= Resta y asignación
*= Producto y asignación
/= División y asignación
%= Resto de la división entera y asignación
<<= Desplazamiento a la izquierda y asignación
>>= Desplazamiento a la derecha y asignación
&= ó and_eq and sobre bits y asignación
|= ó or_eq or sobre bits y asignación
^= ó xor_eq xor sobre bits y asignación
Si los dos operandos de una expresión de asignación son de distinto tipo, el valor de la expresión de la derecha
se convertirá al tipo del operando de la izquierda.
Por ejemplo, una expresión de tipo real (float, double) se truncará si se asigna a un entero, o una expresión de
tipo double se redondeará si se asigna a una variable de tipo float.
En C++ están permitidas las asignaciones múltiples.
Ejemplo: a = b = c = 3; equivale a a = 3; b = 3; c = 3;
Ejemplo de asignaciones:
a += 3; equivale a a = a + 3;
a *= 3; equivale a a = a * 3;
En general:
variable op= expresión equivale a: variable = variable op expresión
En la siguiente tabla vemos más ejemplos de asignaciones:
int i = 5, j = 7, x = 2, y = 2, z = 2;
float f = 5.5F, g = -3.25F;
Expresión Expresión equivalente Valor final
i += 5 i=i+5 10
f –= g f=f–g 8.75
j *= (i – 3) j = j * (i – 3) 14
f /= 3 f=f/3 1.833333
i %= (j - 2) i = i % (j – 2) 0
x *= -2 * (y + z) / 3 x = x * (-2 * (y + z) / 3) -4

Operador condicional.
Lo forman los caracteres ? y :
Se utiliza de la forma siguiente:
expresión1 ? expresión2 : expresión3
Si expresión1 es cierta entonces se evalúa expresión2 y éste será el valor de la expresión condicional. Si
expresión1 falsa, se evalúa expresión3 y éste será el valor de la expresión condicional.
Por ejemplo:
int i = 10, j;
j = (i < 0) ? 0 : 100;

EEST N° 5 Amancio Willians 16


Prof. Abdala Achaval Pablo
Esta expresión asigna a j el valor 100. Su significado es: si el valor de i es menor que 0 asigna a j el valor 0, sino
asigna a j el valor 100. Como i vale 10, a j se le asigna 100.
La instrucción anterior es equivalente a escribir:
if(i < 0)
j = 0;
else
j = 100;

Más Ejemplos de operador condicional en C++:


int a=1, b=2, c=3;
c+=(a>0 && a<= 10) ? ++a : a/b; /* c toma el valor 5*/
int a=50, b=10, c=20;
c+=(a>0 && a<=10) ? ++a : a/b; /* c toma el valor 25*/

Otros operadores
Operador coma
La coma, usada como operador, se utiliza para encadenar varias expresiones.
Ejemplo: x=(v=3,v+5)
Equivale a: v=3
x=v+5
Ejemplo: z=26
v=(z=z+10,72/z)
Equivale a: z=26
z=z+10
v=72/z

Operador de dirección
Se representa por el símbolo & (ampersand), y su función es la de obtener la dirección dónde se almacena una
determinada variable.
Por ejemplo, dadas las siguientes instrucciones:
int x = 10;
cout << “Valor de x: “ << x << endl;
cout << “Dirección de la variable x: “ << &x << endl;
muestran por pantalla:
Valor de x: 10
Dirección de la variable x: 0x27ff44

Operador de indirección
Se representa por un asterisco *, y su función es la de obtener el valor contenido en una dirección de memoria.

EEST N° 5 Amancio Willians 17


Prof. Abdala Achaval Pablo
Un puntero es una variable que contiene una dirección de memoria. Para definir una variable puntero se escribe:
tipo *variable.
Por ejemplo: int *p;
En el siguiente ejemplo se declara un puntero y dos variables enteras y se utiliza el operador de indirección para
obtener el valor contenido en una dirección de memoria.
int *p, x = 10, y = 0; //se declara el puntero p y las variable x e y
p = &x; //a p se le asigna la dirección de memoria de x
y = *p; //a y se le asigna el valor guardado en la dirección de memoria
que contiene p. Como p contiene la dirección de x, a y se le asigna el valor 10
Veremos los punteros en un tema posterior.

Operador referencia a
Una referencia es un nombre alternativo (un alias, un sinónimo) para un objeto.
La forma general de expresar una referencia es:
tipo &referencia = variable;
Por ejemplo:
float m = 30.01;
float &n = m; // n es una referencia de m
Se ha declarado la variable m como float y n como referencia de m, indicando al compilador que en este
programa m también tiene otro nombre ( n ).
Las operaciones realizadas sobre m se reflejan en n, y viceversa. Por lo tanto en el programa podemos utilizar
indistintamente m o n.
Una referencia no es una copia de la variable referenciada, sino que es la misma variable con un nombre
diferente.

Los operadores no operan con la referencia sino directamente sobre la variable referenciada.
Por ejemplo:
int j = 0;
int &k = j; // k es una referencia a j;
k++;
cout << j << endl; // muestra 1
cout << k << endl; // muestra 1;
Una referencia debe ser inicializada y su valor no puede ser alterado después de haberla inicializado, por lo que
siempre se referirá al mismo objeto.
Las referencias se utilizan, por ejemplo, como alternativa a los punteros en el paso de parámetros en las
funciones.

Operador global y de resolución de ámbito


Es el operador :: y permite el acceso a una variable global que ha quedado oculta por una variable local.
En POO se usa para indicar a qué clase pertenece un determinado método.
Operador sizeof
Obtiene el tamaño en bytes de un tipo de datos o de una variable previamente declarada.
Por Ejemplo, las siguientes instrucciones:
double a;
cout << “Entero-> “ << sizeof(int) << endl;
cout << “Caracter-> “ << sizeof(char) << endl;

EEST N° 5 Amancio Willians 18


Prof. Abdala Achaval Pablo
cout << “Double-> “ << sizeof(a) << endl;

Dan como resultado:


Entero-> 4
Caracter-> 1;
Double-> 8
El operador sizeof se puede utilizar con tipos primitivos y con tipos derivados.

Prioridad y orden de evaluación de los operadores en C++

La siguiente tabla muestra todos los operadores de C++ ordenados de mayor a menor prioridad.
Los operadores que aparecen en la misma línea tienen la misma prioridad.

:: Sin asociatividad
() [] . -> n++ n-- _cast typeid Izquierda a Derecha
signo ~ ! * & ++n -–n sizeof new delete (tipo) Derecha a Izquierda
->* .* Izquierda a Derecha
* / % Izquierda a Derecha
+ - Izquierda a Derecha
<< >> Izquierda a Derecha
< <= > >= Izquierda a Derecha
== != Izquierda a Derecha
& Izquierda a Derecha
^ Izquierda a Derecha
| Izquierda a Derecha
&& Izquierda a Derecha
|| Izquierda a Derecha
?: Derecha a Izquierda
= += -= *= /= %= <<= >>= &= |= ^= Derecha a Izquierda
, Izquierda a Derecha

Casting. Conversión entre tipos de datos en C++

Cuando en una expresión en C++ intervienen operandos de distinto tipo, los datos se convierten de forma
temporal al operando de mayor precisión para realizar la operación.
Cuando a un variable se le asigna un valor que no es de su tipo, C++ convierte el valor de la derecha al tipo de
la variable a la que se le va a asignar siempre que no haya pérdida de información.
Si se produce pérdida de información el compilador avisará de ello.
En una asignación de tipos distintos puede ocurrir que:
1. Un valor real (tipo double o float) puede truncarse (pierde la parte decimal) si se asigna a una variable entera.

2. Un valor de tipo double puede ser redondeado si se asigna a una variable de tipo float.

3. Un valor de tipo entero puede ser modificado si se asigna a una variable entera de menor precisión o a una
variable de tipo char. Algunos de los bits más significativos pueden perderse.

EEST N° 5 Amancio Willians 19


Prof. Abdala Achaval Pablo
Por ejemplo, dadas las siguientes declaraciones de variables:
long int k;
unsigned char m;
double p;
int n, q;
Para calcular la siguiente expresión: q = k + m * n / p el proceso es el siguiente:
1. Se realiza la multiplicación m * n. Para ello se convierte m (unsigned char) a int y a continuación se multiplica
por n. El resultado es de tipo int.
2. Se realiza la división. Como p es de tipo double, el resultado anterior de multiplicar m * n que es de tipo int
se convierte a double y se hace la división. El resultado es de tipo double.
3. Se realiza la suma. Para ello se convierte k (long) a double y se suma al resultado de la división anterior. El
resultado de la suma es de tipo double.
4. El último paso es asignar el resultado de tipo double a q que es de tipo int. En este caso el resultado se pasa a
tipo int por truncamiento, o sea, eliminando la parte fraccionaria. En este caso de pérdida de precisión el
compilador avisará de ello.
Estas conversiones las realiza C++ de forma automática. Esta conversión se conoce como conversión
implícita.
En algunos casos necesitaremos asignar datos de un tipo a variables que son de otro tipo y que el compilador no
nos avise ello y permita realizar la operación. En ese caso utilizaremos la conversión explícita o casting.
En general, el uso del casting es obligatorio cuando se hacen asignaciones con pérdida de precisión.
Un casting lo podemos hacer, siguiendo el modelo de C, de dos formas:
(tipo) expresión
ó
tipo(expresión)
Por ejemplo:
float a = 10.2;
int b, c = 5;
b = (int)(a + c); // convierte a int por truncamiento. Asigna a b el valor 15
c = int (a); // asigna a c el valor 10
Si en las instrucciones anteriores no realizamos el casting el compilador avisará de la pérdida de precisión y no
nos dejará hacerlo.

Otro ejemplo. Dadas las variables:


int i = 7;
float f = 8.5;
La expresión (i + f) % 4 no es válida, ya que (i + f) produce un resultado en coma flotante.
Esto se puede solucionar con un casting:
((int) (i + f)) % 4.
Sea ahora la expresión ((int) f) % 3, es una expresión válida, que da como resultado el valor 2, pero debemos
tener en cuenta que lo que se convierte en entero es el valor de f, y sólo para esta expresión, ya que después f
sigue teniendo el valor 8.5.
Un casting también puede ser considerado como un operador unitario.
Además de esta forma de realizar un casting que es la tradicional de C, C++ incorpora 4 nuevos operadores
para realizar un casting de forma explícita:
static_cast<tipo>(expresión)
Convierte el tipo de la expresión al tipo indicado.

EEST N° 5 Amancio Willians 20


Prof. Abdala Achaval Pablo
Se utiliza para realizar conversiones entre tipos relacionados, por ejemplo entre un float y un int.
const_cast<tipo>(expresión)
Convierte el tipo de la expresión al tipo indicado.
Se utiliza para eliminar la acción del calificador const sobre la expresión.
dynamic_cast<tipo>(expresión)
Convierte el tipo de la expresión al tipo indicado.
Se utiliza para realizar conversiones verificadas durante la ejecución, examinando el tipo del objeto que
convierte.
Si la conversión es entre punteros y durante la ejecución no se puede realizar, devuelve un cero (puntero nulo).
reinterpret_cast<tipo>(expresión)
Convierte el tipo de la expresión al tipo indicado.
Se utiliza para realizar conversiones entre tipos no relacionados, por ejemplo, conversiones double * a int * que
static_cast no permite.
Por ejemplo:
float a = 10.2F;
int b, c = 5;
b = static_cast<int>(a + c); // Asigna a b el valor 15
c = static_cast<int>(a); // asigna a c el valor 10

Estructura de un programa C++


C++ es un lenguaje de programación orientado a objetos híbrido. Esto quiere decir que permite realizar
programas estructurados sin la orientación a objetos y programas orientados a objetos.
En este punto veremos la estructura de un programa que no utiliza orientación a objetos. En temas posteriores
estudiaremos la estructura de un programa C++ orientado a objetos.
La estructura general de un programa C++ es la siguiente:
Comentarios
Directivas del preprocesador
Declaración de variables globales y funciones
int main( ) // Función principal main
{
Declaraciones locales de la función principal
Instrucciones de la función principal
}
Otras funciones:
funcion1(.....)
{
Declaraciones locales de la función 1
Instrucciones de la función 1
}
funcion2(.....)
{
Declaraciones locales de la función 2
Instrucciones de la función 2
}
.....
Por ejemplo:
// Programa que muestra el mensaje Hola mundo!!! por pantalla
#include <iostream>

EEST N° 5 Amancio Willians 21


Prof. Abdala Achaval Pablo
using namespace std;
int main(void)
{
cout << "Hola mundo!!!\n";
}

Vamos a comentar cada una de las partes del programa anterior:


// Programa que muestra el mensaje Hola mundo!!! por pantalla
Esta línea es un comentario.
Todas las líneas que comienzan con dos barras (//) se consideran comentarios y no tienen ningún efecto sobre el
comportamiento del programa.
Los comentarios también pueden ir entre los símbolos /* y */. En ese caso pueden ocupar más de una línea.
#include <iostream>
Esta línea es una directiva del preprocesador.
Todas las líneas que comienzan con el símbolo # son directivas para el preprocesador.
La directiva #include, sirve para insertar ficheros externos dentro de nuestro programa. Estos ficheros son
conocidos como ficheros incluidos, ficheros de cabecera o headers.
En este caso, la directiva #include <iostream> indica al preprocesador que en este programa se debe incluir el
archivo iostream. El código fuente no cambia, pero el compilador ve el fichero incluido.
iostream es la librería de entrada/salida de C++. Si no se incluye esta librería no podemos utilizar la instrucción
cout para imprimir un mensaje por pantalla.
La inclusión de ficheros la podemos realizar de dos formas:
#include <nombre de fichero cabecera>
#include "nombre de fichero de cabecera"
En el primer caso el preprocesador buscará en los directorios include definidos en el compilador.
En el segundo, se buscará primero en el directorio actual, es decir, en el que se encuentre el fichero fuente, si
no existe en ese directorio, se buscará en los directorios include definidos en el compilador. Si se proporciona
el camino como parte del nombre de fichero, sólo se buscará en el directorio especificado.

using namespace std;

En grandes proyectos formados por varios archivos, es posible que en archivos diferentes del mismo proyecto
se encuentren recursos con el mismo nombre. Para evitar confusiones y saber a qué recurso estamos haciendo
referencia se utilizan los espacios de nombres (namespace).
Un espacio de nombres es básicamente un conjunto de nombres de recursos (clases, métodos, funciones,
etc) en el cual todos los nombres son únicos.
Todos los elementos de la biblioteca estándar de C++ se declaran dentro de un espacio de nombres llamado
std.
Con la instrucción using namespace std estamos indicando que vamos a usar este espacio de nombres.
Esta línea se incluirá en la mayoría de programas que escribamos en C++.
Si no la escribimos, la instrucción cout << "Hola mundo!!!\n"; tendríamos que escribirla indicando el espacio de
nombres donde se declara cout así:
std::cout<<”Hola mundo!!!\n”;

EEST N° 5 Amancio Willians 22


Prof. Abdala Achaval Pablo
int main (void)
Un programa en C++ no orientado a objetos está formado básicamente por una o varias funciones.
La función main es la función principal del programa.
La función principal es el punto de inicio del programa. Si el programa contiene varias funciones, la ejecución del
mismo comienza por la función main.
Todo programa escrito en C++ debe contener una función main.
Las llaves { } indican donde empiezan y donde acaban las instrucciones de la función.
cout << "Hola mundo!!!\n";
Esta línea muestra por pantalla Hola mundo!!! y un salto de línea.
cout es un objeto que se declara en el archivo iostream en el espacio de nombres std, por eso tenemos que
incluir ese archivo al principio del programa y declarar que vamos a utilizar ese espacio de nombres.
La instrucción acaba con punto y coma.
El punto y coma se utiliza para indicar el final de una instrucción y sirve para separarla de instrucciones
posteriores.

Salida con formato en C++. Manipuladores

Para dar formato a los datos que se muestran por pantalla, C++ asocia con el stream de salida un conjunto de
manipuladores que permiten modificar la forma en la que son visualizados los resultados.
Un manipulador equivale a una llamada a una función.
Algunos de los manipuladores más comunes son los siguientes:
dec conversión a decimal
hex conversión a hexadecimal
oct conversión a octal
skipws extrae un espacio en blanco inicial
endl se imprime un „\n‟ y se vacía el buffer de salida
flush se vacía el buffer de salida
setw(int w) establece la anchura mínima de campo
setprecision(int p) establece el número de cifras significativas, por defecto 6.
setfill(char ch) establece el carácter de relleno
left la salida se alinea a la izquierda
rigth la salida se alinea a la derecha
internal se alinea el signo y los caracteres indicativos de la base por la izquierda y las cifras por la derecha
showbase se muestra la base de los valores numéricos
showpoint se muestra el punto decimal
uppercase los caracteres de formato aparecen en mayúsculas
showpos se muestra el signo (+) en los valores positivos
scientific notación científica para coma flotante
fixed notación normal de C++ para coma flotante
setiosflag(long i) establece una lista de flags de formato
resetriosflag(long i) suprime una lista de flags de formato
Los manipuladores pueden tener argumentos o no tenerlos. Los manipuladores sin argumentos (endl, flush, etc.)
están definidos en iostream. Los que tienen argumentos están declarados en iomanip.
Un manipulador sólo afecta al stream (cin, cout, etc.) al que se aplica.
Un manipulador en C++ se utiliza de la forma:

cout << hex << 100;


cout << setw(10) << “Hola” << endl;

EEST N° 5 Amancio Willians 23


Prof. Abdala Achaval Pablo
El efecto de los manipuladores permanece en el stream correspondiente hasta que se cambian por otro
manipulador, a excepción de setw(n) que hay que introducirlo en el flujo antes de cada dato al que se le quiere
aplicar ese ancho de campo.
Ejemplo:

//*********************************************************
// Ejemplo de uso de manipuladores setfill y setw
//*********************************************************
#include <iostream>
#include <iomanip> // define diferentes manipuladores
using namespace std;
int main(void)
{
cout << setfill('.'); // manipulador de relleno.
//el carácter de relleno será el punto
cout << "Listado de calificaciones\n" << endl;
cout << "Roberto Aniorte" << setw(20) << "8.5" << endl;
cout << "Andrea Gutierrez" << setw(19) << "6.9" << endl;
cout << "Isabel Sanchez" << setw(21) << "5.7" << endl;

cout << "Anastasio Castro" << setw(19) << "7.5" << endl;
cout << "Barbara Lopez" << setw(22) << "7.8" << endl;
cout << "Martin Garcia" << setw(22) << "9.1" << endl;
cout << setfill('\0'); // se restablece el carácter de relleno
cout << endl;
system("pause");
}
Este programa muestra:

Otro ejemplo de uso de manipuladores:

//Ejemplo de uso de manipuladores


#include <iostream>
#include <iomanip>
using namespace std;
int main(void)
{
double a1 = 101.179;
double a2 = 3.12;
cout << "a1->" << a1 << endl;
cout << "a2->" << a2 << endl;
cout << endl;
cout << fixed << "a1->" << a1 << endl;
cout << "a2->" << a2 << endl;
cout << endl;
cout << "a1->" << setprecision(1) << a1 << endl;
cout << "a2->" << a2 << endl;
cout << endl;

EEST N° 5 Amancio Willians 24


Prof. Abdala Achaval Pablo
cout << "a1->" << setw(10) << setfill('.') << a1 << endl;
cout << "a2->" << a2 << endl;
cout << "a1->" << setw(12) << a1 << endl;
system("pause");
}
Este programa muestra como salida:

Otro ejemplo de uso de manipuladores:


// programa que lee un radio y calcula
// la longitud de la circunferencia
// el área del círculo
// y el volumen de la esfera correspondiente a ese radio
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
int main(void)
{
const double PI = 3.1416;
double radio;
cout << "Introduce el valor del radio : ";
cin >> radio;
cout << fixed << setprecision(2); // notación en coma flotante
// con 2 decimales
cout << endl << "Longitud de la circunferencia: " << 2*PI*radio;
cout << endl << "Area del circulo: " << PI*pow(radio,2);
cout << endl << "Volumen de la esfera: ";
cout << (4.0/3)*PI*pow(radio,3) << endl;
system("pause");
}
Este programa muestra como salida:

Leer caracteres y cadenas de caracteres en C++

EEST N° 5 Amancio Willians 25


Prof. Abdala Achaval Pablo
Método get() para leer un carácter
Para leer por teclado datos que están separados por espacios en blanco o intro se puede usar el operador de
extracción >> sobre cin. Pero si queremos leer caracteres incluidos espacios en blanco o el intro este operador
no nos sirve.En ese caso podemos utilizar el método get.
La forma de uso es:
cin.get(caracter);
El método get extrae de cin un carácter y lo guarda en la variable. Si el carácter extraído es el de fin de
fichero se activa el indicador de fin de fichero.
Si el buffer de entrada está vacío, cuando llega a esta instrucción el programa se detiene esperando que se teclee
un carácter y se pulse intro.
Por ejemplo, el siguiente programa lee un carácter por teclado y muestra su código ASCII.
#include <iostream>
using namespace std;
int main(void)
{
char c;
cout << "Introduce un caracter: ";
cin.get(c);
cout << "ASCII de " << c << " -> " << static_cast<int>(c) << endl;
system("pause");
}
El método get extrae del flujo caracteres incluso el intro. En algunas ocasiones leer el intro que puede tener
efectos no deseados.
En el siguiente programa vemos un ejemplo en el que el carácter intro que queda en el buffer después de
introducir un entero hace que el programa no funcione como esperamos. Este programa lee un número entero
y muestra si es par o impar y a continuación lee un carácter y muestra si es una letra minúscula:
#include <iostream>
using namespace std;
int main(void)
{
char c;
int num;
//leemos un número entero
cout << "Introduce un numero entero: ";
cin >> num;
cout << "El numero es " << ((num%2==0)? "par" : "impar") << endl;
//leemos un carácter
cout << "Introduce un caracter: ";
cin.get(c);
cout << "El caracter" << ((c>='a' and c<='z')?" es ":" no es");
cout << " una letra minuscula" << endl;
system("pause");
}
la ejecución de este programa es la siguiente:

Tras el mensaje “Introduce un carácter” el programa no espera a que se teclee y muestra directamente el
mensaje “El carácter no es una letra minúscula”. Esto ocurre porque cuando se ha introducido el valor 18
realmente en el flujo de entrada está ese valor más el intro que hemos pulsado:

EEST N° 5 Amancio Willians 26


Prof. Abdala Achaval Pablo
Flujo de entrada cin: 18\n
Mediante la instrucción cin >> num; se le asigna a num el valor 18. Este valor se extrae de cin pero el \n
permanece:
Flujo de entrada después de leer el entero: \n
Cuando el programa llega a la instrucción cin.get(c); extrae de cin el intro y se lo asigna a c. No se detiene la
ejecución del programa para que se introduzca el carácter y se produce un resultado no deseado.
Para evitar esto, en estos casos es necesario limpiar el buffer con el método ignore.
El programa modificado, limpiando el intro para que funcione correctamente es:
#include <iostream>
using namespace std;
int main(void)
{
char c;
int num;
//leemos un número entero
cout << "Introduce un numero entero: ";
cin >> num;
cout << "El numero es " << ((num%2==0)? "par" : "impar") << endl;

//limpiamos el buffer de entrada


cin.ignore(numeric_limits<int>::max(),'\n');

//leemos un carácter
cout << "Introduce un caracter: ";
cin.get(c);
cout << "El caracter" << ((c>='a' and c<='z')? " es ":" no es");
cout << " una letra minuscula" << endl;
system("pause");
}

Método getline() para leer una cadena de caracteres


El operador >> sobre cin no es útil para leer cadenas de caracteres que contengan espacios en blanco.
Por ejemplo, para leer en un programa el nombre y apellidos de una persona, si utilizamos las siguientes
instrucciones:
char nombre[50]; // cadena de caracteres de longitud máxima 50
...
cout << "Introduce tu nombre: ";
cin >> nombre
...
Si tecleamos Lucas Alonso Guzman, a la variable nombre solo se le asignará Lucas ya que a continuación se
encuentra un espacio en blanco y el operador >> entiende que es el final de la asignación.
Para evitar esto se utiliza el método getline.
La forma general de uso es:
cin.getline(cadena, num, carácter_final);
getline lee una serie de caracteres desde el flujo de entrada y los almacena en la variable cadena. Se leen
caracteres hasta el final del flujo, hasta el primer carácter que coincide con el carácter_final especificado, el cual
se desecha ó hasta que se han leído num-1 caracteres; en este último caso el estado del flujo pasa a ser de fallo.
Esto se puede comprobar con el método fail(). El estado de fallo se produce porque se han leído num-1
caracteres que es el máximo que queremos leer y aun han quedado caracteres en el flujo por lo que es posible
que se hayan tecleado más caracteres de la cuenta y pueden provocar un error en la siguiente lectura.
getline añade automáticamente el carácter nulo (\0) al final de la cadena extraída.

EEST N° 5 Amancio Willians 27


Prof. Abdala Achaval Pablo
Utilizando getline para leer nombre y apellidos del ejemplo anterior escribiremos:
cin.getline(nombre, 50, '\n');
El carácter final se puede omitir, si no aparece se supone que es \n :
cin.getline(nombre, 50);
Ejemplos de lectura de caracteres en C++
Ejemplo 1: El siguiente ejemplo muestra la diferencia cuando se leen cadenas de caracteres en C++ usando o
no getline:
#include <iostream>
using namespace std;
int main(void)
{
char nombre[40];
cout << "Introduce nombre y apellidos: ";
cin.getline(nombre,40); //lectura incluyendo espacios
cout << "Hola " << nombre << endl;
cout << "Introduce nombre y apellidos: ";
cin >> nombre; //lectura sin incluir espacios
cout << "Hola " << nombre << endl;
system("pause");
}
La salida de este programa es:

Ejemplo 2:
En el siguiente ejemplo se leen cadenas de caracteres hasta que se pulsa F6. Se comprueba y se muestra el
estado del flujo cin después de cada lectura.

#include <iostream>
using namespace std;
int main(void)
{ char cadena[15];
cout << "Introduzca cadena de caracteres. F6 Para finalizar\n\n";
do
{ cout << "cadena: ";
cin.getline(cadena,15,'\n');

//se muestran los bits de estado del flujo cin para


//comprobar el resultado de la lectura

cout << "bit eof->" << cin.eof() << " ";


cout << " bit fail->" << cin.fail() << endl;

//si la cadena excede de 15 cin.fail() toma el valor 1

//si no se ha pulsado F6 en el nombre (fin de lectura)


//y el nombre excede de la longitud máxima permitida
//se eliminan el resto de los caracteres
if(!cin.eof() && cin.fail())
{
cin.clear();
cin.ignore(numeric_limits<int>::max(),'\n');

EEST N° 5 Amancio Willians 28


Prof. Abdala Achaval Pablo
}
}while(!cin.eof());
system("pause");
}
La salida de este programa es la siguiente:

Limpiar el Buffer del Teclado

Para limpiar el buffer de entrada estándar con el método cin.ignore() el cual por defecto borra el primer
caracter que encuentra en el buffer (normalmente „\n‟). Otra forma, es pasando al mismo método dos
parámetros, que son la cantidad de caracteres que serán borrados (máximo 256), y el caracter en el cual
terminará el borrado, para nuestro caso „\n‟.

cin.ignore(256,’\n’);

Sentencias de iteración – Ciclos repetitivos


Definición

Las Sentencias de Iteración o Ciclos son estructuras de control que repiten la ejecución de un grupo de
instrucciones. Básicamente, una sentencia de iteración es una estructura de control condicional, ya que dentro
de la misma se repite la ejecución de una o más instrucciones mientras o hasta que una a condición
específica se cumpla. Muchas veces tenemos que repetir un número definido o indefinido de veces un grupo de
instrucciones por lo que en estos casos utilizamos este tipo de sentencias. En C++ los ciclos o bucles se
construyen por medio de las sentencias for, while y do - while. La sentencia for es útil para los casos en
donde se conoce de antemano el número de veces que una o más sentencias han de repetirse. Por otro lado,
la sentencia while es útil en aquellos casos en donde no se conoce de antemano el número de veces que una
o más sentencias se tienen que repetir.

Sentencia For
for(contador; final; incremento)
{
Código a Repetir;
}

donde:

1. contador es una variable numérica


2. final es la condición que se evalúa, o sea, el valor final para contador
3. incremento es el valor que se suma o resta al contador

Ejemplo 1:

EEST N° 5 Amancio Willians 29


Prof. Abdala Achaval Pablo
#include <iostream>
Using namespace std;
int main(int argc, char* argv[])
{
for(int i=1; i<=10; i++)
{
cout<<"Hola Mundo"<<endl;
}
system(“pause”);
return 0;
}

Esto indica que el contador "i" inicia desde 1 y finaliza cuando el contador "i" sea menor o igual a 10 ( en este
caso llegará hasta 10) e "i++" realiza la sumatoria por unidad lo que hace que el for y el contador se sumen.
repitiendo 10 veces "HOLA MUNDO" en pantalla.

Ejemplo 2:

#include <iostream>
Using namespace std;
int main()
{

for(i=10; i>=0; i--)


{
cout<<"Hola Mundo"<<endl;
}
system(“pause”);
return 0;
}

Este ejemplo hace lo mismo que el primero, salvo que el contador se inicializa a 10 en lugar de 1; y por ello
cambia la condición que se evalúa así como que el contador se decremento en lugar de ser incrementado .

Sentencia while

while(condición)
{
código a Repetir
}

donde:

1. condición es la expresión a evaluar

Ejemplo 1:

#include <iostream>
Using namespace std;
int main(int argc, char* argv[])
{
int contador = 0;
while(contador<=10)
{
contador=contador++;

EEST N° 5 Amancio Willians 30


Prof. Abdala Achaval Pablo
cout<<"Hola Mundo"<<endl;
}
system(“pause”);
return 0;
}

El contador Indica que hasta que este llegue a el total de 10 entonces se detendrá y ya no se realizará el código
contenido dentro de la sentencia while, de lo contrario mientras el "contador" sea menor a 10 entonces el
código contenido se ejecutará desplegando hasta 10 veces "Hola Mundo" en pantalla.

Sentencia do - while

La sentencia do es usada generalmente en cooperación con while para garantizar que una o más instrucciones
se ejecuten al menos una vez. Por ejemplo, en la siguiente construcción no se ejecuta nada dentro del ciclo
while, el hecho es que el contador inicialmente vale cero y la condición para que se ejecute lo que está dentro
del while es "mientras el contador sea mayor que diez". Es evidente que a la primera evaluación hecha por
while la condición deja de cumplirse.

int contador = 0;

while(contador > 10)


{
contador ++;
cout<<"Hola Mundo";
}

Al modificar el segmento de código anterior usando do tenemos:

#include <iostream>
Using namespace std;
int main(int argc, char* argv[])
{
int contador = 0;
do
{
contador ++;
cout<<"Hola Mundo";
}
while(contador > 10);

system(“pause”);
return 0;
}
Observe cómo en el caso de do la condición es evaluada al final en lugar de al principio del bloque de
instrucciones y, por lo tanto, el código que le sigue al do se ejecuta al menos la primera vez.

Generar Números Aleatorios en C++


Para generar números aleatorios en C++ se utilizan las funciones rand y srand.

Función rand()
La función rand calcula un número aleatorio en el intervalo entre 0 y RAND_MAX. El valor de RAND_MAX es
una constante predefinida que representa el mayor valor que puede devolver la función rand. En Dev-C++ este
valor es 32767.

EEST N° 5 Amancio Willians 31


Prof. Abdala Achaval Pablo
Ejemplo: Programa C++ que genera 20 números aleatorios.

#include <iostream>

using namespace std;

int main()

int i;

cout << "20 numeros generados aleatoriamente:\n";

for(i=1; i<=20; i++)

cout << rand() << endl;

system("pause");

La función rand genera números a partir de un valor inicial o semilla. Si ejecutamos el programa anterior varias
veces seguidas obtendremos siempre la misma secuencia de números. Para que esto no se produzca debemos
cambiar el valor inicial de la semilla cada vez que se ejecute el programa. Esto se hace con la función srand.

Función srand()
La función srand fija el punto de comienzo para generar números aleatorios. El generador de números
aleatorios obtiene los números en función del valor de su argumento. Cuando esta función no se utiliza, el valor
del primer número generado siempre es el mismo para cada ejecución (corresponde a un argumento de valor
1).

Para obtener números aleatorios mediante estas funciones, es recomendable utilizar como semilla un valor que
cambie constantemente, como por ejemplo, el valor devuelto por la función time (librería ctime). Esta función
devuelve el número de segundos transcurridos desde las 0 horas del 1 de Enero de 1970.

Podemos comprobar el funcionamiento modificando el ejemplo anterior para que genere números diferentes en
cada ejecución:

#include <iostream>
#include <ctime>
using namespace std;
int main()
{
srand(time(NULL));
int i;
cout << "20 numeros generados aleatoriamente:\n";
for(i=1; i<=20; i++)
cout << rand() << endl;
system("pause");
}
Para generar números aleatorios entre dos límites DESDE – HASTA utilizaremos la siguiente expresión:

numero = aleatorio = rand()%(HASTA-DESDE+1)+DESDE;

EEST N° 5 Amancio Willians 32


Prof. Abdala Achaval Pablo
Ejemplo: Programa C++ que genera números aleatorios entre 4 y 10. La cantidad de números a generar se pide
por teclado

#include <iostream>
#include <ctime>
using namespace std;
int main()
{
srand(time(NULL));
int i, n, aleatorio, DESDE=4, HASTA=10;
cout << "Numeros aleatorios entre " << DESDE << " y " << HASTA << endl;
cout << "Cuantos numeros aleatorios quiere generar? ";
cin >> n;
for (i = 1; i <= n; i ++)
{
aleatorio = rand()%(HASTA-DESDE+1)+DESDE;
cout << aleatorio << " ";
}
cout << endl;
system("pause");
}
Otro ejemplo

/* srand example */
#include <iostream>
#include <stdlib.h> /* srand, rand */
#include <time.h> /* time */
using namespace std;
int main ()
{
cout<<"First number: "<< rand()%100<<endl;
srand (time(NULL));
cout<<"Random number: “<< rand()%100<<endl;
srand (1);
cout<<"Again the first number: "<< rand()%100<<endl;

return 0;
}

enum
Sintaxis:

enum nombre {lista-de-nombres} variable-lista;

La palabra clave enum es usada para crear un tipo enumerador llamado nombre que consiste de los elementos
en lista-de-nombre. La variable-lista es opcional, y puede ser usada para crear instancias de tipo nombre junto
con la declaracion. Por ejemplo, el siguiente código crea un tipo enumerador para colores:

enum ColorT {rojo, naranja, amarillo, verde, azul, indigo, violeta};


...
ColotT c1 = indigo;
if( c1 == indigo ) {

EEST N° 5 Amancio Willians 33


Prof. Abdala Achaval Pablo
cout << "c1 es índigo" << endl;
}

En el ejemplo anterior, el efecto de enumeración es introducir nuevas constantes llamadas rojo, naranja,
amarillo, etc. Por defecto, estas constantes son asignadas consecutivamente como enteros empezando en cero.
Puedes cambiar los valores de estas constantes, como es mostrado en el siguiente ejemplo:

int main(int argc, char* argv[])


{
enum ColorT { rojo = 10, azul = 166, verde }; //verde toma el valor de azul+1
ColorT c = azul;
cout << "c es " << c << endl;
system(“pause”);
return 0; }

Se pone typedef para que funcione en compiladores C y C++ a la par:

typedef enum ColorT { rojo = 10, azul = 15, verde } ColorT;

ColorT c = verde;
cout << "c es " << c << endl;

Funciones en C++.

Una función está formada por un conjunto de sentencias que realizan una determinada tarea y que podemos
invocar mediante un nombre.
Un programa C++ está formado por una o más funciones.
Utilizando funciones podemos construir programas modulares. Además consiguen que no se repita el mismo
código en varias partes del programa: en lugar de escribir el mismo código cuando se necesite, por ejemplo para
validar una fecha, se hace una llamada a la función que lo realiza.
Todo programa C++ tiene una función llamada main. La función main es el punto de entrada al programa y
también el punto de salida.

Los parámetros formales son los datos que recibe la función para operar con ellos. Una función puede
recibir cero o más parámetros. Se debe especificar para cada parámetro su tipo.
Una función puede devolver un dato a quien la ha llamado. Esto se realiza mediante la instrucción return. El tipo
del dato devuelto debe coincidir con el tipo_devuelto que se ha indicado antes del nombre de la función.
Ejemplo de función C++ : función que sume dos números enteros

//Función C++ para sumar dos números


int sumar(int a, int b)
{
int c;
c = a + b;
return c;
}

Esta función se llama suma y recibe dos números enteros a y b. La función suma los dos números y guarda el
resultado en c. Finalmente devuelve mediante la instrucción return la suma calculada.

EEST N° 5 Amancio Willians 34


Prof. Abdala Achaval Pablo
Una función tiene un único punto de inicio, representado por la llave de inicio. La ejecución de una función
termina cuando se llega a la llave final o cuando se ejecuta la instrucción return. La instrucción return puede
aparecer en cualquier lugar dentro de la función, no tiene que estar necesariamente al final.
Con una función se deben realizar tres operaciones: declaración, definición y llamada o invocación.

Declaración o prototipo de una función.


Declarar una función es el paso previo antes de definir el conjunto de sentencias que la componen.
En la declaración o prototipo de la función, indicamos el nombre de la misma, el tipo de valor que devuelve y
una lista parámetros separados por comas. La declaración acaba con punto y coma.

Por ejemplo, la función suma del punto anterior se declara así:


int sumar(int a, int b);
En la declaración de una función, no es necesario indicar los identificadores de los parámetros. Solo es
obligatorio poner el tipo. Además, los identificadores usados en la declaración y en la definición no es preciso
que sean los mismos.
Según esto, la función suma la podemos declarar así:
int sumar(int, int);
Estamos indicando que sumar recibe 2 enteros y devuelve un entero. No es necesario poner el nombre de las
variables.

Definición de una función.


Definir una función consiste en escribir la cabecera de la misma y a continuación, entre llaves, el cuerpo de la
función, es decir, sus instrucciones.
La cabecera de la función debe coincidir con la declaración de la función y debe incluir el nombre de los
parámetros. La cabecera no acaba en punto y coma.
Los parámetros definidos en la cabecera de la función se llaman parámetros formales. Son las variables que
reciben los valores de los argumentos en la llamada a la función.
El resultado de la función se devuelve a la instrucción que la ha llamado por medio de la sentencia return.

Llamar o invocar a una función.

Para que una función se ejecute es necesario llamarla o invocarla desde alguna parte del programa.

La llamada a una función está formada por su nombre seguido de una lista de argumentos entre paréntesis y
separados por comas (cero o más argumentos) que son los datos que se le envían a la función.

Los argumentos que aparecen en la llamada a una función se llaman parámetros actuales, porque son los
valores que se pasan a ésta en el momento de la ejecución.

Los parámetros actuales y los formales deben coincidir en número, orden y tipo. Si el tipo de un parámetro
actual no coincide con su correspondiente parámetro formal, el sistema lo convertirá al tipo de este último,
siempre que se trate de tipos compatibles. Si no es posible la conversión, el compilador dará los mensajes de
error correspondientes.
Si la función devuelve un valor, la llamada a la función puede estar incluida en una expresión que recoja el valor
devuelto.

Cuando se llama a una función, se crean en memoria las variables que aparecen en la cabecera de la función. Las
variables declaradas en la cabecera de una función así como las que se declaran en el interior de la
misma son variables locales de la función. Esto significa que solo son accesibles dentro de la función.
Aunque tengan el mismo nombre que otras variables que puedan aparecer en otras partes del programa se trata

EEST N° 5 Amancio Willians 35


Prof. Abdala Achaval Pablo
de variables distintas. La memoria que ocupan las variables locales de una función se libera cuando acaba la
ejecución de la función y dejan de estar accesibles.

Cuando se llama a una función, la ejecución del programa pasa a la función y cuando ésta acaba, la ejecución
continúa a partir del punto donde se produjo la llamada.

Ejemplos de funciones en C++


/ function example
#include <iostream>
using namespace std;

int subtraction (int a, int b)


{
int r;
r=a-b;
return r;
The first result is 5
}
The second result is
5
int main ()
The third result is 2
{
The fourth result is
int x=5, y=3, z;
6
z = subtraction (7,2);
cout << "The first result is " << z << '\n';
cout << "The second result is " << subtraction (7,2) <<
'\n';
cout << "The third result is " << subtraction (x,y) <<
'\n';
z= 4 + subtraction (x,y);
cout << "The fourth result is " << z << '\n';
}

Paso de parámetros en C++


El paso de parámetros en C++ se puede hacer de dos formas:
1. Paso de parámetros por valor.
2. Paso de parámetros por referencia.
1. Paso de parámetros por valor.

Pasar parámetros por valor significa que a la función se le pasa una copia del valor que contiene el
parámetro actual.

Los valores de los parámetros de la llamada se copian en los parámetros de la cabecera de la función. La
función trabaja con una copia de los valores por lo que cualquier modificación en estos valores no afecta
al valor de las variables utilizadas en la llamada.
Aunque los parámetros actuales (los que aparecen en la llamada a la función) y los parámetros formales (los que
aparecen en la cabecera de la función) tengan el mismo nombre son variables distintas que ocupan
posiciones distintas de memoria.

Por defecto, todos los argumentos salvo los arrays se pasan por valor.

Ejemplo de paso de parámetros por valor


El siguiente programa lee un número entero y llama a una función que invierte las cifras del número:
#include <iostream>
using namespace std;
int invertir (int);

EEST N° 5 Amancio Willians 36


Prof. Abdala Achaval Pablo
int main()
{ int num;
int resultado;
cout << "Introduce un numero entero: ";
cin >> num;
resultado = invertir(num);
cout << "Numero introducido: " << num << endl;
cout << "Numero con las cifras invertidas: " << resultado << endl;
system("pause");
}
int invertir(int num)
{
int inverso = 0, cifra;
while (num != 0)
{
cifra = num % 10;
inverso = inverso * 10 + cifra;
num = num / 10;
}
return inverso;
}
La salida de este programa es:

En la llamada a la función el valor de la variable num se copia en la variable num de la cabecera de la función.
Aunque tengan el mismo nombre, se trata de dos variables distintas.
Dentro de la función se modifica el valor de num, pero esto no afecta al valor de num en main. Por eso, al
mostrar en main el valor de num después de la llamada aparece el valor original que se ha leído por teclado.

2. Paso de parámetros por referencia.


El paso de parámetros por referencia permite que la función pueda modificar el valor del parámetro recibido.
Vamos a explicar dos formas de pasar los parámetros por referencia:
2.1 Paso de parámetros por referencia basado en punteros al estilo C.
2.2 Paso de parámetros por referencia usando referencias al estilo C++.
2.1 Paso de parámetros por referencia utilizando punteros.

EEST N° 5 Amancio Willians 37


Prof. Abdala Achaval Pablo
Cuando se pasan parámetros por referencia, se le envía a la función la dirección de memoria del
parámetro actual y no su valor. La función realmente está trabajando con el dato original y
cualquier modificación del valor que se realice dentro de la función se estará realizando con el parámetro actual.
Para recibir la dirección del parámetro actual, el parámetro formal debe ser un puntero.
Ejemplos de paso de parámetros por referencia
Ejemplo 1:
Programa c++ que lee dos números por teclado y los envía a una función para que intercambie sus valores.
#include <iostream>
using namespace std;
void intercambio(int *, int *);
int main( )
{
int a, b;
cout << "Introduce primer numero: ";
cin >> a;
cout << "Introduce segundo numero: ";
cin >> b;
cout << endl;
cout << "valor de a: " << a << " valor de b: " << b << endl;
intercambio(&a, &b);
cout << endl << "Despues del intercambio: " << endl << endl;
cout << "valor de a: " << a << " valor de b: " << b << endl;
system("pause");
}
void intercambio(int *x, int *y)
{
int z;
z = *x;
*x = *y;
*y = z;
}
La salida de este programa es:

En la llamada, a la función se le envía la dirección de los parámetros. El operador que obtiene la dirección de una
variable es &.
intercambio(&a, &b);
En la cabecera de la función, los parámetros formales que reciben las direcciones deben ser punteros. Esto se
indica mediante el operador *
void intercambio(int *x, int *y)
Los punteros x e y reciben las direcciones de memoria de las variables a y b. Al modificar el contenido de las
direcciones x e y, indirectamente estamos modificando los valores a y b. Por tanto, pasar parámetros por
referencia a una función es hacer que la función acceda indirectamente a las variables pasadas.
Ejemplo 2:
En el siguiente ejemplo, se lee una hora (hora, minutos y segundos) y se calcula la hora un segundo después. El
programa utiliza una función segundo_despues que recibe la hora, minutos y segundos leídos y los modifica de
forma que al finalizar contienen la hora un segundo después.
// Hora un segundo después

EEST N° 5 Amancio Willians 38


Prof. Abdala Achaval Pablo
#include <iostream>
#include <iomanip>
using namespace std;
void segundo_despues(int *, int *, int *);
int main()
{ int horas, minutos, segundos;
do
{
cout << "Introduce hora: ";
cin >> horas;
}while(horas<0 || horas > 23);
do
{
cout << "Introduce minutos: ";
cin >> minutos;
}while(minutos<0 || minutos > 59);
do
{
cout << "Introduce segundos: ";
cin >> segundos;
}while(segundos<0 || segundos > 59);

//llamada a la función
segundo_despues(&horas, &minutos, &segundos);

cout << setfill('0');


cout << endl << "Hora un segundo despues: ";
cout << setw(2) << horas << ":";
cout << setw(2) << minutos << ":";
cout << setw(2) << segundos << endl;
system("pause");
}

//function c++ que recibe una hora expresada en


//horas, minutos y segundos y calcula la hora
//un segundo después
void segundo_despues(int *h, int *m, int *s)
{
(*s)++;
if(*s == 60)
{
*s = 0;
(*m)++;
if(*m == 60)
{
*m = 0;
(*h)++;
if(*h == 24)
{
*h = 0;
}
}
}
}

Esta función no devuelve nada (aparece void como tipo devuelto), por lo que no es necesario poner la
instrucción return.
Mediante return una función solo puede devolver un valor. En casos como la función anterior en los que es
necesario devolver más de un valor, habrá que hacerlo pasando los parámetros por referencia.
Este paso de parámetros por referencia basado en punteros es el utilizado por C y por tanto también puede
usarse en C++. Pero C++ incorpora una nueva forma de paso de parámetros que no hace uso de punteros.
Es el paso de parámetros utilizando referencias.

EEST N° 5 Amancio Willians 39


Prof. Abdala Achaval Pablo
2.2 Paso de parámetros utilizando referencias.

Una referencia es un nombre alternativo (un alias, un sinónimo) para un objeto. Una referencia no es una copia
de la variable referenciada, sino que es la misma variable con un nombre diferente.
Utilizando referencias, las funciones trabajan con la misma variable utilizada en la llamada. Si se modifican los
valores en la función, realmente se están modificando los valores de la variable original.
Ejemplo:
El primer ejemplo del punto anterior utilizando referencias lo podemos escribir así:
#include <iostream>
using namespace std;
void intercambio(int &, int &);
int main( )
{ int a, b;
cout << "Introduce primer numero: ";
cin >> a;
cout << "Introduce segundo numero: ";
cin >> b;
cout << endl;
cout << "valor de a: " << a << " valor de b: " << b << endl;
intercambio(a, b);
cout << endl << "Despues del intercambio: " << endl << endl;
cout << "valor de a: " << a << " valor de b: " << b << endl;
system("pause");
}
void intercambio(int &x, int &y)
{
int z;
z = x;
x = y;
y = z;
}
En la declaración de la función y en la definición se coloca el operador referencia a & en aquellos
parámetros formales que son referencias de los parámetros actuales:
void intercambio(int &, int &); //declaración de la función
void intercambio(int &x, int &y) //definición de la función

Cuando se llama a la función:


intercambio(a, b);
se crean dos referencias (x e y) a las variables a y b de la llamada. Lo que se haga dentro de la función con x e y
se está haciendo realmente con a y b.
La llamada a una función usando referencias es idéntica a la llamada por valor.
Ejemplo:
El segundo ejemplo anterior, utilizando referencias:
// Hora un segundo después
#include <iostream>
#include <iomanip>
using namespace std;
void segundo_despues(int &, int &, int &);
int main()
{ int horas, minutos, segundos;
do
{
cout << "Introduce hora: ";
cin >> horas;

EEST N° 5 Amancio Willians 40


Prof. Abdala Achaval Pablo
}while(horas<0 || horas > 23);
do
{
cout << "Introduce minutos: ";
cin >> minutos;
}while(minutos<0 || minutos > 59);
do
{
cout << "Introduce segundos: ";
cin >> segundos;
}while(segundos<0 || segundos > 59);
segundo_despues(horas, minutos, segundos);
cout << setfill('0');
cout << endl << "Hora un segundo despues: ";
cout << setw(2) << horas << ":";
cout << setw(2) << minutos << ":";
cout << setw(2) << segundos << endl;
system("pause");
}

void segundo_despues(int &h, int &m, int &s)


{
s++;
if(s == 60)
{
s = 0;
m++;
if(m == 60)
{
m = 0;
h++;
if(h == 24)
{
h = 0;
}
}
}
}

Otro Ejemplo Funciones

Escribir un programa que permita al usuario elegir el cálculo del área de cualquiera de las
figuras geométricas: círculo, cuadrado, rectángulo o triángulo mediante funciones.

#include<stdio.h>
#include<iostream.h>

int n,r,b,a,b1,b2,a2;
float circulo(int r);
void carga();
float triangulo (int b, int a);
float cuadrado (int b1);
float rectangulo (int b2, int a2);

int main()
{
carga();
system(“pause”);
return 0;
}

EEST N° 5 Amancio Willians 41


Prof. Abdala Achaval Pablo
void carga ()
{
do
{
clrscr();
cout<<"1. circulo"<<endl;
cout<<"2. triangulo"<<endl;
cout<<"3. cuadrado"<<endl;
cout<<"4. rectangulo"<<endl;
cout<<"5. Salir"<<endl;
cout<<"Ingrese opcion:"<<endl;
cin>>n;

switch (n)
{
case 1:cout<<"Opcion 1=circulo"<<endl;
cout<<"Ingrese el radio del circulo:"<<endl;
cin>>r;
cout<<"El superficie del circulo es:"<<circulo(r)<<endl;
break;

case 2:cout<<"Opcion 2=triangulo"<<endl;


cout<<"Ingrese la base del triangulo:"<<endl;
cin>>b;
cout<<"Ingrese la altura del triangulo:"<<endl;
cin>>a;
cout<<"La superficie del triangulo es:"<<triangulo (a,b)<<endl;
break;

case 3:cout<<"Opcion 3=cuadrado"<<endl;


cout<<"Ingrese el lado del cuadrado:"<<endl;
cin>>b1;
cout<<"La superficie del cuadrado es:"<<cuadrado (b1)<<endl;
break;
case 4:cout<<"Opcion 4=rectangulo"<<endl;
cout<<"Ingrese la base del rectangulo:"<<endl;
cin>>b2;
cout<<"Ingrese la altura del rectangulo:"<<endl;
cin>>a2;
cout<<"La superficie del rectangulo es:"<<rectangulo (b2,a2)<<endl;
break;
}

system(“pause”);
}
while (n !=5);

float circulo(int r)
{
return ((float)(3.14*r*r));
}

float triangulo(int a, int b)


{
return ((float) (b*a)/2);
}

float cuadrado (int b1)

EEST N° 5 Amancio Willians 42


Prof. Abdala Achaval Pablo
{
return ((float) (b1*b1));
}

float rectangulo (int b2, int a2)


{
return ((float)(b2*a2));
}

Ambito de una variable en C++


El ámbito, alcance o scope de una variable es la parte del programa donde la variable es accesible.
Esta definición es también aplicable a constantes y objetos.
En C++ existen tres tipos de ámbitos:
- Global o de programa
- Local o de función.
- De bloque.
Según su ámbito las variables se clasifican en variables globales, variables locales y variables de bloque.
1. Variables globales.
Son variables declaradas fuera de cualquier función, normalmente al comienzo del programa.
Las variables globales son accesibles desde su declaración hasta el final del programa por todas las funciones que
lo forman.
Ejemplo de uso de variables globales en C++:
// Ejemplo de variable global
#include <iostream>
using namespace std;

//se declara x como global.


int x = 1;

void funcion();

int main()
{
cout << x << endl; // muestra 1
x++;
cout << x << endl, // muestra 2

//se llama a una función que accede a


//la variable global x
funcion();

cout << x << endl, // muestra 4


system("pause");
}

void funcion()
{
//la función tiene acceso a la variable global x
x = x * 2;
}

EEST N° 5 Amancio Willians 43


Prof. Abdala Achaval Pablo
En el ejemplo se ha declarado la variable x como global. En el momento de la declaración se asigna memoria y
comienza a estar accesible. Tanto main como la función tienen acceso a la variable x y por tanto pueden
modificar su valor.
La variable global deja de estar accesible cuando acaba la ejecución del programa.

2 Variables locales.
Las variables locales son las que se declaran dentro de una función. Son accesibles desde el punto donde se
declaran hasta el final del bloque donde se han declarado. Los límites de los bloques están definidos por las
llaves de apertura y cierre { }. Normalmente el final del bloque coincide con el final de la función. Si el bloque
donde se ha declarado la variable local contiene a su vez otros bloques, también son accesibles dentro de ellos.
Las variables locales se destruyen cuando se sale del bloque donde han sido declaradas.
Los parámetros formales (los que aparecen en la cabecera de una función) se consideran variables locales de la
función.

Ejemplo de uso de variables locales:


El siguiente programa muestra el uso de variables locales. El programa lee 10 números por teclado y calcula si el
número es primo. Para comprobar si el número leído es primo se utiliza una función que recibe el número y
devuelve true o false según el número sea primo o no.

#include <iostream>
using namespace std;

bool es_primo(int);

int main()
{ int numero, i; // variables locales de main
cout << "Introduzca 10 numeros enteros > 0: ";
for(i=1;i<=10;i++)
{
do
{
cout << "numero " << i << ": ";
cin >> numero;
}while(numero <= 0);
if (es_primo(numero))
cout << "Es primo" << endl;
else
cout << "No es primo" << endl;
}
system("pause");
}

//función que comprueba si un número es primo


//el parámetro n es una variable local de la función
bool es_primo(int n)
{
Bool estado=false;
int i=2; // i es una variable local de la función
if(n==1)
estado= true;
else
{
while(n%i!=0)
i++;
if(i==n)
estado= true;

}
return estado;

EEST N° 5 Amancio Willians 44


Prof. Abdala Achaval Pablo
}

Ocultación de variables
Puede ocurrir que una variable global y otra local tengan el mismo nombre. Cuando ocurre esto, la variable
global queda oculta en el ámbito de accesibilidad de la local del mismo nombre.
Para acceder a una variable global que ha quedado oculta por otra local se utiliza el operador de resolución de
ámbito ::
Ejemplo de ocultación de variables en C++:
// Ejemplo de ocultación de variables
#include <iostream>
using namespace std;
int a = 10; //variable global
int main()
{
int a = 5; //variable local de main
//oculta la variable global con el mismo nombre
cout << a << endl; //muestra 5
cout << ::a << endl; //acceso a la variable global mediante ::
//muestra 10
system("pause");
}

El programa muestra:

5
10

3 Variables de bloque.

Una función puede contener bloques definidos dentro de otros. Los límites de los bloques están
definidos por las llaves de apertura y cierre { }.
El ámbito de una variable declarada dentro de un bloque comienza en el punto en que se declara hasta
el final del bloque donde se ha declarado (llave final del bloque).
Una variable de bloque se destruye cuando acaba la ejecución del bloque donde se ha declarado.
Un ejemplo muy usual de declaración de variables dentro de un bloque es hacerlo en las instrucciones
for:
for(int i = 1; i<=20; i+=2)
{
cout << i << endl;
}
La variable i se ha declarado dentro del for y solo es accesible dentro de él.
Si a continuación de la llave final del for escribimos:
cout << i << endl;
se producirá un error de compilación: la variable i no existe fuera del for y el compilador nos dirá que no está
declarada.
Una variable puede quedar oculta (no accesible) si hay otro bloque anidado y se declara otra variable con el
mismo nombre.
La variable declarada en el bloque interior oculta a la primera variable y la hace inaccesible en el bloque interior.

EEST N° 5 Amancio Willians 45


Prof. Abdala Achaval Pablo
Sobrecarga de Funciones en C++
Cuando hablamos de sobrecarga de funciones o métodos en C++, hacemos referencia al hecho de que
podemos tener más de una función con el mismo nombre a lo largo de nuestro programa, sin embargo no
podemos tener exactamente la misma función (de todas formas no tendría sentido), es decir, la variación que
debería haber para realizar una sobrecarga exitosa debería ser el tipo de dato que se retorna, o por ejemplo el
tipo de dato o la cantidad de parámetros de entrada.

Ejemplo

la función llevará a cabo la suma de dos números, llamada suma( )…sin embargo ocurre algo especial con
esta función, debería ser capaz de realizar la suma recibiendo parámetros de tipo entero y de tipo real (como
3.42 o 8.4765).

En el lenguaje C, cuando se declara una función, solo se puede indicar un tipo de dato (int, float, char,
double, etc) por cada dato que se recibirá, por lo tanto lo que haremos a continuación es implementar dos
funciones que tendrán el mismo nombre suma( ) pero que una recibirá y retornará valores de tipo entero (int)
y la otra función recibirá y retornará valores de tipo real (double).

Vamos a dividir el código completo en 3 partes, para explicar cada una de ellas de forma más entendible. A
continuación se presenta la primera parte del programa, con la directiva de preprocesador, el espacio de
nombres a usar (en este caso el estándar, std) y luego, los prototipos de la función suma( ) sobrecargada,
como puedes notar, ambas funciones tienen el mismo nombre pero los tipos de dato con los que trabaja son
diferentes, por lo que es válida la declaración.

#include <iostream>
using namespace std;

//Prototipos de la función sobrecargada suma( )


int suma(int, int);
double suma(double, double);

A continuación se lleva a cabo la definición de la función principal main( ), que dada la finalidad del ejemplo, es
muy sencilla, y lo único que hacemos es imprimir en pantalla el resultado de las dos funciones suma.
// Definición de la función principal

int main(void)
{
cout<<"2 + 3 = "<<suma(2,3)<<endl;
cout<<"4.5 + 2.1 = "<<suma(4.5,2.1)<<endl<<endl;

return 0;
}

Finalmente realizamos la definición de las “dos” funciones suma( ) las cuales resultan ser muy básicas, por la
finalidad del ejemplo.
//Definición de la función suma sobrecargada...para enteros y reales

int suma(int a, int b)


{
return (a+b);
}

double suma(double a, double b)


{
return (a+b);
}

EEST N° 5 Amancio Willians 46


Prof. Abdala Achaval Pablo
Lo que sucede cuando el compilador encuentra funciones sobrecargadas, es “ver” cuáles son los tipos de
dato que se pasan a dicha función o la cantidad de los mismos (ya que estos pueden variar) y ver cuál de todas
las funciones cumple con dichas especificaciones y hacer el llamado respectivo.
Por último, solo queda recordar, que para realizar una buena sobrecarga de funciones, solo hay que tener en
cuenta que todas las funciones del mismo nombre tienen que diferir en algo en sus prototipos, ya sean en los
tipos de datos recibidos o retornados, la cantidad de argumentos, etc; incluso si el cuerpo de las mismas es
completamente diferente, lo importante es lo que mencionábamos anteriormente.
Finalmente, a continuación se encuentra el código completo, listo para compilar y ejecutar.
#include <iostream>

using namespace std;

// Ejemplo de sobrecarga de funciones en C++

//Prototipos de la función sobrecargada suma( )

int suma(int, int);


double suma(double, double);

// Definición de la función principal

int main(void)
{
cout<<"2 + 3 = "<<suma(2,3)<<endl<<endl;
cout<<"4.5 + 2.1 = "<<suma(4.5,2.1)<<endl<<endl;

return 0;
}

//Definición de la función suma sobrecargada...para enteros y reales

int suma(int a, int b)


{
return (a+b);
}

double suma(double a, double b)


{
return (a+b);
}

Arrays / Vectores /Arreglos en C++

Un array es una colección finita de datos del mismo tipo, que se almacenan en posiciones consecutivas de
memoria y reciben un nombre común.
Ejemplo de array: Supongamos que queremos guardar las notas de los 20 alumnos de una clase. Para ello
utilizaremos un array de 20 elementos y en cada elemento almacenaremos una nota.
Podemos representar gráficamente el array de notas de la siguiente forma:
Array notas:

EEST N° 5 Amancio Willians 47


Prof. Abdala Achaval Pablo
Para acceder a cada elemento del array se utiliza el nombre del array y uno o más índices que indican la
posición que ocupa el elemento dentro del array. Cada índice se escribe entre corchetes.
El primer elemento del array ocupa la posición 0, el segundo la posición 1, etc. En un array de N elementos
el último ocupará la posición N-1.
En el ejemplo anterior, notas[0] contiene la nota del primer alumno y notas[19] contiene la del último
Cómo declarar un array:
Un array se declara de forma parecida a una variable de tipo simple añadiéndole al nombre el número de
elementos que contendrá el array.
De forma general, un array se declara así:
tipo_dato nombre_array[elementos1][elementos2]…..;
elementos1, elementos2, etc. son los índices del array. Deben ser números enteros positivos o expresiones
con un resultado entero positivo. Indican el número de elementos del array.
En el ejemplo anterior, el array notas se declara como:
double notas[20];
El array es unidimensional, se llama notas y contiene 20 elementos de tipo double.
Más ejemplos de declaración de arrays:
int ventas[10] ; //array llamado ventas que contiene 10 enteros
double grados[20]; //array grados que contiene 20 elementos de tipo double
float precios[30]; //array llamado precios que contiene 30 elementos de tipo float

El número de índices determina la dimensión del array. Si el array tiene solo un índice es un array de
una dimensión o unidimensional (también llamado vector), si tiene dos índices es un array de dos dimensiones o
bidimensional (también llamados matrices, tablas o arreglos), si tienen tres índice tridimensional, etc.
Para facilitar la modificación del programa, el tamaño del array se puede declarar utilizando una constante en
lugar de una cantidad entera. Esto hace más fácil modificar el programa ya que todas las referencias al tamaño
máximo del array (por ejemplo, en bucles for o en definiciones de arrays) pueden ser modificadas cambiando el
valor de la constante.
Por ejemplo, declaración de 4 arrays A, B, C y D de 10 elementos cada uno de tipo double usando una
constante llamada ELEMENTOS:
const int ELEMENTOS = 10;
double A[ELEMENTOS], B[ELEMENTOS], C[ELEMENTOS], D[ELEMENTOS];
En este caso si se modifica el tamaño de los arrays, solo habrá que cambiar el valor de la constante.
Los arrays declarados como locales en una función tienen como valores iniciales valores indeterminados, como
ocurre con las variables locales.

La declaración de un array puede incluir la asignación de valores iniciales.

La forma general de hacerlo es:


tipo nombre_array[tamaño]={valor1,valor2,..,valorn};
Donde valor1 es el valor del primer elemento del array, valor2 el valor del segundo elemento, y así
sucesivamente.
El tamaño del array es opcional cuando se asignan valores iniciales en la declaración.
Todos los elementos del array que no tienen asignados valores iniciales explícitos, (sucede cuando un array
tienes más elementos que valores iniciales se han asignado), serán puestos automáticamente a cero.

Ejemplos de asignación de valores iniciales en la declaración de un array en C++:


double porcentaje[]={0, 0.3, 7.25, 4.2};

EEST N° 5 Amancio Willians 48


Prof. Abdala Achaval Pablo
Se declara un array unidimensional llamado porcentaje que contiene 4 elementos de tipo double. El número de
elementos no es necesario indicarlo porque se están asignando4 valores iniciales. El compilador asume que el
array tiene 4 elementos.
int numeros[5]= {1,4,-7,5,9};
Se declara un array unidimensional llamado numeros que contiene 5 elementos de tipo int. Se indica el número
de elementos aunque no es necesario hacerlo. Se están asignando 5 valores iniciales. El compilador asume que el
array tiene 5 elementos.
int digitos[8]= {3,4,2,7};
Se declara un array unidimensional llamado digitos que contiene 8 elementos de tipo int. Aquí sí es necesario
indicar el número de elementos del array porque solo se le asignan valores iniciales a los cuatro primeros. El
compilador asumiría que el array tiene solo 4 elementos. En este caso los cuatro últimos elementos del array
que no reciben valores iniciales, toman el valor 0.
digitos[0]=3, digitos[1]=4, digitos[2]=2, digitos[3]=7,
digitos[4]=0, digitos[5]=0, digitos[6]=0, digitos[7]=0

Las declaraciones de arrays que hemos hecho hasta ahora se llaman declaraciones implícitas: para cada array
que se declara hay que indicar el tipo y la dimensión.
Una alternativa a esto es definir un nuevo tipo de dato para el array asignándole un nombre, y posteriormente
declarar las variables como pertenecientes a ese tipo.

C++ dispone del especificador typedef que permite la creación de nuevos tipos de datos.
Los tipos de datos creados con typedef son sinónimos de otros tipos ya existentes.
Por ejemplo, la siguiente instrucción crea un nuevo tipo de dato llamado entero, sinónimo de int.

typedef int entero;

A partir de esta instrucción podemos declarar variables enteras así:


entero a, b=3;
Utilizando typedef podemos crear nuevos tipos de datos sinónimos de tipos array. La forma general
de hacerlo es:

typedef tipo_base nombre_nuevo_tipo[dimension];


Ejemplo:
typedef int Tvector[30];
Esta instrucción crea un nuevo tipo de dato llamado Tvector. Las variables que se declaren de este tipo serán arrays de 30
enteros.

Por ejemplo:
Tvector a, b;

Ejemplo: Generar 2 vectores (a y b) con números aleatorios. Sumar sus elementos en otro vector llamado
s. Mostrar todos los vectores

#include <iostream>
using namespace std;
const int n=10;

void cargarvector(int v[n]);


void sumar(int x[n],int y[n],int s[n]);
void mostrarvec(int v[n]);

int main() {

int a[n],b[n],s[n];
cargarvector(a);
cargarvector(b);
sumar(a,b,s);
cout<<"vector a"<<endl;

EEST N° 5 Amancio Willians 49


Prof. Abdala Achaval Pablo
mostrarvec(a);
cout<<"vector b"<<endl;
mostrarvec(b);
cout<<"suma"<<endl;
mostrarvec(s);
system("pause");
return 0;
}

void cargarvector(int v[n])


{ int i;
srand(time(NULL))
for(i=0;i<n;i++)
{ v[i] = rand()%100;
}
}
void sumar(int x[n],int y[n],int s[n])
{ int i;
for(i=0;i<n;i++)
{ s[i]=x[i]+y[i];
}
}
void mostrarvec(int v[n])
{ int i;
for(i=0;i<n;i++)
{ cout<<v[i]<<'/'<<endl;
}
cout<<endl;
}

Vectores Bidimensionales o Matrices


Un vector multidimensional, es un vector de vectores. Una matriz es un vector bidimensional.
Declaración de una matriz: int vector[filas][columnas];

int a[5][5],m[10][4],i,j,f,c // nombre del vector y dimensión


Ejemplo:
int vector[5][3];
Su representación es:

Lectura de una Matriz (llenado): Cada elemento se referencia a través


for (i=0; i<5;i++) del nombre y su ubicación en el

EEST N° 5 Amancio Willians 50


Prof. Abdala Achaval Pablo
{ conjunto, por ejemplo:
for (j=0; j < 5 ; j=j+1)
{ {
Cout<<”\n Ingrese a[4][2]=10; // Se almacena en
elemento A[“<<i<<”][“<<j<<”] = la fila 5, columna 3 el valor 10
”; m[0][5]=0; // Se almacena en la
Cin>>a[i][j]; fila uno, columna 6 el valor 0
} if (a[i][j] == a[j][i] ) // se
} consulta si el valor ubicado en la
fila i-1 y columna j-1 es igual al
elemento
//
almacenado en la fila j-1 y columna
i-1
}
Consideraciones importantes asociadas al uso de matrices:

• El procesamiento de todos los elementos requiere como mínimo dos ciclos iterativos.
• Dentro de los ciclos se deben realizar las operaciones específicas que se solicitan.
• Una matriz cuadrada es aquella en el numero de filas es igual al número de columnas.
• Entre las aplicaciones más importantes de las matrices está la posibilidad de resolver sistemas de ecuaciones con n
variables.

Las matrices cuadradas tienen algunas características importantes asociadas a la ubicación de sus elementos en el
conjunto. Se puede hablar de diagonal principal, diagonal secundaria, triangular superior, triangular inferior, por mencionar
algunas.

Ordenamiento de Vectores

Es la operación de arreglar los registros de una tabla en algún orden secuencial de acuerdo a un criterio de
ordenamiento. El ordenamiento se efectúa con base en el valor de algún campo en un registro. El propósito
principal de un ordenamiento es el de facilitar las búsquedas de los miembros del conjunto ordenado.

El ordenar un grupo de datos significa mover los datos o sus referencias para que queden en una secuencia tal
que represente un orden, el cual puede ser numérico, alfabético o incluso alfanumérico, ascendente o
descendente.

EEST N° 5 Amancio Willians 51


Prof. Abdala Achaval Pablo
Ordenamiento Por Selección (Selection Sort)

• Busca el elemento más pequeño de la lista.


• Intercambia con el elemento ubicado en la primera posición de la lista.
• Busca el segundo elemento más pequeño de la lista.
• Lo intercambia con el elemento que ocupa la segunda posición en la lista.
• Repite este proceso hasta que haya ordenado toda la lista.

ANÁLISIS DEL ALGORITMO.

• Requerimientos de Memoria: Al igual que el ordenamiento burbuja, este algoritmo sólo necesita una variable
adicional para realizar los intercambios.
• Tiempo de Ejecución: El ciclo externo se ejecuta n veces para una lista de n elementos. Cada búsqueda
requiere comparar todos los elementos no clasificados.

Ventajas:
• Fácil implementación.
• No requiere memoria adicional.
• Rendimiento constante: poca diferencia entre el peor y el mejor caso.

Desventajas:

• Lento.
• Realiza numerosas comparaciones

#include <iostream>
Using namespace std;

void seleccionsort(int vector[15],int tamano);


void mostrarVector(int[], int);

int _main( )
{
const int tamano = 15;
int vector[tamano] = {25,17,13,16,41,32,12,115,95,84,54,63,78,21,10};
int i;
cout << "vector sin ordenar\n" ;
mostrarVector(vector,tamano);
cout << "vector ordenado\n" ;
seleccionsort(vector,tamano);
mostrarVector(vector,tamano);
system(“pause”);
return 0;
}

void seleccionsort (int A[], int n)


{
int min,i,j,aux;
for (i=0; i<n-1; i++)
{
min=i;
for(j=i+1; j<n; j++)
{ if(A[min] > A[j])
{min=j;
aux=A[min];
A[min]=A[i];
A[i]=aux ;}
}
}
}

EEST N° 5 Amancio Willians 52


Prof. Abdala Achaval Pablo
void mostrarVector( int vector[], int tamano)
{
for (int i = 0 ; i < tamano ; i++)
cout << vector[i] << "/";
cout<<"\n";
}

Ordenamiento BubbleSort o Burbuja o Intercambio Directo.

Es un sencillo algoritmo de ordenamiento.

Funciona revisando cada elemento de la lista que va a ser ordenada con el siguiente, intercambiándolos de
posición si están en el orden equivocado. Es necesario revisar varias veces toda la lista hasta que no se necesiten
más intercambios, lo cual significa que la lista está ordenada. Este algoritmo obtiene su nombre de la forma con
la que suben por la lista los elementos durante los intercambios, como si fueran pequeñas "burbujas". También
es conocido como el método del intercambio directo.

Dado que solo usa comparaciones para operar elementos, se lo considera un algoritmo de comparación, siendo
el más sencillo de implementar.

#include <iostream>
Using namespace std;

void BubbleSort(int vector[15],int tamano);


void mostrarVector(int[], int);

int main(int argc, _TCHAR* argv[])


{
const int tamano = 15;
int vector[tamano] = {20,17,13,16,41,32,12,115,95,84,54,63,78,21,10};
int i;
cout << "vector sin ordenar\n" ;
mostrarVector(vector,tamano);
cout << "vector ordenado\n" ;
BubbleSort(vector,tamano);
mostrarVector(vector,tamano);
system(“pause”);
return 0;
}
//-----------------------------------------------------------------
void BubbleSort(int A[],int n)
{int i, j, inc, temp, k,item ;

for (i = 1; i <n; i++ )


{
for (j = 0; j <n - i ; j++)
{
if (A[j]> A[j + 1])
{
temp = A[j];
A[j] = A[j + 1] ;
A[j + 1] = temp;
}
}
}
}

void mostrarVector( int vector[], int tamano)


{
for (int i = 0 ; i < tamano ; i++)
cout << vector[i] << "/";

EEST N° 5 Amancio Willians 53


Prof. Abdala Achaval Pablo
cout<<"\n";
}

Ordenamiento Por Inserción Directa

DESCRIPCIÓN.

El algoritmo de ordenación por el método de inserción directa es un algoritmo relativamente sencillo y


se comporta razonablemente bien en gran cantidad de situaciones.

Completa la tripleta de los algoritmos de ordenación más básicos y de orden de complejidad cuadrático,
junto con SelectionSort y BubbleSort.

Se basa en intentar construir una lista ordenada en el interior del array a ordenar.
De estos tres algoritmos es el que mejor resultado da a efectos prácticos. Realiza una cantidad de
comparaciones bastante equilibrada con respecto a los intercambios, y tiene un par de características que lo
hacen aventajar a los otros dos en la mayor parte de las situaciones.
Este algoritmo se basa en hacer comparaciones, así que para que realice su trabajo de ordenación son
imprescindibles dos cosas: un array o estructura similar de elementos comparables y un criterio claro de
comparación, tal que dados dos elementos nos diga si están en orden o no.

• En cada iteración del ciclo externo los elementos 0 a i forman una lista ordenada

ANÁLISIS DEL ALGORITMO.

• Estabilidad: Este algoritmo nunca intercambia registros con claves iguales. Por lo tanto es estable.
• Requerimientos de Memoria: Una variable adicional para realizar los intercambios.

• Tiempo de Ejecución: Para una lista den elementos el ciclo externo se ejecuta n1 veces. El ciclo interno se
ejecuta como máximo una vez en la primera iteración, 2 veces en la segunda, 3 veces en la tercera, etc.

Ventajas:

• Fácil implementación.
• Requerimientos mínimos de memoria.

Desventajas:

• Lento.
• Realiza numerosas comparaciones.

Este también es un algoritmo lento, pero puede ser de utilidad para listas que están ordenadas o semi
ordenadas, porque en ese caso realiza muy pocos desplazamientos.

void insercionDirecta(int A[],int n)


{
int i,j,v;
for (i = 1; i < n; i++)
{
v = A[i];
j=i -1;

EEST N° 5 Amancio Willians 54


Prof. Abdala Achaval Pablo
while (j >= 0 && A[j] > v)
{
A[j + 1] = A[j];
j--;
}A[j+ 1] = v ;
}
}

Método De Ordenamiento Por Inserción Binaria

El método de ordenación por 'inserción binaria'' es una mejora del método de inserción directa. Para lograr esta
mejora se recurre a una búsqueda binaria en lugar de una búsqueda secuencial para insertar un elemento en la
parte izquierda del vector, que ya se encuentra ordenado. El resto del procedimiento es similar al de inserción
directa, es decir, se repite este mismo procedimiento desde el segundo término hasta el último elemento.

void insercionBinaria(int A[],int n)


{
int i,j,aux,izq,der,m;
for(i=1;i<n;i++)
{
aux = A[i];
izq=0;
der=i-1;
while(izq<=der)
{
m=((izq+der)/2);
if (aux<A[m])
der=m-1;
else
izq=m+1;
}
j=i-1;
while(j>=izq)
{
A[j+1]=A[j];
j=j-1;
}A[izq]=aux;
}

Ordenamiento por el Método Shell

El método Shell es una versión mejorada del método de inserción directa. Este método también se conoce con
el nombre de inserción con incrementos decrecientes. En el método de ordenación por inserción directa cada
elemento se compara para su ubicación correcta en el vector, con los elementos que se encuentran en la parte
izquierda del mismo. Si el elemento a insertar es más pequeño que el grupo de elementos que se encuentran a
su izquierda, es necesario efectuar entonces varias comparaciones antes de su ubicación.

Shell propone que las comparaciones entre elementos se efectúen con saltos de mayor tamaño pero con
incrementos decrecientes, así, los elementos quedarán ordenados en el vector más rápidamente.

EEST N° 5 Amancio Willians 55


Prof. Abdala Achaval Pablo
El Shell sort es una generalización del ordenamiento por inserción, teniendo en cuenta dos observaciones:

1. El ordenamiento por inserción es eficiente si la entrada está "casi ordenada".


2. El ordenamiento por inserción es ineficiente, en general, porque mueve los valores sólo una posición
cada vez.

El algoritmo Shell sort mejora el ordenamiento por inserción comparando elementos separados por un espacio
de varias posiciones. Esto permite que un elemento haga "pasos más grandes" hacia su posición esperada. Los
pasos múltiples sobre los datos se hacen con tamaños de espacio cada vez más pequeños. El último paso del
Shell sort es un simple ordenamiento por inserción, pero para entonces, ya está garantizado que los datos del
vector están casi ordenados.

El Shell sort lleva este nombre en honor a su inventor, Donald Shell, que lo publicó en 1959.

#include <iostream>
Using namespace std;

void ordenShell(int vector[15],int tamano);


void mostrarVector(int[], int);

int main( )
{
const int tamano = 15;
int vector[tamano] = {25,17,13,16,41,32,12,115,95,84,54,63,78,21,10};
int i;
cout << "vector sin ordenar\n" ;
mostrarVector(vector,tamano);
cout << "vector ordenado\n" ;
ordenShell(vector,tamano);
mostrarVector(vector,tamano);
system(“pause”);
return 0;
}
//---------------------------------------------------------------------------
void ordenShell(int A[],int n)
{int i, j, inc, temp;
for(inc = 1 ; inc<n;inc=inc*3+1);
while (inc > 0)
{
for (i=inc; i < n; i++)
{
j = i;
temp = A[i];
while ((j >= inc) && (A[j-inc] > temp))
{
A[j] = A[j - inc];
j = j - inc;
}
A[j] = temp;
}
inc/= 2;
}
}
void mostrarVector( int vector[], int tamano)
{
for (int i = 0 ; i < tamano ; i++)
cout << vector[i] << "/";
cout<<"\n";
}

EEST N° 5 Amancio Willians 56


Prof. Abdala Achaval Pablo
Ordenamiento Heap Sort

El ordenamiento por montículos (Heap sort) es un algoritmo de ordenación no recursivo, no estable.

Este algoritmo consiste en almacenar todos los elementos del vector a ordenar en un montículo (heap), y luego
extraer el nodo que queda como nodo raíz del montículo (cima) en sucesivas iteraciones obteniendo el
conjunto ordenado. Basa su funcionamiento en una propiedad de los montículos, por la cual, la cima contiene
siempre el menor elemento (o el mayor, según se haya definido el montículo) de todos los almacenados en él.

El significado de heap en ciencia computacional es el de una cola de prioridades (priority queue). Tiene las
siguientes características:

Un heap es un vector de n posiciones ocupado por los elementos de la cola. (Nota: se utiliza un vector que
inicia en la posición 1 y no en cero, de tal manera que al implementarla en C se tienen n+1 posiciones en el
vector.)

Se mapea un árbol binario de tal manera en el vector que el nodo en la posición i es el padre de los nodos en las
posiciones (2*i) y (2*i+1).

El valor en un nodo es mayor o igual a los valores de sus hijos. Por consiguiente, el nodo padre tiene el mayor
valor de todo su subárbol.

PROCEDIMIENTO

Heap Sort consiste esencialmente en:

• Convertir el vector en un heap


• Construir un vector ordenado de atrás hacia adelante (mayor a menor) repitiendo los siguientes pasos:

• Sacar el valor máximo en el heap (el de la posición 1)


• Poner ese valor en el vector ordenado
• Reconstruir el heap con un elemento menos
• Utilizar el mismo vector para el heap y el vector ordenado

#include <iostream>
using namespace std;

void heapsort(int vector[15],int tamano);


void mostrarVector(int[], int);

int _tmain( )
{
const int tamano = 15;
int vector[tamano] = {0,17,13,16,41,32,12,115,95,84,54,63,78,21,10};
int i;
cout << "vector sin ordenar\n" ;
mostrarVector(vector,tamano);
cout << "vector ordenado\n" ;
heapsort(vector,tamano);
mostrarVector(vector,tamano);
system(“pause”);
return 0;
}
//-----Este método comienza en la posición 1!!! ---------------------

EEST N° 5 Amancio Willians 57


Prof. Abdala Achaval Pablo
void heapsort(int A[],int n)
{int i, j, inc, temp, k,item ;
for(k=n;k>0;k--)
{
for(i=1;i<=k;i++)
{
item=A[i];
j=i/2;
while(j>0 && A[j]<item)
{
A[i]=A[j];
i=j;
j=j/2;
}
A[i]=item;
}
temp=A[1];
A[1]=A[k];
A[k]=temp;
}
}

void mostrarVector( int vector[], int tamano)


{
for (int i = 1 ; i < tamano ; i++)
cout << vector[i] << "/";
cout<<"\n";
}

Búsqueda de elementos en un Vector

La búsqueda de un elemento dentro de un array es una de las operaciones más importantes en el


procesamiento de la información, y permite la recuperación de datos previamente almacenados. El tipo de
búsqueda se puede clasificar como interna o externa, según el lugar en el que esté almacenada la información
(en memoria o en dispositivos externos). Todos los algoritmos de búsqueda tienen dos finalidades:

- Determinar si el elemento buscado se encuentra en el conjunto en el que se busca.


- Si el elemento está en el conjunto, hallar la posición en la que se encuentra.

En este apartado nos centramos en la búsqueda interna. Como principales algoritmos de búsqueda en arrays
tenemos la búsqueda secuencial, la binaria y la búsqueda utilizando tablas de hash.

Búsqueda secuencial

Consiste en recorrer y examinar cada uno de los elementos del array hasta encontrar el o los elementos
buscados, o hasta que se han mirado todos los elementos del vector.

void secuencia(int a[n1],int k1)


{
int cual,x1;
bool ubicado=false;
cout<<"Que elemento se buscara? : ";cin>>cual;
cout<<endl;
for(x1=0;x1<=k1+1;x1++)
{
if(a[x1]==cual)

EEST N° 5 Amancio Willians 58


Prof. Abdala Achaval Pablo
{
ubicado=true;
cout<<"Elemento encontrado en la posicion "<<x1<<endl;
}
}
if (ubicado=false) cout<<"Elemento no encontrado"<<endl;
}

Búsqueda binaria

La búsqueda binaria sólo se puede implementar si el vector está ordenado. La idea consiste en ir dividiendo el
vector en mitades. Por ejemplo supongamos que tenemos este vector:

int vector[10] = {2,4,6,8,10,12,14,16,18,20};

La clave que queremos buscar es 6. El algoritmo funciona de la siguien manera

1. Se determinan un indice arriba y un indice abajo, Iarriba=0 e Iabajo=9 respectivamente.


2. Se determina un indice central, Icentro = (Iarriba + Iabajo)/2, en este caso quedaría Icentro = 4.
3. Evaluamos si vector[Icentro] es igual a la clave de busqueda, si es igual ya encontramos la clave y
devolvemos Icentro.
4. Si son distintos, evaluamos si vector[Icentro] es mayor o menos que la clave, como el vector está
ordenado al hacer esto ya podemos descartar una mitad del vector asegurandonos que en esa mitad no
está la clave que buscamos. En nuestro caso vector[Icentro] = 4 < 6, entonces la parte del vector
vector[0...4] ya puede descartarse.
5. Reasignamos Iarriba o Iabajo para obtener la nueva parte del vector en donde queremos buscar. Iarriba,
queda igual ya que sigue siendo el tope. Iabajo lo tenemos subir hasta 5, entonces quedaria Iarriba = 9,
Iabajo = 5. Y volvemos al paso 2.

Si la clave no fuese encontrada en algun momento Iabajo > Iarriba, con un while vamos a controlar esta
condición para salir del ciclo en tal caso y devolver -1 (clave no encontrada).

Hagamos modificaciones al código de búsqueda lineal para implementar una función de búsqueda binaria.

//Búsqueda binaria en un vector.

#include <iostream>
using namespace std;

int busquedaBinaria(const int[], int, int); //vector, tamaño, clave


void ordenarVector(int[], int); //prototipo que modifica y ordena el vector
void intercambiar(int&, int&); //prototipo, intercambia los valores de dos
elementos
void mostrarVector(int[], int);
//--------------------------------------------------------------------

#pragma argsused
int main()
{
int clave =0;
const int tamano = 15;
int vector[tamano] = {20,17,13,16,41,32,12,115,95,84,54,63,78,21,10};
int i;
//ordenamos el vector para que funcione la busquedaBinaria

EEST N° 5 Amancio Willians 59


Prof. Abdala Achaval Pablo
cout << "Vector sin ordenar\n" ;
mostrarVector(vector,tamano);
ordenarVector(vector,tamano);
cout << "Elementos del vector ordenado:\n";
mostrarVector(vector,tamano);
cout << "Indique un valor a buscar y se le devolvera el indice: " ;
cin >> clave;
cout<< "Su valor se encuentra en
vector["<<busquedaBinaria(vector,tamano,clave)<<"]" ;
cout << "Fin del programa :)";
system(“pause”);
return 0;
}

void mostrarVector( int vector[], int tamano)


{
for (int i = 0 ; i < tamano ; i++)
cout << vector[i] << "/";
cout<<"\n";
}

int busquedaBinaria(const int vector[], int tamano, int clave)


{
int Iarriba = tamano-1;
int Iabajo = 0;
int Icentro;
while (Iabajo <= Iarriba)
{
Icentro = (Iarriba + Iabajo)/2;
if (vector[Icentro] == clave)
return Icentro;
else
if (clave < vector[Icentro])
Iarriba=Icentro-1;
else
Iabajo=Icentro+1;
}
return -1;
}

void ordenarVector(int vector[], int tamano)


{
for (int i = 0; i< tamano -1 ; i++)
for (int j = 0; j< tamano -1 ; j++)
if (vector[j] > vector[j+1])
intercambiar(vector[j],vector[j+1]);
}

void intercambiar(int &a, int &b)


{
int tmp = b;
b = a;
a = tmp;
}

Archivos
Hasta ahora, siempre hemos leído mediante cin, y escrito mediante cout. Sin embargo, a veces es cómodo
utilizar uno o más (todos los que queramos) archivos de texto de donde sacar los datos, y similarmente
escribir a uno o más archivos los resultados de nuestro programa.

EEST N° 5 Amancio Willians 60


Prof. Abdala Achaval Pablo
En C++, utilizar archivos es muy fácil, ya que la forma de hacerlo es prácticamente igual a lo que ya venimos
haciendo con cin y cout.

Para utilizar archivos y hacer funcionar los ejemplos de esta sección, tendremos que incluir #include <fstream>
en nuestros programas.

Archivos de entrada

Es posible crear una variable que represente un archivo de entrada, del cual el programa leerá datos. Estas
variables se utilizan de exactamente igual manera que cin, y se declaran como en el siguiente programa de
ejemplo:

#include <fstream>

using namespace std;

int main()
{
ifstream archivo1("nombre1.txt");
ifstream archivo2("nombre2.in");
int x,y,z;
archivo1 >> x>> y >> z;
string a; int b;
archivo2 >> a >> b;
return 0;
}

En el ejemplo se ve que podemos leer datos contenidos en los archivos exactamente igual que hacíamos con cin,
pero indicando la variable del archivo correspondiente. En lugar de tener que ser tipeados por el usuario, el
programa recibe los datos contenidos en los archivos correspondientes. Las variables son de tipo ifstream (Del
inglés, “Input File Stream”), y al declararlas se indica entre paréntesis el nombre del archivo del cuál se leerá
utilizando esa variable. Dicho archivo debe existir y contener los datos deseados, al momento de ejecutar el
programa.

En este ejemplo se usan dos archivos distintos: El contenido de “nombre1.txt” se guarda en x,y,z (que tendrán 3
enteros) y el de “nombre2.in” se guarda en a,b (Un string y un entero).

Archivos de salida

Los archivos de salida se pueden utilizar de manera completamente análoga a los de entrada, pero operando
como si fueran cout, y su tipo será ofstream (Del inglés “Output File Stream”).

#include <fstream>

using namespace std;

int main()
{
ofstream archivo1("nombre1.txt");
ofstream archivo2("nombre2.out");
int x = 32,y = 10;
archivo1 << x << " " << y << " " << -33 << endl;
string a = "pepe"; int b = 100;
archivo2 << a << endl << b << endl;
return 0;
}

EEST N° 5 Amancio Willians 61


Prof. Abdala Achaval Pablo
Luego de ejecutar este programa, “nombre1.txt” contendrá lo siguiente:

32 10 -33

y “nombre2.out” contendrá lo siguiente:

pepe
100

Registros / Data Structures / Estructuras

El lenguaje C++ permite definir variables que combinen diferentes ítems/ tipos de datos. A esto se le llama
registros.

Por ejemplo.

El siguiente es un programa que contendrá un registro llamado Netjuegos con los siguientes campos: id_juego;
Nick_jugador; nombre_juegos; puntaje_jugador; dia_mes_anio.

Crear un archivo plano llamado juegos.in que contenga los siguientes datos:

En donde el primer número(15) representa la cantidad de registros.

15
123222 daniel counter-strike 9776 02-noviembre-2017
213323 selena counter-strike 6587 04-noviembre-2017
112326 ciclo_ counter-strike 4355 05-noviembre-2017
131234 nester counter-strike 3456 07-noviembre-2017
244329 cheste counter-strike 1424 10-noviembre-2017
876789 alpase -----LOL------ 5334 08-octubre-2017
324243 lechne -----LOL------ 4223 12-octubre-2017
878976 casior -----LOL------ 3003 14-cotubre-2017
564635 veg777 -----LOL------ 2322 20-julio-2017
647643 alexLO -----LOL------ 1023 23-octubre-2017
875785 redox_ --minecraft--- 100000 04-febrero-2018
437253 astero --minecraft--- 845784 07-febrero-2018
436572 segova --minecraft--- 679864 13-febrero-2018
984394 vipter --minecraft--- 45678 23-febrero-2018
978438 omega_ --minecraft--- 20000 26-febrero-2018

Se solicita: leer los datos del archivo y mostrarlos por pantalla.

#include <iostream>
#include <fstream>
const int maximo=256;
using namespace std;
int n;
struct Netjuegos
{
int id_juego;
char nick_jugador[maximo];
char nombre_juego[máximo];
int puntaje_jugador;
char dia_mes_ano[máximo];

EEST N° 5 Amancio Willians 62


Prof. Abdala Achaval Pablo
};
ifstream ent;
ofstream sal;
void leer_datos(struct Netjuegos Art[maximo]);
void mostrar_datos(struct Netjuegos Art[maximo);
int main()
{
struct Netjuegos Art[máximo];
ent.open("juegos.in");
leer_datos(Art);
mostrar_datos(Art);

system("pause");
return 0;
}
void leer_datos (struct Netjuegos Art[maximo])
{
int i;
ent>>n;
for(i=0;i<n;i++)
{
ent>>Art[i].id_juego>>Art[i].nick_jugador>>Art[i].nombre_juego>>Art[i].puntaj
e_jugador>>Art[i].dia_mes_ano;
}
}
void mostrar_datos (struct Netjuegos Art[maximo])
{
int i;
cout<<"id_juego nick_jugador nombre_juego puntaje_jugador
dia_mes_año"<<endl;
for(i=0;i<n;i++)
{
cout<<Art[i].id_juego<<" "<<Art[i].nick_jugador<<"
"<<Art[i].nombre_juego<<" "<<Art[i].puntaje_jugador<<"
"<<Art[i].dia_mes_ano<<" "<<endl;
}
}

Tratamiento de Cadenas CHAR como "arreglos o vector de


char", "cadenas", o "cstring".
DE COPIA:

strcpy()
Copiar una cadena y pegarla sobre otra.

Copia la cadena apuntada por "fuente" al arreglo apuntado por "destino", insertando por su cuenta el caracter
de fin de cadena (barra invertida cero). Hay que destacar que para que el programa no explote al realizar esta
operación, el arreglo "destino" tiene que tener un tamaño de por lo menos la cantidad de
caracteres que haya en "fuente" + 1 (espacio para el caracter de fin de cadena) o dicho de otra forma:
tamaño mínimo de destino debe ser >= strlen( fuente ) + 1.

EEST N° 5 Amancio Willians 63


Prof. Abdala Achaval Pablo
Valor de retorno: puntero a "destino".

strncpy()
Copia los primeros "n" caracteres de una cadena a otra.

Copia los primeros "cuantos" caracteres de "fuente" a "destino". Si el final de la cadena "fuente" (indicado por el
caracter de fin de cadena 'barra invertida cero' ) es alcanzado antes de que se copien la cantidad de caracteres
indicados por "cuantos", el arreglo "destino" se llena con ceros hasta que una cantidad de "cuantos" caracteres
hayan sido escritos en él.

Valor de retorno: puntero a "destino" .

// Ejemplo de uso en C++


#include <iostream>
#include <cstring>
using namespace std;

int main ()
{
const int tamanyo = 40;
char cad1[]= "Ser o no ser";
char cad2[tamanyo];
char cad3[tamanyo];

/* Copiar la cantidad máxima permitida por cad2 */


strncpy( cad2, cad1, tamanyo );

/* copia parcial (colamente 5 chars): */


strncpy( cad3, cad2, 5 );
cad3[5] = '\0'; /* caracter de fin de cadena agregado manualmente */

cout<<cad1<<endl;
cout<<cad2<<endl;
cout<<cad3<<endl;

return 0;
}
Salida:

Ser o no ser

Ser o no ser

Ser o

EEST N° 5 Amancio Willians 64


Prof. Abdala Achaval Pablo
DE CONCATENACIÓN:

strcat()
Concatena dos cadenas.

Pega una copia de la cadena "fuente" al final de la cadena "destino". El "pegado" se produce desde la posición del
caracter nulo o de fin de cadena (barra invertida cero) en "destino", sobreescribiéndolo con el primer caracter
de "fuente" y continuando. Un nuevo caracter de fin de cadena es insertado al final del proceso. Como con
strcpy(), hay que resaltar que el arreglo "destino" tiene que tener un tamaño suficiente para anexar
su contenido a la cadena "fuente", es decir:

tamaño de destino >= strlen( destino ) + strlen( fuente ) + 1.

Valor de retorno: un puntero a "destino".

Ejemplos de uso:

// Ejemplo de uso en C++


#include <iostream>
#include <cstring>
using namespace std;

int main ()
{
char cad[80];
char cad2[] = "estan ";

strcpy( cad, "estas " );

strcat( cad, "cadenas " );


strcat( cad, cad2 );
strcat( cad, "concatenadas." );

cout<<cad;

return 0;
}
Salida:

estas cadenas estan concatenadas.

EEST N° 5 Amancio Willians 65


Prof. Abdala Achaval Pablo
strncat()
Concatena los primeros "n" caracteres de una cadena al final de otra.

Pega los primeros "cuantos" caracteres de fuente al final de "destino", agregando solo el caracter de fin de
cadena. Si el tamaño de la cadena "fuente" es menor a la cantidad de caracteres "cuantos", se copiará y pegará
solamente los caracteres que haya hasta llegar al caracter de fin de cadena de "fuente". Se deben tener las
mismas precauciones de tamaños de arreglos que las indicadas para strcat().

Valor de retorno: puntero a "destino".

Ejemplos de uso:

// Ejemplo de uso en C++


#include <iostream>
#include <cstring>
using namespace std;

int main ()
{
char cad1[20];
char cad2[20];
strcpy( cad1, "Ser " );
strcpy( cad2, "o no ser" );
strncat( cad1, cad2, 4 );
cout<<cad1;

return 0;
}

Salida:

Ser o no

DE COMPARACIÓN:

strcmp()
Compara si dos cadenas son iguales.

Compara la cadena "cad1" con la cadena "cad2".

Esta función comienza comparando el primer caracter de cada cadena. Si estos caracteres son iguales, continua
con el siguiente par hasta que los caracteres comparados son distintos o se alcanza un caracter nulo o de fin de

EEST N° 5 Amancio Willians 66


Prof. Abdala Achaval Pablo
cadena.

Valor de retorno: retorna un valor int que indica la relación entre las dos cadenas:
- Un valor 0 (cero) indica que las dos cadenas son iguales.
- Un valor mayor a cero indica que el primer caracter encontrado que es distinto tiene un valor mayor en cad1
que en cad2.

- Un valor menor a cero indica lo contrario a lo anterior.

// Ejemplo de uso en C++


#include <iostream>
#include <cstring>
using namespace std;

int main ()
{
char clave[] = "manzana";
char entradaClave[80];
do {
cout<<"Cual es mi fruta preferida? ";
cin.getline( entradaClave, 80 );
} while ( strcmp( clave, entradaClave ) != 0 );
cout<<"Respuesta correcta!";
return 0;
}

strncmp()
Compara si los primeros "n" caracteres de una cadena son iguales a los primeros "n" caracteres de otra.

Compara los primeros "cuantos" caracteres de la cadena "cad1" con los primeros "cuantos" caracteres de la
cadena "cad2".

Esta función comienza comparando el primer caracter de cada cadena. Si estos caracteres son iguales, continua
con el siguiente par hasta que los caracteres comparados son distintos, o se alcanza un caracter nulo o de fin de
cadena, o hasta que "cuantos" caracteres ah sido comparados y encontrados iguales, lo que pase primero.

Valor de retorno: retorna un valor int que indica la relación entre las dos cadenas:
- Un valor 0 (cero) indica que las dos cadenas son iguales.
- Un valor mayor a cero indica que el primer caracter encontrado que es distinto tiene un valor mayor en cad1
que en cad2.

EEST N° 5 Amancio Willians 67


Prof. Abdala Achaval Pablo
- Un valor menor a cero indica lo contrario a lo anterior.

// Ejemplo de uso en C++


#include <iostream>
#include <cstring>
using namespace std;

int main ()
{
char str[][5] = { "R2D2" , "C3PO" , "R2A6" };
cout<<"Buscando astromech droids R2..."<<endl;
for( int n=0 ; n<3; n++ ) {
if ( strncmp ( str[n], "R2xx", 2) == 0 )
{
cout<<"Encontrado: "<<str[n]<<endl;
}
}
return 0;
}

DE BÚSQUEDA:

strrchr()
Busca en la cadena la última ocurrencia de un caracter (char) indicado.

// Ejemplo de uso en C++


#include <iostream>
#include <cstring>
using namespace std;

int main ()
{
char str[] = "Esta es una cadena de ejemplo";
char * pch;
cout<<"Buscando el caracter 's' en \""<<str<<"\"...\n\n";
pch = strchr( str, 's' );
while( pch != NULL )
{
cout<<"Encontrado en la posicion "<<pch-str+1<<endl;
cout<<"El puntero retornado apunta a: "<<pch<<endl;
/* busca desde después del último encontrado */
pch = strchr( pch+1, 's' );
}
return 0;
}
Salida:

EEST N° 5 Amancio Willians 68


Prof. Abdala Achaval Pablo
Buscando el caracter 's' en "Esta es una cadena de ejemplo"...

Encontrado en la posicion 2
El puntero retornado apunta a: sta es una cadena de ejemplo
Encontrado en la posicion 7
El puntero retornado apunta a: s una cadena de ejemplo

strcspn()
Busca en una cadena la primera ocurrencia de cualquiera de los caracteres de otra cadena y retorna la posición
de la misma.

Retorna un puntero a la última ocurrencia de "letra" en "cad". El caracter de fin de cadena es considerado parte
de la cadena, por lo que puede ser buscado para obtener un puntero al final de la misma.

Valor de retorno: Un puntero a la última ocurrencia de "letra" en "cad". Si el caracter no es encontrado,


devuelve NULL.

Ejemplos de uso:

// Ejemplo de uso en C++


#include <iostream>
#include <cstring>
using namespace std;

int main ()
{
char str[] = "Esta es una cadena de prueba";
char * pch;
pch = strrchr( str, 's' );
cout<<"La ultima ocurrencia de 's' fue encontrada en la posicion "<<pch-
str+1<<endl;
cout<<"El puntero retornado apunta a: "<<pch;
return 0;
}
Salida:

La ultima ocurrencia de 's' fue encontrada en la posicion 7


El puntero retornado apunta a: s una cadena de prueba

strpbrk()
Busca en una cadena la primera ocurrencia de cualquiera de los caracteres de otra cadena y retorna un puntero
a char con la subcadena formada desde esa posición.

Retorna un puntero a la primera ocurrencia en "cad1" de cualquiera de los caracteres contenidos en "cad2", o
un puntero a NULL si no hubo coincidencias.

EEST N° 5 Amancio Willians 69


Prof. Abdala Achaval Pablo
La búsqueda no incluye al caracter de fin de cadena de ninguno de los dos cstrings, pero termina ahí.

Ejemplos de uso:

// Ejemplo de uso en C++


#include <iostream>
#include <cstring>
using namespace std;

int main ()
{
char cadena[] = "Esto es un cstring de prueba";
char claves[] = "aeiou";
char * pch;
cout<<"Vocales en '"<<cadena<<"': ";
pch = strpbrk( cadena, claves );
while( pch != NULL )
{
cout<<*pch<<" ";
pch = strpbrk( pch+1, claves );
}
return 0;
}

Salida:

Vocales en 'Esto es un cstring de prueba': o e u i e u e a

strspn()
Retorna el largo de la porción inicial de una cadena que está formada solamente por los caracteres presentes en
otra.

Retorna la longitud de la porción inicial de "cad1" que consiste solamente de caracteres que son parte de
"cad2".

La búsqueda no incluye el caracter de fin de cadena de ninguna de las dos cadenas, pero termina en ese punto.

Valor de retorno: la longitud de la porción inicial de "cad1" que consiste solamente de caracteres que son parte
de "cad2".
Por lo tanto, si todos los caracteres de "cad1" están en "cad2" la función retorna el largo de "cad1", y si el
primer caracter de "cad1" no está en "cad2" la función retorna cero.

Ejemplos de uso:

// Ejemplo de uso en C++


#include <iostream>

EEST N° 5 Amancio Willians 70


Prof. Abdala Achaval Pablo
#include <cstring>
using namespace std;

int main ()
{
char cadena[] = "129asd";
char numeros[] = "1234567890";
int i = strspn( cadena, numeros );
cout<<"El numero inicial de la cadena tiene "<< i <<" digitos.";
return 0;
}
Salida:

El numero inicial de la cadena tiene 3 digitos.

strstr()
Busca una cadena dentro de otra cadena, retorna un puntero a la subcadena.

Retorna un puntero a la primera ocurrencia de "cad2" (completa) en "cad1", o un puntero NULL si "cad2" no es
parte de "cad1".

El proceso de búsqueda y comparación no incluye al caracter de fin de cadena, pero se detiene al llegar al
mismo.

El siguiente ejemplo busca "simple" dentro de la cadena y lo reemplaza por "propia":

// Ejemplo de uso en C++


#include <iostream>
#include <cstring>
using namespace std;

int main ()
{
char str[] ="Esta es una cadena simple";
char * pch;
pch = strstr( str, "simple" );
strncpy( pch, "propia", 6 );
cout<<str;
return 0;
}

strtok()

Divide una cadena en segmentos (o tokens).

EEST N° 5 Amancio Willians 71


Prof. Abdala Achaval Pablo
Una secuencia de llamadas a esta función divide "cad" en tokens, que son secuencias de caracteres contíguos
separados por cualquiera de los caracteres contenidos en la cadena "delimitantes".

En la primera llamada, la función espera un cstring como argumento para "cad", cuyo primer caracter es
utilizado como el punto de partida para buscar tokens. En las llamadas siguientes, la función espera un puntero
NULL y utiliza la posición inmediatamente siguiente al fina del último token como nuevo punto de partida para
realizar la búsqueda.

Para determinar el principio y el fin de un token, la función primero busca desde la posición inicial la ubicación
del primer caracter en "cad" que no está contenido en la cadena "delimitantes" (que se convierte en el principio
del token). Y entonces busca, partiendo desde ese principio del token, al primer caracter en "cad" contenido en
"delimitantes", que se convierte en el final del token. La búsqueda también se detiene si se llega al caracter de fin
de cadena.

Este final del token es automáticamente reemplazado por el caracter de fin de cadena, y el principio del token es
retornado como puntero por la función.

Una vez que el caracter de fin de cadena en "cad" es encontrado por strtok(), todas las subsecuentes llamadas a
esta función (con un puntero NULL como primer argumento) retornarán un puntero NULL.

El punto donde el último token fue encontrado se mantiene guardado internamente por la función para ser
usado en la siguiente llamada.

Valor de retorno: Un puntero al último token encontrado en "cad".

Un puntero NULL si no hay más tokens por retirar.

// Ejemplo de uso en C++


#include <iostream>
#include <cstring>
using namespace std;

int main ()
{
char cad[] ="- Esta, una cadena de prueba.";
char * pch;
cout<<"Partiendo la cadena \""<<cad<<"\" en tokens:\n\n";
pch = strtok( cad, " ,.-" );
while( pch != NULL )
{
cout<< pch <<endl;
pch = strtok( NULL, " ,.-" );
}
return 0;
}

EEST N° 5 Amancio Willians 72


Prof. Abdala Achaval Pablo
OTROS:

strerror()
Retorna una cadena que describe un error producido en el programa (pura magia).

Devuelve un puntero a una cadena que contiene un mensaje sobre un error producido.
La función interpreta el valor de errnum, generando una cadena con un mensaje que describe la condición del
error como fue descrita en errno por una función de la librería.

El puntero retornado apunta a una cadena estática, que no deberá ser modificada por el programa.
Subsecuentes llamadas a esta función pueden sobrescribir su contenido.

La cadena producida por strerror() puede ser específica para cada sistema e implementaciones de la librería.

Valor de retorno: Un puntero a una cadena que describe el error cuyo código representa errnum.

Ejemplos de uso

// Ejemplo de uso en C++


#include <iostream>
#include <cstring>
#include <fstream>
#include <cerrno>
using namespace std;

int main ()
{
ifstream flujo( "inexistente.ent" );
if ( !flujo.is_open() ) {
cout<<"Error al abrir el archivo unexist.ent: "<<strerror( errno );
}
return 0;
}

strlen()
Retorna el largo de una cadena.

Devuelve el largo de "cadena" (el tipo size_t es como un unsigned int). El largo de la cadena es determinado por
el caracter nulo o de fin de cadena (barra invertida cero): una cadena o cstring es tan largo como caracteres
haya antes del caracter de fin de cadena (sin incluirlo).
Esto no debe confundirse con el tamaño de la cadena como arreglo.

Por ejemplo:

char micadena[100] = "probando cadena";

EEST N° 5 Amancio Willians 73


Prof. Abdala Achaval Pablo
define un arreglo de char con un tamaño de 100 chars, pero la cadena con la cual micadena ha sido inicializada
tiene un tamaño de 15 caracteres. Por lo tanto, mientras que sizeof(micadena) devuelve 100, strlen(micadena)
retorna 15.

Valor de retorno: el largo de la cadena.

Ejemplos de uso:

// Ejemplo de uso en C++


#include <iostream>
#include <cstring>
using namespace std;

int main ()
{
char entrada[256];
cout<<"Introduzca una frase: ";

// El método getline() de cin sirve para leer cadenas con espacios.


// sus argumentos son: el arreglo de char donde almacenar la entrada y
// el tamaño de dicho arreglo (obtenido con sizeof).
cin.getline( entrada, sizeof( entrada ) );

cout<<"La frase ingresada tiene "<<strlen( entrada )<<" caracteres de largo.\n"


;
return 0;
}
Salida:

Introduzca una frase: Hola mundo!


La frase ingresada tiene 11 caracteres de largo.

Devuelve una cadena de Asteriscos (*) a partir de una frase ingresada

#include <iostream>
using namespace std;

char *asteriscos(char frase[256]) ;

int main()
{
char frase[]="hola mundo";

cout<<asteriscos(frase)<<endl;
cout<<"*"<<frase<<"*"<<endl;
cout<<asteriscos(frase)<<endl;

system("pause");
return 0;
}

char *asteriscos(char frase[256])


{ int i;

EEST N° 5 Amancio Willians 74


Prof. Abdala Achaval Pablo
char aux[256];
char ast[0]="*/0";
int l=strlen(frase)+2;
for ( i=0; i < l; i++)
{
aux[i]=ast[0];
}
aux[i]= '\0';
return (aux);
}

C++ String
operator+
// concatenating strings
#include <iostream>
#include <string>

main ()
{
std::string firstlevel ("com");
std::string secondlevel ("cplusplus");
std::string scheme ("http://");
std::string hostname;
std::string url;

hostname = "www." + secondlevel + '.' + firstlevel;


url = scheme + hostname;

std::cout << url << '\n';

return 0;
}

Output:
http://www.cplusplus.com

getline
// extract to string
#include <iostream>
#include <string>
using namespace std;
int main ()
{
string name;

cout << "Please, enter your full name: ";


getline (std::cin,name);
cout << "Hello, " << name << "!\n";

return 0;
}

Append // agregar

// appending to string

EEST N° 5 Amancio Willians 75


Prof. Abdala Achaval Pablo
#include <iostream>
#include <string>
using namespace std;

int main ()
{
string str;
string str2="Writing ";
string str3="print 10 and then 5 more";

// used in the same order as described above:


str.append(str2); // "Writing "
str.append(str3,6,3); // "10 "
str.append("dots are cool",5); // "dots "
str.append("here: "); // "here: "
str.append(10u,'.'); // ".........."
str.append(str3.begin()+8,str3.end()); // " and then 5 more"
str.append<int>(5,0x2E); // "....."

cout << str << '\n';


return 0;
}

Assign // asignar
// string::assign
#include <iostream>
#include <string>

int main ()
{
std::string str;
std::string base="The quick brown fox jumps over a lazy dog.";

// used in the same order as described above:

str.assign(base);
std::cout << str << '\n';

str.assign(base,10,9);
std::cout << str << '\n'; // "brown fox"

str.assign("pangrams are cool",7);


std::cout << str << '\n'; // "pangram"

str.assign("c-string");
std::cout << str << '\n'; // "c-string"

str.assign(10,'*');
std::cout << str << '\n'; // "**********"

str.assign<int>(10,0x2D);
std::cout << str << '\n'; // "----------"

str.assign(base.begin()+16,base.end()-12);
std::cout << str << '\n'; // "fox jumps over"

return 0;
}

EEST N° 5 Amancio Willians 76


Prof. Abdala Achaval Pablo
at
// string::at
#include <iostream>
#include <string>

int main ()
{
std::string str ("Test string");
for (unsigned i=0; i<str.length(); ++i)
{
std::cout << str.at(i);
}
return 0;
}

Back//final c++11
// string::back
#include <iostream>
#include <string>

int main ()
{
std::string str ("hello world.");
str.back() = '!';
std::cout << str << '\n';
return 0;
}

Begin
// string::begin/end
#include <iostream>
#include <string>

int main ()
{
std::string str ("Test string");
for ( std::string::iterator it=str.begin(); it!=str.end(); ++it)
std::cout << *it;
std::cout << '\n';

return 0;
}

Output:
Test string

Capacity / length / size / max_size


// comparing size, length, capacity and max_size
#include <iostream>
#include <string>

int main ()
{
std::string str ("Test string");
std::cout << "size: " << str.size() << "\n";
std::cout << "length: " << str.length() << "\n";
std::cout << "capacity: " << str.capacity() << "\n";
std::cout << "max_size: " << str.max_size() << "\n";
return 0;
}

EEST N° 5 Amancio Willians 77


Prof. Abdala Achaval Pablo
A possible output for this program could be:
size: 11
length: 11
capacity: 15
max_size: 429496729

compare
// comparing apples with apples
#include <iostream>
#include <string>

int main ()
{
std::string str1 ("green apple");
std::string str2 ("red apple");

if (str1.compare(str2) != 0)
std::cout << str1 << " is not " << str2 << '\n';

if (str1.compare(6,5,"apple") == 0)
std::cout << "still, " << str1 << " is an apple\n";

if (str2.compare(str2.size()-5,5,"apple") == 0)
std::cout << "and " << str2 << " is also an apple\n";

if (str1.compare(6,5,str2,4,5) == 0)
std::cout << "therefore, both are apples\n";

return 0;
}

Output:
green apple is not red apple
still, green apple is an apple
and red apple is also an apple
therefore, both are apples

copy
// string::copy
#include <iostream>
#include <string>

int main ()
{
char buffer[20];
std::string str ("Test string...");
std::size_t length = str.copy(buffer,6,5);
buffer[length]='\0';
std::cout << "buffer contains: " << buffer << '\n';
return 0;
}

Output:
buffer contains: string

EEST N° 5 Amancio Willians 78


Prof. Abdala Achaval Pablo
c_str
// strings and c-strings
#include <iostream>
#include <cstring>
#include <string>

int main ()
{
std::string str ("Please split this sentence into tokens");

char * cstr = new char [str.length()+1];


std::strcpy (cstr, str.c_str());

// cstr now contains a c-string copy of str

char * p = std::strtok (cstr," ");


while (p!=0)
{
std::cout << p << '\n';
p = std::strtok(NULL," ");
}

delete[] cstr;
return 0;
}

Output:
Please
split
this
sentence
into
tokens

data
// string::data
#include <iostream>
#include <string>
#include <cstring>

int main ()
{
int length;

std::string str = "Test string";


char* cstr = "Test string";

if ( str.length() == std::strlen(cstr) )
{
std::cout << "str and cstr have the same length.\n";

if ( memcmp (cstr, str.data(), str.length() ) == 0 )


std::cout << "str and cstr have the same content.\n";
}
return 0;
}

Output:
str and cstr have the same length.

EEST N° 5 Amancio Willians 79


Prof. Abdala Achaval Pablo
str and cstr have the same content.

empty
// string::empty
#include <iostream>
#include <string>

int main ()
{
std::string content;
std::string line;
std::cout << "Please introduce a text. Enter an empty line to finish:\n";
do {
getline(std::cin,line);
content += line + '\n';
} while (!line.empty());
std::cout << "The text you introduced was:\n" << content;
return 0;
}

erase
// string::erase
#include <iostream>
#include <string>

int main ()
{
std::string str ("This is an example sentence.");
std::cout << str << '\n';
// "This is an example sentence."
str.erase (10,8); // ^^^^^^^^
std::cout << str << '\n';
// "This is an sentence."
str.erase (str.begin()+9); // ^
std::cout << str << '\n';
// "This is a sentence."
str.erase (str.begin()+5, str.end()-9); // ^^^^^
std::cout << str << '\n';
// "This sentence."
return 0;
}

Output:
This is an example sentence.
This is an sentence.
This is a sentence.
This sentence.

find
// string::find
#include <iostream> // std::cout
#include <string> // std::string

int main ()
{
std::string str ("There are two needles in this haystack with needles.");
std::string str2 ("needle");

// different member versions of find in the same order as above:


std::size_t found = str.find(str2);
if (found!=std::string::npos)

EEST N° 5 Amancio Willians 80


Prof. Abdala Achaval Pablo
std::cout << "first 'needle' found at: " << found << '\n';

found=str.find("needles are small",found+1,6);


if (found!=std::string::npos)
std::cout << "second 'needle' found at: " << found << '\n';

found=str.find("haystack");
if (found!=std::string::npos)
std::cout << "'haystack' also found at: " << found << '\n';

found=str.find('.');
if (found!=std::string::npos)
std::cout << "Period found at: " << found << '\n';

// let's replace the first needle:


str.replace(str.find(str2),str2.length(),"preposition");
std::cout << str << '\n';

return 0;
}

Notice how parameter pos is used to search for a second instance of the same search string. Output:
first 'needle' found at: 14
second 'needle' found at: 44
'haystack' also found at: 30
Period found at: 51
There are two prepositions in this haystack with needles.

find_first_not_of
// string::find_first_not_of
#include <iostream> // std::cout
#include <string> // std::string
#include <cstddef> // std::size_t

int main ()
{
std::string str ("look for non-alphabetic characters...");

std::size_t found = str.find_first_not_of("abcdefghijklmnopqrstuvwxyz ");

if (found!=std::string::npos)
{
std::cout << "The first non-alphabetic character is " << str[found];
std::cout << " at position " << found << '\n';
}

return 0;
}

The first non-alphabetic character is - at position 12

find_first_of
// string::find_first_of
#include <iostream> // std::cout
#include <string> // std::string
#include <cstddef> // std::size_t

int main ()
{

EEST N° 5 Amancio Willians 81


Prof. Abdala Achaval Pablo
std::string str ("Please, replace the vowels in this sentence by asterisks.");
std::size_t found = str.find_first_of("aeiou");
while (found!=std::string::npos)
{
str[found]='*';
found=str.find_first_of("aeiou",found+1);
}

std::cout << str << '\n';

return 0;
}

Pl**s*, r*pl*c* th* v*w*ls *n th*s s*nt*nc* by *st*r*sks.

find_last_not_of
// string::find_last_not_of
#include <iostream> // std::cout
#include <string> // std::string
#include <cstddef> // std::size_t

int main ()
{
std::string str ("Please, erase trailing white-spaces \n");
std::string whitespaces (" \t\f\v\n\r");

std::size_t found = str.find_last_not_of(whitespaces);


if (found!=std::string::npos)
str.erase(found+1);
else
str.clear(); // str is all whitespace

std::cout << '[' << str << "]\n";

return 0;
}

find_last_of
// string::find_last_of
#include <iostream> // std::cout
#include <string> // std::string
#include <cstddef> // std::size_t

void SplitFilename (const std::string& str)


{
std::cout << "Splitting: " << str << '\n';
std::size_t found = str.find_last_of("/\\");
std::cout << " path: " << str.substr(0,found) << '\n';
std::cout << " file: " << str.substr(found+1) << '\n';
}

int main ()
{
std::string str1 ("/usr/bin/man");
std::string str2 ("c:\\windows\\winhelp.exe");

SplitFilename (str1);

EEST N° 5 Amancio Willians 82


Prof. Abdala Achaval Pablo
SplitFilename (str2);

return 0;
}

Splitting: /usr/bin/man
path: /usr/bin
file: man
Splitting: c:\windows\winhelp.exe
path: c:\windows
file: winhelp.exe

front
// string::front
#include <iostream>
#include <string>

int main ()
{
std::string str ("test string");
str.front() = 'T';
std::cout << str << '\n';
return 0;
}

Output:
Test string

insert
// inserting into a string
#include <iostream>
#include <string>

int main ()
{
std::string str="to be question";
std::string str2="the ";
std::string str3="or not to be";
std::string::iterator it;

// used in the same order as described above:


str.insert(6,str2); // to be (the )question
str.insert(6,str3,3,4); // to be (not )the
question
str.insert(10,"that is cool",8); // to be not (that is )the
question
str.insert(10,"to be "); // to be not (to be )that
is the question
str.insert(15,1,':'); // to be not to be(:) that
is the question
it = str.insert(str.begin()+5,','); // to be(,) not to be:
that is the question
str.insert (str.end(),3,'.'); // to be, not to be: that
is the question(...)
str.insert (it+2,str3.begin(),str3.begin()+3); // (or )

std::cout << str << '\n';


return 0;

EEST N° 5 Amancio Willians 83


Prof. Abdala Achaval Pablo
}

Output:
to be, or not to be: that is the question...

length
// string::length
#include <iostream>
#include <string>

int main ()
{
std::string str ("Test string");
std::cout << "The size of str is " << str.length() << " bytes.\n";
return 0;
}

Output:
The size of str is 11 bytes

operator+=
// string::operator+=
#include <iostream>
#include <string>

int main ()
{
std::string name ("John");
std::string family ("Smith");
name += " K. "; // c-string
name += family; // string
name += '\n'; // character

std::cout << name;


return 0;
}

Output:
John K. Smith

operator=
// string assigning
#include <iostream>
#include <string>

int main ()
{
std::string str1, str2, str3;
str1 = "Test string: "; // c-string
str2 = 'x'; // single character
str3 = str1 + str2; // string

std::cout << str3 << '\n';


return 0;
}

EEST N° 5 Amancio Willians 84


Prof. Abdala Achaval Pablo
Output:
Test string: x

operator[]
// string::operator[]
#include <iostream>
#include <string>

int main ()
{
std::string str ("Test string");
for (int i=0; i<str.length(); ++i)
{
std::cout << str[i];
}
return 0;
}

pop_back
// string::pop_back
#include <iostream>
#include <string>

int main ()
{
std::string str ("hello world!");
str.pop_back();
std::cout << str << '\n';
return 0;
}

hello world

push_back
// string::push_back
#include <iostream>
#include <fstream>
#include <string>

int main ()
{
std::string str;
std::ifstream file ("test.txt",std::ios::in);
if (file) {
while (!file.eof()) str.push_back(file.get());
}
std::cout << str << '\n';
return 0;
}

replace
// replacing in a string

EEST N° 5 Amancio Willians 85


Prof. Abdala Achaval Pablo
#include <iostream>
#include <string>

int main ()
{
std::string base="this is a test string.";
std::string str2="n example";
std::string str3="sample phrase";
std::string str4="useful.";

// replace signatures used in the same order as described above:

// Using positions: 0123456789*123456789*12345


std::string str=base; // "this is a test string."
str.replace(9,5,str2); // "this is an example string." (1)
str.replace(19,6,str3,7,6); // "this is an example phrase." (2)
str.replace(8,10,"just a"); // "this is just a phrase." (3)
str.replace(8,6,"a shorty",7); // "this is a short phrase." (4)
str.replace(22,1,3,'!'); // "this is a short phrase!!!" (5)

// Using iterators:
0123456789*123456789*
str.replace(str.begin(),str.end()-3,str3); // "sample
phrase!!!" (1)
str.replace(str.begin(),str.begin()+6,"replace"); // "replace
phrase!!!" (3)
str.replace(str.begin()+8,str.begin()+14,"is coolness",7); // "replace is
cool!!!" (4)
str.replace(str.begin()+12,str.end()-4,4,'o'); // "replace is
cooool!!!" (5)
str.replace(str.begin()+11,str.end(),str4.begin(),str4.end());// "replace is
useful." (6)
std::cout << str << '\n';
return 0;
}

Output:
replace is useful.

reserve
// string::reserve
#include <iostream>
#include <fstream>
#include <string>

int main ()
{
std::string str;

std::ifstream file ("test.txt",std::ios::in|std::ios::ate);


if (file) {
std::ifstream::streampos filesize = file.tellg();
str.reserve(filesize);

file.seekg(0);
while (!file.eof())
{
str += file.get();

EEST N° 5 Amancio Willians 86


Prof. Abdala Achaval Pablo
}
std::cout << str;
}
return 0;
}

resize
// resizing string
#include <iostream>
#include <string>

int main ()
{
std::string str ("I like to code in C");
std::cout << str << '\n';

unsigned sz = str.size();

str.resize (sz+2,'+');
std::cout << str << '\n';

str.resize (14);
std::cout << str << '\n';
return 0;
}

Output:
I like to code in C
I like to code in C++
I like to code

substr

// string::substr
#include <iostream>
#include <string>

int main ()
{
std::string str="We think in generalities, but we live in details.";
// (quoting Alfred N. Whitehead)

std::string str2 = str.substr (3,5); // "think"

std::size_t pos = str.find("live"); // position of "live" in str

std::string str3 = str.substr (pos); // get from "live" to the end

std::cout << str2 << ' ' << str3 << '\n';

return 0;
}

swap
// swap strings

EEST N° 5 Amancio Willians 87


Prof. Abdala Achaval Pablo
#include <iostream>
#include <string>

main ()
{
std::string buyer ("money");
std::string seller ("goods");

std::cout << "Before the swap, buyer has " << buyer;
std::cout << " and seller has " << seller << '\n';

seller.swap (buyer);

std::cout << " After the swap, buyer has " << buyer;
std::cout << " and seller has " << seller << '\n';

return 0;
}

Output:
Before the swap, buyer has money and seller has goods
After the swap, buyer has goods and seller has money

Librería math.h

Librería math.h es un archivo de cabecera de la biblioteca estándar . Muchas de sus funciones incluyen el uso
de números en coma flotante.

Nombre Descripción
acos arcocoseno

/* acos example */
#include <stdio.h> /* printf */
#include <math.h> /* acos */

#define PI 3.14159265

int main ()
{
double param, result;
param = 0.5;
result = acos (param) * 180.0 / PI;
printf ("The arc cosine of %f is %f degrees.\n", param,
result);
return 0;
}

asin arcoseno
atan arcotangente
atan2 arcotangente de dos parámetros
/* atan2 example */
#include <stdio.h> /* printf */

EEST N° 5 Amancio Willians 88


Prof. Abdala Achaval Pablo
#include <math.h> /* atan2 */

#define PI 3.14159265

int main ()
{
double x, y, result;
x = -10.0;
y = 10.0;
result = atan2 (y,x) * 180 / PI;
printf ("The arc tangent for (x=%f, y=%f) is %f degrees\n",
x, y, result );
return 0;
}

cos coseno
abs valor absoluto
fmod resto del punto flotante
printf ( "fmod of 5.3 / 2 is %f\n", fmod (5.3,2) );
printf ( "fmod of 18.5 / 4.2 is %f\n", fmod (18.5,4.2) );

Salidas:

fmod of 5.3 / 2 is 1.300000


fmod of 18.5 / 4.2 is 1.700000
pow(x,y) eleva un valor dado a un exponente, xy
sin seno
Sqr Cuadrado de un número
int main ()
{
double param, result;
param = 1024.0;
result = sqrt (param);
printf ("sqrt(%lf) = %lf\n", param, result );
return 0;
}
sqrt raíz cuadrada

/* sqrt example */
#include <stdio.h> /* printf */
#include <math.h> /* sqrt */

int main ()
{
double param, result;
param = 1024.0;
result = sqrt (param);
printf ("sqrt(%f) = %f\n", param, result );
return 0;
}

Salida
sqrt(1024.000000) = 32.000000

tan tangente

EEST N° 5 Amancio Willians 89


Prof. Abdala Achaval Pablo
Punteros
Introducción

El puntero es una técnica muy potente que hace que la programación C++ sea tan utilizada. La técnica
de punteros apoya a la programación orientada a objetos, que es una de las grandes diferencias entre
C y C++.

Definición: Un puntero es una variable que almacena una dirección de memoria.

Operador de Dirección: &

Referencias

EEST N° 5 Amancio Willians 90


Prof. Abdala Achaval Pablo
EEST N° 5 Amancio Willians 91
Prof. Abdala Achaval Pablo
EEST N° 5 Amancio Willians 92
Prof. Abdala Achaval Pablo
EEST N° 5 Amancio Willians 93
Prof. Abdala Achaval Pablo
EEST N° 5 Amancio Willians 94
Prof. Abdala Achaval Pablo
EEST N° 5 Amancio Willians 95
Prof. Abdala Achaval Pablo
EEST N° 5 Amancio Willians 96
Prof. Abdala Achaval Pablo
EEST N° 5 Amancio Willians 97
Prof. Abdala Achaval Pablo
EEST N° 5 Amancio Willians 98
Prof. Abdala Achaval Pablo
EEST N° 5 Amancio Willians 99
Prof. Abdala Achaval Pablo
EEST N° 5 Amancio Willians 100
Prof. Abdala Achaval Pablo
EEST N° 5 Amancio Willians 101
Prof. Abdala Achaval Pablo
EEST N° 5 Amancio Willians 102
Prof. Abdala Achaval Pablo
EEST N° 5 Amancio Willians 103
Prof. Abdala Achaval Pablo
Clases

Una clase es la descripción de un tipo de objeto. La descripción abarca la definición de los distintos
atributos y métodos inherentes al objeto.

Sintaxis:

class tipo_objeto
{
public:
tipo_dato metodo1 (parámetros);
:
tipo_dato metodoN (parámetros);
private:
tipo_dato atributo1;
:
tipo_dato atributoN;
};

tipo_dato tipo_objeto::metodo1 (parámetros)


{
instrucciones;
}
:

EEST N° 5 Amancio Willians 104


Prof. Abdala Achaval Pablo
tipo_dato tipo_objeto::metodoN (parámetros)
{
instrucciones;
}

En algunos casos se puede pensar en la declaración de atributos en la parte publica y asi mismo el declarar
métodos en la parte privada.
La parte pública de la clase implica que los elementos definidos en este bloque solo se pueden manipular en
cualquier lugar del programa a través de un identificador de acceso (variable o arreglo). La parte privada de la
clase implica que los elementos definidos en este bloque solo se pueden manipular solo por métodos definidos
en la parte pública.

Constructores.

Cuando se crean objetos, una de las operaciones más comunes que se realizan sus programas es inicializar los
datos miembros del objeto. Para simplificar el proceso de inicialización de los datos miembros de la clase, el
C++ proporciona una función constructora que se ejecuta por si sola cada vez que se crea un objeto. A
continuación se presentan las siguientes características de los constructores:
 Las funciones constructoras son métodos de la clase que facilitan a los programas la inicialización de los
datos miembros de la clase.

 Las funciones constructoras tienen el mismo nombre que la clase.

 Las funciones constructoras no retornan valores.

 Cada vez que el programa crea un objeto de la clase, C++ llama a la función constructora de la clase, si
existe.

 Pueden existir varias funciones constructoras, pero con diferentes parámetros, esto se conoce como
sobrecarga.

Destructores.
Una función destructora automáticamente se ejecuta cada vez que se finalice la ejecución de un programa.
Muchos de los objetos pueden asignar memoria para almacenar información, cuando se descarta a un objeto, el
C++ llama a una función destructora especial que puede liberar dicha memoria, limpiando la basura dejada por
la desaparición del objeto. A continuación se presentan las siguientes características de los constructores:

 Las funciones destructoras tienen el mismo nombre que la clase, con la excepción de que debe
anteponer a su nombre el carácter tilde (~).

 Las funciones destructoras no retornan valores.

Funciones Amigas

Una función amiga de una clase se define por fuera del alcance directo de los miembros privados de dicha
clase, pero aún así tiene el derecho de acceso a los miembros private de la clase. Se puede declarar una función
o toda una clase como friend de otra clase. Para declarar una función como friend en una clase, en la definición
de clase procede el prototipo de la función con la palabra reservada friend.

EEST N° 5 Amancio Willians 105


Prof. Abdala Achaval Pablo
Sintaxis:

class tipo_objeto
{
friend tipo_dato funcionamiga (tipo_objeto *, parámetros);
public:
:
private:
:
};
tipo_dato funcionamiga (tipo_objeto *, parámetros)
{
instrucciones;
}

Ejercicios Resueltos

//Programa 1: Procesar información de un empleado por medio de una clase.


#include <iostream.h>
#include <conio.h>

class empleado
{
public:
void leer_empleado(void);
void mostrar_empleado(void);
char nombre[15];
long numero_empleado;
float salario;
};

void empleado::leer_empleado(void)
{
cout<< "Nombre:";
cin >> nombre;
cout<< "Número:";
cin >> numero_empleado;
cout<< "Salario: Bs.";
cin >> salario;
}

void empleado::mostrar_empleado(void)
{
cout << "Nombre: " << nombre << endl;
cout << "Número: " << numero_empleado << endl;
cout << "Salario: Bs." << salario << endl;
}

void main()
{
empleado trabajador;
clrscr();
trabajador.leer_empleado();
cout<<"\nResultado después de la lectura...\n";
trabajador.mostrar_empleado();

EEST N° 5 Amancio Willians 106


Prof. Abdala Achaval Pablo
cout<<"\nPresione una Tecla para Continuar";
getch();
}

//Programa 2: Procesar información de cinco empleados por medio de una clase.

#include <iostream.h>
#include <conio.h>

class empleado
{

public:
void leer_empleado(void);
void mostrar_empleado(void);
private:
char nombre[15];
long numero_empleado;
float salario;
};

void empleado::leer_empleado(void)
{
cout<< "Nombre:";
cin >> nombre;
cout<< "Número:";
cin >> numero_empleado;
cout<< "Salario: Bs.";
cin >> salario;
}

void empleado::mostrar_empleado(void)
{
cout<<"\t"<<nombre<<"\t"<<numero_empleado<<"\t"<<salario<< endl;
}

void main()
{
empleado trabajador[5];
clrscr();
for (int i=0; i<5; i++)
{
cout<<"Empleado "<<i+1<<endl;
trabajador[i].leer_empleado();
}
clrscr();
cout<<"\n\tListado de Empleados\n";
cout<<"\tNombre\tNumero\tSalario Bs.\n\n";
for (int i=0; i<5; i++)
trabajador[i].mostrar_empleado();
cout<<"\nPresione una Tecla para Continuar";
getch();
}

//Programa 3: Efectuar la asignación y lectura de datos fuera de la clase.

#include <iostream.h>
#include <conio.h>

class perros
{
public:

EEST N° 5 Amancio Willians 107


Prof. Abdala Achaval Pablo
char raza[15];
int peso_promedio;
int altura_promedio;
void mostrar_raza(void);
};

void perros::mostrar_raza(void)
{
cout << "Raza: " << raza << endl;
cout << "Peso promedio: " << peso_promedio << endl;
cout << "Altura promedio: " << altura_promedio << endl;
}

void main()
{
perros canito, canuto;

strcpy(canito.raza,"Doberman");
canito.peso_promedio = 58;
canito.altura_promedio = 25;

cout<<"Ingrese los Datos Referentes a Canuto...\n";


cout<<"Raza:";
cin>>canuto.raza;
cout<<"Peso Promedio:";
cin>>canuto.peso_promedio;
cout<<"Altura Promedio:";
cin>>canuto.altura_promedio;

clrscr();
cout<<"\nResultados después de la lectura...\n\n";
cout<<"Los datos de Canito son:\n";
canito.mostrar_raza();
cout<<"\nLos datos de Canuto son:\n";
canuto.mostrar_raza();
cout<<"\nPresione una Tecla para Continuar";
getch();
}

//Programa 4: Efectuar la lectura y validacion de los miembros de la parte privada


de la clase.

#include <iostream.h>
#include <conio.h>

class empleado
{
public:
int asignar_valores(char *, long, float);
void mostrar_empleado(void);
void cambiar_salario(void);
private:
char nombre[15];
long numero;
float salario;
};

int empleado::asignar_valores(char *t_nom, long t_num, float t_sal)


{
strcpy(nombre,t_nom);
numero = t_num;
if (t_sal > 198000.0 && t_sal < 600000.0)
{

EEST N° 5 Amancio Willians 108


Prof. Abdala Achaval Pablo
salario = t_sal;
return(0); // salario incorrecto
}
else return(-1); // salario equivocado
}

void empleado::mostrar_empleado(void)
{
cout << "Empleado: " << nombre << endl;
cout << "Número: " << numero << endl;
cout << "Salario: Bs." << salario << endl;
}

void empleado::cambiar_salario (void)


{
do
{
cin>>salario;
if (salario < 198000.0 || salario > 600000.0)
cout<<"\nSalario Incorrecto...\nDar un nuevo salario:";
}
while(salario < 198000.0 || salario > 600000.0);
}

void main()
{
empleado trabajador;

if (trabajador.asignar_valores("Ana Pérez", 101, 850000.0)== 0)


{
cout << "Valores asignados al empleado." << endl;
trabajador.mostrar_empleado();
}
else
{
cout << "Especifico un salario no válido." << endl;
cout << "\nAsigne un nuevo salario:";
trabajador.cambiar_salario();
}

cout<<"\nPresione una Tecla para Continuar";


getch();
}

//Programa 5: Efectuar la invocación y lectura de los miembros de la clase, luego


//de efectuar la lectura de una clave de seguridad.

#include <iostream.h>
#include <string.h>
#include <conio.h>
#define ENTER 13

class empleado
{
public:
void leer_clave(void);
void validar_clave(char *);
private:
void asignar_valores(void);
void mostrar_empleado(void);
char clave[6];
char nombre[15];
float salario;

EEST N° 5 Amancio Willians 109


Prof. Abdala Achaval Pablo
};

void empleado::leer_clave(void)
{
int j=0;
char t_clave[6];
do
{
t_clave[j]=getch();
if (t_clave[j]!=ENTER) cout<<"*";
j++;
}
while (t_clave[j-1]!=ENTER);
t_clave[j-1]='\0';
validar_clave(t_clave);
}

void empleado::validar_clave(char *c)


{
static int i=1;
strcpy(clave,"josef");
if (strcmp(c,clave)!=0)
{
cout<<"\nClave Incorrecta";
if (i==1)
{
cout<<"\nDar de nuevo la clave:";
i=2;
leer_clave();
}
else
{
cout<<"\nHasta Luego...Usuario no Autorizado";
}
}
else
{
cout<<"\nClave Correcta";
asignar_valores();
clrscr();
mostrar_empleado();
}
}

void empleado::asignar_valores(void)
{
cout<< "\nNombre:";
cin >> nombre;
cout<< "Salario: Bs.";
cin >> salario;
}

void empleado::mostrar_empleado(void)
{
cout << "\nEmpleado: " << nombre << endl;
cout << "Salario: Bs." << salario << endl;
}

void main()
{
empleado acceso;

cout<<"Introduzca clave de acceso (5 caracteres):";


acceso.leer_clave();

EEST N° 5 Amancio Willians 110


Prof. Abdala Achaval Pablo
cout<<"\nPresione una Tecla para Continuar";
getch();
}

//Programa 6: Implementación de una función constructora sin parámetros.

#include <iostream.h>
#include <conio.h>

// Construccion de la clase tiempo


class tiempo
{
public:
tiempo();
void activar_tiempo (int, int, int );
void imprimir_formato_militar ();
void imprimir_formato_estandar ();
private:
int hora; // 0-23
int minuto; // 0-59
int segundo; // 0-59
};

// La funcion tiempo inicializa a 0 los miembros de datos de la clase


tiempo::tiempo ()
{
hora=minuto=segundo=0;
}

// Activa un nuevo tiempo usando el formato militar. Chequea los datos


// introducidos, si los datos son invalidos iniciliza los valores de
// los miembros de datos en cero.
void tiempo::activar_tiempo (int h, int m, int s)
{
hora = (h >= 0 && h < 24) ? h : 0;
minuto = (m >=0 && m < 60) ? m : 0;
segundo = (s >=0 && s < 60) ? s : 0;
}

// Funcion para imprimir el tiempo en formato militar


void tiempo::imprimir_formato_militar ()
{
cout<< (hora < 10 ? "0" : "") << hora << ":"
<< (minuto < 10 ? "0" : "") << minuto << ":"
<< (segundo < 10 ? "0" : "") << segundo;
}

// Funcion para imprimir el tiempo en formato estandar


void tiempo::imprimir_formato_estandar ()
{
cout << (hora==0 || hora==12 ? 12 : hora%12) << ":"
<< (minuto < 10 ? "0" : "") << minuto << ":"
<< (segundo < 10 ? "0" : "") << segundo
<< (hora < 12 ? " AM" : " PM");
}

void main()
{
clrscr();
tiempo t; // t es una variable objeto de tipo tiempo
cout << "El tiempo inicial en formato militar es -> ";
t.imprimir_formato_militar ();

EEST N° 5 Amancio Willians 111


Prof. Abdala Achaval Pablo
cout << "\nEl tiempo inicial en formato estandar es -> ";
t.imprimir_formato_estandar ();
t.activar_tiempo (13, 27, 6);
cout << "\n\nEl tiempo en formato militar despues de activar un tiempo es -> ";
t.imprimir_formato_militar ();
cout << "\nEl tiempo en formato estandar despues de activar un tiempo es -> ";
t.imprimir_formato_estandar ();
t.activar_tiempo (99, 99, 99);
cout << "\n\nEl tiempo con datos invalidos:"<< "\nEn formato militar es -> ";
t.imprimir_formato_militar ();
cout << "\nEn formato estandar es -> ";
t.imprimir_formato_estandar ();
getch();
}

//Programa 7: Implementación de una función constructora sin parámetros.


//Inicialización de un vector numérico a través del constructor.

#include <iostream.h>
#include <conio.h>

class entero
{
public:
entero()
{
x=2;
};
void mostrar_valor(void);
private:
int x;
};

void entero::mostrar_valor(void)
{
cout<<x;
}

void main(void)
{
entero vec[10];
clrscr();
for (int i=0; i<10; i++)
{
cout<<"\nEl valor de vec["<<i<<"]:";
vec[i].mostrar_valor();
}
cout<<"\nPresione una Tecla para Continuar";
getch();
}

//Programa 8: Implementación de una función constructora con parámetros.

#include <iostream.h>
#include <string.h>
#include <conio.h>

class empleado
{
public:
empleado(char *, int, float);
void mostrar_empleado(void);
private:
char nombre[15];

EEST N° 5 Amancio Willians 112


Prof. Abdala Achaval Pablo
int numero;
float salario;
};

empleado::empleado(char *t_nom, int t_num, float t_sal)


{
strcpy(nombre, t_nom);
numero = t_num;
salario = (t_sal < 500000.0)? t_sal: 0.0;
}

void empleado::mostrar_empleado(void)
{
cout << "\nEmpleado: " << nombre << endl;
cout << "Número: " << numero << endl;
cout << "Salario: Bs." << salario << endl;
}

void main()
{
char nom[15];
float sal;
int num;
cout<< "Nombre:";
cin >> nom;
cout<< "Número:";
cin >> num;
cout<< "Salario: Bs.";
cin >> sal;
empleado trabajador(nom, num, sal);
cout<<"\n\nLos datos almacenados después de ejecutarse la función
constructora";
trabajador.mostrar_empleado();
cout<<"\nPresione una Tecla para Continuar";
getch();
}

//Programa 9: Sobrecarga de funciones constructoras.

#include <iostream.h>
#include <string.h>
#include <conio.h>

class empleado
{
public:
empleado(char *, long, float);
empleado(char *, long);
void mostrar_empleado(void);
int cambiar_salario(float);
long leer_numero(void);
private:
char nombre[25];
long numero_empleado;
float salario;
};

empleado::empleado(char *nombre, long numero_empleado,float salario)


{
strcpy(empleado::nombre, nombre);
empleado::numero_empleado = numero_empleado;
if (salario < 50000.0) empleado::salario = salario;
else empleado::salario = 0.0; // salario especificado no válido

EEST N° 5 Amancio Willians 113


Prof. Abdala Achaval Pablo
}

empleado::empleado(char *nombre, long numero_empleado)


{
strcpy(empleado::nombre, nombre);
empleado::numero_empleado = numero_empleado;
do
{
cout << "Digite un salario para " << nombre << " menor a Pesos. 500,000.00:
";
cin >> empleado::salario;
}
while(salario >= 500000.0);
}

void empleado::mostrar_empleado(void)
{
cout << "Empleado: " << nombre << endl;
cout << "Número: " << numero_empleado << endl;
cout << "Salario: Bs." << salario << endl;
}

void main()
{
empleado trabajador("Feliz Guerra", 101, 10101.0);
empleado gerente("Juana Pérez", 102);
trabajador.mostrar_empleado();
gerente.mostrar_empleado();
cout<<"\nPresione una Tecla para Continuar";
getch();
}

//Programa 10: Implementación de una función destructora.

#include <iostream.h>
#include <string.h>
#include <conio.h>

class empleado
{
public:
empleado(char *, int, float);
~empleado(void);
void mostrar_empleado(void);
private:
char nombre[15];
int numero;
float salario;
};

empleado::empleado(char *t_nom, int t_num, float t_sal)


{
strcpy(nombre, t_nom);
numero = t_num;
salario = (t_sal < 500000.0)? t_sal: 0.0;
}

empleado::~empleado(void)
{
cout<<"\n\nDestruyendo el objeto para "<< nombre<< endl;
getch();
}

void empleado::mostrar_empleado(void)

EEST N° 5 Amancio Willians 114


Prof. Abdala Achaval Pablo
{
cout << "\nEmpleado: " << nombre << endl;
cout << "Número: " << numero << endl;
cout << "Salario: Bs." << salario << endl;
}

void main()
{
char nom[15];
float sal;
int num;
cout<< "Nombre:";
cin >> nom;
cout<< "Número:";
cin >> num;
cout<< "Salario: Bs.";
cin >> sal;
empleado trabajador(nom, num, sal);
cout<<"\n\nLos datos almacenados después de ejecutarse la función constructora";
trabajador.mostrar_empleado();
cout<<"\nPresione una Tecla para Continuar";
getch();
}

//Programa 11: Implementación de una clase cadena para crear y manipular objetos
tipo cadenas de caracteres.

#include <iostream.h>
#include <string.h>
#include <conio.h>

class cadena
{
public:
cadena(char *); // Constructor
void sumar_cadena(char *);
void restar_caracter(char);
void mostrar_cadena(void);
private:
char datos[100];
};

cadena::cadena(char *letras)
{
strcpy(datos, letras);
}

void cadena::sumar_cadena(char *letras)


{
strcat(datos, letras);
}

void cadena::restar_caracter(char letra)


{
char temp[100];
int i, j;
for (i = 0, j = 0; datos[i]; i++)
{
if (datos[i] != letra) temp[j++] = datos[i];
}
temp[j] = NULL;
strcpy(datos, temp);
}

EEST N° 5 Amancio Willians 115


Prof. Abdala Achaval Pablo
void cadena::mostrar_cadena(void)
{
cout << datos << endl;
}

void main()
{
cadena titulo("Aprenda Programación Orientada a Objetos en C++");
cadena tema("Entienda la sobrecarga de operadores");

titulo.mostrar_cadena();
titulo.sumar_cadena(" paso a paso!");
titulo.mostrar_cadena();

tema.mostrar_cadena();
tema.restar_caracter('r');
tema.mostrar_cadena();
cout<<"\nPresione una Tecla para Continuar";
getch();
}

//Programa 12: Implementación de una funcion amiga.

#include <iostream.h>
#include <conio.h>

class numero
{
friend void asignar_valor(numero *,int );
public:
numero(){x=0;}
void imprimir(void);
private:
int x;
};

void asignar_valor (numero *c,int nx)


{
c->x=nx;
}

void numero::imprimir(void)
{
cout << x << endl;
}

void main()
{
int n;
numero m;
cout<<"El valor de la variable x antes de activar la función amiga: ";
m.imprimir();
cout<<"Dar un valor para x:";
cin>>n;
asignar_valor(&m,n);
cout<<"El valor de la variable x después de activar la función amiga: ";
m.imprimir();
cout<<"\nPresione una Tecla para Continuar";
getch();
}

EEST N° 5 Amancio Willians 116


Prof. Abdala Achaval Pablo
//Programa 13: Manipulación de una función amiga y variables por referencia.

#include <iostream.h>
#include <conio.h>

class entero
{
friend float suma_condicionada(entero *, int &);
public:
void cargar();
private:
float y;
};

void entero::cargar()
{
cin>>y;
}

float suma_condicionada(entero *num, int &c)


{
float x;
if (num->y>=100 && num->y<=200)
{
c++;
x=num->y;
}
else x=0;
return x;
}

void main()
{
entero vec[100];
float pro, acum=0;
char resp;
int i=-1,con=0;
do
{
i++;
cout<<"Dar valor "<<i+1<<":";
vec[i].cargar();
cout<<"Desea cargar otro valor (s/n):";
resp=getch();
resp=toupper(resp);
cout<<endl;
}
while (resp=='S'||i>=100);
for (int j=0; j<=i; j++)
{
acum+=(suma_condicionada(&vec[j],con));
}
pro=acum/con;
printf ("El promedio de los valores condicionados es de:%.2f",pro);
cout<<"\nPresione una Tecla para Continuar";
getch();
}

//Programa 14: Implementación de una función amiga dentro de una clase perteneciente a
otra clase.

#include <iostream.h>
#include <string.h>
#include <conio.h>

EEST N° 5 Amancio Willians 117


Prof. Abdala Achaval Pablo
class libro;

class biblioteca
{
public:
void cambiar_catalogo(libro *, char *);
};

class libro
{
public:
libro(char *, char *, char *);
void mostrar_libro(void);
friend void biblioteca::cambiar_catalogo(libro *,char *);
private:
char titulo[25];
char autor[25];
char catalogo[25];
};

void biblioteca::cambiar_catalogo(libro *este_libro, char *catalogo_nuevo)


{
strcpy(este_libro->catalogo, catalogo_nuevo);
}

libro::libro(char *t_titulo, char *t_autor, char *t_catalogo)


{
strcpy(titulo, t_titulo);
strcpy(autor, t_autor);
strcpy(catalogo, t_catalogo);
}

void libro::mostrar_libro(void)
{
cout << "Título: " << titulo << endl;
cout << "Autor: " << autor << endl;
cout << "Catálogo: " << catalogo << "\n\n";
}

void main()
{
libro programacion("Aprenda C++ paso a paso"," Ing. Informatica","
Principiantes");
programacion.mostrar_libro();
biblioteca bibliotecario;
bibliotecario.cambiar_catalogo(&programacion,"Como aprender en C++ funciones
amigas");
programacion.mostrar_libro();
cout<<"\nPresione una Tecla para Continuar";
getch();
}

Herencia

En un material previo se definio la herencia como la habilidad que tiene una clase derivada de heredar las
características de una clase base existente. En este material se indicará la manera de cómo programar una
herencia simple y múltiple, y una cadena de herencia respectivamente.

Herencia Simple

EEST N° 5 Amancio Willians 118


Prof. Abdala Achaval Pablo
Sintaxis:

class BASE
{
public:
BASE (tipo_dato1,...,tipo_datoN);
:
//Otros métodos
private:
tipo_dato atributo1;
:
tipo_dato atributoN;
};
class DERIVADA: public BASE
{
public:
DERIVADA (tipo_dato1,...,tipo_datoM);
:
//Otros métodos
private:
tipo_dato atributo[N+1];
:
tipo_dato atributoM;
};
DERIVADA::DERIVADA (tipo_dato param1,... ,tipo_dato paramM)
:BASE (param1,... ,paramN) //No incluye el tipo
de dato
{
//Asignación de los valores de los parámetros
//a los atributos de la clase derivada
}
//Cuerpo Principal
DERIVADA identificador (valor1,...,valorM);

Herencia Múltiple

EEST N° 5 Amancio Willians 119


Prof. Abdala Achaval Pablo
Sintaxis:
class BASE1
{
public:
BASE1 (tipo_dato1,...,tipo_datoN);
:
//Otros métodos
private:
tipo_dato atributo1;
:
tipo_dato atributoN;
};
class BASE2
{
public:
BASE2 (tipo_dato[N+1],...,tipo_datoM);
:
//Otros métodos
private:
tipo_dato atributo[N+1];
:
tipo_dato atributoM;
};
class DERIVADA: public BASE1, public BASE2
{
public:
DERIVADA (tipo_dato1,...,tipo_datoK);
:
//Otros métodos
private:
tipo_dato atributo[M+1];
:
tipo_dato atributoK;
};
DERIVADA::DERIVADA (tipo_dato param1,...,tipo_dato paramK)
:BASE1 (param1,... ,paramN), BASE2 (param[N+1],... ,paramM)
{
//Asignación de los valores de los parámetros
//a los atributos de la clase derivada
};
//Cuerpo Principal
DERIVADA identificador (valor1,...,valorK);

Ejercicios Resueltos
//Programa 1: Herencia simple entre la clase base EMPLEADO y la clase derivada
//GERENTE.

#include <iostream.h>
#include <string.h>
#include <conio.h>

class empleado
{
public:
empleado(char *, char *, float);
void mostrar_empleado(void);

EEST N° 5 Amancio Willians 120


Prof. Abdala Achaval Pablo
private:
char nombre[15], puesto[15];
float salario;
};

class gerente:public empleado


{
public:
gerente(char *, char *, char *, float, float, int);
void mostrar_gerente(void);
private:
float bono;
char automovil[15];
int acciones;
};

empleado::empleado(char *t_nom, char *t_pue, float t_sal)


{
strcpy(nombre, t_nom);
strcpy(puesto, t_pue);
salario = t_sal;
}

void empleado::mostrar_empleado(void)
{
cout << "\nNombre: " << nombre << endl;
cout << "Puesto: " << puesto << endl;
cout << "Salario: Bs." << salario << endl;
}

gerente::gerente(char *t_nom, char *t_pue, char *t_aut, float t_sal, float t_bono,
int t_acc):empleado(t_nom,t_pue,t_sal)
{
strcpy(automovil, t_aut);
bono = t_bono;
acciones = t_acc;
}

void gerente::mostrar_gerente(void)
{
mostrar_empleado();
cout << "Automóvil de la Empresa: " << automovil << endl;
cout << "Bonificacion Anual: Bs." << bono << endl;
cout << "Acciones de la Empresa: " << acciones << endl;
}

void main()
{
empleado trabajador("Juan Pérez","Programador",850000);
gerente jefe("Carmen Gómez","Vicepresidente","Corsa",2500000,30000,500);
trabajador.mostrar_empleado();
jefe.mostrar_gerente();
cout<<"\nPresione una Tecla para Continuar";
getch();
}

//Programa 2: Herencia simple entre la clase base LIBRO y la clase derivada


//FICHA_PRESTAMO.

#include <iostream.h>
#include <string.h>
#include <conio.h>

class libro

EEST N° 5 Amancio Willians 121


Prof. Abdala Achaval Pablo
{
public:
libro(char *, char *, int);
void mostrar_libro(void);
private:
char titulo[20], autor[20];
int paginas;
};

class ficha_prestamo : public libro


{
public:
ficha_prestamo(char *, char *, int, int, int);
void mostrar_ficha(void);
private:
int entrega; // Número de días del préstamo
int prestado; // 1 si ha sido prestado, de otra manera 0
};

libro::libro(char *t_tit, char *t_aut, int t_pag)


{
strcpy(titulo, t_tit);
strcpy(autor, t_aut);
paginas = t_pag;
}
void libro::mostrar_libro(void)
{
cout << "Título: " << titulo << endl;
cout << "Autor: " << autor << endl;
cout << "Páginas: " << paginas << endl;
}

ficha_prestamo::ficha_prestamo(char *t_tit, char *t_aut, int t_pag, int t_ent,


int t_pre):libro(t_tit, t_aut, t_pag)
{
entrega = t_ent;
prestado = t_pre;
}

void ficha_prestamo::mostrar_ficha(void)
{
mostrar_libro();
cout << "Numero de dias del Prestamo: " << entrega << endl;
if (prestado)
cout << "Estado: No disponible" << endl;
else
cout << "Estado: Disponible" << endl;
}

void main()
{
ficha_prestamo ficha("Herencia en C++","Carmen Cordero",272,3,0);
ficha.mostrar_ficha();
cout<<"\nPresione una Tecla para Continuar";
getch();
}

//Programa 3: Herencia simple entre la clase base EMPLEADO y la clase derivada


//GERENTE. Uso de la parte protegida en la clase base.

#include <iostream.h>
#include <string.h>
#include <conio.h>

EEST N° 5 Amancio Willians 122


Prof. Abdala Achaval Pablo
class empleado
{
public:
void mostrar_empleado(void);
protected:
char nombre[15], puesto[15];
float salario;
};

class gerente:public empleado


{
public:
gerente(char *, char *, char *, float, float, int);
void mostrar_gerente(void);
private:
float bono;
char automovil[15];
int acciones;
};

void empleado::mostrar_empleado(void)
{
cout << "Nombre: " << nombre << endl;
cout << "Puesto: " << puesto << endl;
cout << "Salario: Bs." << salario << endl;
}

gerente::gerente(char *t_nom, char *t_pue, char *t_aut, float t_sal, float


t_bono,int t_acc)
{
strcpy(nombre, t_nom);
strcpy(puesto, t_pue);
salario = t_sal;
strcpy(automovil, t_aut);
bono = t_bono;
acciones = t_acc;
}

void gerente::mostrar_gerente(void)
{
mostrar_empleado();
cout << "Automóvil de la Empresa: " << automovil << endl;
cout << "Bonificacion Anual: Bs." << bono << endl;
cout << "Acciones de la Empresa: " << acciones << endl;
}

void main()
{
gerente jefe("Carmen Gómez","Vicepresidente","Corsa",2500000,30000,500);
jefe.mostrar_gerente();
cout<<"\nPresione una Tecla para Continuar";
getch();
}

//Programa 4: Herencia simple entre la clase base LIBRO y la clase derivada


//FICHA_PRESTAMO. Uso de la parte protegida en la clase base.

#include <iostream.h>
#include <string.h>
#include <conio.h>

class libro
{
public:

EEST N° 5 Amancio Willians 123


Prof. Abdala Achaval Pablo
libro(char *, char *, int);
protected:
char titulo[20], autor[20];
int paginas;
};

class ficha_prestamo : public libro


{
public:
ficha_prestamo(char *, char *, int, int, int);
void mostrar_ficha(void);
private:
int entrega; // Número de días del préstamo
int prestado; // 1 si ha sido prestado, de otra manera 0
};

libro::libro(char *t_tit, char *t_aut, int t_pag)


{
strcpy(titulo, t_tit);
strcpy(autor, t_aut);
paginas = t_pag;
}

ficha_prestamo::ficha_prestamo(char *t_tit, char *t_aut, int t_pag, int t_ent,


int t_pre):libro(t_tit, t_aut, t_pag)
{
entrega = t_ent;
prestado = t_pre;
}

void ficha_prestamo::mostrar_ficha(void)
{
cout << "Título: " << titulo << endl;
cout << "Autor: " << autor << endl;
cout << "Páginas: " << paginas << endl;
cout << "Numero de dias del Prestamo: " << entrega << endl;
if (prestado)
cout << "Estado: No disponible" << endl;
else
cout << "Estado: Disponible" << endl;
}

void main()
{
ficha_prestamo ficha("Herencia en C++","Carmen Cordero",272,3,0);
ficha.mostrar_ficha();
cout<<"\nPresione una Tecla para Continuar";
getch();
}

//Programa 5: Herencia simple entre la clases base EMPLEADO y la clases derivadas


//ASALARIADO, POR_HORA y TEMPORAL.

#include <iostream.h>
#include <string.h>
#include <conio.h>

class empleado
{
public:
empleado (char *, char *, char *, char *);
void mostrar_empleado (void);
private:
char nombre [20];

EEST N° 5 Amancio Willians 124


Prof. Abdala Achaval Pablo
char telefono_casa [20];
char telefono_oficina [20];
char reporta_a [20];
};

class asalariado : public empleado


{
public:
asalariado (char *, char *, char *, char *, float, float, char *);
void mostrar_asalariado (void);
private:
float salario;
float nivel_de_primas;
char asistente [20];
};

class por_hora : public empleado


{
public:
por_hora (char *, char *, char *, char *,float);
void mostrar_por_hora (void);
private:
float sueldo;
};

class temporal : public empleado


{
public:
temporal (char *, char *, char *, char *, float);
void mostrar_temporal (void);
private:
float sueldo;
};

empleado::empleado (char *t_nom, char *t_casa, char *t_oficina, char *t_rep)


{
strcpy (nombre, t_nom);
strcpy (telefono_casa, t_casa);
strcpy (telefono_oficina, t_oficina);
strcpy (reporta_a, t_rep);
}

void empleado::mostrar_empleado (void)


{
cout << "Nombre: " << nombre << endl;
cout << "Teléfono de casa: " << telefono_casa <<endl;
cout << "Teléfono de oficina: " << telefono_oficina << endl;
cout << "Reporta a:" << reporta_a << endl;
}

asalariado::asalariado (char *t_nom, char *t_casa, char *t_oficina, char *t_rep,


float t_sal, float t_primas, char *t_asi) :
empleado (t_nom, t_casa, t_oficina, t_rep)
{
salario = t_sal;
nivel_de_primas = t_primas;
strcpy (asistente, t_asi);
}

void asalariado:: mostrar_asalariado (void)


{
mostrar_empleado ( ) ;
cout << "Salario: Bs." << salario << endl;
cout << "Nivel de primas: Bs." << nivel_de_primas << endl;

EEST N° 5 Amancio Willians 125


Prof. Abdala Achaval Pablo
cout << "Asistente: " << asistente << endl;
}

por_hora::por_hora (char *t_nom, char *t_casa, char *t_oficina, char *t_rep,


float t_sue) : empleado (t_nom, t_casa, t_oficina, t_rep)
{
sueldo = t_sue;
}

void por_hora::mostrar_por_hora (void)


{
mostrar_empleado ();
cout << "Sueldo: Bs." << sueldo << endl;
}

temporal::temporal (char *t_nom, char *t_casa, char *t_oficina, char *t_rep,


float t_sue) : empleado (t_nom, t_casa, t_oficina, t_rep)
{
sueldo = t_sue;
}

void temporal :: mostrar_temporal (void)


{
mostrar_empleado ( );
cout << "Sueldo: Bs." << sueldo << endl;
}

void main (void)


{
asalariado gerente ("Joel Pérez", "555-1111", "555-1112", "Marco López",
3000000, 10000.0, "Alicia Hernández");
por_hora plomero ("David García", "555-2222", "555-2223", "Marco Sánchez",
45000);
temporal recepcionista ("María Flores","555-3333","555-3334","Dora Galván",
40000);
gerente.mostrar_asalariado();
cout << endl << endl;
plomero.mostrar_por_hora();
cout << endl << endl;
recepcionista.mostrar_temporal();
cout<<"\nPresione una Tecla para Continuar";
getch();
}

//Programa 6: Herencia múltiple entre la clases base MONITOR y TARJETA y la clase


//derivada COMPUTADORA.

#include <iostream.h>
#include <string.h>
#include <conio.h>

class monitor
{
public:
monitor(char *, long, int, int);
void mostrar_pantalla(void);
private:
char tipo[32];
long colores;
int resolucion_x;
int resolucion_y;
};

class tarjeta

EEST N° 5 Amancio Willians 126


Prof. Abdala Achaval Pablo
{
public:
tarjeta(int, int);
void mostrar_tarjeta(void);
private:
int procesador;
int velocidad;
};
class computadora : public monitor, public tarjeta
{
public:
computadora(char *, int, float, char *, long, int, int,int, int);
void mostrar_computadora(void);
private:
char marca[25];
int disco_duro; //Capacidad de almacenamiento.
float disco_flexible; //Capacidad de almacenamiento.
};

monitor::monitor(char *t_tipo, long t_col,int x_res, int y_res)


{
strcpy(tipo, t_tipo);
colores = t_col;
resolucion_x = x_res;
resolucion_y = y_res;
}
void monitor::mostrar_pantalla(void)
{
cout << "Tipo de video: " << tipo << endl;
cout << "Colores: " << colores << endl;
cout << "Resolucion: " << resolucion_x << " por "<< resolucion_y << endl;
}

tarjeta::tarjeta(int t_pro,int t_vel)


{
procesador = t_pro;
velocidad = t_vel;
}

void tarjeta::mostrar_tarjeta(void)
{
cout << "Procesador: " << procesador << endl;
cout << "Velocidad: " << velocidad << " Mhz" << endl;
}

computadora::computadora(char *t_mar, int t_duro, float t_fle, char *t_pan, long


t_col,int res_x, int res_y, int t_pro, int t_vel): monitor (t_pan, t_col,res_x,
res_y), tarjeta(t_pro, t_vel)
{
strcpy(marca, t_mar);
disco_duro = t_duro;
disco_flexible = t_fle;
}
void computadora::mostrar_computadora(void)
{
cout << "Marca: " << marca << endl;
cout << "Disco Duro: " << disco_duro << " GB" << endl;
cout << "Unidad de disquete: " << disco_flexible << " MB" << endl;
mostrar_tarjeta();
mostrar_pantalla();
}

void main()
{

EEST N° 5 Amancio Willians 127


Prof. Abdala Achaval Pablo
computadora mipc("Compaq",12,1.44,"VGA",16000000,800,600,586,133);
mipc.mostrar_computadora();
cout<<"\nPresione una Tecla para Continuar";
getch();
}

Polimorfismo
Mediante las funciones virtuales y el polimorfismo, se hace posible diseñar y poner en práctica sistemas
que son de mayor facilidad extensibles. Se pueden escribir programas para procesar objetos de clases existentes
y de clases que aun no existan cuando el programa esté en desarrollo. Si esas clases deben ser derivadas de
clases base que el programa conozca, éste puede proporcionar un marco general para manipular los objetos de
las clases base, y los objetos de las clases derivadas encajarán bien dentro de este marco general.

Suponga un conjunto de clases de figuras, como circulo, triángulo, rectángulo y cuadrado, todas ellas
derivadas de la clase base figura. En la programación orientada a objetos cada una de estas clases estaría
investida con la capacidad de dibujarse a si misma. Aunque cada clase tiene su propia función miembro dibujar, la
función dibujar correspondiente a cada figura es bien distinta. Cuando se dibuja una forma, cualquiera que ésta
sea, sería agradable tener la capacidad de tratar todas estas formas en una genérica, como objetos de la clase
base figura. Entonces al dibujar cualquier figura, solo se llamaría a la función dibujar de la clase base figura, y
dejariamos que el programa determinase en forma dinámica (es decir, en tiempo de ejecución) cual de las
funciones dibujar de las clases derivadas utilizar.

Para habilitar este tipo de comportamiento se declara el método dibujar en la clase base en forma de una
función virtual, a continuación, en cada una de las clases derivadas redefinimos dibujar, a fin de que se dibuje la
forma apropiada. Se declara una función virtual en la clase base precediendo el prototipo de función con la
palabra reservada virtual. Una clase con funciones virtuales se hace abstracta al declarar una o más de sus
funciones virtuales como puras. Una función virtual pura es aquella que en su declaración contenga un
inicializador de = 0.

El polimorfismo es la habilidad que tiene un objeto de cambiar de forma. Si se desglosa el término,


descubrirá que el término poli significa “muchos” y morfismo se refiere a “cambios de forma”. Un objeto
polimórfico, entonces, es algo que puede tomar muchas formas diferentes. Entre las características más
destacadas del polimorfismo se pueden mencionar:

El polimorfismo es la habilidad de un objeto de cambiar de forma conforme se establezca en el


programa.
Para crear objetos polimórficos el programa debe utilizar funciones virtuales.
Cualquier clase derivada de una clase base puede utilizar o sobrecargar a una función virtual.
Para crear un objeto polimórfico se utiliza un apuntador hacia un objeto de la clase base.

Con el polimorfismo existe la capacidad de comportarse de diferentes maneras dependiendo de


situaciones que se definen en tiempo de ejecución. En la vida real un objeto puede moverse, eliminarse,
repararse y pintarse. Todas las acciones anteriores son genéricas, dependen del objeto sobre el que actúa.

Ejercicios Resueltos
//Programa 1: Implementación de una función virtual y polimorfismo.

#include <iostream.h>
#include <string.h>
#include <conio.h>

class Base
{

EEST N° 5 Amancio Willians 128


Prof. Abdala Achaval Pablo
public:
virtual void f() {cout<<"f(): Clase Base !"<<endl;}
void g() {cout<<"g(): Clase Base !"<<endl;};
};

class Derivada1: public Base


{
public:
void f() {cout<<"f(): Clase Derivada1 !"<<endl;}
void g() {cout<<"g(): Clase Derivada1 !"<<endl;};
};

class Derivada2: public Derivada1


{
public:
void f() {cout<<"f(): Clase Derivada2 !"<<endl;}
void g() {cout<<"g(): Clase Derivada2!"<<endl;};
};

void main()
{
Base b, *p;
Derivada1 d1;
Derivada2 d2;

p=&b;
p->f();
p->g();

p=&d1;
p->f();
p->g();

p=&d2;
p->f();
p->g();

cout<<"\nPresione una Tecla para Continuar";


getch();
}

//Programa 2: Implementación de funciones virtuales y polimorfismo.

#include <iostream.h>
#include <string.h>
#include <conio.h>

class Base
{
public:
virtual void f() {cout<<"f(): Clase Base !"<<endl;}
virtual void g() {cout<<"g(): Clase Base !"<<endl;};
};

class Derivada1: public Base


{
public:
void f() {cout<<"f(): Clase Derivada1 !"<<endl;}
void g() {cout<<"g(): Clase Derivada1 !"<<endl;};

EEST N° 5 Amancio Willians 129


Prof. Abdala Achaval Pablo
};

class Derivada2: public Derivada1


{
public:
void f() {cout<<"f(): Clase Derivada2 !"<<endl;}
void g() {cout<<"g(): Clase Derivada2 !"<<endl;};
};

void main()
{
Base b, *p;
Derivada1 d1;
Derivada2 d2;

p=&b;
p->f();
p->g();

p=&d1;
p->f();
p->g();

p=&d2;
p->f();
p->g();

cout<<"\nPresione una Tecla para Continuar";


getch();
}

//Programa 3: Implementación de funciones virtuales y polimorfismo.

#include <iostream.h>
#include <string.h>
#include <conio.h>

class telefono
{
public:
telefono (char *, int );
virtual void marcaje (char *);
protected:
char numero_telefonico[32];
int volumen;
};

class por_tono: public telefono


{
public:
por_tono (char *numero, int vol):telefono (numero, vol) {};
void marcaje (char *marcar_numero);
};

class con_disco: public telefono


{
public:
con_disco (char *numero, int vol):telefono (numero, vol) {};
void marcaje (char *marcar_numero);
};

telefono::telefono(char *numero, int vol)


{
strcpy (numero_telefonico, numero);

EEST N° 5 Amancio Willians 130


Prof. Abdala Achaval Pablo
volumen = vol;
}

void telefono::marcaje (char *marcar_numero)


{
cout << "Use un teléfono de disco o tono para llamar : "<< marcar_numero;
cout << " Volumen: " << volumen << endl;
}

void por_tono::marcaje (char *marcar_numero)


{
cout << "Es un telefono de tono: " << marcar_numero;
cout << "Volumen: " << volumen << endl;
}

void con_disco::marcaje (char *marcar_numero)


{
cout << "Es un telefono de disco: " << marcar_numero;
cout << " Volumen: " << volumen << endl;
}

void main()
{
por_tono oficina ("5326-5614", 5);
con_disco casa ("5355-5555", 2);

casa.marcaje ("5222-3333"); // Polimorfismo en tiempo de compilación


oficina.marcaje ("5333-4444");

telefono *celular; // Polimorfismo en tiempo de ejecución

celular = &casa;
celular->marcaje ("5555-3434");

celular = &oficina;
celular->marcaje ("6666-8888");

cout<<"\nPresione una Tecla para Continuar";


getch();
}

//Programa 4: Uso de una función virtual pura.


#include <iostream>
using namespace std;

#include <string.h>
#include <conio.h>

class telefono_abstracto
{
public:
telefono_abstracto (char *, int);
virtual void marcaje (char *marcar_numero)=0;
protected:
char numero_telefonico[32];
int volumen;
};

class por_tono: public telefono_abstracto


{
public:
por_tono(char *numero, int volumen):telefono_abstracto(numero, volumen){ };

EEST N° 5 Amancio Willians 131


Prof. Abdala Achaval Pablo
void marcaje (char *marcar_numero);
};

telefono_abstracto::telefono_abstracto (char *num, int vol)


{
strcpy (numero_telefonico, num);
volumen = vol;
}

void por_tono::marcaje (char *marcar_numero)


{
cout << "Es un telefono de tono: " << marcar_numero;
cout << " Volumen: " << volumen << endl;
}

void main( )
{
por_tono oficina ("5326-5614",5);
oficina.marcaje ("5326-5538");
telefono_abstracto *p;
p=&oficina;
p->marcaje("7877-9992");
cout<<"\nPresione una Tecla para Continuar";
system(“pause”);
}

Templates
INTRODUCCIÓN

Las técnicas de Templates en C++, permiten un grado de programación genérica, creando códigos especiales
para problemas especializados.

Por ejemplo, la idea del valor mínimo o máximo, se repite infinidad de veces en la programación, aunque los
objetos a evaluar varíen de un caso a otro por el tipo de datos. Sobre esta idea surgió un nuevo paradigma
denominado programación genérica o funcional.

La programación genérica está mucho más centrada en los algoritmos que en los datos y su postulado
fundamental puede sintetizarse en una palabra: generalización. Significa que, en la medida de lo posible, los
algoritmos deben ser parametrizados al máximo y expresados de la forma más independiente posible de
detalles concretos, permitiendo así que puedan servir para la mayor variedad posible de tipos y
estructuras de datos.

A menudo se tiene el pensamiento que un programa es la implementación de un mapeo (mapping). El


programa toma valores y mapea entonces a su salida. En la programación imperativa este mapping es
realizado en forma indirecta, por los comandos que leen valores de entrada, manipulan estos y luego
escriben las salidas. Los comandos influyen en los programas mediante el uso de las variables almacenadas
en la memoria.

En la programación funcional, el mapping de valores de entrada a valores de salida es realizado de modo


directo. El programa es una función o grupo de funciones; sus relaciones son muy simples: entre ellas se
invocan. Los programas son escritos en un lenguaje de expresiones, funciones y declaraciones.

EEST N° 5 Amancio Willians 132


Prof. Abdala Achaval Pablo
El código es similar siempre, pero estamos obligados a rescribir ciertas funciones que dependen del tipo o de la
clase del objeto que se almacena. Tómese por ejemplo el problema de encontrar el valor mayor de un par de
datos; tanto para un entero, flotante, carácter, etc.

Se hace uso de las funciones prototipos; en este caso para encontrar el mayor de dos valores para distintos
tipos de datos:

Se hace uso de esta sobrecarga de funciones, para obtener el mayor entre dos enteros, doble flotantes y
carácter.

int max(int,int);
double max(double,double);
char max(char,char);

#include <iostream.h>
#include <stdlib.h>
// sobrecarga de funciones para max()
int max(int,int);
double max(double,double);
char max(char,char);

void main()
{
int a=5,b=3;
cout <<" El mayor de los enteros es : “ << max(a,b)<< endl;
double c=5.5,d=10;
cout << “ El mayor de los flotantes es: “ << max(c,d)<< endl;
char e='a',f='A';
cout << “ El mayor de los char es : “ << max(e,f)<< endl;
system(“PAUSE”);
}
int max(int a,int b)
{
return a>b?a:b;
}
double max(double a,double b)
{
return a>b?a:b;
}
char max(char a,char b)
{
return a>b?a:b;
}

Un Template es una forma de objeto, que se aplica a diferentes instancias, sin especificar el tipo de objeto a ser
referenciado. El patrón con un simple código cubre un gran rango de funciones de sobrecarga denominadas
funciones patrones o un gran rango de clases denominadas clases patrones.
Se dice que los patrones son como una factoría de ensamblaje, porque producen una variedad de objetos; es
decir, dado un material se produce un determinado artículo.
Las templates permiten parametrizar estas clases para adaptarlas a cualquier tipo. Así el cambio de las tres
sobrecargas, viene reemplazado siguiente Template:

EEST N° 5 Amancio Willians 133


Prof. Abdala Achaval Pablo
Esta función trabaja para enteros, como también para flotantes y para caracteres.
Afortunadamente existen los template que hacen la labor de programación más fácil.
Los templates también denominadas tipos parametrizados, son un mecanismo de C++ que permite que
un tipo pueda ser utilizado como parámetro en la definición de una clase o una función.

template<class T>
T max(T a,T b)
{
return a>b?a:b;
}

#include <iostream>
using namespace std;
// sobrecarga de funciones para max()
template<class T>
T max(T a,T b)
{
return a>b?a:b;
}
#pragma argsused
int main(int argc, char* argv[])
{ int a=5,b=3;
cout << " El mayor de los enteros es : " << max(a,b)<< endl;
double c=5.5,d=10;
cout << " El mayor de los flotantes es: " << max(c,d)<< endl;
char e='a',f='A';
cout << " El mayor de los char es : " << max(e,f)<< endl;
system("PAUSE");
return 0;
}

C++ permite crear Templates de funciones y de clases.


La sintaxis para declarar un template de función es parecida a la de cualquier otra función, pero se añade al
principio una presentación de la clase que se usará como referencia en la plantilla:
La lista de clases que se incluye a continuación de la palabra reservada template se escribe entre las llaves "<"
y ">"; y en este caso esos símbolos no indican que
se debe introducir un literal.

Se ha considerado que el template, radique en un archivo tipo header, donde se ha incluido la función
plantilla min(),

template<class | typename<id>[...]>
<tipo de retorno> <identificador>(<lista de parámetros>)
{
// cuerpo de la función
}

Considerar que el template radique en un archivo tipo header, donde se ha incluido la función plantilla min().

EEST N° 5 Amancio Willians 134


Prof. Abdala Achaval Pablo
// minymax.h
#ifndef __MINYMAX_H
#define __MINYMAX_H

template <class T>


T max(T a,T b)
{ return (a>b)?a:b;}

template <class T>


T min(T a,T b)
{ return (a<b)?a:b;}
#endif

//Programa principal
#include <iostream>
#include <stdlib.h>
#include "minymax.h"
using namespace std
void main()
{
int x1=4,x2=3;
double y1=7.5,y2=8.3;
char c1='a',c2='A';
cout << "min int : " << min(x1,x2) << endl;
cout << "max double : " << max(y1,y2) << endl;
cout << "max char : " << max(c1,c2) << endl;
system("PAUSE");
}

Un Template que ejecuta el valor máximo para tres valores


#include <iostream.h>
#include <stdlib.h>
template <class T>
T maximo(T a,T b,T c)
{
T max=(a>b?a:b);
return(max>c?max:c);
}
Int main()
{
int a,b,c;
cout << "ingrese 3 enteros : " << endl;
cin >> a >> b >> c;
int j=maximo(a,b,c);
cout << "mayor : " << j << endl;
char d,e,f;
cout << "ingrese 3 char : " << endl;
cin >> d >> e >> f;
char k=maximo(d,e,f);

EEST N° 5 Amancio Willians 135


Prof. Abdala Achaval Pablo
cout << "mayor : " << k << endl;
system("PAUSE");
}

Introducción a Visual C++ Builder de Embarcadero RAD Studio XE series


Introducción:
Embarcadero (Borland) Rad Studio C++ Builder es un IDE que permite utilizar la programación orientada a objetos
utilizando como base el lenguaje C++ en modo visual. Aunque también permite hacer aplicaciones C++ de consola.
Este IDE comparte las mismas funciones y librerías básicas, llamadas VCL que Delphi, lenguaje basado en lenguaje
Pascal orientado a objetos.
Para crear un proyecto en modo visual orientado a objetos escoger del menú: New – Project o New - VCL Form
Application para emplear las librerías VCL para Windows. Las versiones XE incorporan la variante Firemonkey que
permite compilar en multiplataforma OS – Android e incluso dispositivos móviles.
Para un archivo Cpp en modo consola, escoger: New – Other – Console application. Puedes escoger el lenguaje C o
C++

Conceptos básicos Visual.


Proyecto. Un proyecto es un conjunto de módulos de formulario, de códigos y de archivos que componen
una aplicación. La ventana View Project Manager muestra todos los archivos que componen una
aplicación.
Formulario. Ventana donde se incluye los controles y el código asociado a dicho formulario.
Componentes o controles. Los componentes son herramientas como cuadros, botones y etiquetas que se
disponen en un formulario para permitir la entrada de datos o para presentar resultados. Para poner
controles en un formulario usar la Paleta de componentes o Tool Palette
Propiedades. Usando la ventana de Object inspector (F11) se definen las propiedades de formularios y
controles. Las propiedades especifican los valores iniciales de las características, tales como tamaño,
nombre y posición.
Eventos: Es quien desencadena las acciones del sistema.

Propiedades básicas de los objetos:


Alignm. ent - Alineación
BevelInner - borde interior
BorderStyle - estilo del borde
Caption - rótulo
TabStop - Salto tabulación
Color, Cursor - Color, puntero
Eventos o acciones (sobre un Enabled - Activo
componente): Font - Tipo letra
Height - Altura del objeto
Lista de eventos (Acciones sobre los controles)
Hint - Etiqueta ayuda
Left - Posición izquierda
Evento Acción
Name - Nombre del objeto
Click Al hacer clic con el mouse (o el teclado)
PopupMenu - Menú contextual
DragDrop Al soltar un control arrastrado con el mouse
ShowHint - Mostrar etiquetas
DragOver Al Arrastrar un control con el mouse.
Top - Posición superior
KeyDown Presionar una tecla mientras el objeto tiene el foco.
Visible - Visible
KeyPress Presionar una tecla y devolver su valor ASCII. KeyUp
Width - Ancho del objeto
Liberar una tecla mientras el objeto tiene el foco. MouseDown
Presionar el botón del mouse sobre el objeto. MouseMove
Mover el puntero del mouse por encima del objeto MouseUp
Liberar el botón del mouse en el objeto.

EEST N° 5 Amancio Willians 136


Prof. Abdala Achaval Pablo
Conversión de tipos:

IntToStr (Integer to String) Cambia del tipo de número entero a cadena de texto
StrToInt (String to Integer) Cambia del tipo cadena de texto a número entero
Otros:
StrToFloat (texto a decimal flotante) DateTimeToStr (Fecha/hora a texto)
FloatToStr (Decimal flotante a texto)) DateToStr (Fecha a Texto)
FloatToDecimal (Decimal flotante a decimal StrToTime (Texto a hora)
Formatfloat (Decimal flotante a texto con formato) StrToDate (Texto a fecha)

Ventanas de mensaje. (Mostrar o pedir mensajes al usuario):


Usando las funciones VCL internas que incorpora C++Builder:
- ShowMessage(): Muestra un mensaje de texto en una ventana
- MessageDlg(): Muestra una ventana con mensaje y botones de respuesta
Los botones de acción pueden ser: mbOK – mbCancel – mbYes – mbNo – mbAbort – mbRetry – mbClose
Y sus repuestas son: mrOk - mrCancel – mrYes – mrNo – mrAbort – mrRetry - mrClose
- MessageDlgPos() ídem pero con posibilidades extras
Usando las funciones de la API de Windows
- Application->MessageBox(): Muestra un mensaje de texto en una ventana de Windows estándar con o sin botones
de respuesta que pueden ser: MB_OK - MB_OKCANCEL- MB_ABORTRETRYIGNORE - MB_YESNOCANCEL -
MB_YESNO -MB_RETRYCANCEL - MB_HELP
Creando nuestros propios formularios/ventanas:
- Primero: crear un nuevo formulario secundario: Flie – New – Form donde se pondrá el mensaje y los botones
- Segundo: incluir la unidad cabecera de este formulario en la principal: #include "secundario.h"
- Tercero: Mostrar la ventana utilizando las funciones show() o showmodal();

Pedir datos al usuario en ventanas:


Utilizando ventanas con entradas de texto:
- InputBox('Nombre_ventana', 'Texto_Dato', 'Respuesta_predeterminada'); Devuelve Var String
- InputQuery('Identificate!', 'Pon tu nombre, por favor...', Nombre); Devuelve Var Bolean
Añadiendo componentes de diálogo estándar al formulario desde la paleta Dialogs:
- Opendialog – Savedialog: Componentes para abrir y guardar archivos
- PrintDialog – PrinterSetupDialog - PageSetupDialog: Componentes para imprimir y configurar impresión
- FontDialog – ColorDialog - FindDialog: Cambiar la fuente, el color o buscar texto.

Ejercicio 1:

Crear una nueva aplicación VCL (librería visual C para Windows) escogiendo del menú: File New VCL Form
Applicaton C++ Builder.
En un formulario nuevo, desde la Tool palette, añade un
componente TButton (botón Button1). Desde el panel de
propiedades, cambia su propiedad Caption por: Aceptar
Pulsa doble clic sobre el botón e introduce el código (en el
evento OnClic del botón Button1) por:

void fastcall TForm1::Button1Click(TObject *Sender)


{
Button1->Caption="Vale";
ShowMessage ("Hola mundo");
}
(Importante escribir “Button” con la 1ª letra en mayúsculas, ya que C++ distingue mayúsculas de minúsculas)
Prueba la aplicación pulsando en Run .
Si funciona correctamente, guarda la aplicación: File Save all . El archivo de proyecto se llamará Clase0cpp.

EEST N° 5 Amancio Willians 137


Prof. Abdala Achaval Pablo
Ejercicio 2:

Abre el proyecto anterior Clase0cpp.


Desde la Tool palette, añade al ejercicio anterior un
componente TEdit y un componente TLabel con las
propiedades de la imagen:
Cambiar el evento: OnClick del botón Button1 por:
void fastcall TForm1::Button1Click(TObject *Sender)
{
ShowMessage("Hola, " + Edit1->Text + ".");

ShowMessage es una función que sirve para mostrar una ventana


de mensaje
Guarda el proyecto con el nombre: ClaseunoCpp

Ampliación llamadas a cuadros de diálogo:


Puedes hacer llamadas a cuadros de diálogo de la API de Windows usando: Application->MessageBox
Si añades la línea:
Application->MessageBox(L"¿Desea continuar?", L"Pregunta", MB_OKCANCEL); //con L si es Unicode
Application->MessageBox("¿Desea continuar?", "Pregunta", MB_OKCANCEL); //sin L si no es Unicode

Dispones de las variantes: MB_OK - MB_OKCANCEL- MB_ABORTRETRYIGNORE- MB_YESNOCANCEL- MB_YESNO-


MB_RETRYCANCEL- MB_HELP

Ejercicio 3. Contador:
StrToInt y InttoStr: Son funciones que convierten un valor de numérico entero (Integer) a texto (String) y viceversa
Recupera el ejercicio anterior.
Cambia el texto (propiedad caption) del botón por: 0
Añade un segundo botón a la ventana formulario desde la paleta
Tool palette – sección Standard: Tbutton
Al botón 2 cambia el texto (propiedad caption) por Contar
Pulsa doble clic encima de él, para abrir la ventana de código.
Entre las llaves { } debes escribir el código:
Button1->Caption= Button1->Caption +1;
Si lo ejecutas (run), verás cuenta mal porque añade la letra 1 pero no suma el número 1
Para ello hay que convertir las letras en números enteros: string to integer o abreviado: StrToInt
Button1->Caption = StrToInt(Button1->Caption) +1;
Si ahora lo ejecutas, verás que ya funciona.
Si funciona correctamente, guarda la aplicación: File – Save Project as.. El archivo de proyecto se llamará Contador.
File – Save as…Guarda la unidad como: Contador1.cpp

EEST N° 5 Amancio Willians 138


Prof. Abdala Achaval Pablo
Construcción de una aplicación con dos formularios. Mensajes
Teoría previa: if/else permite separar las acciones en dos casos; el caso verdadero o falso según se cumpla
o no la comparación. Sintaxis: if (comparación) {acción_verdadera} else {acción_falsa}

Crear aplicación nueva:


(File - New – VCL Form Applicaton C++ Builder)
Poner en el formulario principal los siguientes componentes:
3 Label (solapa Standard), 3 Edits (solapa Standard), y 2
botones BitBtn (solapa Additional).
Distribuir los objetos para que la ventana tenga el aspecto de
la imagen.
En una carpeta nueva llamada: Mensajes, guarda esta unidad
(File Save as…) con el nombre mensaje1.cpp, el archivo
cabecera por defecto y el proyecto con el nombre:
mensajes.cbproj

Configurar el formulario secundario.


Añade un nuevo formulario al proyecto: selecciona File New Form
Cambia las propiedades del formulario:
Name =SaludoBox y Caption= Cuadro de saludo.
Añade un componente Label llamado Label1. Como en la imagen.
Guarda esta unidad (File Sav e as…) con el nombre saludo1.cpp y el
archivo cabecera: saludo.h
Escribir el código.
En este caso, sólo se escribirá código para el evento OnClick del componente BotonOK del formulario principal.
Con dicho componente seleccionado, ir a la pestaña Events del inspector de objetos y hacer doble click en el evento
OnClick. El gestor de este evento quedará como sigue:
void fastcall TForm1::BitBtn1Click(TObject *Sender)
{
SaludoBox ->Label1->Caption = "Bienvenido, " + EditNombre->Text ; //pone texto en label
SaludoBox ->Show(); //muestra la ventana en modo no modal cambiar por ShowModal()
}
En el formulario principal, seleccionar File - Use Unit y seleccionar Saludo1.
Observar que se añade la línea: #include "Saludo.h" y ejecuta el programa.
Variante 1:
Cambia el código del evento OnClick por el siguiente: ( || equivale a un O lógico, && equivale a un Y lógico)
void fastcall TForm1::BitBtn1Click(TObject *Sender)
{
if (EditNombre->Text == "" || EditApellidos->Text == "" || EditClave->Text == "" )
{ ShowMessage ("Debe especificar todos los campos"); //mostrar mensaje
}
else {
SaludoBox->Label1->Caption = "Bienvenido, " + EditNombre->Text + " " +
EditApellidos->Text + ". Su clave es: " + EditClave->Text;
SaludoBox->ShowModal(); //muestra ventana en modo modal
} }
El siguiente código muestra un mensaje si la clave es incorrecta y prepara entrada para nuevo usuario:
void __fastcall TForm1::BitBtn1Click(TObject *Sender)
{
if (EditNombre->Text == "" || EditApellidos->Text == "" || EditClave->Text == "" )
{ ShowMessage ("Debe especificar todos los campos"); //mostrar mensaje
}
else if (EditClave->Text != "ofimega") {ShowMessage("Clave incorrecta");
}

EEST N° 5 Amancio Willians 139


Prof. Abdala Achaval Pablo
else {

}}

En el siguiente código, cambia el error de clave (ShowMessage("Clave incorrecta” ) por una ventana de diálogo:
MessageDlg("Clave incorrecta",mtError,mbAbortRetryIgnore,0);

SaludoBox->LLabel1->Cap tion = " Bienvenido, " + EditNom+ " " + EditApellidos-


>Text + ". Su clave es: " + EditClave->Text;

SaludoBox->ShowModal(); //muestra ventana en modo modal

//prepara un nuevo usuario: EditNombre->Text = ""; EditApellidos->Text = "";


EditClave->Text = ""; EditNombre->SetFocus();

Ejercicio. Adivinar el número.


Crear una nueva aplicación VCL escogiendo del menú: File - New – VCL Form Applicaton C++ Builder.
En el formulario nuevo, desde la Tool palette, añade los siguientes
Ingredientes:
2 Labels - 1 Edit - 1 Button

Preparación:
Creamos 2 variables públicas: Bueno: integer y Intentos: integer:
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
int bueno, intentos; // -> declaramos dos variables numéricas enteras públicas

Cocción:
Al crearse el formulario se genera un número aleatorio del 1 al 100 y se guarda en la variable bueno:
void fastcall TForm1::FormCreate(TObject *Sender)
{
randomize; //baraja
bueno=random(100); //crea un num aleatorio entre 0 y 100 y lo guarda en la variable bueno
intentos=0; //pone intentos a cero
}
Acciones: Al pulsar el botón, se crea una variable numerousuario y se evalúa si la variable es igual o mayor a
la variable bueno:
void fastcall TForm1::Button1Click(TObject *Sender)
{
int numerousuario; //declaramos una variable numérica entera privada válida sólo para esta función
numerousuario = StrToInt(Edit1->Text); //pasa valor de texto a numérico y lo guarda en la variable
if (numerousuario==bueno) {
ShowMessage("Acertaste");
}
else
{
ShowMessage("Fallaste, el número era el " + IntToStr(bueno));
}}
Mejoras:

EEST N° 5 Amancio Willians 140


Prof. Abdala Achaval Pablo
Mejora 1ª: Consigue que el programa te informe si el número introducido es mayor o menor

void fastcall TForm1::Button1Click(TObject *Sender)


{
int numerousuario;
numerousuario = StrToInt(Edit1->Text);
if (numerousuario==bueno) {
ShowMessage("Acertaste");
}
else
{

if (numerousuario>bueno) {
ShowMessage("Fallaste, el número es más pequeño");
}
else
{
ShowMessage("Fallaste, el número es más grande");
}

}}
Mejora 2ª:
Añadir una barra de progreso: progressbar1 (paleta win32) Progressbar: Max: 60 Position: 60
Añadir un Temporizador: Timer (paleta system) Interval: 1000 (Repetirá el evento cada 1 segundo)
En el evento del timer OnTimer añadir el código para evaluar el tiempo tardado en acertar y decrementar la barra de
progreso. if (ProgressBar1->Position=0) {Showmessage('Se acabó el tiempo'); Timer1->enabled:=false;}
Mejora 3ª:
Al pulsar la tecla Enter en el Edit1 (Edit1KeyPress), llama a la función Button1Click:
if (Key==13) Button1Click(Sender);
Guardar: Guarda la aplicación (Save all).
La unidad con el nombre: adivinanza1.cpp y el proyecto con el nombre: adivinanza.cproj

Ejercicio 4: Conversor
Teoría previa:
StrToInt y InttoStr: Son funciones que convierten un valor de numérico entero (integer) a texto y viceversa
FloatToStr y StrToFloat: Convierten un valor de numérico decimal flotante (float) a texto y viceversa
Sender: Es un parámetro que indica el nombre del objeto que ha desencadenado el evento
Ejercicio:
Crear una nueva aplicación VCL (librería visual c para windows) escogiendo
del menú: File - New – VCL Form Applicaton C++ Builder.
En el formulario nuevo, desde la Tool palette, añade: 2 edits, 1 botón y 3
labels
Cambia la propiedad caption de las label y del botón para que muestre el
texto de la imagen.
Pulsa doble clic encima del botón para llamar al evento (on click)
void fastcall TForm1::Button1Click(TObject *Sender) y escribe:
Edit2->Text=Edit1->Text * 1.3;
Si no funciona correctamente escribe en su lugar:
Edit2->Text=StrToInt(Edit1->Text) * 1.3;
Si funciona correctamente, guarda toda la aplicación: Fila – Save all
El archivo de proyecto se llamará Conversor y la unidad: Conversor1.cpp

Usar dos botones con la misma función (usando el parámetro sender)


Añade un segundo botón Button2 como en la imagen. 
En el código del botón Button1 cambia el código por el del recuadro.

void fastcall TForm1::Button1Click(TObject *Sender)


{
if (Sender = Button2) {
Edit2->Text=Edit1->Text*1.3;

EEST N° 5 Amancio Willians 141


Prof. Abdala Achaval Pablo
}
else
{

}
}

Edit1->Text=Edit2->Text/1.3;

En el evento onclick del botón 2 tienes que asignar el mismo evento que el del botón 1 para que ambos botones
llamen a la misma función.
Si funciona correctamente, guarda toda la aplicación: Fila – Save all.

Versión para Mobile Android: (Firemonkey. Para versiones de Embarcadero XE3 y superiores)
Para versiones XE3-XE4: Crear una nueva aplicación: File – New - Firemonkey – Mobile Application C++ Builder
Para versiones XE7-XE8: File - New - Multi-device application C++ Builder
Diseño: Header footer -
Guardar en la carpeta: conversor.
Añadir 2 labels, 2 Spinbox y 2 botones.
Cambiar las propiedades como en la figura: 
Añadir el código a cada
botón: ButtonCmClick:
SpinBox2->Value=SpinBox1-
>Value*2.54;
ButtonPulgaClic
k:
SpinBox1->Value=SpinBox2-
>Value/2.54;

Si funciona correctamente, guarda toda la aplicación: Fila –


Save all.
Guarda la unidad cpp, el archivo cabecera h y el proyecto:
cbproj con el nombre: ConversorM.cbpro

Ejercicio 4 ext: - Área del triángulo


Añadir al ejercicio anterior los componentes de la imagen.
Cambiar el evento: OnClick del botón Button1 por:

void fastcall TForm1::Button1Click(TObject *Sender)


{
Edit3->Text=FormatFloat("###.##",(aca poner function que
calcula area del triangulo utilizando archivo
header file));
}

Versión para Firemonkey (XE):


En la etiquetas Labels, cambiar la
propiedad Caption por la
propiedad Text.
Añadir al Form1 un componente:
StyleBook1

EEST N° 5 Amancio Willians 142


Prof. Abdala Achaval Pablo
Pulsar doble clic sobre el
componente StyleBook1
y cargar
(Load…) de la carpeta:
Users\Public\Documents\RAD
Studio\12.0\Styles el estilo: AquaGraphite.style – Apply and close
Cambiar la propiedad del formulario Form1. Stylebook:
Guardar ( File - Save Project ) Guarda la unidad cpp, el archivo cabecera h y el proyecto: cbproj

Ejercicio 5: - Uso de grilla StringGrid con Firemonkey


Crear una nueva aplicación:
o Vers. XE3: Crear una nueva aplicación: File – New - Firemonkey – Mobile Application C++ Builder
o Vers. XE8: File - New - Multi-device application C++ Builder
Diseño: Header footer - Guardar en la carpeta Elementos
Inserta una etiqueta Label y una rejilla Grid o mejor StringGrid (porque va a contener sólo texto) en el formulario.
Con el botón derecho sobre la Stringrid escoger: Items editor y añadir 2 columnas. Pon su propiedad Align al Bottom.
Cambia la propiedad Header de la column1 y column2 por: elemento y nº atómico.
Para introducir los datos en tiempo de ejecución, activar el evento On Show (al mostrar la ventana).

Escribe el código para el evento: onshow FormShow:


void fastcall THeaderFooterForm::FormShow(TObject *Sender)
{
StringGrid1->Cells[0][0]="Hidrógeno";
StringGrid1->Cells[1][0]="1"; //columna 1 fila 0
StringGrid1->Cells[0][1]="Helio"; //columna 0 fila 1
StringGrid1->Cells[1][1]="2"; //columna 1 fila 1
}

Al hacer clic en un elemento de la lista debe aparecer su valor en la etiqueta Label1


Escribe el código para el evento OnSelectCell de la StringGrid1:
void fastcall THeaderFooterForm::StringGrid1SelectCell(TObject *Sender, const int ACol,
const int ARow, bool &CanSelect)
{
int fila; //-> creo la variable entera fila
fila=ARow; //recojo el valor devuelto por ARow y lo pongo en mi variable fila
Label1->Text=StringGrid1->Cells[0][fila] + " = "+ StringGrid1->Cells[1][fila];
}
Comprueba runeando la aplicación [F9] y si funciona correctamente, guarda toda la aplicación: Fila – Save all.

Pizarra de dibujo
Crear una nueva aplicación VCL (librería visual) escogiendo del menú: File - New – VCL Form Applicaton C++ Builder.
Cambiar el nombre y título del formulario principal: Con el inspector de objetos, cambiar la propiedad Caption por
PIZARRA y la propiedad Name por MainForm.
Guardar (File Save As) la unidad asociada al formulario (Unit1.cpp, por defecto) como PizarraUnit.cpp. El archivo
cabezera a Pizarrah.h y el proyecto (File | Save Project As) como Pizarra.bpr. o .cbproj
Poner icono: Para asignar un icono: (Project - Options Application). Puls: Load Icon… - Seleccionar un icono.
Temas en XE: Asignar un tema: Esoge (Project - Options - Application) - Appearance. Escoge: Amakrits. Asigna
el tema como Default y pulsa Ok
Ya podemos comprobar la apariencia del ejecutable: selecciona del menú: Project – Run.

Diseño del formulario principal:


Fijar manualmente el tamaño del Form a 300 X
400: (Height = 300 y Width = 400) Nombre:
MainForm
Añadir 3 componentes:
En la parte superior, alineado a lo alto (Align: alTop),
un componente PaintBox (solapa System). Fijar las

EEST N° 5 Amancio Willians 143


Prof. Abdala Achaval Pablo
propiedades: Name = PaintBox, Align = alTop y Height
=
225.
Debajo del PaintBox un componente Bevel
(solapa Additional). Fijar las siguientes propiedades: Name
= Linea, Align = alTop, Style = bsLowered y Height = 8.
Debajo del Bevel, centrado horizontalmente
un componente BitBtn (solapa Additional). Fijar las
siguientes propiedades: Name = ExitBtn, Kind = bkClose
y Caption =
&Salir.

Escribir el código.
En primer lugar, escribiremos el código asociado al evento OnPaint del componente PaintBox. Seleccionar en
el inspector de objetos dicho componente, y tras seleccionar la pestaña Events haremos doble click en el gestor
del evento OnPaint. El gestor de este evento quedará como sigue:
void __fastcall TMainForm::PaintBoxPaint(TObject
*Sender)
{
// Dibujar un círculo amarillo:
PaintBox->Canvas->Pen->Color = clBlack;
PaintBox->Canvas->Brush->Color = clYellow;
PaintBox->Canvas->Ellipse (100, 100, 150,
150);
// Dibujar un cuadrado rojo:
PaintBox->Canvas->Pen->Color = clRed;
PaintBox->Canvas->Brush->Color =
clRed;
PaintBox->Canvas->Rectangle (200, 100, 250, 150);
/*Si quisiera dibujar una linea en diagonal:
PaintBox->Canvas->MoveTo(0,PaintBox->Height/2);
PaintBox->Canvas->LineTo(PaintBox-
>Width,PaintBox-
>Height/2);
*/
} //----------------------------------------------------------------------
--

Finalmente, escribiremos el código asociado al evento OnClick del componente BitBtn (ExitBtn). Seleccionar
en el inspector de objetos dicho componente, y tras seleccionar la pestaña Events haremos doble click en el
gestor del evento OnClick. El gestor de este evento quedará como sigue:
void __fastcall TMainForm::ExitBtnClick(TObject *Sender) //---------------
--
{
Application->Terminate(); //-> termina la aplicación
//o también: MainForm->Close(); //-> cierra la ventana
} //------------------------------------------------------------------------

Generar el ejecutable:
Ahora podemos construir el ejecutable y probarlo: seleccionar Project Build Pizarra y a continuación, Run Run.
Guardar:
Para finalizar esta parte, Guarda todo (File Save All) Esto guardará: PizarraUnit.cpp - Pizarrah.h - Pizarra. .cbpro

Eventos del Mouse: Dibujar en la Pizarra:


Crearemos una variable pública Pintar del tipo “Flag” booleriana que nos dé permiso para pintar al presionar el
botón del mouse pero no lo permita si movemos el mouse sin apretar el botón.
Recupera el proyecto anterior (File Open): Pizarra. .cbproj
Anula el código de la Función PaintBoxPaint. Para ello utiliza los caracteres /* y */ para convertirlo en comentario.
Añade la variable booleriana tras las líneas de Include de cabazera iniciada por defecto en false: bool Pintar = false;
Añade las siguientes funciones para los eventos on mousedown, on mouse up y on mousemove del objeto Paintbox:
//---------------------------------------------------------------------------
void __fastcall TMainForm::PaintBoxMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y)
{
Pintar = True;
PaintBox->Canvas->MoveTo(X,Y); //los valores de X e Y son las coordenadas del mouse para empezar al pintar

EEST N° 5 Amancio Willians 144


Prof. Abdala Achaval Pablo
}
void __fastcall TMainForm::PaintBoxMouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y)
{
Pintar = False;
}
void __fastcall TMainForm::PaintBoxMouseMove(TObject *Sender, TShiftState Shift, int X, int Y)
{
if (Pintar==True) {PaintBox->Canvas->LineTo(X,Y); //los valores de X e Y son las coordenadas del mouse
}
//---------------------------------------------------------------------------

Ejecuta y prueba (Run): Al arrastrar el mouse sobre el objeto Paintbox dibujará desde la coordenada que se indica en
PaintBoxMouseDown.
Guardar: Guarda todo (File Save All)

Cuadro de diálogo color.


Añade un nuevo botón BitButton junto al de Salir llamado: Color
y un Componente ColorDialog de la paleta Dialogs.
Desencadena el evento Onclick donde añadirás el código:

void __fastcall TMainForm::ColorClick(TObject *Sender)


{
if (ColorDialog1->Execute()) {
PaintBox->Canvas->Pen->Color = ColorDialog1->Color;
}}
//-----------------------------------------------------------------
Comprueba su funcionamineto (Run) y Guarda todo (Save All)

Uso del Timer y posición del objeto:


Crea una nueva aplicación VCL (librería visual) escogiendo del menú: File - New – VCL Form Applicaton C++ Builder.
Añade un botón Button1 en un formulario nuevo. Cambiar su propiedad Caption por: Púlsame.
En el evento del botón OnMouseMove:
void fastcall TForm6::Button1MouseMove(TObject *Sender, TShiftState Shift, int X, int Y)
{ Button1->Left = Button1->Left + 1; }
Ejecuta y prueba (Run): Al intentar pulsar el botón, este se desplaza hacia la derecha.
Anula esta última línea de código convirtiéndola en un comentario: añade // delante
Añade un componente Ttimer de la paleta System.
Poner su propiedad Interval a 10 y si propiedad enabled en
False:
En el evento del botón OnClick:
void __fastcall TForm6::Button1Click(TObject *Sender)
{ Timer1->Enabled = True; }
En el evento del Timer OnTimer:
void __fastcall TForm6::Timer1Timer(TObject *Sender)
{ Button1->Left = Button1->Left + 1; }

Ejecuta y prueba (Run): Al pulsar el botón, activamos


el temporizador Timer que desplaza un pixel a la
derecha la
posición del botón a cada pulso de su intervalo, de duración 10 milisegundos.

Eventos del teclado: dirección de nave.

Dibujar previamente, desde Paint, 4 imágenes de una nave conteniendo las cuatro direcciones. Guardar en la
carpeta Naves.

EEST N° 5 Amancio Willians 145


Prof. Abdala Achaval Pablo
Desde C++ Builder, crear una nueva aplicación escogiendo
del menú: File - New – VCL Form Applicaton C++ Builder.
Cambiar la propiedad Caption del formulario por Naves,
su propiedad KeyPreview por True y su propiedad
DoubleBuffered por true.
Guardar (File Save As) la unidad asociada al formulario (Unit1.cpp, por defecto) como NaveUnit1.cpp. El archivo
cabezera a Nave.h y el proyecto (File | Save Project As) como Naves.bpr. o .cbproj en la carpeta Naves.
Añadir 5 componentes de imagen con los nombres de la figura. Cargar, desde su propiedad Picture, las
imágenes previamente dibujadas.
void fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift)

{
//ShowMessage(Key); para test de tecla
switch (Key)
{
case 37: Nave->Left=Nave->Left-1;
//izda break;
case 38: Nave->Top=Nave->Top-1;
//arriba break;
case 39: Nave->Left=Nave->Left+1;
//derecha break;
case 40: Nave->Top=Nave->Top+1; //abajo
}
}
Variante con ImageList:
Borrar los 4 componentes de imagen y agregar un componente ImageList.
En el componente ImageList, agregar las 4 imágenes de posición de la nave
Cambiar el código anterior por:
switch (Key)
{
case 37: izquierda();
break;
case 38: arriba();
break;
case 39: derecha();
break;
case 40: abajo();
}
Crear las funciones:
void fastcall TForm1::izquierda()
{ImageList1->GetBitmap(2,Nave->Picture-
>Bitmap); Nave->Left=Nave->Left-1;}
void fastcall TForm1::arriba()
{ImageList1->GetBitmap(0,Nave->Picture-
>Bitmap); Nave->Top=Nave->Top-1; }
void fastcall TForm1::derecha()
{ImageList1->GetBitmap(3,Nave->Picture-
>Bitmap); Nave->Left=Nave->Left+1;}
void fastcall TForm1::abajo()
{ImageList1->GetBitmap(1,Nave->Picture-
>Bitmap); Nave->Top=Nave->Top+1;}
Declarar las funciones en el archivo cabecera h:
void fastcall
izquierda(); void
fastcall arriba(); void
fastcall derecha(); void
fastcall abajo();

Ampliación: Uso de un procedimiento: llamar a una función con parámetros.

Añadir Shape de forma circle , llamarle:bala , visible:false

EEST N° 5 Amancio Willians 146


Prof. Abdala Achaval Pablo
Añadir Timer (de paleta system): Timer1 – Interval: 10
Declara la función en el archivo cabecera h: void fastcall mover(int direc);
En el archivo cpp:
Añadir las variables públicas:
int direccion;
int velocidad;
Cambiar el código:
void fastcall TForm1::FormCreate(TObject *Sender)
{
ImageList1->GetBitmap(2,Nave->Picture->Bitmap);
velocidad=2;
}
void fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift)
{
switch (Key)
{
case 37: mover(3);//izquierda
break;
case 38: mover(0);//arriba
break;
case 39: mover(2);//derecha
break;
case 40: mover(1);//abajo
break;
case 32: dispara(); //barra espaciadora
}
}
void fastcall TForm1::mover(int direc)
{ImageList1->GetBitmap(direc,Nave->Picture->Bitmap);
direccion=direc;
switch (direccion)
{
case 3: Nave->Left=Nave->Left-velocidad;//izquierda();
break;
case 0: Nave->Top=Nave->Top-velocidad;//arriba();
break;
case 2: Nave->Left=Nave->Left+velocidad;//derecha();
break;
case 1: Nave->Top=Nave->Top+velocidad;//abajo();
}
}

void fastcall TForm1::dispara()


{
bala->Left=Nave->Left;
bala->Top=Nave->Top;
bala->Visible=true;
Timer1->Enabled=True;
}
void fastcall TForm1::Timer1Timer(TObject *Sender)
{

EEST N° 5 Amancio Willians 147


Prof. Abdala Achaval Pablo
witch (direccion)
{
case 3: bala->Left=bala->Left-velocidad;//izquierda();
break;
case 0: bala->Top=bala->Top-velocidad;//arriba();
break;
case 2: bala->Left=bala->Left+velocidad;//derecha();
break;
case 1: bala->Top=bala->Top+velocidad;//abajo();
}
if ((bala->Left> Form1->Width) && (bala->Left<0 )
&& (bala->Top<0 ) && (bala->Top>Form1->Height ) )
{Timer1->Enabled=false;
bala->Visible=false; }
}

Animación. Protector de pantalla (Uso del estamento CASE)


Ingredientes:
- Shape (de la Paleta Additional o Shapes): Name: Bola;
Shape: Circle
- Timer (de paleta system): Timer1 – Interval: 30
- Botones: 2 (Empezar y parar)
Formulario: Si lo deseas, puedes asignar color transparente o
negro (Fill: black kind: solid)
Variables: añadir al principio como variable pública:
Int mover=1;
Acciones:
void fastcall TForm1::BempezarClick(TObject *Sender) //***** al pulsar el botón empezar
{mover=1;
Timer1->Enabled=True; }
void fastcall TForm1::BpararClick(TObject *Sender) //***** al parar el botón switch - Case:
Bifurca las acciones
{Timer1->Enabled=False; }
dependiendo de un parámetro
del tipo ordinal
Método utilizando las funciones swith - case
void fastcall TForm1::Timer1Timer(TObject *Sender) //***** al activar el timer
{
switch (mover)
{ case 3: //arribader
case 1: //abajoder bola->Position->X++;
bola->Position->X++; bola->Position->Y--;
bola->Position->Y++; if (bola->Position->X>=Form1->Width-bola->Width)
if (bola->Position->X>=Form1->Width-bola->Width) {mover=1;};
{mover=2;}; if (bola->Position->Y<=0) {mover=3;};
if (bola->Position->Y>=Form1->Height-bola->Height)
{mover=3;}; case 4: // arribaiz
case 2: //abajoiz bola->Position->X--;
bola->Position->X--; bola->Position->Y--;
bola->Position->Y++; if (bola->Position->X<=0) {mover=3;};
if (bola->Position->X<=0) {mover=1;}; if (bola->Position->Y<=0) {mover=2;};
if (bola->Position->Y>=Form1-y Height-bola->Height) }
{mover=4;};

Método utilizando if funciones creadas


void fastcall TForm1::Timer1Timer(TObject bola->Position->Y++;
*Sender) if (bola->Position->X<=0) {mover=1;};
{ if (bola->Position->Y>=Form1->Height-bola-

EEST N° 5 Amancio Willians 148


Prof. Abdala Achaval Pablo
if (mover==1) {abajoder();} else if (mover==2) {abajoiz();} else if (mover==3) {arribader();}
else if (mover==4) {arribaiz();}
}
//********************************************
void fastcall TForm1::abajoder()
{
bola->Position->X++;
bola->Position->Y++;
if (bola->Position->X>=Form1->Width-bola-
>Width) {mover=2;};
if (bola->Position->Y>=Form1->Height-bola-
>Height) {mover=3;};
}
void fastcall TForm1::abajoiz()
{
bola->Position->X--;
Height-bola>Height) {mover=4;};
}
void fastcall TForm1::arribader()
{
bola->Position->X++;
bola->Position->Y--;
if (bola->Position->X>=Form1->Width-bola->Width)
{mover=1;};
if (bola->Position->Y<=0) {mover=3;};
}
void fastcall TForm1::arribaiz()
{
bola->Position->X--;
bola->Position->Y--;
if (bola->Position->X<=0) {mover=3;};
if (bola->Position->Y<=0) {mover=2;};
}

Recuerde declarar en el archivo cabecera (.h) las funciones:


void fastcall abajo
der(); void fastcall abajoiz(); void fastcall arribaiz(); void fastcall arribader();

USO DE COMPONENTES DE TEXTO. MEMO


Para mostrar y editar varias líneas de texto, disponemos de los componentes: Memo (paleta estándar) para texto
sencillo TXT y Richedit (paleta Win32) que permite almacenar texto enriquecido (con formato).

1. Elije del menú principal: File New VCL form Application.


2. Con el formulario seleccionado, selecciona del inspector de objetos el evento
OnCreate haciendo doble clic y escribe lo siguiente:
Memo1->Lines->LoadFromFile(“Unit1.cpp”);
3. Selecciona de la paleta Standard, el objeto Memo, y extiéndelo sobre el
formulario, alineado al cliente, con el nombre: Memo1.
4. Guardar: En una carpeta nueva llamada Memo, guarda la unidad con el nombre:
Unit1.cpp y el proyecto con el nombre: Memo
5. Ejecutar: Pulsa en (Run) y comprueba que al iniciar la aplicación, se muestra el
texto de la unidad.
Variación:
Recupera el proyecto anterior (File Open)
Añade tres botones dentro un panel alineado al top. (Antes deberás desajustar el
Memo) Con el texto: Cargar Nota, Borrar nota y Guardar nota.
• Anula el código que añadimos en la Función OnCreate
Asigna el código a los botones:

void __fastcall TNotas::Button1Click(TObject *Sender) → { Memo1->Lines->LoadFromFile("nota.txt"); }


void __fastcall TNotas::Button2Click(TObject *Sender) → {Memo1->Lines->Clear();}
void __fastcall TNotas::Button3Click(TObject *Sender) → {Memo1->Lines->SaveToFile("nota.txt");}

EEST N° 5 Amancio Willians 149


Prof. Abdala Achaval Pablo
Comprueba su funcionamineto (Run) y Guarda todo (Save All)
Ejercicio propuesto FireMonkey: Editor de Notas para FireMonkey Mobile
Repite el ejercicio en una nueva aplicación: File – New - Firemonkey – Mobile Application C++ Builder
Diseño: Header footer

USO DE COMPONENTES DE TEXTO. RICHEDIT y ActionList


Vamos a generar un pequeño procesador de textos utilizando la plantilla SDI y el componente Richedit.
1. Elije del menú principal: File New Other…
2. Escoge de C++ Projects: SDI Application. Nos generará un formulario con los
componentes básicos. Un menú, una barra de herramientas y una barra de
estado.
3. Añade al formulario un objeto Richedit (Paleta Win32) alineado al cliente.
Cambia su propiedad Align: alCliente y su borra el texto de la propiedad Lines
La plantilla nos ha generado un formulario con una barra de herramientas y un
menú que contienen llamadas a las mismas acciones, por ejemplo, la acción de
Abrir puede ser llamada desde el botón de abrir o desde el menú: Archivo - Abrir.
Cada objeto de ambas, hace referencia a una acción que está centralizada en la
lista de acciones: ActionList1 y es llamado desde el evento Action.

Para completar el evento Abrir,


pulsamos doble click sobre
Acciónlist1 y seleccionamos a
acción: FileOpen1.
En sus propiedades: cambia sus
propiedades Caption y Hint
como en la figura.

En el evento OnExecute, cambia el código: OpenDialog->Execute(); por:


if (OpenDialog->Execute())
{ RichEdit1->Lines->LoadFromFile(OpenDialog->FileName); }
Del mismo modo selecciona la Acción FileSave1 y cambia el código por:
if (SaveDialog->Execute())
{ RichEdit1->Lines->SaveToFile(SaveDialog->FileName); }

En ambos objetos, cambiar la propiedad filter, para poder especificar e tipo de


documento al abrir o guardar, como en la figura y las propiedades: Filterindex: 3
DefaultExt: *.rtf

Otras acciones:
Acciones Cortar, copiar y pegar: Estas acciones funcionan sin código escrito porque estás asociadas a una combinación
del teclado que se designa en la propiedad: ShortCut: Ctrl+X, Ctrl+C y Ctrl+V.
Acción Nuevo: FileNew1 - FileNew1Execute: añade el código: RichEdit1->Lines->Clear();
Accción Salir: FileExit1 - FileExit1Execute. Comprueba el código: Close(); ó Application->Terminate();
Accción Acrecade (Créditos): HelpAbout1 - HelpAbout1Execute. Comprueba el código:
AboutBox->ShowModal();

EEST N° 5 Amancio Willians 150


Prof. Abdala Achaval Pablo
Problemas y mejoras:
Nombre de archivo al guardar:
Al escoger Guardar la aplicación no nos debería solicitar el nombre si ya se ha guardado o recuperado antes:
Creamos una variable pública que guardará el nombre del archivo: String nombrearchivo = "";
Cambiamos el código del procedimiento FileSave1Execute:
void __fastcall TSDIAppForm::FileSave1Execute(TObject *Sender)
{
if (Sender==FileSave1) {
if (nombrearchivo!="")
{RichEdit1->Lines->SaveToFile(nombrearchivo);
RichEdit1->Modified = False; }
}
else
{
if (SaveDialog->Execute()){
RichEdit1->Lines->SaveToFile(SaveDialog->FileName);
nombrearchivo=SaveDialog->FileName; }
}

Añadimos el código al Abrir: nombrearchivo=OpenDialog->FileName;


Preguntar al cerrar o nuevo:
Tanto si creamos un archivo nuevo o salimos del programa, la aplicación nos debería peguntar si deseamos conser var o
guardar el documento editado. Para ello utilizamos la propiedad Modified del componente Richedit.
void __fastcall TSDIAppForm::FileNew1Execute(TObject *Sender)
{
if (RichEdit1->Modified==True) {
if (MessageDlg("¿Guardar documento anterior?",
mtInformation, TMsgDlgButtons() << mbYes << mbNo << mbCancel, 0)== mrYes)
{ FileSave1Execute(Sender);}
}
RichEdit1->Lines->Clear();
RichEdit1->Modified=False;
}
Al cerrar el formulario ocurre antes el evento FormCloseQuery donde se consulta antes de cerrar la variable CanClose:
void __fastcall TSDIAppForm::FormCloseQuery(TObject *Sender, bool &CanClose)
{
if (RichEdit1->Modified==True) {
if (MessageDlg("¿Guardar documento?", mtInformation, TMsgDlgButtons() << mbYes << mbNo << mbCancel, 0)==
mrYes) {FileSave1Execute(Sender);}
CanClose=True;}
}
Imprimir:
Añade un objeto PrintDialog1 de la paleta Dialogs.
Añade una nueva acción a la lista ActionList1 para imprimir, con las propiedades
de la imagen al que le añadiremos la siguiente acción en el evento
OnExecute:
if (PrintDialog1->Execute()){ RichEdit1->Print(nombrearchivo); }
Añade un elemento en la sección file del MainMenu y un nuevo botón en la ToolBar1 de modo que su acción Action se
vincule a: Print.
Para generar la acción Configurar Impresora, puedes crear una Standard Action del tipo: FilePrintSetup. Luego puedes
añadir el elemento en el menú para abrir el cuadro de diálogo: Configurar impresora:

EEST N° 5 Amancio Willians 151


Prof. Abdala Achaval Pablo
Ejecuta y prueba (Run). Si todo es correcto, Guarda todo (File Save All): Unit:
Editor1 - Cabezera: Editor1h - Proyecto: Editor

Otras variantes de texto:


Código común habitual llamado desde el menú para uso con aplicaciones con texto memo.
En este caso se ha llamado al memo: TextMemo
Al escoger archivo nuevo (New)
void fastcall TTextEditorForm::NewExecute(TObject *Sender)
{
// Check TMemo number of lines property
if (TextMemo->Lines->Count > 0)
{
Copyright 2010 Embarcadero Technologies, Inc.Coding responses
to user actions in the Code Editor (IDE Tutorial) 54
int userResponse = MessageDlg(
String("This will clear the current document. ")
+ "Do you want to continue?", mtInformation,
TMsgDlgButtons() << mbYes << mbNo, 0);

if (userResponse == mrYes) {
TextMemo->Clear();
currentFile = "";
}
}
}

Al abrir (Open)
void fastcall TTextEditorForm::FileOpen1Accept(TObject
*Sender)
{
// Get file name from TFileOpen component
String fileName = FileOpen1->Dialog->FileName;
if (FileExists(fileName)) {
TextMemo->Lines->LoadFromFile(fileName);
currentFile = fileName;
this->Caption = "Text Editor - " + ExtractFileName(fileName);
}
}

Al Guardar como

void fastcall TTextEditorForm::FileSaveAs1Accept(TObject

*Sender)

// Get file name from TFileSaveAs component

String fileName = FileSaveAs1->Dialog->FileName;

if (FileExists(fileName)) {

int userResponse = MessageDlg(

String( "File already exists. " ) +

"Do you want to overwrite?" , mtInformation,

TMsgDlgButtons() << mbYes << mbNo, 0);

if (userResponse == mrNo) {

EEST N° 5 Amancio Willians 152


Prof. Abdala Achaval Pablo
Al Guardar (Save)

void fastcall TTextEditorForm::SaveExecute(TObject *Sender)


{
if (currentFile == "") {
this->FileSaveAs1->Execute();
}
else {
TextMemo->Lines->SaveToFile(currentFile);
}
}
Al escoger Fuente de letra

void fastcall TTextEditorForm::FontEdit1Accept(TObject


*Sender)
{
// Set TMemo font property
TextMemo->Font = FontEdit1->Dialog->Font;
}
Al ajustar

void fastcall TTextEditorForm::WordWrapExecute(TObject


*Sender)
{
// Toggle the word wrapping state.
TextMemo->WordWrap = !TextMemo->WordWrap;
WordWrap->Checked = TextMemo->WordWrap;
if (TextMemo->WordWrap == True) {
// Only vertical scrollbars are needed when word wrapping is set.
TextMemo->ScrollBars = ssVertical;
}
else {
TextMemo->ScrollBars = ssBoth;
}
}
Al bajar mouse en el texto info en la barra de estado

void fastcall TTextEditorForm::TextMemoMouseDown(TObject


*Sender,
TMouseButton Button, TShiftState Shift, int X, int Y)
{
TextStatus->Panels->Items[ 0]->Text =
"L: " + String (TextMemo->CaretPos.y + 1);
TextStatus->Panels->Items[ 1]->Text =
"C: " + String (TextMemo->CaretPos.x + 1);
TextStatus->Panels->Items[ 2]->Text =
"Lines: " + IntToStr (TextMemo->Lines->Count);
}
Al bajar mouse o hacer clic en el texto info en la barra de estado

void fastcall TTextEditorForm::TextMemoMouseDown(TObject

*Sender,

TMouseButton Button, TShiftState Shift, int X, int Y)

TextStatus->Panels->Items[ 0]->Text =

"L: " + String (TextMemo->CaretPos.y + 1);

TextStatus->Panels->Items[ 1]->Text =

"C: " + String (TextMemo->CaretPos.x + 1);

TextStatus->Panels->Items[ 2]->Text =
EEST N° 5 Amancio Willians 153
Prof. Abdala
"Lines: Achaval
" + IntToStr Pablo
(TextMemo->Lines->Count);
Juego de TATETI (modo visual)
Diseño:
Iniciamos nuevo proyecto: File – New – VCL Forms application C++
De la paleta Adicional, añadimos una rejilla StrinGrid.
Cambiamos sus propiedades:
Name: Tablero
ColCount t RowCount: 3
FixedCol y FixedRow: 0
ScrollBars: None
DefaultColWith y DefaultColHeight:50

De la Paleta Stardard, añadimos un componente tButton


y cambiamos sus propiedades:
Name: Inicia
Caption: Iniciar

Código:
Evaluar Movimiento del jugador: Pulsamos doble clic en el evento OnSelectCell del tablero para activar el procedure:
TableroSelectCell(TObject *Sender, int ACol, int ARow, bool &CanSelect)

- El tablero es una rejilla (grid) que empieza a {


int f,c;
contar desde cero primero la columna y luego la
fila. Así que intercambiamos nuestras variables f=ACol; //-> número de columna recogido por parámetro del procedure
f y c de fila y columna por las Arow y Acol, que c=ARow; //-> número de fila -> se intercambian por columnas
nos devuelve el procedure, por simplicidad.
if (Tablero->Cells[f][c] == ESP)
- El usuario hace clic sobre una celda de la grid {
que comparamos con ESP para ver si está vacía. Tablero->Cells[f][c]='X';
}
En caso contrario, informamos que reintente. else
{
ShowMessage(String("No vale, intenta de nuevo"));
}
}

Iniciar el Tablero: En el Form1 pulsa doble click sobre el evento void fastcall TForm1::IniciaClick(TObject *Sender)
del Button Inicia para descadenar la función: IniciaClick {
Aquí rellenamos el tablero de espacios en blanco para luego poder int i,j;
comparar con algo. Para ello utilizamos dos contadores para for (i = 0; i < 3; i++) {
incrementar fila y columna en la rejilla (grid) del tablero. for (j = 0; j < 3; j++) {
Tablero->Cells[i][j]=ESP;
Añade, al principio del código , la directiva:
}
#define ESP ' ' //-> ESPACIO en blanco }
}

Sobre el Form1 activa (doble clic) el evento Onshow: void fastcall TForm1::FormShow(TObject *Sender)
Este evento se desencadena al mostrarse el formulario, por lo {
tanto, llamamos aquí también a la función IniciaClick para que IniciaClick(Sender);
ya se nos prepare el tablero al iniciarse la aplicación: → }

Primera prueba de ejecución:

EEST N° 5 Amancio Willians 154


Prof. Abdala Achaval Pablo
Guarda la unidad y el proyecto con los nombres: tresenraya1.cpp y tresenraya.cbproj
Para evitar cuelgues del programa, ejecuta primero con debug, pulsando en Run o F9.
Programa completo:
En el archivo de cabecera tresenraya.h se han declarado las funciones automáticas, pero deberemos declaran
nosotros algunas manualmente:
void fastcall TableroSelectCell(TObject *Sender, int ACol, int ARow, bool &CanSelect);
void fastcall IniciaClick(TObject *Sender);
void fastcall FormShow(TObject *Sender);
char fastcall Comprobar(char letra); -> Procedimiento/función manual
char fastcall Obtener_movimiento_computadora(); -> Procedimiento/función manual

En el código tresenraya1.cpp, escribiremos lo siguiente:


#include <vcl.h> Tablero->Cells[i][j]=ESP;
#pragma hdrstop }
#include "tresenraya1.h" }
//--------------------------------------------------------------------------- }
#pragma package(smart_init)
#pragma resource "*.dfm" //---------------------------------------------------------------------------
#define ESP ' ' //-> ESPACIO en blanco
TForm1 *Form1; void fastcall TForm1::FormShow(TObject *Sender)
//--------------------------------------------------------------------------- {
fastcall TForm1::TForm1(TComponent* Owner) IniciaClick(Sender);
: TForm(Owner) }
{ //---------------------------------------------------------------------------
} char fastcall TForm1::Comprobar(char letra)
//--------------------------------------------------------------------------- {
int t;
void fastcall TForm1::TableroSelectCell(TObject *Sender, int /* comprobar filas */
ACol, int ARow, for (t = 0; t < 3; t++)
bool &CanSelect) if (Tablero->Cells[t][0] == Tablero->Cells[t][1] && Tablero-
{ >Cells[t][1] == Tablero->Cells[t][2]
int f,c; && Tablero->Cells[t][2]==letra ) return letra;
char ganar = ESP; /* comprobar columnas */
for (t = 0; t < 3; t++)
f=ACol; //-> número de columna recogido por parámetro if (Tablero->Cells[0][t] == Tablero->Cells[1][t] && Tablero-
c=ARow; //-> número de fila -> se intercambian por columnas >Cells[1][t] == Tablero->Cells[2][t]
&& Tablero->Cells[2][t]==letra ) return letra;
if (Tablero->Cells[f][c] == ESP) /* comprobar diagonal principal */
{ if (Tablero->Cells[0][0] == Tablero->Cells[1][1] && Tablero-
Tablero->Cells[f][c]='X'; >Cells[1][1] == Tablero->Cells[2][2]
ganar = Comprobar('X'); && Tablero->Cells[2][2]==letra ) return letra;
if (ganar=='X') { /* comprobar diagonal inversa */
ShowMessage(String("Has ganado")); if (Tablero->Cells[0][2] == Tablero->Cells[1][1] && Tablero-
} >Cells[1][1] == Tablero->Cells[2][0]
else { && Tablero->Cells[2][0]==letra ) return letra;
Obtener_movimiento_computadora(); }
ganar = Comprobar('O');
if (ganar=='O') //---------------------------------------------------------------------------
{
ShowMessage(String("Yo he ganado")); char fastcall TForm1::Obtener_movimiento_computadora()
} {
} int encontrado = 0;
} int i, j;
else for (i = 0; ! encontrado && i < 3; i++)
{ for (j = 0; ! encontrado && j < 3; j++)
ShowMessage(String("No vale, intenta de nuevo")); if (Tablero->Cells[i][j] == ESP)
} encontrado = 1;
} if (encontrado) Tablero->Cells[i-1][j-1] = 'O';
//--------------------------------------------------------------------------- else
{
void fastcall TForm1::IniciaClick(TObject *Sender) ShowMessage(String("Tablero completo"));
{ // exit (0);
int i,j; }
for (i = 0; i < 3; i++) { }
for (j = 0; j < 3; j++) {

EEST N° 5 Amancio Willians 155


Prof. Abdala Achaval Pablo
Ejemplo Labels.
El siguiente ejemplo muestra un formulario, con dos botones y cinco etiquetas, que ha de simular un juego de dados, al
pulsar sobre el botón se ha de realizar una tirada de los dados de forma aleatorio, y si se pulsa sobre cualquiera de las
etiquetas se ha de generar una nueva tirada sobre la etiqueta que se haya pulsado. Para realizar esta última acción
vamos a ver como se programan los eventos compartidos.
El formulario ha de tener el siguiente aspecto:

A continuación definimos el primer evento


que
se desea programar, siendo este el Clic del botón “Jugador 1”, el cual ha de realizar una jugada completa de los dados,
es
decir al realizar el clic sobre el botón los caption de las etiquetas se han de modificar para que reflejen un numero
aleatorio entre 1 y 6.
Para programar el evento se ha de seleccionar en primer lugar el control sobre el cual queremos actuar, siendo en esta
ocasión el botón, seguidamente en el panel de propiedades y eventos, pulsamos sobre la pestaña de eventos y
realizamos un doble clic sobre la casilla en blanco situada a la derecha del evento OnClick del botón.
Nos aparece la función del evento onclick del botón y programamos las siguientes líneas de
código.
Código Fuente: Botón1 -
Jugador 1
void fastcall TForm1::Button1Click(TObject
*Sender)
{
// establecemos valores aleatorios entre 1 y 6 para las etiquetas utilizando la funcion
rand,
// la cual permite generar números aleatorios. y la funcion randomize, la cual genera la
semilla
// para que los numeros aleatorios no sigan una
secuencia. randomize();
Label1->Caption =
(rand()%6)+1 ; Label2-
>Caption = (rand()%6)+1 ;
Label3->Caption =
(rand()%6)+1 ; Label4-
>Caption = (rand()%6)+1 ;
Label5->Caption =
(rand()%6)+1 ;
}
A Continuación programamos el evento onClick del botón Salir, el cual ha de finalizar la ejecución del programa. El
código correspondiente al evento será el siguiente.
Código fuente: Botón 2 -
Salir
void fastcall TForm1::Button2Click(TObject *Sender)

EEST N° 5 Amancio Willians 156


Prof. Abdala Achaval Pablo
{
Form1->Close(); // finaliza la ejecución del
programa
}

Una vez programados los dos eventos anteriores, vamos a definir un evento común para las etiquetas, de forma que
al realizar un clic sobre la misma, se ha de generar una tirada aleatoria. Para realizar este proceso programamos el
evento onClick de la primera etiqueta.
Para posteriormente poder asociar el evento a las otras etiquetas, el evento que se está programando ha de capturar
el objeto sobre el cual se ha hecho clic y para ello si nos fijamos en el código observamos que la función recibe un
objeto denominado “Sender”, el cual es una referencia al objeto sobre el que se ha realizado la acción.
Para poder capturar el objeto y aplicar la programación, se ha de realizar la interpretación del objeto indicando que es
una etiqueta. Para aplicar esta interpretación se ha de realizar un “casting” del objeto con la orden dynamic_cast, una
vez realizada la conversión se puede interactuar con las propiedades del objeto. El código que se ha de teclear en la
función del evento es la siguiente:

Código fuente
void fastcall TForm1::Label1Click(TObject *Sender) Código Fuente unit1.cpp
{ #include <vcl.h>
// al hacer clic en la etiqueta se ha de volver a generar un numero TLabel *Label2;
// aleatorio para el dado seleccionado. TLabel *Label3;
// Para no tener que programar el evento para todas las TLabel *Label4;
etiquetas TLabel *Label5;
// utilizaremos el objeto Sender el cual almacena el objeto sobre TButton
// el que se ha realizado la acción. *Button2;
// para poder actual sobre el objeto realizamos una conversion o void fastcall Button1Click(TObject *Sender);
// casting sobre el objeto sender, al cual se le realiza una void fastcall Label1Click(TObject *Sender);
// conversion dinamica utilizando la orden dynamic_cast, a la cual void fastcall Button2Click(TObject
// se le indica el tipo de objeto sobre el cual realizar la conversion *Sender); private: // User declarations
// seguidamente se especifica el objeto recibido sender public: // User declarations
randomize(); fastcall TForm1(TComponent* Owner);
dynamic_cast <TLabel *>(Sender)->Caption = };
(rand()%6)+1; //---------------------------------------------------------------------------
} extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
#endif
Una vez finalizada la programación de los eventos
correspondientes, al ejecutar el programa se ha de
visualizar un formulario similar al que se muestra a
continuación.

El código completo del programa es el siguiente:


El archivo encabezado: unit1.h
#ifndef Unit1H
#define Unit1H
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
published: // IDE-managed Components
TLabel *Label1;
TButton *Button1;

EEST N° 5 Amancio Willians 157


Prof. Abdala Achaval Pablo
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
void fastcall TForm1::Button1Click(TObject *Sender)
{
// establecemos valores aleatorios entre 1 y 6 para las
etiquetas
// utilizando la funcion rand, la cual permite generar numeros
// aleatorios. y la funcion randomize, la cual genera la semilla
// para que los numeros aleatorios no sigan una secuencia.
randomize();
Label1->Caption = (rand()%6)+1 ;
Label2->Caption = (rand()%6)+1 ;
Label3->Caption = (rand()%6)+1 ;
Label4->Caption = (rand()%6)+1 ;
Label5->Caption = (rand()%6)+1 ;
}
//---------------------------------------------------------------------------
void fastcall TForm1::Label1Click(TObject *Sender)
{
// al hacer clic en la etiqueta se ha de volver a generar un
numero
// aleatorio para el dado seleccionado.
// Para no tener que programar el evento para todas las
etiquetas
// utilizaremos el objeto Sender el cual almacena el objeto
sobre
// el que se ha realizado la acción.
// para poder actual sobre el objeto realizamos una conversion
o
// casting sobre el objeto sender, al cual se le realiza una
// conversion dinamica utilizando la orden dynamic_cast, a la
cual
// se le indica el tipo de objeto sobre el cual realizar la
conversion
// seguidamente se especifica el objeto recibido sender y al
haber
// realizado la conversion se puede acceder a las propiedades
del objeto
randomize();
dynamic_cast <TLabel *>(Sender)->Caption = (rand()%6)+1;
}
//---------------------------------------------------------------------------
void fastcall TForm1::Button2Click(TObject *Sender)
{
// finaliza la ejecución del programa
Form1->Close();
}

EEST N° 5 Amancio Willians 158


Prof. Abdala Achaval Pablo
Acceso password con base de datos por FireDAC
Acceso sin base de datos:
Añadir los objetos al formulario:
Label1Caption: Usuario
Label2 Clave o Password
Edit1 se llamará EditUsuario
Edit2 se llamará EditClave y su PaswordChar será *
Button1 Caption: Aceptar

Pulsar doble clic en el botón Button1 (Aceptar) y añadir el siguiente código:


if (EditUsuario->Text=="admin")
{
if (EditClave->Text=="1234") ShowMessage("Correcto");
else ShowMessage("Clave incorrecta");
}
Else ShowMessage("Nombre de usuario incorrecto");
}

Acceso con base de datos Acces desde FireDAC


1º -Accede a Microsoft Access y escoge: Nueva - Base de datos en Blanco.
- Crea la base de datos llamada Acceso
- Pulsa en Diseño para crear la tabla Acceso con los campos de la imagen y
que contenga los campos de texto: Usuario y Clave de ancho 20.
Guardar/publicar la base de datos en la carpeta del proyecto llamada Acceso.mdb en formato Access 2000
- Cierra y guarda la tabla de Usuarios.
- Rellena al menos 3 usuarios y abandona Access al finalizar

2º Ampliar el formulario anterior con los


componentes de la figura y especificar:
Panel1->Visible=False
Dbgrid1->DataSource = Datasource1
DNavigator1->DataSource = Datasource1
DataSource1->DataSet=Table1
Table1->Concction=FDconection1
FDConection1-> Params->
Database=acceso.mdb
3º Añadir el código al evento Click del Button1:
Table1->IndexFieldNames = "Usuario"; //indexar la tabla por el campo Usuario
Table1->SetKey(); //inicia la indexación
if (Table1->Locate("Usuario",EditUsuario->Text)==True) //Localiza el dato en el campo Usuario
{
if (EditClave->Text != TableClave->Value) ShowMessage("Clave INcorrecta");
else
{
Label3->Caption="Sesión iniciada por usuario "+TableUsuario->Value;
Panel1->Visible=True;
}}
else
{
Label3->Caption="Usuario no registrado";
ShowMessage(Label3->Caption);
}

EEST N° 5 Amancio Willians 159


Prof. Abdala Achaval Pablo
Acceso a taboas utilizando ADO
ADO (ActiveX Data Objects), es el modo que ofrece Microsoft para el acceso a datos desde Windows.
Primero vamos a crear una tabla en Access en formato mdb:
- Accede a Microsoft Access y escoge: Nueva - Base de datos en Blanco.
- Escoge Crear en la carpeta: …Documents\RAD Studio\Projects\C++builder\Lista
- Escoge el formato de Access 200-2003: Usuarios.mdb

- Pulsa en Diseño para crear la tabla de Usuarios con los campos de la imagen.
- El tipo será numérico entero con valor predeterminado 0.
- Cierra y guarda la tabla de Usuarios.
- Rellena al menos 3 usuarios y abandona Access al finalizar

Accede a RAD Studio y crea una nueva aplicación VCL escogiendo del menú:
File - New – VCL Form Applicaton C++ Builder.
Desde inspector de objetos, cambia la propiedad del formulario principal Caption por lista
Guarda (File Save As) en una carpeta nueva llamada Lista, Guarda el archivo fuente como Lista1.cpp. El archivo
cabezera: Listah.h y el proyecto (File | Save Project As) como: Lista.bpr. o .cbproj
Poner icono: Para asignar un icono: (Project - Options Application). Puls: Load Icon… - Seleccionar un icono.
Temas en XE: Escoge (Project - Options - Application) - Appearance. Escoge: Rubi Graphite como el tema y pulsa Ok

Componentes de datos en el formulario principal:


En la paleta DbGO. Añadir un componente ADOtable y un ADOConection por si necesitáramos más tablas.
En la propiedad del ADOConection1 escoger: ConectionString - Build…

En la tabla ADOTable1, asigna las propiedades: Conection a el


ADOConection1, su TableName: Usuarios y su propiedad Name:
TableUsuarios
Pulsa doble clic sobre tabla ADO TableUsuarios y escoge del
menú contextual: añadir All fileds.
De la paleta DataAccess, añade un Datasource. Cambia sus
propiedades Name: DSUsuarios y Dataset :TableUsuarios

Componentes de diseño
De la paleta Win 32 añade un ToolBar y un StatusBar.
De la paleta DataControls, añade un DBGrid con su propiedad Align al cliente y un DBNavigator sobre la
toolBar1
En ambos componentes le asignamos su propiedad Datasource a

EEST N° 5 Amancio Willians 160


Prof. Abdala Achaval Pablo
DSUsuarios.
Sobre el componente DbGrid1 pulsa doble click para abrir el
editor de columnas y añadir todos los campos.
Activa la propiedad de la TableUsuarios a True para ver los datos
en la tabla.

Ejecuta y prueba (Run). Si todo es correcto, Guarda todo (File Save All):
Añadir botón para filtrar usuarios:
void fastcall TVentanaAgenda::FiltrarClick(TObject *Sender)
Este botón filtrará la lista de usuarios para que sólo se {
vean los usuarios de tipo 0 if (Filtrar->Down==True) {
Filtrar->Down=False ;
TableUsuarios->Filtered=False;

}
else
{
Filtrar->Down=True;
TableUsuarios->Filter="tipo=0";
TableUsuarios->Filtered=True;
}
}

Crear ventana de acceso autenticación de usuario:


Continuando con el ejercicio anterior:
Para crear la ventana de acceso, disponemos de dos métodos:
Utilizar una plantilla o formulario predefinido llamado PasswordDialog o crear un
nuevo formulario en blanco y añadir dos edits.
Para crear la ventana de acceso, escoge desde la plantilla:
File – New – Other: C++ Builder files: PasswordDialog.
Se mostrará una ventana de acceso a la que le añadiremos (copiando y pegando)
las variaciones de la figura.
Añade el código al botón cancelar: Application->Terminate();
Para incluir la UNIDAD (Unit) de la otra ventana, escoger del menú: File - Use Unit,
Añadirá al código: #include "PassWord.h" ver que al final este seleccionada la
opcion header

Luego añadir al evento OnShow de nuestro formulario principal (no OnCreate): PasswordDlg->ShowModal();

En el botón OK de la ventana Password:


void fastcall TVentanaClave::Button1Click(TObject *Sender)
{
if (EditUsuario->Text!=Dm->TableAjustesUser->Value) //Usuario=usuario
{
ShowMessage("El usuario es incorrecto");
if (EditClave->Text!=Dm->TableAjustesPassword->Value) //Contraseña=contraseña
{
ShowMessage("La contraseña es incorrecta");
}
}
else
{
VentanaClave->Close();
}
}

EEST N° 5 Amancio Willians 161


Prof. Abdala Achaval Pablo
Acceso a base de datos SQlite desde una aplicación móvil. Lista de tareas.
RAD Studio dispone de una aplicación de ejemplo en la carpeta:
Samples. Puedes enlazar el listbox con el campo visualmnete desde el
diseño visual liveBindigs:

void fastcall TSQLiteForm::FormCreate(TObject *Sender)


{
try {
TaskList->Connected = true; SQLDataSetTask-
>Active = true; LinkFillControlToField1-
>BindList->FillList();
}
catch (Exception &e) {
ShowMessage(e.Message);
}
}// -------------------------------------------------------------------
--------

void fastcall TSQLiteForm::btnAddClick(TObject *Sender) {


String TaskName;
try {
if ((InputQuery("Entre tarea", "Tareas", TaskName)) &&
(!(Trim(TaskName) == ""))) {
SQLQueryInsert->ParamByName("TaskName")->AsString =
TaskName;
SQLQueryInsert->ExecSQL(); SQLDataSetTask-
>Refresh(); LinkFillControlToField1->BindList-
>FillList();
}

EEST N° 5 Amancio Willians 162


Prof. Abdala Achaval Pablo
}
catch (Exception &e) { ShowMessage(e.Message);
}
}// ---------------------------------------------------------------------------

void fastcall TSQLiteForm::btnDeleteClick(TObject *Sender)


{
String TaskName = ListBox1->Selected->Text;
try {
SQLQueryDelete->ParamByName("TaskName")-
>AsString = TaskName; SQLQueryDelete-
>ExecSQL();
SQLDataSetTask->Refresh();
LinkFillControlToField1-
>BindList->FillList();
if ((ListBox1->Selected) && (ListBox1->Count > 0))
// Select last item
ListBox1->ItemIndex = ListBox1->Count - 1;
}
catch (Exception &e) { ShowMessage(e.Message);
}
}// ---------------------------------------------------------------------------

void fastcall TSQLiteForm::TaskListBeforeConnect(TObject *Sender)


{
#if defined(TARGET_OS_IPHONE) || defined(TARGET_IPHONE_SIMULATOR) ||
defined(__ANDROID__) TaskList->Params->Values["Database"] =
IncludeTrailingPathDelimiter(
System::Ioutils::TPath::GetDocumentsPath()) + "tasks.s3db";
#else
TaskList->Params->Values["Database"] = "tasks.s3db";
#endif
}//---------------------------------------------------------------------------

void fastcall TSQLiteForm::TaskListAfterConnect(TObject *Sender)


{
TaskList->ExecuteDirect("CREATE TABLE IF NOT EXISTS Task (TaskName TEXT NOT NULL)");
}
//---------------------------------------------------------------------------

En el string del SQLQueryInsert: insert into task (TaskName) values (:TaskName)


En el string del SQLQueryDelete: delete from task where TaskName = (:TaskName)

EJERCICIO DE BASE DE DATOS CON C++ Builder – Control


bancario de ahorros
Creación de la base de datos y las
tablas con MySQL
Creación de la base de datos

1. Una vez instalado Xampp o Wampp, ejecuta


el acceso directo al panel de control para
comprobar que tienes activado los servicios
Apache y MySQL. En caso contrario actívalos
pulsando el botón Start.

2. Ejecuta tu navegador
web (Chrome, Explorer,
EEST N° 5 Amancio Willians 163
Prof. Abdala Achaval Pablo
Mozilla…) y escribe en
el cuadro de la
dirección: localhost
Accederás a la página de presentación de Xampp.
Localhost equivale a usar
nuestra propia máquina local
como servidor de nuestra
página web. Es decir, emula la
dirección de nuestra web
desde nuestro ordenador.
3. En el panel de navegación
izquierdo de la página, pulsa
sobre: PhpMyAdmin.
Otra manera de acceder, es
escribir directamente, la
dirección:
localhost/phpmyadmin
Nota: la carpeta virtual localhost quedará localizado
normalmente en: C:\xampp\htdocs
4. Pulsa en Base de datos.
Luego escribe en el cuadro de
Crear base de datos el
nombre: Bancos. Escoge un
cotejamiento para el juego de
caracteres tipo Unicode
utf8_spanish o similar, para
evitar luego problemas
con los acentos y la ñ, como la imagen y pulsa el botón
Crear.

La base de datos Bancos contendrá tres tablas: una para las libretas de ahorros, con los
datos del titular. Otra tabla servirá para las operaciones en las libretas y la tercera tabla
contendrá los apuntes realizados en todas las libretas, asociando cada apunte con su
libreta mediante una relación entre campos.

Escoge Crear Tabla con los siguientes campos:

Saldo Int Saldo en el momento de la


operación

Para facilitar la verificación de las reglas de consistencia observa que hemos añadido los
siguientes campos redundantes al esquema:
Tabla Columna Significado
Libretas Apuntes Número de apuntes en la libreta
Saldo Saldo acumulado
Fecha Fecha del último apunte
Apuntes Saldo Saldo en el momento de la operación

Crear la aplicación:
Elije del menú principal: File New VCL form Application.
Preparar el driver mysql:
Copiar todos los archivos *.dll de la carpeta xampp/mysql/lib
a la carpeta de C:\Program Files (x86)\Embarcadero\RAD Studio\XX\bin

EEST N° 5 Amancio Willians 164


Prof. Abdala Achaval Pablo
Tabla Columna Tipo Significado
Libretas Codigo Int - Primary Key Número que identifica a la libreta

Titular VarChar(35) El titular de la libreta


Descripcion VarChar(35) Descripción de la libreta
Saldo Int Redundante
Apuntes
Fecha Int Redundante
Codigo datetime
Redundante
Descripcion Int - Primary Key
Ingreso Un código numérico de operación
Libreta VarChar(30)
Operaciones Char La descripción de la operación
Numero
Importe
Fecha Int El importe de la operación

El módulo de datos.
Crea un formulario: New Other C++ Builder files- Datamodule. Llámalo DM. La configuración
de las conexiones dependerá del formato que se esté utilizando para los datos: InterBase, Oracle,
MS SQL Server o MySql.
Métodos de conexión a la base de datos MySql:
Método utilizando el conector dbxExpress:
Con los servicios Xampp iniciados, añadir al
formulario el componente

EEST N° 5 Amancio Willians 165


Prof. Abdala Achaval Pablo
SQLConection de la paleta dbxExpress
En sus propiedades, seleccionar el driver MySQL con
los valores de la imagen. Activar la propiedad
Conected = True.
Si no conecta es que algo va mal. En ese caso,
deberás tener la librería mysql en una carpeta
accesible por el programa: Busca el archivo:
xampp\mysql\libmysql.dll y cópialo en la carpeta Bin
de Embarcadero.

Método utilizando el conector ODBC:


En primer lugar, acceder a la página de mysql.com y en Products – Conectors, descargar
el driver ODBC para
Windows, para vuestra versión de 32 o 64 bits. Una vez descargado,
instalarlo en el equipo.
En segundo lugar, acceder a las herramientas administrativas del panel de control
de Windows y , en orígenes de datos, agregar una nueva conexión seleccionando el
controlador MySQL e introducir los valores de la imagen. Pulsa en Test para comprobar
que la conexión es satisfactoria.

Volver al IDE del programa, buscar la paleta DbGO. Añadir un componente ADOtable y un
ADOConection al formulario. Si sólo fuésemos a utilizar una tabla, podríamos añadir la
Conectionstring directamente en la AdoTable. Pero como utilizaremos tres tablas,
utilizaremos el componente ADOConection para introducir la cadena de conexión.

EEST N° 5 Amancio Willians 166


Prof. Abdala Achaval Pablo
Escoge el origen de datos de la conexión_mysql creada anteriormente: conexión_mysql
Desactiva el LoginPromt para que no nos pida el user y activar la propiedad Conected =
True.
Si no
conecta es que
algo va mal.
TablasADO:
Selecciona la ADOTable1 e Introduce las propiedades de la imagen.
Name: TbApuntes Tablename: Apuntes
Copia la tabla dos veces
cambiando los nombre y
tablas: Name: TbOperaciones
Tablename: Operaciones
Name: TbLibretas Tablename:
Libretas
Pulsa doble clic sobre cada tabla ADO y escoge del menú contextual:

De la paleta DataAccess, añade tres componentes Datasource apuntando cada


Dataset una a su respectiva tabla:
DSApuntes
dataset:
TbApuntes.
DSOperaciones
dataset:
TbOperaciones.
DSLibretas
dataset:
TbLibretas.
Relaciones:
Establecemos una relación master/detail desde la tabla de libretas hacia la tabla de apuntes

Propiedad Valor
Name tbApuntes
TableName Apuntes
MasterSource DSLibretas
La propiedad IndexFieldNames, han concatenado los campos MasterFields Codigo
Libreta y Numero, para que la tabla de detalles quede ordenada IndexFieldNames Libreta;Numero
efectivamente por el número de los apuntes.
Diseño del Form Principal:
La ventana principal será una ventana SDI, que mostrará los apuntes
correspondientes a una libreta seleccionada.
Propiedad Valor
EEST N° 5 Amancio Willians Name tbApuntes
167
Prof. Abdala Achaval Pablo
TableName Apuntes
MasterSource DSLibretas
La propiedad IndexFieldNames, han concatenado los campos
Ejercicios / Guía de Trabajos Prácticos

Trabajo Práctico 1 – Introducción al C++

Ejercicio 1.A+B
Enunciado
Este es un sencillo problema de ejemplo, adecuado para probar que todo está funcionando
bien. La consigna es la siguiente: Dados dos números enteros A y B , calcular su suma, A + B .
Entrada: La entrada, que se recibe por cin , consta de dos enteros A y B , en una única línea,
separados por un espacio.
Salida : La salida, que se debe escribir por cout, consta del entero A + B , en una única línea.
Ejemplo: Si la entrada fuera: 1 2
La salida debería ser: 3

Ejercicio 2 Identificando múltiplos de 3


Enunciado
Dado un número entero, se desea determinar si el número es múltiplo de 3 o no.
Entrada: La entrada, que se recibe por cin , consta de un único entero x
Salida: La salida, que se debe escribir por cout, constará de una única línea con el texto ES
MULTIPLO si x es múltiplo de 3, o con el texto NO ES MULTIPLO en caso de que x no sea
múltiplo de 3.
Ejemplos: Si la entrada fuera 1:
La salida deberá ser: NO ES MULTIPLO
Si en cambio la entrada fuera: 9
La salida deberá ser: ES MULTIPLO

Ejercicio 3 ¿Es bisiesto?


Enunciado:
La mayoría de los años tienen 365 días, pero algunos años se llaman bisiestos, y tienen 366
días. Dado un número de año a, se debe indicar si ese año será bisiesto o no.
Recordamos la regla de los bisiestos:
Los años múltiplos de 100 solamente son bisiestos si son también múltiplos de 400
Los demás años son bisiestos exactamente cuando son múltiplos de 4
Entrada: La entrada, que se recibe por cin, consta de un único entero a , en una única línea.
Salida : La salida, que se debe escribir a cout, consta de una palabra en una única línea: SI en
caso de que el año sea bisiesto, y NO en caso de que sea un año normal de 365 días.
Cotas: 2020 > a < 3000
Ejemplo
Si la entrada fuera: 2032
La salida deberá ser: SI
Si en cambio fuese: 2100
La salida deberá ser: NO

Ejercicio 4: Transformando la hora

EEST N° 5 Amancio Willians 168


Prof. Abdala Achaval Pablo
Enunciado: Dada una cierta hora en formato de 24 horas (mediante exactamente 5
caracteres), se debe convertir a formato AM / PM.
Por ejemplo:
23:12 se convierte en 11:12 PM
10:15 se convierte en 10:15 AM
12:15 se convierte en 12:15 PM
00:15 se convierte en 12:15 AM
Entrada: La entrada, que se recibe por cin, consta de 2 numeros , indicando una cierta hora en
formato de 24 horas. La hora dada siempre será valida: es decir, las horas estarán entre 0 y 23,
y los minutos entre 0 y 59.
Salida : La salida, que se debe escribir cout, mostrara en una sola línea la hora convertida a
formato AM/PM.
Ejemplo: Si la entrada fuera: 23 12
La salida deberá ser: 11:12 PM

Ejercicio 5: Calculo de Hora de finalización


Enunciado:
Entrada: La entrada, que se recibe por cin, consta de una primera línea con tres enteros h; m;
s, que indican respectivamente las horas, minutos y segundos de comienzo de la hora en
formato de 24 horas.
Luego de esto se recibe una segunda línea con un único entero d , la duración a sumar para la
hora de salida en segundos .
Salida
La salida, que se debe escribir con cout, debe contener exactamente una línea con tres
números enteros separados por espacios: estos deben indicar, en orden, las horas, minutos y
segundos correspondientes a la hora de suma. 0
Ejemplo: Si la entrada fuera: 12 30 50
80
La salida deberá ser: 12 32 10

Ejercicio 6: Ordenando 3 números

Enunciado: Dados tres números enteros A; B ; C , se deben escribir esos números


nuevamente en la salida, pero ordenados de menor a mayor.
Entrada: La entrada, que se recibe por cin , consta de 3 enteros A; B ; C en una misma línea,
separados por un espacio.
Salida: La salida, que se debe escribir cout, consta de 3 enteros separados en un espacio: los
mismos 3 enteros de la entrada, pero ordenados de menor a mayor.
Ejemplo: Si la entrada fuera: 2 5 3
La salida deberá ser: 2 3 5

Ejercicio 7 Mostrando un producto


Enunciado
Dados dos números de hasta 2 dígitos decimales, se debe imprimir una “cuenta" del producto
(multiplicación) de ambos. La cuenta debe estar bien alineada a derecha .
Entrada La entrada, que se recibe por cin , consta de exactamente 2 números A y B , que
deben multiplicarse.

EEST N° 5 Amancio Willians 169


Prof. Abdala Achaval Pablo
Salida: La salida, que se debe escribir a cout, mostrara el producto debidamente alineado con
un ancho de exactamente 4 caracteres (ver ejemplos).

Ejemplos: Si la entrada fuera: 12 5


La salida deberá ser:
12
x5
----
60

2. Si la entrada fuera: 10 10
La salida deberá ser:
10
x 10
----
100

3. Si la entrada fuera: 50 60
La salida deberá ser:
50
x 60
----
3000

Ejercicio 8: Pares e Impares

Enunciado: Dado un númerosentero N , calcular la suma de todos los números pares


hasta N , menos la suma de todos los impares hasta N .
Por ejemplo:
Para N = 1 sería −1

Para N = 3 sería 2 − (1 + 3)

Para N = 6 sería (2 + 4 + 6) − (1 + 3 + 5)

Entrada:La entrada, que se recibe por cin, consta de un solo entero N .


Salida: La salida, que se debe escribir a cout, consta de un solo entero con el
resultado pedido.
Cotas :1 ≤ N ≤ 1000

Ejemplo

Si la entrada fuera: 6

La salida deberı́a ser: 3

Ejercicio 9 Pedir una cantidad de dólares y pasarla a pesos (21.37), mostrando el resultado.
Ejercicio 10 Pedir una cantidad de pesos y pasarla a dólares, mostrando el resultado.
Ejercicio 11 Leer 2 variables. Intercambiar su valor y mostrarlas por pantalla.
EEST N° 5 Amancio Willians 170
Prof. Abdala Achaval Pablo
Ejercicio 12. Pedir tres números al usuario y decir cuál es el mayor.
Ejercicio 13 Dados tres números, escribirlos en orden ascendente y descendente
Ejercicio 14 Escribir un programa para convertir una medida dada en pies a sus equivalentes
en

a) Yardas; b) pulgadas; c) centímetros; d) metros. Un pie = 12 pulgadas, 1 yarda =3 pies, 1


pulgada = 2.54 cm, 1 m = 100 cm). Leer el número de pies e imprimir el número de yardas,
pies, pulgadas, centímetros y metros.

Ejercicio 15 Escribir un programa que lea la hora de un día de notación de 24 horas y la


respuesta en notación 12 horas. Por ejemplo, si la entrada es 13:45, la salida será 1:45 PM.

Ejercicio 16. .- Que imprimen los siguientes códigos

a) b) c) d)

int x = 2, y = 6, z = 4; int x = 2, y = 6, z = 4; int x = 2, y = 6; int i=4, x=5;

y = y+4*z; if(x>y || x<z) if(x<y && x==y) for(i=0; i<10; i++)

y +=x; cout<<"verdadero" ; cout<<"verdadero"; {

cout<<y; else else if(i<x) cout<<i;

cout<<"falso"; cout<<"falso"; else cout<<i-x;

Ejercicio 17 propuesto: Escribir un programa que acepte un año escrito en cifras arábigas y
visualice el año escrito en números romanos, dentro del rango 1000 a 2100.

Nota: recuerde que V =5, X=10, L=50, C=100, D=500, M= 1000.

IV= 4, XL= 40, CM=900, MCM= 1900, MCML= 1950, MCMLXXXIX= 1989

Trabajo Práctico 2- Ciclos repetitivos

Ejercicio 1. Pedir siete números al usuario.


Ejercicio 2. Pedir números hasta que nos den un cero.
Ejercicio 3 Pedir números comprendidos entre dos límites hasta acertar uno dado.
Ejercicio 4 Listar Números múltiplo de 3 y de 5 que comienzan desde el 15 hasta el 15000.
Ejercicio 5 Escribir un programa que pida 4 números y diga si están ordenados en sentido
creciente, decreciente o no están ordenados.
Ejercicio 6 Calcular la suma de los primeros 1000 múltiplos de 2.

EEST N° 5 Amancio Willians 171


Prof. Abdala Achaval Pablo
Trabajo Practico Funciones
Reescribir los ejercicios del Trabajo Práctico 1 al 15 utilizando funciones.

Ejercicio 16- Escribir un programa que permita deducir si un número N es primo,


apoyándose en una función llamada Primo.

Ejercicio 17- CasiPrimos: Un grupo de estudiantes de matemática trabaja sobre una


hipótesis de propiedades de números casi-primos. Sostienen que estos números, cuya
característica distintiva es tener muy pocos divisores, podrían ser usados como reemplazo de
números primos en algunas operaciones

Como parte del trabajo de estudio, se han repartido la tarea de encontrar estos números,
dado que resulta bastante laborioso.

Para hacerle la tarea facil al grupo, se te pide que desarrolles un programa que encuentre
todos los números dentro de un rango que no son divisibles por ningún número menor o igual
que una cota dada.

Esto es, tienes que escribir un programa que dados tres naturales a, b y c, encuentre
todos los naturales i que cumplen que a i b y además i no es divisible por ningún divisor d
mayor que 1 y menor o igual a c.

Ejemplo: Si la entrada fuera:40 50 5 -------------- La salida debería ser: 4

Ejercicio 18 -¡Piedra, Papel, Tijera!

Descripción del problema


Ana y Bartolo juegan a uno de los juegos más populares del planeta: el archifamoso “Piedra,
Papel, Tijera”. En este juego, cada uno de los jugadores elige una de tres opciones posibles:
Piedra, Papel, o Tijera. Es fundamental que ambos jugadores realicen la elección en simultáneo,
sin saber lo que eligió el rival.
El ganador del juego se determina de acuerdo a las siguientes reglas:
_ Piedra vence a Tijera (Es posible desafilar una tijera con una piedra común y corriente. Otra
buena estrategia es romper la tijera a piedrazos).
_ Tijera vence a Papel (Es muy fácil cortar papeles con una tijera).
_ Papel vence a Piedra (Bueno, a alguien le tenía que ganar, pobre papel).
_ Si ambos jugadores eligen la misma opción, el juego resulta en empate.
Las reglas anteriores permiten siempre decidir el resultado del juego.
Se te pide que escribas un programa que reciba las opciones que eligieron Ana y Bartolo, y
determine el ganador.
Se reciben en una única línea dos palabras separadas por un espacio, que indican en el siguiente
orden:
1.La opción elegida por Ana
2.La opción elegida por Bartolo
Las opciones pueden ser únicamente
“piedra” “papel” “tijera” escritas exactamente de esta manera (sin las comillas).
Datos de salida
Se debe escribir una única línea, con la palabra “Ana”si es Ana quien gana el juego, “Bartolo” si
es Bartolo quien gana, o bien “Empate” si el resultado del juego es un empate.
Nota: Toda la salida debe respetar el uso de mayúsculas y minúsculas exactamente como se
ha indicado.
Ejemplo
Si la entrada fuera:
Piedra Tijera
La salida debería ser:

EEST N° 5 Amancio Willians 172


Prof. Abdala Achaval Pablo
Ana

Trabajo Práctico Cadena de Caracteres

• Ejercicio 1

El cifrado César, también conocido como cifrado por desplazamiento, es una de lastécnicas de
codificación de textos más simples y usadas. Es un tipo de cifrado por sustitución en el que una
letra en el texto original es reemplazada por otra letra que se encuentra un número fijo de
posiciones más adelante en el alfabeto. Por ejemplo, con un desplazamiento de 3 posiciones, la
A sería sustituida por la D (situada 3 lugares a la derecha de la A ), la B sería reemplazada por
la E, etc. Se supone que el alfabeto es circular de modo que, a todos los efectos, a
continuación de la Z comienzan de nuevo las letras A, B, C, etc.

Se propone que programe una función que recibiendo como parámetros una cadena de
caracteres escrita exclusivamente en mayúsculas y el desplazamiento, devuelva el texto
codificado. Debe tener en cuenta que sólo se codifican los caracteres correspondientes a las
letras del alfabeto, el resto de caracteres (letras minúsculas, espacios en blanco, signos de
puntuación, etc) permanecerán inalterados.

Ejemplo: Si el texto a codificar es: “UN TEXTO, y algo MAS” y la clave es 1 resultará “VO
UFYUP, y algo NBT”

• Ejercicio 2

Igual que el ejercicio 1, pero esta vez las letras minúsculas se transformarán en Mayúsculas, y
se codificarán junto con el resto del texto. El resto de símbolos del texto que no sean letras
(mayúsculas o minúsculas) se eliminarán del texto codificado.

Ejemplo: Si el texto a codificar es: “UN TEXTO, y algo MAS” y la clave es 1 resultará
“VOUFYUPZBMHPNBT”

• Ejercicio 3

Desarrolle un programa que permita decodificar el siguiente texto sabiendo que se encriptó
empleando la codificación CESAR con una clave desconocida (El texto no contiene espacios ni
signos de puntuación). Se sabe que el texto decodificado contiene la palabra FELIX como parte
de su texto.

LEGREXIRDRVJLEKVOKFHLVTFEKZVEVKFURJCRJCVKIRJUVCRSVTVURIZFLEVAVDGCFVJ
TRURMVQHLVKIRSRAFWVCZODVGRXRLENYZJB

 Ejercicio 4 Mensajes secretos

EEST N° 5 Amancio Willians 173


Prof. Abdala Achaval Pablo
Descripción del problema
Un grupo de pequeños amigos suele reunirse para jugar a los espías. Como pretenden imitar a
los buenos espías, tienen sus medios para codificar mensajes. En particular, para informar a sus
colegas si sus actividades de espionaje han dado resultado o no, han ideado el siguiente
método. Los chicos tienen una hilera „base‟ de letras del alfabeto internacional. Cuando
quieren transmitir lea otro un mensaje indicando el resultado exitoso de su misión, envían por
celular una palabra que sólo puede leerse en la hilera base de izquierda a derecha. Si la misión
resultó fallida, mandan una palabra que en la hilera base sólo puede leerse al revés, es decir de
derecha a izquierda.
A veces necesitan avisar que la misión encomendada está demorada, por lo que no pueden
usar el método anterior. En este caso mandan una palabra que no puede leerse en ningún
sentido. Para ayudar a los chicos, se te pide que hagas un programa que recibiendo una palabra
y teniendo la secuencia de letras „base‟, decida si la palabra está o no, y en el primer caso en
qué dirección se pudo leer.

Datos de entrada
Se recibe un archivo mensajes.in con el siguiente formato:
Una línea conteniendo un número indicando la cantidad L de letras de la secuencia base ( 1
= L = 100 ).
Una línea conteniendo L letras del alfabeto internacional a…z separadas por blanco.
Una línea conteniendo la palabra enviada, de largo l ( 2 = l = 10 ) formada también con
letras del alfabeto internacional a…z. datos de salida
Se debe generar un archivo mensajes.out conteniendo
Si es posible leer la palabra:
o una línea que diga SI
o una línea con la dirección de lectura: I si se lee de izquierda a derecha o
D si se lee en forma inversa.

Si no es posible leer la palabra: o una línea que diga NO

EEST N° 5 Amancio Willians 174


Prof. Abdala Achaval Pablo
Ejercicio 5 Imágenes Espaciales

Un grupo de investigadores se encuentra trabajando en un centro de observación espacial,


donde toman fotografías digitales mediante un nuevo telescopio a una zona aún no explorada
del espacio, con el objetivo de determinar la presencia de nuevos planetas girando alrededor
de las estrellas que allí se encuentran.
Estas fotografías tienen la particularidad de contener muy pocos colores, por lo que cada pixel
puede ser representado mediante alguna de las siguientes letras que indica su color: „B‟, „N‟,
„R‟, „V‟, „A‟. De esta forma una imagen es directamente una secuencia de letras. Además de
contener una poca cantidad de colores, también tienen la particularidad de ser demasiado
grandes con la intención de obtener la mejor resolución posible. Por este motivo los
investigadores necesitan de un método para comprimir estas imágenes y luego poder ser
almacenadas.
Mediante un estudio determinaron que un método muy simple para comprimir estas imágenes
es buscar secuencias donde una letra este repetida de forma consecutiva, para después
almacenarse sólo una única letra junto al número de veces que se repite. Para diferenciar las
partes de la imagen que han sido comprimidas, y luego poder recuperar la imagen original sin
ningún problema, se encierran entre paréntesis tanto la letra como el valor que indica la
cantidad de repeticiones. Para lograr una verdadera compresión, se debe reemplazar una
repetición de letras siempre que esta sea mayor que 4, ya que en caso contrario no se obtiene
compresión alguna.
Se te pide que escribas un programa que, recibiendo como entrada un archivo conteniendo
una imagen sin comprimir y otra ya comprimida, genere otro archivo con la compresión de la
primera imagen y la descompresión correspondiente a la segunda imagen.
Se recibe lo siguiente

Una línea conteniendo una imagen sin comprimir, con una longitud máxima de 250 letras.
Una línea con una imagen ya comprimida, con una longitud tal,
que una vez expandida no supere las 250 letras.
Datos de salida
Se debe generar un archivo imagenes.out conteniendo:
Una línea con la compresión de la imagen obtenida de la primera línea
del archivo de entrada.
Una línea con la descompresión de la imagen de la segunda línea del archivo de entrada.
Ejemplo
Si el archivo de imagenes.in de tu programa fuera el siguiente:

NNNNNNNNBRAVBRRRRRAAAAAAAVVVVV
(N5)(A6)VBNNN(R6)
El archivo imagenes.out debería ser:
(N8)BRAVB(R5)(A7)(V5)
NNNNNAAAAAAVBNNNRRRRRR

Ejercicio 6 Cambiando las reglas del dictado

Una maestra se encuentra preparando un dictado para sus alumnos. Como desea incentivar la
participación de los niños, decidió modificar el esquema tradicional incorporando las siguientes
reglas:
• Solamente dictará las primeras P letras de la palabra.
• Los alumnos deberán completar la palabra con la menor cantidad
de letras al final para que la misma sea un palíndromo (palabra que es igual si se lee de
izquierda a derecha que de derecha a izquierda)
Por ejemplo, si la maestra dicta “hola” los alumnos deberán escribir “holaloh”. Es decir, que se
agregarán 3 letras a la palabra original.

EEST N° 5 Amancio Willians 175


Prof. Abdala Achaval Pablo
Se te pide que ayudes a la maestra a corregir escribiendo
la función dictado(palabra) que devuelva en un ENTERO la mínima cantidad de letras que
se deberán agregar al final de la palabra para que la misma sea un palíndromo.
Parámetros de la función:
palabra: una CADENA de P letras que contiene la palabra dictada por la maestra (1 = P =
1.000). Todas las letras son minúsculas en el rango [a-z]
Si se remite al evaluador la siguiente línea: hola
De aportarlo como entrada a un programa correcto deberá devolver en pantalla:
3

Ejercicio 7 Desinfectando los archivos

Los archivos de texto de una computadora han sido afectados por un nuevo virus. Este virus
daña los archivos de texto de la siguiente manera: elige dos caracteres cualesquiera, luego
recorre el texto y cada vez que encuentra dos ocurrencias consecutivas del primer carácter le
intercala el segundo carácter.
Por ejemplo si el texto original fuera aadabeaa y el virus elige como primer carácter a y
como segundo carácter b, el texto infectado será abadabeaba. Si el archivo de texto original
no contenía la secuencia aba entonces el archivo se puede desinfectar realizando el proceso
inverso. A estos archivos los denominaremos desinfectables.

Con el objeto de ayudar a desinfectar los archivos de texto de la computadora se te pide que
escribas un que conociendo el texto infectado y los dos caracteres elegidos por el virus,
realice el proceso de desinfección del mismo. Tu programa sólo recibirá archivos que sean
desinfectables.

Datos de entrada

Se recibe un archivo antivirus.in con dos líneas:


• La primera línea contiene la cantidad de caracteres del texto infectado, seguido de los dos
caracteres elegidos por el virus, separados por un espacio.
• La segunda línea contiene el texto infectado.

Se debe generar un archivo antivirus.out conteniendo dos líneas:


• La primera línea contiene la cantidad de caracteres del texto desinfectado.
• La segunda línea contiene el texto desinfectado.

Restricciones

• Tanto los caracteres que elige el virus como los caracteres del texto pueden ser cualquier
letra del alfabeto, excepto la ñ, en minúsculas y sin acentos.
• La longitud máxima del texto a desinfectar es de 255 caracteres.

Ejemplo

Si la entrada antivirus.in fuera:


14 a b
cabadeabfaeaba
la salida antivirus.out debe ser:

12
caadeabfaeaa

Ejercicio 8 Encontrando mutaciones

EEST N° 5 Amancio Willians 176


Prof. Abdala Achaval Pablo
El ADN guarda la información genética de un individuo, en cada una de las células. Puede verse
como una secuencia de bases que se representan con una de cuatro letras: A, T, C, G. De
esta forma, una cadena de ADN se traduce en una secuencia de caracteres.

Con frecuencia estas cadenas sufren mutaciones, pudiendo estas agregar una base, quitar una
base o reemplazar una base de la cadena por otra.
Debes escribir un programa que dadas dos cadenas de ADN de largo
N y M, determine la menor cantidad de mutaciones que pudo haber sufrido la primera cadena
para convertirse en la segunda cadena.
Si este número fuera mayor que K, presumiblemente no hubo una mutación de una a la otra y
en esos casos se debe escribir "Muy distintas.".

Datos de entrada

Se recibe un archivo adn.in con el siguiente formato:


• Primero una línea con los números N, M y K ( 1 = N,M = 200.000; K = 10 )
• Una línea con el la primera secuencia de ADN de largo N (letras A, C, G o T).
• Una línea con el la segunda secuencia de ADN de largo M (letras A, C, G o T).
Datos de salida
Se debe generar un archivo adn.out que contendrá una línea con el menor cantidad de
mutaciones necesarias para transformar la primer cadena en la segunda, o la frase “Muy
distintas.”

Ejemplo
Si la entrada adn.in fuera:
15 14 4
ATTCGCCCATACGCT
ATTCGGGCATACGT
La salida adn.out debe ser:
3

Ejercicio 9

EEST N° 5 Amancio Willians 177


Prof. Abdala Achaval Pablo
Ejercicio 10 NOTACIÓN POLACA INVERSA

Dada una expresión aritmética tal como la (a+b)*(c+d) se puede representar con la notación
polaca inversa de forma que cada operador va después de sus dos operandos de la forma:
ab+cd+*
Se trata de calcular una expresión dada en notación polaca inversa.
Datos de entrada:
El programa debe leer los datos de entrada del archivo NOPOIN.IN. En la primera línea figura
la expresión a evaluar. Ésta está formada por enteros del rango [–32000..32000] y por los
operadores +, -, * y /. Un espacio en blanco separa a cada operando y a cada operador. La
expresión es sintácticamente correcta.
Datos de salida:
El archivo de salida NOPOIN.OUT consistirá de una sola línea donde aparece el entero que es
el valor de la expresión evaluada.
EJEMPLO:

NOPOIN.IN NOPOIN.OUT
10 8 + 4 2 - * 36

EEST N° 5 Amancio Willians 178


Prof. Abdala Achaval Pablo
Trabajo Práctico Vectores

Ejercicio 1. Dada una secuencia de números enteros positivos, se debe determinar si la


secuencia contiene algún un numero repetido mediante un cartel: Hay repetidos o No Hay
repetidos.

Ejercicio 2. Sumando filas y columnas

Dada una matriz de números enteros positivos, de N filas y M columnas, se debe determinar la
suma de cada fila y de cada columna.

Entrada: La entrada, consta de una primera lı́nea con dos números, N y M . Luego siguen N
lı́neas, cada una con M números x, que son los números de la matriz.

Salida

La salida, debe contener exactamente dos lı́neas:

La primera lı́nea debe contener N números separados por un espacio: la suma de cada
fila, en orden de arriba hacia abajo.

La segunda lı́nea debe contener M números separados por un espacio: la suma de cada
columna, en orden de izquierda a derecha.

Cotas1 ≤ N, M, x ≤ 100

Ejemplo

Entrada Salida
4 3 9 18 9 6
2 3 4 12 14 16
5 6 7
4 3 2
1 2 3

Ejercicio 3. Escribir un programa que lea un vector A de N elementos (N es un dato entero


suministrado por el usuario). Una vez leído el vector, el programa debe permitir al usuario elegir a
través de un menú la ejecución de las siguientes opciones:

a) Volver a leer los datos del vector


b) Calcular el elemento mayor y menor del vector
c) Calcular la suma de los elementos que componen el vector (ΣA[i]=A[1]+A[2]+…+A[N])
d) Calcular el promedio de los elementos que componen el vector (ΣA[i]/N)
e) Calcular el producto de los elementos que componen el vector
f) Crear un nuevo vector que contenga los elementos del array transpuestos, es decir, B[1] contiene el
elemento A[N], B[2] contiene el elemento A[N-1], …, B[N] contiene el elemento A[1]
g) Crear un nuevo vector que contenga los elementos del vector A pero con una posición corrida, es
decir, B[1] contiene el elemento A[2], B[2] contiene el elemento A[3], …, B[N] contiene el elemento
A[1]
h) Crear un nuevo vector que contenga los elementos del vector A pero con M posiciones corridas
(siendo M<N), es decir, B[1] contiene el elemento A[M+1], B[2] contiene el elemento A[M+2], …

EEST N° 5 Amancio Willians 179


Prof. Abdala Achaval Pablo
i) Salir del programa

Ejercicio 4. Se posee una matriz de F filas y C columnas.


a.- Asignarle valores a todos sus elementos teniendo en cuenta que cada elemento a[i,j] está definido
como
si i*j es par el valor que se le asigna a la posición es i+j

si i*j es impar el valor que se le asigna a la posición es i-j.

Ejemplo: si f=2 y c=4

b.- Imprimir la matriz.

0 3 -2 5

3 4 5 6

Ejercicio 5 Ingresar una matriz A(10,8), calcular e informar la suma de sus elementos.

Ejercicio 6 Leer una matriz de F filas y C columnas. (F =C)

a.- Calcular el elemento Minimo de la matriz


b.- Calcular el promedio de cada una de las filas.
c.- Calcular el promedio de los elementos de la diagonal principal
d.- Calcular el promedio de los elementos de la diagonal secundaria.
e.- A cada elemento par de la matriz guardarlo en un vector llamado Pares.

Ejercicio 7 Entrada: Se tienen una matriz de N líneas, y M números para cada uno de estos i números,
0<i<10000.

Salida: Generar otra matriz que encuentre a qué grupo se refiere imprimiendo el número que lo
representa y el número de integrantes que tiene, deberá imprimir los grupos en orden primero el grupo
con más integrantes y por último el que menos integrantes tiene.

Utilizar recursividad en la búsqueda de los elementos integrantes.


Mostrar ambas matrices.
Ejemplo:
Entrada Salida

12233 18
11153 37
11353 53
13135 22

Ejercicio 8 Generar una matriz de NxN (N ingresada por el usuario < 100) con números aleatorios
menores a 5000. Guardar en un Vector todos los números abundantes (función recursiva) que se
encuentren en la matriz.

Número abundante: todo número natural que cumpla la condición que la suma de sus divisores
propios sea mayor que el propio número. Por ejemplo, 12 es abundante ya que sus divisores son 1, 2,
3, 4 y 6 y se cumple que 1+2+3+4+6=16, que es mayor que el propio 12.

Los primeros números abundantes son:

12, 18, 20, 24, 30, 36, 40, 42, 48, 54, 56, 60, 66, 70, 72, 78, 80, 84, 88, 90, 96, 100, 102, …

EEST N° 5 Amancio Willians 180


Prof. Abdala Achaval Pablo
Ejercicio 9 se ingresan datos a un vector de enteros de 8 elementos. escribir la función

bool BuscaVal(int v[], int val);

la cual recibirá el valor por referencia y la variable val, dicha funcion devolvera true o false si
val existe en el vector.

Ejercicio 10 se ingresan datos de 2 vectores de enteros. con el procedimiento void


Cargavec(); escribir la funcion

bool compara(int vec1, int vec2)

que indicara si la carga fue de ambos fue igual o no. mostrar ambos vectores.

Ejercicio 11 Crear un programa que imprima el 25% del total de los elementos de un vector
de 12 posiciones.

Ejercicio 12 Virus polimorfo

Para pasar desapercibidos, algunos virus permutan trozos de instrucciones aprovechando, por ejemplo,
que el orden en que se ejecutan no afecta a la finalidad del virus. Si los trozos sujetos a un orden
arbitrario son muchos, la cantidad de patrones de los cuales debiera disponer el antivirus se haría
inmanejable. Esta característica de estos virus permite llamarlos polimorfos, o sea de muchas formas.
Para detectar su presencia se han estudiado los trozos que puede conmutar y para referirse a ellos se
han numerado 1, 2,... M. La presencia de uno de estos trozos no es significativa porque programas
normales también pueden realizar acciones similares.

Para detectar estos virus se ha diseñado la siguiente estrategia. En una primera etapa se descompone el
código en trozos de ejecución independiente. Estos se numeran con un número del rango 1 a M, o con
uno distinto según sea que ese trozo coincida con una acción del virus, o no concuerde,
respectivamente. El resultado de este primer análisis es transformar el programa en una secuencia de
números enteros que lo describen en un modo abreviado.
En una segunda etapa se espera detectar la presencia de los trozos del virus en posiciones consecutivas,
aunque sea en cualquier orden. Con más precisión, se considera que el virus está localizado en la
posición p si los elementos p, p+1,..., p+M-1 de la secuencia (que describe el programa) constituyen
una permutación de los números 1 a M (1 = M = 50.000 ).
Se pide tu colaboración para esta segunda etapa de análisis, escribiendo un programa que efectúe el
trabajo de localización. Es posible que el virus tenga múltiples localizaciones. Interesa encontrarlas
todas.
Los elementos de la secuencia que describe el programa tienen sus posiciones numeradas a partir de 1.
Por ejemplo, si la primera etapa produjera 1, -1, 3, 2, 4, 1, 2, 3, 6; y el virus tuviera cuatro trozos
habría una localización en 3 y otra en 5.

Datos de entrada
Se recibe un archivo polimorfo.in con:
• Una primera línea que contiene la cantidad de números N ( 1 = N = 2.000.000) que describen los
trozos del código a examinar, seguido de la cantidad de trozos M de código que posee el virus,
separados por un espacio.
• N líneas conteniendo cada una un número entero en el rango -100.000 a
+100.000 que describe un trozo de código.
Datos de salida
Se debe generar un archivo polimorfo.out conteniendo dos líneas:
• La primera línea contiene la cantidad de localizaciones del virus.
• La segunda línea contiene dichas localizaciones, si su cantidad fuera menor o igual a 10. De ser más de
10, las primeras 5 y las últimas 5. En ambos casos separadas por espacios.
Puntuación
Una solución correcta recibirá 100 puntos.
Ejemplo
EEST N° 5 Amancio Willians 181
Prof. Abdala Achaval Pablo
Si la entrada polimorfo.in fuera:
9 4

1
-1
3
2
4
1
2
3
6

la salida polimorfo.out debe ser:


2
3 5

Ejercicio 13 MUDANZA (olimpiadas Mexico)

Una familia va a cambiar de residencia y para ello va a utilizar dos camiones de mudanza. La empresa de
mudanzas desea que todas las pertenencias de la familia se repartan equitativamente entre los dos
camiones de manera que:

 ambos transporten el mismo número de objetos,


 y el peso que carga un camión sea lo más parecido al peso que carga el otro, es decir, la
diferencia entre los pesos debe ser la mínima.

Escribir un programa que dada la lista de los pesos de las pertenencias de la familia, determine el peso
que cada camión deberá llevar para cumplir con los requerimientos de la empresa. Nota: No hay límite
para el peso que pueden cargar los camiones.

Entrada

La entrada deberá realizarse del archivo de texto mudanza.in. La primera línea contiene el número N
de pertenencias de la familia (10 ≤ N ≤ 10000, con N par). Las siguientes N líneas contienen el peso de
cada uno de los objetos representado como un entero positivo menor o igual a 60000.

Salida

En el archivo de texto mudanza.out deberá escribirse el peso que cargará cada uno de los camiones,
en cualquier orden, separados por un espacio. Ambos pesos son números enteros.

Ejemplo:

mudanza.in mudanza.out

10 15871 17689
5320
21
34
17
100
286
9870
17605
12
295

EEST N° 5 Amancio Willians 182


Prof. Abdala Achaval Pablo
Ejercicio 12

Hilera de ladrillos

Descripción del problema

Recientes hallazgos en ruinas del lejano oriente aportan datos sobre las formas que los esclavos tenían
para distraerse durante las arduas jornadas en que se construyó la célebre muralla china.

En un viejísimo manual de juego se detallan las siguientes reglas: se construye una hilera de ladrillos y se
les asigna a cada uno un número. Pero esto siempre respetando la regla del juego, que indica que un
ladrillo tiene que tener un número equivalente a la suma de sus dos ladrillos predecesores en la hilera, si
los hubiera.

Algunos ladrillos tienen número asignado y otros están vacíos. La idea es que se deben completar con
números todos los ladrillos vacíos cumpliendo la regla anteriormente mencionada.

Para completar las investigaciones, los excavadores nos han pedido escribir un programa ladrillos.cpp
que encuentre a partir de una cantidad de ladrillos y algunos casilleros una forma de completar todos los
números faltantes en los ladrillos de las hileras.

Datos de entrada

Los ladrillos vacíos los representaremos con un * (asterisco) y los números explícitos o desconocidos
de cada ladrillo serán enteros de -1.000.000.000 a +1.000.000.000.

Se recibe un archivo ladrillos.in del directorio actual, que contiene la descripción de una hilera de
ladrillos. La misma se describe por una primera línea que contiene un entero M, 1 ≤ M ≤ 45, que
representa la cantidad de ladrillos que componen la hilera.

A continuación, en una segunda línea el archivo contiene M datos, separados por blancos, detallando en
cada posición los números conocidos o espacios vacíos a completar mediante asteriscos.

Datos de salida

El programa debe generar el archivo ladrillos.out, en el directorio actual con la hilera de ladrillos
completa (con todos sus casilleros definidos, con el formato de la entrada). Los casos con los que será
probado el programa tienen solución con números enteros.

Si hubiera más de una solución cualquiera vale.

EEST N° 5 Amancio Willians 183


Prof. Abdala Achaval Pablo
Trabajo Práctico Punteros
Ejercicio 1: Punteros ¿Qué imprime?.
a)
int *punt;
int x=7;
int y=5;
punt=&x;
*punt=4;
cout<<x<<endl<<y; // ¿qué imprime este cout?
b)
int *punt;
int x=7;
int y=5;
punt=&x;
x=4;
cout<<*punt<<endl<<y; // ¿qué imprime este cout?
c)
int *punt;
int x=7;
int y=5;
punt=&x;
x=4;
punt=&y;
cout<<*punt<<endl<<x; // ¿qué imprime este cout?

d)
int *punt;
int x=7;
int y=5;
punt=&x;
*punt=3;
punt=&y;
*punt=x;
x=9;
cout<<*punt<<endl<<y; // ¿qué imprime este cout?

e)
int *punta, *puntb;
int x=7;
int y=5;
punta=&x;
*punta=3;
puntb=&y;
*puntb=x;
x=9;
cout<<*puntb<<endl<<x; // ¿qué imprime este cout?

f)

EEST N° 5 Amancio Willians 184


Prof. Abdala Achaval Pablo
int *punta, *puntb;
int x=7;
int y=5;
punta=&x;
*punta=3;
puntb=&y;
*puntb=x;
x=9;
cout<<*puntb<<endl<<*punta; // ¿qué imprime este cout?

g)
int *punta, *puntb;
int x=7;
int y=5;
punta=&x;
*punta=3;
puntb=&y;
*puntb=x;
x=9;
puntb=punta;
cout<<*puntb<<endl<<y; // ¿qué imprime este cout?
h)
int *punt,i;
int x[5]={1,2,3,4,5};
punt=x;
*punt=9;
for(i=0;i<5;i++)
cout<< x[i] <<”/”<<; // ¿qué imprime este cout?

i)
int *punt,i;
int x[5]={1,2,3,4,5};
punt=&x[0];
*punt=9;
punt[3]=7;
for(i=0;i<5;i++)
Cout<< x[i] <<”/”<<; // ¿qué imprime este cout?

j)
int *punt,i;
int x[5]={1,2,3,4,5};
punt=x;
*x=11;
*(punt+3)=9 ;
for(i=0;i<5;i++)
Cout<< x[i] <<”/”<<; // ¿qué imprime este cout?

k)
int *punt,i;
int x[5]={1,2,3,4,5};
punt=x;
EEST N° 5 Amancio Willians 185
Prof. Abdala Achaval Pablo
*(punt+2)=9;
*(x+3)=7 ;
punt[1]=11 ;
for(i=0;i<5;i++)
Cout<< *(punt+i) <<”/”<<; // ¿qué imprime este cout?
l)
int *punt,i;
int x[5]={1,2,3,4,5};
punt=x+4;
*(punt-2)=9;
punt--;
*(punt)=7 ;
punt[1]=11 ;
for(i=0;i<5;i++)
Cout<< *(punt+i) <<”/”<<; // ¿qué imprime este cout?

ll)
int *punt,i;
int x[5]={1,2,3,4,5};
punt=&x[0]+3;
*(punt-2)=9;
punt--;
*(punt)=7 ;
punt[1]=11 ;
punt=x;
for(i=0;i<5;i++)
Cout<< punt[i]<<”/”<<; // ¿qué imprime este cout?

m)
void suma_dos(int *x, int *y, int *z)
{
*x=*x+2;
*y=*y+2;
*z=*z+2;
}

int main(){
int x,y,z;
x=3;
y=10;
z=15;
suma_dos (&x, &y, &z);
Cout<< x<<”/”<< y<<”/”<< z<<; // ¿qué imprime este cout?
}
n)
void datos(int *x, float *y, char *c)
{
*x=8;
*y=4.2;
*c=‟g‟;
}
EEST N° 5 Amancio Willians 186
Prof. Abdala Achaval Pablo
int main(){
int x=9;
float y=44.6;
char c=‟a‟;
datos (&x, &y, &c);
cout<< x<<”/”<< y<<”/”<< c<<; // ¿qué imprime este cout?

}
ñ)
void datos(int *x, float *y, char *c)
{
cout<< x<<”/”<< y<<”/”<<c<<; // ¿qué imprime este cout?
*x=8;
*y=4.2;
*c=‟g‟;
}
int main(){
int x=9;
float y=44.6;
char c=‟a‟;
datos (&x, &y, &c);
Cout<< x<<”/”<< y<<”/”<<c<<; // ¿qué imprime este cout?
}
o)
void datos(int x, float y, char c)
{
Cout<< x<<”/”<< y<<”/”<<c<<; // ¿qué imprime este cout?
x=8;
y=4.2;
c=‟g‟;
}

int main( ){
int x=9;
float y=44.6;
char c=‟a‟;
datos (x, y, c);
Cout<< x<<”/”<< y<<”/”<<c<<; // ¿qué imprime este cout?
}
p)
int datos(int x, float y, char c)
{
Cout<< x<<”/”<< y<<”/”<<c<<; // ¿qué imprime este cout?
x=8;
y=4.2;
c=‟g‟;
return x;
}

int main( ){
EEST N° 5 Amancio Willians 187
Prof. Abdala Achaval Pablo
int x=9;
float y=44.6;
char c=‟a‟;
x=datos (x, y, c);
Cout<< x<<”/”<< y<<”/”<<c<<; // ¿qué imprime este cout?
}
q)
char datos(int *x, float *y, char *c)
{
Cout<< x<<”/”<< y<<”/”<<c<<; // ¿qué imprime este cout?
*x=8;
*y=4.2;
*c=‟g‟;
return „h‟ ;
}

int main( ){
int x=9;
float y=44.6;
char c=‟a‟;
c=datos (&x, &y, &c);
Cout<< x<<”/”<< y<<”/”<<c<<; // ¿qué imprime este cout?
}

r)
#include <stdio.h>

void vector (float * vp[], float v[], int lon);


void main(){
float v[5]={1,2,3,4,5};
float * vp[5]={NULL}; //vector de punteros a float
for (int i=0; i<5; i++)
{
vp[i]=&v[i];
}
vector(vp, v, 5);

void vector (float * vp[], float v[], int lon)


{
for (int i=0; i<lon; i++)
{
v[i]=*(vp[i]);

s)
#include <iostream.h>
EEST N° 5 Amancio Willians 188
Prof. Abdala Achaval Pablo
#include <stdio.h>
void inverso_array (int v[], int inv[], int & lon)
{
for(int i=0; i<lon ; i++)
{
*(inv+i)=*(v+(lon-(i+1)));
}
}

void main(){
int v[5]={2,3,4,5,6};
int inv[5]={0};
inverso_array(v, inv, 5);
for (int i=0; i<5; i++)
{
cout << *(inv+i) << " ";
}
}

t)
#include <stdio.h>
void vector (float * vp[], float v[], int lon);

void main(){
float v[5]={1,2,3,4,5};
float * vp[5]={NULL}; //vector de punteros a float
for (int i=0; i<5; i++)
{
vp[i]=&v[i];
}
vector(vp, v, 5);

void vector (float * vp[], float v[], int lon)


{
for (int i=0; i<lon; i++)
{
v[i]=*(vp[i]);

}
u)
#include <vcl.h>
#pragma hdrstop

#include <tchar.h>
#include <iostream.h>
#pragma argsused
int I(char *s);
EEST N° 5 Amancio Willians 189
Prof. Abdala Achaval Pablo
int main()
{
char *s= "Pablo Abdala Achaval";

I(s);
cout << s;
system(“pause”);
return 0;
}
//-----
int I(char *s) {
char *t= s;

while (*t)
t++;

t--;

while(s < t) {
char Temp= *s;
*s++= *t;
*t--= Temp;
}
}

Trabajo Practico Classes

1. El gobierno municipal ha realizado una encuesta, donde se han solicitado los datos más
relevantes, sobre la preferencia de los vehículos disponibles en el mercado, para determinar
cuales modelos se escogerán para la puesta en marcha de un plan denominado “FonBienes”.
Los datos registrados, para cada encuestado se refieren a: Nombre del encuestado, marca del
vehículo, modelo, monto disponible para entregar como cuota inicial y número de meses para
pagar. El gobierno desea un programa en C++, que posea las siguientes características:

a) La función constructora y destructora de la respectiva clase.

b) Almacenar los datos recopilados en un arreglo de objetos. Utilice una función miembro
pública.

c) Generar un listado por pantalla con los nombres de aquellos encuestados que hayan
seleccionado vehículos de la marca “Ford” a excepción del modelo “Sport” y que requieran un
plazo mayor a dos años para cancelar el vehículo. Utilice una función miembro pública.

EEST N° 5 Amancio Willians 190


Prof. Abdala Achaval Pablo
d) Determinar si el modelo “Spin” de la marca “Chevrolet” tiene mayor preferencia que el
modelo “Ecosport” de la marca “Ford”. Utilice una función amiga.

2. La biblioteca de la EEST N°5b desea adquirir N cantidad de libros, los cuales se


identifican mediante los siguientes datos: ISBN, Título, Editorial, Año de Publicación, Costo y
Observación. La biblioteca desea un programa en C++, que posea las siguientes características:

a) Una función amiga para cargar los datos de los atributos del objeto.

b) Una función miembro pública para validar el costo del libro (el costo debe se mayor a
400$.).

c) Una función miembro pública para asignarle al atributo “Observación” un valor con base a
la siguiente condición: Si el costo del libro es mayor a 6000 $. o la publicación del libro es
menor al año 2018, este libro no lo puede adquirir la universidad; en caso contrario el libro si
se lo puede adquirir la universidad.

d) Una función miembro pública para listar los datos de aquellos libros que la biblioteca no
puede adquirir.

e) Una función amiga para determinar el costo promedio de los libros de una determinada
editorial suministrada por el usuario.

f) La función constructora y destructora de la respectiva clase.

3. Una inmobiliaria posee el registro para cado uno de los tipos de inmuebles que administra
(casas, quintas y apartamentos) y que están actualmente disponibles con los siguientes campos:
Nombre del propietario, tipo de transacción (venta o alquiler), costo de la transacción,
características del inmueble (cantidad de habitaciones, cantidad de baños, garage), para este
último atributo hacer uso de un campo tipo estructura. Escriba un programa en C++ para:

a) Almacenar los datos de la siguiente cantidad de inmuebles: seis casas, tres quintas y
cuatro apartamentos.

b) Calcular mediante una función amiga el costo promedio de las casas en venta.

c) Listar en un archivo de texto el nombre del propietario y el costo de los apartamentos


de tres habitaciones, disponibles para alquilar. Use una función miembro pública.

4. Leer N números y almacenarlos en un arreglo de objetos a través de una función definida


por el usuario. Diseñar un programa en C++ con tres funciones amigas para determinar en
cada caso respectivamente: si el número es capicua, cantidad de divisores y el cubo del
número. Ir visualizando para cada número y en forma de columnas los resultados que retornen
las funciones amigas de la clase.

5. Leer N números y almacenarlos en un arreglo de objetos a través de una función definida


por el usuario. Diseñar un programa en C++ con tres funciones amigas para determinar en

EEST N° 5 Amancio Willians 191


Prof. Abdala Achaval Pablo
cada caso respectivamente: si el número es primo, perfecto, par o impar. Ir visualizando para
cada número y en forma de columnas los resultados que retornen las funciones amigas de la
clase.

6. En la sucursal Monolito del banco Provincia de Mar del Plata existe un gerente, tres
subgerentes y seis cajeros, cada uno de estos empleados mencionados poseen por jerarquia un
nombre de usuario y una contraseña iguales para tener acceso al sistema de transacciones u
operaciones de los clientes del banco. Diseñar un programa en C++ con menús de
operaciones para efectuar lo siguiente:

a) Use funciones miembros públicas para introducir y validar el nombre de usuario y


contraseña dependiendo del tipo de empleado seleccionado por el usuario.

b) Si la validación realizada en el punto anterior es correcta a través de funciones miembros


privadas cargar, modificar y consultar datos de los clientes desde archivos binarios. Pero
existen ciertas restricciones por cada nivel de jerarquia existente en el banco para el manejo
de las transacciones u operaciones de los clientes, estas son:

Gerente: Puede cargar, modificar y consultar datos de los clientes.

Subgerente: Solo puede cargar y consultar datos de los clientes.

Cajeros: Solo puede consultar datos de los clientes.

Los datos almacenados acerca de los clientes en el archivo son los siguientes: Nro. de cuenta,
Nro. de libreta, fecha de apertura de la cuenta (un campo de tipo estructura: dia, mes y año) y
nombre del cliente.

En otra clase independiente a los clientes manejar los datos de los empleados de los cuales se
tienen los siguientes datos privados y funciones miembros públicas: Nombre del empleado,
nombre de usuario, contraseña, tipo de empleado, sueldo y prima; cargar y listar los datos de
los empleados. Aplicar sobrecarga de funciones constructoras.

EEST N° 5 Amancio Willians 192


Prof. Abdala Achaval Pablo
EEST N° 5 Amancio Willians 193
Prof. Abdala Achaval Pablo
Bibliografía

http://wiki.oia.unsam.edu.ar/curso-cpp

https://www.geeksforgeeks.org/c-plus-plus/

http://www.cplusplus.com/doc/tutorial/

http://www.stroustrup.com/C++.html

http://ejercicioscpp.blogspot.com.ar/p/teoria.html

https://blogdelingeniero1.wordpress.com/

 Stroustrup - Bjarne - The C++ Programming Language 3rd Edition- Addison


Wesley - 2011
 Stroustrup - Programming - Principles and Practice Using C++ (Pearson,
2009).
 Herb Schildt C++ - The Complete Reference (3rd Ed).
 Grady Booch - Object-Oriented Analysis and Design With Applications, 2nd
EDITION.

EEST N° 5 Amancio Willians 194


Prof. Abdala Achaval Pablo

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