Tutorial Profr. Rogelio Cesar

212
 Tutorial de programacion, tentativament llamado: El lenguaje de programacion C++ por Rogelio Cesar Rodriguez Cervantes (c) copyright 2008-2012, por Rogelio Cesar Rodriguez Cervantes Esta version es una edicion temprana aun en desarrollo, para cualquier comentario y/o sugerencia este es mi email: [email protected] (c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 1

Transcript of Tutorial Profr. Rogelio Cesar

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 1/212

 

Tutorial de programacion, tentativament llamado:

El lenguaje de

programacion C++por

Rogelio Cesar Rodriguez Cervantes

(c) copyright 2008-2012, por Rogelio Cesar Rodriguez Cervantes

Esta version es una edicion temprana aun en desarrollo, para 

cualquier comentario y/o sugerencia este es mi email:

[email protected]

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 1

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 2/212

 

CONTENIDO

Prefacio iv

Capítulo 1 Fundamentos del lenguaje………………………….……… 1

1.1 Introducción al lenguaje y a su entorno de desarrollo……..…. 11.2 Comentarios.………….………………………….……………..… 51.3 Variables y constantes.………….………………………………. 81.4 Objetos que permiten E/S por consola.………….…………….. 151.5 Operadores…………………………………..………..………….. 171.6 Tipos de datos.……………………………….…………….…….. 21

1.6.1 Fundamentales…………………….…………………… 211.6.2 Definidos por el usuario..………….………………….. 27

1.7 Palabras reservadas…….…………………….…………………. 331.8 Expresiones………………………………………..……………… 351.9 Estructuras de control…………………….…………………….... 35

1.9.1 Asignación…………………….………………………… 361.9.2 Selección…………………….…………………..…….... 36

1.9.3 Iteración…………………….…………………………… 51Capítulo 2 Subprogramas………………………………………………... 58

2.1 Definición de un subprograma…………………….……………. 582.1.1 Estructura de un subprograma……………………..… 592.1.2 Valor de retorno…………………….………………….. 60

2.2 Declaración de un subprograma…………………….………..… 622.3 Bibliotecas o librería de subprogramas…………………….….. 632.4 Primer acercamiento a clases y objetos……………………… 672.5 Ámbito y tiempo de vida de variables…………………….……. 692.6 Argumentos y paso de parámetros…………………….………. 732.7 Sobrecarga de subprogramas…………………….……………. 772.8 Recursividad….…………….…………………..……….……….. 78

Capítulo 3 Punteros, referencias y arreglos………………………….. 823.1 Creación………………………..………………………………….. 823.2 Operaciones con punteros………………………..……………... 853.3 Referencias…………………….………….……………………… 913.4 Arreglos unidimensionales, bidimensionales y multidimensionales.. 943.5 Cadenas de caracteres…………………….……………...…….. 1063.6 Asignación dinámica de memoria…………………….………… 1163.7 Uso de clases predefinidas para arreglos……………………... 129

Capítulo 4 Clases y Objetos…………………………………………….. 1324.1 Definición de una clase…………………….……………………. 1324.2 Declaración de clases…………………….…………………..…. 1324.3 Miembros de una clase…………………….……………………. 1334.4 Ámbito referente a una clase…………………….……………… 133

4.5 Especificadores de acceso…………………….………………... 1344.6 Creación de objetos…………………….…………………..……. 1354.7 Puntero this…………………….…………………..………….….. 1384.8 Constructores y destructores...…………………..……………... 142

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 2

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 3/212

 

Capítulo 5 Herencia……………………………………………………….. 1565.1 Importancia de la herencia en la POO…………………….…… 1565.2 Jerarquía de herencia…………………….…………………..…. 156

5.2.1 Conceptos de herencia simple y múltiple…………… 1575.2.2 Principios generales de diseño de jerarquías………. 1585.2.3 Especificadores de acceso a jerarquía de clases…... 159

5.3 Definición de una clase base…………………….……………… 1605.4 Definición de una clase derivada…………………….…………. 165

5.4.1 Constructores y destructores de clases derivadas…. 1665.4.2 Conversión implícita de objetos de clase derivada a

objeto de clase base……………..…………………….. 1665.5 Herencia múltiple…………………….………………………….... 173

Capítulo 6 Polimorfismo……………………………………………...….. 1796.1 Concepto de polimorfismo…………………….………………… 1796.2 Clase base abstracta…………………….…………………..….. 1826.3 Subprogramas virtuales…………………….…………………… 1866.4 Destructores virtuales…………………….…………………..…. 190

Capítulo 7 Archivos……………………………………………………….. 1937.1 Clases de E/S Clase base abstracta…………………….……... 1937.2 Realizar entrada y salida de texto…………………….………… 1947.3 Leer y escribir archivos…………………….…………………..… 1947.4 Realizar entrada y salida binaria…………………….………….. 203

Bibliografía……………………………………………………………………. 209

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 3

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 4/212

 

Prefacio

Se intenta que cada programa de ejemplo sea una aplicación completa y

práctica en la medida que el conocimiento adquirido hasta ese punto lo permita,

sin que llegue a ser compleja. También se ha tratado de evitar en todo lo posible

el tipo de escritura compacta tradicional de los programas en C/C++ para lograr

mayor claridad en los ejemplos.

Cuando la presentación de los programas de ejemplo lo permite (no interfiere

con la explicación) siguen una notación de anteponer la(s) primera(s) letras de

los tipos de datos usados, basada un poco en la notación húngara.

Versión de C++

El material presentado aquí, sigue el estándar de programación de C++ ISO/IEC

98-14882, por lo tanto los ejemplos podrán ser compilados con cualquier

compilador que sigua el estándar ISO Internacional así como el ANSI de

Estados Unidos.

Los programas de ejemplo fueron compilados con “Visual C++ 2008 Express

Edition” en el sistema operativo Windows XP y con el compilador “GNU de C/C++” en el sistema operativo Linux.

“Que sea sencillo: lo mas sencillo posible, pero no mas”- Albert Einstein

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 4

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 5/212

 

Capitulo 1

Fundamentos del lenguaje

1.1 Introducción al lenguaje y a su entorno de

desarrollo.

El lenguaje de programación C++ fue desarrollado por Bjarne Stroustrup en los

laboratorios BELL en 1983, originalmente Stroustup lo llamo “C con clases” al

ser C++ un súper conjunto del lenguaje C; C++ trata de seguir la eficiencia, la

rapidez de ejecución y la libertad de programación de C con la inclusión de lastécnicas de programación del modelo orientado a objetos; pero a diferencia de

otros lenguaje orientados a objetos, C++ sigue el espíritu original del lenguaje C,

donde el uso de esas técnicas depende del programador, así que al igual que en

C; en C++ el programador tiene la última palabra.

Lo mejor de C++ es que permite muchas formas de codificar programas, los

paradigmas de programación más comunes y que el C++ soporta fácilmente son

(Stroustrup 1997):

1. Programación estructurada

2. Programación modular

3. Abstracción de datos

4. Programación orientada a objetos

5. Programación genérica

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 5

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 6/212

 

El lenguaje C es parte del lenguaje C++, la mayoría de las instrucciones de C

funcionan en C++, y existen muchas instrucciones equivalentes, en estos casos

se ha utilizado las instrucciones de C++ y dejado afuera las de C. Esto no quiere

decir que las del Lenguaje C no sean útiles, la capacidad de discernir cuales

utilizar en cada caso se obtendrá conforme se domine el lenguaje.

Los programas de ejemplo siguen la notación de anteponer la(s) primera(s)

letras de los tipos de datos usados, basada un poco en la notación húngara.

Para evitar complejidad innecesaria algunos programas de ejemplo no siguen tal

notación.

En C++ el entorno de desarrollo no esta ligado a un solo programa hecho por

una sola compañía como en el caso del lenguaje de programación Visual Basic

de Microsoft. Siendo C++ un lenguaje estándar, el entorno de desarrollo

depende de la selección de entre una variedad de ofertas, así como del sistema

operativo que se este utilizando. Independientemente del entorno de desarrollo

utilizado, la creación de programas usando el lenguaje C++ sigue un proceso

como se muestra en la figura de la siguiente pagina.

fig1. Diagrama del proceso de creación de un programa ejecutable usando el lenguaje C++

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 6

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 7/212

 

Editor

Un programa usado para escribir el texto del lenguaje, este texto es sin formato.

Compilador

Programa que checa que el lenguaje sea usado correctamente y lo traduce a un

lenguaje objeto cercano a lenguaje máquina.

Encadenador

Programa que toma programas compilados separadamente y los une en un

lenguaje de maquina, los deja listo para ejecutarse.

Lenguaje Maquina Instrucciones que la computadora entiende directamente.

El proceso llamado preprocesador, compilador y el de encadenador se realizan

generalmente invocando un solo programa, por ejemplo en una terminal de

Linux usando:

g++ programa.cpp 

g++ realiza los tres procesos y deja un programa ejecutable, llamado por

omisión "a.out".En el caso de Windows, en la ventana de comandos utilizando borland C++ por

ejemplo es como sigue:

bcc programa.cpp 

Dando como salida el programa ejecutable llamado por omisión igual que el de

entrada pero con la extensión “exe”, en este caso "programa.exe".

A estos programas g++ y bcc se les llama por el termino general de "compilador"

aunque realicen mas cosas que la compilación (generalmente estos programas

mandan llamar otros programas que realizan cada uno un proceso mostrado en

la figura de arriba), además estos compiladores cuentan con opciones para que

solo se ejecute uno de los procesos arriba mencionados porque en ocasiones es

útil hacerlo de esa manera.

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 7

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 8/212

 

La selección de un entorno de desarrollo para C++ depende en gran parte de las

necesidades particulares de cada programador, la plataforma de desarrollo y/o la

imposición de este por parte de un empleador, por ejemplo.

El entorno de desarrollo puede ser tan escueto como utilizar un editor de texto y

un compilador o tan basto como el uso de un entrono de desarrollo integrado,

por ejemplo Microsoft Visual C++ en el caso de Windows y Eclipse con el plugin

CDT en Windows/Linux.

fig2. Entorno integrado de desarrollo de Microsoft Visual C++ Express Edition

fig3. Entorno integrado de desarrollo de Eclipse con el plugin CDT

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 8

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 9/212

 

1.2 Comentarios

Dos diagonales seguidas indican el inicio de un comentario; las diagonales

deben estar pegadas sin espacios intermedio.

// Primer.cpp// Escribe un mensaje en pantalla

Todo lo que esta después de estos caracteres hasta el fin de la línea es

ignorado por el compilador, se utilizan para poner notas para el programador.

También se pueden utilizar los caracteres /* */ para poner comentarios, estos

son los usados por el lenguaje C, la ventaja de estos es que pueden ser

utilizados para crear bloques de varias líneas, por ejemplo los comentariosanteriores pueden ser línea por línea:

/* Primer.cpp */

/* Escribe un mensaje en pantalla */

O pueden enmarcar varias líneas:

/* Primer.cpp

Escribe un mensaje en pantalla */

Los caracteres, diagonal y asterisco deben de ir pegados.

El primer programa en C++, el siguiente ejemplo muestra un pequeño

programa, que despliega un mensaje en la pantalla, utilizando el objeto “cout”

para realizar salida a la consola.

Listado// Primer.cpp

// Escribe un mensaje en pantalla

#include <iostream>

using namespace std;

int main()

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 9

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 10/212

 

{

cout << "Este es mi primer programa en C++";

return 0;

}

Salida 

Este es mi primer programa en C++

Nota:

El C++ hace distinción entre minúsculas y mayúsculas, por ejemplo: La palabra

Main, es diferente de mAin, o main que es la que reconoce C++.

Aunque el programa de ejemplo anterior es bastante pequeño, este incluye

elementos clave que conforman la mayoría de los programas en C++.

// Primer.cpp

// Escribe un mensaje en pantalla

Es recomendado incluir como comentarios al inicio de cada programa fuente el

nombre del programa así como una breve descripción de lo que hace.

#include <iostream>

#include se utiliza para especificar la inclusión de un archivo de texto, el nombre

del archivo se pone entre los símbolos menor que y mayor que. En este caso el

nombre del archivo de texto es iostream el cual contiene definiciones para

realizar entrada y salida de datos –por ejemplo leer del teclado y desplegar en

pantalla- entre otras cosas.

 

using namespace std;

Se asocia, el “namespace std” para todo el programa e indica que el programa

va a utilizar el conjunto de variables globales definidos en el espacio de nombres

estándar.

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 10

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 11/212

 

Los espacios entre las palabras se utilizan para separar las instrucciones, las

líneas en blanco son ignoradas por el compilador y se utilizan para darle

legibilidad al código.

int main() 

main indica donde empieza la ejecución del programa, int es un tipo de datos

(esto se discute mas adelante) e indica el tipo de valor que el programa va a

regresar al proceso que lo ejecute.

 

La llave que abre indica que inicia la ejecución de un bloque de código

}

La llave que cierra termina el bloque y ambas “{“ y “}” enmarcan el código que

integra la función.

cout << "Este es mi primer programa en C++";

Imprime en la consola lo que esta entre comillas "Este es mi primer programa en

C++".

return 0;

“return” regresa el valor indicado al proceso que lo mando llamar, en este caso

un cero y probablemente al Sistema Operativo.

Nota:

Si esta usando el Sistema Operativo Windows y un IDE (Integrated DevelopmentEnvironment/Entorno de Desarrollo Integrado) como por ejemplo Visual C++ o

Dev-C++, puede detener la ejecución del programa para evitar que se cierre la

ventana de comandos (msdos), utilizando:

system("PAUSE > NUL");

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 11

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 12/212

 

De lo contrario al terminar la ejecución regrese al IDE como si no hubiera

realizado nada el programa.

Nota (continua de la página anterior):

#include <iostream>

using namespace std;

int main()

{

cout << "Este es mi primer programa en C++";

//para pasusa si se ejecuta en un IDE como dev-c++ o vc++ por ej.

  system("PAUSE > NUL");

return 0;

}

system() Es una función que permite ejecutar comandos externos. PAUSE es un

comando batch –del msdos- para detener la ejecución de un script, la sentencia:

PAUSE > NUL redireccióna la salida del comando PAUSE a nulo, -la salida de

este comando es un mensaje.

Los programas de ejemplo no incluyen tal sentencia porque un Entorno de

Desarrollo Integrado solo se utiliza cuando se esta desarrollando el programa,

cuando el programa (o programas según sea el caso) esta terminado, este se

ejecuta fuera del Entorno de Desarrollo Integrado, por lo tanto tal sentencia

dejaría de ser útil o peor, entorpecería la función del programa terminado.

1.3 Variables y constantes

Las variables son lugares de almacenamiento al cual se le asigna un nombre

para poder accesar y manipular lo que se guarda en ese lugar.

Declaración de variables

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 12

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 13/212

 

Una declaración especifica un tipo y le sigue una lista de una o más variables de

ese tipo. Todas las variables deben de ser declaradas antes de utilizarlas.

Ejemplo:

int a, b;

char c;

Al declarar una variable también se le pude asignar un valor.

Ejemplo:

int i = 0;

float x = 3.4;

Listado// variables.cpp

// Declaracion de variables

#include <iostream>

using namespace std;

int main() {

int n, c;

c = 2;n = c * c;

cout << "El cuadrado de 2 es " << n;

return 0;

}

Salida 

El cuadrado de 2 es 4

Nota:

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 13

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 14/212

 

Un programa es perfectamente legal para el compilador si se escribe en una

sola línea, por Ejemplo:

int main() { cout << "Hola"; return 0; }

Nota (continua de la página anterior):

Escribir los programas en varias líneas y con la sangría adecuada mejora la

legibilidad de los mismos, algo trivial en programas pequeños pero de de suma

importancia en programas “reales” donde el numero de líneas suman docenas si

no es que cientos (Miles en ocasiones).

Los programas de ejemplo de aquí en adelante llevan la llave que abre “{“ en la

misma línea del “main()” principalmente para ahorrar una línea de espacio y

mostrar mas líneas de código en una pantalla de edición, sin sacrificar legibilidadya que el “int main() “ indica claramente el inicio del programa (y el nombre de la

función, estructura, etc., en los ejemplos posteriores).

Ejercicios

Declare una variable para cada inciso que pueda ser usada para almacenar el

valor mencionado

a) 3.1416

b) -554

c) 30000

d) Resultado de 10 * 3

e) Resultado de 10/3

f) 'a'

g) "a"

h) "HOLA"

i) Resultado de 'a' + 'b' j) Resultado de "a" + "b"

Constantes

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 14

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 15/212

 

Son los valores fijos que el programa no puede alterar, en C++ las constantes

tienen un tipo de dato (ver tipos de datos mas adelante) por ejemplo las

constantes de carácter, las cuales se encierran entre apóstrofes.

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 15

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 16/212

 

Ejemplo:

'a', '%'

Distíngase que son diferentes:

'a' y "a"

'a' es una constante de carácter compuesta por la letra a y "a" es una cadena de

caracteres compuesta por la letra a y el carácter nulo y esta formada de dos

elementos.

"" es una cadena nula con un elemento (\0).

Ejemplo:

123L constante long

123.3 constante float

Un cero que encabeza un número significa octal

Ejemplo:

011 9 en decimal

Un cero y una equis antes significa hexadecimal.

Ejemplo:0xFF 255 en hexadecimal.

Constantes de carácter no imprimibles

Código Significado\b Retroceso\f Alimentación de hoja\n Nueva línea\r Retorno de carro\t Tabulador horizontal\” Doble comilla\’ Comilla simple\0 Nulo\\ Barra invertida\v Tabulador vertical\a Alerta

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 16

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 17/212

 

\o Constante octal\x Constante hexadecimal

Una constante de carácter no imprimible no tiene una representación gráfica

solo realiza una acción.Ejemplo:

cout << “\n”;

No imprime nada, solo brinca de línea, es como si presionáramos la tecla

ENTER/RETORNO. Los dos caracteres “\n” son interpretados como un

solo carácter.

Ejemplo: 

Para desplegar un mensaje con una parte entre comillas por ejemplo:

Referencia: “C++ Simplificado”-pagina 123, se necesita utilizar el

carácter no imprimible \”

cout << ”Referencia: \”C++ Simplificado\”-pagina 123”;

Si no se antepone la diagonal invertida a las comillas el string termina enlas segundas comillas y las terceras comillas producirían un error.

Listado

// caracter.cpp

// Formato de texto en la salida estándar

// utilizando las constantes de carácter no imprimibles

#include <iostream>

using namespace std;

int main(){

cout << "CARACTERES\t\t";

cout << "NO IMPRIMIBLES";

cout << endl << "Esta linea esta en otro renglon";

cout << "\n\n\n\n\nEsta despues de cuatro renglones";

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 17

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 18/212

 

return 0;

}

Salida CARACTERES NO IMPRIMIBLES

Esta linea esta en otro renglón

Esta despues de cuatro renglones

cout << "CARACTERES\t\t";

La secuencia de caracteres “\t”, indica imprimir un TAB, es como si se

presionara la tecla TAB.

cout << endl << "Esta linea esta en otro renglon";

La palabra “endl” después de los caracteres “<<” indica un salto de línea antes

de imprimir el mensaje. 

cout << "\n\n\n\n\nEsta despues de cuatro renglones";

El “endl” se utiliza para cambiar al siguiente renglón, pero en ocasiones es mas

practico usar el carácter no imprimible “\n”.

Ejercicio

Escriba un programa que imprima sus datos personales centrados lo más

posible en pantalla, utilizando las constantes de carácter no imprimibles.

Constantes simbólicas

#define

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 18

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 19/212

 

Mediante esta construcción al principio de un programa se puede definir un

nombre simbólico o constante simbólica como una determinada cadena de

caracteres.

Listado

// pascual.cpp

// Emulacion del PASCAL mediante el preprocesador

#include <iostream>

using namespace std;

#define PROGRAM int main()

#define BEGIN {

#define END return 0; }

#define WRITE(A) cout << A

PROGRAM

BEGIN

WRITE("Pascal en C++!!!");

END

Salida 

Pascal en C++!!!

El preprocesador remplaza todas las apariciones no entre comillas del nombre

por su cadena correspondiente.

Ejercicio

Investigue todas las palabras reservadas del preprocesador, su sintaxis y un

ejemplo de cada una.

Constantes con nombre

Para crear una constante con nombre se utiliza la palabra reservada “const ” al

declarar un objeto.

Ejemplo:

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 19

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 20/212

 

const int numero_constante = 10;

const char caracter_constante = ‘X’;

A las constantes no se les puede asignar valores después de creadas así que se

les asigna al momento de declararlas.

1.4 Objetos que permiten E/S por consola 

El lenguaje C++ cuenta con una biblioteca estándar de objetos predefinidos para

realizar diversas actividades, entre estos objetos se encuentran el "cin" y el

"cout" para realizar entrada y salida por la consola.

Objeto cout

“cout” es el nombre de un objeto que representa la salida estándar a la consola

(Console output/Salida en la consola).

Ejemplo:

cout << "Este es mi primer programa en C++";

Imprime en la salida estándar lo que esta entre comillas "Este es mi primer 

 programa en C++".

Los caracteres << son para simular una flecha la cual indica que lo que sigue va

para la salida estándar.

Un mensaje en cada línea, para controlar el cambio de línea se manda imprimir

la palabra “endl”, que es un acrónimo de end line –fin de línea-.

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 20

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 21/212

 

Listado

// control.cpp

// utilización del objeto cout con el endl

#include <iostream>

using namespace std;int main() {

cout << "Ahora vamos a controlar" << endl;

cout << "el cambio de linea ";

cout << "para dominar" << endl << "los mensajes";

cout << endl << endl << endl << "Y DESPUES EL C++...";

return 0;

}

Salida 

Ahora vamos a controlar

el cambio de linea para dominar

los mensajes

 Y DESPUES EL C++...";

cout << "Ahora vamos a controlar" << endl;

La palabra endl después de los caracteres << indica un salto de línea después

de imprimir el mensaje.

cout << "para dominar" << endl << "los mensajes";

cout << endl << endl << endl << "Y DESPUES EL C++...";

El endl se puede incluir en cualquier parte después de los caracteres << y tantas

veces como sea necesario. 

Nota:

Las siguientes líneas producen la misma salida:

cout << “Hola a todos”;

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 21

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 22/212

 

cout << “Hola” << “ a “ << “todos”;

Objeto cin

“cin” es un el nombre de un objeto que representa la entrada estándar (Console

INput/Entrada en la consola), por omisión el teclado de una computadora.Ejemplo:

cin >> fDolares

Ingresa una entrada de datos de la entrada estándar y lo almacena en la

variable fDolares.

Los caracteres >> son para simular una flecha la cual indica que lo que sigue va

de la entrada estándar hacia una variable.

El objeto “cin”, como la mayoría de los objetos cuenta con métodos (Se estudian

en el siguiente capítulo) que se pueden llamar.

Ejemplo:

cout << “Presione ENTER para continuar”;

// Ignora el ultimo ENTER leído, que puede estar en el buffer de entrada

cin.ignore(1, '\n');

cin.get(); // espera por un ENTER

El código anterior detiene la ejecución hasta que el usuario presione la tecla

ENTER.

1.5 Operadores

Lo operadores son utilizados para realizar operaciones matemáticas, lógicas y/o

de relación.

Operadores aritméticos

Operador Acción- Resta y menos unario+ Suma

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 22

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 23/212

 

* Multiplicación/ División

% Modulo de división-- Decremento en uno++ Incremento en uno+= Incremento y asignación-= Resta y asignación*= Multiplicación y

asignación/= División y asignación

Operadores ++ y --

Lo mas común al utilizar estos operadores es aplicarlos dentro de una sentencia

de una sola variable, en este caso no importa el orden del operador, ya sea en

forma prefija o pos fija actúan de la misma manera, incrementa o decrementa en

uno según sea el caso.

Ejemplo:

i++;

Es equivalente a:

i = i + 1;

Prefijo y posfijo de los operadores ++, --

Los operadores ++ y – actúan diferente dependiendo de la forma en que se

usen, prefija o postfija

Ejemplo:

n = i++;

Es equivalente a:

n = i;

i = i +1;

n = ++i;

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 23

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 24/212

 

Es equivalente a:

i = i +1;

n = i;

Al usar la forma de prefijo la variable se incrementa o decrementa antes de ser

usada; en la forma pos fijo la variable primero se usa y después se incrementa o

decrementa según sea el caso.

Listado

// mas_mas.cpp

// Desmostracion del operador unario ++

#include <iostream>

using namespace std;

int main() {

int i;

i = 10;

i++;

cout << "i = " << i;

cout << "\nSalida en posfija de i++ = " << i++;

cout << "\n\nSalida de i = " << i;

cout << "\nSalida prefija de ++i = " << ++i;

return 0;

}

Salida 

i = 11

Salida en posfija de i++ = 11

Salida de i = 12

Salida prefija de ++i = 13

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 24

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 25/212

 

Operadores relacionales

Operador Acción

> mayor que

>= mayor que o igual que< menor que

<= menor que o igual que== Igual!= no igual

