Está en la página 1de 99

Algoritmos y Estructura de Datos

Dr. Arturo Gonzlez Gutirrez

Unidad 1.Transicin a C++

1.1 Introduccin a C++ 1.2 Estructuras de Datos y Algoritmos en C++ 1.3 Programacin Bsica en C++ 1.4 Administracin de la Memoria 1.5 Mecanismos para la Reutilizacin y Abstraccin del Cdigo

Ago-Dic 2010

Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

1.1 Introduccin a C++


Se presenta una introduccin al lenguaje de programacin C++ Se incluye una revisin general de sus principales caractersticas Se discute la historia y desarrollo de C++ como lenguaje de programacin Se muestra la compilacin y ejecucin de un programa sencillo de C++.

Ago-Dic 2010 Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez 3

1.1.1 Antecedentes de C++


Historia:
C++ es un moderno lenguaje de programacin orientado a objetos. Soporta las caractersticas de: clase, herencia, polimorfismo y excepciones. Dichas caractersticas son herramientas para crear y mantener grandes sistemas de software. Juntos permiten el diseo de software para seguir de cerca la forma del problema, reduciendo la cantidad de cdigo que se requiere escribir mientras que a la vez se maximiza su confiabilidad. C++ no es un lenguaje completamente nuevo, y est basado en el lenguaje de programacin C C++ agrega al lenguaje C caractersticas como clase y herencia, y se convierte en un lenguaje mucho ms grande que C, pero ms adecuado para proyectos de gran escala. Debido a que los compiladores de C++ pueden compilar programas en C, C++ gan una aceptacin rpida en el mercado. Actualmente, existen literalmente millones de lneas de cdigo de C++ en uso, por una amplia variedad de aplicaciones de software.

Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

Ago-Dic 2010

Historia

Ago-Dic 2010

Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

Principales Caractersticas

C++ es fuertemente tipeado. Cada objeto debe pertenecer a cierto tipo y las operaciones como evaluaciones o comparaciones slo estn permitidas entre objetos del mismo tipo. C++ tiene el concepto de clase, un tipo de registro que combina los miembros de los datos y las funciones que operan sobre los datos. C++ soporta tipos parametrizados o plantillas. Las plantillas hacen posible definir una clase de vector sencillo, que trabaja para datos tipo Booleanos, carcter, enteros, reales, etc. La ventaja real de las plantillas de C++ esta en que su uso no le prohbe al compilador desarrollar la revisin de los tipos estticos o en tiempo de compilacin. C++ soporta herencia, un mecanismo que hace posible construir nuevas clases (llamadas clases derivadas) arriba de una clase existente (llamada la clase base) sin tener que reiterar el diseo de la clase base para cada clase nueva. C++ soporta polimorfismo. sto se logra a travs del uso de funciones virtuales y apuntadores. Junto con la herencia, esto convierte a C++ en un lenguaje orientado a objetos muy completo. C++ viene con dos bibliotecas conocidas como la Biblioteca Estndar y la Biblioteca de Plantillas Estndar (STL), las cuales extienden la capacidad del lenguaje base. La Biblioteca Estndar provee todas las antiguas bibliotecas de C, as como nuevas facilidades de entrada y salida. STL provee una biblioteca de tipo contenedor (tipos que mantienen o "contienen" colecciones de objetos) as como un conjunto de algoritmos asociados (que son algoritmos de propsito general para estructuras comunes de datos). STL complementa los tipos intrnsecos de C++ con vectores, listas enlazadas y otros tipos. C++ tiene una base muy grande de usuarios. Alrededor del mundo, compaas pblicas y privadas, agencias de gobierno, academias y otros usuarios utilizan C++ en todo tipo de formas y aplicaciones. Un beneficio de contar con esta gran base de usuarios es la amplia disponibilidad de diferentes herramientas, bibliotecas y tutoriales, todos relacionados a algn aspecto del lenguaje.
Ago-Dic 2010 Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez 6

1.1.2 Cmo Compilar y Ejecutar un Programa de C++

Hello World!
#include <iostream> #include <cstdlib> using namespace std; Listado 1 int main(int argc, char* argv[ ]) { // Say hello. cout << "Hello World!" << endl; /* indicate normal termination */ return EXIT_SUCCESS; }

Ago-Dic 2010

Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

Fases del Desarrollo de un Programa en C++

Los programadores de C++ deben realizar cinco pasos para producir una copia ejecutable de un programa:
1. 2. 3. 4.

5.

Editar Preprocesar Compilar Encadenar, y Ejecutar


Ago-Dic 2010 Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez 8