Nota:

El doble signo igual == es la notación de C++ para "es igual a". Este símbolo se

distingue de la condición de igualdad del simple = empleado en las

asignaciones.

Operadores lógicos

Operador Acción

&& and|| or! not

Precedencia y orden de evaluación de operadores

Existen reglas de precedencia y orden de evaluación de operadores para

cuando estos se mezclan en una misma sentencia.

Operador Asociatividad() [] -> . Izquierda a derecha

! ~ ++ -- - * & sizeof Derecha a izquierda* / % Izquierda a derecha+ - Izquierda a derecha

<< >> Izquierda a derecha< <= > >= Izquierda a derecha

== != Izquierda a derecha& Izquierda a derecha

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 25

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 26/212

 

^ Izquierda a derecha| Izquierda a derecha

&& Izquierda a derecha|| Izquierda a derecha?: Derecha a izquierda

= += -= *= /= Izquierda a derecha, Derecha a izquierda

1.6 Tipos de datos

Los tipos de datos sirven para declarar lugares de almacenamiento durante la

ejecución del programa, dependiendo del tipo de dato utilizado es lo que

podemos almacenar.

1.6.1 Tipos de datos fundamentales

Los tipos básicos y más usados en un programa de C++ son:

Tipo Se utiliza para 

almacenar

Descripción

char caracteres Un tipo de dato específico para manejo de

caracteres de 8 bits de rango igual a -128 a

127.int enteros Tipo de dato entero con signo de 16, 32 ó

64 bits, dependiendo del compilador. En

sistemas de 16 bits su rango de valores es

de -32763 a 32762. Para sistemas de 32

bits el rango se de -2147483648 a

2147483647. En sistemas de 64 bits el

rango será de 1.7+/-308.long enteros largosfloat flotante, número con

fracción

Número real de 32 bits cuyo rango vá de

3.4+/-38. Generalmente su precisión es de

7 dígitos.

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 26

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 27/212

 

double flotante, número con

fracción

Número de 64 bits y de rango igual a 1.7+/-

308 con una precisión en general de 15

dígitos.void indica que nada o

indefinido

Nota:

Para saber exactamente cuantos bytes están disponibles para un determinado

tipo de dato en el compilador que se este usando, se puede usar la función

sizeof.

Ejemplo:

cout << sizeof(char);

Imprime el número de bytes usados por el tipo de datos char.+

Listado

// condolar.cpp

// Demuestra la declaración de variables

// así como la entrada y salida de datos

// Convierte dolares a pesos

#include <iostream>

using namespace std;

int main(){

float iPesos, fDolares;

cout << endl << "Cuantos dolares desea convertir a pesos? ";

cin >> fDolares;

iPesos = fDolares * 12.5;

cout << "Pesos = " << iPesos;

 

return 0;

}

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 27

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 28/212

 

Salida en base a la entrada de ejemplo

Cuantos dolares desea convertir a pesos? 9

Pesos = 112.5

float iPesos, fDolares;

Se declaran dos variables de tipo punto flotante, para almacenar números con

parte fraccionaria, números como 3.1416, 2.5 y 1234, este último es un número

entero pero es almacenado como 1234.00.

Nota:

También se puede declarar cada variable en una línea separada:

float iPesos;

float fDolares;

Para guardar un número entero; números sin parte faccionaria como 5, 100 y 15

pero no 3.14 seria:

int pesos;

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 28

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 29/212

 

Ejercicios

1. Modifique el programa condolar.cpp, para que pida el tipo de cambio.

2. Realice un programa que calcule el área de un triángulo.

3. Escriba un programa que calcule el área de un cuadrado.

Modificadores de tipo

Excepto para void, los tipos de datos básicos tienen varios modificadores que los

proceden. Se usa un modificador para alterar el significado de un tipo base para

encajar con las necesidades diversas mas precisamente. En otras palabras

estos modificadores de tipos combinados con los tipos de datos fundamentales

dan paso a diferentes tipos de almacenamiento.

Modificador de

Tipo

Descripción

Signed Forza al compilador a utilizar un tipo de dato con signo si

antes se declaró como de tipo unsigned.Unsigned Se aplica a los tipos de datos enlistados arriba, su efecto

es eliminar el signo a el tipo de dato aplicado, por

ejemplo, para un tipo de dato int podemos especificarunsigned int en cuyo caso el rango para el tipo de dato

int cambia de ser -2147483648 a 2147483647, por éste

nuevo rango: 0 a 4294967295.long Un número entero de 32 bits de rango igual a

-2147483648 a 2147483647.Short Un número de 16 bits de rango igual a -32763 a 32762.Volatile Específica una variable que almacena datos cuyo

contenido puede cambiar en cualquier momento sea por

la acción del programa ó como reacción de la interacción

del usuario con el programa.Auto Es lo mismo que si no se usara ningún modificadorRegister El compilador procurará almacenar la variable cualificada

de este modo en un registro de la CPU.Extern La variable se considera declarada en otro fichero. No se

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 29

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 30/212

 

le asignará dirección ni espacio de memoria.Static Cuando se invoca a una función por segunda vez se

pierden los valores que las variables locales de la función

tenían al acabar la anterior llamada. Declarando una

variable de este tipo cuando se llama por segunda vez a

la subrutina la variable static (estática) contiene el mismo

valor que al acabar la llamada anterior.

Conversiones de tipo

Cuando se mezclan constantes y variables de diferentes tipos en una expresión,

C++ las convierte en el mismo tipo. El compilador de C++ convertirá todos los

operandos al tipo del operando mas grande en una operación según la base de

esta operación.

Reglas de conversión de tipos

1. Todos los char y short int se convierten a int.

Todos los float a double

2. Para todo par de operandos, lo siguiente ocurre en secuencia:

Si uno de los operandos es long double, el otro se convierte a long double.Si uno de los operandos es double el otro se convierte a double

Si uno de los operandos es long, el otro se convierte a long.

Si uno de los operandos es unsigned, el otro se convierte a unsigned.

Después de que el compilador aplique estas reglas de conversión, cada par de

operandos será del mismo tipo, y el resultado de la operación será del tipo de los

operandos.

Ejemplo:

char c;

int i;

float f;

c = 65;

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 30

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 31/212

 

i = 10;

f = i + c;

La variable c se convierte a “int” al hacer la suma i + c, al realizar la asignación

el resultado de la suma se convierte a “flota”.

Construcción cast

Se usa para forzar la conversión explícita de tipos de datos.

Listado

// lconst.cpp

// Ejemplo de constantes literales

#include <iostream>

using namespace std;

int main(){

cout << endl << 1/2;

cout << endl << 1.0/2;

cout << endl << float(1)/2;

return 0;

}

Salida 

0

0.5

0.5

Nota:

En la última línea se usa la construcción cast para forzar la conversión explícita

del tipo de dato.

Ejercicio

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 31

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 32/212

 

Quite la construcción cast (Sustituya la línea: cout << endl << float(1)/2; por

cout << endl << 1/2;) ejecute el programa y discuta con sus compañeros la

salida del programa modificado.

1.6.2 Tipos de datos definidos por el usuario

Los tipos definidos por el usuario es la creación de un tipo de dato mediante la

combinación de los tipos de datos existentes y se definen como uniones,

enumeraciones, tipos definidos (typedef), estructuras o clases. Las estructuras y

uniones son tipos de clase (El tipo clase –class- se estudia brevemente en el

capitulo 3 y extensamente en el capitulo 4).

Uniones

Una unión es una localidad de memoria la cual es usada por dos o más

variables diferentes; generalmente de tipos diferentes. Cuando una unión es

declarada, el compilador crea una variable de la longitud de la variable mayor

definida en la unión. Solo un dato puede estar activo en un momento

determinado de la lista de datos que formen la unión.

Forma general:union etiqueta {

tipo nombre_de_variable;

.

.

.

tipo nombre_de_variable;

} variable_union;

Ejemplo:

union int_char {

int i;

char c;

};

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 32

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 33/212

 

union int_char dosv;

En la unión dosv, las 2 variables el “int” y el “char” comparten la misma localidad

de memoria, el dato “int” ocupa toda la memoria disponible y el dato “char” solo

una parte.

Para acceder a una variable de la “union” se utiliza el operador de acceso “.” o “-

>” según sea el caso (“->” para punteros, estos serán estudiados en el capitulo

3):

Ejemplo:

dosv.c = ‘x’;

fig 4. Ejemplo de la comparticion de memoria usada por la unión en una 

maquina de 16 bits.

Uniones anónimas

Las uniones anónimas son aquellas que no tienen etiqueta y no se utilizan para

nombrar un objeto.

Forma general:

union {

tipo nombre_de_variable;

.

.

.

tipo nombre_de_variable;

};

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 33

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 34/212

 

Sus miembros pueden ser accedidos directamente en el ámbito de su

declaración sin necesidad de usar ninguno de los operadores de acceso

x.y o p->y.

Listado

// union.cpp

// Ejemplo de union con etiqueta y union anonima

#include <iostream>

using namespace std;

 

int main(){

union { float f; char c; };

union int_char { int i; char c; };

int_char dos_var;

 

c = 'X';

dos_var.c = 'Y';

cout << dos_var.c << "\t" << c << endl;

return 0;

}

Salida 

 Y X

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 34

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 35/212

 

Enumeraciones

Una enumeración es un conjunto de nombres de constantes enteras las cuales

especifican todos los valores legales que debe tener un tipo de variable.

Forma General:

enum nombre {lista de enumeración} lista_variables;

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 35

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 36/212

 

Typedef

Declara identificadores que se pueden utilizar para dar nombres a tipos de datos

básicos o derivados excepto funciones. El identificador se transforma en el

equivalente sintáctico a una palabra reservada.

Forma general:

typdef nombre_tipo;

Ejemplo:

Definición de la palabra “Entero”:

typedef int Entero;

Uso:

Entero n;

Estructuras

Una estructura es un método lógico de organizar datos y funciones (ver capitulo

de funciones”). La estructura es un patrón a seguir para crear variables de tipo

estructura. Al definir una estructura se crea un tipo de dato definido por el

usuario, y este tipo sirve para crear instancias de este tipo de dato.

Se puede ver como un conjunto de una o más variables, posiblemente de tipos

diferentes, agrupadas bajo un mismo nombre. Principalmente se usa para

organizar datos y esta parte es la que se describe a continuación.

Forma general:

struct etiqueta {

tipo nombre_variable;

tipo nombre_variable;

.

.

tipo nombre_variable;

} variables_de_estructura;

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 36

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 37/212

 

Para acceder a los elementos de la estructura:

nombre_estructura.nombre_elemento

Listado// structFecha.cpp

// Estructuras

#include <iostream>

using namespace std;

// definicion de la estructura (tipo)

struct Fecha {

int dd;

int mm;

int aa;

};

int main() {

Fecha fecha; // Declaracion de una variable de tipo estructura

cout << "Numero de dia ";

cin >> fecha.dd;

cout << "Numero de mes ";

cin >> fecha.mm;

cout << "A#o ";

cin >> fecha.aa;

cout << fecha.dd << "/" << fecha.mm << "/" << fecha.aa;

return 0;

}

Salida 

Numero de dia 24

Numero de mes 12

A#o 2010

24/12/2010

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 37

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 38/212

 

struct Fecha {

int dd;

int mm;

int aa;

};

Estas líneas definen la estructura, aquí solo se crea el tipo de dato definido por

el usuario llamado Fecha.

Fecha fecha;

Se declara la variable fecha del tipo Fecha, que es del tipo de estructura definida

anteriormente.

cin >> fecha.dd;

Se ingresa desde la entrada estándar, un valor y se le asigna al elemento entero

“dd” que es parte de la variable fecha.

1.7 Palabras reservadas

Las palabras reservadas son identificadores utilizados por el lenguaje para fines

especiales, y no pueden ser utilizadas para por ejemplo nombrar variables,

clases, funciones, etc.

La siguiente tabla contiene las palabras reservadas del lenguaje divididas en las

palabras que provienen del lenguaje C, las que cambiaron su significado al

trasladarse al C++, y las exclusivas de C++.

Lenguaje C De C sobrecargadas en C++ Lenguaje C++Auto Struct andBreak Static and_eqcase Const asmchar enum bitandconst bitor

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 38

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 39/212

 

continue booldefault catchDo classdouble complelse const_castenum deleteextern dynamic_castfloat explicitfor exportgoto falseIf friendint inlinelong mutableregister namespace

return newshort notsigned not_eqsizeof operatorstatic orstruct or_eqswitch privatetypedef protectedunion publicunsigned reinterpret_cast

void static_castvolatile template

 while thisthrowtruetrytypeidtypenameusinvirtual

w_charxorxor_eq

1.8 Expresiones

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 39

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 40/212

 

“Una expresión es una secuencia de operadores y operandos que especifica un

calculo. Una expresión puede dar como resultado un valor y puede originar

efectos secundarios (efectos colaterales)” (Ellis/Stroustrup 1994)

 

Sintaxis de las expresiones C++

Las expresiones son definidas recursivamente, de forma que las subexpresiones

pueden ser anidadas sin ningún límite formal, aunque quizás el compilador

pueda reportar un error de límite de memoria si no puede compilar una

expresión muy compleja.

1.9 Estructuras de ControlLas estructuras de control determinan el flujo de ejecución de las instrucciones,

mediante estas estructuras se puede controlar en orden y las veces que se

ejecutan las instrucciones.

1.9.1 Asignación

El hecho que las expresiones sean definidas recursivamente permite porejemplo la asignación múltiple.

Ejemplo:

int x, y, z;

x = y = z = 0;

Todas las variables se inicializan a cero.

1.9.2 Selección

C++ cuenta con dos tipos de tratamiento de condiciones, para condiciones de

cierto / verdadero y para condiciones múltiples.

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 40

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 41/212

 

if-else

Permite seleccionar la ejecución de dos bloques de código mediante la

evaluación de una condición.

Forma general 1:

 if (expresión)

bloque de código;

Si la expresión es verdadera se ejecuta el bloque de código, si la

expresión es falsa no se ejecuta el bloque de código.

Forma general 2:

 if (expresión)bloque de código 1;

 else

bloque de código 2;

Si la expresión es verdadera se ejecuta el bloque de código 1, si la

expresión es falsa se ejecuta el bloque de código 2.

Donde expresión:

a) variables de tipo boolean

b) operación con operadores aritméticos, lógicos y/o relaciónales

Donde bloque de código:

a) una sola instrucción

b) {

varias instrucciones

}

Listado

// adivina.cpp

// Ejemplo if..else

// juego de adivina el numero que la computadora genera aleatoriamente

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 41

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 42/212

 

#include <iostream>

#include <ctime>

using namespace std;

int main() {

int n, pc;

srand( (unsigned)time( NULL ) );

pc = rand() % 5;

cout << "\nAdivina el numero que pienso (0-4) " << endl;

cin >> n;

if (n == pc)

cout << "Adivinaste!";

else

cout << endl << "Intenta otra vez";

 

return 0;

}

Salida en base a la entrada de ejemplo

Adivina el numero que pienso (0-4)

2

Intenta otra vez

#include <ctime>;“ctime” es para usar la función “time()” para plantar la semilla de la función

“rand()”.

srand( (unsigned)time( NULL ) );

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 42

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 43/212

 

La función “srand”, se usa para plantar la semilla de los números aleatorios

usando el tiempo regresado por la función “time()”, el “NULL” dentro de “time()”

es para que agarre el tiempo actual.

pc = rand() % 5;

“rand()”, genera el número aleatorio, el “% 5”, le dice que genere un numero en

un rango de 5 números, desde el 0 hasta el 4.

En el resto del código se lee un número de la entrada y lo compara con el

número generado en forma aleatoria, “if (n == pc)”, en caso que la evaluación

sea verdadera despliega “Adivinaste!” de lo contrario despliega “Intenta otra

vez”.

Los bloques a seleccionar mediante la condición están compuestos solo por una

línea y mediante el punto y coma el compilador sabe exactamente cual bloque

pertenece a la parte del “if” y cual a la del “else“.

Note que al final de la comprobación de la condición del “if” este no tiene un

punto y coma sino hasta el final de la sentencia:

if (n == pc)

cout << "Adivinaste!";

Igual pasa con la sentencia “else”, el punto y coma esta al finalizar la línea que

va a ejecutarse en caso de que la condición hecha en el encabezado del if  no

se cumpla:

else

cout << endl << "Intenta otra vez";

En caso de que el bloque a ejecutar al hacerse la selección se componga de

mas de una línea de código hay que indicarle al compilador donde empieza este

bloque mediante el uso de la llave que abre “{“ y también donde termina el

bloque de instrucciones utilizando la llave que cierra “}”.

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 43

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 44/212

 

Ejemplo:

if (n == pc)

{

cout << "Adivinaste!" << endl;

cout << "\t\tTienes poderes siquicos?" << endl;

}

else

{

cout << endl << "No le atinaste";

cout << endl << "\t\tIntenta otra vez";

}

Otras combinaciones pueden ser por ejemplo:

if (n == pc)

{

cout << "Adivinaste!" << endl;

cout << "\t\tAcaso tienes poderes siquicos?" << endl;

}

else

cout << endl << "Intenta otra vez";

También:

if (n == pc)

cout << "Adivinaste!" << endl;

else

{

cout << endl << "No le atinaste";

cout << endl << "\t\tIntenta otra vez";

}

Las llaves de inicio y fin de bloque se pueden usar aunque sea solo una

sentencia, por ejemplo lo siguiente es perfectamente valido:

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 44

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 45/212

 

if (n == pc)

{

cout << "Adivinaste!" << endl;

}

else

{

cout << endl << "Intenta otra vez";

}

En el siguiente fragmento de código el “else” no tiene llaves, por lo tanto el

bloque de instrucciones perteneciente al “else” es de una sola línea:

if (n == pc){

cout << "Adivinaste!" << endl;

cout << "\t\tAcaso tienes poderes siquicos?" << endl;

}

else

cout << endl << "No le atinaste";

cout << endl << "\t\tIntenta otra vez";

La ultima línea en este fragmento de código no pertenece al “else”, esta línea

siempre se ejecuta no importa si se cumple la condición del “if” o no; lo único

que tiene es la sangría y a simple vista pudiera parecer que pertenece al cuerpo

del “else”.

En el siguiente ejemplo el bloque de código perteneciente al “if” es de una sola

línea ya que no tiene llaves:

if (n == pc)

cout << "Adivinaste!" << endl;

cout << "\t\tAcaso tienes poderes siquicos?" << endl;

else

{

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 45

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 46/212

 

cout << endl << "No le atinaste";

cout << endl << "\t\tIntenta otra vez";

}

El “if” se compone realmente por:

if (n == pc)

cout << "Adivinaste!" << endl;

La línea que le sigue está fuera del “if”:

cout << "\t\tAcaso tienes poderes siquicos?" << endl;

El “else” no forma parte del “if” porque este termino con el punto y coma, por lotanto marca un error de sintaxis por el compilador ya que “else” solo puede ir

acompañado de un “if”.

else

{

cout << endl << "No le atinaste";

cout << endl << "\t\tIntenta otra vez";

}

Al mostrar el párrafo de código anterior con sangría se aprecia mas el error (otra

razon del porque utilizar sangrías)

if (n == pc)

cout << "Adivinaste!" << endl;

cout << "\t\tAcaso tienes poderes siquicos?" << endl;

else

{

cout << endl << "No le atinaste";

cout << endl << "\t\tIntenta otra vez";

}

Ejercicios

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 46

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 47/212

 

1. Modifique el programa “condolar.cpp”, para presentarle al usuario la opción

de convertir de dolares a pesos y de pesos a dólares, realice la operación

seleccionada por el usuario.

2. Realice un programa que lea un número de la entrada estándar y despliegue

si el número leído es par o impar, utilice el operador “%” para obtener el

residuo de la división, note que el residuo de una división entre dos de un

número par siempre es cero.

Evaluación de la expresión

En C++ la evaluación de la expresión dentro de los paréntesis después del “if”,

para que sea verdadera debe ser distinta de cero y es falsa cuando es cero.Ejemplo:

if (1)

cout << “Expresion verdadera”; // <-- se imprime esto en pantalla

if (0)

cout << “Expresion verdadera”;

else

cout << “Expresion falsa”; // <-- se imprime esto en pantalla

El lenguaje C++ no pone restricción al tipo de expresiones a solo las que

invocan operadores relacionales y lógicos. Todo lo que se requiere es que la

expresión evaluada de cero o no cero.

Listado

// divide.cpp

// Divide el primer numero por el segundo

#include <iostream>

using namespace std;

int main() {

float a, b;

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 47

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 48/212

 

cout << endl << "Introduce dos numeros enteros: ";

cin >> a >> b;

 

if (b) // equivalente a (b != 0)

cout << a/b << endl;

else

cout << "No puedo dividir por cero" << endl;

return 0;

}

Salida en base a la entrada de ejemplo

Introduce dos numeros enteros: 3

0

No puedo dividir por cero

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 48

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 49/212

 

if (b)

Evalúa si la variable es distinta de cero (verdadero) o cero (falso)

if anidado

Se le llama “if” anidado cuando un bloque de código perteneciente a un “if-else”

contiene otro “if” o “if-else”.

Listado

// mayor.cpp

// compara dos numeros y dice si son iguales o cual es el mayor

#include <iostream>

using namespace std;

int main(){

int a, b;

cout << "\nDame un numero ";

cin >> a;

cout << "Dame otro numero ";

cin >> b;

 

if (a == b)

cout << "Los numero son iguales";

else

if (a > b)

cout << "El numero " << a << " es mayor que " << b;

else

cout << "El numero " << b << " es mayor que " << a;

return 0;

}

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 49

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 50/212

 

Salida en base a la entrada de ejemplo

Dame un numero 12

Dame otro numero 3

El numero 12 es mayor que 3

if (a == b)

cout << "Los numero son iguales";

else

if (a > b)

cout << "El numero " << a << " es mayor que " << b;

else

cout << "El numero " << b << " es mayor que " << a;

El segundo “if” se encuentra dentro del bloque de código perteneciente al “else”,

ambos “if” tienen la parte del “else”, cuando esto no sucede se puede prestar a

confusiones.

Ejemplo:

if (a != b)

if (a > b)cout << "El numero " << a << " es mayor que " << b;

else

cout << "El numero " << b << " es mayor que " << a;

En esta situación el último “else” pertenece al “if” inmediato anterior.

if (a != b)

if (a > b)

cout << "El numero " << a << " es mayor que " << b;

else

cout << "numeros iguales ";

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 50

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 51/212

 

Aquí aunque el “else” este alineado con el primer “if”, este sigue perteneciendo

al “if” inmediato anterior, para lograr que el “else” pertenezca al primer “if” se

necesita utilizar las llaves de inicio y fin de código.

if (a != b)

{

if (a > b)

cout << "El numero " << a << " es mayor que " << b;

}

else

cout << "numeros iguales ";

switch

La sentencia “switch” es usada para decisiones múltiples que comprueba si una

expresión iguala uno entre varios valores constantes.

Forma General:

switch (variable) {

case constante1:

  bloque de código;

case constante2:

  bloque de código;

break;

.

.

.

default:

bloque de código;

}

Descripción

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 51

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 52/212

 

1. El “switch” difiere del “if” porque la primera solo puede comprobar por

igualdad, mientras que la expresión condicional del “if” puede ser de cualquier

tipo.

2. No pueden tener dos constantes case con idénticos valores en el mismo

“switch”. Una sentencia “switch” que esta encerrada por otro “switch” puede

tener constantes case que son las mismas.

 

case

Actúa como una etiqueta.

break

Opcional dentro de la sentencia “switch”. Se usa para terminar la secuencia queesta asociada con cada constante. Si se omite, la ejecución continuara en las

sentencias del siguiente case hasta encontrar un “break”, un “return” o el final

del “switch”.

 

default

Es opcional y se ejecuta si no se satisface ninguna opción.

Listado

// fechaSwitch.cpp

// demostracion del switch

#include <iostream>

using namespace std;

int main(){

int iMes = 9;

cout << iMes << " ";

switch(iMes) {

case 1:

cout << "enero";

break;

case 2:

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 52

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 53/212

 

cout << "febrero";

break;

case 3:

cout << "marzo";

break;

case 4:

cout << "abril";

break;

case 5:

cout << "mayo";

break;

case 6:

cout << "junio";

break;

case 7:

cout << "julio";

break;

case 8:

cout << "agosto";

break;

case 9:

cout << "septiembre";

break;

case 10:

cout << "octubre";

break;

case 11:

cout << "noviembre";

break;

case 12:

cout << "diciembre";

break;default:

cout << " *error*";

}

return 0;

}

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 53

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 54/212

 

Salida 

9 septiembre

int iMes = 9;

La variable mes es inicializada al momento de declararla, al entrar al “switch”

este compara la variable “iMes” con las constantes literales en los cases hasta

encontrar el “case 9:” y se ejecuta la línea debajo de este desplegando

“septiembre”, a continuación se ejecuta la siguiente línea conteniendo la

instrucción “break” la cual rompe el “switch”.