Editar
El primer paso involucrado en llevar un programa de la fuente a la ejecucin es la creacin de un archivo que contenga el cdigo fuente. El programa que se usa para crear un cdigo fuente es llamado editor. Los editores que los programadores usan, varan de simples y genricos editores de texto (como el Notepad de Windows o el vi de UNIX) a editores sofisticados que tpicamente vienen como parte de los Ambientes de Desarrollo Integrados (ADI's). Estos sofisticados editores son tan poderosos debido a que brindan funcionalidad a travs de la creacin y mantenimiento del cdigo fuente. La sintaxis en colores es un ejemplo de la funcionalidad que estos editores ofrecen.

Ago-Dic 2010

Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

Preproceso
El preprocesamiento involucra la modificacin de los archivos del cdigo fuente antes de la compilacin. Las primeras dos lneas del Listado 1 contienen comandos llamados directivas al preprocesador, las cuales informan al preprocesador que desarrolle alguna accin. Estas lneas indican al preprocesador que incluya el contenido de los archivos dentro del cdigo fuente del programa. El preprocesamiento tambin involucra la sustitucin de textos de macros.

Ago-Dic 2010 Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez 10

Compilar

El preprocesamiento usualmente es desarrollado de manera automtica justo antes de la etapa de compilacin. La compilacin es un proceso complejo que convierte el cdigo fuente preprocesado en un cdigo objeto. Parte del proceso de compilacin involucra la verificacin de que la sintaxis del cdigo fuente sea vlida. Cuando un programa es compilado (especialmente la primera vez), se tienen errores de sintaxis. Esto es conocido como un "error de compilacin". Cuando nos enfrentamos con un error de compilacin, el programador debe regresar al primer paso de este proceso y editar el cdigo fuente para eliminar el error. La herramienta de software usada para compilar el cdigo fuente es conocida como compilador. Un ejemplo de un compilador de C++ es el GNU o GCC. El GNU compila muchos lenguajes de programacin diferentes, uno de los cuales es C++. El GCC es software gratuito.
Ago-Dic 2010 Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez 11

Encadenar
El proceso de encadenado es una etapa que normalmente se realiza por la misma herramienta que compila un programa e involucra la combinacin del cdigo objeto producido por el compilador con otro cdigo de biblioteca precompilado. El resultado de esta operacin es un archivo ejecutable. El archivo ejecutable es una imagen que contiene el cdigo objeto del programa compilado y encadenado, grabado en un dispositivo de almacenamiento permanente (el disco duro).

Ago-Dic 2010 Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez 12

Ejecutar

Despus de que el cdigo fuente del programa ha sido editado, preprocesado, compilado y encadenado en un archivo ejecutable, el programa esta listo para ser ejecutado. Los errores que se detecten en este punto son conocidos como "errores de ejecucin" y normalmente son ms difciles de corregir que los errores de compilacin, debido a que involucran problemas en la lgica del programa.
Ago-Dic 2010 Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez 13

Cmo Compilar y Ejecutar un Programa en la Lnea de Comandos

Muy a menudo, las etapas de preprocesamiento, compilacin y encadenado son agrupadas informalmente y conocidas todas juntas como "compilacin". Es fcil ver esto por que las herramientas que los programadores utilizan desarrollan estas tareas juntas. Por ejemplo, al usar GCC, podemos preprocesar, compilar y encadenar en una misma etapa. La siguiente lnea de comando asume que el cdigo fuente es llamado hello.cpp. $ g++ hello.cpp Como resultado de la ejecucin del comando anterior, el archivo del cdigo fuente hello.cpp ser preprocesado, despus compilado y por ltimo encadenado para producir un archivo ejecutable llamado a.exe. El nombre default del archivo a.exe puede ser reemplazado usando la opcin del compilador -o. $ g++ hello.cpp -o hello.exe
Ago-Dic 2010 Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez 14

Las opciones adicionales (-ansi y-pedantic) le informan al compilador que este deber compilar solamente programas que estn escritos en ANSI C++ y que deber emitir mensajes de advertencia cuando encuentre cdigo que viole el estndar de la ANSI. El uso de estas opciones ayuda a localizar y prevenir ciertos tipos de errores. $ g++ -ansi -pedantic hello.cpp -o hello.exe Una vez que el programa ha sido compilado y el archivo ejecutable ha sido generado, el programa puede ser ejecutado. Desde la lnea de comandos, podemos utilizar la siguiente instruccin: $ ./hello.exe El punto y la diagonal que preceden al nombre del archivo no son necesarios, son instrucciones que le indican al sistema operativo que busque al archivo hello.exe en el directorio actual. La siguiente pantalla muestra el resultado de la compilacin y ejecucin del programa.

Ago-Dic 2010

Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

15

Ago-Dic 2010

Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

16

Compilador:

Microsoft Visual Studio 2008

Ago-Dic 2010

Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

17

1.2 Estructuras de Datos y Algoritmos en C++


1.2.1 Qu son los Algoritmos y Estructuras de Datos? 1.2.2 Solucin de Problemas con Estructuras de Datos y Algoritmos

Ago-Dic 2010

Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

18

Estructuras de Datos

En casi cualquier aspecto del mundo moderno actual, encontramos informacin en todas formas y tamaos. La cantidad de informacin que encontramos es algunas veces tan grande, que sin un mtodo efectivo de almacenaje y representacin, sta se vuelve inservible. (libros guardados en la biblioteca local, o una fila mientras espera comprar boletos en un cine). Una estructura de datos, en el trmino ms simple, es una representacin estructurada de informacin. Tanto el sistema usado para almacenar libros en la biblioteca y la fila de gente en el cine son ejemplos reales de estructuras de datos. Considerando un contexto ms amplio, las estructuras de datos tpicamente representan o almacenan datos para facilitar la solucin de algunos problemas
Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

Ago-Dic 2010

19

En el ejemplo de la biblioteca, el problema que la estructura de datos ayuda a resolver es la localizacin de un libro especfico. En el cine, la gente espera en una fila por lo que es ms fcil determinar quin tiene el siguiente turno. Una estructura de datos puede estar compuesta de piezas simples de datos. Considera tu direccin como una estructura de datos. Existen muchos componentes en esta estructura de datos, todos los cuales son piezas simples de datos. Las estructuras de datos tambin pueden ser complejas, incluso pueden contener otras estructuras de datos. Por ejemplo, una biblioteca contiene muchos estantes, los cuales a su vez contienen muchos libros. Sobre la repisa de uno de estos estantes podra estar una caja de cartn, la cual a su vez contiene unos cuantos libros. En este ejemplo, los estantes es una estructura de datos compuesta de libros y cajas de libros. Las cajas tambin son estructuras de datos, ya que tambin almacenan libros. Tenemos una estructura de datos (estantes) que esta compuesta de otra estructura de datos (una caja). Ambas estructuras de datos proveen un medio para almacenar informacin (los libros) para ayudar a resolver algunos problemas (encontrar un libro especfico).

Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

Ago-Dic 2010

20

Un archivero que contiene carpetas es otro buen ejemplo de como las estructuras de datos pueden componerse de otras estructuras de datos. El archivero es una estructura de datos completa. El archivero esta compuesta de cajones, los cuales contienen carpetas, que a su vez contienen archivos.

Ago-Dic 2010

Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

21

Algoritmos
Adems de tener una estructura de datos que representa informacin, se requiere de algunas secuencias de acciones o serie de pasos, para resolver un problema. La serie de pasos que usa y manipula una estructura de datos para solucionar un problema es llamada algoritmo.

Ago-Dic 2010

Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

22

Ejemplo: la fila del cine

El problema a resolver es:


Un grupo de gente esperando para comprar boletos.

La estructura de datos:
Una fila de gente.

El algoritmo involucra:
Eliminar a una persona del inicio de la fila (hasta que la fila est vaca) cuando el cajero se desocupa.
Ago-Dic 2010 Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez 23

Algoritmo:
1. 2.

3. 4.

Esperar a que el cajero est disponible. Eliminar al cliente que est al inicio de la fila. Dejar que el cajero ayude al cliente eliminado. Ir al paso 1.

Ago-Dic 2010

Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

24

1.3 Programacin Bsica en C++


Se estudiarn las caractersticas y conceptos bsicos del lenguaje de programacin C++. 1.3.1 Tipos de Datos 1.3.2 Clases 1.3.3 Entrada y Salida 1.3.4 El Preprocesador 1.3.5 Ejemplo
Ago-Dic 2010 Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez 25

1.3.1 Tipos de Datos


Tipos de Datos Cadenas de Caracteres (Strings) Arreglos Vectores Creando Nuevos Nombres de Tipos de Datos (Data Type Names)

Ago-Dic 2010

Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

26

Tipos de Datos

C++ clasifica los objetos de datos en diferentes tipos. Los diferentes tipos de datos:
Describen las operaciones fundamentales que el lenguaje desempea sobre los datos, Describen el rango de valores que los tipos de datos aceptan.

El lenguaje verifica y asegura que un programador asigne solamente valores apropiados al objeto de datos:
Debido a que los diferentes tipos de datos permiten guardar valores diferentes, Si un programador asigna un valor inapropiado, ocurrir un error,
Ejemplo: un nmero que es muy grande o muy pequeo, para un objeto de datos.

Este mecanismo conocido como revisin de tipos hace que C++ sea considerado un lenguaje fuertemente tipeado
Es muy estricto al revisar los tipos de datos y sus valores correspondientes. Esto es bueno para el programador de C++, ya que los lenguajes altamente tipeados pueden detectar errores que otros lenguajes no detectan.

Ago-Dic 2010

Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

27

Tipos de datos en Java y C++


C++
bool
char int short long float double

Java
Boolean
Char Int Short long float double

Ago-Dic 2010

Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

28

Tipos de Datos
El espacio requerido para almacenar variables difiere entre los lenguajes. En C++, los requerimientos de espacio de almacenamiento, son dejados a discrecin del compilador. A diferencia de Java, estos requerimientos no son especficamente establecidos por el estndar del lenguaje.

Por lo tanto, sobre una plataforma de C++ las variables int pueden ocupar dos bytes de longitud, mientras que en otra pueden ocupar cuatro bytes. En Java, una variable de tipo int necesariamente requiere cuatro bytes de memoria. Usualmente el tamao en bytes de una variable no es importante, a menos de que este defina el rango de valores que la variable puede aceptar.
A medida que aumenta el nmero de bytes que una variable necesita para almacenar sus datos, el rango de valores permitido por la variable tambin aumenta.
Ago-Dic 2010 Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez 29

Tipos de Datos
El siguiente programa usa el operador sizeof de C++ para desplegar el tamao, en bytes, de los tipos de datos de la implementacin particular de C++ usada en la compilacin.
#include <cstdlib> #include <iostream> using namespace std; int main(int argc, char* argv[]) { cout << " bool: " << sizeof(bool) << endl; cout << " char: " << sizeof(char) << endl; cout << " short: " << sizeof(short) << endl; cout << " int: " << sizeof(int) << endl; cout << " long: " << sizeof(long) << endl; cout << " float: " << sizeof(float) << endl; cout << "double: " << sizeof(double) << endl; return EXIT_SUCCESS; }
Ago-Dic 2010 Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez 30

C++ contiene un mecanismo para crear variables de "solo-lectura (o "variables constantes" o solo "constantes): usa la palabra reservada const: indica que la variable que ha sido declarada no puede ser modificada despus de que sta haya sido inicializada.