En caso que la variable no se encuentre en ninguno de los case, se ejecuta lasentenciaque le sigue a “default”.

Note el uso del “break” al terminar cada case, esto es necesario para que

termine la ejecución del “switch” y no continué con los siguientes case, lo cual es

útil en algunas situaciones, como en el siguiente programa por ejemplo.

Listado

// switch_dolar.cpp

// Convierte dolares a pesos o viceversa, pide el tipo de cambio

// ejemplo del switch con las clasusulas case sin el break

#include <iostream>

using namespace std;

int main(){

char opcion;

float dolares, pesos, cambio;

cout << "Cual es el tipo de cambio? ";

cin >> cambio;

cout << "*** M E N U ***" << endl

<< "ingrese la primera letra de la palabra"

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 54

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 55/212

 

<< endl;

cout << "D olares a pesos" << endl;

cout << "P esos a dolares" << endl;

cout << "Opcion? ";

cin >> opcion;

switch (opcion) {

case 'd':

case 'D':

cout << endl << "Cuantos dolares desea convertir a pesos? ";

cin >> dolares;

pesos = dolares * cambio;

cout << "Pesos = " << pesos;

break;

case 'p':

case 'P':

cout << endl << "Cuantos pesos desea convertir a dolares? ";

cin >> pesos;

dolares = pesos / cambio;

cout << "Pesos = " << dolares;

break;

default:

cout << "opcion no implemenrada";

}

 

return 0;

}

Salida en base a la entrada de ejemplo

Cual es el tipo de cambio? 12.5

*** M E N U ***

ingrese la primera letra de la palabra

D olares a pesos

P esos a dolares

Opcion? d

Cuantos dolares desea convertir a pesos? 18

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 55

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 56/212

 

Pesos = 225

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 56

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 57/212

 

case 'd':

case 'D':

cout << endl << "Cuantos dolares desea convertir a pesos? ";

cin >> dolares;

pesos = dolares * cambio;

cout << "Pesos = " << pesos;

break;

El “case ‘d’:” no contiene un “break” (ni código) por lo tanto si el usuario del

programa ingresa una ‘d’ minúscula entra a este “case” continua hacia abajo y

se ejecuta el código del “case” con la ‘D’ mayúscula, el cuerpo de este “case”

tiene un “break” porque no debe ejecutar lo que esta en el siguiente “case”.

Ejercicios

1. Modifique el programa “fechaSwitch.cpp” para que pida el mes del teclado

2. Escriba un programa que lea un carácter del teclado y si se trata de un

número despliegue el número con letra, si no es un número mencionarlo,

utilize la sentencia “switch”.

3. Discuta la posibilidad de hacer un programa que escriba su nombre completo

100 veces; 10,000 veces?; 9,000,000 de veces?

1.9.3 Iteración

Las sentencias de repetición permiten ejecutar una porción de código varias

veces.

do-while

Hace la comprobación al final después de cada pasada a través del cuerpo delciclo. Y este se ejecuta al menos una vez.

Forma general:

do

bloque de código;

while (expresión);

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 57

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 58/212

 

Listado

// doadivina.cpp

// do..while, adivina el numero generado aleatoriamente

// Termina cuando el usuario así lo desea

#include <iostream>

#include <ctime>

using namespace std;

int main() {

int n, pc;

char c;

srand( (unsigned)time( NULL ) );

pc = rand() % 5;

do {

cout << "\nAdivina el numero que pienso (0-4) " << endl;

cin >> n;

if (n == pc)

cout << "ADIVINASTE!!!" << endl;

else

cout << "NO ES!!!" << endl;

 

cout << endl << "Intenta otra vez? (s/n)";

cin >> c;

} while (c != 'n');

 

return 0;

}

Salida en base a la entrada de ejemplo

Adivina el numero que pienso (0-4)

1

NO ES!!!

Intenta otra vez? (s/n)s

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 58

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 59/212

 

Adivina el numero que pienso (0-4)

3

ADIVINASTE!!!

Intenta otra vez? (s/n)n

Este es el ejemplo adivina.cpp presentado en el listado 2.1, pero dentro de un

ciclo.

do {

Inicia el ciclo, línea 14, en la línea 22 y 23 pregunta si se quiere continuar

intentando.

} while (c != 'n');

En la línea 24, checa lo que se leyó en la variable c y la compara, con en caso

que sea verdadera la evaluación el ciclo termina, de lo contrario regresa al do {.

Ejercicios

1. Modifique el programa “switch_dolar.cpp”, que lee un carácter del teclado y sise trata de un número despliega el número con letra y si no es un número lo

menciona para que termine hasta que se ingrese una 'X'.

2. Discuta como se puede mejorar el ejemplo anterior (“doadivina.cpp”), por

ejemplo, ¿que sucede si el usuario adivina el número y desea seguir

 jugando?, realice las modificaciones sugeridas.

3. Hacer un programa que escriba su nombre completo 10,000 veces

 while

Hace la comprobación al inicio de cada pasada a través del cuerpo del ciclo. Si

la evaluación es falsa no se ejecuta ni una sola vez.

Forma general:

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 59

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 60/212

 

while (expresión)

bloque de código;

Listado

// ascii.cpp

// Despliega la tabla Ascii en la salida estándar

#include <iostream>

using namespace std;

int main() {

int i;

i = 0;

while (i < 256) {

// el caracter 26, puede borrar pantalla

cout << char(i) << " " << i << " ";

i++;

}

 

return 0;

}

Salida 

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 60

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 61/212

 

 while (i < 255) {

Se evalúa la variable “i” si es menor a 255 empieza el ciclo y se ejecuta la

primera sentencia después de la llave “{“ así sucesivamente hasta que se

encuentra la llave que cierra “}” al pasar esto, se evalúa la condición dentro de

los paréntesis del “while” si la “i” todavía es menor a 255 vuelve a ejecutar unapor una las instrucciones dentro de las llaves “{“ y “}”, cuando la variable “i” sea

igual a 255 el ciclo termina.

La instrucción char(i), regresa el carácter ASCII correspondiente al entero de la

variable “i”.

for

Forma general:

for (inicialización; condición; incremento)

bloque de código;

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 61

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 62/212

 

Gramaticalmente, los tres componentes de un “for” son expresiones. Mas

comúnmente, inicialización e incremento son asignaciones o llamadas a función

y condición es una expresión de relación.

Puede omitirse cualquiera de las tres partes, aunque deben permanecer los

puntos y comas.

Ejemplo:

for (; ;)

;

Este es un ciclo infinito; que podríamos terminar con un “break” o con un

“return”.

La proposición for es equivalente a:inicialización;

while (condición) {

bloque de código;

incremento;

}

Listado

// for_prom.cpp

// ejemplo del for el promedio de la suma de 5 números

#include <iostream>

using namespace std;

int main() {

float fCalificacion, fSuma, fPromedio;

int i;

cout << "Ingresa calificaciones " << endl;

fSuma = 0;

for (i = 0; i < 5; i++) {

cout << i << ". Calificacion? ";

cin >> fCalificacion;

fSuma = fSuma + fCalificacion;

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 62

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 63/212

 

}

fPromedio = fSuma / 5;

cout << endl << "El promedio es " << fPromedio;

 

return 0;

}

Salida en base a la entrada de ejemplo

Ingresa calificaciones

0. Calificacion? 100

1. Calificacion? 95

2. Calificacion? 90

El promedio es 95

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 63

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 64/212

 

for (i = 0; i < 5; i++) {

Inicia el ciclo “for” ejecutándose primero la parte de inicialización “i = 0;”

después se evalúa “i < 5;” la primer a vez se cumple la condición y entra al

cuerpo del “for”, en el cuerpo del “for” (todas las sentencias que están en medio

de la llave que abre “{“ que le sigue al “for” y la llave que cierra “}”

correspondiente) se pide la calificación y se acumula en “fSuma”.

 

Al terminar el cuerpo del “for” regresa a la línea 12 e incrementa i++ después

evalúa i < 5, si la evaluación es verdadera vuelve al cuerpo del for si no es así

termina (nótese que después de la primera vez que se ejecuta el for , ya no se

realiza la parte de inicialización y el encabezado del for se evalúa de derecha a

izquierda)

fPromedio = fSuma / TAM;

En la línea 17 se calcula el promedio y lo despliega en la siguiente línea.

Ejercicios

1. Modifique programa ejemplo “for_prom.cpp” para que utilice la iteración

“while” en vez del “for”.

2. Modifique el programa ejemplo “ascii.cpp” para que utilice la iteración “for” en

vez del “while” (asciifor.cpp) .

3. Discuta la posibilidad de hacer un programa

a) Que almacene 3 números y los despliegue en orden de menor a mayor

b) Que almacene 100 números y los despliegue en orden de menor a mayor

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 64

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 65/212

 

Capitulo 2

Subprogramas

2.1 Definición de un subprograma

En C++ un programa puede crearse como un grupo de bloques,

donde cada bloque contiene código lo más independiente

posible y comprobable llamado subprograma. Los subprogramas

contienen entradas y salidas para conectarlos a otros

bloques de código –subprogramas- para formar el programaprincipal.

La división de un programa en subprogramas es parte de una

técnica de programación llamada programación modular; la

cual es basada en la filosofía de “divide y vencerás”.

Módulos

Un modulo es un conjunto encapsulado de datos y operaciones que tienen relación entre si. Enel caso de C++ lo común es que sea en un archivo de encabezado y en un archivo de

implementación.

La utilización de módulos es para formar partes de código independiente con el propósito de

reducir la complejidad, aumentar y facilitar la reutilización del código además de hacer más

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 58

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 66/212

 

mantenible los programas. “La modularidad es la capacidad de dividir el problema en pequeñas

 partes independientes entre si” [Hernandez 2002]

fig1. Organización de programas mediante módulos

2.1.1 Estructura de un subprograma

Un subprograma se implementa en C++ mediante funciones. Una

función es una o más instrucciones en designadas para una

tarea especifica, a este conjunto de instrucciones se le

asigna un nombre, que identifica la función dentro del

programa.

Los programas en C++ cuentan con una función especial llamada main() esta es llamada

automáticamente al iniciar la ejecución del programa; dentro de esta función se realizanllamadas a objetos y/o otras funciones.

El código de una función es privado a la función y no puede ser accesado por ninguna

declaración en ninguna otra función excepto a través de argumentos y variables globales.

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 59

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 67/212

 

Las variables definidas dentro de una función son variables locales dinámicas (empiezan a existir

cuando la función es llamada y se destruyen al terminar).

Forma general:

especificador_tipo nombre_funcion(lista_de_argumentos)

{

cuerpo de la función

<return valor>

}

La lista_de_argumentos es una lista de nombres de variables separados por comas que recibe

los valores de los argumentos cuando se llama la función.

El especificador_de_tipo es el tipo de valor que la función devuelve mediante el “return”.

2.1.2 Valor de retornoLas funciones terminan cuando se encuentra la última llave o mediante la sentencia “return” y

devuelven el control de flujo del programa automáticamente al procedimiento que la llamó.

Listado

// linea.cpp

// Funcion que dibuja una linea de 40 guiones

#include<iostream>using namespace std;

void linea() {

int i;

for (i = 0; i < 40; i++)

cout << "-";

}

int main() {

linea();

cout << endl << "Este mensaje es importante" << endl;

linea();

return 0;

}

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 60

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 68/212

 

Salida

----------------------------------------

Este mensaje es importante

----------------------------------------

void linea()

“linea” es el nombre de la función, y “void” antes del nombre indica que esta función no va a

regresar un valor al proceso que la llame, el paréntesis que abre y el paréntesis que cierra

después del nombre indican que es una función, entre estos paréntesis se ponen los argumentos

de la función, en este caso la función no necesita argumentos.

linea()

En la primera línea de la función “main” se hace el llamado a la función definida anteriormente,note que aunque la función no recibe parámetros el uso de los paréntesis es obligatorio.

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 61

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 69/212

 

Nota:

La función “linea()” esta definida antes de la función “main()” esto es para que el compilador ya la

conozca cuando se haga la llamada dentro de “main()”, si se escribiera la función “linea()” abajo

o en otro archivo, abría que poner la declaración arriba del “main()”, ya sea escribiéndola

directamente en el archivo principal o en un archivo de encabezado, mediante un “#include”.

2.2 Declaración de un subprograma

La declaración de un subprograma llamada en C++ prototipo de

función se refiere a solo escribir el encabezado de la

misma. Cuando la implementación se codifica después de que

la función es llamada o en un archivo aparte de donde se

manda llamar se debe incluir el encabezado de la función

antes de que esta sea llamada, esto es para que el

compilador verifique si la sintaxis con que se llamó la

función definida por el usuario es correcta. “Decirle al

compilador que la función existe y como es llamada” [Eckel

1993]

Listado

// proto_linea.cpp

// Ejemplo de prototipo de funciones

// Funcion que dibuja una linea de 40 guiones

#include<iostream>

using namespace std;

void linea();

int main() {

linea();

cout << endl << "Este mensaje es importante" << endl;

linea();

return 0;

}

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 62

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 70/212

 

void linea() {

int i;

for (i = 0; i < 40; i++)

cout << "-";

}

Salida

----------------------------------------

Este mensaje es importante

----------------------------------------

2.3 Bibliotecas o librería de subprogramasLas librerías son una manera de añadir funcionalidad al lenguaje sin agregar palabras

reservadas al lenguaje, por ejemplo una función puede ser compilada y almacenada en una

librería o archivo, de donde el encadenador la extrae.

El proveedor del compilador generalmente proporciona bibliotecas estándar de funciones y

clases. Los proveedores de software independientes proporcionan bibliotecas de propósito

especial.

Tipos de librerías

En C++ existen dos tipos fundamentales de librerías: estáticas y dinámicas. En ambos casos

 junto a las librerías (archivos con la extensión .lib, .a, .dll etc) se incluyen archivos "de cabecera",

archivos con la extensión .h estos archivos contienen las declaraciones de las entidades

contenidas en la librería, así como las macros y constantes predefinidas utilizadas en ella. Es

decir, la "interfaz" de las funciones o clases que utilizará. En el caso de funciones esto se

concreta en el prototipo; en el caso de clases, en la especificación de sus métodos y

propiedades públicas*. (http://www.zator.com/Cpp/E1_4_4b.htm)

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 63

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 71/212

 

Estáticas

Son también denominadas librerías-objeto, son colecciones de archivos objeto (compilados)

agrupados en un solo archivo con la extensión .lib, .a, etc. junto con uno o varios archivos de

cabecera (generalmente con la extensión “.h”).

Los componentes utilizados de estas librerías quedan incluidos en el programa ejecutable.

Dinámicas

Son las denominadas librerías de enlazado dinámico, es decir los componentes utilizados se

agregan cunado el programa se esta ejecutando y permite que la misma librería pueda ser

usada por varios ejecutables sin necesidad que se embeba permanentemente en un solo archivo

ejecutable. Generalmente conocidas como DLLs, acrónimo de su nombre en inglés ("Dynamic

Linked Library"). Estas librerías se utilizan mucho en la programación para el Sistema Operativo

Windows.

Listado

// tolower.cpp

// Muestra el uso de la funcion tolower

// que convierte un caracter a minusculas

#include <iostream>

using namespace std;

int main() {

char a, b, c;

a = 'R';

b = tolower(a);

cout << a << " " << b;

 

cout << endl << "Ingrese una letra en Mayusculas ";

cin >> c;

b = tolower(c);

cout << "Letra en minusculas " << b;

 

return 0;

}

Salida

R r

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 64

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 72/212

 

Ingrese una letra en Mayusculas Q

Letra en minusculas q

EjercicioModifique el programa doadivina.cpp –del cap 1- para que acepte minúsculas y mayúsculas

cuando pregunta si desea continuar, utilice la función “toupper()”.

Clase string

El tipo de dato string no existe en C++, este se implementa mediante tipo de dato definido por el

usuario mediante una clase (esta clase se incluye en una de las librerías del C++ estándar

proporcionadas por el compilador).

Un string es una clase para declarar objetos y estos objetos contienen básicamente una

secuencia de caracteres. Los programas que usen la clase string deben incluir la sentencia

“using namespace std” y el archivo de encabezado: #include <string>

Listado

// string1.cpp

#include <iostream>

#include <string>

using namespace std;

int main() {

string strNombre;

cout << "Cual es tu nombre? ";

cin >> strNombre;

cout << "\nSaludos " << strNombre << endl;

cout << "\nTu nombre tiene " << strNombre.length() << " letras";

return 0;

}

Salida

Cual es tu nombre? Batman

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 65

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 73/212

 

Saludos Batman

 Tu nombre tiene 6 letras

strNombre.length()

Objeto “strNombre” llamando un metodo, la cual regresa cuantos caracteres tiene el string.

Nota:

Para ingresar oraciones (palabras con espacios intermedios) usar:

getline(cin, str, ‘\n’);

Donde str es un objeto de tipo string.

Ejercicio

Tome como base el ejemplo string1.cpp para hacer un programa donde declare

3 variables string s1, s2, s3

a) Asigne s1 y s2 con datos proporcionados por el usuario

b) Concatene s1 y s2 (s1 + s2 concatena los strings) dejando el resultado en s3

c) Despliegue el string s3

Nota:

Algunos compiladores de C++ incluyen subprogramas que no son parte de las librerías estándar,

esto facilita de alguna forma la programación, pero limita la portabilidad del código a otros

compiladores y/o plataformas.

2.4 Primer acercamiento a clases y objetosProgramación orientada a objetos

El objetivo principal de la programación orientada a objetos es facilitar las tareas de programar y

reutilizar el código, en una forma integrada y más modular que la estructurada.

Clase

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 66

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 74/212

 

Describe un conjunto de objetos los cuales tienen las mismas características (datos) y el mismo

comportamiento (código), una clase es realmente un tipo de dato definido por el usuario, es una

extensión del concepto del tipo de dato registro, el cual nos permite organizar diferentes tipos de

datos en un solo lugar. La clase nos permite combinar datos y código dentro de un solo paquete.

Objeto

Un objeto es una instancia de una clase, la clase es el tipo de dato y el objeto es la variable. Un

objeto tiene un estado, comportamiento e identidad. Una identidad porque cada objeto pose un

nombre (identificador) único, un estado porque los datos tienen un valor determinado

dependiendo del proceso en que se encuentre el objeto, y un comportamiento porque “sabe” que

hacer con esos datos, es decir tiene sus propios algoritmos para procesar sus datos.

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 67

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 75/212

 

Listado

// claseFecha.cpp

// Clases

#include <iostream>

#include <string>

using namespace std;

class Fecha {

public:

int dd;

string mm;

int aa;

};

main() {

Fecha fecha;

cout << "Dia ";

cin >> fecha.dd;

cout << "Mes en letra ";

cin >> fecha.mm;

cout << "A#o ";

cin >> fecha.aa;

cout << fecha.dd << " de " << fecha.mm << " de " << fecha.aa;

}

Salida en base a la entrada de ejemplo

Dia 12

Mes en letra enero

A#o 2009

12 de enero de 2009

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 68

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 76/212

 

2.5 Ámbito y tiempo de vida de variables

Alcance de variables

Los programas en C++ se forman a base de bloques de código estos bloques inician con la llave

“{“ y terminan con la llave “}”.

Las variables declaradas dentro de un bloque de código son locales a ese bloque, no pueden ser

accesadas por otro bloque o afuera de este.

Variables automáticas, también llamadas locales dinámicas

Cada variable local comienza a existir cuando se ejecuta el bloque donde fue declarada y

desaparece cuando el bloque de código acaba. Estas variables no conservan su valor entre dos

llamadas sucesivas.

Variables externas, también llamadas globales

Se definen fuera de las funciones, estas son externas a todas las funciones; esto es variables

globales a las que puede acceder cualquier función mediante su nombre. Cuando son

declaradas en otro archivo se debe usar la palabra reservada “extern”.

Listado

// alcance.cpp

// Ejemplo de alcance de variables y del operador de alcance ::

#include <iostream>

using namespace std;

int a = 0;

int main() {

int a = 10;

 

cout << a << endl;

cout << ::a << endl;

{

int x = 20;

cout << x << endl;

x++;

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 69

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 77/212

 

}

//cout << x;

return 0;

}

Salida

10

0

20

int a = 0;

Declara una variable global, para todos los bloques de código que le siguen hacia abajo, en estecaso el bloque de “main()” que empieza y el bloque sin nombre que empieza abajo del segundo

“cout”.

int a = 10;

Sobrescribe a la variable con el mismo nombre declarada anteriormente antes de empezar la

función “main()”.

El primer “cout” despliega el contenido de la variable local “a”.

El segundo “cout” despliega el contenido de la variable global, utilizando el operador de alcance

“::”

La llave que abre “{“ después del segundo “cout” indica el inicio de un bloque de código sin

nombre.

int x = 20;

Declara una variable local para el bloque que inicio en la

línea anterior, la variable empieza a existir aquí y termina

al cerrar el bloque con la llave que cierra “}”.

 

El ultimo “cout” esta como comentario porque marca un error, de variable no encontrada ya que

la variable “x” dejo de “existir” al terminarse el bloque sin nombre.

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 70

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 78/212

 

Espacio de nombres

Por omisión cuando un nuevo tipo de dato es definido este existe globalmente. Lo cual significa

que está disponible a cualquier función en la aplicación.

Para evitar conflictos entre las diferentes librerías (módulos de código para ser rehusado), cadalibrería puede crear su propio bloque de espacio de definición de datos, utilizando la palabra

reservada “namespace”.

namespace

Un espacio de nombres definido por la palabra “namespace” es el alcance en el cual los tipos de

datos pueden ser definidos para evitar la sobrecarga del espacio de alcance global.

El uso de “namespace” permite agrupar un conjunto de variables globales dentro de un nombre.

Es decir el alcance global se subdivide en espacios de nombres.

Forma general:

namespace identificador

{

cuerpo-del-namespace

}

using namespace

La directiva “using” seguida del “namespace” sirve para asociar el nivel en que un identificador

esta con cierto “namespace”, para que los objetos, funciones y variables de ese “namespace”

pueden ser accesibles directamente como si estuvieran definidos en el alcance global.

Forma general:

using namespace identificador;

Listado

// namespace.cpp

#include <iostream>

using namespace std;

namespace espacio1 {

int a = 0;

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 71

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 79/212

 

};

namespace espacio2 {

int a = 100;

};

int main() {

cout << "namespace espacio1 " << espacio1::a;

cout << "\nnamespace espacio2 " << espacio2::a;

return 0;

}

Salida

namespace espacio1 0

namespace espacio2 100

En este ejemplo se utiliza el operador de alcance :: para especificar que espacio de nombre

utilizar; para evitar poner el nombre cada vez que se use lo que esta definido en el espacio de

nombres se puede utilizar “using namespace”. 

2.6 Argumentos y paso de parámetros.Hay tres tipos de argumentos para las funciones

Por valor

Por puntero*

Por referencia*

* Estos dos últimos se estudian en el siguiente capitulo de Punteros, referencias y arreglos.

Llamada por valor

Este método copia el valor del argumento dentro de los parámetros formales de la función y

todos los cambios que sufran los parámetros no afectan el valor del argumento usado para

llamar la función. Los parámetros formales de la función son las declaraciones de las variables

que aceptan los valores de los argumentos.

Listado

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 72

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 80/212

 

// sqr.cpp

// Usa una funcion que recibe y regresa un valor entero

#include <iostream>

using namespace std;

int sqr(int num) {

num = num * num;

 

return num;

}

int main() {

int n, x;

cout << "Ingresa un numero ";

cin >> n;

x = sqr(n);

cout << endl << "El cuadrado de " << n << " es " << x;

return 0;

}

Salida 

Ingresa un numero 3

El cuadrado de 3 es 9