Ago-Dic 2010

Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

31

const int BOILING_POINT = 100; const int FREEZING_POINT = 0; const float PI = 3.14159;
Listado 2 Variables
Los nombres de las variables constantes aparecen en maysculas, aunque esto no es necesario, pero es un estndar que los programadores profesionales de C++ tienden a seguir. El nombrar constantes en maysculas permite a los programadores reconocer y recordar fcilmente que el identificador es una variable constante.
Ago-Dic 2010 Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez 32

Cadenas de Caracteres (Strings)

En C++ el tipo de dato cadena de caracteres (string), provee la abstraccin necesaria para permitir que los programadores trabajen con cadenas de caracteres. El tipo cadena de caracteres no est disponible en todos los programas:
Si un programa de C++ requiere el tipo cadena de caracteres, el programador de C++ deber referirse a la biblioteca que define este tipo.
Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

Ago-Dic 2010

33

#include <iostream> #include <string> #include <cstdlib> using namespace std;

int main(int argc, char* argv[]) { string s1 = "first"; // Initialization string s2; s1 += " string"; // Concatenation s2 = s1; // Assignment cout << s1 << endl; // Stream output cout << s1.length() << endl; // Length return EXIT_SUCCESS; }

Listado 3 Variables cadenas de caracteres


Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

Ago-Dic 2010

34

Arreglos

C++ provee el soporte bsico para una secuencia de datos homogneos a travs de los arreglos. El siguiente listado muestra la declaracin de un arreglo tipo int de tamao diez en C++.
// declare and create an array of integers int cpp_array[10]; Listado 5 Un arreglo en C++

Ago-Dic 2010

Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

35

#include <iostream> #include <cstdlib> using namespace std; int main(int argc, char* argv[]) {

int arr[25];
for (int i = 0; i < 25; i++) { arr[i] = i; } cout << "The first element equals: " << arr[0] << endl; cout << "The second element equals: " << arr[1] << endl; cout << "The last element equals: " << arr[24] << endl; return EXIT_SUCCESS;

Listado 6 Acceso de elementos en un arreglo de C++

Ago-Dic 2010

Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

36

Un peligro inherente que existe al hacer arreglos en C++ es la falta de la verificacin de los lmites del arreglo. En C++, si tenemos un arreglo de diez elementos, podemos intentar acceder las posiciones 12, 20 100 del arreglo. Dependiendo de unas cuantas cosas, el programa puede o no "tronar" como un resultado de querer acceder elementos fuera de los lmites del arreglo. Sin embargo, podemos asegurar que los datos que obtenemos de un acceso fuera de los lmites podran no ser significativos. El siguiente listado muestra un acceso fuera de los lmites en C++.
Ago-Dic 2010 Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez 37

int arr[10]; cout << arr[11] << endl;


Listado 7 Acceso fuera de los lmites
El cdigo del listado anterior dentro del contexto de un programa en C++, definitivamente compila, y podra an correr sin errores. Qu valor despliega la lnea 2? Este depende de algunas cosas, pero comnmente ese valor podra ser el valor de otra variable en el programa. Esto claramente es una prctica peligrosa, que deberamos evitar.
Ago-Dic 2010

Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

38

Vectores
El tipo de dato vector provee una alternativa mucho ms segura a un arreglo bsico en C++. En C++, como en Java, los vectores existen como un arreglo con mltiples caractersticas.

Por ejemplo, a diferencia de un arreglo en C++, un vector tiene una funcin que regresa el tamao del vector. Los vectores tambin ofrecen soporte en la revisin de lmites, y a diferencia de los arreglos, automticamente aumentan en tamao cuando se requiere. La pgina 2.2.2 Cmo Usar el Contenedor vector de STL contiene una discusin completa de los datos tipo vector.
Ago-Dic 2010 Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

39

Creando Nuevos Nombres de Tipos de Datos (Data Type Names)

C++ da la posibilidad a los programadores de crear nombres adicionales para los tipos de datos existentes. Para crear otro nombre se utiliza la palabra clave typedef con la siguiente sintaxis.

typedef type-expression new-name; Ejemplo 1 Uso de typedef


Ago-Dic 2010 Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez 40

#include <iostream> #include <cstdlib> using namespace std; typedef int my_int; typedef my_int* my_int_ptr; int main(int argc, char* argv[]) { my_int i = 10; my_int_ptr ptr = &i; cout << *ptr << endl; return EXIT_SUCCESS; }

Listado 8 Ejemplos del uso de typedef


Ago-Dic 2010 Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez 41

Utilizando nombres de tipos de datos creados con typedef les permite a los programadores encapsular su eleccin de tipos de datos. Esta es una buena prctica de programacin, debido a que, si es necesario, un programador puede fcilmente cambiar todos los usos de un tipo de dato en particular simplemente cambiando la definicin del typedef. Otros beneficios adicionales de la utilizacin de typedef sern examinados en 1.5.3 Plantillas (Templates).

Ago-Dic 2010 Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez 42

1.3.2 Clases
Sintaxis Bsica Constructores El Destructor Declaracin vs. Definicin

Ago-Dic 2010

Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

43

Sintaxis Bsica

La clase es la unidad bsica de abstraccin en C++.


Como en Java, podemos usar clases para especificar y luego instanciar objetos. El siguiente listado muestra la versin equivalente de la clase BankAccount en C++.
class BankAccount { private: double sum; string name; public: BankAccount(string nm) : name(nm), sum(0) {}

double balance() { return sum;} void deposit(double amount) {sum += amount;} void withdraw(double amount) {sum -= amount;} string getName() { return name;}
}; Listado 2 Clase BankAccount en C++
Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

Ago-Dic 2010

44

Constructores
Los constructores son los mtodos de una clase que definen que acciones tomar al crear un objeto. Una clase en C++ puede tener mltiples constructores:

Esto permite que exista variacin en la instancia de los objetos, debido a que pueden existir nmeros y tipos de parmetros diferentes en cada constructor.

El siguiente listado es una versin modificada de la clase BankAccount de C++. Esta versin modificada incluye un constructor adicional.
class BankAccount { private: double sum; string name; public: BankAccount(string nm) : name(nm), sum(0) {} BankAccount(string nm, double bal) : name(nm), sum(bal) {} double balance() { return sum;} void deposit(double amount) {sum += amount;} void withdraw(double amount) {sum -= amount;} string getName() { return name;} }; Ago-Dic 2010 Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez 45

Listado 3 Listas iniciales y constructores mltiples

Los programadores pueden declarar e instanciar objetos en C++ usando una sintaxis idntica a la declaracin de los tipos fundamentales de datos. El listado 4 muestra la instanciacin de la clase BankAccount.

BankAccount account1("checking"); BankAccount account2("savings", 200); account2.withdraw(100); account1.deposit(100); Listado 4 Instanciacin de Objetos

Ago-Dic 2010

Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

46

El Destructor
Un destructor es una funcin miembro especial de una clase de C++, llamada cuando termina el ciclo de vida de un objeto. Al igual que un constructor copy (copy constructor), slo un puede existir un destructor para una clase. Debido a que se ejecutan cuando termina el ciclo de vida de un objeto, los destructores por lo general definen acciones necesarias para liberar recursos que un objeto puede estar usando. Por ejemplo, considera un objeto que abre una conexin a una base de datos. Cuando el ciclo de vida del objeto termina, el destructor puede cerrar esa conexin a la base de datos. Examinaremos usos ms importantes de destructores en la seccin 1.4.3 Administracin de la Memoria Dinmica. Por lo pronto, podemos revisar un listado para ver como se ve la definicin de un destructor en C++.

Listado 5 El destructor

~BankAccount() { if (balance() < 0) { cout << "Warning: negative balance!" << endl; } }
Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

Ago-Dic 2010

47

Declaracin vs. Definicin

En esta discusin sobre la especificacin de clases en C++, el trmino "definicin" ha sido usado con respecto a las funciones.

La "declaracin" de una funcin, por su parte, solo especifica la interfaz de la funcin.


Esta interfaz incluye el nombre de la funcin, el tipo de regreso, y la lista de parmetros y sus tipos. El siguiente listado muestra tanto la declaracin como la definicin de la funcin average.
Ago-Dic 2010 Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

Cuando "definimos" una funcin, dictamos el comportamiento de la funcin a travs del cdigo que existe dentro de los {}.

48

#include <iostream> #include <cstdlib> using namespace std; // function declaration double average(int, int); int main(int argc, char* argv[]) { cout << average(10, 2) << endl; return EXIT_SUCCESS; } // function definition double average(int total, int count) { return (total / count); }
Ago-Dic 2010 Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez 49

Listado 6 Declaracin vs. definicin

La declaracin y la definicin de una funcin difieren en muchos aspectos.


En el ejemplo anterior, observa que la declaracin de la funcin average es seguida por un punto y coma y no por {}. Esto especifica que es la declaracin, no la definicin. La declaracin de una funcin no necesita incluir nombres de variables para los parmetros. La definicin, por otro lado, luce igual que cualquier funcin de C++ que hemos visto hasta ahora. La definicin de la funcin viene despus de su uso real en la funcin main. Esto es aceptable debido a que colocamos la declaracin de la funcin antes de la funcin main. Esta prctica, conocida como "forward reference" (referencia directa) es comn en la programacin en C++. Est permitido usar una funcin o una clase que an no ha sido definida, siempre y cuando haya sido declarada. Sin embargo, no est permitido usar una funcin o una clase que an no haya sido definida, sin incluir la referencia directa.

Ago-Dic 2010

Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

50

Las reglas relacionadas con la especificacin de la clase en C++ ofrecen cierta flexibilidad en la colocacin de las definiciones de la funcin miembro. Una clase en C++ puede incluir todas las definiciones de sus funciones miembro dentro de la definicin de clase. De manera alternativa, las definiciones para una o ms funciones de la clase miembro pueden aparecer fuera de la definicin de clase, siempre y cuando se incluya las declaraciones dentro de la definicin de clase. Los programadores deben calificar completamente los nombres de las funciones de la clase miembro que aparecen fuera de la definicin de clase. Para calificar un nombre completamente, al nombre de la funcin se le debe aadir (prepended) previamente el nombre de la clase, seguido por el operador de resolucin de visibilidad (::).

Ago-Dic 2010 Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez 51

class BankAccount {

private: double sum; string name;

public: BankAccount(string nm) : name(nm), sum(0) {} BankAccount(string nm, double bal) : name(nm), sum(bal) {}

double balance(); void deposit(double); void withdraw(double); string getName(); };

Listado 7 Definicin de las funciones de la clase miembro fuera de la declaracin

double BankAccount::balance() {

return sum;
} void BankAccount::deposit(double amount) { sum += amount; } void BankAccount::withdraw(double amount) {

sum -= amount;
} string BankAccount::getName() { return name; }

Ago-Dic 2010

Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

52

Las definiciones de funcin de la clase miembro tambin pueden aparecer todas juntas en otro archivo diferente al de la definicin de clase. Cuando un programador especifica una clase de esta forma, puede compilar de forma independiente el archivo que contiene las declaraciones de la funcin de la clase miembro. El archivo que contiene las definiciones de la funcin de la clase miembro es conocido como un archivo de implantacin. El archivo de definicin de clase (o archivo de cabecera o encabezado) se convierte en la interfaz que comparte el cdigo precompilado.

Ago-Dic 2010 Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez 53

#include <string> #include <cstdlib> #include <iostream> #ifndef _BANKACCOUNT_H #define _BANKACCOUNT_H using namespace std;

#include "bankaccount.h" double BankAccount::balance() { return sum; } void BankAccount::deposit(double amount) { sum += amount; } void BankAccount::withdraw(double amount) { sum -= amount; } string BankAccount::getName() { return name; }

class BankAccount {
private: double sum; string name;

Listado 9 bankaccount.cpp La directiva del preprocesador #include reemplaza la directiva con el contenido del archivo especificado. Las directivas #define, #ifndef y #endif son utilizadas para prevenir que un archivo de definicin no sea incluido en ms de una ocasin. Los usos de las directivas del preprocesador se revisarn en la pgina 1.3.4 El Preprocesador.

public:
BankAccount(string nm) : name(nm), sum(0) {} BankAccount(string nm, double bal) : name(nm), sum(bal) {} double balance(); void deposit(double); void withdraw(double); string getName(); }; #endif

Listado 8 bankaccount.h
Ago-Dic 2010 Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez 54

1.3.3 Entrada y Salida


Flujos (Streams) Uso de los Flujos Estndar El Archivo de Entrada y Salida Fallas Comunes

Ago-Dic 2010

Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

55

Flujos (Streams)
La entrada y salida de informacin en C++ se basa en el concepto de un flujo. Un flujo (stream) es una secuencia de bytes que fluyen desde algo hacia algo ms. El proceso de la salida implica el movimiento de bytes, uno a la vez, de un programa a un dispositivo. Este dispositivo poda ser un monitor, impresora, o an un archivo en un disco duro. La entrada de informacin es lo contrario. La entrada de informacin implica el flujo de bytes de un dispositivo (un teclado, un archivo, una conexin de red) hacia el programa.

Ago-Dic 2010 Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez 56

#include <string> #include <cstdlib> #include <iostream> using namespace std;

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


cout << "Enter your name: "; string name; cin >> name; cout << "Hello " << name; return EXIT_SUCCESS; }