int sqr(int num) {

El primer “int” indica que la función regresa un valor de tipo entero y el segundo que recibe un

entero como argumento.

return num;

Aquí se regresa el valor contenido en la variable “num”, el tipo de dato que se regrese con

“return” debe de corresponder al tipo de dato que aparece antes del nombre de la función.

El “return” puede aparecer en cualquier parte del cuerpo de la función e inmediatamente regresa

el control a la línea de donde fue llamada la función, devolviendo el valor indicado después del

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 73

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 81/212

 

“return” en caso que exista tal valor ya que también puede estar solo y en ese caso solamente

regresará el control a la parte de donde fue llamada.

x = sqr(n);

La función es llamada con “n” como argumento y regresa el número indicado en el “return”

asignándoselo a la variable “ x ”.

Ejercicios

1 Escriba una función que reciba un número y regrese su valor absoluto.

2 Realice una función eleva(n, x) que eleve el valor de “n” a la potencia “x”, regrese el numero

elevado.

3 Hacer un programa que pruebe las funciones de un modulo compuesto de un archivo de

encabezado (.h) y un archivo fuente (.cpp) que contenga las siguientes funciones:

- Convierta de centímetros a pulgadas

- Convierta de pulgadas a centímetros

- Convierta de metros a yardas

- Convierta de yardas a metros

- Convierta de kilómetros a millas

- Convierta de millas a kilómetros

Argumentos por omisión

Si la función tiene un prototipo los argumentos por omisión

se declaran en el prototipo y no en la definición. Si la

función no tiene prototipos se pueden declarar en la

definición.

Hay que notar que no todos los argumentos deben de estar

definidos por omisión; puede ser uno solo pero este solo

puede estar al final de la lista de argumentos.

Ejemplo:

Formato(int x, int y, int z = 0);

Formato(int x, int y = 0, int z = 0);

Esto es valido, los últimos argumentos en la lista son

por defecto.

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 74

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 82/212

 

Formato(int x, int y = 0, int z);

Formato(int x = 0, int y, int z = 0);

Esto es inválido, una vez que se pone un argumento por

omisión en la lista todos los demás que le siguen deben

ser por omisión.

Listado

// omision.cpp

// Argumentos por omision de las funciones

// en los prototipos de las funciones de C++

#include <iostream>

using namespace std;

void muestra(int = 1, float = 2.3, long = 4);

int main() {

muestra(); // Los tres parametros por defecto

muestra(5); // Provee el primer parámetro

muestra(6, 7.8); // Provee los primeros dos

muestra(9, 10.11, 12L); // Provee los tres parametros

return 0;

}

void muestra(int pr, float seg, long ter) {

cout << "\n Primero = " << pr;

cout << ", Segundo = " << seg;

cout << ", Tercero = " << ter;

}

Salida

Primero = 1, Segundo = 2.3, Tercero = 4

Primero = 5, Segundo = 2.3, Tercero = 4

Primero = 6, Segundo = 7.8, Tercero = 4

Primero = 9, Segundo = 10.11, Tercero = 12

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 75

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 83/212

 

void muestra(int = 1, float = 2.3, long = 4);

Se declara el prototipo de la función con los argumentos por

omisión.

En el “main()” se manda llamar la función muestra() con

diferente número de argumentos para que se utilicen los

argumentos por omisión.

2.7 Sobrecarga de subprogramas.

La sobrecarga de subprogramas en C++ significa que se pueden tener varias funciones con elmismo nombre, esto es posible ya que el identificador de una función se determina por el

nombre de la función y sus argumentos. Las funciones deben diferir en la lista de argumentos, ya

sea en el número de variables que se pasan a la función, en el tipo de argumentos que recibe o

bien en el orden.

Listado

// sobrecarga.cpp

//Sobrecarga de una funcion

#include <iostream>

using namespace std;

int cuadrado(int); //prototipo de funcion sobrecargada

double cuadrado(double);//prototipo de funcion sobrecargada

int main() {

int ix = 5;

double dx = 1.5;

cout << "El cuadrado de "<< ix << " es "<< cuadrado(ix) << endl;

//el compilador al ver un valor int elige la funcion

cout << "El cuadrado de " << dx << " es " << cuadrado(dx) << endl;

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 76

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 84/212

 

return 0;

}

//Funcion sobrecargada para valores int

int cuadrado(int y ) {

return y*y;

}

//Funcion sobrecargada para valores double

double cuadrado(double y) {

return y*y;

}

Salida

El cuadrado de 5 es 25

El cuadrado de 1.5 es 2.25

2.8 RecursividadUna función es recursiva si una sentencia en el cuerpo de una función se llama a si misma.

Listado

// recursiva.cpp

// Usa una funcion normal y una recursiva para sacar el factorial

#include <iostream>

using namespace std;

int factorial(int n) { // no recursiva

int i, f = 1;

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

f = f * i;

return f;

}

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 77

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 85/212

 

int factorial_recusiva(int n) { // Funcion recursiva

if (n == 0)

return 1;

else

return n * factorial_recusiva(n-1);

}

int main() {

int n;

cout << "ingrese un numero ";

cin >> n;

cout << "El factorial de " << n

<< " es " << factorial(n) << endl;

cout << "El factorial de " << n

<< " es " << factorial_recusiva(n) << endl;

return 0;

}

Salida en base a la entrada de ejemplo

ingrese un numero 5

El factorial de 5 es 120El factorial de 5 es 120

Funciones inline

Las funciones en línea se declaran anteponiendo la palabra “inline” al tipo de dato de la función,

y éstas funciones actúan como macros; el compilador pone el código que se encuentra dentro de

la función en la parte donde está el llamado como si fuera escrito ahí originalmente, esto hace

que el programa sea mas grande pero se evita el tiempo del llamado a la función haciendo el

programa mas rápido, con la ventaja de tener el código centralizado en una sola parte y con el

chequeo de sintaxis de una función.

Las funciones en línea que contienen ciclos no son expandidas y generalmente el compilador da

una advertencia.

Nota:

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 78

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 86/212

 

El compilador puede ignorar una declaración “inline”; y también dependiendo de las

optimizaciones que se usen, el compilador puede hacer funciones en línea que no se declararon

como “inline”.

Listado// enlinea.cpp

// funciones en linea

// utiliza una función "inline" para intercambiar dos valores

#include<iostream>

#include <ctime>

using namespace std;

// Las funciones inline (en linea) se expanden donde se llaman

inline void cambia(char &a, char &b) {

char c;

if (rand()%2) {

c = a;

a = b;

b = c;

}

}

void tabs(int n) {

int i;

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

cout << "\t";

}

int main() {

int i;

char x, y;

x = '#';

y = 'O';

srand( (unsigned)time( NULL ) );

for (i = 0; i < 10; i++) {

tabs(i);

cout << x << endl;

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 79

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 87/212

 

cambia(x, y);

}

return 0;

}

Salida

#

#

O

O

O

O

O

#

#

#

inline void cambia(char &a, char &b)

La palabra “inline” indica que la función será expandida donde sea llamada.

for (i = 0; i < 10; i++) {tabs(i);

cout << x << endl;

cambia(x, y);

}

Aquí se encuentra la llamada a la función “cambia” y en esta

parte se incluye el código de la función en lugar del código

para llamarla por parte del compilador.

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 80

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 88/212

 

Capitulo 3Punteros, referencias y arreglos

3.1 CreaciónUn puntero es un a variable que almacena una dirección de memoria. Esta dirección es

usualmente la localidad de otra variable en memoria. Si una variable contiene la dirección de otra

variable, entonces se dice que la primera variable apunta a la segunda.

Los punteros son usados para accesar en forma expedita porciones de memoria.

Pasos a seguir al usar punteros1. Define el puntero (Usando el *)

char *pn;

2. Inicializa el puntero para apuntar a algo (Usando &)

pn = &n;

3. Toma a lo que este apuntando el puntero (Usando *), a este proceso se le llama indirección

cout << “pn esta apuntando a “ << *pn;

Ejemplo:

char c, n, *pn;

n = 'X';

pn = &n;

c = *pn; ( c = 'X')

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 82

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 89/212

 

fig1. Simplificación de variables en memoria

El operador & solo se puede aplicar a variables y a elementos de un arreglo. Son ilegales

construcciones como:

&(x+1)

&3

Listado

// apunta.cpp// ejemplo de punteros e indireccion

// recomendable analisar la salida al mismo tiempo que el codigo

#include <iostream>

using namespace std;

int main() {

int n;

int *pn;

n = 123;

cout << endl << "n = 123;";

cout << endl << "valor de n=" << n

<< " Direccion de n=" << &n

<< endl;

 

pn = &n; // pn apunta a n (contiene la direccion de n)

cout << endl << "pn = &n;";

cout << endl << "Valor de pn=" << pn<< " Valor a donde apunta pn=" << *pn

<< endl;

*pn = 321; // se accesa n indirectamente

cout << endl << "*pn = 321;";

cout << endl << "valor de n=" << n

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 83

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 90/212

 

<< endl;

n++;

cout << endl << "n++;";

cout << endl << "acceso indirecto al valor de *pn="

<< *pn;

return 0;

}

Salida (los valores de las direcciones son dependientes de

la ejecución)

n = 123;

valor de n=123 Direccion de n=0xbfb9aaf8

pn = &n;

Valor de pn=0xbfb9aaf8 Valor a donde apunta pn=123

*pn = 321;

valor de n=321

n++;

acceso indirecto al valor de *pn=322

La salida explica el programa al mostrar los valores, las direcciones de las variables, y como se

asigna estas direcciones a la variable de tipo puntero, además del acceso indirecto que se logra

por medio del puntero.

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 84

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 91/212

 

3.2 Operaciones con punterosMediante un puntero se puede acceder a diferentes direcciones de memoria siempre y cuando

sea del mismo tipo. Se puede realizar comparaciones entre punteros y hacer restas y sumas a

punteros y entre punteros. Al incrementar o decrementar un puntero, éste apuntara a la posición

de memoria del elemento siguiente o anterior según sea el caso en función de su tipo base.

Ejemplo:

char *pn, n =’X’;

pn = &x;

fig2. Simplificación de memoria, en base a una maquina de 16 bits

pn++;

fig3. Simplificación de memoria, en base a una maquina de 16 bits

Listado

// operap.cpp

// operaciones con punteros

#include <iostream>

using namespace std;

int main() {

char a, b, *pc1, *pc2;

a = 'A';

b = 'B';

pc1 = &a;

cout << "pc1 = &a;" << endl;

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 85

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 92/212

 

cout << " Acceso indirecto variable \"a\" mediante pc1 "

<< *pc1 << endl;

pc1 = &b;

cout << "pc1 = &b;" << endl;

cout << " Acceso indirecto variable \"b\" mediante pc1 "

<< *pc1 << endl;

pc2 = pc1;

cout << "pc2 = pc1;" << endl;

cout << " Acceso indirecto variable \"b\" mediante pc2 "

<< *pc1 << endl;

if (pc1 == pc2)

cout << "Los dos punteros apuntan a la misma direccion" << endl;

else

cout << "Los dos punteros apuntan a diferentes direcciones" <<

endl;

pc1 = &a;

cout << "pc1 = &a;" << endl;

if (pc1 == pc2)

cout << "Los dos punteros apuntan a la misma direccion" << endl;

else

cout << "Los dos punteros apuntan a diferentes direcciones" <<

endl;

// Se incrementa el contenido de donde apunta pc1

cout << endl << "Valor de donde apunta pc1 = " << *pc1

<< endl << "(Valor de donde apunta pc1) + 1 = "

<< char(*pc1 + 1)

<< endl << "(Valor de donde apunta pc1) + 2 = "<< char(*pc1 + 2) << endl;

return 0;

}

Salida

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 86

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 93/212

 

pc1 = &a;

Acceso indirecto variable "a" mediante pc1 A

pc1 = &b;

Acceso indirecto variable "b" mediante pc1 B

pc2 = pc1;Acceso indirecto variable "b" mediante pc2 B

Los dos punteros apuntan a la misma direccion

pc1 = &a;

Los dos punteros apuntan a diferentes direcciones

Valor de donde apunta pc1 = A

(Valor de donde apunta pc1) + 1 = B

(Valor de donde apunta pc1) + 2 = C

pc1 = &a;

Se asigna la dirección de la variable “a”.

char(*pc1 + 1)

Incrementa el contenido de donde apunta “pc1”, el valor de la variable “a” es “A” que es 65 en

código ASCII, 65 + 1 = 66 y lo despliega como carácter con la conversión a tipo char().

Nota:

La aritmética de punteros se analiza después de estudiar arreglos, en el siguiente tema.

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 87

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 94/212

 

Puntero nulo

Un puntero nulo es un puntero que apunta a “NULL”, es decir apunta a una dirección cero, se

dice que es un puntero “0”. El puntero “NULL” no concide con ninguna dirección de variable o

función. Muy útil en manejo de colas, listas, pilas, etc.

Punteros a void

Es aquel que apunta a un tipo “void”. Significa que el puntero no apunta a ningún tipo de valor...

y es más o menos genérico, es decir se puede usar para apuntar a diferentes tipos de memoria.

(Más o menos genérico porque no se permite la asignación de la dirección de una constante o

de punteros a constantes, punteros a miembros de una clase, etc)

Ejemplo:

void *puntero;

Indireccion simple y múltiple

fig4, Simplificación de indireccion

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 88

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 95/212

 

Ejemplo:

float **n;

Aquí “n” no es un puntero a un numero en punto flotante, sino un puntero aun puntero

“float”.

Listado

// indir_multiple.cpp

// Ejemplo de indireccion multiple

#include <iostream>

using namespace std;

int main() {

int x, *p, **q;

 

x = 10;

p = &x;

q = &p;

cout << endl << "q=" << q

<< endl << "*q=" << *q

<< endl << "**q=" << **q;

 

return 0;

}

Salida (Dependiente de la ejecución)

q=0xbfff1f40

*q=0xbfff1f44

**q=10

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 89

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 96/212

 

Llamada por punteros

En este método, la dirección en memoria del argumento es copiada dentro del argumento de la

función. La dirección es usada para accesar el valor en memoria de la variable usada en la

llamada.

Para usar este método se pasa una dirección de memoria como argumento. Los punteros son

pasados a la función como cualquier otro valor pero declarando los parámetros de tipo

apuntador.

Listado

// cambia.cpp

// intercambia dos numeros con una funcion

#include <iostream>

using namespace std;

void cambia(int *x, int *y) {

int paso;

paso = *x;

*x = *y;

*y = paso;

}

int main() {

int x = 20, y = 10;

cout << "x=" << x << " y=" << y << endl;

cambia(&x, &y);

cout << "x=" << x << " y=" << y;

 

return 0;

}

Salida 

10 20

void cambia(int *x, int *y) {

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 90

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 97/212

 

Las variables dentro de los paréntesis indican que se va a recibir direcciones, al igual “void”

indica que la función no va a regresar un valor.

cambia(&x, &y);

El símbolo “&” antes del nombre de la variable indica que se manda la dirección de la variable.

Punteros a funciones

Las funciones se encuentran dentro de la memoria de segmento de código, por lo tanto la

dirección de inicio de la función se puede asignar a un puntero.

Teniendo una función:

int nombre_funcion(int char *);

Se declara un puntero a función:

int (*puntero_a_funcion) (int, char *)

Para inicializar el puntero:

puntero_a_funcion = nombre_funcion;

3.3 ReferenciasUna referencia es la asociación de un nombre a un objeto determinado; una referencia es como

un puntero constante al que se le aplica una indirección cada vez que se hace referencia a éste.Es como un puntero porque aloja una dirección y como una variable común porque no se tiene

que usar una notación específica como en el caso de los punteros cuando se usa la variable.

La variable tipo referencia debe inicializarse al momento de declararse.

Listado

// referencias.cpp

// ejemplo de referencias

#include <iostream>

using namespace std;

int main() {

int n = 123;

int &rn = n;

cout << "n=" << n << endl;

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 91

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 98/212

 

cout << "rn=" << rn << endl << endl;

rn++;

cout << "rn++=" << rn << endl;

cout << "n=" << n << endl << endl;

n++;

cout << "n++=" << n << endl;

cout << "rn=" << rn << endl;

return 0;

}

Salidan=123

rn=123

rn++=124

n=124

n++=125

rn=125

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 92

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 99/212

 

int &rn = n;

Se declara la variable de referencia “rn”, con el signo “&” antes de la variable y se hace

referencia a la variable “n”.

rn++;Se incrementa indirectamente la variable “n” por medio de la referencia.

cout << "\n rn = " << rn;

Se despliega el valor de “n” por medio de la referencia “rn”.

Llamada por referencia 

El argumento de la función es inicializado con la dirección en memoria del argumento, la

referencia es usada para accesar el valor en memoria de la variable usada en la llamada.

Listado

// cambia_rf.cpp

// Usa una funcion que intercambia los valores de sus argumentos

// utilizando paso por Referencia

#include <iostream>

using namespace std;

void cambia(int &a, int &b) {

int paso;

paso = a;

a = b;

b = paso;

}

int main() {

int x, y;

x = 10; y = 20;

cambia(x, y);

cout << endl << "X = " << x;

cout << endl << "Y = " << y;

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 93

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 100/212

 

return 0;

}

Salida

X = 20 Y = 10

void cambia(int &a, int &b) {

Se declara la función con paso por referencia

cambia(x, y);

Se llama la función. Note que en la llamada no se encuentra

diferencia entre la llamada por valor y la de por

referencia.

3.4 Arreglos unidimensionales, bidimensionales y

multidimensionales

Arreglos unidimensionalesLos arreglos son listas en memoria de variables del mismo tipo reunidas bajo un

mismo nombre; cada variable de la lista puede ser accesada individualmente

mediante un número el cual corresponde al orden en que son almacenadas, a

este número se le llama índice.

Forma general:

tipo nombre_variable[tamaño]

En C++ todos los arreglos usan el cero como índice del primer elemento.

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 94

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 101/212

 

Ejemplo:

int lista[3];

 Declara un arreglo llamado lista con tres elementos desde “lista[0]” hasta “lista[2]”.

Listado

// fecha.cpp

// elementos del arreglo accesados fuera de un ciclo

#include <iostream>

using namespace std;

int main() {

int fecha[3];

fecha[0] = 1; // mes

fecha[1] = 1; // dia

fecha[2] = 2010; // aa

cout << "Fecha ";

cout << fecha[0] << '/' << fecha[1] << '/' << fecha[2];

return 0;

}

Salida

Fecha 1/1/2010

int fecha[3];Se declara un arreglo de enteros de tres elementos.

fecha[0] = 1;

fecha[1] = 1;

fecha[2] = 2010;

Se le asigna valores al arreglo elemento por elemento.

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 95

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 102/212

 

Ejercicio

1. Modifique el ejemplo anterior (fecha.cpp) para que lea la fecha del teclado.

Listado

// ordena_c.cpp

// Lee un arreglo de enteros y ordena los elementos de mayor a menor

#include <iostream>

using namespace std;

const int TAM = 3;

int main() {

int iCalificacion[TAM], iCalifTemp;int i, j;

cout << "Ingresa calificaciones" << endl;

for (i = 0; i < TAM; i++) {

cout << "Calificacion " << i << "? ";

cin >> iCalificacion[i];

}

 

// Ordena califcaciones en base a la califiacion de mayor a menorfor (i = 0; i < TAM; i++)

for (j = 0; j < TAM; j++) {

// ordena de mayor a menor

if (iCalificacion[i] > iCalificacion[j]) {

// intercambia la califcacion

iCalifTemp = iCalificacion[i];

iCalificacion[i] = iCalificacion[j];

iCalificacion[j] = iCalifTemp;

}}

cout << endl << "Calificaciones de mayor a menor: " << endl;

for (i = 0; i < TAM; i++)

cout << iCalificacion[i] << endl;

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 96

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 103/212

 

return 0;

}

Salida en base a la entrada de ejemplo

Ingresa calificacionesCalificacion 0? 100

Calificacion 1? 90

Calificacion 2? 95

Calificaciones de mayor a menor:

100

95

90

const int TAM=3;

Declara una constante de tipo entero, es decir un almacenamiento con el nombre “TAM” el cual

no puede ser cambiado durante la ejecución del programa.

for (i = 0; i < TAM; i++) {

cout << "Calificacion " << i << "? ";

cin >> iCalificacion[i];

}

Se llena el arreglo dentro del ciclo “for”.

for (i = 0; i < TAM; i++)

for (j = 0; j < TAM; j++) {

// ordena de mayor a menor

if (iCalificacion[i] > iCalificacion[j]) {

// intercambia la califcacion

iCalifTemp = iCalificacion[i];

iCalificacion[i] = iCalificacion[j];iCalificacion[j] = iCalifTemp;

}

}

En estas líneas el arreglo es ordenado en base al valor mayor.

El ordenamiento del arreglo se realiza al comparar el primer elemento del arreglo con todos los

demás y si se cumple la condición, el elemento que es comparado con todos se intercambia, el

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 97

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 104/212

 

segundo con todos y así sucesivamente, en este algoritmo el ciclo interno es el que controla el

ordenamiento, en este caso moviendo el mayor hacia el primer elemento del arreglo.

Ejemplo 1:

Ingresa calificaciones

Calificacion 0? 1

Calificacion 1? 4

Calificacion 2? 7

Calificaciones de mayor a

menor:

7

4

1

Primera pasada:

1 4 7

1 4 7

Segunda pasada:

1 4 7

4 1 7

Tercera pasada:

4 1 7

7 4 1

Ejemplo 2:Ingresa calificaciones

Calificacion 0? 4

Calificacion 1? 1

Calificacion 2? 7

 

Calificaciones de mayor a menor:

1

4

7

Primera pasada:

4 1 7

1 4 7

Segunda pasada:

1 4 7

1 4 7

Tercera pasada:

1 4 7

1 4 7

Este método de ordenamiento es fácil de implementar, pero definitivamente no es el más

eficiente, se puede observar que se pierden ciclos al repetir las comparaciones y redundar el

ordenamiento. Se puede optimizar al pasar el control del ordenamiento al primer ciclo haciendo

lo siguiente:

for (i = 0; i < TAM; i++)

for (j = i+1; j < TAM; j++) {

if (iCalificacion[i] < iCalificacion[j]) {

iCalifTemp = iCalificacion[i];

iCalificacion[i] = iCalificacion[j];

iCalificacion[j] = iCalifTemp;

}

}

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 98

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 105/212

 

Note que se asigna a la variable de control del ciclo interno el valor de la variable de control del

ciclo externo mas uno, para no repetir la comparación, también se cambia la condición de mayor

que a menor que.

 

Ejercicios

1. Modifique el ejemplo anterior (ordena_c.cpp) para que ordene el arreglo de menor 2. Realice

un programa que

a) Pida diez números enteros y los almacene en un arreglo

b) Busque el número menor y el número mayor en el arreglo leído

c) Despliegue el número menor y el número mayor

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 99

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 106/212

 

Comprobación de contornos

El lenguaje C++ no realiza comprobación de contornos en los arreglos. Si se sobrepasa el final

durante una operación de asignación, entonces se asignarán valores a otras variables en

memoria o memoria usada por el propio código del programa, lo que puede provocar resultados

no deseados, o un error que detiene la ejecución del programa. Las comprobaciones son

responsabilidad del programador.

Listado

// for_out.cpp

// Programa que sobrepasa el limite de indexacion

#include <iostream>

using namespace std;

int main() {

int lista[10], i;

for (i = 0; i < 100; i++) {

lista[i] = i;

cout << lista[i] << ' ';

}

return 0;

}

Salida (depende de la ejecución, puede marcar errores de memoria y no haber salida)

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

31 32 33 34 35 36 37 38

Nota:

Este programa compilará bien. Y sirve de ejemplo para la comprobación de los límites del

arreglo.

Arreglos bidimensionales y multidimensionales

Los arreglos multidimensionales son arreglos con más de un índice, por ejemplo

los bidimensionales son arreglos con dos subíndices que son usados para

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 100

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 107/212

 

representar tablas de valores, con información organizada en reglones y

columnas. Para accesar un elemento particular de la tabla hay que identificar el

renglón del elemento seguido por la columna.

Forma general:

tipo nombre[longitud_1][longitud_2]

Ejemplo:

int matriz[3][2];

Declara un arreglo 3 x 2 llamado matriz con seis elementos desde “matriz[0][0]” hasta

“matriz[2][1]”.

Listado

// sumamat.cpp

// Suma dos matrices dejando el resultado en una tercera

#include <iostream>

using namespace std;

const int LON = 2;

int main(){

int i, j, a[LON][LON], b[LON][LON], c[LON][LON];

cout << "Ingresa la matriz A " << endl;

for (i=0; i < LON; i++)

for (j=0; j < LON; j++) {

cout << "A[" << i << "][" << j << " ] = ? ";

cin >> a[i][j];

}

cout << endl << "Ingresa la matriz B " << endl;

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 101

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 108/212

 

for (i=0; i < LON; i++)

for (j=0; j < LON; j++) {

cout << "B[" << i << "][" << j << " ] = ? ";

cin >> b[i][j];

}

 

// Suma las matrices y deja el resultado en una tercera matriz

for (i=0; i < LON; i++)

for (j=0; j < LON; j++)

c[i][j] = a[i][j] + b[i][j];

cout << endl << "El resultado de la suma de A + B es:" << endl;

for (i=0; i < LON; i++) {

for (j=0; j < LON; j++)

cout << c[i][j] << "\t";

cout << endl;

}

return 0;

}

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 102

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 109/212

 

Salida en base a la entrada de ejemplo

Ingresa la matriz A

A[0][0 ] = ? 1

A[0][1 ] = ? 1

A[1][0 ] = ? 1A[1][1 ] = ? 1

Ingresa la matriz B

B[0][0 ] = ? 2

B[0][1 ] = ? 2

B[1][0 ] = ? 2

B[1][1 ] = ? 2

El resultado de la suma de A + B es:

3 3

3 3

int i, j, a[LON][LON], b[LON][LON], c[LON][LON];

Se declaran las variables a ser usadas, “i” y “j” para usarlas como subíndices y tres arreglos de

dos dimensiones.

for (i=0; i < LON; i++)

for (j=0; j < LON; j++) {

cout << "A[" << i << "][" << j << " ] = ? ";

cin >> a[i][j];

}

Se usan dos “for”, el primero para accesar los renglones y el segundo que está dentro del cuerpo

del primer “for” para accesar las columnas.

1 for (i=0; i < LON; i++)

2 for (j=0; j < LON; j++)

3 c[i][j] = a[i][j] + b[i][j];

Se suman los dos arreglos dejando el resultado en el tercer arreglo.

Ejercicio

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 103

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 110/212

 

1 Realice un programa que pida un arreglo de 3x3 y sume la diagonal principal, despliegue la

suma.

Arreglos de más de dos dimensionesUn arreglo de enteros de tres dimensiones de 2 x 2 x 2 se declararía de la siguiente manera:

int cubo[2][2][2];

Para acceder el primer elemento seria:

cubo[0][0][0] = 0; //asigna cero al primer elemento del arreglo tridimensional

Para un arreglo de enteros de cuatro dimensiones de 2 x 2 x 2x2 se declararía de la siguiente

manera:

int cuatridimensional[2][2][2][2];

Para acceder el primer elemento seria:

cuatridimensional [0][0][0][0] = 0; //asigna cero al primer elemento del arreglo

Este tipo de arreglos son raramente usados ya que aumenta la complejidad del programa y

generalmente la solución del problema se pude replantear para evitar complejidades

innecesarias, en caso de que sea inevitable siempre se puede usar este tipo de arreglos.

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 104

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 111/212

 

Arreglos y punteros

Cuando se declara un arreglo el compilador debe asignar una dirección base y la cantidad de

almacenamiento suficiente para alojar a todos los elementos del arreglo. Los punteros y arreglos

se utilizan casi de la misma manera para acceder a la memoria.

Nota

El nombre de un arreglo es una constante que contiene la dirección del inicio del arreglo también

llamado puntero fijo y un puntero es una variable cuyos valores son direcciones.

Listado

// a_apunta.cpp

// Relacion entre arreglos y punteros

#include <iostream>

using namespace std;

int main(){

char cstr1[] = "ARREGLO";

char cstr2[] = "PUNTERO";

char *pc;

cout << "cstr1: " << cstr1 << endl;

cout << "cstr2: " << cstr2 << endl;

pc = cstr1;

cout << "\npc: " << pc;

pc = cstr2;

cout << "\npc: " << pc;

return 0;

}

Salida en base a la entrada de ejemplo

cstr1: ARREGLO

cstr2: PUNTERO

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 105

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 112/212

 

pc: ARREGLO

pc: PUNTERO

char cstr1[] = "ARREGLO";char cstr2[] = "PUNTERO";

Se declaran dos arreglos de caracteres y se inicializan,.

char *pc;

Se declara la variable de tipo puntero.

cout << "cstr1: " << cstr1 << endl;

cout << "cstr2: " << cstr2 << endl;

Se despliega el contenido de cstr1 y cstr2, (líneas 11 y 12).

pc = cstr1;

Se asigna la dirección de la cadena de caracteres y en la siguiente línea se despliega el

contenido de “cstr1” por medio del puntero “pc”.

3.5 Cadenas de caracteresUna cadena de caracteres consiste en un arreglo de caracteres terminado en un nulo. Un nulo

se especifica como '\0'. Si se quiere definir una cadena de 5 elementos se debe definir de 6 para

soportar el carácter nulo.

Ejemplo:

char str[6];

Una constante de cadena es una lista de caracteres que se encierran entre comillas.

Ejemplo:

"HOLA"

Al declarar una constante de cadena el compilador de C++ agregara automáticamente elcarácter nulo al final.

La cadena "HOLA" se vera en memoria así:

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 106

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 113/212

 

Listado

// cadena.cpp// Cadenas de caracteres

#include <iostream>

using namespace std;

int main() {

char s[16];

char s2[] = {'h', 'o', 'l', 'a', '\0'};

char s3[] = "HOLA A TODOS";

cout << endl << "Ingresa una cadena de caracteres ";

// El "cin" por si solo, deja de leer cuando encuentra

// un espacio

cin.getline(s, 15); // para incluir espacios en la cadena

cout << "s=" << s << endl

<< "s2=" << s2 << endl

<< "s3=" << s3 << endl;

s3[5] = '\0';

cout << "s3=" << s3 << endl;

return 0;

}

Salida en base a la entrada de ejemplo

Ingresa una cadena de caracteres Issac Asimov

s=Issac Asimov

s2=hola

s3=HOLA A TODOS

s3=HOLA

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 107

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 114/212

 

char s[16];

Declara un arreglo de caracteres.

char s2[] = {'h', 'o', 'l', 'a', '\0'};

Se declara un arreglo de caracteres y se inicializa, este tipo de inicialización en arreglos solo es

permitido al momento de declarar el arreglo.

La asignación del elemento '\0' al final del arreglo es para tratar el arreglo como una cadena de

caracteres. Hay que notar que no se indica cuantos elementos tiene el arreglo; como se está

inicializando se deja la cantidad fuera de la declaración para que el compilador incluya la

cantidad en “s2[]”.

char s3[] = "HOLA A TODOS";

Se declara un arreglo de caracteres y se inicializa con una cadena de caracteres. Al hacer la

inicialización de esta forma, el compilador incluye además de la cantidad de elementos en “s3[]”

el carácter “\0” al final, este tipo de inicialización en arreglos solo es permitido al momento de

declarar el arreglo.

La cadena s3 se vería en memoria así:

s3[5] = '\0';

Se asigna el carácter nulo en el quinto elemento, por lo tanto:

La cadena s3 se vería en memoria así:

cout << s3 << endl;

Despliega la cadena “s3”, siendo la salida “HOLA ”, porque el “cout” se detiene al encontrar el

primer carácter '\0' que es el que indica el fin de cadena.

Listado

// mayusculas.cpp

// Convierte una cadena de caracteres a mayusculas

#include <iostream>

using namespace std;

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 108

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 115/212

 

char mensaje[80];

void mayusculas(void) {

int i;

for (i = 0; mensaje[i] != '\0'; i++)

mensaje[i] = toupper(mensaje[i]);

}

main() {

cout << "\Ingresa un mensaje ";

cin.getline(mensaje, 79);

mayusculas();

cout << "\nEl mensaje en mayusculas es " << mensaje;

}

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 109

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 116/212

 

Salida

Ingresa un mensaje issac asimov

El mensaje en mayusculas es ISSAC ASIMOV

char mensaje[80];

Se declara una cadena de caracteres global para las

funciones que están abajo de ésta.

void mayusculas(void) {

El primer “void” significa que la función no regresa nada,

actúa como un procedimiento. “mayusculas” es el nombre de la

función y “void” dentro de los paréntesis significa que la

función no recibe parámetros.

En el cuerpo de la función se convierte cada elemento de la

cadena de caracteres a mayúsculas.

mayusculas();

Manda llamar la función.

Ejercicios

1. Realice un programa que ingrese y despliegue una cadena de caracteres elemento por

elemento.

2. Hacer un programa que lea y almacene una cadena caracteres con un máximo de 80

caracteres y despliegue la cadena en mayúsculas, investigue el uso de la función toupper ()

(#include <ctype>)

3. Hacer un programa que lea y almacene una cadena caracteres con un máximo de 80

caracteres y despliegue la cadena en orden inverso, recuerde que el carácter nulo ‘\0’ indica

el fin del texto.

Apuntadores a caracteres

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 110

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 117/212

 

Si se declara mensaje como:

char *mensaje;

 

La sentencia:

mensaje = "esta es una cadena"

Asigna a mensaje un apuntador a los caracteres. No es la copia de una cadena.

Listado

// strlen_punteros.cpp

// Ejemplo de como puede estar implementada la funcion de la

// biblioteca estandard strlen (implementada usando apuntadores)

int strlen(char *s) {

char *p = s;

while (*p != '\0')

p++;

return p-s;

}

Ejercicios

1. Analice como es que la función cuenta el número de caracteres contenidos en la cadena

2. Implemente la función “main” para probar la función

Listado

// copia_cadena.cpp

// Copia origen a destino usando apuntadores

#include <iostream>

using namespace std;

void copia_cadena(char *destino, char *origen) {

do {

*destino = *origen;

destino++;

origen++;

} while(*origen != '\0');

*destino = *origen; // copia el caracter '\0'

}

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 111

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 118/212

 

int main(){

char str1[80], str2[80];

cout << "Ingresa un string ";

cin.getline(str1, 79);

 

copia_cadena(str2, str1);

cout << str2 << endl;

 

return 0;

}

Salida en base a la entrada de ejemplo

Ingresa un string Bjarne Stroustrup

Bjarne Stroustrup

Ejercicio

1. Escriba una función str_busca(str, c) que reciba un apuntador a una cadena de caracteres

str, y un carácter c. Busque el carácter en la cadena y regrese la posición en que se

encuentra el carácter en la cadena o un -1 si no se encuentra utilizando apuntadores.2. Realice una función concatena(str1, str2) que agregue la cadena de caracteres str2 al final

de la cadena str1.

3. Realice una función reversa(str) que reciba un apuntador a una cadena de caracteres e

invierta la cadena. Utilizando apuntadores.

Aritmética de punteros

Ejemplo:

Teniendo:int n[3] = {1, 2, 3}, *p;

Las siguientes sentencias son equivalentes; ambas asignan la dirección de inicio del

arreglo al puntero p.

p = n;

p = &n[0];

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 112

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 119/212

 

fig5. Simplificación de memoria, maquina de 16 bits

Las siguientes sentencias son equivalentes; ambas asignan la dirección de memoria del

segundo elemento al puntero p.

p = n + 1;

p = &n[1];

fig6. Simplificación de memoria, maquina de 16 bits

Las siguientes sentencias son equivalentes para accesar el contenido de un elemento:

n[i];

*(p+i)

Las siguientes sentencias son equivalentes para accesar la dirección de un elemento:&n[i];

n+i;

Un apuntador es una variable, por lo que son correctas las siguientes operaciones:

p = n;

p++;

El nombre de un arreglo es una constante; así que son ilegales construcciones como:

n = p;n++;

p = &n;

n = n + 2;

Listado

// aritmetica_puntero.cpp

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 113

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 120/212

 

// Aritmetica de punteros

#include <iostream>

using namespace std;

int main() {

char *p, s[] = "ABCDEFG";

p = s;

// despliega la cadena a traves del puntero

cout << endl << p // toda la cadena

<< endl << p[0] // un elemento, el primero

<< endl << *(p+1) // un elemento, el segundo

<< endl << p+2; // a partir del tercer elemento

return 0;

}

Salida

ABCDEFG

A

B

CDEFG

char *p, s[] = "ABCDEFG";

Se declara un carácter, una cadena de caracteres y un puntero a caracteres, que se utiliza para

accesar el contenido de la cadena y del carácter en el resto del programa.

 

p = s;

Se asigna la dirección de s al puntero p.

cout << endl << p[0]

Despliega el primer elemento de la cadena s indirectamente, esto es equivalente a decir *p, el

contenido de donde apunta p.

<< endl << *(p+1)

Despliega, el contenido del segundo elemento de s, esto es equivalente a p[1], aquí se realiza

primero la operación de lo que esta entre paréntesis, se incrementa la dirección del puntero y

después accesa el contenido de la dirección que contiene p después de la suma *(p+1).

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 114

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 121/212

 

<< endl << p+1;

Incrementa el contenido de la variable (en una dirección –note que esto solo es temporalmente)

y despliega la cadena a partir de la dirección del elemento 2, como se muestra.

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 115

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 122/212

 

3.6 Asignación dinámica de memoriaManejar la memoria dinámicamente es útil cuando no se sabe la cantidad o el tipo de objeto

hasta que el programa está en ejecución, o cuando se quiere que los objetos no estén sujetos a

las reglas normales de alcance definidas por el lenguaje.

Normalmente se definen y se usan los objetos en tiempo de compilación, el manejo dinámico de

la memoria libera de la limitante de saber todo al tiempo de compilación, permitiendo crear y

destruir objetos en tiempo de ejecución.

new

Aloja memoria dinámicamente, regresa un apuntador a la memoria alojada. Si falla resulta una

excepción “bad_alloc”.

Ejemplo:

int *n;n = new int;

Aloja memoria suficiente para almacenar un entero.

delete

Desaloja un bloque de memoria dinámica que ha sido previamente alojado por el operador

“new”. El desalojo de memoria la libera para su reutilización.

Ejemplo:

int *n;n = new int;

delete n;

Desaloja la memoria que fue separada por “new” y asigna un nulo al puntero.

Listado

// new_del.cpp

// ejemplo de manejo dinámico de memoria// Operadores new y delete con un arreglo

#include <iostream>

using namespace std;

int main() {

int *ca;

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 116

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 123/212

 

ca = new int[3]; // Toma memoria para el arreglo

ca[0] = 8;

ca[1] = 21;

ca[2] = 2020;

cout << "Fecha ";

cout << ca[0] << '/' << ca[1] << '/' << ca[2];

 

delete []ca; // Regresa la memoria al almacenamiento libre

return 0;

}

Salida

Fecha 8/21/2020

int *ca;

Se declara un puntero a enteros.

ca = new int[3];

“new”, separa memoria necesaria para almacenar 3 enteros y le asigna la dirección de inicio del

bloque de memoria separado.

En el programa se trata el bloque como un arreglo normal (los arreglos y el manejo de punteros

esta íntimamente ligado) y se le asigna enteros a cada elemento.

delete []ca;

Se libera el bloque de memoria separado anteriormente con el operador “new”.

Listado

// asientos.cpp

// anejo dinámico de memoria utilizando un arreglo de strings,

// el programa administra un lugar con asientos numerados.

#include <iostream>

#include <string>

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 117

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 124/212

 

using namespace std;

int main() {

int total_asientos, numero, i;

string *asiento;

 

cout << "\nCantidad de asientos con que cuenta el local? ";

cin >> total_asientos; // Toma la longitud del arreglo

asiento = new string[total_asientos]; // Aloja el arreglo

do {

for (i=0; i < total_asientos; i++)

cout << endl << "Asiento " << i

<< ": " << asiento[i];

cout << endl << "Numero de Asiento? (-1 termina)";

cin >> numero;

 

if (numero < 0)

break;

cout << "Nombre ";

cin >> asiento[numero];

} while(1);

 

delete []asiento;

return 0;

}

Salida en base a la entrada de ejemploCantidad de asientos con que cuenta el local? 3

Asiento 0:

Asiento 1:

Asiento 2:

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 118

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 125/212

 

Numero de Asiento? (-1 termina)1

Nombre Batman

Asiento 0:

Asiento 1: BatmanAsiento 2:

Numero de Asiento? (-1 termina)0

Nombre Superman

Asiento 0: Superman

Asiento 1: Batman

Asiento 2:

Numero de Asiento? (-1 termina)

string *asiento;

Se declara un puntero a string

asiento = new string[total_asientos];

Se crea un bloque de memoria suficiente para almacenar el número asignado a la variable

“total_asientos”.

El resto del programa muestra los elementos y se accesa el elemento seleccionado por elusuario, en caso de que el numero sea -1 se cumple la condición del “if” y se ejecuta la

instrucción “break” que termina el ciclo “do .. while”

delete []asiento;

“delete”, regresa el bloque de memoria al almacenamiento libre.

Ejercicio

Modifique el programa ordena_c.cpp para que pida la cantidad

de calificaciones al momento de ejecución, es decir cree el

arreglo dinámicamente

Punteros a estructuras y manejo de memoria dinámica

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 119

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 126/212

 

El uso de punteros es para generar llamadas por referencia al llamar una función, para crear

listas encadenadas así como estructuras dinámicas de datos.

Cuando un puntero a estructura es pasado a una función, solo la dirección de la estructura es

puesta en el stack de datos. Esto permite unas llamadas muy rápidas a las funciones.

Ejemplo:

struct bal {

float balance;

char nombre[40];

} persona;

Declarando un apuntador a estructura.

struct bal *p;

Esto pone la dirección de la estructura persona en el apuntador p:

p = &persona;

Para accesar los elementos de la estructura usando un apuntador a esa estructura, usamos:

(*p).balance;

Los paréntesis son necesarios alrededor del apuntador porque el operador punto (.) tiene mayor

prioridad mayor que el operador *.

El segundo método de acceso es utilizando el operador ->; lo cual nos facilita la programación.

Ejemplo:

p->balance;

Para usar asignar memoria dinámica usamos el operador “new”.

Ejemplo:

p = new bal;

Listado

// newstruct.cpp

// ejemplo del manejo de memoria dinamica con estructuras.

// Los operadores new y delete

#include <iostream>

using namespace std;

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 120

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 127/212

 

struct Fecha {

int mes;

int dia;

int ayo;

};

int main() {

Fecha *fecha = new Fecha; // Toma memoria para una fecha

 

fecha->mes = 3;

fecha->dia = 30;

fecha->ayo = 1968;

cout << "\nFecha: "

<< fecha->mes << '/'

<< fecha->dia << '/'

<< fecha->ayo;

 

delete fecha; // Regresa la memoria al almacenamiento libre

return 0;

}

Salida

Fecha: 3/30/1968

Fecha *fecha = new Fecha;

Se declara el puntero de tipo estructura “Fecha”, y se

inicializa con la dirección de inicio del bloque de memoria

alojado con el operador “new”.

Operador ->

fecha->mes = 3;

Es equivalente a:

(*fecha).mes

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 121

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 128/212

 

los paréntesis son necesarios ya que el punto (.) tiene

mayor procedencia que el asterisco (*) y sin ellos la

expresión:

*fecha.mes

Significa:

(*fecha.mes)

Lo cual es ilegal porque “mes” no es un puntero.

Nota:

El operado “->” se implemento ya que los punteros a

estructuras son bastante comunes.

Arreglo de punteros y manejo de memoria dinámica

Los apuntadores son variables, así que los podemos almacenar en un arreglo.

Declaración:int *x[10];

Asignación:

x[2] = &v;

Encontrar el valor de v.

*x[2]

Diferencias de arreglos bidimensionales y arreglos de punterosEjemplo sin punteros:

char cap[3][32] = {

"introduccion",

"tipos, operadores y expresiones",

"control de flujo" // No se pone coma

};

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 122

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 129/212

 

 

introduccion\0tipos, operadores y expresiones\0control de flujo\0

Se separan 96 bytes de almacenamiento, siempre, sin importar si se usan o no.

Ejemplo con punteros:

char *cap[3] = {

"introduccion",

"tipos, operadores y expresiones",

"control de flujo"

};

2000 3000 3000 introduccion\02000 3001 3001 tipos, operadores y expresiones\0

2002 3002 3002 control de flujo\0

Se separa solo 63 bytes de almacenamiento + 6 bytes para el almacenamiento de los

punteros, es decir solo el espacio estrictamente requerido.

Listado

// nombres.cpp

// Manejo de memoria dinamica, arreglo de punteros

#include <iostream>

using namespace std;

const int LIMITE=5;

int main() {

char str[80], *nombre[LIMITE];

int i;

cout << "Ingresa una lista de nombres" << endl;

for (i=0; i < LIMITE; i++) {

cout << i << ".-Nombre ? ";

cin.getline(str, 79);

// Asigna memoria al elemento i del arreglo nombre

nombre[i] = new char[strlen(str)+1];

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 123

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 130/212

 

strcpy(nombre[i], str); // Copia str a nombre

}

cout << endl << "Lista de nombres:" << endl;

for (i=0; i < LIMITE; i++)

cout << i << ".- " << nombre[i] << endl;

// desaloja la memoria

for (i=0; i < LIMITE; i++)

delete nombre[i];

return 0;

}

Salida en base a la entrada de ejemplo

Ingresa una lista de nombres

0.-Nombre ? Stroustrup

1.-Nombre ? Abrash

2.-Nombre ? Lamothe

3.-Nombre ? Schildt

4.-Nombre ? Kernighan

Lista de nombres:

0.- Stroustrup

1.- Abrash

2.- Lamothe

3.- Schildt

4.- Kernighan

Ejemplo de Asignación de memoria dinámica con punteros a punteros

Listado

// punteros_punteros.cpp

// manejo de memoria dinamica, punteros a punteros

// Modificacion del programa nombres.cpp

#include <iostream>

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 124

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 131/212

 

using namespace std;

int main() {

char str[80], **nombre;

int i, n;

cout << endl << "Cantidad de elementos en la lista ? ";

cin >> n;

// Desecha el ultimo caracter del buffer de entrada

// en este caso el caracter nueva linea: '\n'

cin.ignore();

nombre = new char *[n];

cout << endl << "Ingresa una lista de nombres";

 

for (i=0; i < n; i++) {

cout << endl << i << ".-Nombre? ";

cin.getline(str, 79);

 

// Asigna memoria a nombre

nombre[i] = new char[strlen(str)+1];

// Copia str a nombre

strcpy(nombre[i], str);

}

 

cout << endl << "lista de nombres";

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

cout << endl << i << ".-Nombre? " << nombre[i];

 

// desaloja la memoria de cada elemento

for (i=0; i < n; i++)delete nombre[i];

 

// Desaloja el total de elementos

delete nombre;

return 0;

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 125

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 132/212

 

}

Salida en base a la entrada de ejemplo

Cantidad de elementos en la lista ? 3

Ingresa una lista de nombres

0.-Nombre? Bill Watterson

1.-Nombre? Charles M. Schulz

2.-Nombre? Jim Davis

lista de nombres

0.-Nombre? Bill Watterson1.-Nombre? Charles M. Schulz

2.-Nombre? Jim Davis

Argumentos para “main”

Algunas veces es necesario pasar información al programa cuando antes de ejecutarse; esta

información se pasa a la función “main” vía la línea de argumentos.

Argumentos en la línea de comandos

Es la información que sigue incluyendo el nombre del programa en la línea de comandos del

sistema operativo separada por espacios.

Cuando se invoca a “main” al comienzo de la ejecución se llama con dos argumentos llamados

por costumbre: “argc” y “argv”.

argc

Contiene el número de argumentos que están presentes en la línea de comandos cuando seinvoco el programa.

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 126

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 133/212

 

argv

Variable tipo puntero que contiene la dirección al inicio de un arreglo de cadenas de caracteres.

Este arreglo contienen los argumentos donde cada cadena contiene un argumento.

Ejemplo:

1.- Hacer ejecutable el programa llamado arg.exe por ejemplo.

2.- Ejecutarlo: arg buenos días

Nota:

Es un arreglo de apuntadores. “argc” siempre será 1 porque el primer argumento es el nombre

del programa (algunos sistemas operativos incluyen el “path”).

Listado

// args.cpp// argumentos en la linea de comandos

#include <iostream>

using namespace std;

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

int i;

cout << "Numero de Argumentos " << argc;

for (i = 0; i < argc; i++)cout << endl << i << " - " << argv[i];

return 0;

}

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 127

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 134/212

 

Salida

Numero de Argumentos 4

0 - args

1 - uno

2 - 2

3 - tres

3.7 Uso de clases predefinidas para arreglosClase vector

Útil para trabajar con cierta cantidad de datos desconocidos y arreglos, pues permite manejar

dinámicamente objetos en dichos arreglos, pudiendo crearlos de clases y variables expandiendo

o contrayendo el arreglo. Se encuentra definida en el archivo de encabezado “vector”

Listado

// vector.cpp

// ejemplo de la clase vector

#include <vector>

#include <iostream>

using namespace std;

int main() {

//Declara un vector simple

vector<int> enteros;

int i, num;

cout << "Ingresa un numero: ";

cin >> num;

// agrega un elemento al final del vector

enteros.push_back(num);

// accede a una posicion del vector y se muestra su longuitud

cout << endl << "En la posicion 0 esta: " << enteros[0]

<< endl << "Longitud del vector : " << enteros.size()

<< endl << "Capacidad del vector : " << enteros.capacity()

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 128

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 135/212

 

<< endl << "Longitud maxima del vector: "

<< enteros.max_size();

// vacia el vector

enteros.clear();

// agrega 10 elementos al vector

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

enteros.push_back(i);

for (i=0; i < 10; i++)

cout << endl << enteros[i];

cout << endl << "Ahora hay en el vector: "

<< enteros.size() << " elementos\n";

//Elimina el ultimo elemento del vector

enteros.pop_back();

cout << endl << "Hay en el vector: "

<< enteros.size() << " elementos\n";

return 0;

}

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 129

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 136/212

 

Salida

Ingresa un numero: 55

En la posicion 0 esta: 55

Longitud del vector : 1Capacidad del vector : 1

Longitud maxima del vector: 1073741823

1

2

3

4

5

6

7

8

9

10

Ahora hay en el vector: 10 elementos

Hay en el vector: 9 elementos

Ejercicio

1. Modifique el ejemplo de la pagina 89 (fecha.cpp) para que use la clase vector en vez de un

arreglo.

2. Modifique el ejemplo de la pagina 90 (ordena_c.cpp) para que use la clase vector en vez de

un arreglo.

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 130

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 137/212

 

Capitulo 4Clases y objetos

4.1 Definición de una claseUna clase es un método lógico de organizar datos y funciones en una misma estructura. La clase

es un patrón a seguir al crear objetos.

Al definir una clase se define un tipo de dato definido por el usuario, y este tipo sirve para crear

instancias de este tipo de dato, a estas instancias se le llama objetos.

La definición de clase es el proceso de definir cuales serán sus propiedades y métodos; proceso

que crea un nuevo tipo de dato.

4.2 Declaración de clasesLa declaración de clase es la asignación de un nombre; una sentencia que establece la

conexión entre el identificador y el objeto que representa (en este caso una clase). La

declaración asocia el nombre con un tipo de dato, lo que supone definir como se usa, que

operaciones son permitidas y que sentido tienen estas operaciones.

Ejemplo:

class mi_clase;

Con frecuencia la declaración y definición de una clase ocurren simultáneamente en la misma

sentencia, igual que con las variables normales,

Forma general:

class nombre_de_la_clase {

etiqueta_de_nivel_de_permiso_1:

miembros1;

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 132

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 138/212

 

etiqueta_de_nivel_de_permiso_2:

miembros2;

...

} nombre_del_objeto;

4.3 Miembros de una claseTodo lo que esta definido dentro de la clase se dice que es miembro de ésta, como variables,

arreglos, funciones etc.

Las etiqueta_de_nivel_de_permiso se refieren al control de acceso a miembros del objeto. Por

defecto los miembros de una clase son privados.

4.4 Ambito referente a una claseUna clase actúa como cualquier otro tipo de dato con respecto al ámbito. Todos los miembros de

una clase se dice que están en el ámbito de esa clase; cualquier miembro de una clase puede

referenciar a cualquier otro miembro de la misma clase.

Las funciones miembro de una clase tienen acceso no restringido a los miembros dato de esa

clase. El acceso a los miembros dato y funciones de una clase fuera del ámbito de la clase está

controlado por el programador. La idea es encapsular la estructura de datos y funcionalidad de

una clase, de modo que el acceso a la estructura de datos de la clase desde fuera de las

funciones miembro de la clase, sea limitada o innecesaria. El nombre de la clase tiene que ser

único dentro de su ámbito.

4.5 Especificadores de accesoprivate

Los miembros que le siguen a esta palabra reservada solo pueden ser accesados por lasfunciones miembro declaradas dentro de la misma clase.

protected

Los miembros que le siguen a esta palabra reservada solo pueden ser accesados por las

funciones miembro dentro de la misma clase, y por las funciones miembro de las clases que son

derivadas de esta clase.

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 133

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 139/212

 

public

Los miembros que le siguen a esta palabra reservada pueden ser accesados en cualquier lugar

dentro del alcance de la clase.

La funcionalidad que brinda el control de acceso “protected” es usada principalmente cuando se

prevé que la clase creada va a ser heredada; este tipo de acceso se cubre en el capitulo de

herencia.

La funciones están implementadas dentro de la definición de

la clase, si cumplen con las especificaciones de una función

“inline” el compilador las implementa como tales (ver

capitulo de subprogramas).

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 134

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 140/212

 

4.6 Creación de objetosUn objeto es una instancia de una clase, la clase es el tipo de dato y el objeto es la variable.

Cuando un objeto de la clase es creado, este tendrá su propia copia de las variables miembros

que contiene la clase.

En el siguiente ejemplo se crea una clase para derivar un objeto para representar un emoticon.

Los emoticones son una secuencia de caracteres comúnmente utilizados en la transmisión de

texto mediante correo electrónico, estas secuencias representan una abreviación de palabras y/o

emociones, como por ejemplo “:)” significa sonreír; “:-D” reír a carcajadas, etc.