Ago-Dic 2010

Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

57

Uso de los Flujos Estndar

Tres flujos especficos estn siempre disponibles a travs del ciclo de vida de cada programa de C++.
stos son los flujos de entrada estndar, salida estndar y error estndar. El flujo de entrada estndar lee datos de la consola, el flujo de la salida estndar escribe datos a la consola, y el flujo de error estndar muestra mensajes de error a la consola.

Los programadores tienen acceso a los flujos estndar a travs de un conjunto de objetos.
Los objetos cin y cout brindan acceso respectivamente a los flujos estndar de entrada y salida. El objeto cerr proporciona acceso al flujo de error estndar.

Ago-Dic 2010

Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

58

cout << "Enter your name and age: ";


string name; int age; cin >> name >> age; if (age < 0) { cerr << "\nInvalid age entered"; } else { cout << "\n" << name << " is " << age; }
Listado 2 Salida estndar y el operador <<

Ago-Dic 2010

Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

59

Los programadores de C++ pueden definir cmo las clases que crean interactan con los flujos usando los operadores < < y > >. Esto es conocido como sobrecarga del operador. Las clases del flujo definen la insercin (< <) y la extraccin (> >) para funcionar de una manera especial, para diversos tipos de datos.

Si es utilizada con enteros, nmeros de punto flotante o cadenas de caracteres, estos operadores sacan y dan formato a los datos de la manera apropiada. Podemos tambin definir el comportamiento de estos operadores para las clases que creamos. Esto permite que el cdigo de entrada y salida para las clases definidas por el usuario se asemejen a los cdigos de entrada y salida de los tipos construidos.
Ago-Dic 2010 Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez 60

class Person { private: string first_name; string last_name; string job; public: Person (string f, string l, string j) : first_name(f), last_name(l), job(j) {} friend ostream& operator<<(ostream& os, Person const& r); }; ostream& operator<<(ostream& os, Person const& r) { os << r.first_name << " " << r.last_name; os << " works as a " << r.job;

Listado 3 Una clase que sobrecarga <<

return os;
}
Ago-Dic 2010 Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez 61

El Listado 3 define la clase Person. Debido a que quisiramos sacar objetos de la clase Person de la misma manera que sacamos enteros o cadenas de caracteres, sobrecargamos el operador < <. Declarar esta funcin como una funcin "amiga" en la lnea 11 permite que la funcin tenga acceso a datos confidenciales de la clase Person. Esto es necesario puesto que la funcin sobrecargada del operador no es un miembro de la clase Person.

Person p("Stan", "Dardeviation", "Math Teacher"); cout << p << endl; Stan Dardeviation works as a Math Teacher

Listado 4 Uso de la clase Person


Ejemplo1 Salida del Listado 4

Ago-Dic 2010

Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

62

El Archivo de Entrada y Salida


La entrada y salida basada en archivos es similar a los mecanismos de entrada y salida para el teclado y la pantalla. La diferencia principal es que los programadores deben abrir y cerrar archivos explcitamente.

open input file while( there is input left ) { read next input item process it } close input file

Ejemplo 2 Pseudocdigo para leer entradas de un archivo

Ago-Dic 2010

Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

63

Abriendo y leyendo un archivo de enteros.