Listado

// emoticon.cpp

#include <iostream>

#include <string>

using namespace std;

class CEmoticon {

private:

string m_sIcon;

public:

void Muestra(void){

cout << "\n" << m_sIcon;

}

void Apariencia(string a_sIcon){

m_sIcon = a_sIcon;

}

};

int main(){

CEmoticon objeto_icon1; // Declara un objeto de tipo CEmoticon

CEmoticon objeto_icon2;

 

objeto_icon1.Apariencia(":O");

objeto_icon2.Apariencia(":]");

objeto_icon1.Muestra();

objeto_icon2.Muestra();

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 135

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 141/212

 

cout << endl;

objeto_icon1.Apariencia(":)");

objeto_icon1.Muestra();

objeto_icon2.Muestra();

return 0;

}

Salida

:O

:]

:)

:]

class CEmoticon {

Se declara la clase “CEmoticon” usando la palabra reservada “class” seguida del nombre de la

clase.

private:

string m_sIcon;

La palabra “private” específica que todos los miembros que le siguen hasta que se encuentre

con otro especificador o el fin de la clase, solo podrán ser accesados por otros miembros de

esta clase, en este caso “m_sIcon” que es de tipo “string”.

public:

void Muestra(void){

cout << "\n" << m_sIcon;

}

void Apariencia(string a_sIcon){

m_sIcon = a_sIcon;

}

Se declaran los miembros que pueden ser accesados en cualquier parte donde se este usando

una instancia de esta clase (objeto).

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 136

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 142/212

 

La función miembro “Muestra()” es usada para desplegar el contenido de la variable privada

“m_sIcon” y la función Apariencia() para cambiar el valor de esta variable.

Nota:

Las funciones miembro solo pueden ser llamadas en asociación de un objeto, a diferencia de las

funciones definidas fuera de una clase.

Las funciones en el ejemplo anterior serían innecesarias si se declarara la variable “m_sIcon”

como publica pero esto iría en contra de la ocultación de la información que es uno de los

principios fundamentales de la programación orientada a objetos.

Al definir la clase utilizando miembros privados y públicos, se puede decir que un objeto tiene un

estado interno (miembros privados) y operaciones externas (miembros públicos).

objeto_icon1.Apariencia(":O");

objeto_icon2.Apariencia(":]");

Cada objeto llama la función “Apariencia()” para cambiar sus respectivas variables “m_sIcon”.

objeto_icon1.Muestra();

objeto_icon2.Muestra();

Los objetos despliegan el valor de la variable privada “m_sIcon” mediante sus funciones miembro

“Muestra()”.

objeto_icon1.Apariencia(":)");

objeto_icon1.Muestra();

objeto_icon2.Muestra();

Se llama otra vez la función “Apariencia()” asociada al “objeto_icono1” y en las se vuelven a

desplegar el contenido de las variables de cada objeto.

Ejercicio

Cree una clase Persona que contenga el nombre, dirección, teléfono y una función para

actualizar y otra para desplegar los datos.

4.7 Puntero this

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 137

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 143/212

 

Cada vez que se crea una instancia de una clase, el objeto ocupa espacio en memoria y “this” es

la palabra reservada con el valor de la dirección en memoria del objeto que está siendo

ejecutado.

En un objeto, “this” es un puntero a si mismo, éste es utilizado implícitamente para referenciar

todos los miembros del objeto; también puede ser utilizado en forma explicita.

El siguiente ejemplo es una modificación a la clase “CFecha” e incluye una función miembro que

recibe una referencia a un objeto del mismo tipo y comprueba si los datos que contienen los

objetos son iguales o diferentes, además comprueba sí trata de si mismo.

Listado

// cfechacompara.h

#pragma once

class CFecha {

private:

int mm, dd, aa;

public:

CFecha(int a_dd, int a_mm, int a_aa) {

mm = a_mm;

dd = a_dd;

aa = a_aa;

}void Fecha();

void Compara(CFecha &fecha);

};

void Compara(CFecha &fecha);

Esta función recibe una referencia a la clase “CFecha” (a sí misma).

Listado

// cfechacompara.cpp

#include "cfechacompara.h"

#include <iostream>

using namespace std;

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 138

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 144/212

 

void CFecha::Fecha() {

cout << dd << '/' << mm << '/'<< aa;

}

void CFecha::Compara(CFecha &fecha) {

if (&fecha == this) {

cout << "Fechas iguales, mismo objeto";

return;

}

// if (fecha.mm == this.mm

// && fecha.dd == this.dd & fecha.aa == this.aa)

if (fecha.mm == mm && fecha.dd == dd & fecha.aa == aa)

cout << "Fechas iguales";

else

cout << "Fechas diferentes";

}

if (&fecha == this) {

cout << "Fechas iguales, mismo objeto";

return;

}

Se compara la dirección en memoria de la referencia al objeto recibido con la dirección actual del

objeto que recibió la referencia, usando el “this”.

//if (fecha.mm == this.mm

// && fecha.dd == this.dd & fecha.aa == this.aa)

Las líneas que aparecen como comentario son idéntica en funcionalidad a las siguientes líneas:

if (fecha.mm == mm && fecha.dd == dd & fecha.aa ==

aa)

cout << "Fechas iguales";

elsecout << "Fechas diferentes";

Listado

// testcfechacompara.cpp

#include <iostream>

#include "cfechacompara.h"

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 139

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 145/212

 

using namespace std;

int main() {

CFecha f1(10, 1, 05);

CFecha f2(22, 1, 05);

f1.Fecha();

cout << "\t\t";

f1.Compara(f1);

cout << endl;

 

f2.Fecha();

cout << "\t\t";

f2.Compara(f1);

return 0;

}

Salida

10/1/5 Fechas iguales, mismo objeto

22/1/5 Fechas diferentes

CFecha f1(10, 1, 05);

CFecha f2(22, 1, 05);

Se declaran dos objetos de tipo “CFecha” y se inicializan mediante su constructor.

f1.Compara(f1);

El objeto “f1” manda llamar la función “Compara()” y le manda la dirección de sí mismo.

f2.Compara(f1);

El objeto “f2” manda llamar la función “Compara()” y le manda la dirección del objeto “f1”.

Ejercicios

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 140

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 146/212

 

3. Agregue funciones miembro a la clase “CFecha” en cfecha.h y cfecha.cpp para que actualice

el año, el mes y el día independientemente, así como funciones para que regrese solo el

año, mes y día respectivamente.

4. Hacer un programa con una clase hora que implemente una funcionalidad parecida a la de la

clase de fecha.

4.8 Constructores y destructoresConstructores

Los constructores son utilizados para inicializar variables miembro porque estas no se pueden

inicializar en el momento en que son declaradas.

Un constructor es una función miembro con el mismo nombre que la clase y no debe regresar un

valor; solo es usada para inicializar los datos del objeto. Las funciones constructor son llamadas

automáticamente cuando se crea un objeto (Una variable del tipo de la clase) sin necesidad de

hacer referencias a éstas.

Por ejemplo si el objeto tiene variables que se deben inicializar a cero o separar memoria

dinámicamente, estas operaciones se incluyen dentro del constructor.

El siguiente programa es una modificación del ejemplo anterior y muestra el uso de un

constructor y presenta como implementar las funciones miembro fuera de la interfase de la clase.

Listado

// emoticon2.cpp

#include <iostream>

#include <string>

using namespace std;

class CEmoticon {

private:

string m_sIcon;

public:

CEmoticon() { Apariencia(":|"); }

void Muestra(void){

cout << endl << m_sIcon;

}

void Apariencia(string a_sIcon);

};

void CEmoticon::Apariencia(string a_sIcon) {

m_sIcon = a_sIcon;

}

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 141

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 147/212

 

int main(){

CEmoticon objeto_icon1; // Declara un objeto de tipo CEmoticon

CEmoticon objeto_icon2;

objeto_icon1.Muestra();

objeto_icon2.Muestra();

cout << endl;

objeto_icon1.Apariencia(":D");

objeto_icon1.Muestra();

objeto_icon2.Muestra();

return 0;

}

Salida

:|

:|

:D

:|

CEmoticon() { Apariencia(":|"); }

La función “CEmoticon()” tiene el mismo nombre de la clase, por lo tanto es una función

constructor y esta es llamada automáticamente cuando se crean instancias de la clase.

Nótese que en el cuerpo de la función constructor se llama la función miembro “Apariencia()”,

aquí no se necesita el nombre del objeto, porque automáticamente se usa el objeto que se este

ejecutando (ver el operador “this”, al final de este capitulo)

En vez de llamar el método “Apariencia()” la función miembro anterior se pudo haber escrito

como:

CEmoticon() { m_sIcon = ":|"; }

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 142

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 148/212

 

void Apariencia(string a_sIcon);

A diferencia de la función miembro “Muestra()” la cual esta completamente implementada dentro

de la clase (En forma “inline”, ver capitulo de subprogramas), aquí solo se incluye el encabezado

de la función (El prototipo, ver capitulo de subprogramas) para indicar que pertenece a la clase, y

la implementación de la misma se realiza fuera de la declaración de la clase. El análisis de esta

manera de crear las clases se discute en el siguiente tema en este capitulo: “Clases y módulos”.

void CEmoticon::Apariencia(string a_sIcon) {

m_sIcon = a_sIcon;

}

Usando el nombre de la clase “CEmoticon” y el operador de alcance “::” se implementa la función

“Apariencia()” fuera de la declaración de la clase.

CEmoticon objeto_icon1; // Declara un objeto de tipo

CEmoticon

CEmoticon objeto_icon2;

Al declarar los objetos “objeto_icon1” y “objeto_icon2” se llama automáticamente la función

constructor “CEmoticon()”.

objeto_icon1.Muestra();

objeto_icon2.Muestra();

Muestra el contenido de cada objeto, a diferencia del ejemplo anterior esto se hace sin antes

llamar la función “Apariencia()” gracias a que el constructor ha inicializado la variable miembro

“m_sIcon” al crear los objetos.

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 143

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 149/212

 

Ejercicio

Discuta cuales son las ventajas y desventajas de usar constructores como inicializadores de las

variables miembro.

Clases y módulos

Al diseñar una clase es conveniente separar la interfase de la implementación, “la interfase dice

aquí está como es el objeto y estos son los métodos del objeto, la implementación muestra cómo

los métodos trabajan” [Eckel 1993]

La declaración de la clase es la interfase en C++, que a excepción de las funciones

implementadas dentro de la clase, solo indica cómo es el objeto. La práctica en C++ es escribir

la declaración de la clase en un archivo de encabezado y la implementación en un archivo con

extensión cpp.

La siguiente aplicación muestra una clase con una función constructor con argumentos y cómo

mandarle los argumentos al constructor al crear el objeto; también sigue la práctica común en C+

+ de crear un archivo de encabezado con la especificación de la clase y un archivo de código

(.cpp) con la implementación de la clase.

Listado

// cfecha.h

// clase implementada con módulos

// un constructor con argumentos

#pragma once

class CFecha {

private:

int mm, dd, aa;

public:

CFecha(int a_dd, int a_mm, int a_aa) {

mm = a_mm;

dd = a_dd;

aa = a_aa;

}

void Fecha();

void FechaCompleta();

};

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 144

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 150/212

 

CFecha(int a_dd, int a_mm, int a_aa) {

Se implementa el constructor con argumentos.

Listado

// cfecha.cpp// Implementacion de la clase cfecha

#include "cfecha.h"

#include <iostream>

using namespace std;

void CFecha::Fecha() {

cout << dd << '/' << mm << '/'<< aa;

}

void CFecha::FechaCompleta() {

char *meses[] = {

"Enero", "febrero", "Marzo", "Abril",

"Mayo", "Junio", "Julio", "Agosto",

"Septiembre", "Octubre", "Noviembre", "Diciembre"

};

cout << dd << " de " << meses[mm-1] << " del " << (2000 + aa);}

En este archivo se implementan dos de las funciones miembro de la clase definida en el archivo

de encabezado, esto permite incluir la clase en varias aplicaciones ya que la función “main()” no

está en este archivo.

char *meses[] = {

"Enero", "febrero", "Marzo", "Abril",

"Mayo", "Junio", "Julio", "Agosto",

"Septiembre", "Octubre", "Noviembre", "Diciembre"

};

Declara un arreglo de cadenas de caracteres y se inicializa con los nombres de los meses del

año.

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 145

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 151/212

 

cout << dd << " de " << meses[mm-1] << " del " << (2000 +

aa);

Despliega la fecha completa usando las variables con el numero de día, el numero de mes como

índice del arreglo de nombres de los meses (menos uno ya que los arreglos en C++ empiezan

en cero) y el numero de año mas el milenio “meses[mm-1] “ (claro que esta clase solo es útil sise utiliza en este milenio, pero espero que para entonces salga una edición nueva de este libro

con los ajustes necesario )

Listado

// testcfecha.cpp

#include <iostream>

#include "cfecha.h"

using namespace std;

int main() {

CFecha f1(10, 1, 9);

CFecha f2(15, 1, 10);

f1.Fecha();

cout << "\t\t";

 

f1.FechaCompleta();

cout << endl;

 

f2.Fecha();

cout << "\t\t";

f2.FechaCompleta();

 

return 0;

}

Salida

10/1/9 10 de Enero del 2009

15/1/10 15 de Enero del 2010

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 146

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 152/212

 

CFecha f1(10, 1, 05);

Se declara el objeto “f1”, ya que el constructor tiene argumentos se le tiene que mandar los

datos necesarios al declararlo, si el constructor no tuviera argumentos la declaración seria solo

“CFecha f1”.

Destructores

Un destructor es una función miembro con el mismo nombre que la clase, pero precedido por un

carácter tilde “~”. Una clase sólo tiene una función destructor, no tiene argumentos y no devuelve

ningún valor. Al igual que las demás funciones miembro puede estar definido dentro o fuera de la

clase.

El destructor es usado para realizar las operaciones necesarias para el objeto cuando este deja

de existir, como por ejemplo liberar espacio adquirido durante el tiempo de vida del objeto.

El siguiente programa es una modificación del ejemplo emoticon2.cpp presentado en el listado

7.2. Se usa un destructor y se muestra el orden de llamado del constructor y el destructor.

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 147

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 153/212

 

Listado

// emoticon_con.cpp

// uso de constructores y destructores

#include <iostream>

using namespace std;

class CEmoticon {

private:

string m_sIcon;

public:

CEmoticon(string a_sIcon);

~CEmoticon() {

cout << endl << "Adios mundo cruel! " << m_sIcon;

}

void Muestra(void){

cout << endl << "Yo estoy " << m_sIcon;

}

};

CEmoticon::CEmoticon(string a_sIcon) {

m_sIcon = a_sIcon;

cout << endl << "Acabo de nacer! " << m_sIcon;

}

int main(){

CEmoticon emoticon1(":)");

{

CEmoticon emoticon2(":(");

emoticon2.Muestra();

}

emoticon1.Muestra();

return 0;

}

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 148

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 154/212

 

Salida

Acabo de nacer! :)

Acabo de nacer! :(

 Yo estoy :(

Adios mundo cruel! :( Yo estoy :)

Adios mundo cruel! :)

~CEmoticon() {

cout << ende << "Adios mundo cruel! " << m_sIcon;

}

Aquí se implementa el destructor el cual solo despliega un mensaje para anunciar que ha sido

llamado, igual que el constructor.

main(){

CEmoticon emoticon1(":)");

{

CEmoticon emoticon2(":|");

emoticon2.Muestra();

}

emoticon1.Muestra()

}

En la función principal se crean dos objetos, uno en el bloque de código de la función “main()

CEmoticon emoticon1(":)")” ; y el otro dentro de un bloque de código para mostrar la creación y

destrucción de los objetos como se observa en la salida del programa.

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 149

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 155/212

 

Miembros estáticos

Al crearse un objeto, se separa espacio para las variables por cada objeto creado, a excepción

de las variables miembro estáticas; éstas pertenecen a todos los objetos derivados de la clase.

Las variables estáticas son globales para todos los objetos de la misma clase; éstas variables

también son llamadas variables de la clase ya que su contenido no depende de cada objeto.Una clase puede contener datos y funciones estáticas.

Los siguientes tres listados de código presentan una aplicación donde dentro de un ciclo se

crean aleatoriamente varios objetos dentro de un arreglo de punteros, se muestran los objetos

creados y después se destruyen; todo esto llevando un conteo de los objetos creados y

destruidos en una variable miembro de tipo “static”.

Listado

// static_emoticon.h

// miembros estaticos

// definición clase CEmoticon

#pragma once

#include <string>

using namespace std;

class CEmoticon {

private:

static int m_iPoblacion;

string m_sIcon;

public:

CEmoticon(string a_sIcon);

~CEmoticon();

static int Poblacion() { return m_iPoblacion; }

void Muestra();

};

static int m_iPoblacion;Se declara una variable miembro de tipo “static”.

Listado

// static_emoticon.cpp

// implementacion de CEmoticon con miembros estaticos

#include <iostream>

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 150

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 156/212

 

#include "static_emoticon.h"

int CEmoticon::m_iPoblacion = 0;

CEmoticon::CEmoticon(string a_sIcon) {

m_iPoblacion++;

m_sIcon = a_sIcon;

}

CEmoticon::~CEmoticon() {

m_iPoblacion--;

}

void CEmoticon::Muestra() {

cout << " " << m_sIcon;

}

int CEmoticon::m_iPoblacion = 0;

Como la variable tipo “static” pertenece a la clase y no a un objeto en particular se inicializa

haciendo referencia a la clase.

m_iPoblacion++;

La variable se incrementa dentro del constructor; como el constructor se llama cada vez que secrea un objeto, se lleva un conteo de los objetos en esta variable.

m_iPoblacion--;

La variable se decrementa cada vez que un objeto ejecuta al destructor el cual se llama

automáticamente cada vez que el objeto se destruye.

Listado

// test_static_emoticon.cpp

// prueba la clase CEmoticon incluida en static_emoticon.cpp

#include <iostream>

#include <string>

#include <cstdio>

#include <ctime>

#include "static_emoticon.h"

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 151

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 157/212

 

int main(){

int nc, i;

CEmoticon *emoticon[10];

string op;

nc = 0;

srand((unsigned)time( NULL ));

do {

nc = rand() % 10;

for (i = 0; i < nc; i++)

emoticon[i] = new CEmoticon(":)");

cout << "Poblacion: " << CEmoticon::Poblacion()

<< endl;

for (i = 0; i < nc; i++)

emoticon[i]->Muestra();

for (i = 0; i < nc; i++)

delete emoticon[i];

cout << endl << "Continuar (s/n) ?";

cin >> op;

} while (op != "n" && op != "N");

return 0;

}

Salida

Poblacion: 2

:) :)

Continuar (s/n) ?sPoblacion: 9

:) :) :) :) :) :) :) :) :)

Continuar (s/n) ?s

Poblacion: 6

:) :) :) :) :) :)

Continuar (s/n) ?n

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 152

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 158/212

 

CEmoticon *emoticon[10];

Se declara un arreglo de punteros de tipo “CEmoticon”, note que aquí no se crean los objetos,

solo el espacio para almacenar diez direcciones a diez objetos del tipo “CEmoticon”.

nc = rand() % 10;

Dentro del ciclo se genera un número aleatorio entre el cero y nueve, para crear esta cantidad de

objetos y guardar sus direcciones en el arreglo de punteros.

for (i = 0; i < nc; i++)

emoticon[i] = new CEmoticon(":)");

Se crean los objetos dentro de un ciclo “for: controlado por el numero generado aleatoriamente.

cout << "Poblacion: " << CEmoticon::Poblacion() << "\n";

Una vez que se han creado los objetos se despliega la variable estática llamando la función

miembro “Población()”.

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 153

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 159/212

 

for (i = 0; i < nc; i++)

emoticon[i]->Muestra();

Despliegan los strings que contienen los objetos recién creados.

for (i = 0; i < nc; i++)

delete emoticon[i];

Los objetos se destruyen.

Las siguientes líneas controlan si se desea continuar dentro del ciclo principal; de ser así, todos

los objetos habrán sido destruidos y se volverá a empezar en cero objetos creados.

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 154

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 160/212

 

Capitulo 5

Herencia

5.1 Importancia de la herencia en la POOLa herencia es una manera de reutilizar código al crear clases nuevas en base a otras que ya

existen, esto ahorra tiempo de desarrollo al utilizar código probado anteriormente. Utilizando la

herencia el desarrollador puede decidir que partes de la clase reutiliza y cuales implementa

nuevamente para que se ajusten a las necesidades de la nueva clase.

Hay que notar que no todos los miembros de la clase pueden ser heredados, los constructores,

el destructor, los operadores de asignación y los miembros estáticos no son heredables.

5.2 Jerarquía de herenciaAl usar la herencia se forma con las clases derivadas estructuras jerárquicas en forma de árbol.

A la clase que va ser heredada se le llama clase base, superclase o clase padre y a la clase que

hereda se le llama clase derivada, subclase o clase hijo.

Mediante el uso de la jerarquía se implementa una relación de especialización/generalización

entre clases.

5.2.1 Conceptos de herencia simple y múltipleHerencia simple

La herencia simple significa que una clase es derivada de una sola clase a la vez.

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 156

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 161/212

 

Por ejemplo si se quiere realizar un programa para dibujar figuras, se puede empezar por el

elemento principal que todo dibujo contiene, un punto, de ahí una línea, un rectángulo, etc., y se

va reutilizando el código ya escrito de la clase anterior.

Ejemplo:

Donde:

1. La clase línea hereda de clase punto

2. La clase rectángulo hereda de clase línea (y a la vez de punto a través de

línea)

Herencia múltiple

La herencia múltiple es cuando una clase se deriva de más de una a la vez y hereda lascaracterísticas de todas las clases de donde se deriva.