#include <fstream> #include <iostream> #include <cstdlib> using namespace std; int main(int argc, char* argv[]) { ifstream inf; inf.open("somefile.txt"); if (! inf) { // Check to see if file opened cerr << "Could not open file!" << endl; return EXIT_FAILURE; } int x; // While input remains, read an integer. while (inf >> x) { cout << x << endl; } inf.close(); // Close the input file return EXIT_SUCCESS; }

El objeto usado en la entrada del archivo es del tipo ifstream. Puesto que esta clase no es parte del lenguaje de C++, debemos incluir su biblioteca en nuestro programa. Se declara un objeto del tipo ifstream y se llama la funcin miembro open para abrir un archivo. Es buena prctica de programacin revisar si al intentar abrir un archivo realmente se tiene xito. Uso del operador de extraccin en el condicional del while.: Mientras el intento de extraccin tenga xito, se regresa true (el valor ledo del archivo se asigna a x). Se seala una falla para leer otro entero por un valor de false, lo que termina el while.

Listado 5 Entrada de un Archivo 64

Ago-Dic 2010

Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

La salida del archivo se asemeja a su entrada. Necesitamos incluir una referencia a la biblioteca del fstream, Pero utilizamos un objeto ofstream en vez de un objeto ifstream.

ofstream onf; onf.open("output.txt"); if (! onf) { // Check to see if file opened cerr << "Could not open file!" << endl; return EXIT_FAILURE; } for (int i = 1; i <= 10; i++) { onf << "This is line " << i << endl; } onf.close(); // Close the output file Listado 6 Salida del Archivo

Ago-Dic 2010

Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

65

1.3.4 El Preprocesador
Sustitucin de Texto Inclusin de Archivos Sustitucin Macro Compilacin Condicional Ejemplo:Verificacin de Suposiciones

Ago-Dic 2010

Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

66

Sustitucin de Texto

El preprocesador es una herramienta que los programadores de C++ utilizan para manipular el contenido de los archivos del cdigo fuente antes de compilar: el preprocesador realiza la sustitucin y modificacin de texto -> Alto nivel. Un programador interacta con el preprocesador a travs de los comandos llamados directivas del preprocesador. Comenzando con el signo de nmero (#) , las directivas del preprocesador son comandos de una sola lnea que un programador coloca en un archivo del cdigo fuente. La inclusin de archivos, sustitucin macro, y la compilacin condicional son tres caractersticas de alto nivel que el preprocesador brinda al programador. Como los programas de C++ se componen enteramente de texto, un programador debe utilizar el preprocesador para incluir la declaracin de clases o funciones externas. Esto se conoce como inclusin de archivo. Las directivas del preprocesador usadas para definir otras tareas, tales como una sustitucin macro, pueden causar que el preprocesador haga muchas modificaciones en un archivo del cdigo fuente.
Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

Ago-Dic 2010

67

#include <string> #include <cstdlib> #include <iostream> #include <fstream> #include "my_functions.h" #include "my_class.h" #include "..\another_file1.h" #include "directory\sub\another_file2.h" using namespace std; int main(int argc, char* argv[]) {

Listado 1 #include

// Rest of program...

Ago-Dic 2010

Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

68

Sustitucin Macro
#define identifier replacement-text
Ejemplo 1 Forma general de la directiva #define

#include <iostream> #include <cstdlib>


#define MAXIMUM 20 using namespace std; int main(int argc, char* argv[]) {

Listado 2 Sustitucin Macro

for (int i = 0; i < MAXIMUM; i++) { cout << i << endl; }


return EXIT_SUCCESS; }
Ago-Dic 2010 Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez 69

Podemos utilizar la sustitucin macro para implantar una variable constante.(la sustitucin macro, en el ejemplo anterior, permite que el identificador MAXIMUM funcione como una variable constante. Los programadores de C++ deben utilizar la palabra reservada const en lugar de la sustitucin macro para crear variables constantes.
La palabra reservada const es parte del lenguaje de C++ (y no una caracterstica del preprocesador), Las constantes creadas con ella soportan mejor la revisin de tipos que las constantes creadas usando la sustitucin macro. Las constantes creadas con la sustitucin macro existen en C++ para proveer la compatibilidad con programas de C.

El preprocesador de C++ tambin soporta macros con parmetros. El uso de una macro con parmetros es muy parecido a una funcin normal de C++. El preprocesador sustituye la llamada de la funcin aparente con el texto de reemplazo macro.
Ago-Dic 2010 Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez 70

#define identifier(identifier, identifier, ...) replacement-text


Ejemplo 2 Forma general de una macro con parmetros
#include <iostream> #include <cstdlib> #define max(x,y) ( ( (x)>(y) ) ? (x):(y) ) using namespace std;

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


int i = 4; int j = 3; cout << max(i, j) << endl; return EXIT_SUCCESS; }
Ago-Dic 2010 Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez 71

Listado 3 Macro con Parmetros

Compilacin Condicional

Al utilizar #define, y algunas otras directivas del preprocesador, podemos ordenar al compilador, compilar solamente ciertas secciones de nuestro cdigo fuente. Esto es til en muchas circunstancias, una de las cuales es para insertar el cdigo de depuracin que puede ser habilitado y deshabilitado fcilmente. En seguida, veremos un ejemplo que utiliza las directivas #define, #if, y #endif.
Ago-Dic 2010 Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez 72

#include <iostream> #include <cstdlib> #define DEBUG using namespace std; int main(int argc, char* argv[]) { #if defined(DEBUG) cerr << "Debugging enabled" << endl; #endif int arr[10]; for (int i = 0; i < 10; i++) { arr[i] = i; #if defined(DEBUG) cerr << "i = " << i << endl;

Listado 4 Compilacin Condicional

cerr << "arr[i] = " << arr[i] << endl;


#endif } return EXIT_SUCCESS; }

Ago-Dic 2010

Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

73

La compilacin condicional tambin se utiliza a menudo para prevenir definiciones mltiples de las clases y funciones contenidas en archivos de cabecera (header files). Incluir un archivo de cabecera ms de una vez en un programa puede causar problemas en la redefinicin de la clase y funcin. Podemos prevenir esto con una tcnica que utilice la compilacin condicional.
Ago-Dic 2010 Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez 74

#if !defined(_PERSON_H_) #define _PERSON_H_ class Person { // Class declaration... }; #endif


La directiva #ifdef identificador es equivalente a #if defined(identificador). La directiva #ifndef identificador es equivalente a #if !defined(identificador).

Listado 5 Prevencin de declaraciones mltiples


Ago-Dic 2010 Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez 75

Verificacin de Suposiciones
double calculate_average(int total, int count) { // avoid divide by zero error if (count != 0) { return total / count; } else { return 0; }
} Listado 7 Verificacin de una suposicin usando una asercin

double calculate_average(int total, int count) {


// assume we are given valid data assert (count != 0); return total / count;

}
Listado 6 Codificacin defensiva
Ago-Dic 2010 Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez 76

En este mdulo, el curso introduce algunos de los conceptos y caractersticas bsicas del lenguaje de programacin C++ relacionadas con la adminis

1.4 Administracin de la Memoria


Se introducen algunos de los conceptos y caractersticas bsicas del lenguaje de programacin C++ relacionadas con la administracin de la memoria.

1.4.1 Apuntadores 1.4.2 Mecanismos de Paso de Parmetros 1.4.3 Administracin de la Memoria Dinmica

Ago-Dic 2010 Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez 77

1.4.1 Apuntadores
Apuntadores e Indireccin Operaciones Bsicas

Declaracin e Inicializacin Dereferenciar (Dereference)

Aritmtica del Apuntador

Ago-Dic 2010

Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

78

Apuntadores e Indireccin
Un apuntador es una variable que almacena la direccin de la memoria de otra variable. Hemos visto ya en C++ que los tipos de datos dictan el rango y tipo de valores que una variable puede almacenar.

Las variables de los tipos de datos que hemos examinado hasta ahora almacenan valores como por ejemplo enteros, nmeros de punto flotante y cadenas de caracteres (strings).

La variable apuntador es nica ya que salva la direccin de la memoria de otra variable. La direccin de memoria es la localizacin especfica en la memoria principal donde existe una variable durante la ejecucin de un programa. Los programadores usan apuntadores para acceder y manipular indirectamente otras variables.

Este acceso y manipulacin se considera "indirecta" puesto que se logra usando un apuntador en vez de la variable real que est siendo modificada. La "indireccin" permite la creacin de las estructuras de datos complejas y algoritmos poderosos. Por ejemplo, sin apuntadores e indireccin no sera posible crear una estructura de datos de la lista encadenada.

Ago-Dic 2010

Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

79

Operaciones Bsicas: Declaracin e Inicializacin


La declaracin de una variable apuntador requiere el uso de cierta sintaxis desconocida. Una declaracin del apuntador debe prefijar su nombre de variable con un asterisco (*). Esto significa para el compilador que la variable declarada es un apuntador.

int *int_ptr; float *float_ptr; char *char_ptr; Listado 1 Declaracin del Apuntador

Ago-Dic 2010

Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

80

Aunque los apuntadores solamente almacenan direcciones de la memoria, la declaracin de una variable apuntador debe especificar un tipo de datos especfico cuya direccin de memoria pueda almacenar el apuntador.
Las variables de diferentes tipos de datos pueden no utilizar necesariamente la misma cantidad de almacenaje en memoria. Para permitir el acceso y la manipulacin indirecta de una variable usando un apuntador, el compilador debe saber el tamao exacto de la variable.

La inicializacin del apuntador tambin requiere algo de sintaxis nueva. No podemos simplemente inicializar un apuntador a una variable no-apuntador porque los apuntadores almacenan las direcciones de memoria y valores no regulares.
Debemos obtener la direccin de memoria de la variable mediante el operador address-of (&), que regresa la direccin de la memoria de donde est almacenada la variable.
Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

Ago-Dic 2010

81

El listado 2:
declara una variable entera y fija 100 como su valor inicial. declara un apuntador del tipo int, inicializado con la direccin de la variable i.
int i = 100; int *ptr = &i; Listado 2 Inicializacin del Apuntador

ptr "apunta" a i.
Ago-Dic 2010 Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez 82

Dereferenciar (Dereference)
El acceso indirecto y la manipulacin de variables usando apuntadores se logra usando el operador dereference. Un programador aplica el operador dereference (*) para acceder o modificar el valor de la variable sealada por un apuntador. El Listado 3 demuestra el acceso indirecto y la modificacin de una variable usando un apuntador.

int i = 100; int *ptr = &i; cout << *ptr << endl; // outputs 100 *ptr = 200; // Sets i = 200 cout << i << endl; // outputs 200 Listado 3 Dereferenciacin de apuntadores

Ago-Dic 2010

Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

83

#include <iostream> #include <cstdlib> using namespace std; class Thing { public: int number; Thing() : number(0) {} void method1() { cout << "Method 1" << endl; } void method2() { cout << "Method 2" << endl; } }; int main(int argc, char* argv[]) { // Direct access Thing thing; cout << thing.number << endl; thing.method1(); thing.method2(); // Equivalent indirect access Thing *ptr = &thing; cout << ptr->number << endl; ptr->method1(); ptr->method2(); return EXIT_SUCCESS; }

Se pueden invocar funciones miembro de un objeto a travs de un apuntador. El operador de la flecha (->) primero dereferencia el apuntador y en seguida invoca la funcin miembro nombrada.

Listado 4 El operador arrow


Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

Ago-Dic 2010

84

Solamente podemos dereferenciar de forma segura los apuntadores que sealan hacia direcciones vlidas de memoria. Dereferenciar apuntadores que no se han inicializado a direcciones de memoria vlidas causan un error de ejecucin. Una tcnica utilizada para evitar este problema es la inicializacin de variables apuntador al puntero nulo.

El puntero nulo representa un lugar en la memoria que no puede ser dereferenciado. La inicializacin de punteros al puntero nulo, evita que una dereferenciacin accidental pueda causar un error de ejecucin. El apuntador nulo es referenciado usando la macro NULL previamente definida.
Ago-Dic 2010 Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez 85

int *ptr = NULL; // Initialize to null pointer // ... Some other code ...

int i = 100; ptr = &i; // Now set our pointer


Listado 5 El apuntador null Los programadores tambin usan apuntadores nulos como valores para indicar el fin de alguna estructura o secuencia. Ms adelante examinaremos el uso del apuntador null.

Ago-Dic 2010

Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

86

Aritmtica del Apuntador


La aritmtica del apuntador es el uso de sumas y restas para cambiar la posicin de memoria que un apuntador almacena. Estas operaciones son concernientes a la posicin de la memoria actualmente almacenada en un apuntador. Restar el valor 3 de un apuntador, por ejemplo, mueve la posicin tres lugares antes del apuntador. El incremento de un apuntador causa que ste "apunte" a la siguiente posicin de memoria. La aritmtica del apuntador automticamente toma en cuenta el tamao del tipo de dato implicado. La adicin del valor 3 a un apuntador de tipo entero, en realidad agrega un 3 multiplicado por el tamao del entero a la posicin actualmente almacenada en el apuntador.

int array[] = {10, 20, 30, 40, 50}; int *ptr = &array[0]; cout << *ptr << endl; ptr++; cout << *ptr << endl; ptr--; cout << *ptr << endl; // outputs 10 // outputs 20

// outputs 10

cout << *(ptr + 4) << endl; // outputs 50

Listado 6 Aritmtica bsica de los apuntadores

Ago-Dic 2010

Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

87

La aritmtica del apuntador tiene muchos usos importantes en la programacin en C++. Un uso es el recorrido de arreglos (traversal of arrays).

int data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; int *ptr = &data[10]; // points to last element in array do { cout << *ptr << endl; } while (ptr-- != &data[0]);

Ago-Dic 2010

Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

88

1.4.2 Mecanismos de Paso de Parmetros

Paso de Parmetros por Valor Paso de Parmetros por Referencia

Ago-Dic 2010

Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

89

Paso de parmetros por valor

El paso de parmetros por valor es el mecanismo default de paso de parmetros en C++. Cuando un parmetro es pasado por valor a una funcin, se crea y entrega una copia del parmetro a la funcin. Si realizamos un cambio a un parmetro que sea pasado por valor, la variable original permanece sin cambios. El cambio se realiza a una copia de la variable original.
Ago-Dic 2010 Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez 90

#include <iostream> #include <cstdlib>

using namespace std;


void increment(int x) { x++; // Increment x by 1 } int main(int argc, char* argv[]) { int y = 10; increment(y); // Variable y remains unchanged. cout << y << endl; Listado 1 Paso de parmetros por valor en C++

return EXIT_SUCCESS;
}
Ago-Dic 2010 Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez 91

C++ tambin puede pasar objetos por valor.

#include <iostream> #include <cstdlib> #include <string> #include <cassert> using namespace std; class Person { private: string name; int age; public: Person() : name(""), age(0) {} void set_age(int age) {this->age = age;} int get_age() { return age;} void set_name(string name) {this->name = name;} string get_name() { return name;} }; void increment_age(Person p) { p.set_age(p.get_age() + 1); } int main(int argc, char* argv[]) {

Listado 2 Paso de un objeto por valor

Person person; person.set_name("John Doe"); person.set_age(30); increment_age(person); // age remains unchanged cout << person.get_age() << endl; return EXIT_SUCCESS;
}

Ago-Dic 2010

Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

92

Paso de parmetros por referencia


C++ tambin soporta el mecanismo de paso de parmetros por referencia. A diferencia del paso de parmetros por valor, no se hacen copias de las variables que son pasadas por referencia. En su lugar, una funcin llamada recibe una referencia, o alias, al parmetro real provisto por la funcin llamada. Por esta razn, el paso por referencia se utiliza para construir funciones que pueden modificar las variables en la funcin llamada. Incluso cuando una funcin no necesita modificar las variables en la funcin llamada, el paso por referencia es utilizado a veces para evitar el sobreproceso del paso de parmetros por valor. Un uso comn del paso de parmetros por referencia es la creacin de funciones que pueden modificar las variables pasadas a ellas por una funcin llamada.
Ago-Dic 2010 Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez 93

#include <iostream> #include <cstdlib> using namespace std; void increment(int& x) { x++; // Increment x by 1 } int main(int argc, char* argv[]) {

int y = 10; increment(y);


// Variable y is changed. cout << y << endl; return EXIT_SUCCESS; }
Listado 3 Paso de parmetros por referencia

El parmetro x se declara como parmetro de referencia usando la sintaxis int& x. No confunda este uso del signo "&" con el operador address-of. Aqu el signo "&" seala al compilador que este parmetro debe ser pasado por referencia.