Ejemplo:

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 157

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 162/212

 

Donde:

1. La clase CTiempo hereda de la clase CFecha y de clase CHora

5.2.2 Principios generales de diseño de jerarquíasLa jerarquía se debe empezar desde lo más genérico hasta lo más específico. Cada nivel de la

 jerarquía debe reutilizar código del nivel anterior y extender la clase o clases de las cuales

heredo.

Ejemplo:

Solo los elementos de la clase que sean absolutamente necesarios para la comunicación

externa de los objetos deben de ser de tipo “puiblic”.

Los miembros que solo sean necesarios para las clases derivadas deben marcarse como

“protected”.

Todos los demás miembros de la clase deben ser de tipo “private”, esto es para encapsular el

objeto y reducir al mínimo los conflictos de acceso a los mismos, así como para aumentar la

flexibilidad del mantenimiento de la clase, al no estar expuestos es mas fácil cambiarlos, ya sea

de tipo de datos, nombres, etc.

Lo recomendable es hacer o seguir un análisis y diseño orientado a objetos antes de empezar a

codificar.

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 158

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 163/212

 

5.2.3 Especificadores de acceso a jerarquía de clasesAl crear una clase se cuenta con un control de acceso a los miembros de la misma que son

“private”, “protected” y “public”, este control se puede restringir aún mas al derivar.

Dependiendo del tipo de acceso con que cuenten los miembros de la clase base estos son

cambiados de acuerdo al modificador de acceso impuesto al derivarse.

Si al heredar se usa el

modificador de acceso:

Los miembros de la clase

base que sean:

Su acceso en la clase derivada

es:private private

protected

public

Inaccesible

private

privateprotected private

protected

public

Inaccesible

protected

protected

public private

protected

public

Inaccesible

protected

public

5.3 Definición de una clase baseCualquier clase puede ser una base clase, inclusive una clase derivada puede servir como clase

base para subsecuentes derivaciones.

La sintaxis para definir clases bases es igual a definir clases ordinarias, solo que ahora se debe

declarar como “protected” los miembros que se quiere que sean heredados por las clases

derivadas.

Tomar en cuenta la tabla anterior para asegurarse que las clases derivadas cuenten con el

acceso debido a los miembros de la clase base.

Se puede crear una clase con el solo propósito de ser heredada, a este tipo de clases se les

llama clases abstractas.

Listado

// cbase.h

// ejemplo de tipos de acceso para usar en la herencia

#pragma once

#include <string>

using namespace std;

class CBase {

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 159

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 164/212

 

private:

string strPrivado;

protected:

string strProtegido;

public:

string strPublico;

CBase(){

strPrivado = "Privado, dominio de esta clase";

strProtegido = "Protegido, dominio de la familia";

strPublico = "Publico, dominio publico";

}

};

Esta clase contiene los tres tipos de acceso y servirá como base para ser heredada mas

adelante, así como para mostrar el tipo de acceso de los miembros al usarla.

Listado

// testcbase.cpp

#include "cbase.h"

#include <iostream>

using namespace std;

int main(){

CBase base;

//cout << base.strPrivado << endl; // no accesible

//cout << base.strProtegido << endl; // no accesible

cout << base.strPublico << endl; // accesible porque es publico

return 0;

}

Salida

Publico, dominio publico

Note que el campo miembro de tipo “protected” actúa como tipo “private” para la clase base.

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 160

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 165/212

 

Listado

// CJugadorVirtual.h

// clase base, para ser heredada por otra

// los objetos generan un numero aleatorio entre

// 0 y 9

#pragma once

#include <iostream>

#include <cstdlib> // rand()

#include <ctime>

using namespace std;

class CJugadorVirtual {

protected:

int numero;

public:

CJugadorVirtual() {

numero = 0;

}

void Adivina() {

numero = rand() % 10;

}

int MiNumero() {

return numero;

}

};

protected:

int numero;

Aquí se declara un entero con control de acceso protegido, cada objeto debe generar un numero

aleatorio al llamar el método “Adivina()” y regresar el numero con el método “MiNumero()”, la

idea es que sea parte de un “jugador artificial” dentro de un programa y a la vez servir como

base para una clase que represente a un “jugador humano”.

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 161

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 166/212

 

Listado

// test_jugadorvirtual.cpp

// se genera un numero aleatorio en la funcion main

// y los objetos CJugadorVirtual "juegan" a

// "adivinar" el numero generado en main

#include <iostream>

#include <cstdlib> // srand()

#include <ctime> // time()

#include "CJugadorVirtual.h"

using namespace std;

int main() {

bool adivinado = false;

int numeroGenerado;

CJugadorVirtual j1;

CJugadorVirtual j2;

srand((unsigned)time( NULL ));

numeroGenerado = rand() % 10;

cout << "Estoy pensando en un numero entre 0 y 9..." << endl;

while (true) {

j1.Adivina();

j2.Adivina();

cout << endl << "Jugador uno dice " << j1.MiNumero();

cout << endl << "Jugador dos dice " << j2.MiNumero();

if (j1.MiNumero() == numeroGenerado)

adivinado = true;

if (j2.MiNumero() == numeroGenerado)

adivinado = true;

if (adivinado){

cout << endl << "Numero Adivinado!, el numero era "

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 162

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 167/212

 

<< numeroGenerado;

break;

}

else

cout << endl

<< "Los jugadores deben de intentar otra vez.\n";

}

return 0;

}

Salida

Estoy pensando en un numero entre 0 y 9...

 Jugador uno dice 9 Jugador dos dice 9

Los jugadores deben de intentar otra vez.

 Jugador uno dice 1

 Jugador dos dice 4

Numero Adivinado!, el numero era 1

El programa genera un número aleatorio y usa la clase “CJugadorVirtual” para crear objetos quegeneren números y compararlos con el número generado dentro de “main”, esto para crear un

 juego de “adivina el número que pienso”, en este caso no hay intervención externa y los

programas juegan “solos”.

Ejercicios

3.Modifique la siguiente clase para ser usada como clase base, siguiendo los principios de

diseño de la programación orientada a objetos, tip: es una sola línea la que hay que modificar.

// cpersona.h

// Ejercicio modificar para ser clase base

#pragma once

#include <iostream>

#include <string>

using namespace std;

class CPersona {

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 163

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 168/212

 

private:

string Nombre;

string Direccion;

string Telefono;

public:

void Captura(void);

void Despliega(void);

};

void CPersona::Captura(void) {

cout << endl << "Nombre : ";

getline(cin, Nombre, '\n');

cout << "Direccion: ";

getline(cin, Direccion, '\n');

cout << "Telefono : ";

getline(cin, Telefono, '\n');

}

void CPersona::Despliega(void) {

cout << endl << Nombre;

cout << endl << Direccion;

cout << endl << Telefono;

}

2. Realice un programa principal para que pruebe la clase “CPersona”

5.4 Definición de una clase derivadaUna clase derivada hereda la capacidad para llamar a funciones miembro de la clase base en los

objetos de la clase derivada.

Forma general:

class clase_derivada : modificador_de_acceso clase_base { … };

5.4.1 Constructores y destructores de clases derivadasSi la clase derivada no cuente con constructores, utiliza los de la clase base, en igual forma con

el destructor. En caso de que cuente con constructor o destructor debe estar coordinado con el

constructor y destructor de la clase base. El constructor de la clase derivada debe llamar al

constructor de la clase base y enviar los valores requeridos por el constructor de la clase base.

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 164

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 169/212

 

Si la clase base y la clase derivada cuentan con un constructor primero de ejecuta el constructor

de la clase base y después el de la clase derivada.

El orden de llamado de inicialización de las clases en la jerarquía de herencia es primero las

clases base de una clase derivada.

En el caso del destructor el orden de ejecución es inverso, primero la clase derivada y después

las clases base.

5.4.2 Conversión implícita de objetos de clase derivada a

objeto de clase baseUn objeto de la clase derivada se convierte en forma implícita en un objeto de la clase base

pública. Una referencia a una clase derivada se convierte implícitamente en una referencia a la

clase base pública.

Un puntero a la clase derivada se convertirá implícitamente en un puntero a la clase base. Un

puntero a un miembro de una clase base se convertirá en forma implícita en un puntero a

miembro de la clase derivada.

Adicionalmente, un puntero a cualquier objeto será implícitamente convertido en un puntero del

tipo void * (Para asignar este a un puntero a otro tipo hace falta el uso de cast explícito.)

Listado

// hereda_cbase.cpp

// ejemplo de tipos de acceso herencia

#include <iostream>

#include <string>

#include "cbase.h"

using namespace std;

// Derivando en forma privada

class CDerivadaPrivada : private CBase {

public:

void Despliega() {

// no accesible, privado solo lo puede usar "CBase"

// cout << strPrivado << endl;

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 165

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 170/212

 

cout << strProtegido << endl;

cout << strPublico << endl;

}

};

// Derivando en forma protegida

class CDerivadaProtegida : protected CBase {

public:

void Despliega() {

// no accesible, privado solo lo puede usar "CBase"

// cout << strPrivado << endl;

cout << strProtegido << endl;

cout << strPublico << endl;

}

};

// Derivando en forma publica

class CDerivadaPublica : public CBase {

public:

void Despliega() {

//cout << strPrivado << endl;

cout << strProtegido << endl;

cout << strPublico << endl;

}

};

int main(){

CDerivadaPrivada privada;

privada.Despliega();

// no accesible al heredar se uso "private",

// y un publico se convierte en privado

// cout << privada.strPublico << endl;

CDerivadaProtegida protegida;

protegida.Despliega();

// no accesible al heredar se uso "protected",

// un publico se convierte en potegido

// cout << protegida.strPublico << endl;

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 166

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 171/212

 

CDerivadaPublica publica;

publica.Despliega();

// accesible al heredar se uso "public",

// un publico se queda como publico

cout << publica.strPublico << endl;

return 0;

}

Salida

Protegido, dominio de la familia

Publico, dominio publico

Protegido, dominio de la familiaPublico, dominio publico

Protegido, dominio de la familia

Publico, dominio publico

Publico, dominio publico

#include "cbase.h"

La clase CBase se incluye con aquí.