Ago-Dic 2010

Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

94

El

paso de un parmetro por referencia tambin se utiliza como mecanismo para pasar objetos grandes a las funciones. Cuando los objetos son grandes, el paso por valor puede dar lugar a operaciones que consumen demasiado tiempo al sacar copias. El paso por referencia es ms eficiente porque no implica el sacar copias. Incluso cuando una funcin no intenta modificar uno de sus parmetros, se debe usar el paso por referencia cuando el parmetro es un objeto grande. Debemos declarar como constantes los parmetros pasados por referencia que una funcin no debe modificar. Esto es una buena prctica puesto que proporciona proteccin contra modificaciones accidentales.
Ago-Dic 2010 Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez 95

#include <iostream> #include <string> #include <cstdlib> using namespace std;

void display_letters(const string& data) {


for (int i = 0; i < data.length(); i++) { cout << data[i] << "\n"; } } int main(int argc, char* argv[]) {

string s = "This is a demonstration"; display_letters(s);


return EXIT_SUCCESS; } Listado 4 Una referencia constante
Ago-Dic 2010 Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez 96

A veces es til pasar un apuntador por referencia. Esto se hace cuando una funcin necesita cambiar la posicin almacenada de memoria del apuntador. Es decir se pasa un apuntador a una funcin por referencia cuando la funcin necesita reposicionar el apuntador.

Ago-Dic 2010 Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez 97

#include <iostream>
#include <cstdlib> using namespace std; void find_first_greater_than(int*& ptr, int threshold) { while (*ptr <= threshold) { ptr++; } } int main(int argc, char* argv[]) { int exam_scores[] = {74, 94, 64, 77, 68, 99, 58, 89, 74, 88, 100, 95, 71, 81, 89, 54, 76, 83, 88, 67}; int* score = &exam_scores[0]; cout << *score << endl; find_first_greater_than(score, 98); cout << *score << endl; return EXIT_SUCCESS; }
Ago-Dic 2010 Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez 98

Listado 5 Paso de un apuntador por referencia

class Person { private: string name; int age; public: Person() : name(""), age(0) {} void set_age(int age) {this->age = age;} int get_age() { return age;} void set_name(string name) {this->name = name;} string get_name() { return name;} char &replace_letter(int i) { return name[i]; } };

Listado 6 Regreso por referencia

Person person; person.set_name("John Doe"); person.set_age(30); person.replace_letter(1) = 'a'; person.replace_letter(2) = 'n'; person.replace_letter(3) = 'e'; cout << person.get_name() << endl;

El paso de parmetros por valor, por default, es un mecanismo usado en C++ para regresar valores de las funciones. Es til, tambin, regresar por referencia para permitir que la funcin llamada modifique algunas variables almacenadas. El Listado 6 muestra cmo regresar por referencia. Este listado aade la funcin replace_letter a la clase Person.

Listado 7 Uso de una funcin de regreso por referencia

Ago-Dic 2010

Algoritmos y Estructura de Datos Dr. Arturo Gonzlez Gutirrez

99

También podría gustarte