class CDerivadaPrivada : private CBase {

En esta línea se hereda en forma privada la clase “Cbase” y la clase “CDerivadaPrivada” obtiene

derecho a todos los miembros permitidos de la clase “CBase” como si fueran incluidos

directamente en la clase derivada.

class CDerivadaProtegida : protected CBase {

class CDerivadaPublica : public CBase {

En estas líneas se hereda de la clase “CBase” en forma protegida y publica respectivamente

obteniendo el acceso a los miembros de la clase “CBase” según las reglas de acceso y sepueden usar como de la misma manera que los miembros propios.

En la función principal “main()” se crean objetos de las tres clases derivadas de “CBase” y se

prueban sus miembros para mostrar el acceso que se obtiene con los diferentes controles de

acceso al heredar.

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 167

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 172/212

 

Listado

// CJugadorHumano.h

#pragma once

#include <iostream>

#include "CJugadorVirtual.h"

using namespace std;

class CJugadorHumano : public CJugadorVirtual {

public:

void Adivina() {

cout << " Numero que piensas? ";

cin >> numero;

}

};

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 168

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 173/212

 

class CJugadorHumano : public CJugadorVirtual {

En esta línea la clase “CJugadorHumano” hereda públicamente a la clase “CJugadorVirtual”

obteniendo el acceso a todos sus miembros permitidos.

protected:

int numero;

El campo numero es heredado y se vuelve de tipo “protected” para que pueda ser heredado en

clases derivadas si así se necesitara. El acceso esta garantizado para la clase

“CJugadorHumano” como si fuera escrito directamente en la clase.

CJugadorVirtual() {

int MiNumero() {

Estos métodos son heredados tal y como están, ya que la el constructor “CJugadorVirtual()” no

usa argumentos este se manda llamar automáticamente y no es necesario tomar medidas dentro

de la clase derivada.

 

void Adivina() {

En el caso de este método, se sobre-escribe ya que la implementación del método dentro de la

clase “CJugadorVirtual” no se aplica para esta clase y es necesario pedir el numero al usuario. Al

sobrescribir este método la clase derivada “desecha” el uso del método de la clase base, al

menos automáticamente, ya que aun puede ser llamado indicando el nombre de la clase base,

por ejemplo: “CBase::Adivina()” y ejecutaría le método de la clase padre en ve del método

propio.

Listado

// JuegoAdivina3.cpp

#include <iostream>

#include <ctime>

#include <cstdlib>

#include "CJugadorHumano.h"

using namespace std;

int main() {

bool adivinado = false;

int numeroGenerado;

CJugadorVirtual j1;

CJugadorVirtual j2;

CJugadorHumano jh;

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 169

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 174/212

 

srand((unsigned)time( NULL ));

numeroGenerado = rand() % 10;

cout << "Estoy pensando en un numero entre 0 y 9..." << endl;

while (true) {

j1.Adivina();

j2.Adivina();

jh.Adivina();

cout << endl << "Jugador uno dice " << j1.MiNumero();

cout << endl << "Jugador dos dice " << j2.MiNumero();

cout << endl << "Jugador tres dice " << jh.MiNumero();

if (j1.MiNumero() == numeroGenerado)

adivinado = true;

if (j2.MiNumero() == numeroGenerado)

adivinado = true;

if (jh.MiNumero() == numeroGenerado)

adivinado = true;

if (adivinado){

cout << endl << "Numero Adivinado!, el numero era "

<< numeroGenerado;

break;

}

else

cout << endl

<< "Los jugadores deben de intentar otra vez.\n";}

return 0;

}

Salida

Estoy pensando en un numero entre 0 y 9...

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 170

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 175/212

 

Numero que piensas? 3

 Jugador uno dice 7

 Jugador dos dice 6

 Jugador tres dice 3Los jugadores deben de intentar otra vez.

Numero que piensas? 4

 Jugador uno dice 1

 Jugador dos dice 1

 Jugador tres dice 4

Este ejemplo es casi idéntico al del programa “test_jugadorvirtual.cpp” con la diferencia que secrea un objeto de tipo “CJugadorHumano” y este objeto permite la participación externa al

preguntar por un número para comparar con el generado en el programa principal.

Ejercicios

4 Realicé una clase derivada de la clase “CPersona”, la cual se sugiere se llame “CEstudiante” que

además contenga los siguientes miembros:

string numero_control

int calificacion

Método Captura() – Debe de capturar tanto los campos heredados como los propios.Método Despliega() – Debe de desplegar en pantalla tanto los campos heredados como los

propios.

Método RegresaCalificacion() - regresar la calificación

2. Realice un programa principal para que pruebe la clase “CEstudiante”

5.5 Herencia múltipleForma general:

class clase_derivada : modificador_de_acceso clase_base,

modificador_de_acceso clase_base2, …

{

};

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 171

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 176/212

 

La siguiente clase es para usarla como una de las clases padres en el ejemplo de herencia

múltiple; es una modificación a la clase de “CFecha” mostrada en el capitulo de clases, la

modificación consiste en inicializar las variables que representan la fecha desde el sistema.

Listado

// autofecha.h

// clase CFecha, el constructor toma la fecha del sistema

#pragma once

#include <iostream>

#include <time>

using namespace std;

class CFecha {

protected:

int mm, dd, aa;

public:

CFecha(){

time_t ahora = time(NULL); // Hora y fecha de hoy

struct tm *tiempo = localtime(&ahora);

dd = tiempo->tm_mday;

mm = tiempo->tm_mon + 1;

aa = tiempo->tm_year - 100;

}

void Despliega() {

cout << dd << '/' << mm << '/'<< aa;

}

};

time_t ahora = time(NULL); // lee la fecha/hora del sistema

Se asigna el tiempo que regresa la función “time()”, al incluir el “NULL” como argumento esta

función regresa el tiempo actual del sistema.

struct tm *tiempo = localtime(&ahora);

“tm” es una estructura para almacenar información

correspondiente a varias funciones de manejo del tiempo.

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 172

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 177/212

 

La función “localtime()” acomoda la información del la

variable “ahora” para que se formatee el tiempo para ser

desplegado.

En las siguientes líneas se asignan las variables miembro de la estructura “tiempo” a las

variables miembro de la clase, que son “dd”, “mm” y “aa”.

La siguiente clase es para usarla como una de las clases padres en el ejemplo de herencia

múltiple, una clase para representar la hora la inicialización de las variables es desde el sistema.

Listado

// autohora.h

// clase CHora, el constructor toma la hora del sistema#pragma once

#include <iostream>

#include <time>

using namespace std;

class CHora {

protected:

int hh, mm, ss;

public:

CHora(){

time_t ahora = time(NULL); // Hora y fecha de hoy

struct tm *tiempo = localtime(&ahora);

hh = tiempo->tm_hour;

mm = tiempo->tm_min;

ss = tiempo->tm_sec;

}

void Despliega() {

cout << hh << ':' << mm << ':'<< ss;

}

};

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 173

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 178/212

 

La diferencia entre esta clase y la de “CFecha” es que se asignan las variables de la estructura

“tiempo” correspondientes a la hora a las variables miembro de la clase, que son “hh”, “mm” y

“ss”.

El siguiente ejemplo implementa la Clase “CTiempo” y esta hereda de dos clases “CFecha” y

“CHora”.

Listado

// tiempo.h

// Clase CTiempo, ejemplo de multiple herencia

#include "autofecha.h"

#include "autohora.h"

class CTiempo : public CFecha, public CHora {

public:

void Despliega(){

CFecha::Despliega();

cout << " ";

CHora::Despliega();

}

void CambiaFecha(int ad, int am, int aa) {

dd = ad;

CFecha::mm = am;

aa = aa;

}

void CambiaHora(int ah, int am, int as) {

hh = ah;

CHora::mm = am;

ss = as;

}

};

#include "autofecha.h"

#include "autohora.h"

Se incluyen los archivos de encabezado donde se encuentran las clases de “CFecha” y “CHora”.

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 174

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 179/212

 

class CTiempo : public CFecha, public CHora {

Se define la clase “CTiempo” y hereda de “CFecha” y de “CHora”, especificando el modificador

de acceso y separadas ambas por comas; ésta clase no tiene variables miembro por sí misma

solo utiliza las variables de las clases de las que se deriva.

void Despliega(){

CFecha::Despliega();

cout << " ";

CHora::Despliega();

}

En la implementación de la función “Despliega()” se imprime en pantalla la fecha y la hora, aquí

como ambas clases de las que hereda “CTiempo” cuentan con una función “Despliega()”, se

utiliza el operador de acceso “::” para especificar de cual clase se usa la función “Despliega()”.

void CambiaFecha(int ad, int am, int aa) {

dd = ad;

CFecha::mm = am;

aa = aa;

}

En este método se actualizan las variables. Nótese que las clases “CFecha” y “CHora” cuentan

con una variable que se llama igual por lo tanto es necesario utilizar el operador de acceso para

indicarle al compilador a cual clase pertenece la variable.

El siguiente programa hace uso de la clase creada en el programa anterior.

Listado

// testTiempo.cpp

// Prueba la clase con herencia multiple CTiempo

#include "tiempo.h"

int main(){

CFecha fecha;

fecha.Despliega();

cout << endl;

CHora hora;

hora.Despliega();

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 175

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 180/212

 

cout << endl;

CTiempo tiempo;

tiempo.Despliega();

tiempo.CambiaHora(12, 10, 20);

cout << endl;

tiempo.Despliega();

return 0;

}

Salida

19/6/9

16:50:6

19/6/9 16:50:6

19/6/9 12:10:20

 

La utilización de la clase “CTiempo” es idéntica a los demás ejemplos donde se declaran objetos,

independientemente de si fue una clase sola o sí uso herencia simple o herencia múltiple.

Ejercicio

1 Discuta las ventajas y desventajas del uso de la herencia

múltiple

2 Investigue que problemas se pueden presentar al usar

herencia múltiple

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 176

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 181/212

 

Capitulo 6

Polimorfismo

6.1 Concepto de polimorfismoEn C++ es la propiedad de ejecutar funciones miembro (métodos) de diferentes clases que

pertenecen a una jerarquía formada mediante la herencia, esto se obtiene usando funciones

virtuales y punteros a la clase base, este proceso se conoce como enlace dinámico.

También se puede implementar polimorfismo estático a través de la sobrecarga de funciones, lo

cual es la propiedad de tener más de una función miembro con el mismo nombre, donde cada

función puede pude implementar un proceso diferente (ver mas en el capitulo 2, subprogramas,

“2.7 Sobrecarga de subprogramas”)

El siguiente ejemplo muestra la sobrecarga de funciones, dos funciones constructor. Las

funciones se pueden sobrecargar independientemente de si son parte de una clase o no.

Listado

// cpolifecha.h

// clase implementada en módulos, dos constructores

#pragma once

class CFecha {

private:

int mm, dd, aa;

public:

CFecha();

CFecha(int a_dd, int a_mm, int a_aa) {

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 179

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 182/212

 

mm = a_mm;

dd = a_dd;

aa = a_aa;

}

void Fecha();

void FechaCompleta();

};

CFecha();

CFecha(int a_dd, int a_mm, int a_aa) {

Se declaran dos constructores con el mismo nombre pero uno sin argumentos y otro con tres

argumentos.

Listado// cpolifecha.cpp

#include "cpolifecha.h"

#include <iostream>

#include <ctime>

using namespace std;

CFecha::CFecha(){

time_t ahora = time(NULL); // Hora y fecha de hoy

struct tm *tiempo = localtime(&ahora);

dd = tiempo->tm_mday;

mm = tiempo->tm_mon + 1;

aa = tiempo->tm_year - 100;

}

void CFecha::Fecha() {

cout << dd << '/' << mm << '/'<< aa;

}

void CFecha::FechaCompleta() {

string meses[] = {"Enero", "febrero", "Marzo", "Abril",

"Mayo", "Junio", "Julio", "Agosto", "Septiembre",

"Octubre", "Noviembre", "Diciembre"};

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 180

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 183/212

 

cout << dd << " de " << meses[mm-1] << " del " << (2000 + aa);

}

Listado

// testcpolifecha.cpp

#include <iostream>

#include "cpolifecha.h"

using namespace std;

int main() {

CFecha f1(10, 1, 15);

CFecha f2;

f1.Fecha();

cout << "\t\t";

f1.FechaCompleta();

cout << endl;

 

f2.Fecha();

cout << "\t\t";

f2.FechaCompleta();

cout << endl;

return 0;

}

Salida

10/1/15 10 de Enero del 2015

1/6/9 1 de Junio del 2009

CFecha f1(10, 1, 05);

CFecha f2;

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 181

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 184/212

 

Se declaran dos objetos de tipo “CFecha”, el primer objeto recibe 3 argumentos, por lo tanto el

constructor con tres argumentos es llamado. En la siguiente línea al declarar el objeto “f2” se

llama el constructor sin argumentos.

Ejercicio

1 Discuta si es posible sobrecargar los métodos “Fecha()” y “FechaCompleta()”.

2 Discuta cual son las posibles ventajas y desventajas de la sobrecarga de funciones miembro.

6.2 Clase base abstractaUna clase base abstracta tiene funciones virtuales puras, es decir funciones que no son

implementadas en la clase; este tipo de clases es para ser usada como clase base solo para ser

derivada por otras clases y no para declarar instancias de la misma; al contener funciones

virtuales es imposible que se creen objetos del tipo de la clase (aunque sí se pueden crear

punteros que hagan referencia a este tipo de clases).

Si las clases derivadas no implementan las funciones virtuales puras, estas clases derivadas se

convierten también en clases abstractas. Si las clases derivadas implementan todas las

funciones virtuales puras se convierten en clases concretas y pueden ser usadas para instanciar

objetos.

Ejemplo:

virtual void dibujar() = 0;

El siguiente ejemplo implementa una clase abstracta y dos clases que se derivan de ella eimplementan las funciones virtuales puras definidas en la clase abstracta.

Listado

// abstracta.h

// ejemplo de clase con funciones virtuales puras

#pragma once

#include <iostream>

#include <string>

using namespace std;

class CPersona {

protected:

string m_sNombre;

public:

virtual void Agrega() = 0;

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 182

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 185/212

 

virtual void Muestra() = 0;

};

class CEmpleado : public CPersona {

protected:

float m_fSalario;

public:

void Agrega() {

cout << "Nombre ";

cin >> m_sNombre;

cout << "Salario ";

cin >> m_fSalario;

}

void Muestra() {

cout << "\nNombre " << m_sNombre;

cout << "\nSalario " << m_fSalario;

}

};

class CSocio : public CPersona {

protected:

int m_iAcciones;

public:

void Agrega() {

cout << "Nombre ";

cin >> m_sNombre;

cout << "Acciones ";

cin >> m_iAcciones;

}

void Muestra() {

cout << "\nNombre " << m_sNombre;

cout << "\nAcciones " << m_iAcciones;}

};

virtual void Agrega() = 0;

virtual void Muestra() = 0;

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 183

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 186/212

 

Aqui se declaran las funciones miembro como virtuales puras, esto le indica al compilador que

estas funciones van a ser implementadas por las clases derivadas.

Listado

// testAbstracta.cpp

// prueba la clae abstracta CPersona y sus clases derivadas

#include "abstracta.h"

int main(){

CPersona *persona;

CEmpleado empleado;

CSocio socio;

 

cout << "\nAgrega los datos del empleado " << endl;

empleado.Agrega();

 

cout << "\nAgrega los datos del socio " << endl;

socio.Agrega();

persona = &empleado;

persona->Muestra();

 

persona = &socio;

cout << endl;

persona->Muestra();

cout << endl;

return 0;

}

Salida

Agrega los datos del empleadoNombre Bruce

Salario 150

Agrega los datos del socio

Nombre Bjarne

Acciones 33

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 184

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 187/212

 

Nombre Bruce

Salario 150

Nombre BjarneAcciones 33

En este ejemplo se declaran dos objetos uno de tipo “CEmpleado” y otro de tipo “CSocio”, un

puntero a la clase base “CPersona”.

El objeto empleado y el objeto socio mandan llamar sus funciones miembro de “Agrega()” para

asignar valores a las variables miembro por medio de la entrada de datos del usuario, como se

muestra en los dos primeros párrafos de la salida.Mediante el puntero se accesa indirectamente a los objetos y se despliega el contenido las

variables miembro a través de la función “Muestra()”.

Ejercicio

5 Discuta si la clase abstracta en el ejemplo anterior podría no serlo y de ser así, porque.

6 Proponga situaciones donde sea útil usar una clase abstracta.

6.3 Subprogramas virtualesLas funciones virtuales son resueltas a la hora de ejecución del programa (run time), mediante

un mecanismo llamado ligamiento tardío (late-binding)

De esta manera un objeto se puede manipular como si fuera genérico accesando los objetos

derivados mediante el objeto base. Solo las funciones miembros pueden ser declaradas como

virtual.

Para declarar que una función de la clase base es virtual, a su prototipo se le antepone la

palabra reservada virtual, esta palabra solo debe ser usada en la declaración de la función, y no

en la definición de la función si se realiza fuera del cuerpo de la clase.

Ejemplo:

virtual void dibujar();

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 185

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 188/212

 

Para que el ligado tardío funcione, las funciones derivadas deben tener exactamente el mismo

nombre, incluyendo el numero de argumentos y sus tipos de datos, de no ser así el mecanismo

virtual es inoperable.

Listado

// virtual.h

// ejemplo de clase con funciones virtuales

#pragma once

#include <iostream>

#include <string>

using namespace std;

class CPersona {

protected:

string m_sNombre;

public:

virtual void Agrega() {

cout << "Nombre ";

cin >> m_sNombre;

}

virtual void Muestra() {

cout << "\nNombre " << m_sNombre;

}

};

class CEmpleado : public CPersona {

protected:

float m_fSalario;

public:

void Agrega() {

CPersona::Agrega();

cout << "Salario ";

cin >> m_fSalario;

}

void Muestra() {

CPersona::Muestra();

cout << "\nSalario " << m_fSalario;

}

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 186

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 189/212

 

};

class CSocio : public CPersona {

protected:

int m_iAcciones;

public:

void Agrega() {

CPersona::Agrega();

cout << "Acciones ";

cin >> m_iAcciones;

}

void Muestra() {

CPersona::Muestra();

cout << "\nAcciones " << m_iAcciones;

}

};

virtual void Agrega() {

Se declara (y empieza la implementación) de la función miembro “Agrega()” en forma virtual, esto

le indica al compilador que la resolución de esta función sea resuelta en tiempo de ejecución.

La clase “CPersona” a diferencia del ejemplo anterior no es

mas una clase abstracta ya que todas los métodos están

implementados.

Listado

// testVirtual.cpp

// prueba la clae abstracta CPersona y sus clases derivadas

#include "virtual.h"

int main(){

CPersona *persona;CPersona obj_persona;

CEmpleado empleado;

CSocio socio;

cout << "\nAgrega los datos de una persona " << endl;

obj_persona.Agrega();

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 187

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 190/212

 

cout << "\nAgrega los datos del empleado " << endl;

empleado.Agrega();

 

cout << "\nAgrega los datos del socio " << endl;

socio.Agrega();

// despliega los datos de obj_persona

obj_persona.Muestra();

// Despliega los datos de empleado y socio mediante

// el puntero persona

persona = &empleado;

persona->Muestra();

 

persona = &socio;

cout << endl;

persona->Muestra();

cout << endl;

return 0;

}

Salida

Agrega los datos de una persona

Nombre Batman

Agrega los datos del empleado

Nombre Superman

Salario 3500.50

Agrega los datos del socioNombre Tarzan

Acciones 33

Nombre Batman

Nombre Superman

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 188

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 191/212

 

Salario 3500.5

Nombre Tarzan

Acciones 33

CPersona obj_persona;

Aquí se declara un objeto de tipo “CPersona”, note que la clase “CPersona” del programa

“testAbstracta.cpp” no puede ser usada para instanciar objetos ya que es una clase abstracta

porque tiene funciones virtuales puras, no así en este ejemplo que las funciones virtuales están

plenamente implementadas.

Nota:

El uso de funciones miembro virtuales permite acceder a los métodos virtuales de las clasesderivadas usando indireccion mediante un puntero de tipo clase base.

Los métodos virtuales puros garantiza el acceso a los métodos de las clases derivadas

mediante la clase base aun cuando la clase base no cuente con suficientes datos para

implementar tales métodos.

6.4 Destructores virtualesLos destructores virtuales son como todas demás funciones miembro, por ejemplo, si en una

 jerarquía de clases tiene destructores y se accesan los objetos de las clases derivadas mediante

un puntero a la clase base, al momento de que un objeto es destruido y si el destructor de la

clase base no es virtual, se llamara el destructor de la clase base y no a los demás destructores

de la jerarquía.

Cuando el destructor de la clase base es virtual y es llamado para destruir el objeto se llama a

todos los destructores que estén hacia arriba en la jerarquía de la herencia.

Como regla general, si en una clase existen funciones virtuales, el destructor debe ser virtual.

Listado

// destructor_virtual.cpp

#include <iostream>

using namespace std;

class CBase {

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 189

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 192/212

 

public:

// no virtual, posible problema

// ~CBase() {

virtual ~CBase() {

cout << " Destruyendo CBase" << endl;

}

virtual void Metodo() {

cout << "CBase::Metodo()" << endl;

}

};

class CDerivada1 : public CBase {

public:

~CDerivada1() {

cout << "Destruyendo CDerivada1" << endl;

}

void Metodo() {

cout << "CDerivada1::Metodo()" << endl;

}

};

class CDerivada2 : public CDerivada1 {

public:

~CDerivada2() {

cout << " Destruyendo CDerivada2" << endl;

}

void Metodo() {

cout << "CDerivada2::Metodo()" << endl;

}

};

main() {// puntero clase base a objeto derivado

CBase * pBase = new CDerivada2;

pBase->Metodo(); // llamada a función virtual

delete pBase; // borrar puntero a clase base

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 190

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 193/212

 

return 0;

}

Salida sin destructor virtual

CDerivada2::Metodo()Destruyendo CBase

Salida con destructor virtual

CDerivada2::Metodo()

Destruyendo CDerivada2

Destruyendo CDerivada1

Destruyendo CBase

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 191

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 194/212

 

Capitulo 7

Archivos

7.1 Clases de E/S Clase base abstractaStream es la clase base abstracta de E/S, esta es compatible con bytes de lectura y escritura.

Todas las clases que representan secuencias se derivan de la clase Stream. La clase Stream y

sus clases derivadas proporcionan una visión genérica de los orígenes de datos y de su

almacenamiento.

Corrientes de flujoEl sistema de E/S de C++ proporciona una interfaz independiente del dispositivo real al que se

accede; esto es una abstracción entre el programador y el dispositivo que se usa. Esta

abstracción se llama corriente y el dispositivo real se llama archivo.

Corrientes

Almacenamiento temporal de archivo para transformar los dispositivos físicos en un

almacenamiento lógico. Esto permite que las corrientes sean independientes de los dispositivos.

Existen dos tipos de corrientes: texto y binarias.

7.2 Realizar entrada y salida de textoArchivos de texto

Las corrientes de texto son una secuencia de caracteres organizadas en líneas terminadas por

un carácter nueva línea. La traducción del carácter nueva línea depende de la implementación.

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 193

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 195/212

 

Entrada de texto

La entrada o también llamada lectura es la transferencia de datos desde una secuencia a una

estructura de datos, como, por ejemplo, una matriz de bytes.

Salida de texto

La salida, también llamada escritura consiste en la transferencia de información desde un origen

de datos a una secuencia.

Operaciones de búsqueda

Las operaciones de búsqueda consisten en la consulta y modificación de la posición actual en

una secuencia.

7.3 Leer y escribir archivosEn el archivo fstream están definidas varias clases de entrada y salida, incluyendo ifstream –

flujo de entrada, ofstream – flujo de salida. Para leer y/o escribir en un archivo se crea un objeto

de tipo fstream.

Forma general:

fstream objeto(nombre_archivo, modo);

Donde modo es:

ios::in abre archivo existente para lecturaios::out abre archivo para escrituraios::out | ios::trunc crea archivo para escritura o trunca el archivo existenteios::out | ios::app abre archivo existente para agregarios::out | ios::in abre archivo existente para lectura y escrituraios::in | ios::out | ios::trunc trunca el archivo existente o crea archivo para lectura y

escrituraios::in | ios::out | ios::app abre el archivo existente o crea archivo para lectura y

escrituraios::binary para archivos binarios

Lectura de un archivo de texto

Se crea el objeto con fstream nombre_del_objeto, indicando que es de lectura con el

manipulador ios::in.

Ejemplo:

fstream entrada(“archivo.txt”, ios::in);

Listado

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 194

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 196/212

 

// muestra.cpp

// ejemplo de lectura de un archivo de texto

// muestra un archivo de texto en la salida estandard

#include <iostream>

#include <fstream>

#include <cstdlib>

using namespace std;

int main() {

char szArchivo[20];

char c;

cout << "Archivo a mostrar? ";

cin >> szArchivo;

fstream entrada(szArchivo, ios::in);

 

if (entrada.fail()) {

cout << "Error al abrir archivo! Abortando";

exit(1); // termina la ejecucion del programa

}

while (!entrada.eof()){

entrada.get(c);

cout << c;

}

entrada.close();

return 0;

}

Salida

Archivo a mostrar? primer.cpp// Primer.cpp

// Escribe un mensaje en pantalla

#include <iostream>

using namespace std;

int main()

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 195

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 197/212

 

{

cout << "Este es mi primer programa en C++";

return 0;

}

fstream entrada(szArchivo, ios::in);

Se crea el objeto de tipo “fstream”, y se intenta abrir el

archivo que indica la cadena de caracteres “szArchivo”; el

manipulador “ios::in” indica abrirlo en modo solo lectura.

La información sobre el éxito o fracaso se almacena en

“basic_ios:réstate”.

if (entrada.fail()) {

La función miembro “fail()”, regresa el numero uno o “true” o bien un cero o “false” dependiendo

de la información en “basic_ios::réstate”.

En caso de error de creación del objeto termina la ejecución del programa al llamar la función

“exit()”.

while (!entrada.eof()){“eof()”, regresa un cero o “false” si no se ha alcanzado el

final del archivo y uno o “trae” si esta en el fin de

archivo.

entrada.get(c);

“get()”, lee un carácter del flujo de entrada y lo asigna a

la variable “c”.

entrada.close();

“close()”, cierra el archivo.

Ejercicio

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 196

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 198/212

 

Escriba un programa que lea un archivo de texto y lo despliegue en mayúsculas en la salida

estándar.

Escritura en un archivo de texto

Para escribir en un archivo se crea un objeto de tipo “fstream”, con la sentencia “fstream

nombre_del_objeto”, indicando que es de escritura con el manipulador “ios::out”. Al crear el

objeto, si el archivo físico no existe se crea físicamente en blanco, si ya existe se sobrescribe en

blanco.

Ejemplo:

fstream salida(“archivo.txt”, ios::out);

El siguiente programa de ejemplo lee un archivo de texto y la va escribiendo en otro archivo de

texto pero en forma encriptada. La técnica usada para encriptar el archivo se basa en desfasar

en uno cada carácter.

Ejemplo:

Teniendo la cadena: “HOLA”

H O L A \0

El correspondiente código ascii para cada letra es:

72 48 76 64 \0

Si se le suma un uno a cada código:72 = H

72 + 1 = 73

73 = J

Toda la cadena en ascii con cada elemento incrementado en uno:

73 49 77 65 \0

Por lo tanto la cadena queda como: “J1MB”

J 1 M B \0

Para desencriptarla solo hay que restarle uno a cada elemento.

Listado

// encripta.cpp

// ejemplo de lectura y de escritura a archivos de texto.

// lee un archivo de entrada, desfasa el caracter leido y

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 197

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 199/212

 

// lo escribe en el archivo de salida

#include <iostream>

#include <fstream>

#include <cstdlib>

using namespace std;

int main() {

char szEntrada[20];

char szSalida[20];

char c;

cout << "Archivo a encriptar? ";

cin >> szEntrada;

cout << "Guardar archivo encriptado en? ";

cin >> szSalida;

fstream entrada(szEntrada, ios::in);

fstream salida(szSalida, ios::out);

 

if (entrada.fail()) {

cout << "Error al abrir archivo de entrada! Abortando";

exit(1);

}

if (salida.fail()) {

cout << "Error al abrir archivo de salida! Abortando";

exit(1);

}

while (!entrada.eof()){

entrada.get(c);

salida.put(c+1); // encripta

}

entrada.close();salida.close();

return 0;

Salida

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 198

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 200/212

 

Archivo a encriptar? primer.cpp

Guardar archivo encriptado en? primer.txt

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 199

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 201/212

 

Nota, Listado del archivo primer.txt:

00!Qsjnfs/dqq

00!Ftdsjcf!vo!nfotbkf!fo!qboubmmb$jodmvef!=jptusfbn?

vtjoh!obnftqbdf!tue<

 jou!nbjo)*

|

!!!dpvu!==!#Ftuf!ft!nj!qsjnfs!qsphsbnb!fo!D,,#<

!!!sfuvso!1<

~

fstream entrada(szEntrada, ios::in);

fstream salida(szSalida, ios::out);

Se crean y se abren los archivos de entrada y de salida.

while (!entrada.eof()){

entrada.get(c);

salida.put(c+1); // encripta

}

Se recorre el archivo de entrada leyendo carácter por carácter y se escribe en la salida

sumándole un uno para encriptarlo.

entrada.close();

salida.close();

La llamada al método “close()” cierra el archivo.

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 200

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 202/212

 

Ejercicios

4.Escriba un programa que lea un archivo de texto y lo escriba en un nuevo archivo de texto –

copie el contenido de un archivo de texto existente en otro.

5.Desarrolle un programa que lea una cadena de caracteres y la grabe en un archivo de texto.

6.Modifique el programa encripta.cpp para que desencripte un archivo.

Lectura y Escritura en un archivo de texto

Para modificar un archivo (leer y escribir en un mismo archivo) se crea un objeto de tipo

“fstream”, con la sentencia “fstream nombre_del_objeto”, indicando que es de lectura y escritura

con los manipuladores “ios::in | ios::out | ios::app”.

Al crear el objeto, si el archivo físico no existe se crea físicamente en blanco, si ya existe lo abre

para lectura y escritura.

Ejemplo:

fstream archivo(“nombre_archivo.txt”, ios::in | ios::out | ios::app);

Para posicionarse en una parte del archivo se usa la función miembro “seekg”

Ejemplo:

// se posiciona exactamente al final del archivo

archivo.seekg(0, ios::end);

//se posiciona 10 caracteres despues del inicio

archivo.seekg(10, ios::beg);

El siguiente programa de ejemplo ilustra la entrada y salida en un solo archivo, implementando

una bitácora básica, la idea principal es ir agregando texto en un archivo existente, para llevar un

control de las actividades realizadas.

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 201

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 203/212

 

Listado

// bitacora.cpp

// abre un archivo para E/S y agrega texto al final del mismo

#include <iostream>

#include <fstream>#include <cstdlib>

using namespace std;

int main() {

char szTexto[256];

fstream esArchivo("bitacora.txt", ios::in | ios::out | ios::app);

if (esArchivo.fail()) {cout << "Error al abrir archivo! Abortando";

exit(1);

}

cout << "Texto? ";

cin.getline(szTexto, 255);

esArchivo.seekg(0, ios::end);

esArchivo << szTexto << "\n";

esArchivo.close();

return 0;

}

Salida

 Texto? Punteros, referencias y arreglos

Nota, Listado del archivo bitacora.txt:

Fundamentos del lenguaje

subprogramas

Punteros, referencias y arreglos

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 202

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 204/212

 

fstream esArchivo("bitacora.txt", ios::in | ios::out |

ios::app);

Se crea el objeto “esArchivo”, y se abre de entrada y salida con “ios::in y ios::out”

respectivamente, se agrega el manipulador “ios::app”, para que en caso de que no exista el

archivo éste sea creado.

cin.getline(szTexto, 255);

“getline()”, lee toda una línea del flujo de entrada, con un

máximo de 255 caracteres

esArchivo.seekg(0, ios::end);

Al abrir un archivo para lectura, el indicador de lectura

del flujo de entrada se posiciona al inicio del archivo.

Como lo que se quiere es agregar texto al final del archivo

se usa el “seekg()”, para mover el indicador al final del

archivo. De no hacer esto, cualquier texto agregado al

archivo sobrescribe el existente.

esArchivo << szTexto << "\n";

Ya que “esArchivo” es un flujo de datos y “fstream” se

deriva de “basic_stream”, se asigna la cadena con el

operador “<<”, tal y como se hace con el objeto “cout”.

7.4 Realizar entrada y salida binariaArchivos binarios

Los archivos binarios son archivos no formateados; se utilizan para manejar los datos byte por

byte. Se usa el manipulador “ios::binary” al abrir el archivo y no se usan los operadores “<<”,

“>>”.

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 203

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 205/212

 

El siguiente ejemplo es la versión dos de la bitácora, usando estructuras para incluir el porciento

terminado de la tarea a grabar en la bitácora, además cuenta con un menú para con las

opciones de mostrar el contenido del archivo y agregar nuevos datos.

Listado

// bitacorax.cpp

// agrega texto al final de un archivo

#include <iostream>

#include <fstream>

#include <string>

#include <cstdlib>

using namespace std;

const int LON = 80;

struct BitacoraX {

int iPorcientoTerminado;

char szTexto[LON];

};

int main() {

BitacoraX bitacora;

int iOpcion, i;

fstream esArchivo("bitacorax.dat",

ios::out | ios::in | ios_base::app | ios::binary);

if (esArchivo.fail()) {

cout << "Error al abrir archivo! Abortando";

exit(1);

}

do {

cout << "\n1. Muestra";

cout << "\n2. Agrega";

cout << "\n3. Termina";

cout << "\nOpcion? ";

cin >> iOpcion;

cin.ignore();

switch (iOpcion) {

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 204

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 206/212

 

case 1:

cout << "Porciento\tTexto\n";

cout <<

"-------------------------------------------------------"

<< endl;

esArchivo.clear();

esArchivo.seekg(0, ios::beg);

esArchivo.read((char *)&bitacora,

sizeof(struct BitacoraX));

while (!esArchivo.eof()){

cout << bitacora.iPorcientoTerminado

<< "\t\t" << bitacora.szTexto << endl;

esArchivo.read((char *)&bitacora,

sizeof(BitacoraX));

}

break;

case 2:

cout << "\nTexto ? ";

cin.getline(bitacora.szTexto, LON-1);

cout << "Porciento terminado? ";

cin >> bitacora.iPorcientoTerminado;

esArchivo.clear();

esArchivo.seekg(0, ios::end);

esArchivo.write((const char *)&bitacora, sizeof(BitacoraX));

esArchivo.flush();

break;

case 3:

break;

default:

cout << "Opcion no implementada";

}

} while (iOpcion != 3);

esArchivo.close();

return 0;

}

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 205

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 207/212

 

Salida

1. Muestra

2. Agrega

3. Termina

Opcion? 1

Porciento Texto

-------------------------------------------------------------

100 Instrucciones basicas

100 control de flujo

70 arreglos

1. Muestra

2. Agrega

3. Termina

Opcion? 2

 Texto ? Archivos y estructuras

Porciento terminado? 60

1. Muestra

2. Agrega

3. Termina

Opcion? 3

El programa incluye un ciclo donde se presenta un menú para

seleccionar si se quiere mostrar todos los elementos del

archivo, agregar un elemento o terminar el ciclo y por

consiguiente cerrar el archivo y terminar la ejecución delprograma.

La opción ingresada se compara en un “switch”, y en caso de

ser la opción 1, se ejecuta el “case 1:” y despliega unas

líneas de encabezado.

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 206

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 208/212

 

esArchivo.clear();

Al abrir el archivo, su indicador se encuentra en el inicio

del mismo pero al recorrerlo en modo de lectura una vez, se

prende la bandera de “eof” y se queda así. “clear()”, borra

la bandera puesta al alcanzar el fin de archivo -eof- para

recorrerlo desde el inicio tantas veces como el usuario así

lo desee.

esArchivo.seekg(0, ios::beg);

seekg(), posiciona el indicador de archivo al inicio, para

recorrerlo mientras no sea fin de archivo.

esArchivo.read((char *)&bitacora, sizeof(struct BitacoraX));

El método “read()”, recibe dos parámetros: el primero “(char

*)&bitácora” es el buffer donde se almacenan los datos

obtenidos del archivo y el segundo parámetro

“sizeof(BitacoraX)” indica el tamaño del buffer; en este

caso se invoca la función “sizeof()” la cual regresa el

tamaño en bytes del tipo de dato recibido como parámetro (en

este ejemplo la estructura “BitacoraX").

esArchivo.seekg(0, ios::end);

“seekg()”, posiciona el indicador de archivo al final, para

agregar datos.

esArchivo.write((const char *)&bitacora, sizeof(struct

BitacoraX));

El método “write()”, recibe dos parámetros: el primero

“(const char *)&bitácora” es el buffer donde están

almacenados los datos obtenidos que se van a grabar al

archivo y el segundo parámetro “sizeof(BitacoraX)” indica el

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 207

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 209/212

 

tamaño del buffer; en este caso se invoca la función

“sizeof()” la cual regresa el tamaño en bytes del tipo de

dato recibido como parámetro (en este ejemplo la estructura

“BitácoraX”).

esArchivo.flush();

“flush()”, este método graba el flujo del archivo al

dispositivo de almacenamiento físico, esto es para

actualizar el contenido del archivo.

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 208

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 210/212

 

Ejercicio

Realice un programa donde utilice archivos binarios, que

grabe y recupere la siguiente estructura:

struct SArticulo {

int clave;

char descripcion[40];

float precio;

};

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 209

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 211/212

 

Bibliografía

[Stroustrup 1997] Bjarne Stroustrup: “The C++ Programming Language” Third Edition Addison-

Wesley 1997

[Stroustrup 1993] Bjarne Stroustrup: “El lenguaje de programación C++” Segunda Edición

 Addison-Wesley/Diaz de Santos 1993

[Hernandez 2002] Enrique Hernández Orallo, Jose Hernández Orallo y Ma. Carmen Juan

Lizandra: “C++ Estándar” Parainfo Thomson Learning 2002

[Eckel 1993] Bruce Eckel: “C++ Inside & Out” Osborne McGraw-Hill 1993

[Ellis 1994] Margaret A. Ellis y Bjarne Stroustrup: “C++ Manual de referencia con anotaciones”

 Addison-Wesley/Diaz de Santos 1994

 

[Eckel 2000] Bruce Eckel: “Thinking in C++” 2nd ed. volume 1 http://www.BruceEckel.com 2000

[Deitel 1995] H.M. Deitel y P. J. Deitel: “Como programar en C/C++” segunda edición Pearson / 

Prentice Hall 1995

[Visual C++ 2008 Express Edition] Microsoft Corporation: “Ayuda Visual C++ 2008 ExpressEdition” Microsoft Corporation

[Builder C++ 5.0] Borland, Inprise Corporation: “Ayuda C++ Builder 5.0” Borland, Inprise

Corporation

[Kernighan 1991] Brian W. Kernighan y Dennis M. Ritchie: “El lenguaje de programación C”

(c) copyright 2008-2012 Rogelio Cesar Rodriguez Cervantes 209

5/14/2018 Tutorial Profr. Rogelio Cesar - slidepdf.com

http://slidepdf.com/reader/full/tutorial-profr-rogelio-cesar 212/212

 

segunda edición Prentice Hall 1991

[Schildt 1990] Herlbert Schildt: “C The Complete Reference” second edition Osborne McGraw-

Hill 1990

[Rodriguez 2006] Rogelio Cesar Rodriguez Cervantes “Guía para el aprendizaje sistemático del

lenguaje de programación C++”, Proyecto utilitario para presentar examen profesional de

conocimientos para la Maestría en tecnología Informática en la Universidad Autónoma de

Tamaulipas, México.