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

en C++ para Ciencia e Ingeniera, por M.Storti, L.

Dalcn, Rodrigo Paz


Programacion

en C++ para Ciencia e


Programacion
Ingeniera
Mario Storti, Lisandro Dalcn, Rodrigo Paz

http://www.cimec.org.ar/prog
Facultad de Ingeniera y Ciencias Hdricas
Universidad Nacional del Litoral http://www.unl.edu.ar
de Metodos

Centro de Investigacion
Computacionales - CIMEC
INTEC, (CONICET-UNL), http://www.cimec.org.ar

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 1

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Autores
Mario Storti <mario.storti@gmail.>
Lisandro Dalcn, <dalcinl@gmail.com>
Rodrigo Paz, <rodrigo.r.paz@gmail.com>

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 2

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Contents

slide 11.....Elementos basicos


de programacion
vs. interpretes

. slide 12.....Compilacion

. slide 13.....El proceso de compilacion


. slide 15.....El preprocesador CPP
. slide 18.....Chequeo de tipos
por separado
. slide 19.....Compilacion
. slide 21.....Declaraciones y definiciones
. slide 23.....Definiciones y declaraciones de variables
. slide 25.....Incluyendo headers
. slide 28.....Usando libreras
. slide 29.....Formato de include para C++
. slide 30.....Un primer programa en C++
. slide 31.....Namespaces
. slide 34.....Estructura de un programa
. slide 36.....Hello world
de arreglos de caracters
. slide 37.....Concatenacion
. slide 38.....Entrada de datos
. slide 39.....Llamando a otros programas
Facultad de Ingeniera y Ciencias Hdricas FICH - UNL
((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 3

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

.
.
.
.
.

slide 40.....Strings de C
slide 41.....Strings de C++
slide 43.....Escribir y leer de archivos
slide 45.....La clase vector
slide 48.....Ejercicios
slide 49.....El C en C++
. slide 50.....Funciones
. slide 51.....Valores de retorno

. slide 53.....Usando la librera estandar


de C
True and False
. slide 54.....Control de ejecucion.
. slide 56.....If-else
. slide 60.....while
. slide 63.....do-while
. slide 64.....Lazo for
. slide 66.....Break and continue
. slide 67.....La sentencia switch
. slide 69.....goto
. slide 71.....Recursion
. slide 73.....Operadores
. slide 74.....Operadores de auto incremento
. slide 76.....Tipos de datos

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 4

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

slide 79.....Especificadores
slide 82.....Punteros
slide 92.....Referencias
slide 95.....Punteros a void
slide 97.....Scope de las variables
slide 99.....Definiendo variables on-the-fly
slide 103.....Variables locales
slide 107.....Punteros a variables locales

slide 108.....Variables estaticas


slide 110.....Constantes

slide 111.....Operadores. Asignacion

slide 112.....Operadores matematicos


slide 113.....Operadores relacionales

slide 114.....Operadores logicos


slide 115.....El operador hook
slide 116.....Errores comunes con los operadores
slide 117.....Operadores de cast
slide 118.....Operador sizeof
slide 119.....typedef: Aliases de tipos
slide 120.....Estructuras
slide 124.....Arrow operator

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 5

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

.
.
.
.
.
.

slide 125.....Enums
slide 128.....Arreglos de estructuras
slide 129.....Punteros y arreglos
slide 131.....Arreglos de punteros

slide 135.....Aritmetica
de punteros

slide 137.....Tamanos
de estructuras
Orientada a Objetos
slide 138.....Programacion
de datos
. slide 139.....Abstraccion

. slide 149.....POO basica


. slide 159.....Inclusion de headers
. slide 163.....Estructuras enlazadas
sobre scoping
. slide 171.....Mas
. slide 172.....Tipos Abstractos de Datos (ADT)

. slide 173.....Ocultando la implementacion


. slide 175.....Control de acceso a los miembros
. slide 179.....Amistad (Friendship)
. slide 182.....Anidamiento (nesting) y amistad
. slide 183.....Object layout
. slide 184.....Clases

. slide 188.....Ocultando totalmente la implementacion


y cleanup
. slide 190.....Inicializacion

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 6

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

.
.
.
.
.
.
.
.
.
.
.
.
.
.

slide 192.....El constructor


slide 193.....El destructor
del bloque de definicion

slide 196.....Eliminacion
slide 198.....Clase stash con ctor/dtor
slide 202.....Stack con ctor/dtor
de agregados
slide 205.....Initializacion
de estructuras
slide 206.....Inicializacion
slide 207.....Sobrecarga de funciones
slide 211.....Argumentos por default
slide 212.....Constantes
slide 215.....Punteros a arreglos constantes de caracteres
slide 216.....Const en argumentos de funciones
slide 217.....Const en clases
slide 218.....Objetos const y funciones de la clase
slide 220.....Chapter 5
. slide 221.....Funciones inline
. slide 225.....Especificaciones de linkedicion
. slide 227.....Referencias en C++
. slide 233.....Reglas para las referencias
. slide 235.....Paso por referencia y por copia
. slide 236.....El constructor por copia

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 7

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

. slide 237.....Sobrecarga de operadores


. slide 242.....Sobrecarga de operadores unarios
. slide 250.....Sobrecarga de operadores binarios

slide 272.....Chapter
. slide 273.....Otros operadores que se pueden sobrecargar
dinamica

. slide 274.....Creacion
de objetos

. slide 275.....Uso de la memoria dinamica


en C

en C++
. slide 276.....Uso de la memoria dinamica
. slide 278.....Porque usar new y no arreglos
. slide 279.....Memory exhaust

. slide 280.....Composicion
y la cadena de inicializacion

. slide 282.....Composicion
. slide 283.....Herencia
de metodos

. slide 286.....Redefinicion
. slide 288.....Herencia protegida
. slide 290.....Upcasting
. slide 291.....Polimorfismo
. slide 293.....Ejemplo polimorfismo. Integral 1D/2D/3D
. slide 297.....Clase que calcula integral 1D
cruda
. slide 299.....Integral 2D. Version
mejorada
. slide 314.....Integral 2D. Version
Facultad de Ingeniera y Ciencias Hdricas FICH - UNL
((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 8

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

.
.
.
.

slide 317.....Integral 3D
slide 320.....Integral 1D/2D/3D. User code
slide 322.....Polimorfismo: ej. suma de los elementos de un vector
slide ??.....Ejemplo clase vector sparse
slide 325.....Contenedores de la librera STL
. slide 327.....La librera STL
. slide 327.....La clase vector
. slide 332.....La clase list
. slide 335.....La clase set
. slide 339.....La clase map
. slide 341.....Algoritmos

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 9

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Dictado

Docentes de la catedra:
. Mario Storti <mario.storti@gmail.>
. Lisandro Dalcn, <dalcinl@gmail.com>
. Rodrigo Paz, <rodrigo.r.paz@gmail.com>

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 10

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Elementos basicos
de

programacion

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 11

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

vs. interpretes

Compilacion
tienen un interprete,

Algunos lenguajes de programacion


por ejemplo

Matlab/Octave, Python, Perl, Lisp/Scheme. En un interprete


el usuario va

emitiendo comandos que son interpretados por el interprete


y va
devolviendo un resultado.
los lenguajes compilados el usuario escribe un
Por contraposicion,

es procesado por un compilador, que


archivo con lneas de codigo,
el cual

genera codigo
de maquina,
el cual es ejecutado directamente por el
procesador.
el codigo

rapido,

Ventajas de la compilacion:
suele ser mas
y mas
compacto.

Desventajas: el paso de codigo


a ejecutarlo es inmediato, no hay pasos

intermedios. Usualmente los interpretes


permiten escribir tareas que se
repiten comunmente

en archivos de texto (scripts). El usuario puede


mezclar estas funciones con comandos directamente en el
ademas

con los interprete

facil

interprete.
Tambien
es mas
debuggear.
C++ es un lenguaje compilado.

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 12

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

El proceso de compilacion
simple es cuando todo el codigo

El caso mas
del programa esta en un
archivo fuente:
solo

$$ g++ -o prog prog.cpp

Genera un archivo ejecutable prog.


Si el programa es muy grande conviene dividirlo en varias partes, en ese
caso

$$ g++ -o prog prog1.cpp prog2.cpp


Esto requiere recompilar cada vez todos los *.cpp, si son muchos

conviene hacer

1
2
3

$$ g++ -o prog1.o -c prog1.cpp


$$ g++ -o prog2.o -c prog2.cpp
$$ g++ -o prog prog1.o prog2.o

Los archivos .o son objeto, contienen codigo


de maquina.
(No tiene
con la Programacion
Orientada a Objetos).
relacion

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 13

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

(cont.)
El proceso de compilacion
hace
Si solo se modifica uno de los archivos (prog1.cpp), entonces solo
falta recompilar ese.

$$ g++ -o prog1.o -c prog1.cpp


2 $$ g++ -o prog prog1.o prog2.o
si hay muchos *.o conviene ponerlos en una
Para mejor organizacion,
1

librera

$$ g++ -o prog1.o -c prog1.cpp


2 $$ g++ -o prog2.o -c prog2.cpp
3 $$ g++ -o prog3.o -c prog3.cpp
4 $$ ar r libprog.a prog1.o prog2.o prog3.o
5 $$ g++ -o prog main.cpp libprog.a
A veces la librera puede ser que haya sido desarrollada por un tercero:
1

libpetsc.a, libmkl.a.

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 14

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

El preprocesador CPP

Muchas veces hay texto que se repite muchas veces en el codigo.


En ese
caso se pueden usar macros
1
2
3
4

int v[100000];
if (n<100000) {
....
}
Se puede simplificar de la siguiente forma

1
2
3
4
5

#define MAX 100000


int v[MAX];
if (n<MAX) {
....
}
Estos macros son manejados por el preprocesador, el cual se llama
normalmente cpp (por C preprocesor). Podemos pensar que el CPP
genera un paso intermedio en el cual toma el archivo prog.cpp y genera
un archivo intermedio tempo.cpp que es el que finalmente es compilado.

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 15

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

El preprocesador CPP (cont.)


realiza manipulaciones a nivel de texto, no conoce nada
CPP solo

especfico del lenguaje C/C++, incluso puede usarse (y se usa) para otros
lenguajes como Fortran.
usuales son
Las directivas mas

1 // Incluye todo el texto del archivo library.h


2 #include <library.h>
3
4 #define CHECK(a,n) if (a>n) error()
Para #include el preprocesador simplemente incluye todo el archivo

mencionado en el punto donde se invoca el include.


se puede llamar al macro en otros
#define define un macro, despues

lugares del codigo


y es reemplazado por su expansi
on. Los macros
se suele dar a los macros
pueden tener argumentos. Por convencion
nombres en mayusculas.

Se puede conocer cual es el resultado del CPP llamando a g++ con la


-E
opcion

$$ g++ -o tempo.cpp -E prog.cpp


El CPP es un programa separado que se puede llamar por s mismo

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 16

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

(/usr/bin/cpp).

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 17

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Chequeo de tipos

typed language),
C++ es un lenguaje tipado (aka tipeo estatico,
en ingles
es decir las variables tienen tipos definidos. El compilador chequea que
los resultados de las expresiones que se asignan a las variables
correspondan al tipo con el cual fueron definidas, caso contrario se
produce un error en tiempo de compilaci
on. Esto es bueno porque
permite detectar tempranamente errores. (Es equivalente al chequeo de
unidades en Fsica).

// error: asigna un string a una variable entera


2 int a;
3 a = "Hello";

Otros lenguajes (sobre todos los interpretados) hacen chequeo dinamico


1

de tipo, esto implica una perdida


de eficiencia.
para los argumentos de una funcion

El chequeo se hace tambien

1 void fun(int a,string s);


2 . . .
3 fun(23,45); // ERROR (45 no es un string!)

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 18

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

por separado
Compilacion
En C++ se favorece que un programa grande se pueda dividir en

pequenas.

fracciones mas
El mecanismo fundamental para dividir un
pequenas

programa en partes mas


es usar funciones que realizan tareas
int
bien definidas. Por ejemplo podemos pensar en una funcion

gcd(int,int); que toma dos enteros y retorna el maximo


comun
divisor
de los mismos.
termina su
Las funciones tienen argumentos, una vez que la funcion
puede ser que las funciones tengan
tarea, retorna un valor. Tambien
efectos colaterales (side effects) es decir que modifiquen sus
argumentos u otros objetos.

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 19

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

por separado (cont.)


Compilacion

Para crear un programa que este dividido en varios archivos, el codigo


de
un archivo debe poder usar las funciones del otro. Supongamos que un
gcd(). Si queremos usar a gcd()
archivo prog1.cpp contiene a la funcion

en el codigo
de otro archivo prog2.cpp entonces el compilador debe estar
seguro que el tipo de los argumentos que se le van a pasar son los
en prog2.cpp antes de
correctos. Para eso hay que declarar a la funcion
poder llamarla
1
2
3
4

int gcd(int,int); // declara gcd()


...
r = gcd(m,n); // la puede usar porque ya
// fue declarada

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 20

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Declaraciones y definiciones
le dice al compilador que esa funcion
existe y su
Una declaracion
prototipo o signatura, es decir el tipo de argumentos de entrada y de
salida. Por ejemplo

int gcd(int,int);
por otra parte dice especficamente como la funcion
realiza
La definicion

su tarea

1
2
3
4
5
6
7
8
9
10
11

int gcd(int x, int y) {


int a = x, b = y;
if (b>a) {
a = y; b = x;
}
while (true) {
int c = a % b;
if (c==0) return b;
a = b; b = c;
}
}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 21

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Declaraciones y definiciones (cont.)


puede estar declarada varias veces en un archivo (mientras
Cada funcion
sea la misma en cada una de las declaraciones).
la signatura de la funcion

int f(int x);


...
3 int f(int); // OK, misma signatura
solo
puede estar definida una sola vez en todos
Por el contrario, la funcion
1
2

los archivos del programa, ya que si no el compilador no sabra cual usar.


1
2
3
4
5
6

// archivo prog1.cpp
int f(int x) { return 2*x; }
// archivo prog2.cpp
int f(int) { return 3*x; }
// -> ERROR: m
ultiplemente definida

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 22

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Definiciones y declaraciones de variables


Si declaramos una variable, por ejemplo
1

int m;

en realidad ya tiene toda la informacion


para
si bien parace una declaracion,
construir al objeto (un entero de 4 bytes) por lo tanto el compilador lo toma
como una definicion.
Por eso no podemos incluir dos veces esta
ademas

aunque sea del mismo tipo.


declaracion/definici
on,
1
2
3

int m;
...
int m; // ERROR

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 23

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Definiciones y declaraciones de variables (cont.)


y no una definicion

Si queremos forzar a que sea una declaracion


entonces debemos usar el keyword extern

extern int m;
...
3 extern int m; // OK
4 . . .
5 int m; // OK
con las funciones, para hacer hincapie en
extern se puede usar tambien
1
2

por ejemplo
que es una declaracion,
1

extern int f(int x);


pero no es necesario.

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 24

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Incluyendo headers
Es usual que en nuestros programas escribamos una serie de funciones
utilizaremos en otras partes del programa.
que despues

// utils.cpp
2 int gcd(int m,int n) { /* . . . */ }
3 double cos(double alpha) { /* . . . */ }
4 double sin(double alpha) { /* . . . */ }
5 . . .
Cuando queremos usar estas funciones en otro archivo fuente prog.cpp
1

primero tenemos que declararlas


1
2
3
4
5
6
7
8
9

// prog.cpp
int gcd(int m,int n);
double cos(double alpha);
double sin(double alpha);
...
int x = gcd(m,n);
double c = cos(alpha);
double s = sin(theta);
...
Esto se vuelve muy engorroso si hay que incluir las declaraciones en cada

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 25

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

uno de los archivos prog1.cpp, prog2.cpp... y utils.cpp tiene cientos de


funciones. Entonces para resolver esto incluimos todas las declaraciones
en un archivo header (cabecera) utils.h:
1
2
3
4

// utils.h
int gcd(int m,int n);
double cos(double alpha);
double sin(double alpha);
en prog1.cpp hay que solo incluir el header:
Entonces despues

1
2
3
4
5
6
7

// prog1.cpp
#include "utils.h"
...
int x = gcd(m,n);
double c = cos(alpha);
double s = sin(theta);
...
Recordemos que lo que ocurre es que el preprocesador CPP se encarga
de buscar el archivo header y crear un archivo temporario donde la linea
del include es reemplazada por los contenidos del archivo.

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 26

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Incluyendo headers (cont.)


Hay dos versiones de include,

Una que especifica archivos en forma relativa o absoluta


1 #include ". ./utils.h"
2 #include "utils2.h"
3 #include "/usr/include/utils3.h"
4 . . .
Otra que busca los headers en una serie de directorios que el usuario

define en el comando de compilacion


1

1
2
3
4
5

$$ g++ -I/home/mstorti/utils -c -o prog.o prog.cpp


// lo encuentra en /home/mstorti/utils
#include <utils4.h>
// lo encuentra en /home/mstorti/utils/src
#include <src/utils5.h>
...

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 27

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Usando libreras
Entonces si tengo que usar una librera matrix que esta compuesta de
varios archivos fuente matrix2.cpp, matrix1.cpp, matrix3.cpp... en realidad
no hace falta que compile todos estos archivos, mientras que el
desarrollador de esa librera provea
. Un archivo libmatrix.a con todos los matrix<n>.cpp compilados.
. Un archivo header con las declaraciones de las funciones matrix.h.
Entonces para usar la librera basta con incluir el header

1 // myprog.cpp
2 #include <matrix.h>
3 . . .

y al linkeditar incluir la librera


1

$$ g++ myprog.cpp /usr/lib/libmatrix.a -o myprog

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 28

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Formato de include para C++


que se usa para los archivos fuente puede ser .cpp, .cxx.
La extension

Para los headers se utiliza .h, .hpp, .hxx.


Para evitar confusiones y ambiguedad

con las extensiones, C++ introdujo


El traductor se encarga de convertir
el concepto de include sin extension.

el nombre y buscar la extension.

#include <matrix>

Existe una librera con muchas funciones muy utiles

que es estandar
de C

y se llama justamente libc.a. Entre otras incluye funciones

. Matematicas
math.h: round, cos, sin, floor, ceil, ...
. Input/output stdio.h: printf, scanf, read, write,
. stdlib.h: rand, system, ...
En C++ estos headers es mejor incluirlos sin el .h y con una c:

1
2

#include <stdio.h> // C
#include <cstdio> // C++

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 29

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Un primer programa en C++


Para imprimir por terminal hay que usar el operador << de la clase
iostream:

1
2
3

#include <iostream>
...
cout << "Hola";
El operador << en C quiere decir en realidad otra cosa: es para desplazar
los bits en un numero

entero. Pero C++ permite redefinir los operadores


(lo que se llama sobrecarga de operadores) de manera que en este
contexto << quiere decir enviar a.

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 30

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Namespaces
funciones
A medida que una librera o programa crecen cada vez hay mas

de nombres. Por ejemplo, si


y es muy posible que se produzca la colision
escribo una librera para manipular matrices, puedo querer implementar
rand() que llena la matriz con numeros
una funcion

aleatorios.
Lamentablemente la libc ya usa el nombre rand() para generar un unico

numero aleatorio.
que se usaba en C era prependizar un prefijo identificador
Una solucion
de la librera a todas las funciones de la misma matrix_rand(),
matrix_sum(), matrix_prod(). Esto se vuelve muy engorroso.

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 31

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Namespaces (cont.)
C++ provee un mecanismo para evitar colisiones llamado namespaces.
Todos los archivos de la librera se incluyen en un namespace de la
siguiente forma

// matrix.cpp
2 namespace matrix {
3
void rand(. . .) { /* . . . */ }
4
double sum(. . .) { /* . . . */ }
5
void prod(. . .) { /* . . . */ }
6 }
las funciones se deben llamar con el operador de
Entonces despues
1

1
2
3
4
5

scope ::: por ejemplo matrix::rand().


Si en un archivo fuente se va a utilizar mucho una librera entonces puede
incluir todo el namespace, de manera que no hay que hacer el scope

// prog.cpp
using namespace matrix;
rand(A);
double m = max(A);

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 32

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Namespaces (cont.)

en
Muchas utilidades y variables estandar
de C++, por ejemplo cout, estan
el namespace std de manera que o bien hay que hacer

std::cout << "Hola";


o si no

1
2
3

using namespace std;


...
cout << "Hola";

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 33

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Estructura de un programa
de funciones y
Un programa en C/C++ esta compuesto de una coleccion

variables. Cuando uno lanza el programa hay que determinar donde


se

empieza a ejecutar el codigo,


o sea el punto de entrada. En C/C++ el punto
main().
de entrada es la funcion
de una funcion
consiste en un valor de retorno, el nombre
La definicion
y su lista de argumentos. El cuerpo de la funcion
(las
de la funcion
instrucciones que la componen) van entre llaves.

int function() {
2
// Function code here (this is a comment)
3 }
pares de llaves balanceadas ({}) adentro de la funcion

Puede haber mas


1

externo que define el cuerpo de la funcion.

pero debe haber uno mas


debe respetar estos requisitos. main() no
Como main() es una funcion,
tiene argumentos y retorna un int.

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 34

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Estructura de un programa (cont.)


o la
C/C++ es un lenguaje de formato libre (free form), la indentacion

1
2
3

de las variables en la lnea son irrelevantes.


posicion
Tampoco es relevante la cantidad espacio en blanco (espacios, tabs, fin
de lnea). Cualquier cantidad de estos caracteres juntos es equivalente a
un solo espacio. De hecho un programa en C++ podra escribirse ne una
sola lnea.
En C los comentarios van encerrados entre /* y */ (comentario multilnea).
En C++ se agrego un nuevo tipo de comentario que es por lnea desde un
// hasta el final de la lnea. (Esto viola un poco el concepto de free form).

/* Comentario multilinea tipo C */


int /* comentario en el medio del c
odigo */ x;
// Comentario por linea tipo C++

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 35

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Hello world
1
2
3
4
5
6
7
8

// Saying Hello with C++


#include <iostream> // Stream declarations
using namespace std;
int main() {
cout << "Hello, World. I am "
<< 8 << " Today" << endl;
}

Le pasamos a cout una serie de elementos de diferentes tipos: enteros,

arreglos de caracteres.
endl es un final de lnea.
En C se llama string a un pedazo de texto entre comillas. No confundir
con la clase string de C++ que cumple funciones similares pero es mucho
potente. A los strings de C se los debe llamar mas
correctamente
mas
arreglos de caracteres.
Dentro del texto entre comillas se pueden incluir secuencias de escape
que permiten incluir caracteres especiales con precedidos de una barra
invertida: \n es un caracter de fin de lnea, \t un TAB, \0 un NULL, \\ una
barra invertida.

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 36

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

de arreglos de caracters
Concatenacion
Para incluir arreglos de caracteres muy largos se puede simplemente
de otro (puede ser en diferentes lneas). El CPP
poner uno a continuacion
se encarga de juntarlos todos en una sola lnea: "aaa" "bbbb" es
completamente equivalente a "aaabbbb".
1
2
3
4
5
6
7
8
9
10
11

// Character array Concatenation


#include <iostream>
using namespace std;
int main() {
cout << "This is far too long to put on a "
"single line but it can be broken up with "
"no ill effects\nas long as there is no "
"punctuation separating adjacent character "
"arrays.\n";
}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 37

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Entrada de datos
cout es console output, cin es console input y permite ingresar datos.
1
2
3
4
5
6
7
8
9
10
11
12
13

// Converts decimal to octal and hex


#include <iostream>
using namespace std;
int main() {
int number;
cout << "Enter a decimal number: ";
cin >> number;
cout << "value in octal = 0"
<< oct << number << endl;
cout << "value in hex = 0x"
<< hex << number << endl;
}

oct y hex son manipulators, cambian el estado de cout.

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 38

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Llamando a otros programas

muy potente system() que


Dentro de la librera estandar
de C hay una funcion
permite llamar a otros programas desde un programa en C/C++. Se le pasa un
arreglo de caracteres con el comando que uno ejecutara en la lnea de
comandos.
1
2
3
4
5
6
7

// Call another program


#include <cstdlib> // Declare system()
using namespace std;
int main() {
system("date -u");
}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 39

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Strings de C
Manipular arreglos de caracteres en C se vuelve muy engorroso.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

#include <iostream>
#include <cstring>
using namespace std;
int main() {
// concatenate two character arrays s1 and s2
char s1[ ] = "Hola ";
char s2[ ] = "mundo.";
cout << strlen(s1) << endl;
int n1 = strlen(s1);
int n2 = strlen(s2);
char *s = new char[n1+n2+1];
strncpy(s,s1,n1);
strncpy(s+n1,s2,n2);
s[n1+n2] = \0;
cout << s << endl;
delete[ ] s;
return 0;
}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 40

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Strings de C++
Para eso C++ tiene objetos llamados strings que permiten manipularlos en
simple y con menor probabilidad de error.
forma mucho mas
1
2
3
4
5
6
7
8
9
10
11
12

#include <iostream>
#include <cstring>
using namespace std;
int main() {
// concatenate two character arrays s1 and s2
string s1 = "Hola ";
string s2 = "mundo.";
string s = s1 + s2;
cout << s << endl;
return 0;
}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 41

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Strings de C++ (cont.)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

//: C02:HelloStrings.cpp
// The basics of the Standard C++ string class
#include <string>
#include <iostream>
using namespace std;
int main() {
string s1, s2; // Empty strings
string s3 = "Hello, World."; // Initialized
string s4("I am"); // Also initialized
s2 = "Today"; // Assigning to a string
s1 = s3 + " " + s4; // Combining strings
s1 += " 8 "; // Appending to a string
cout << s1 + s2 + "." << endl;
}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 42

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Escribir y leer de archivos

1
2
3
4
5
6
7
8
9
10
11

declaradas en el header <fstream>.


Las funciones estan
Para escritura hay que crear un objeto de tipo ofstream (como cout).
Para lectura hay que crear un objeto de tipo ifstream (como cin).
getline(stream,s) lee una lnea de stream y la guarda en el
La funcion
string s

// Copy one file to another, a line at a time


#include <string>
#include <fstream>
using namespace std;
int main() {
ifstream in("Scopy.cpp"); // Open for reading
ofstream out("Scopy2.cpp"); // Open for writing
string s;
while(getline(in, s)) // Discards newline char
out << s << "\n"; // . . . must add it back
}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 43

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Escribir y leer de archivos (cont.)


string:
Otro ejemplo es guardar todo el archivo en un solo
1
2
3
4
5
6
7
8
9
10
11
12
13

// Read an entire file into a single string


#include <string>
#include <iostream>
#include <fstream>
using namespace std;
int main() {
ifstream in("FillString.cpp");
string s, line;
while(getline(in, line))
s += line + "\n";
cout << s;
}

Que pasa si queremos guardar cada lnea en un string separado?

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 44

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

La clase vector
Un vector es un contenedor que permite guardar un numero

indefinido de

elementos en forma contigua e indexada.

Se puede agrandar o achicar en forma dinamica,


sin perder los elementos
preexistentes.
Esta templatizado o sea que se pueden definir vectores de diferentes
tipos: vector<int>, vector<double>, vector<string>,...
push_back() permite agregar un nuevo objeto al final del vector.
La funcion

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 45

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

La clase vector (cont.)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

// Copy an entire file into a vector of string


#include <string>
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
int main() {
vector<string> v;
ifstream in("Fillvector.cpp");
string line;
while(getline(in, line))
v.push-back(line); // Add the line to the end
// Add line numbers:
for(int i = 0; i < v.size(); i++)
cout << i << ": " << v[i] << endl;
}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 46

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

La clase vector (cont.)


puede guardar cualquier otro tipo, por ejemplo enteros:
vector tambien
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

// Creating a vector that holds integers


#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> v;
for(int i = 0; i < 10; i++)
v.push-back(i);
for(int i = 0; i < v.size(); i++)
cout << v[i] << ", ";
cout << endl;
for(int i = 0; i < v.size(); i++)
v[i] = v[i] * 10; // Assignment
for(int i = 0; i < v.size(); i++)
cout << v[i] << ", ";
cout << endl;
}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 47

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Ejercicios
1. Crear un programa que abre un archivo y cuenta las palabras (separadas
por whitespace). Ayuda: el operador << lee de a palabras de un ifstream.
2. Crear un programa que cuenta la cantidad de caracteres que tiene un
archivo.
3. Crear un programa que cuenta la cantidad de ocurrencias de una palabra
especfica en un archivo. Ayuda: usar == para comparar strings.
4. Escribir un programa que imprime las lneas de un archivo de texto en
orden inverso.

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 48

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

El C en C++

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 49

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Funciones
Para evitar errores, C/C++ usa el concepto de prototipo o signatura de

funciones.
hay que declararla.
Antes de usar una funcion
los argumentos con que es llamada deben coincidir con
Al usar la funcion
el el tipo que fueron declarados.

int translate(float x, float y, float z);


2 int translate(float, float, float);
tiene que estar definida, aqu los nombres de los
En algun
lugar la funcion
1

argumentos tienen que aparecer para poder ser usados en la funcion


1
2
3
4

int translate(float x, float y, float z) {


x = y = z;
// . . .
}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 50

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Valores de retorno
de la funcion
debe indicar el valor de retorno. Si la funcion

La declaracion
no retorna nada usar void:

int f1(void); // Returns an int, takes no arguments


2 int f2(); // Like f1() in C++ but not in Standard C
3 float f3(float, int, char, double); // Returns a float
4 void f4(void); // Takes no arguments, returns nothing
Para retornar el valor usar la sentencia return.
retorna void entonces no se debe llamar a return.
Si la funcion
de un return en la funcion.
Son puntos de salida.
Se puede tener mas

El valor de retorno debe ser compatible con el indicado en la declaracion.


1

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 51

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Valores de retorno (cont.)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

// Use of return
#include <iostream>
using namespace std;
char cfunc(int i) {
if(i == 0)
return a;
if(i == 1)
return g;
if(i == 5)
return z;
return c;
}
int main() {
cout << "type an integer: ";
int val;
cin >> val;
cout << cfunc(val) << endl;
} ///:

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 52

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Usando la librera estandar


de C

llamada libc). Todos


C incluye una librera de funciones estandar
(tambien

los compiladores que satisfacen la norma deben incluir estas funciones


en su libc. Esto permite la portabilidad de los programas entre diferentes
compiladores.
en la
Muchos compiladores incluyen funciones adicionales que NO estan
norma. Por lo tanto hay que prever que si se lleva el proyecto a otra
plataforma puede ser que estas funciones no existan en esa plataforma.
de las libreras usualmente incluye la declaracion
de la
La documentacion
y en que header (archivo .h) esta.

funcion
En caso que la librera no este documentada hay que directamente ver los

headers para encontrarel prototipo de la funcion.

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 53

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

True and False


Control de ejecucion.

Todas los condicionales (por ejemplo if o while) usan expresiones logicas

1
2
3
4
5
6

A==B. Esta
como por ejemplo el resultado del operador de comparacion
retorna directamente un valor logico

expresion
true o false. No confundiir
A=B.
con el operador de asignacion

Lo mismo ocurre con otros operadores de comparacion

A==B; //Its equal?


A!=B; //Its distinct?
A<B; //Its smaller?
A<=B; //Its smaller or equal?
A>B; //Its greater?
A>=B; //Its greater or equal?

no retorna un valor booleano, entonces C trata de convertirlo.


Si la expresion

Para todos los valores numericos


(enteros, float, double, char, punteros) el
valor es falso si es cero, y en cualquier otra caso es verdadero. Entonces por

ejemplo el valor logico


de las siguientes expresiones es equivalente
1
2

if (n) { . . . }
if (n!=0) { . . . . }

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 54

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

if (!(n==0)) { . . . . } // ! is negation

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 55

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

If-else
El if puede existir de dos formas, con o sin else
1
2
3
4
5
6
7
8
9

if (expression)
statement
// o
if (expression)
statement
else
statement

En ambos casos statement puede ser una sentencia simple, terminada en una
coma, o compuesta, es decir un bloque de instrucciones encerrado en {}.
1
2
3
4
5
6

if (n>0) x=23; // sentencia simple


if (n>0) { // sentencia compuesta
x=23;
s="haha";
}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 56

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

If-else (cont.)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

int i;
cout << "type a number and Enter" << endl;
cin >> i;
if(i > 5)
cout << "Its greater than 5" << endl;
else
if(i < 5)
cout << "Its less than 5 " << endl;
else
cout << "Its equal to 5 " << endl;
cout << "type a number and Enter" << endl;
cin >> i;
if(i < 10)
if(i > 5) // if is just another statement
cout << "5 < i < 10" << endl;
else
cout << "i <= 5" << endl;
else // Matches if(i < 10)
cout << "i >= 10" << endl;

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 57

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

If-else (cont.)
por eso no hace falta
Notar que todo el if actua
como una sola instruccion,
encerrarlo con un {}.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

if(i > 5)
cout << "Its greater than 5" << endl;
else
if(i < 5)
cout << "Its less than 5 " << endl;
else
cout << "Its equal to 5 " << endl;
// es equivalente a
if(i > 5) { cout << "Its greater than 5" << endl; }
else {
if(i < 5)
cout << "Its less than 5 " << endl;
else
cout << "Its equal to 5 " << endl;
}

mut util
Es una convencion
indentar ambos bloques del if para mejorar la
Facultad de Ingeniera y Ciencias Hdricas FICH - UNL
((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 58

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

legibilidad.

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 59

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

while

while, do-while y for controlan lazos (loops) de ejecucion.


1
2

while(expression)
statement

se evalua
Como antes statement puede ser simple o compuesto. La expresion

de falso. Para que el lazo termine en algun


momento
hasta que la condicion
es necesario que statement tenga algun
efecto que haga que eventualmente
expression de falso
1
2
3
4
5
6

int x=0;
while (x<5) x=2; // ejecuta una vez el lazo
while (x<5) x=34; // ejecuta indefinidamente
x=0;
while (x<5) x++; // ejecuta el bloque 5 veces

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 60

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

while (cont.)
1
2
3
4
5
6
7
8
9
10
11
12
13
14

// Guess a number (demonstrates while)


#include <iostream>1
using namespace std;
int main() {
int secret = 15;
int guess = 0;
// != is the not-equal conditional:
while(guess != secret) { // Compound statement
cout << "guess the number: ";
cin >> guess;
}
cout << "You guessed it!" << endl;
}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 61

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

while (cont.)
dentro del condicional puede ser tan elaborada como se
En C la condicion
es que debe retornar un valor logico

quiera, la unica

restriccion
(o convertible

a logico),
incluso puede ser que el cuerpo del lazo este vaco
1
2
3

while(/* Do a lot here */) ;


while() { }

por ejemplo
1

while(is-prime(n)) n++; // busca el primer n no primo

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 62

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

do-while
1
2
3

do

statement
while(expression);

Es similar al while pero ahora statement es ejecutado antes de verificar la

condicion.
1
2
3
4
5
6
7

n=0;
while (n>0) /* body. . .*/ ; // body is not executed
n=0;
do
/* body. . .*/ ; // body is executed once
while (n>0);

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 63

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Lazo for
La forma del for es
1
2

for(initialization; conditional; step)


statement

Se utiliza mucho cuando simplemente se quiere ejecutar un bloque una serie


de veces bien definida
1
2
3

for (int i=0; i<n; i++) {


// This block is executed n times
}

Esto es completamente equivalente a


1
2
3
4
5

int i=0;
while(i<n) {
// This block is executed n times
i++;
}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 64

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Lazo for (cont.)


del
continue es similar a break pero hace que se ejecute la siguiente iteracion
lazo
1
2
3
4
5

for (int j=0; j<n; j++) {


//. . . .
if (!is-prime(j)) continue;
// do this only for primes. . .
}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 65

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Break and continue


Adentro de cualquiera de los bloques while, do-while o for se puede usar
break para salir del lazo inmediatamente.
1
2
3
4
5
6

while (true) { // Infinite loop


cout << "Enter a number: ";
cin >> n;
if (is-prime(n)) break;
cout << n << " es un n
umero compuesto" << endl;
}

de un lazo anidado entonces break sale del lazo mas


interno
Si hay mas
1
2
3
4
5
6

for (int i=0; i<n; i++) {


for (int j=0; j<n; j++) {
if (j>i*i) break;
//. . .
}
}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 66

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

La sentencia switch
Va comparando la variable selector hasta que coincide con uno de los case
1
2
3
4
5
6
7
8
9

switch(selector) {
case integral-value1
case integral-value2
case integral-value3
case integral-value4
case integral-value5
(. . .)
default: statement;
}

:
:
:
:
:

statement;
statement;
statement;
statement;
statement;

break;
break;
break;
break;
break;

por ejemplo
1
2
3
4
5
6
7

char c;
//. . .
switch (c) {
case a: cout << "Its an a" << endl; break;
case b: cout << "Its a b" << endl; break;
default: cout << "Neither a or b" << endl;
}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 67

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

sigue al siguiente case.


Si no se incluyen los break entonces la ejecucion

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 68

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

goto
La sentencia goto permite saltar a otro punto del programa. Se lo considera

aunque a veces
muchas veces como una mala practica
de programacion,
puede ser util,

por ejemplo para saltar de varios lazos anidados cuando se

encuentra una condicion.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

// The infamous goto is supported in C++


#include <iostream>
using namespace std;
int main() {
long val = 0;
for(int i = 1; i < 1000; i++) {
for(int j = 1; j < 100; j += 10) {
val = i * j;
if(val > 47000)
goto bottom;
// Break would only go to the outer for
}
}
bottom: // A label
cout << val << endl;

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 69

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

17

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 70

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Recursion
de un
Muchos problemas son intrnsecamente recursivos, es decir la solucion
de uno menor con el mismo algoritmo,
problema esta dada por la solucion
de factorial se puede hacer en forma recursiva
por ejemplo la definicion

n! = n (n 1)!

(1)

en realidad esto es cierto si n

correcta es
> 1, la definicion

1;
si n = 1;
n! =
n (n 1)! ; si n > 1

decimos que el caso n

(2)

= 1 corta la recursion.

Usando llamadas recursivas a funciones podemos implementar la funcion


factorial
1
2
3
4

int factorial(int n) {
if (n==1) return 1;
else return n*factorial(n-1);
}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 71

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Recursion (cont.)
es muy elegante para resolver problemas, pero puede ser
La recursion

simple si calculamos el
demandante en terminos
de recursos. Es mas
factorial con un lazo
1
2
3
4
5

int factorial(int n) {
int fac=1;
for (int j=2; j<=n; j++) fac *= j;
return fac;
}

El operador *= quiere decir aqu


1

fac = fac*j;

Se puede aplicar a otros operadores binarios asociativos como +, operadores

de strings...
logicos,
concatenacion

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 72

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Operadores
que funciones, con una sintaxis especial. Un
Los operadores no son mas
series de valores y devuelve un resultado.
operador toma una o mas
1

a = b + c;

podemos pensar que es traducido por el compilador en


1

a = sum(b,c);

importante con los operadores es la precedencia de los


Una cuestion

mismos. Para los operadores matematicos


es similar a las reglas que
aprendemos en la escuela
1

a = b * c + d;

es equivalente a
1

a = (b * c) + d;

porque * tiene mayor precedencia que +. Ante la duda, se pueden introducir

parentesis
para forzar el orden en que se evaluan

las expresiones.

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 73

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Operadores de auto incremento


muy comun

El operador ++ es un atajo para una operacion


en programacion:
incrementar una variable de tipo entero en una unidad. Hay dos variantes,
prefija y postfija, ambos tienen el mismo efecto colateral (incrementar la
variable) pero en el prefijo retorna el valor de la variable incrementada, y el
postfijo sin incrementar
1
2
3
4
5

int m,n=5;
m = n++; // n=6, m=5
int m,n=5;
m = ++n; // n=6, m=6

retorna el primer primo siguiente (mayor o


Por ejemplo la siguiente funcion
igual) a n.
1
2
3
4

int next-prime(int n) {
while (!is-prime(n++)) { }
return n;
}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 74

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Operadores de auto incremento (cont.)


hay autodecremento -- prefijo y postfijo.
Tambien
1
2
3

1
2

int n=10;
while (n >= 0) cout << n-- << ", ";
cout << "Boom!!" << endl;
[mstorti@galileo garage]$$ ./boom.bin
10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, Boom!!

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 75

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Tipos de datos

Dijimos que C/C++ es un lenguaje de tipeo estatico,


es decir en el momento
de crear las variables hay que decir de que tipo son. Hay tipos de datos
definidos en el compilador,
built-in como enteros, floats, strings, que ya estan
el programador puede crear sus propios tipos, muchas veces por
y tambien
Por ejemplo si estamos creando la base de datos de una
composicion.
empresa podemos querer tener un tipo de dato employee que contenga un
string (el nombre), un entero (el numero

de empleado) y un float (el sueldo).


Los tipos built-in son

char un entero de al menos 8 bits, usualmente se usa para almacenar

caracteres.
int un entero de al menos 16 bits (2 bytes)

float un numero

de punto flotante con al menos 4 bytes (simple precision)


double un numero

de punto flotante con al menos 8 bytes (doble

precision).

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 76

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Tipos de datos (cont.)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

// Defining the four basic data


// types in C and C++
int main() {
// Definition without initialization:
char protein;
int carbohydrates;
float fiber;
double fat;
// Simultaneous definition & initialization:
char pizza = A, pop = Z;
int dongdings = 100, twinkles = 150,
heehos = 200;
float chocolate = 3.14159;
// Exponential notation:
double fudge-ripple = 6e-4;
}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 77

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Tipos de datos (cont.)

Como los tipos basicos


tienen una cantidad de bits fija pueden representar un
maximo.

pueden estar entre


tamano
Por ejemplo los enteros de 16 bits solo
el tamano
del tipo (la cantidad de bits) puede
-32768 y +32768. Ademas

depender de la maquina
y del compilador, entonce los valores maximos
y
definidos en headers float.h y limits.h,
mnimos (los lmites) estan
1
2
3
4
5
6

1
2
3

#include <climits>
cout << "Minimum and maximum integers are "
<< endl << INT-MIN << " and " << INT-MAX
<< endl;
}
[mstorti@galileo garage]$$ ./intmax.bin
Minimum and maximum integers are
-2147483648 and 2147483647

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 78

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Especificadores
Para representar enteros se utiliza un bit de los 32 disponibles para

representar el signo.
se van a utilizar enteros positivos entonces podemos usar ese bit
Si solo
para extender un factor 2 el rango.
int en el rango [-2147483648,2147483647]
unsigned int en el rango [0,4294967295]

unsigned es un specifier, otros son: signed, unsigned, short, long.

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 79

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Especificadores (cont.)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

//: C03:Specify.cpp
// Demonstrates the use of specifiers
#include <iostream>
using namespace std;
int main() {
char c;
unsigned char cu;
int i;
unsigned int iu;
short int is;
short iis; // Same as short int
unsigned short int isu;
unsigned short iisu;
long int il;
long iil; // Same as long int
unsigned long int ilu;
unsigned long iilu;
float f;
double d;
long double ld;

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 80

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

22
23
24
25
26
27
28
29
30
31
32
33
34
35

cout
<< "\n char= " << sizeof(c)
<< "\n unsigned char = " << sizeof(cu)
<< "\n int = " << sizeof(i)
<< "\n unsigned int = " << sizeof(iu)
<< "\n short = " << sizeof(is)
<< "\n unsigned short = " << sizeof(isu)
<< "\n long = " << sizeof(il)
<< "\n unsigned long = " << sizeof(ilu)
<< "\n float = " << sizeof(f)
<< "\n double = " << sizeof(d)
<< "\n long double = " << sizeof(ld)
<< endl;
} ///:

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 81

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Punteros
Al declarar variables lo que estamos haciendo es dar un nombre a un pedazo
de la memoria. Cuando decimos int n lo que estamos diciendo al compilador

4 bytes de la memoria y a partir de ahora lo voy a llamar n. El


es: reserveme
de la memoria fue alocada la variable
operador & nos muestra en que posicion
1
2

1
2

int n;
cout << "variable n is in position " << &n << endl;
[mstorti@galileo garage]$$ ./ptr.bin
variable n is in position 0x7fff1c46d92c

Los punteros son impresos normalmente en formato de hexadecimales, si

quisieramos
verlo en formato decimal podemos castear (convertir) el puntero
a un entero
1
2

1
2

int n;
cout << "variable n is in position " << (long)&n << endl;
[mstorti@galileo garage]$$ ./ptr.bin
variable n is in position 140737075615260

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 82

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Punteros (cont.)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

#include <iostream>
using namespace std;
int dog, cat, bird, fish;
void f(int pet) {
cout << "pet id number: " << pet << endl;
}
int main() {
int i, j, k;
cout << "f(): " << (long)&f << endl;
cout << "dog: " << (long)&dog << endl;
cout << "cat: " << (long)&cat << endl;
cout << "bird: " << (long)&bird << endl;
cout << "fish: " << (long)&fish << endl;
cout << "i: " << (long)&i << endl;
cout << "j: " << (long)&j << endl;
cout << "k: " << (long)&k << endl;
}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 83

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Punteros (cont.)
El resultado es
1
2
3
4
5
6
7
8
9
10

[mstorti@galileo garage]$$ ./pointers.bin


f(): 4196630
dog: 6295956
cat: 6295960
bird: 6295964
fish: 6295968
i: 140736631158572
j: 140736631158568
k: 140736631158564
[mstorti@galileo garage]$$

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 84

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Punteros (cont.)
en memoria de un variable puede cambiar de una corrida a
La direccion

1
2

otra.
Funciones, variables y globales parecen estar en sectores de la memoria
diferentes.
Enteros parecen ocupar 4 bytes.
Las posiciones en la memoria se pueden guardar en una variable de tipo
especial llamada puntero

int number;
int *number-p = &number;

una
El sufijo _p o simplemente p indica que es un puntero (es solo

convencion).

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 85

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Punteros (cont.)
Algunos programadores ponen el * junto al tipo.
1
int* number-p;
Es totalmente equivalente, pero confuso,
1

int* number-p,n-p,m-p;

Declara a number_p, pero n_p y m_p son declarados enteros. Lo correcto es


1

int *number-p,*n-p,*m-p;

de una
Podemos asignar a una variable de tipo puntero la direccion
de ese proxy
variable, lo cual nos permite modificarla a traves
1
2
3

int number=100;
int *number-p = &number;
*number-p = 25; // Ahora number contiene 25!!

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 86

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Punteros (cont.)
OJO: el hecho de declarar una variable de tipo puntero no significa que

este apuntando a un objeto valido,


es deber del programador asignarle al
valida,

puntero una posicion


si no puede dar error en tiempo de ejecucion
al querer usar el puntero.
1
2
3
4
5

int *p;
cout << "contenido de *p " << *p << endl; // ERROR
int x;
p = &x;
cout << "contenido de *p " << *p << endl; // OK

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 87

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Punteros (cont.)
de usos, el primero que podemos ver aca
Los punteros tienen un monton
modifique un objeto
es el de causar que una funcion
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

#include <iostream>
using namespace std;
void f(int a) {
cout << "a = " << a <<
a = 5;
cout << "a = " << a <<
}
int main() {
int x = 47;
cout << "x = " << x <<
f(x);
cout << "x = " << x <<
}

endl;
endl;

endl;
endl;

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 88

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Punteros (cont.)
Imprime:
1
2
3
4

x
a
a
x

=
=
=
=

47
47
5
47

que se
Como la variable a en f() es una copia, resulta que la modificacion
hace en f() no persiste, de manera que queda el mismo valor.

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 89

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Punteros (cont.)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

#include <iostream>
using namespace std;
void f(int* p) {
cout << "p = " << p << endl;
cout << "*p = " << *p << endl;
*p = 5;
cout << "p = " << p << endl;
}
int main() {
int x = 47;
cout << "x = " << x << endl;
cout << "&x = " << &x << endl;
f(&x);
cout << "x = " << x << endl;
}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 90

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Punteros (cont.)
Imprime:
1
2
3
4
5
6

x = 47
&x = 0065FE00
p = 0065FE00
*p = 47
p = 0065FE00
x=5

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 91

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Referencias
Los punteros son muy utiles

pero engorrosos porque hay que estar

dereferenciando al puntero cada vez. C++ introdujo las referencias que


son completamente equivalentes a los punteros pero evitan la

dereferenciacion.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

#include <iostream>
using namespace std;
void f(int& r) {
cout << "r = " << r << endl;
cout << "&r = " << &r << endl;
r = 5;
cout << "r = " << r << endl;
}
int main() {
int x = 47;
cout << "x = " << x << endl;
cout << "&x = " << &x << endl;
f(x); // Looks like pass-by-value,
// is actually pass by reference
cout << "x = " << x << endl;

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 92

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

18

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 93

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Referencias (cont.)
Imprime:
1
2
3
4
5
6

x = 47
&x = 0065FE00
r = 47
&r = 0065FE00
r=5
x=5

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 94

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Punteros a void
acepta que asignemos a una variable de tipo int* la
El compilador solo
de una variable de tipo int, en otro caso da un error
direccion

int *p;
2 int n;
3 p = &n; // OK
4 double a;
5 p = &a; // Error
El tipo void* permite almacenar un puntero a cualquier tipo de variable
1 void* vp;
2 char c;
3 int i;
4 float f;
5 double d;
6 vp = &c;
7 vp = &i;
8 vp = &f;
9 vp = &d;
1

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 95

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Punteros a void (cont.)


es asignada a un void* el compilador no puede
Una vez que una direccion
saber de que tipo es el objeto al cual apunta, y por lo tanto no se puede
dereferenciar
1
2
3

int i = 99;
void* vp = &i;
*vp = 3; // Error de compilacion

Para poder recuperar el objeto tenemos que castear el puntero, de esa


forma le estamos diciendo al compilador que es del tipo indicado
1
2
3

int i = 99;
void* vp = &i;
*((int*)vp) = 3; // OK!

Si casteamos al tipo incorrecto el compilador no protesta, pero se puede

producir un error en tiempo de ejecucion


1
2
3
4

int i = 99;
void* vp = &i;
// Compila OK, posible error en tiempo de ejecucion
*((string*)vp) = "Hello world";

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 96

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Scope de las variables


hasta la siguiente llave que cierra (}).
Una variable existe desde su definicion
Eso se llama el scope de la variable.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

// How variables are scoped


int main() {
int scp1;
// scp1 visible here
{
// scp1 still visible here
//. . . . .
int scp2;
// scp2 visible here
//. . . . .
{
// scp1 & scp2 still visible here
//. .
int scp3;
// scp1, scp2 & scp3 visible here
// . . .
} // scp3 destroyed here
// scp3 not available here

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 97

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

19
20
21
22
23
24
25

// scp1 & scp2 still visible here


// . . .
} // scp2 destroyed here
// scp3 & scp2 not available here
// scp1 still visible here
//. .
} // scp1 destroyed here

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 98

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Definiendo variables on-the-fly


En C todas las variables deben ser definidas al comienzo del scope. En C++
se pueden definir en cualquier lugar.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

// On-the-fly variable definitions


#include <iostream>
using namespace std;
int main() {
//. .
{ // Begin a new scope
int q = 0; // C requires definitions here
//. .
// Define at point of use:
for(int i = 0; i < 100; i++) {
q++; // q comes from a larger scope
// Definition at the end of the scope:
int p = 12;
}
int p = 1; // A different p
} // End scope containing q & outer p
cout << "Type characters:" << endl;

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 99

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

while(char c = cin.get() != q) {
cout << c << " wasnt it" << endl;
if(char x = c == a | | c == b)
cout << "You typed a or b" << endl;
else
cout << "You typed " << x << endl;
}
cout << "Type A, B, or C" << endl;
switch(int i = cin.get()) {
case A: cout << "Snap" << endl; break;
case B: cout << "Crackle" << endl; break;
case C: cout << "Pop" << endl; break;
default: cout << "Not A, B or C!" << endl;
}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 100

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Definiendo variables on-the-fly (cont.)


fuera de todas las funciones son globales, su scope
Las variables que estan
es todo el programa, includo dentro de las funciones.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

// == file1.cpp ==
// Demonstration of global variables
#include <iostream>
using namespace std;
int globe;
void func();
int main() {
globe = 12;
cout << globe << endl;
func(); // Modifies globe
cout << globe << endl;
}
// == file2.cpp ==
// Accessing external global variables
extern int globe;
// (The linker resolves the reference)
void func() {

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 101

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

19
20

globe = 47;

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 102

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Variables locales
se les
Las variables que existen dentro de un scope son locales, tambien

llama automaticas
ya que son creadas en el momento de llegar a ese bloque.
La memoria que le es asignada no tiene porque ser siempre la misma, por lo
tanto la variable no retiene el valor que le fue asignado antes.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

void f(int x) {
int a;
cout << "a en f(): " << a << endl;
cout << "&a en f(): " << &a << endl;
a=x;
cout << "a en f() despues de asignar: " << a << endl;
}
void g(int x) {
int a;
cout << "a en g(): " << a << endl;
cout << "&a en g(): " << &a << endl;
a=x;
cout << "a en g() despues de asignar: " << a << endl;
}
void h(int x) {

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 103

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

int a;
f(435);
cout << "a en h(): " << a << endl;
cout << "&a en h(): " << &a << endl;
a=x;
cout << "a en h() despues de asignar: " << a << endl;

}
int main() {
f(23);
g(45);
f(23);
g(45);
h(234);
return 0;
}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 104

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Variables locales (cont.)


El resultado es:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

[mstorti@galileo garage]$$ ./try2.bin


a en f(): 0
&a en f(): 0x7fff6df56d1c
a en f() despues de asignar: 23
a en g(): 23
&a en g(): 0x7fff6df56d1c
a en g() despues de asignar: 45
a en f(): 45
&a en f(): 0x7fff6df56d1c
a en f() despues de asignar: 23
a en g(): 23
&a en g(): 0x7fff6df56d1c
a en g() despues de asignar: 45
a en f(): 59
&a en f(): 0x7fff6df56cdc
a en f() despues de asignar: 435
a en h(): 45
&a en h(): 0x7fff6df56d1c

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 105

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

19
20

a en h() despues de asignar: 234


[mstorti@galileo garage]$$

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 106

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Punteros a variables locales


Si una variable sale de scope, es un error tratar de utilizar punteros que
apuntaban a esa variable.
1
2
3
4
5
6
7
8

int *p;
for (int j=0; j<N; j++) {
int z;
p = &z;
...
}
// ERROR (z no existe mas)
cout << "contenido de *p " << *p << endl;

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 107

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Variables estaticas

Si queremos que el area


asignada a una variable local sea siempre el mismo,

entonces le agregamos el keyword static. Un ejemplo clasico


es una funcion
que cuenta cuantas veces fue llamada:
1
2
3
4
5
6
7
8
9
10
11

void f() {
static int count=0;
cout << "f() fue llamada " << count << " veces" << endl;
cout++;
}
int main() {
for (int j=0; j<10; j++)
f();
return 0;
}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 108

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Variables estaticas
(cont.)
El resultado es:
1
2
3
4
5
6
7
8
9
10
11
12

[mstorti@galileo garage]$ ./try14.bin


f() fue llamada 0 veces
f() fue llamada 1 veces
f() fue llamada 2 veces
f() fue llamada 3 veces
f() fue llamada 4 veces
f() fue llamada 5 veces
f() fue llamada 6 veces
f() fue llamada 7 veces
f() fue llamada 8 veces
f() fue llamada 9 veces
[mstorti@galileo garage]$

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 109

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Constantes
Si se utilizara muchas veces un valor que es constante se pueden hacer a
de un macro
traves
1

#define PI 3.141459

de una variable de tipo const


o bien a traves
1

const double pi = 3.141459;

prolijo esto ultimo


Es mas

(le permite al compilador hacer chequeo de tipo).

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 110

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Operadores. Asignacion

El caracter = se utiliza como el operador de asignacion:


1

A=4;

Lo que esta a la izquierda de = es el lvalue y lo que esta a la derecha el rvalue.


El compilador la evalua y asigna el
El rvalue puede ser cualquier expresion.
resultado a lo que esta en el lvalue. Ahora bien lo que esta en el lvalue no
puede ser cualquier cosa, debe ser una variable o cualquier otra cosa a la
cual se le pueda asignar un valor. Por ejemplo no puede ser una constante, es
decir no podemos hacer
1

4=A;

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 111

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Operadores matematicos

Los operadores matematicos


binarios usuales son +-*/. Cada uno de ellos se
+=, -=, *=, /=. Por ejemplo
puede usar en forma de acumulacion
1

x += 5;

es equivalente a
1

x = x + 5;

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 112

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Operadores relacionales
Son
1

>, <, >=, <=, ==, !=

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 113

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Operadores logicos
Son && (and) y || (or). Recordar que en C/C++ muchos tipos se castean

automaticamente
a bool, siendo 0 el valor falso y cualquier otro valor
verdadero. Cuando se imprimen los valores booleanos dan 0 o 1. ! es la

negacion.
Son operadores cortocircuitados es decir si hacemos
1

expr1 && expr2

entonces primero se evalua expr1 y si da falso, entonces expr2 NO se evalua,

logica

ya que no es necesario porque la expresion


resultara en falso de todas
formas. Eso puede ser importante, por ejemplo
1

if (n>0 && m/n!=3) . . .

esta garantizado que no dara error si n==0 ya que si es as directamente la


por n no se hara.
Lo mismo ocurre en
division
1

expr1 | | expr2

si la primera da verdadero.

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 114

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

El operador hook

Es una forma muy compacta de escribir un if-else. Por ejemplo esta expresion
calcula el mnimo de dos valores
1

x = (m<n ? m : n);

en un lvalue. La siguiente expresion


asigna al menor
Se puede usar tambien
de m,n el valor 23.
1

(m<n ? m : n) = 23;

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 115

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Errores comunes con los operadores


Las reglas de precedencia a veces son simples, pero si se escriben

expresiones complejas ya no. Ante la duda utilizar parentesis.


No confundir = con ==.

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 116

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Operadores de cast

Si el compilador ve que estamos mezclando tipos en una asignacion,


de cast (conversion
de tipo) automaticamente

insertara una operacion


1
2
3
4
5
6
7
8
9
10

int x=5;
double z=x; // OK
z=23.3;
x=z; // se pierde la mantisa (truncamiento)
x = (int) z; // cast explicito
x = int(z); // otra forma del cast explicito
int ixp = &x; // error, no puede convertir ptr a int
long int ixp2 = (long int)&x; // OK!
long int ixp3 = static-cast<long int>(&x); // OK!

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 117

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Operador sizeof
de una variable o tipo en bytes
Retorna el tamano
1 cout << "sizeof(char) " << sizeof(char) << endl; // ->1
2 cout << "sizeof(int) " << sizeof(int) << endl; // ->4
3 cout << "sizeof(float) " << sizeof(float) << endl; // ->4
4 cout << "sizeof(double) " << sizeof(double) << endl; // ->8
5
6 double a;
7 cout << "sizeof(a) " << sizeof(a) << endl; // ->8
8 cout << "sizeof(&a) " << sizeof(&a) << endl; // ->8 (in x86 64)
9 int x;
10 cout << "sizeof(&x) " << sizeof(&x) << endl; // ->8 (in x86 64)
-

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 118

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

typedef: Aliases de tipos


Permite hacer un alias de un tipo a un nuevo tipo
1 typedef unsigned long int ulong;
2 . . .
3 ulong x;

complicado para punteros


Simple para tipos basicos,
mas
1 typedef int *int p;
de una variable
La regla es que se escribe una lnea como la declaracion

1
2

con typedef al principio y reemplazando la variable por el tipo.


cortas pero ademas
tiene un uso muy
Esto permite hacer expresiones mas
importante. Permitir cambiar de tipo todas las variables de un programa

typedef float scalar;


scalar i,j,k;

Para cambiar todo el programa a doble precision:

typedef double scalar;

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 119

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Estructuras
Se pueden definir nuevos tipos agrupando varios miembros en una

estructura. Los miembros de la estructura se toman con el operador .:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

struct A {
char c;
int m;
float a;
double b;
};
void printa(A a) {
cout << "structure is (" << a.c << "," << a.m << ","
<< a.f << "," << a.b << ")" << endl;
}
...
A a1, a2;
a1.c = h;
a2.m = 23;
printa(a1);

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 120

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Estructuras (cont.)
Se pueden tomar punteros a estructuras y enlazarlas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

struct cell {
char c;
double x;
cell *next;
};
int main() {
cell c1,c2,c3;
c1.c = a; c1.x = 1; c1.next = &c2;
c2.c = b; c2.x = 2; c2.next = &c3;
c3.c = c; c3.x = 3; c3.next = &c1;
cell *cp = &c1;
for (int k=0; k<20; k++) {
cout << "cp " << cp << ", c "
<< (*cp).c << ", x " << (*cp).x << endl;
cp = (*cp).next;
}
}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 121

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Estructuras (cont.)
1
2
3
4

cell
c1.c
c2.c
c3.c

c1,c2,c3;
= a; c1.x = 1; c1.next = &c2;
= b; c2.x = 2; c2.next = &c3;
= c; c3.x = 3; c3.next = &c1;
c1

c='a' x=1

c2

c3

c='c' x=3

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

next

next

c='b' x=2

next

slide 122

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Estructuras (cont.)
El resultado es
1
2
3
4
5
6
7
8
9

[mstorti@galileo garage]$$ ./try8.bin


cp 0x7fff571b2d20, c a, x 1
cp 0x7fff571b2d00, c b, x 2
cp 0x7fff571b2ce0, c c, x 3
cp 0x7fff571b2d20, c a, x 1
...
cp 0x7fff571b2d20, c a, x 1
cp 0x7fff571b2d00, c b, x 2
[mstorti@galileo garage]$$

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 123

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Arrow operator
(*cp).x es decir
Como en el ejemplo anterior es muy comun
la compinacion
tener un puntero a una estructura cp y querer tomar un miembro x de la

estructura apuntada. Como es tan comun


hay un atajo sintactico
para eso
1

(*cp).x es equivalente a cp->x

Entonces el lazo del programa anterior pasa a ser


1
2
3
4
5

for (int k=0; k<20; k++) {


cout << "cp " << cp << ", c " << cp->c
<< ", x " << cp->x << endl;
cp = cp->next;
}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 124

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Enums
Supongamos que queremos definir una estructura shape que contiene una

forma geometrica,
digamos las coordenadas x,y de su centro y un entero
que indica su forma. Para ello incluimos un entero gtype (por geometric
type) que define que tipo de forma es. Podemos por ejemplo asignar

arbitrariamente gtype=0 para crculos, 1=cuadrados, 2=rectangulos.

1
2
3
4

struct shape {
double x,y;
int gtype;
};
que imprime la forma sera algo as como
Entonces una funcion

1
2
3
4
5
6

void draw(shape s) {
if (s.gtype==0) //. . . imprime un circulo
else if (s.gtype==1) //. . . imprime un cuadrado
else if (s.gtype==2) //. . . imprime un rect
...
}
El problema con esto es que tenemos que guardar mentalmente una tabla
para saber que entero corresponda a cada forma.

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 125

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Enums (cont.)
Una posibilidad es usar macros
1
2
3
4
5
6
7
8
9
10

#define CIRCLE 0
#define SQUARE 1
#define RECTANGLE 2
void draw(shape s) {
if (s.gtype==CIRCLE) //. . . imprime un circulo
else if (s.gtype==SQUARE) //. . . imprime un cuadrado
else if (s.gtype==RECTANGLE) //. . . imprime un rect
...
}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 126

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Enums (cont.)
Pero, como ya dijimos, es preferible no usar macros, para esto esta el enum:
1
2
3
4
5
6
7
8
9
10
11
12
13

enum GeoType { circle, square, rectangle};


struct shape {
double x,y;
GeoType gtype;
};
void draw(shape s) {
if (s.gtype==circle) //. . . imprime un circulo
else if (s.gtype==square) //. . . imprime un cuadrado
else if (s.gtype==rectangle) //. . . imprime un rect
...
}

Internamente los enums son enteros, pero esto es transparente para

nosotros.
El compilador traduce cada identificador de la lista a un entero
consecutivo.
Se puede forzar a que tomen un valor especfico

1 enum GeoType { circle=5, square=10, rectangle=15};


Facultad de Ingeniera y Ciencias Hdricas FICH - UNL
((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 127

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Arreglos de estructuras
Vimos que podemos definir arreglos como int v[100].
lo podemos hacer con estructuras cell sv[100]
Tambien
Los elementos son guardados en forma consecutiva
1 struct cell {
2
double x;
3
cell *next;
4 };
5
6 for (int j=0; j<4; j++)
7
cout << "&cellv[" << j << "] "
8
<< (long int)&cellv[j] << endl;
9 . . .
10 &cellv[0] 140736201505632
11 &cellv[1] 140736201505648
12 &cellv[2] 140736201505664
de la celda es de 16 bytes (8 para el doble y 8 para el
ya que el tamano
puntero):
1
2
3

cout << "sizeof(cell): " << sizeof(cell) << endl;


...
sizeof(cell): 16

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 128

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Punteros y arreglos
Si imprimimos un arreglo, el compilador lo imprime como hexadecimal, o sea
como si fuera un puntero
1
2
3
4

int v[100];
cout << v << endl;
...
-> 0x7fff7e388420

almacena para el vector la direccion


donde
Esto es porque el compilador solo

comienza el area
asignada al vector. Esto lo podemos verificar imprimiento la
del primer elemento
direccion
1
2

cout << &cellv[0] << endl;


-> 0x7fff7e388420

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 129

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Punteros y arreglos (cont.)


Si tomamos un puntero al primer elemento podemos manipular al vector a
de ese puntero
traves
1
2
3

int v[100];
int *p= &v[0];
for (int j=0; j<1000, j++) *(p+j) = 100*j;

De hecho en la mayora de los casos punteros y arreglos son intercambiables,


por ejemplo a los punteros se les puede aplicar el operador [] de manera que
se lo puede utilizar como un vector.
1
2
3

int v[100];
int *p= &v[0];
for (int j=0; j<1000, j++) p[j] = 100*j;

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 130

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Arreglos de punteros
se pueden tener arreglos de punteros
Tambien
1 int *v[100]; // arreglo de 100 punteros a enteros
Los arreglos de caracteres, son de tipo char* entonces si queremos tener
un arreglo de strings de C, tenemos un arreglo de arreglos de char, o lo
que es equivalente a arreglos de punteros a char
1
2

char *as[ ];
char **as; // equivalente

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 131

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Arreglos de punteros (cont.)


Un caso frecuente de esto es la segunda forma de llamada a main(). Si
llamamos a nuestro programa con argumentos
1
2
3
4
5

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


for (int j=0; j<argc; j++)
cout << j << ": " << argv[j] << endl;
return 0;
}
El resultado es

1
2
3
4
5
6
7
8
9
10

$$
0:
1:
2:
3:
4:
5:
6:
7:
8:

./try10.bin -u mstorti -d 453 -l 34 -f 34.56


./try10.bin
-u
mstorti
-d
453
-l
34
-f
34.56

El shell (en este caso bash) divide los argumentos pasados en la lnea de
comando por whitespace y construye un arreglo de strings
Facultad de Ingeniera y Ciencias Hdricas FICH - UNL
((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 132

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Arreglos de punteros (cont.)

El acceso a elementos de un arreglo de C es extremadamente rapido.


alla de la ultima
del
Sin embargo si se accede a posiciones mas

posicion
vector se puede producir un error

int v[100];
2 . . .
3 v[100] = x; // Muy probablemente SIGSEGV o SEGFAULT
del vector en tiempo de compilacion
(hay una
Se debe conocer el tamano
1

forma de hacerlo dinamico,


con new[]/delete[] o malloc()/free().
versatil
y mas
segura.
La clase vector<> es mucho mas

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 133

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Arreglos de punteros (cont.)


en posiciones
Podemos verificar que los elementos de un vector estan
contiguas.
1
2
3
4
5

int a[10];
cout << "sizeof(int) = "<< sizeof(int) << endl;
for(int i = 0; i < 10; i++)
cout << "&a[" << i << "] = "
<< (long)&a[i] << endl;

produce
1
2
3
4
5
6

$$ ./try17.bin
sizeof(int) = 4
&a[0] = 140736359816368
&a[1] = 140736359816372
&a[2] = 140736359816376
&a[3] = 140736359816380

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 134

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Aritmetica
de punteros
Se pueden hacer cuentas con punteros de tipo ptr = ptr + int y todas las
derivadas, por ejemplo
1
2
3
4
5

ptr = ptr + int


int = ptr - ptr
ptr += int
ptr++
ptr--

En todas estas operaciones el entero indica posiciones en el vector, no bytes.

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 135

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Aritmetica
de punteros (cont.)
1
2
3
4
5
6
7
8
9
10

int i[10];
double d[10];
int* ip = i;
double* dp = d;
cout << "ip = " <<
ip++;
cout << "ip = " <<
cout << "dp = " <<
dp++;
cout << "dp = " <<

(long)ip << endl;


(long)ip << endl;
(long)dp << endl;
(long)dp << endl;

produce
1
2
3
4
5

[mstorti@galileo garage]$$ ./try18.bin


ip = 140733418503296
ip = 140733418503300
dp = 140733418503216
dp = 140733418503224

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 136

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Tamanos
de estructuras
del
Cuando se usan estructuras con tipos mezclados puede ser que el tamano

tipo combinado no sea igual a la suma de los tamanos


de los tipos (pero
seguro es mayor o igual) porque el compilador tiene que alinear los tipos.
1
2
3
4

struct A {
char c;
double d;
};

da sizeof(A) -> 16, y


1
2

struct B { char c; double d; char c2; };


struct C { char c; char c2; double d; };

da
1
2

sizeof(B) -> 24
sizeof(C) -> 16

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 137

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Orientada
Programacion
a Objetos

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 138

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

de datos
Abstraccion
Un contenedor de elementos de longitud arbitraria
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

#ifndef CSTASH-H
#define CSTASH-H
struct CStash {
int size; // Size of each space
int quantity; // Number of storage spaces
int next; // Next empty space
// Dynamically allocated array of bytes:
unsigned char* storage;
};
void initialize(CStash* s, int size);
void cleanup(CStash* s);
int add(CStash* s, const void* element);
void* fetch(CStash* s, int index);
int count(CStash* s);
void inflate(CStash* s, int increase);
#endif

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 139

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

de datos (cont.)
Abstraccion
1
2
3
4
5
6
7

struct CStash {
int size; // Size of each space
int quantity; // Number of storage spaces
int next; // Next empty space
// Dynamically allocated array of bytes:
unsigned char* storage;
};

size
used

free

store

quantity
next
Facultad de Ingeniera y Ciencias Hdricas FICH - UNL
((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 140

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

de datos (cont.)
Abstraccion
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

// Implementation of example C-like library


// Declare structure and functions:
#include "./cstash.h"
#include <iostream>
#include <cassert>
using namespace std;
// Quantity of elements to add
// when increasing storage:
const int increment = 100;
void initialize(CStash* s, int sz) {
s->size = sz;
s->quantity = 0;
s->storage = 0;
s->next = 0;
}
int add(CStash* s, const void* element) {
if(s->next >= s->quantity) //Enough space left?
inflate(s, increment);
// Copy element into storage,

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 141

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

// starting at next empty space:


int startBytes = s->next * s->size;
unsigned char* e = (unsigned char*)element;
for(int i = 0; i < s->size; i++)
s->storage[startBytes + i] = e[i];
s->next++;
return(s->next - 1); // Index number

}
void* fetch(CStash* s, int index) {
// Check index boundaries:
assert(0 <= index);
if(index >= s->next)
return 0; // To indicate the end
// Produce pointer to desired element:
return &(s->storage[index * s->size]);
}
int count(CStash* s) {
return s->next; // Elements in CStash
}
void inflate(CStash* s, int increase) {
assert(increase > 0);
int newQuantity = s->quantity + increase;

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 142

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

int newBytes = newQuantity * s->size;


int oldBytes = s->quantity * s->size;
unsigned char* b = new unsigned char[newBytes];
for(int i = 0; i < oldBytes; i++)
b[i] = s->storage[i]; // Copy old to new
delete [ ](s->storage); // Old storage
s->storage = b; // Point to new memory
s->quantity = newQuantity;

}
void cleanup(CStash* s) {
if(s->storage != 0) {
cout << "freeing storage" << endl;
delete [ ]s->storage;
}
}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 143

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

de datos (cont.)
Abstraccion
CStash es un tipo que permite almacenar una cantidad ilimitada de

size.
elementos de tamano

Tiene un area
de almacenamiento interno unsigned char *storage.
del almacenamiento
Se pueden agregar elementos con add(), si el tamano
interno no es suficiente entences se incrementa en una dada cantidad
(por default 100).
initialize() realiza la inicializacion de la estructura, poniendo a cero los
de los elementos al valor entrado por el
diferentes contadores y el tamano
usuario (int sz).

add() agrega un elemento copiandolo


byte por byte a storage. Si el tamano

no es suficiente llama a inflate() para alocar una nueva area


recopiando

todo el area
previa y agregando el nuevo elemento.
quantity es el numero

de lugares disponibles
next es la cantidad de lugares realmente ocupados.
fetch() retorna el puntero al lugar donde comienza el elemento en la
index. Primero chequea que efectivamente el ndice este en el
posicion
rango de valores apropiados (0<=index<next). En caso contrario retorna un
puntero nulo. Esta garantizado que el puntero nulo no apunta a ningun

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 144

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

lado de la memoria.
count() retorna la cantidad de elementos que hay en el contenedor.
Simplemente retorna next.
dinamica

Alocacion
de memoria: Como no sabemos en principio que
va a tomar el area

tamano
de memoria vamos alocando dinamicamente
con el operador new

new unsigned char[newBytes];


En general se puede hacer
1 t = new Type; // aloca un solo objeto
2 tp = new Type[count]; // aloca un arreglo de count objetos

se hace
El area
utilizada debe ser liberada. Si no (y si la alocacion
1

repetidamente) se produce un memory leak.

delete t;
2 delete[ ] tp;

Las areas
de memoria reservadas con new se alocan en el heap. Si el heap
1

da un error (OJO que no necesariamente retorna un


se acaba la alocacion
puntero nulo).

Los pedazos de memoria alocados con new pueden crear fragmentacion


de la memoria. (No hay un defragmentador).

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 145

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

de datos (cont.)
Abstraccion
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

#include "./cstash.h"
#include <fstream>
#include <iostream>
#include <string>
#include <cassert>
using namespace std;
int main() {
// Define variables at the beginning
// of the block, as in C:
CStash intStash, stringStash;
int i;
char* cp;
ifstream in;
string line;
const int bufsize = 80;
// Now remember to initialize the variables:
initialize(&intStash, sizeof(int));
for(i = 0; i < 100; i++)
add(&intStash, &i);
for(i = 0; i < count(&intStash); i++)

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 146

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

cout << "fetch(&intStash, " << i << ") = "


<< *(int*)fetch(&intStash, i)
<< endl;
// Holds 80-character strings:
initialize(&stringStash, sizeof(char)*bufsize);
in.open("./trycstash.cpp");
assert(in);
while(getline(in, line))
add(&stringStash, line.c-str());
i = 0;
while((cp = (char*)fetch(&stringStash,i++))!=0)
cout << "fetch(&stringStash, " << i << ") = "
<< cp << endl;
cleanup(&intStash);
cleanup(&stringStash);
return 0;

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 147

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

de datos (cont.)
Abstraccion
Resultado:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

[mstorti@galileo garage]$ ./trycstash.bin


fetch(&intStash, 0) = 0
fetch(&intStash, 1) = 1
fetch(&intStash, 2) = 2
fetch(&intStash, 3) = 3
...
fetch(&intStash, 97) = 97
fetch(&intStash, 98) = 98
fetch(&intStash, 99) = 99
0: #include "./cstash.h"
1: #include <fstream>
2: #include <iostream>
3: #include <string>
...
37: cleanup(&stringStash);
38: return 0;
39: }
freeing storage
freeing storage
[mstorti@galileo garage]$

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 148

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

POO basica

La librera que creamos tiene dos problemas basicos:


y destruccion
de los objetos fuera
Sera bueno que la construccion

automatica.
del espacio de nombres: Si necesitamos otro contenedor no
Polucion
vamos a poder usar los nombres initialize() y cleanup(). Una posible
sera usar nombres con prefijos CStash_initialize(),
solucion
CStash_cleanup() ...

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 149

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

POO basica
(cont.)
1
2
3
4
5
6
7
8
9
10
11
12
13
14

struct Stash {
int size; // Size of each space
int quantity; // Number of storage spaces
int next; // Next empty space
// Dynamically allocated array of bytes:
unsigned char* storage;
// Functions!
void initialize(int size);
void cleanup();
int add(const void* element);
void* fetch(int index);
int count();
void inflate(int increase);
};

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 150

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

POO basica
(cont.)
Ahora las funciones aparecen dentro de la estructura, de manera que esta

1
2

actua
como un namespace, de manera que la funciones se llaman ahora
Stash::initialize(), Stash::cleanup()
No hace falta pasar a las funciones el puntero al objeto. Esto se hace

como miembro de un objeto


automaticamente
llamando a la funcion

Stash s1,s2,s3;
s1.initialize(10);

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 151

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

POO basica
(cont.)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

// C library converted to C++


// Declare structure and functions:
#include "CppLib.h"
#include <iostream>
#include <cassert>
using namespace std;
// Quantity of elements to add
// when increasing storage:
const int increment = 100;
void Stash::initialize(int sz) {
size = sz;
quantity = 0;
storage = 0;
next = 0;
}
int Stash::add(const void* element) {
if(next >= quantity) // Enough space left?
inflate(increment);
// Copy element into storage,
// starting at next empty space:

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 152

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

int startBytes = next * size;


unsigned char* e = (unsigned char*)element;
for(int i = 0; i < size; i++)
storage[startBytes + i] = e[i];
next++;
return(next - 1); // Index number

}
void* Stash::fetch(int index) {
// Check index boundaries:
assert(0 <= index);
if(index >= next)
return 0; // To indicate the end
// Produce pointer to desired element:
return &(storage[index * size]);
}
int Stash::count() {
return next; // Number of elements in CStash
}
void Stash::inflate(int increase) {
assert(increase > 0);
int newQuantity = quantity + increase;
int newBytes = newQuantity * size;

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 153

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

48
49
50
51
52
53
54
55
56
57
58
59
60
61
62

int oldBytes = quantity * size;


unsigned char* b = new unsigned char[newBytes];
for(int i = 0; i < oldBytes; i++)
b[i] = storage[i]; // Copy old to new
delete [ ]storage; // Old storage
storage = b; // Point to new memory
quantity = newQuantity;

}
void Stash::cleanup() {
if(storage != 0) {
cout << "freeing storage" << endl;
delete [ ]storage;
}
}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 154

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

POO basica
(cont.)
Adentro de las funciones miembro no es necesario dereferenciar al objeto

1
2
3
4
5
6
7
8

para obtener los miembros size, quantity. Es decir en vez de aparecer


aparece size, lo que ocurre es que al llamar
s->size ahora solo
s1.initialize() la variable size corresponde al del objeto s1.
Si uno necesita conocer el puntero a la estructura en la que estoy en este
momento se usa el keyword this que es un puntero al objeto en el que
estamos parados

void Stash::initialize(int sz) {


cout << "this: " << this << endl;
...
}
Stash s1;
cout << "&s1: " << &s1 << endl;
s1.initialize();
Imprimen el mismo puntero.

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 155

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

POO basica
(cont.)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

// Test of C++ library


#include "CppLib.h"
#include ". ./require.h"
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int main() {
Stash intStash;
intStash.initialize(sizeof(int));
for(int i = 0; i < 100; i++)
intStash.add(&i);
for(int j = 0; j < intStash.count(); j++)
cout << "intStash.fetch(" << j << ") = "
<< *(int*)intStash.fetch(j)
<< endl;
// Holds 80-character strings:
Stash stringStash;
const int bufsize = 80;
stringStash.initialize(sizeof(char) * bufsize);

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 156

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

22
23
24
25
26
27
28
29
30
31
32
33
34

ifstream in("CppLibTest.cpp");
assure(in, "CppLibTest.cpp");
string line;
while(getline(in, line))
stringStash.add(line.c-str());
int k = 0;
char* cp;
while((cp =(char*)stringStash.fetch(k++)) != 0)
cout << "stringStash.fetch(" << k << ") = "
<< cp << endl;
intStash.cleanup();
stringStash.cleanup();

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 157

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

POO basica
(cont.)
Las llamadas a funciones de la librera se convierten as
1 CStash initialize(&s1,sz);
2 s1.initialize(size);

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 158

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Inclusion de headers
Algunos headers pueden incluir a otros, por ejemplo el header de una
librera lib1.h puede incluir iostream. Entonces si otra librera lib2.h
incluye iostream, al querer incluir a las dos libreras
tambien

#include <lib1.h>
2 #include <lib2.h> // Incluye iostream 2 veces -> error
No hay problema con las funciones, pero si con las estructuras (y clases).

Se utiliza un mecanismo con macros para evitar la doble inclusion.


1

Podemos usar los macros para incluir condicionalmente partes del

codigo.
1
2
3
4
5
6
7

#define FLAG
#ifdef FLAG
//. . .
#else
//. . .
#endif
Notar que es muy diferente este condicional del preprocesador que el
uno de los bloques se
if-else de C++. En el del preprocesador solo
compila. Quiere decir que se puede usar para usar diferentes pedazos de

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 159

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

codigo
que de otra forma no compilara. Por ejemplo

#ifdef HAS-PETSC
2 //. . . Version que usa la libreria PETSC
3 #else
4 //. . . Version alternativa
5 #endif

El macro se puede definir usando un #define FLAG como arriba, o tambien

al compilar usando $$ g++ -DFLAG ...


Lo contrario de definir un macro es hacerlo indefinido con #undef FLAG, a
partir de ahi #ifdef FLAG da falso.
#undef se puede usar para redefinir macros

1 #define MAX SIZE


2 . . . .
3 #define MAX SIZE
1 #define MAX SIZE
2
3 . . .
4 #undef MAX SIZE
5 #define MAX SIZE
-

100
1000 // -> Error
100
1000 // OK!

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 160

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Inclusion de headers (cont.)


se utiliza un macro de proteccion

Para evitar la doble inclusion


1 #ifndef STASH H
2 #define STASH H
3 // Type declaration here. . .
4 #endif // STASH H
Ahora si se incluye dos veces el header no hay problema, ya que la
segunda vez en realidad no es incluido.

#include <stash.h>
2 #include <stash.h> // no es incluido esta vez!!
El macro centinela STASH_H debe ser unico

para ese archivo. Si otro


1

archivo usa el mismo macro centinela entonces sus declaraciones no son


incluidas

1
2

#include <libreria1/stash.h>
#include <libreria2/stash.h> // Error: este no es incluido
Deberian usar LIBRERIA1_STASH_H y LIBRERIA2_STASH_H.

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 161

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Inclusion de headers (cont.)


Si en un header mylib.h se utilizan elementos de iostream es tentador

poner un using namespace std; en el header, para no tener que andar


poniendo el namespace std explcitamente (e.g. std::cout).
Lamentablemente esto producira que si un usuario incluye mylib.h todo

del namespace y volvemos a la situacion

su codigo
pierde la proteccion
de nombres.
que queramos impedir con los namespace: la colision
en
Por lo tanto la regla es: NO usar using namespace.. en los headers, solo
los .cpp

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 162

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Estructuras enlazadas
La siguiente estructura Stack representa una pila implementada con

celdas enlazadas. Las celdas son de otra estructura llamada Link que
contiene el dato data y un puntero a la siguiente celda next.

1
2
3
4
5

struct Link {
void* data;
Link* next;
void initialize(void* dat, Link* nxt);
};

Stack S
head

data

next

data

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

next

data

next

data

slide 163

next

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Estructuras enlazadas (cont.)


1
2
3
4
5
6
7
8
9
10
11
12
13
14

struct Link {
void* data;
Link* next;
void initialize(void* dat, Link* nxt);
};
struct Stack {
Link *head;
void initialize();
void push(void* dat);
void* peek();
void* pop();
void cleanup();
};

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 164

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Estructuras enlazadas (cont.)


push() mete un nuevo elemento en la pila, peek() retorna un
La funcion

puntero al elemento en el tope de la pila. pop() elimina un elemento del


tope. initialize() y cleanup() son como antes: se encargan de la
y destruccion
de la estructura.
inicializacion
se usara con la clase Stack. Si nuestra
El tipo de las celdas Link solo
definir un tipo Queue que representa una cola, con
librera quiere ademas
celdas enlazadas, entonces no podra usar el mismo nombre Link para sus
celdas.
ponemos la clase Link adentro de la clase Stack
Para evitar esta colision

1 struct Stack {
2
struct Link {
3
void* data;
4
Link* next;
5
void initialize(void* dat, Link* nxt);
6
} *head;
7
void initialize();
8
void push(void* dat);
9
void* peek();
10
void* pop();
Facultad de Ingeniera y Ciencias Hdricas FICH - UNL
((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 165

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

void cleanup();
12 };
del tipo se define
Notar que al definir el tipo Link en la misma declaracion

11

un puntero Link *head a la primera celda. Por supuesto se puede hacer

por separado tambien

1
2
3
4

struct Link {
...
};
Link *head;
Por eso las definiciones de estructuras struct Type {...}; terminan en un
punto y coma, ya que all se pueden definir objetos de tipo Type al mismo
tiempo que se define el nuevo tipo.
de inicializacion

Notar que cada estructura Stack y Link tienen su funcion


initialize().
Link no tiene cleanup(), el mismo usario es responsable de liberar el
espacio apuntado por data, si existe.

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 166

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Estructuras enlazadas (cont.)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

// Linked list with nesting


#include "Stack.h"
#include ". ./require.h"
using namespace std;
void
Stack::Link::initialize(void* dat, Link* nxt) {
data = dat;
next = nxt;
}
void Stack::initialize() { head = 0; }
void Stack::push(void* dat) {
Link* newLink = new Link;
newLink->initialize(dat, head);
head = newLink;
}
void* Stack::peek() {
require(head != 0, "Stack empty");
return head->data;
}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 167

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

24
25
26
27
28
29
30
31
32
33
34
35
36

void* Stack::pop() {
if(head == 0) return 0;
void* result = head->data;
Link* oldHead = head;
head = head->next;
delete oldHead;
return result;
}
void Stack::cleanup() {
require(head == 0, "Stack not empty");
}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 168

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Estructuras enlazadas (cont.)


Uso de Stack
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

// Test of nested linked list


#include "Stack.h"
#include ". ./require.h"
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char* argv[ ]) {
requireArgs(argc, 1); // File name is argument
ifstream in(argv[1]);
assure(in, argv[1]);
Stack textlines;
textlines.initialize();
string line;
// Read file and store lines in the Stack:
while(getline(in, line))
textlines.push(new string(line));
// Pop the lines from the Stack and print them:
string* s;

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 169

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

21
22
23
24
25
26

while((s = (string*)textlines.pop()) != 0) {
cout << *s << endl;
delete s;
}
textlines.cleanup();

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 170

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

sobre scoping
Mas
Si existen varias versiones de variables con un mismo nombre, la que se ve
es la del scope mas interno. Se puede acceder a las otras utilizando el
operador de scope apropiado. Para las globales hay que usar el scop :: (sin
nada a la izquierda).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

// Global scope resolution


int a;
void f() {}
struct S {
int a;
void f();
};
void S::f() {
::f(); // Would be recursive otherwise!
::a++; // Select the global a
a--; // The a at struct scope
}
int main() { S s; f(); }

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 171

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Tipos Abstractos de Datos (ADT)


Con este ejemplo hemos visto una idea fundamental de C++ que es incluir
funciones adentro de las estructuras. Este nuevo tipo de estructura es
llamado un Tipo Abstracto de Datos (Abstract Data Type, ADT)). Las variables
de la estructura sobre
de estos tipos se llaman objetos. Llamar una funcion
un objeto es mandarle un mensaje al objeto.
Si bien encapsular datos y funciones en un TAD es un beneficio considerable

de nombres, la OOP
para organizar el codigo
y prevenir la colision
Orientada a Objetos) es mucho mas
que esto.
(Programacion

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 172

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Ocultando la implementacion
definiciones de estructuras
Una librera tpica de C consiste de una o mas
(struct) y funciones asociadas que actuan

sobre dichas estructuras. En C++


las funciones se pueden asociar explcitamente a esas estructuras poniendo
sus declaraciones dentro del scope de la estructura.
adicional que es hasta donde el programador debe
Pero hay una cuestion
permitir que el usuario de la librera manipule a la estructura. Si el usuario lee
las definiciones de la estructura puede por s mismo manipular la estructura.
Ahora bien, si en algun
momento el programador cambia la forma en que esta

armada la estructura el codigo


del usuario dejara de funcionar (breaks the
code).
Por ejemplo en la estructura Stack definida previamente el programador
podra en el futuro decidir que es mejor alocar la memoria de a grandes
que alocar de a uno como esta hecho en esa
chunks de 100 elementos o mas
Si el codigo

se
implementacion.
del usuario depende de que la alocacion

haga de a un elemento, entonces al producirse el cambio de implementacion

dejara de funcionar.
su codigo

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 173

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

(cont.)
Ocultando la implementacion
En C esto se puede resolver parcialmente si el programador especifica en la
de la librera las funciones con las cuales el usuario de la
documentacion
de las funciones provistas, y
estructura debe manipular los objetos a traves
hasta que punto puede usar directamente los datos almacenados en la
un pacto entre el usuario y el programador, el
estructura. Pero esto es solo
compilador no tiene forma de conocer estas reglas y prevenir al usuario de
manipular los objetos indebidamente.

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 174

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Control de acceso a los miembros


de 3
El acceso a los miembros de una estructura en C++ se hace a traves
especificadores de acceso public, private y protected.
El keyword public quiere decir que todos los miembros siguientes son
accesibles para cualquiera, como ocurre con los miembros de una struct por
defecto. Por lo tanto, en el caso de una struct da lo mismo poner public al
principio o no. Las dos declaraciones siguientes son por lo tanto equivalentes
1
2
3
4
5
6
7
8
9
10
11
12

struct A {
int i,j;
float f;
void func();
};
struct A {
public:
int i,j;
float f;
void func();
};

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 175

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Control de acceso a los miembros (cont.)


La clave keyword private por el contrario, indica que los miembros
se pueden acceder desde codigo

correspondientes solo
(es decir funciones)
de la misma clase.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

struct B {
private:
char j;
float f;
public:
int i;
void func();
};
void B::func() {
i = 0;
j = 0; // OK, access from a B function member
f = 0.0; // OK, idem
};
int main() {
B b;
b.i = 1; // OK, public

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 176

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

19
20
21
22

b.func(); // OK, public


b.j = 1; // Illegal, private
b.f = 1.0; // Illegal, private

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 177

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Control de acceso a los miembros (cont.)


B::func() puede acceder a los miembros privados, porque es una funcion

de la clase, independientemente de si func() es a su vez privada o publica.


Una vez que se incluye el keyword private todas las declaraciones de
miembros dato y funciones son privadas, hasta la siguiente keyword
public.
Se pueden incluir tantas declaraciones private y public como sea
necesario.
Se pueden incluir dos declaraciones private o public seguidas.
adelante
protected es una mezcla de los dos, pero sera explicado mas
cuando se explique el concepto de herencia.

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 178

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Amistad (Friendship)
que no es miembro de la
El keyword friend permite declarar que una funcion
estructura tenga acceso a todos los miembros de la misma.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

// Declaration (incomplete type specification):


struct X;
struct Y {
void f(X*);
};
struct X { // Definition
private:
int i;
public:
void initialize();
friend void g(X*, int); // Global friend
friend void Y::f(X*); // Struct member friend
friend struct Z; // Entire struct is a friend
friend void h();
};
void X::initialize() {

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 179

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

i = 0;

}
void g(X* x, int i) {
x->i = i;
}
void Y::f(X* x) {
x->i = 47;
}
struct Z {
private:
int j;
public:
void initialize();
void g(X* x);
};
void Z::initialize() {
j = 99;
}
void Z::g(X* x) {
x->i += j;
}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 180

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

46
47
48
49
50
51
52
53
54
55
56

void h() {
X x;
x.i = 100; // Direct data manipulation
}
int main() {
X x;
Z z;
z.g(&x);
}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 181

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Anidamiento (nesting) y amistad

El estandar
dice que en principio una clases anidada no tienen que ser
necesariamente amiga de la clase externa.
1
2
3
4
5
6
7
8
9
10
11
12
13
14

struct E {
private:
int x;
struct B { };
struct I {
private:
B b; // error1: E::B is private
int y;
void f(E* p, int i) {
p->x = i; // error2: E::x is private
}
};
int g(I* p) { return p->y; } // error3: I::y is private
};

Sin embargo en la practica


el GCC da acceso a la clase externa a la clase
Es decir da error en 1 y 2, pero no en 3.
interna, pero no al reves.
Facultad de Ingeniera y Ciencias Hdricas FICH - UNL
((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 182

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Object layout
de C++ fue que codigo

Una de las condiciones de diseno


valido
en C debera
compilar sin problemas en C++. Por esto las construcciones de tipo struct
tienen a todos sus miembros publicos.

Cuando el compilador organiza los datos dentro del objeto los guarda en
en la estructura.
memoria en forma contigua, en el orden en el que estan
Cuando introducimos especificadores de acceso, cada bloque de acceso
guarda sus miembros en forma contigua, pero los bloques de acceso pueden
estar entre s puestos de cualquier forma (como si cada uno fuera una
estructura).
Las cuestiones de privilegios de acceso (acceso a los miembros privados y
en el momento de compilacion.
Una
publicos

de la clase) tiene sentido solo

vez que el codigo


fuente es convertido a codigo
de maquina
dos estructuras
en cuanto a sus secciones private y public son
que difieren solo
indistinguibles entre s, a menos del efecto discutido previamente de la
en la memoria (object layout).
disposicion

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 183

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Clases
Controlar el acceso a los miembros de una estructura es parte de lo que se

llama ocultar la implementacion


(implementation hiding). Esto es un
concepto clave en OOP.
posible los miembros de la estructura, por
En OOP se trata de ocultar lo mas
eso lo deseable sera que todos los miembros fueran privados por defecto.
Por eso en C++ existe un tipo de estructura alternativo class que es
completamente equivalente a las struct de C, pero donde todos los miembros
son por defecto private.
Todas estas clases son equivalentes
1
2
3
4
5
6
7
8
9
10

class A {
int i,j,k;
public:
double z;
void f();
};
struct B {
private:
int i,j,k;

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 184

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

11
12
13
14
15
16
17
18
19
20
21

public:
double z;
void f();
};
struct C {
double z; // salvo por el object layout
void f();
private:
int i,j,k;
};

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 185

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Clases (cont.)
Vemos la clase Stash ahora con control de acceso. Todos los datos son
inflate() tambien
ya que solo
es usada internamente.
privados. La funcion
1
2
3
4
5
6
7
8
9
10
11
12
13
14

class Stash {
int size; // Size of each space
int quantity; // Number of storage spaces
int next; // Next empty space
// Dynamically allocated array of bytes:
unsigned char* storage;
void inflate(int increase);
public:
void initialize(int size);
void cleanup();
int add(void* element);
void* fetch(int index);
int count();
};

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 186

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Clases (cont.)
es
En Stack ahora hacemos que toda la estructura Link sea privada o sea solo
accesible desde las funciones miembro de Stack.
1
2
3
4
5
6
7
8
9
10
11
12
13

class Stack {
struct Link {
void* data;
Link* next;
void initialize(void* dat, Link* nxt);
}* head;
public:
void initialize();
void push(void* dat);
void* peek();
void* pop();
void cleanup();
};

Notar que Link sigue siendo declarada como struct. De todas formas toda la
estructura es privada, o sea que desde fuera de Stack no se puede acceder.
declararla como clase, pero entonces deberamos
Podramos tambien
declarar friend a Stack.
Facultad de Ingeniera y Ciencias Hdricas FICH - UNL
((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 187

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Ocultando totalmente la implementacion


la
Todava uno podra preguntarse si se puede ocultar aun
mas
Que el usuario vea solo
la parte publica.
es evitar
implementacion.

Otra razon
innecesaria. Una solucion
es usar punteros opacos, (aka
la recompilacion
el nombre Cheshires cat). Por ejemplo
handles, en C++ se usa tambien
podramos ocultar completamente los detalles de Stash como esta abajo. El
tiene acceso a stashwrapper.h.
usuario solo
1
2
3
4
5
6
7
8
9
10
11
12
13
14

// Header file stashwrapper.h


class StashWrapper {
class Stash;
Stash *stash;
public:
void initialize(int size);
void cleanup();
int add(void* element);
void* fetch(int index);
int count();
};
// Implementation file stashwrapper.cpp
#include "stash.h"

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 188

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

void StashWrapper::initialize(int size) {


stash=new Stash;
stash->initialize();
}
void StashWrapper::cleanup() {
stash->cleanup();
delete stash;
}
int StashWrapper::add(void* element) {
stash->add(element);
}
//. . .

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 189

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

y cleanup
Inicializacion
comunes cuando se utilizan libreras es no inicializar
Uno de los errores mas
y destruir (cleanup) apropiadamente los objetos. En las libreras que hemos
descripto hasta ahora esto se haca con funciones initialize() y cleanup().
Una de las ideas que C++ toma de la OOP es que estas operaciones de
y cleanup se hagan en forma automatica.

inicializacion
1
2
3
4
5
6
7
8
9
10

class A {
// . . .
};
void f() {
A a; // a is created -> do initialization
// Usar a . . .
// . . .
// . . .
} // a is destroyed -> do cleanup

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 190

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

y cleanup (cont.)
Inicializacion
y otra de cleanup)
Para esto debe haber dos funciones (una de inicializacion

que tengan nombres especiales ya que deben ser llamadas automaticamente


por el compilador. En C++ estas funciones se llaman el constructor y el
destructor de la clase. El constructor tiene el mismo nombre que la clase y
puede tener argumentos
1
2
3
4
5
6
7
8
9
10
11

class A {
public:
A() { /*. . .*/ }
// . . .
};
void f() {
A a; // a is created -> calls ctor A::A()
// Usar a . . .
// . . .
}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 191

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

El constructor
El ctor puede tener argumentos y puede haber varios constructores. Cual

de ellos es utilizado depende del contexto en el que es llamado.


El ctor que no tiene argumentos se llama el constructor por defecto.
No retorna ningun
valor.
Debe ser declarado public para que pueda ser utilizado.
Puede ser privado pero entonces al menos debe tener una clase amiga ya
que si no no se podra construir ningun
objeto de la clase.
Si no declaramos ningun
constructor entonces el compilador sintetiza
uno por nosotros y que es el constructor por defecto. Este ctor por
defecto no tiene cuerpo, lo unico

que hace es llamar a los ctores por


defecto de cada uno de los miembros (si son clases).

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 192

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

El destructor
Asi como el constructor garantiza que se llama a la rutina de

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

el destructor (abreviado dtor) se encarga de realizar las


inicializacion,
tareas de cleanup.

Es llamado automaticamente
cuando termina el scope del objeto.

// Constructors & destructors


#include <iostream>
using namespace std;
class Tree {
int height;
public:
Tree(int initialHeight); // Constructor
Tree(); // Destructor
void grow(int years);
void printsize();
};
Tree::Tree(int initialHeight) {
height = initialHeight;
}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 193

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

Tree::Tree() {
cout << "inside Tree destructor" << endl;
printsize();
}
void Tree::grow(int years) {
height += years;
}
void Tree::printsize() {
cout << "Tree height is " << height << endl;
}
int main() {
cout << "before opening brace" << endl;
{
Tree t(12);
cout << "after Tree creation" << endl;
t.printsize();
t.grow(4);
cout << "before closing brace" << endl;
}
cout << "after closing brace" << endl;
} ///:

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 194

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

El destructor (cont.)
Salida del programa:
1
2
3
4
5
6
7

before opening brace


after Tree creation
Tree height is 12
before closing brace
inside Tree destructor
Tree height is 16
after closing brace

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 195

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

del bloque de definicion

Eliminacion
Es tpico de C tener que definir todas las variables al principio de un scope

(por ejemplo de una funcion).


Por el contrario C++ promueve que las variables
cerca posible del punto en el que van a ser usadas. Esto se
se definan lo mas

pega con el uso automatico


de constructores, ya que puede ser que el
como para llamar al constructor.
compilador no tenga toda la informacion
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

// Defining variables anywhere


#include ". ./require.h"
#include <iostream>
#include <string>
using namespace std;
class G {
int i;
public:
G(int ii);
};
G::G(int ii) { i = ii; }
int main() {
cout << "initialization value? ";

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 196

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

17
18
19
20
21
22

int retval = 0;
cin >> retval;
require(retval != 0);
int y = retval + 3;
G g(y);

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 197

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Clase stash con ctor/dtor


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

// With constructors & destructors


class Stash {
int size; // Size of each space
int quantity; // Number of storage spaces
int next; // Next empty space
// Dynamically allocated array of bytes:
unsigned char* storage;
void inflate(int increase);
public:
Stash(int size);
Stash();
int add(void* element);
void* fetch(int index);
int count();
};

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 198

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Clase stash con ctor/dtor (cont.)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

//: C06:Stash2.cpp {O}


// Constructors & destructors
#include "Stash2.h"
#include ". ./require.h"
#include <iostream>
#include <cassert>
using namespace std;
const int increment = 100;
Stash::Stash(int sz) {
size = sz;
quantity = 0;
storage = 0;
next = 0;
}
int Stash::add(void* element) {
if(next >= quantity) // Enough space left?
inflate(increment);
// Copy element into storage,
// starting at next empty space:
int startBytes = next * size;

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 199

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

unsigned char* e = (unsigned char*)element;


for(int i = 0; i < size; i++)
storage[startBytes + i] = e[i];
next++;
return(next - 1); // Index number

}
void* Stash::fetch(int index) {
require(0 <= index, "Stash::fetch (-)index");
if(index >= next)
return 0; // To indicate the end
// Produce pointer to desired element:
return &(storage[index * size]);
}
int Stash::count() {
return next; // Number of elements in CStash
}
void Stash::inflate(int increase) {
require(increase > 0,
"Stash::inflate zero or negative increase");
int newQuantity = quantity + increase;
int newBytes = newQuantity * size;
int oldBytes = quantity * size;

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 200

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

48
49
50
51
52
53
54
55
56
57
58
59
60
61

unsigned char* b = new unsigned char[newBytes];


for(int i = 0; i < oldBytes; i++)
b[i] = storage[i]; // Copy old to new
delete [ ](storage); // Old storage
storage = b; // Point to new memory
quantity = newQuantity;

}
Stash::Stash() {
if(storage != 0) {
cout << "freeing storage" << endl;
delete [ ]storage;
}
}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 201

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Stack con ctor/dtor


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

// With constructors/destructors
#ifndef STACK3-H
#define STACK3-H

class Stack {
struct Link {
void* data;
Link* next;
Link(void* dat, Link* nxt);
Link();
}* head;
public:
Stack();
Stack();
void push(void* dat);
void* peek();
void* pop();
};

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 202

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Stack con ctor/dtor (cont.)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

#include "Stack3.h"
#include ". ./require.h"
using namespace std;
Stack::Link::Link(void* dat, Link* nxt) {
data = dat;
next = nxt;
}
Stack::Link::Link() { }
Stack::Stack() { head = 0; }
void Stack::push(void* dat) {
head = new Link(dat,head);
}
void* Stack::peek() {
require(head != 0, "Stack empty");
return head->data;
}
void* Stack::pop() {
if(head == 0) return 0;

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 203

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

25
26
27
28
29
30
31
32
33
34

void* result = head->data;


Link* oldHead = head;
head = head->next;
delete oldHead;
return result;

}
Stack::Stack() {
require(head == 0, "Stack not empty");
} ///:

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 204

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

de agregados
Initializacion
Agregados son arreglos, estructuras y clases. Arreglos son de elementos

de un solo tipo, estructuras y clases puede ser de elementos de diferente


tipo.
Cuando se define un arreglo se puede inicializar con un juego de valores
entre llaves.

int a[5] = { 1, 2, 3, 4, 5 };

Inicializa cada uno de las posiciones de a en base a los valores entre


llaves.
a partir del
Inicializa el primero a partir de 17 y todos los demas
constructor por defecto

int b[6] = {17};

Conteo automatico:
automaticamente
dimensiona c como c[4] a partir del

numero

de elementos entre llaves.

int c[ ] = { 1, 2, 3, 4 };

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 205

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

de estructuras
Inicializacion
1
2
3
4
5
6
7

struct X {
int i;
float f;
char c;
};
X x1 = { 1, 2.2, c };

Se pueden inicializar un arreglo de X al mismo tiempo con doble llaves.


1

X x2[3] = { {1, 1.1, a}, {2, 2.2, b} };

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 206

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Sobrecarga de funciones
Vimos que el compilador decora los nombres de las funciones que

con el nombre de la clase


pertenecen a una clase (metodos)
1
2

void f();
class X { void f(); };

Aca los nombres de las f no colisionan ya que son en realildad ::f() y X::f().
decora los nombres de las funciones con el tipo de
El compilador tambien
sus argumentos de manera que
1
2

void print(char);
void print(float);

no colisionan entre s. (En C esto dara un error.) Esto se llama sobrecargar el


(en este caso print()). Sobrecargar quiere decir
nombre de la funcion
entonces usar un mismo nombre para varias cosas diferentes.
NO se puede sobrecargar funciones por el valor de retorno.
Atencion:
1
2

int f(char c,double x);


char f(char c,double x); // ERROR!

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 207

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Sobrecarga de funciones (cont.)


Si compilamos y corremos la utilidad nm al archivo objeto nos da el nombre

interno de la funcion
1
2
3
4
5

[mstorti@galileo garage]$ nm try22.o


U --cxa-atexit
U --dso-handle
0000000000000010 T main
0000000000000000 T -Z1fcd <- This is int f(char c,double d)

El mangling _Z1fcd hace que el nombre del del archivo objeto sea unico.

El
lenguaje C no hace mangling, por eso no se puede sobrecargar.

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 208

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Sobrecarga de funciones (cont.)

El nombre mangleado es difcil de identificar con respecto a la funcion


nm -C permite obtener un nombre mas
legible. Esto es muy
original. La opcion
o no. Por
util
cuando queremos buscar si una librera tiene una dada funcion
otro lado el mangling puede depender del sistema y del compilador, lo cual va
en contra de la portabilidad. Es decir no es posible transferir una librera de
C++ compilado con un dado compilador a otro.
1
2
3
4

[mstorti@galileo
00000000000002d4
0000000000000000
[mstorti@galileo

garage]$ nm -C try22.o | grep f


t -GLOBAL--sub-I--Z1fcd
T f(char, double)
garage]$

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 209

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Sobrecarga de funciones (cont.)


Por lo tando, cuando definimos varios ctores, estamos sobrecargando el
nombre del ctor.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

class Stash {
int size; // Size of each space
int quantity; // Number of storage spaces
int next; // Next empty space
// Dynamically allocated array of bytes:
unsigned char* storage;
void inflate(int increase);
public:
Stash(int size); // Zero quantity
Stash(int size, int initQuantity);
Stash();
int add(void* element);
void* fetch(int index);
int count();
};

del stash a partir del segundo


Ahora el ctor Stash(int,int) inicializa el tamano
argumento. En cambio recordemos que Stash(int) dejaba al stash vaco.
Facultad de Ingeniera y Ciencias Hdricas FICH - UNL
((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 210

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Argumentos por default


Otra posibilidad es que los dos ctores previos sean el mismo con un

argumento por default para el tamano


1

Stash(int size, int initQuantity = 0);

Entonces cuando se usa


1

Stash A(100), B(100, 2000);

En el primer llamado es equivalente a A(100,0)

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 211

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Constantes
Objetos de los cuales se supone que su valor no va a variar se pueden definir
como constantes
1
2

#define BUFSIZE 100 // en C


const int bufsize = 100; // en C++ (preferible)

En el caso de querer ponerlo en un header hay que usar


1
2
3

extern const int bufsize; // en un header


...
const int bufsize = 100; // en el .cpp

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 212

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Constantes (cont.)
Otro uso de const es para prometerle al compilador que no se va a modificar
esa variable, especialmente con punteros
1

const int* u;

Declara que u es un puntero a un int que es constante. De manera que si el


compilador detecta que estamos modificando al entero apuntado dara un
error
1
2
3
4

int x = 23;
const int* u;
u = &x;
*u = 55; // ERROR!

Notar que lo que es constante es el valor apuntado, no el puntero en si


mismo, el cual es modificado al hacer u = &x. Si queremos que el puntero sea
constante entonces hay que hacer
1
2
3
4

int x = 23, z=45;


int* const u = &x;
u = &z; // ERROR!
*u = 55; // OK, modifica x

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 213

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Constantes (cont.)
pueden ser constantes las dos cosas, el puntero y el objeto
Tambien
1
2

const int x = 32;


const int* const u = &x;

C/C++ chequea los tipos, tambien la constancia


1
2
3
4
5
6

int d = 1;
const int e = 2;
int* u = &d; // OK -- d not const
int* v = &e; // ERROR! -- e const
int* w = (int*)&e; // Legal but bad practice
const int* z = &e; // OK

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 214

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Punteros a arreglos constantes de caracteres


1

char* cp = "Hello world"; // warning!!

Como el arreglo de caracteres no fue alocado con new, es constante, o sea


que debe ser declarado as
1

const char* cp = "Hello world"; // OK

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 215

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Const en argumentos de funciones


1
2
3

void f(const int i) {


i++; // Illegal -- compile-time error
}

De todas formas no tiene demasiado sentido porque i es pasado por copia.


Pero s tiene sentido cuando se pasan argumentos por referencia o por
puntero
1
2
3
4
5
6
7

void f(const int *p) {


*p = 23; // ERROR!
}
void g(const int &x) {
x = 23; // ERROR!
}

Recordar que pasar por puntero o referencia puede ser para modificar el valor
para evitar la copia. Incluyendo el const permite pasar los
o tambien
argumentos en forma eficiente, pero evitando que accidentalmente se
modifique el objeto.

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 216

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Const en clases

Si se quiere tener parametros


de una clase, que son constantes, entonces no
hay que ponerle const, sino tambien
static que quiere decir que ese
solo
miembro es el mismo para todos los objetos de la clase. De esa forma actua

como una variable global pero protegida por el scope de la clase. Sirve para
definir opciones de la clase para poder ser inspeccionadas o modificadas por
el usuario.
1
2
3
4
5
6
7
8
9

class StringStack {
static const int size = 100;
const string* stack[size];
int index;
public:
StringStack();
void push(const string* s);
const string* pop();
};

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 217

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Objetos const y funciones de la clase


Si tenemos una clase A entonces al declarar funciones as
1
2

void f(const A &a);


void g(const A *p);

estamos diciendo que no van a modificar el argumento correspondiente.

Como hacer lo mismo con los metodos


de la clase para decir que no
modifican al objeto que son aplicados (*this)?
1
2
3
4
5
6

class A {
public:
void f() const;
void g();
};
void A::f() const { /* . . . */ }

Quiere decir que si hacemos


1
2

A a;
a.f();

podemos estar seguros que la llamada a f() no modifica a a.


Facultad de Ingeniera y Ciencias Hdricas FICH - UNL
((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 218

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Objetos const y funciones de la clase (cont.)


pueden ser
Entonces el compilador chequea que si un objeto es const solo

llamados sobre el funciones y metodos


que no lo modifican, es decir que lo
declaran const.
1
2
3
4
5
6
7
8
9
10
11
12

const A a1;
a1.f(); // OK, f es const
a1.g(); // ERROR, g no es const
void h(A &a) {
a.g(); // OK a no es const
}
void h2(const A &a) {
a.f(); // OK, f es const
a.g(); // ERROR, g no es const
}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 219

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Chapter 5

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 220

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Funciones inline
hay un costo adicional de pasar
Cada vez que hay una llamada a funcion

y hacer un jump de assemble.


los argumentos por el stack a la funcion
Para evitar esto podemos usar el keyword inline que indica al compilador

sea replicado en cada punto


que queremos que el codigo
de esa funcion
en que lo llamamos.
La ventaja, como dijimos, es la eficiencia, se evita el mecanismo de
en assemble.
llamado a funcion

aparece duplicado en
La desventaja es que el codigo
binario de la funcion
grande. Tambien

cada punto, con lo cual el ejecutable se hace mas

debe ser visible (o sea estar en el


implica que el codigo
de la funcion
header) en cada punto en que queremos que sea implementado inline.
El keyword inline es una sugerencia para el compilador. El compilador
hacer la funcion
realmente inline o no. A veces puede
puede despues
hacerla no inline porque es muy compleja (e.g. tiene lazos) o porque en
de la funcion.

algun
punto se toma la direccion
Funciones definidas en la misma clase (y por lo tanto en el header
normalmente) son candidatas a ser promovidas a inline por el compilador.

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 221

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Funciones inline (cont.)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

// file: a.hpp
// max es explicitamente inline
// (Notar que si no es inline daria error
// al linkeditar por multiple definicion de max())
inline double max(double x,double y) {
return (x>y ? x : y);
}
class A {
private:
int maxsize;
public:
// Accessors: automaticamente inline
int get-maxsize() { return maxsize; }
void set-maxsize(int maxsz) { maxsize=maxsz; }
//. . .
};

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 222

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Funciones inline (cont.)


Otra forma que habra para evitar el llamado a funciones sera no definir la
sino que en cada punto que se usa incluir explcitamente su codigo.

funcion
Para evitar esto una forma que exista en C para crear las funciones inline era
definir macros, por ejemplo
1

#define MAX(x,y) (x>y ? x : y)

Recordar que eso hace que en cada punto del codigo


final se reemplaze la
del macro.
llamada a MAX por la expansion

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 223

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Funciones inline (cont.)


OJO, como pasa en general con los macros son peligrosos, Por ejemplo
1 int l = MAX(j++,k);
tiene el efecto indeseado que incrementa dos veces a j.
Otro problema es con la precedencia de los operadores.

1 #define SQUARE(x) x*x


2 . . .
3 // Hace a=11!!
4 a = SQUARE(5+1)

ya que es completamente equivalente a


1

a = 5+1*5+1
apropiada se obtiene protegiendo los argumentos con
La definicion

parentesis.

#define SQUARE(x) (x)*(x)

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 224

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Especificaciones de linkedicion
digamos
Cuando declaramos una funcion,
1

void f(int x, char c);

se llama a esto
dijimos que internamente el compilador la decora (tambien

mangling) a, por ejemplo, _Z1fcd. Esto es a efectos de poder despues


Ahora bien, si queremos usar una librera de C,
sobrecargar la funcion.

entonces esta
cuando fue compilada no hizo el mangling, y por lo tanto
cuando se va a linkeditar no la va a encontrar. Para eso hay que usar el

keyword extern al declarar la funcion


1

extern "C" void f(int x, char c);

Notar que
Esto le dice al compilador que no decore el nombre de esa funcion.
no puede ser sobrecargada.
por lo tanto esa funcion

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 225

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Especificaciones de linkedicion (cont.)


en headers de esas libreras,
Como las declaraciones de las libreras estaran
como hacemos para ponerle un extern "C" a cada una de las funciones del
header? Basta con hacerlo externo al include
1
2
3

extern "C" {
#include <clibheader.h>
}

Muchos de los headers de libreras de C importantes ya vienen con este tipo


de declaraciones de forma de poder ser llamados desde C++, por ejemplo
todas las de la libc.

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 226

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Referencias en C++

Vimos el concepto de referencia, basicamente


son punteros inteligentes que
se autodereferencian.
Se pueden implementar funciones que modifican sus argumentos mediante
punteros
1
2
3
4
5
6

void inc(int *x) {


*x = *x + 1,
}
...
int a=2;
inc(&a); // hace a=3

pero son engorrosos porque hay que ir derereferenciando el puntero. Con


referencias es mucho mejor,
1
2
3
4
5
6

void inc(int &x) {


x = x + 1,
}
...
int a=2;
inc(a); // hace a=3

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 227

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Referencias en C++ (cont.)


Otro uso es para crear aliases locales para modificar una parte de un
grande, por ejemplo un arreglo de varias dimensiones
contenedor mas
puede ser con los contenedores de las STL)
(tambien
1
2
3
4
5
6
7
8
9
10
11

class A {
// . . . .
void f(); // modifica a *this
};
// arreglo multidimensional de As
A av[100][100][100];
// Un elemento particular de av
int i,j,k;
//. . .
av[i][j][k].f();

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 228

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Referencias en C++ (cont.)


Si queremos manipular mucho a ese elemento particular de av entonces en
cada punto hay que poner av[i][j][k]. Si fuera un tipo simple, como un int o
pisar el valor
un double, entonces podramos crear una copia local y despues
en av
1
2
3
4
5
6
7

// arreglo multidimensional de As
int v[100][100][100];
// Un elemento particular de av
int x = av[i][j][k];
// . . . hace calculos con x
// Pisa el valor en av
av[i][j][k] = x;

Pero si A es una clase complicada esto implica hacer una copia del objeto, lo
cual es ineficiente y incluso puede ser que no podamos hacer copias del
objeto.

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 229

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Referencias en C++ (cont.)


De nuevo, una posibilidad es usar macros
1
2
3
4
5
6
7

// arreglo multidimensional de As
A av[100][100][100];
// Un elemento particular de av
int i,j,k;
#define AIJK av[i][j][k]
//. . .
AIJK.f();

Como siempre, los macros son peligrosos y hay que tratar de no usarlos.
cada vez que llamamos a AIJK estamos haciendo una cuenta con
Ademas
correspondiente en v.
i,j,k para encontrar la posicion

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 230

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Referencias en C++ (cont.)


Una posibilidad es usar punteros
1
2
3
4
5
6
7

// arreglo multidimensional de As
A av[100][100][100];
// Un elemento particular de av
int i,j,k;
A *ap = &av[i][j][k];
ap->f();

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 231

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Referencias en C++ (cont.)


Esto es eficiente, y compacto pero hay que andar dereferenciando ap. Todava
mejor es usar referencias
1
2
3
4
5
6
7

// arreglo multidimensional de As
A av[100][100][100];
// Un elemento particular de av
int i,j,k;
A &a = av[i][j][k];
a.f();

de la clase.
Es eficiente, limpio, y a se manipula como un objeto mas

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 232

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Reglas para las referencias


Las referencias deben ser inicializadas cuando son creadas
1 A &a = av[i][j][k]; // OK
2
3 A &a; // ERROR (No incluye inicializacion)
4 a = av[i][j][k];
Una vez que una referencia apunta a un objeto, no se lo puede hacer
apuntar a otro
1
2
3
4

A &a = av[i][j][k];
a = av[l][m][n]; // compila OK, pero no reposiciona
// la referencia, simplemente hace
// una copia del elemento l,m,n al i,j,k

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 233

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Reglas para las referencias (cont.)


Lo que SI se puede hacer es ir creando referencias con el mismo nombre a
diferentes objetos
1
2
3
4
5
6
7
8

for (int i=0; i<N; i++) {


for (int j=0; j<N; j++) {
for (int k=0; k<N; k++) {
A &a = av[i][j][k];
// manipula av[i][j][k] a trav
es de a
}
}
}

No se puede hacer una referencia a NULL.


Hacer referencias es muy eficiente, igual que con punteros.

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 234

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Paso por referencia y por copia


Normalmente uno escribe el paso de argumentos por copia
1

void f(A a, B b) {. . .}

requiere que las clases A, B implementen el


Esto es ineficiente y ademas
constructor por copia A(A&), B(B&) (en general se le llama X(X&)).
1
2
3
4

class A {
//. . .
A(A&) { . . . } // Constructor por copia
};

Para evitar esto ya mencionamos que se puede pasar por referencia


1

void f(A &a, B &b) {. . .}

no va a modificar los argumentos es todava mejor declarar a las


Si la funcion
referencias como const
1

void f(const A &a,const B &b) {. . .}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 235

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

El constructor por copia


Vimos que al pasar objetos a funciones por copia se llama al constructor

1
2
3
4
5
6
7

por copia.
Si la clase no define al constructor por copia el compilador sintetiza uno
por nosotros (haciendo copia bit-a-bit).
con una deep copy) y
Esto se llama una shallow copy (por contraposicion

puede traer problemas, sobre todo si el objeto contiene punteros a areas

de almacenamiento dinamico
alocados con new.
O bien hay que implementar el constructor por copia haciendo la deep
copy o bien hay que prohibirlo declarando al constructor por copia
privado

class A {
private:
A(A&) {}
}
void f(A a) { // ERROR, llama al ctor por copia
}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 236

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Sobrecarga de operadores

Sobrecarga de operadores es simplemente un aditivo sintactico


(sintactic

sugar) para hacer llamadas a funciones de la clase en forma mas


compacta.
Los nombres de los operadores son operator@ donde @ puede ser algunos

[], (),
de los operadores usuales, matematicos
(+, -, *, /), de indexacion
(+=, -=, *=, /=), logicos

incremento ++, --, acumulacion


||, &&, etc...
Hay operadores unarios y binarios. A veces el mismo operador puede ser
unario o binario dependiendo del contexto (por ejemplo *
como unario, producto como binario), +, -).
(dereferenciacion
de los operadores es llamado y sobre que objetos es a veces un
Cual
poco difcil de discernir.

Pueden ser metodos


de la clase o pueden ser funciones globales
(declaradas friend)

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 237

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Sobrecarga de operadores (cont.)


En el caso de operadores unarios, el objeto al cual se aplica el operador pasa
a ser *this
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

class A {
A operator*(const A& right) { . . . } // producto (1)
};
class HandleToA {
A &operator*() { . . . } // dereferenciacion (2)
};
A a1, a2, a3;
HandleToA p;
a1 = a2*a3; // llama a (1) con *this = a2,
// right = a3 y el valor de retorno
// es asignado a a1
a1 = *p; // llama a (2) con *this = p

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 238

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Sobrecarga de operadores (cont.)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

#include <iostream>
using namespace std;
class Integer {
int i;
public:
Integer(int ii) : i(ii) {}
const Integer
operator+(const Integer& rv) const {
cout << "operator+" << endl;
return Integer(i + rv.i);
}
Integer&
operator+=(const Integer& rv) {
cout << "operator+=" << endl;
i += rv.i;
return *this;
}
};
int main() {
cout << "built-in types:" << endl;

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 239

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

23
24
25
26
27
28

int i = 1, j = 2, k = 3;
k += i + j;
cout << "user-defined types:" << endl;
Integer ii(1), jj(2), kk(3);
kk += ii + jj;

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 240

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Sobrecarga de operadores (cont.)


Se pueden sobrecargar buena parte de los operadores que ya existen en C.
No se pueden inventar nuevos operadores (e.g. usar ** para la

como en Fortran).
exponenciacion,
No se puede cambiar la regla de precedencia de los operadores.

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 241

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Sobrecarga de operadores unarios


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

#include <iostream>
using namespace std;
// Non-member functions:
class Integer {
long i;
Integer* This() { return this; }
public:
Integer(long ll = 0) : i(ll) {}
// No side effects takes const& argument:
friend const Integer&
operator+(const Integer& a);
friend const Integer
operator-(const Integer& a);
friend const Integer
operator(const Integer& a);
friend Integer*
operator&(Integer& a);
friend int
operator!(const Integer& a);
// Side effects have non-const& argument:

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 242

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

// Prefix:
friend const Integer&
operator++(Integer& a);
// Postfix:
friend const Integer
operator++(Integer& a, int);
// Prefix:
friend const Integer&
operator--(Integer& a);
// Postfix:
friend const Integer
operator--(Integer& a, int);
};
// Global operators:
const Integer& operator+(const Integer& a) {
cout << "+Integer\n";
return a; // Unary + has no effect
}
const Integer operator-(const Integer& a) {
cout << "-Integer\n";
return Integer(-a.i);
}
const Integer operator(const Integer& a) {

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 243

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68

cout << "Integer\n";


return Integer(a.i);

}
Integer* operator&(Integer& a) {
cout << "&Integer\n";
return a.This(); // &a is recursive!
}
int operator!(const Integer& a) {
cout << "bang Integer\n";
return !a.i;
}
// Prefix; return incremented value
const Integer& operator++(Integer& a) {
cout << "++Integer\n";
a.i++;
return a;
}
// Postfix; return the value before increment:
const Integer operator++(Integer& a, int) {
cout << "Integer++\n";
Integer before(a.i);
a.i++;
return before;

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 244

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93

}
// Prefix; return decremented value
const Integer& operator--(Integer& a) {
cout << "--Integer\n";
a.i--;
return a;
}
// Postfix; return the value before decrement:
const Integer operator--(Integer& a, int) {
cout << "Integer--\n";
Integer before(a.i);
a.i--;
return before;
}
// Show that the overloaded operators work:
void f(Integer a) {
+a;
-a;
a;
Integer* ip = &a;
!a;
++a;
a++;
--a;

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 245

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117

a--;

}
// Member functions (implicit this):
class Byte {
unsigned char b;
public:
Byte(unsigned char bb = 0) : b(bb) {}
// No side effects: const member function:
const Byte& operator+() const {
cout << "+Byte\n";
return *this;
}
const Byte operator-() const {
cout << "-Byte\n";
return Byte(-b);
}
const Byte operator() const {
cout << "Byte\n";
return Byte(b);
}
Byte operator!() const {
cout << "bang Byte\n";
return Byte(!b);

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 246

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141

}
Byte* operator&() {
cout << "&Byte\n";
return this;
}
// Side effects: non-const member function:
const Byte& operator++() { // Prefix
cout << "++Byte\n";
b++;
return *this;
}
const Byte operator++(int) { // Postfix
cout << "Byte++\n";
Byte before(b);
b++;
return before;
}
const Byte& operator--() { // Prefix
cout << "--Byte\n";
--b;
return *this;
}
const Byte operator--(int) { // Postfix
cout << "Byte--\n";

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 247

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165

Byte before(b);
--b;
return before;

}
};
void g(Byte b) {
+b;
-b;
b;
Byte* bp = &b;
!b;
++b;
b++;
--b;
b--;
}
int main() {
Integer a;
f(a);
Byte b;
g(b);
} ///:

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 248

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Sobrecarga de operadores unarios (cont.)


Operadores ++ y -- prefijo y postfijo: Recordemos que hay dos versiones del
operador ++, cuando hacemos i++ y ++i, ambos se pueden sobrecargar con el
operador operator++() pero como hacer para diferenciarlos? El prefijo es
operator++() y el postfijo es operator++(int). Notar que el argumento int para
el postfijo no se usa y por lo tanto no hace falta pasarle el argumento dummy
correspondiente.

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 249

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Sobrecarga de operadores binarios


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

// Non-member overloaded operators


#include <iostream>
// Non-member functions:
class Integer {
long i;
public:
Integer(long ll = 0) : i(ll) {}
// Operators that create new, modified value:
friend const Integer
operator+(const Integer& left,
const Integer& right);
friend const Integer
operator-(const Integer& left,
const Integer& right);
friend const Integer
operator*(const Integer& left,
const Integer& right);
friend const Integer
operator/(const Integer& left,
const Integer& right);

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 250

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

friend const Integer


operator%(const Integer& left,
const Integer& right);
friend const Integer
operator(const Integer& left,
const Integer& right);
friend const Integer
operator&(const Integer& left,
const Integer& right);
friend const Integer
operator|(const Integer& left,
const Integer& right);
friend const Integer
operator<<(const Integer& left,
const Integer& right);
friend const Integer
operator>>(const Integer& left,
const Integer& right);
// Assignments modify & return lvalue:
friend Integer&
operator+=(Integer& left,
const Integer& right);
friend Integer&

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 251

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67

operator-=(Integer& left,
const Integer& right);
friend Integer&
operator*=(Integer& left,
const Integer& right);
friend Integer&
operator/=(Integer& left,
const Integer& right);
friend Integer&
operator%=(Integer& left,
const Integer& right);
friend Integer&
operator=(Integer& left,
const Integer& right);
friend Integer&
operator&=(Integer& left,
const Integer& right);
friend Integer&
operator|=(Integer& left,
const Integer& right);
friend Integer&
operator>>=(Integer& left,
const Integer& right);

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 252

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91

friend Integer&
operator<<=(Integer& left,
const Integer& right);
// Conditional operators return true/false:
friend int
operator==(const Integer& left,
const Integer& right);
friend int
operator!=(const Integer& left,
const Integer& right);
friend int
operator<(const Integer& left,
const Integer& right);
friend int
operator>(const Integer& left,
const Integer& right);
friend int
operator<=(const Integer& left,
const Integer& right);
friend int
operator>=(const Integer& left,
const Integer& right);
friend int
operator&&(const Integer& left,

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 253

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116

const Integer& right);


friend int
operator| |(const Integer& left,
const Integer& right);
// Write the contents to an ostream:
void print(std::ostream& os) const { os << i; }
};
#endif // INTEGER-H ///:
//: C12:Integer.cpp {O}
// Implementation of overloaded operators
#include "Integer.h"
#include ". ./require.h"
const Integer
operator+(const Integer& left,
const Integer& right) {
return Integer(left.i + right.i);
}
const Integer
operator-(const Integer& left,
const Integer& right) {
return Integer(left.i - right.i);
}
const Integer

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 254

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139

operator*(const Integer& left,


const Integer& right) {
return Integer(left.i * right.i);

}
const Integer
operator/(const Integer& left,
const Integer& right) {
require(right.i != 0, "divide by zero");
return Integer(left.i / right.i);
}
const Integer
operator%(const Integer& left,
const Integer& right) {
require(right.i != 0, "modulo by zero");
return Integer(left.i % right.i);
}
const Integer
operator(const Integer& left,
const Integer& right) {
return Integer(left.i right.i);
}
const Integer
operator&(const Integer& left,

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 255

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162

const Integer& right) {


return Integer(left.i & right.i);

}
const Integer
operator|(const Integer& left,
const Integer& right) {
return Integer(left.i | right.i);
}
const Integer
operator<<(const Integer& left,
const Integer& right) {
return Integer(left.i << right.i);
}
const Integer
operator>>(const Integer& left,
const Integer& right) {
return Integer(left.i >> right.i);
}
// Assignments modify & return lvalue:
Integer& operator+=(Integer& left,
const Integer& right) {
if(&left == &right) {/* self-assignment */}
left.i += right.i;

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 256

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185

return left;

}
Integer& operator-=(Integer& left,
const Integer& right) {
if(&left == &right) {/* self-assignment */}
left.i -= right.i;
return left;
}
Integer& operator*=(Integer& left,
const Integer& right) {
if(&left == &right) {/* self-assignment */}
left.i *= right.i;
return left;
}
Integer& operator/=(Integer& left,
const Integer& right) {
require(right.i != 0, "divide by zero");
if(&left == &right) {/* self-assignment */}
left.i /= right.i;
return left;
}
Integer& operator%=(Integer& left,
const Integer& right) {

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 257

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208

require(right.i != 0, "modulo by zero");


if(&left == &right) {/* self-assignment */}
left.i %= right.i;
return left;

}
Integer& operator=(Integer& left,
const Integer& right) {
if(&left == &right) {/* self-assignment */}
left.i = right.i;
return left;
}
Integer& operator&=(Integer& left,
const Integer& right) {
if(&left == &right) {/* self-assignment */}
left.i &= right.i;
return left;
}
Integer& operator|=(Integer& left,
const Integer& right) {
if(&left == &right) {/* self-assignment */}
left.i |= right.i;
return left;
}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 258

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231

Integer& operator>>=(Integer& left,


const Integer& right) {
if(&left == &right) {/* self-assignment */}
left.i >>= right.i;
return left;
}
Integer& operator<<=(Integer& left,
const Integer& right) {
if(&left == &right) {/* self-assignment */}
left.i <<= right.i;
return left;
}
// Conditional operators return true/false:
int operator==(const Integer& left,
const Integer& right) {
return left.i == right.i;
}
int operator!=(const Integer& left,
const Integer& right) {
return left.i != right.i;
}
int operator<(const Integer& left,
const Integer& right) {

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 259

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255

return left.i < right.i;

}
int operator>(const Integer& left,
const Integer& right) {
return left.i > right.i;
}
int operator<=(const Integer& left,
const Integer& right) {
return left.i <= right.i;
}
int operator>=(const Integer& left,
const Integer& right) {
return left.i >= right.i;
}
int operator&&(const Integer& left,
const Integer& right) {
return left.i && right.i;
}
int operator| |(const Integer& left,
const Integer& right) {
return left.i | | right.i;
} ///:
//: C12:IntegerTest.cpp

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 260

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279

//{L} Integer
#include "Integer.h"
#include <fstream>
using namespace std;
ofstream out("IntegerTest.out");
void h(Integer& c1, Integer& c2) {
// A complex expression:
c1 += c1 * c2 + c2 % c1;
#define TRY(OP) \
out << "c1 = "; c1.print(out); \
out << ", c2 = "; c2.print(out); \
out << "; c1 " #OP " c2 produces "; \
(c1 OP c2).print(out); \
out << endl;
TRY(+) TRY(-) TRY(*) TRY(/)
TRY(%) TRY() TRY(&) TRY(|)
TRY(<<) TRY(>>) TRY(+=) TRY(-=)
TRY(*=) TRY(/=) TRY(%=) TRY(=)
TRY(&=) TRY(|=) TRY(>>=) TRY(<<=)
// Conditionals:
#define TRYC(OP) \
out << "c1 = "; c1.print(out); \
out << ", c2 = "; c2.print(out); \

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 261

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303

out << "; c1 " #OP " c2 produces "; \


out << (c1 OP c2); \
out << endl;
TRYC(<) TRYC(>) TRYC(==) TRYC(!=) TRYC(<=)
TRYC(>=) TRYC(&&) TRYC(| |)

}
int main() {
cout << "friend functions" << endl;
Integer c1(47), c2(9);
h(c1, c2);
} ///:
//: C12:Byte.h
// Member overloaded operators
#ifndef BYTE-H
#define BYTE-H
#include ". ./require.h"
#include <iostream>
// Member functions (implicit this):
class Byte {
unsigned char b;
public:
Byte(unsigned char bb = 0) : b(bb) {}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 262

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327

// No side effects: const member function:


const Byte
operator+(const Byte& right) const {
return Byte(b + right.b);
}
const Byte
operator-(const Byte& right) const {
return Byte(b - right.b);
}
const Byte
operator*(const Byte& right) const {
return Byte(b * right.b);
}
const Byte
operator/(const Byte& right) const {
require(right.b != 0, "divide by zero");
return Byte(b / right.b);
}
const Byte
operator%(const Byte& right) const {
require(right.b != 0, "modulo by zero");
return Byte(b % right.b);
}
const Byte

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 263

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350

operator(const Byte& right) const {


return Byte(b right.b);

}
const Byte
operator&(const Byte& right) const {
return Byte(b & right.b);
}
const Byte
operator|(const Byte& right) const {
return Byte(b | right.b);
}
const Byte
operator<<(const Byte& right) const {
return Byte(b << right.b);
}
const Byte
operator>>(const Byte& right) const {
return Byte(b >> right.b);
}
// Assignments modify & return lvalue.
// operator= can only be a member function:
Byte& operator=(const Byte& right) {
// Handle self-assignment:

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 264

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373

if(this == &right) return *this;


b = right.b;
return *this;

}
Byte& operator+=(const Byte& right) {
if(this == &right) {/* self-assignment */}
b += right.b;
return *this;
}
Byte& operator-=(const Byte& right) {
if(this == &right) {/* self-assignment */}
b -= right.b;
return *this;
}
Byte& operator*=(const Byte& right) {
if(this == &right) {/* self-assignment */}
b *= right.b;
return *this;
}
Byte& operator/=(const Byte& right) {
require(right.b != 0, "divide by zero");
if(this == &right) {/* self-assignment */}
b /= right.b;

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 265

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396

return *this;

}
Byte& operator%=(const Byte& right) {
require(right.b != 0, "modulo by zero");
if(this == &right) {/* self-assignment */}
b %= right.b;
return *this;
}
Byte& operator=(const Byte& right) {
if(this == &right) {/* self-assignment */}
b = right.b;
return *this;
}
Byte& operator&=(const Byte& right) {
if(this == &right) {/* self-assignment */}
b &= right.b;
return *this;
}
Byte& operator|=(const Byte& right) {
if(this == &right) {/* self-assignment */}
b |= right.b;
return *this;
}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 266

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419

Byte& operator>>=(const Byte& right) {


if(this == &right) {/* self-assignment */}
b >>= right.b;
return *this;
}
Byte& operator<<=(const Byte& right) {
if(this == &right) {/* self-assignment */}
b <<= right.b;
return *this;
}
// Conditional operators return true/false:
int operator==(const Byte& right) const {
return b == right.b;
}
int operator!=(const Byte& right) const {
return b != right.b;
}
int operator<(const Byte& right) const {
return b < right.b;
}
int operator>(const Byte& right) const {
return b > right.b;
}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 267

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443

int operator<=(const Byte& right) const {


return b <= right.b;
}
int operator>=(const Byte& right) const {
return b >= right.b;
}
int operator&&(const Byte& right) const {
return b && right.b;
}
int operator| |(const Byte& right) const {
return b | | right.b;
}
// Write the contents to an ostream:
void print(std::ostream& os) const {
os << "0x" << std::hex << int(b) << std::dec;
}
};
#endif // BYTE-H ///:
//: C12:ByteTest.cpp
#include "Byte.h"
#include <fstream>
using namespace std;
ofstream out("ByteTest.out");

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 268

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468

void k(Byte& b1, Byte& b2) {


b1 = b1 * b2 + b2 % b1;
#define TRY2(OP) \
out << "b1 = "; b1.print(out); \
out << ", b2 = "; b2.print(out); \
out << "; b1 " #OP " b2 produces "; \
(b1 OP b2).print(out); \
out << endl;
b1 = 9; b2 = 47;
TRY2(+) TRY2(-) TRY2(*) TRY2(/)
TRY2(%) TRY2() TRY2(&) TRY2(|)
TRY2(<<) TRY2(>>) TRY2(+=) TRY2(-=)
TRY2(*=) TRY2(/=) TRY2(%=) TRY2(=)
TRY2(&=) TRY2(|=) TRY2(>>=) TRY2(<<=)
TRY2(=) // Assignment operator
// Conditionals:
#define TRYC2(OP) \
out << "b1 = "; b1.print(out); \
out << ", b2 = "; b2.print(out); \
out << "; b1 " #OP " b2 produces "; \
out << (b1 OP b2); \

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 269

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484

out << endl;


b1 = 9; b2 = 47;
TRYC2(<) TRYC2(>) TRYC2(==) TRYC2(!=) TRYC2(<=)
TRYC2(>=) TRYC2(&&) TRYC2(| |)
// Chained assignment:
Byte b3 = 92;
b1 = b2 = b3;

}
int main() {
out << "member functions:" << endl;
Byte b1(47), b2(9);
k(b1, b2);
} ///:

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 270

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Sobrecarga de operadores binarios (cont.)


(e.g. operator+=) se tiene que
En los operadores de acumulacion
1 Integer& operator+=(Integer& left,
2
const Integer& right) {
3
if(&left == &right) {/* self-assignment */}
4
left.i += right.i;
5
return left;
6 }
7 // . . .
8 Integer R,L;
9 L += R;
Tenemos que left es L, right es R. Hay que tener cuidado porque el L y R
podran ser el mismo objeto, por ejemplo si hacemos
1
2

Integer A;
A += A;
operator=(). A esto se le
Lo mismo pasa con el operador de asignacion
Sobre todo si hay componentes
llama chequear por autoasignacion.
apuntadas por punteros.

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 271

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Chapter

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 272

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Otros operadores que se pueden sobrecargar


operator[]: Se usa normalmente para emular lo que ocurre al indexar un

vector por un entero. En las STL se usa en las clases vector<> y map<>

operator(): Se usa para emular que el objeto actua


como una funcion
(functor).
operator*, operator->: Se utilizan para emular el comportamiento de los
punteros (por ejemplo los smart pointers). En las STL se usan para los
iterators de los diferentes contenedores.

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 273

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

dinamica

Creacion
de objetos
Las variables de un programa pueden ser alocados en tres formas diferentes
y normalmente viven en secciones diferentes de memoria

Objetos globales y estaticos


son alocados en el momento de arrancar el

del mismo.
programa y viven durante toda la duracion

Objetos dinamicos
son alocados al entrar en el scope correspondiente.
se hace en el stack.
La alocacion
Objetos pueden ser alocados y desalocados en cualquier momento
(responsabilidad del programador) en el heap.

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 274

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Uso de la memoria dinamica


en C
en el heap se hace con las funciones malloc() y free(). El
En C la alocacion

uso basico
para objetos en C sera as
1
2
3
4
5
6
7

struct A { };
A *p = (A*)malloc(sizeof(A));
A-initialize(p);
// . . . . usa *p
A-destroy(p);
free(p);

Hay varios puntos donde esto puede fallar, por un error del programador:

No alocar apropiadamente la memoria apropiada para el objeto.


No convertir el puntero al tipo apropiado.
No inicializar el objeto.
No destruir el objeto.
No liberar la memoria alocada.

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 275

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Uso de la memoria dinamica


en C++
En C++ se trata que todas estas acciones sean hechas en lo posible en forma

automatica
por el operador. Para esto las funciones malloc() y free() (que
de todo son funciones de librera es decir que no son parte del
despues
lenguaje) son reemplazadas por operadores intrnsecos del lenguaje: new y
delete.
1
2
3

A *p = new A;
// . . . usa *p
delete p;

new A se encarga de alocar el espacio apropiado (sizeof(A), castear al tipo


correcto (A*) e inicializar (llamar al constructor).
delete p se encarga de llamar al destructor y liberar la memoria alocada.

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 276

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Uso de la memoria dinamica


en C++ (cont.)
tambien
se puede llamar con
Como new se encarga de la inicializacion,
del ctor por defecto
cualquier otro constructor, ademas
1

A *p = new A(x,y,z);

se pueden alocar arreglos de objetos


Tambien
1

A *av = new A[100];

En este caso el compilador se encarga de alocar el espacio para los 100


objetos y llamar al constructor por defecto sobre cada uno de ellos. No hay
forma de inicializar arreglos con un constructor que no sea el ctor por defecto.
Recordar que para arreglos se puede inicializar explcitamente cada objeto
(pero no todos al mismo tiempo)
1

A av[4] = {1,2,3}

Para el cuarto (av[3]) usa el constructor por defecto.

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 277

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Porque usar new y no arreglos


1
2
3
4
5
6
7

A av1[20]; // OK la dimension es una cte


const int m=100;
A av1[m]; // OK la dimension es una cte
int n=100;
A a[n]; // ERROR

aunque dependiendo del


El ultimo

debera dar error de compilacion


del compilador). De
compilador puede que no lo de (sera una extension
restrictivo que alocar con new porque el arreglo
todas formas siempre es mas
es desalocado y destruido cuando termina su scope.

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 278

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Memory exhaust
Que ocurre si se acaba la memoria? En viejos compiladores new retornaba un

de tipo bad_alloc().
puntero nulo. En el estandar
actual lanza una excepcion
antigua se le puede usar new(std::nothrow)
Por compatibilidad con la version
que emula el primer comportamiento.
1
2
3
4
5
6
7
8
9
10
11
12
13

try { // version throw


int *p = new int[N];
// alocacion exitosa, usar p. . .
} catch(bad-alloc) {
cout << "error" << endl;
break;
}
// version nothrow
int *p = new(std::nothrow) int[N];
if (!p) {
// error. . .
}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 279

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Composicion
Hasta ahora vimos clases/estructuras que se construyen a partir de tipos

basicos
usando composicion.
1
2
3
4
5
6
7
8

class A {
private:
int i;
double x;
public:
char c;
void f();
};

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 280

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

(cont.)
Composicion
La idea es que las clases de objetos se pueden usar como nuevos tipos, por
de otros tipos
lo tanto se pueden usar en la composicion
1
2
3
4
5
6
7
8

class B {
private:
int k;
double z;
public:
A a;
void g();
};

En este caso B::a es publico,

de forma que los metodos


publicos

de A tambien
se pueden llamar sobre este campo, es decir
1
2

B b;
b.a.f(); // OK

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 281

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

y la cadena de inicializacion

Composicion
Hemos visto que en el constructor de la clase podemos inicializar sus
En particular tambien
se pueden
miembros en la cadena de inicializacion.
llamar constructores de los subobjetos que forman parte de la clase
1
2
3
4
5
6
7
8
9

class B {
private:
int k;
double z;
public:
B() : a(234,"jaja") { }
A a;
void g();
};

se pueden poner tanto constructores de


En la cadena de inicializacion
inicializar objetos built-in (int, double...) por copia.
subobjetos como tambien

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 282

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Herencia
complejas a partir de otras mas
simples es
Otra forma de elaborar clases mas
por herencia.
1
2
3
4
5
6

class C : public A {
int k;
double z;
public:
void g();
};

Se dice que C es una clase derivada de A y A es la clase base de C.

sobre C. en este caso


Los metodos
de A se pueden llamar ahora tambien
estamos diciendo C es como A pero tiene algunas cosas adicionales. Al hacer
estamos diciendo que C contiene a un objeto de tipo A.
composicion

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 283

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Herencia (cont.)
los miembros de A se acceden a traves

Notar que en el caso de composicion


de B::a, es decir por ejemplo
1
2

B b;
b.a.c = 5;

mientras que en el caso de herencia, no existe directamente el miembro B::a


de manera que los miembros de A pasan a ser directamente miembros de C
1
2

C c;
c.c = 7;

Al declarar en la herencia que A es publico,

todos los miembros y metodos


de
vistos a traves
de C con la privacidad que tenan en A, es decir C.c es
A seran
publico

y C.i es privado. Por el contrario, si declaramos


1

class C : private A { . . .

entonces todos los campos de A son privados.

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 284

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Herencia (cont.)
se pueden incluir en la nueva clase muchos
Notar que con composicion
objetos del mismo tipo o de diferente tipo, mientras que con herencia no es
usual derivar de varias clases al mismo tiempo.
1
2
3
4
5
6
7
8

class A { . . . . };
class X { . . . . };
class B {
A a1,a2;
X x;
// . . .
};

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 285

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

de metodos

Redefinicion

Que pasa si la clase derivada tiene un metodo


con el mismo nombre que la
no hay problema
clase base? Con composicion
1
2
3
4
5
6
7
8
9
10
11
12
13
14

class A {
public:
void f();
};
class B {
public:
A a;
void f();
};
B b;
b.f(); // llama la f de B
b.a.f(); // llama la f de A

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 286

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

de metodos

Redefinicion
(cont.)

Con herencia el nuevo metodo


redefine u oculta el metodo
anterior
1
2
3
4
5
6
7
8
9
10
11
12
13

class A {
public:
void f();
};
class B : public A {
public:
void f();
};
B b;
b.f(); // llama la f de B
b.A::f(); // llama la f de A

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 287

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Herencia protegida
Hay una forma de herencia que es intermedia entre publico

y privado, y es la

herencia protected. En este caso lo metodos


de la clase son privados para el
exterior pero pueden ser usados como publicos

por la base derivada.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

class Base {
int i;
protected:
int read() const { return i; }
void set(int ii) { i = ii; }
public:
Base(int ii = 0) : i(ii) {}
int value(int m) const { return m*i; }
};
class Derived : public Base {
int j;
public:
Derived(int jj = 0) : j(jj) {}
void change(int x) { set(x); }
};

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 288

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

18
19
20
21

int main() {
Derived d;
d.change(10);
}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 289

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Upcasting
El compilador nos deja sin problema castear un puntero de la clase derivada a
la clase base, porque sabe que la clase derivada tiene todas las cosas de la
base
1
2
3
4
5
6
7

class Base { //. . .


class Derived : public Base { . . .
Derived d1, d2;
Base &b = d1;
Base *p = &d2;

Esto se llama upcasting. Sin embargo, si llamamos a un metodo


de la clase
que esta implementado en las dos, llama al de la base.
1

p->f(); // llama a Base::f()

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 290

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Polimorfismo

Nosotros queremos definir clases base que son genericas


(por ejemplo

Matrix) y plantear algoritmos/operaciones genericos


para las mismas (por
ejemplo GradConj()). Estos algoritmos toman un puntero a la clase base y

llaman operaciones genericas


sobre la misma (por ejemplo el producto matriz
vector MatVec()). Luego podemos definir clases derivadas para las matrices

de distinto tipo (llena, banda, sparse, simetrica...)


La idea es que cuando el

algoritmo generico
GradConj() llama al metodo
MatVec()), esta
llamada sea
correspondiente en la clase derivada.
despachada a la funcion

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 291

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Polimorfismo (cont.)

Para que la llamada al metodo


sea despachada a la clase derivada debemos

declarar al metodo
virtual en la clase base.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

class Base {
public:
virtual void f();
//. . .
class Derived : public Base {
public:
void f();
//. . .
}
Derived d1, d2;
Base &b = d1;
b.f(); // llama a Derived::f()
Base *p = d2;
p->f(); // llama a Derived::f()

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 292

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Ejemplo polimorfismo. Integral 1D/2D/3D


Queremos calcular la integral de funciones en segmentos ([a, b]) en 1D y
productos cartesianos ([xa , xb ] [ya , yb ]) en 2D y 3D.

xb

f (x) dx,

I1 =
xa
yb

xb

f (x, y) dx dy,

I2 =
ya
zb

xa
yb

xb

I3 =

f (x, y, z) dx dy dz,
za

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

ya

xa

slide 293

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Ejemplo polimorfismo. Integral 1D/2D/3D (cont.)


Empecemos definiendo el tipo de funciones de una variable
1
2
3
4

class scalarfun1d-t {
public:
virtual double eval(double x)=0;
};

Notemos que el metodo


eval() esta declarado =0 eso quiere decir que no se
por lo tanto es una clase virtual pura es decir que no se
implementara,
es un prototipo del cual
pueden definir instancias de esta clase. Solo
ser integradas.
podremos derivar clases concretas que podran

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 294

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Ejemplo polimorfismo. Integral 1D/2D/3D (cont.)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

// LIBRARY CODE
class scalarfun1d-t {
public:
virtual double eval(double x)=0;
};
class integral1d-t {
public:
void set(int N, double a,double b,scalarfun1d-t *fxp);
double integral();
};
// USER CODE
class sin-fun-t {
public:
double eval(double x) { return sin(x); }
} sin-fun;
int main() {
integral1d-t int1d;
int1d.set(100,0,1,&sin-fun);

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 295

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

22
23
24
25

cout << "Integral of sin(x) in [0,1] is "


<< int1d.integral() << endl;
return 0

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 296

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Clase que calcula integral 1D


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

class integral1d-t {
private:
int N;
// Nbr of integration pts
double xa,xb;
// integration interval
scalarfun1d-t *fp; // ptr to function
public:
// Ctor, set values
integral1d-t(int Na=0,double xaa=NAN,
double xba=NAN,scalarfun1d-t *fpa=NULL) {
set(Na,xaa,xba,fpa);
}
// Set values
void set(int Na,double xaa,double xba,scalarfun1d-t *fpa) {
N=Na; xa=xaa; xb=xba; fp=fpa;
}
// Computes the integral using Simpsons rule
double integral() {
double
h = (xb-xa)/N,
h2 = h/2.0,

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 297

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

21
22
23
24
25
26
27
28
29
30
31
32
33

}
};

finteg=0.0;
for (int j=0; j<N; j++) {
double x = j*h;
double f = fp->eval(x);
finteg += 2.0*f;
finteg += 4.0*fp->eval(x+h2);
}
finteg -= fp->eval(xa);
finteg += fp->eval(xb);
finteg *= h/6.0;
return finteg;

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 298

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

cruda
Integral 2D. Version
de dos integrales simples
La integral doble la hacemos como composicion

yb

Z

xb


f (x, y) dx

I2 =
xa

ya
yb

Z
=

g(y) dy,

yb

fy (x) dx.

y
ya

ya
Z xb

g(y) =

dy,

xa

fx (y) f (x, y).

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

g(y)

xa

xb x

slide 299

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

cruda (cont.)
Integral 2D. Version
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

class fy-t : public scalarfun1d-t {


public:
scalarfun2d-t *f2dp; // Ptr to 2var funct fx,y)
double y;
double eval(double x) { return f2dp->eval(x,y); }
} fy;
class g-t : public scalarfun1d-t {
public:
integral1d-t int1dx; // integral over x
double eval(double y) { // wrapper pass to calling class
fy.y = y;
return int1dx.integral();
}
} g;
class integral2d-t {
private:
int N;
// Nbr of integr segments
double xa,xb,ya,yb; // rectangle corners

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 300

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

integral1d-t int1dy; // integral over y


public:
void set(int Na=0,double xaa=NAN,double xba=NAN,
double yaa=NAN,double yba=NAN,
scalarfun2d-t *f2dpa=NULL) {
N = Na; xa=xaa; xb=xba; ya=yaa; yb=yba;
fy.f2dp = f2dpa;
int1dy.set(N,ya,yb,&g);
g.int1dx.set(N,xa,xb,&fy);
}
integral2d-t(int Na=0, // Ctor
double xaa=NAN,double xba=NAN,
double yaa=NAN,double yba=NAN,
scalarfun2d-t *f2dpa=NULL) {
set(Na,xaa,xba,yaa,yba,f2dpa);
}
double integral() {
// 2D integral. Integrates over y the
// integral over x
return int1dy.integral();
}
};

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 301

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62

// User code starts here---// Specific 2var function to be integrated


class fun-t : public scalarfun2d-t {
public:
double eval(double x,double y) {
// Must give (2/pi)2 = 0.40528
return sin(0.5*M-PI*x)*sin(0.5*M-PI*y);
}
} fun;
int main() {
int N=10;
// 2D integration example
integral2d-t int2d(N,0.0,1.0,0.0,1.0,&fun);
cout << "integral(x,y) = " << int2d.integral() << endl;
return 0;
}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 302

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

cruda (cont.)
Integral 2D. Version
fy y g son wrappers.
fy toma una scalarfun2d_t y devuelve una scalarfun1d_t fijando y a un

valor (almacenado en el wrapper).


g es una scalarfun1d_t. Usa un objeto de la clase integradora 1D llamado
eval correspondiente consiste en fijar el valor de y para
int1dx. La funcion
la fy y llamar a la clase integradora sobre y.
Ambos objetos pertenecen a clases fy_t y g_t.
hemos hecho estas clases globales y totalmente
En esta implementacion
publicas

para simplificar.
La clase integradora 2D utiliza otr integrador 1D (int1dy) para integrar
sobre y.
Las dos instancias de integral1d_t son utilizadas en forma recursiva,
g().
int1dy.eval() utiliza internamente a int1dx.eval() al evaluar la funcion

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 303

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

cruda (cont.)
Integral 2D. Version
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

#include <cmath>
#include <iostream>
#include <vector>
using namespace std;
// One variable function f(x)
class scalarfun1d-t {
public:
virtual double eval(double x)=0;
};
// Two variables function f(x,y)
class scalarfun2d-t {
public:
virtual double eval(double x,double y)=0;
};
// Two variables function f(x,y,z)
class scalarfun3d-t {
public:
virtual double eval(double x,double y,double z)=0;

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 304

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

};
// Integral of a one var funct over an interval
class integral1d-t {
private:
int N;
// Nbr of integration pts
double xa,xb;
// integration interval
scalarfun1d-t *fp; // ptr to function
public:
// Ctor, set values
integral1d-t(int Na=0,double xaa=NAN,
double xba=NAN,scalarfun1d-t *fpa=NULL) {
set(Na,xaa,xba,fpa);
}
// Set values
void set(int Na,double xaa,double xba,scalarfun1d-t *fpa) {
N=Na; xa=xaa; xb=xba; fp=fpa;
}
// Computes the integral using Simpsons rule
double integral() {
double
h = (xb-xa)/N,
h2 = h/2.0,

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 305

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68

}
};

finteg=0.0;
for (int j=0; j<N; j++) {
double x = j*h;
double f = fp->eval(x);
finteg += 2.0*f;
finteg += 4.0*fp->eval(x+h2);
}
finteg -= fp->eval(xa);
finteg += fp->eval(xb);
finteg *= h/6.0;
return finteg;

// Integral of 2var functions over a rectangle


class integral2d-t {
private:
scalarfun2d-t *f2dp; // Ptr to 2var funct
integral1d-t int1dy, int1dx; // integrals over x and y
// For a given y gives the function fy(x) = f(x,y)
class fy-t : public scalarfun1d-t {
double y;

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 306

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90

integral2d-t *i2dp; // ptr to calling class


friend class integral2d-t;
public:
double eval(double x) { return i2dp->f2dp->eval(x,y); }
} fy;
// For a given y, integral over x: g(y) = int-{x=xa}xb f(x,y) dx
class g-t : public scalarfun1d-t {
integral2d-t *i2dp; // ptr to calling class
friend class integral2d-t;
public:
double eval(double y) { // wrapper pass to calling class
return i2dp->geval(y);
}
} g;
double geval(double y) {
// Integrates over x for y=cnst
fy.y = y;
return int1dx.integral();
}
int N;
// Nbr of integr segments
double xa,xb,ya,yb; // rectangle corners
friend class fy-t;

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 307

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113

friend class g-t;


public:
void set(int Na=0,double xaa=NAN,double xba=NAN,
double yaa=NAN,double yba=NAN,
scalarfun2d-t *f2dpa=NULL) {
N = Na; xa=xaa; xb=xba; ya=yaa; yb=yba;
f2dp = f2dpa;
int1dy.set(N,ya,yb,&g);
int1dx.set(N,xa,xb,&fy);
}
integral2d-t(int Na=0, // Ctor
double xaa=NAN,double xba=NAN,
double yaa=NAN,double yba=NAN,
scalarfun2d-t *f2dpa=NULL) {
set(Na,xaa,xba,yaa,yba,f2dpa);
g.i2dp = this;
fy.i2dp = this;
}
double integral() {
// 2D integral. Integrates over y the
// integral over x
return int1dy.integral();
}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 308

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136

};
// Integral of 3var functions over a cube
class integral3d-t {
private:
scalarfun3d-t *f3dp; // Ptr to 3var funct
integral2d-t int2dxy; // integral over x,y
integral1d-t int1dz; // integral over z
// For a given z gives the function fz(x,y) = f(x,y,z)
class fz-t : public scalarfun2d-t {
double z;
integral3d-t *i3dp; // ptr to calling class
friend class integral3d-t;
public:
double eval(double x,double y) {
return i3dp->f3dp->eval(x,y,z);
}
} fz;
// For a given z, gives g(z) = integral over x,y:
// g(z) = int-{x=xa}xb int-{y=ya}yb f(x,y,z) dx dy
class g-t : public scalarfun1d-t {
integral3d-t *i3dp; // ptr to calling class

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 309

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159

friend class integral3d-t;


public:
double eval(double z) { // wrapper pass to calling class
return i3dp->geval(z);
}
} g;
double geval(double z) {
// Integrates over x,y for z=cnst
fz.z = z;
return int2dxy.integral();
}
int N;
// Nbr of integr segments
double xa,xb,ya,yb,za,zb; // rectangle corners
friend class fz-t;
friend class g-t;
public:
void set(int Na,double xaa,double xba, // Set from args
double yaa,double yba,
double zaa,double zba,
scalarfun3d-t *f3dpa) {
N = Na; xa=xaa; xb=xba; ya=yaa; yb=yba; za=zaa; zb=zba;
f3dp = f3dpa;
int2dxy.set(N,xa,xb,ya,yb,&fz);

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 310

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183

int1dz.set(N,za,zb,&g);

}
integral3d-t(int Na=0, // Ctor
double xaa=NAN,double xba=NAN,
double yaa=NAN,double yba=NAN,
double zaa=NAN,double zba=NAN,
scalarfun3d-t *f3dpa=NULL) {
set(Na,xaa,xba,yaa,yba,zaa,zba,f3dpa);
g.i3dp = this;
fz.i3dp = this;
}
double integral() { // Comp 3D integral. Integrates over z
return int1dz.integral();
}
};
// User code starts here---// Specific 1var function to be integrated
class fun-t : public scalarfun1d-t {
public:
double eval(double x) {
// Must give (2/pi) = 0.63662
return sin(0.5*M-PI*x);

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 311

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207

}
} fun;
// Specific 2var function to be integrated
class fun2-t : public scalarfun2d-t {
public:
double eval(double x,double y) {
// Must give (2/pi)2 = 0.40528
return sin(0.5*M-PI*x)*sin(0.5*M-PI*y);
}
} fun2;
// Specific 3var function to be integrated
class fun3-t : public scalarfun3d-t {
public:
double eval(double x,double y,double z) {
// Must give (2/pi)3 = 0.25801
return sin(0.5*M-PI*x)
*sin(0.5*M-PI*y)*sin(0.5*M-PI*z);
}
} fun3;
int main() {
int N=10;

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 312

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

208
209
210
211
212
213
214
215
216
217
218
219
220
221

// 1D integration example
integral1d-t int1d(N,0,1.0,&fun);
cout << "integral(x) = " << int1d.integral() << endl;
// 2D integration example
integral2d-t int2d(N,0.0,1.0,0.0,1.0,&fun2);
cout << "integral(x,y) = " << int2d.integral() << endl;
// 3D integration example
integral3d-t int3d(N,0.0,1.0,0.0,1.0,0.0,1.0,&fun3);
cout << "integral(x,y,z) = " << int3d.integral() << endl;
return 0;

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 313

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

mejorada
Integral 2D. Version
Funciona pero tiene algunas desprolijidades, usa variables globales y las
clases auxiliares es mejor si se anidan en la clase que la utiliza integral2d_t.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

class integral2d-t {
private:
scalarfun2d-t *f2dp; // Ptr to 2var funct
integral1d-t int1dy, int1dx; // integrals over x and y
// For a given y gives the function fy(x) = f(x,y)
class fy-t : public scalarfun1d-t {
double y;
integral2d-t *i2dp; // ptr to calling class
friend class integral2d-t;
public:
double eval(double x) { return i2dp->f2dp->eval(x,y); }
} fy;
// For a given y, integral over x: g(y) = int-{x=xa}xb f(x,y) dx
class g-t : public scalarfun1d-t {
integral2d-t *i2dp; // ptr to calling class
friend class integral2d-t;

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 314

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

public:
double eval(double y) { // wrapper pass to calling class
return i2dp->geval(y);
}
} g;
double geval(double y) {
// Integrates over x for y=cnst
fy.y = y;
return int1dx.integral();
}
int N;
// Nbr of integr segments
double xa,xb,ya,yb; // rectangle corners
friend class fy-t;
friend class g-t;
public:
void set(int Na=0,double xaa=NAN,double xba=NAN,
double yaa=NAN,double yba=NAN,
scalarfun2d-t *f2dpa=NULL) {
N = Na; xa=xaa; xb=xba; ya=yaa; yb=yba;
f2dp = f2dpa;
int1dy.set(N,ya,yb,&g);
int1dx.set(N,xa,xb,&fy);
}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 315

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

40
41
42
43
44
45
46
47
48
49
50
51
52
53

integral2d-t(int Na=0, // Ctor


double xaa=NAN,double xba=NAN,
double yaa=NAN,double yba=NAN,
scalarfun2d-t *f2dpa=NULL) {
set(Na,xaa,xba,yaa,yba,f2dpa);
g.i2dp = this;
fy.i2dp = this;
}
double integral() {
// 2D integral. Integrates over y the
// integral over x
return int1dy.integral();
}
};

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 316

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Integral 3D
De la misma forma se puede hacer la integral en 3D combinando una integral
en 1D con otra en 2D.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

class integral3d-t {
private:
scalarfun3d-t *f3dp; // Ptr to 3var funct
integral2d-t int2dxy; // integral over x,y
integral1d-t int1dz; // integral over z
// For a given z gives the function fz(x,y) = f(x,y,z)
class fz-t : public scalarfun2d-t {
double z;
integral3d-t *i3dp; // ptr to calling class
friend class integral3d-t;
public:
double eval(double x,double y) {
return i3dp->f3dp->eval(x,y,z);
}
} fz;
// For a given z, gives g(z) = integral over x,y:

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 317

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

// g(z) = int-{x=xa}xb int-{y=ya}yb f(x,y,z) dx dy


class g-t : public scalarfun1d-t {
integral3d-t *i3dp; // ptr to calling class
friend class integral3d-t;
public:
double eval(double z) { // wrapper pass to calling class
return i3dp->geval(z);
}
} g;
double geval(double z) {
// Integrates over x,y for z=cnst
fz.z = z;
return int2dxy.integral();
}
int N;
// Nbr of integr segments
double xa,xb,ya,yb,za,zb; // rectangle corners
friend class fz-t;
friend class g-t;
public:
void set(int Na,double xaa,double xba, // Set from args
double yaa,double yba,
double zaa,double zba,

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 318

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

scalarfun3d-t *f3dpa) {
N = Na; xa=xaa; xb=xba; ya=yaa; yb=yba; za=zaa; zb=zba;
f3dp = f3dpa;
int2dxy.set(N,xa,xb,ya,yb,&fz);
int1dz.set(N,za,zb,&g);

}
integral3d-t(int Na=0, // Ctor
double xaa=NAN,double xba=NAN,
double yaa=NAN,double yba=NAN,
double zaa=NAN,double zba=NAN,
scalarfun3d-t *f3dpa=NULL) {
set(Na,xaa,xba,yaa,yba,zaa,zba,f3dpa);
g.i3dp = this;
fz.i3dp = this;
}
double integral() { // Comp 3D integral. Integrates over z
return int1dz.integral();
}
};

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 319

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Integral 1D/2D/3D. User code


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

class fun-t : public scalarfun1d-t {


public:
double eval(double x) {
// Must give (2/pi) = 0.63662
return sin(0.5*M-PI*x);
}
} fun;
// Specific 2var function to be integrated
class fun2-t : public scalarfun2d-t {
public:
double eval(double x,double y) {
// Must give (2/pi)2 = 0.40528
return sin(0.5*M-PI*x)*sin(0.5*M-PI*y);
}
} fun2;
// Specific 3var function to be integrated
class fun3-t : public scalarfun3d-t {
public:

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 320

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

double eval(double x,double y,double z) {


// Must give (2/pi)3 = 0.25801
return sin(0.5*M-PI*x)
*sin(0.5*M-PI*y)*sin(0.5*M-PI*z);
}
} fun3;
int main() {
int N=10;
// 1D integration example
integral1d-t int1d(N,0,1.0,&fun);
cout << "integral(x) = " << int1d.integral() << endl;
// 2D integration example
integral2d-t int2d(N,0.0,1.0,0.0,1.0,&fun2);
cout << "integral(x,y) = " << int2d.integral() << endl;
// 3D integration example
integral3d-t int3d(N,0.0,1.0,0.0,1.0,0.0,1.0,&fun3);
cout << "integral(x,y,z) = " << int3d.integral() << endl;
return 0;
}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 321

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Polimorfismo: ej. suma de los elementos de un vector


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

#include <cmath>
#include <iostream>
#include <vector>
using namespace std;
class vector-t {
public:
virtual int size()=0;
virtual double operator[ ](int j)=0;
};
double vecsum(vector-t &v) {
int N = v.size();
double sum = 0.0;
for (int j=0; j<N; j++) sum += v[j];
return sum;
}
// A stride, linearly spaced values
class stride-t : public vector-t {
private:
int N;

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 322

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

double start, inc;


public:
stride-t(int Na, double s,double i) :
N(Na), start(s), inc(i) { }
int size() { return N; }
double operator[ ](int j) { return start+j*inc; }
};
// A wrapper to a vector<double>
class vecwrap-t : public vector-t {
private:
const vector<double> *ap;
public:
vecwrap-t(const vector<double> &a) : ap(&a) { }
int size() { return ap->size(); }
double operator[ ](int j) { return (*ap)[j]; }
};
// A plain function that computes its values
class fun-t : public vector-t {
public:
int N;
double p;
fun-t() : N(10), p(3.0) { }

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 323

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68

int size() { return N; }


double operator[ ](int j) { return pow(j,p); }
};
int main() {
stride-t stride(10,0,1);
cout << "sum(0. .9): " << vecsum(stride) << endl;
vector<double> a;
double p=3; int N=10;
a.resize(N);
for (int j=0; j<N; j++) a[j] = pow(j,p);
vecwrap-t vw(a);
cout << "sum-{j=0}{j=9} x3 (with vecwrap): "
<< vecsum(vw) << endl;
fun-t f;
cout << "sum-{j=0}{j=9} x3 (with fun-t): "
<< vecsum(f) << endl;
return 0;
}

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 324

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Contenedores de la
librera STL

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 325

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

La clase vector
Inicialmente eran una serie de headers con clases desarrollado por

Hewlett Packard.
Es una librera de contenedores (vectores, listas, conjuntos, maps...) y
algoritmos (ordenamiento, filtrado, operaciones de conjuntos, eliminar
elementos duplicados...)
templatizados es decir cada contenedor puede obtener objetos de
Estan
un tipo arbitrario (todos del mismo), por ejemplo vector<int>,
vector<double>.
puede contener objetos de clases definidas por el usuario
Tambien
de que la clase A cumpla con ciertas restricciones
vector<A>, a condicion

(por ejemplo tener un constructor por defecto, operador de asignacion


a1=a2...)
Muchos pueden anidarse, por ejemplo vector<vector<int>>.
de un tipo, por ejemplo map<int,string>.
Algunos pueden involucrar mas

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 326

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

La clase vector

Emula el comportamiento de un vector estandar


de C, pero se puede

redimensionar dinamicamente
y libera sus recursos dinamicamente.

vector<int> v; // declara el vector


2 v.resize(N); // lo dimensiona a N elementos
3
// OJO preserva elementos existentes.
4 vector<int> v(N); // Lo crea con N elementos
5 int z; vector<int> v(N,z); // Lo crea con N elementos =z
6 v.clear(); // Elimina todos los elementos dejando al vector vac
o
Tiene sobrecargado el operator[] para acceder para lectura/escritura los
elementos del vector. El acceso es en tiempo O(1).
1
x = v[j]; v[k]=z;
v.push_back(z) inserta el elemento z al final (muy eficiente, O(1)
1

amortizado).
v.push_front(z) inserta el elemento z al comienzo del vector (muy
ineficiente, O(n)).
z = v.front(), z = v.back() accede al primer y ultimo

elemento del vector


(eficiente, O(1).
de iterators
Se puede acceder a los elementos a traves

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 327

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

1
2
3

1
2

1
2
3
4
5
6
7

vector<int>::iterator q = v.begin(); // Comienzo del vector (v[0])


int z = *q;
// Se dereferencian como ptrs
q++;
// Incrementa al siguiente elemento
de hacer el incremento equivale a v[1].
*q equivale a v[0]. Despues
La clase iterator es una clase anidada dentro de vector. Casi todos los
contenedores tienen su propia clase iterator.
El iterator v.end() es un iterator pasado el ultimo

elemento del vector

vector<int> v(10);
vector<int>::iterator q = v.end();
q apunta a v[10] (el ultimo

elemento es v[9].
Se puede iterar sobre todo el vector as

// Suma todos los elementos de v


double sum = 0;
vector<int>::iterator q = v.begin();
while (q!=v.end()) {
sum += *q;
q++;
}

Notar que q++ se puede hacer ya que el operator++ esta sobrecargado para

prefija y postfija.
la clase iterator. Igual que para enteros existe la version
se puede hacer como con un vector comun
Para vector tambien

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 328

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

1
2

1
2
3

double sum = 0;
for (int j=0; j<v.size(); j++) sum += v[j];
con vector, con iteradores se puede iterar
Pero esto se puede usar solo
sobre casi cualquiera de los otros contenedores.

Los iterators de vector<> soportan aritmetica


de punteros (como los
valido

punteros). Esto es solo


para los iterators de vector, no para list<>
o map<> por ejemplo.
del vector, sin
Se puede insertar un elemento en cualquier posicion
embargo esto puede ser costoso (O(n)).

vector<double> v(100,0);
q = v.begin() + 50; // Apunta al elemento v[50]
v.insert(q,33); // Inserta un 33 en la posicion 50
de esto el vector tiene 101 elementos. Por supuesto esto implica
Despues
copiar los elementos en
no solo redimensionar el vector sino tambien
[50,99] a [51,100].
de
Para pasar los vectores como argumentos conviene hacerlo a traves
no modifica al
referencias para evitar la copia. Para indicar que la funcion
vector se debe declarar el argumento como const.

double vecsum(const vector<double> &w) {

Pero entonces se debe iterar sobre el mismo con un const_iterator


Facultad de Ingeniera y Ciencias Hdricas FICH - UNL
((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 329

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

1
2
3
4
5
6

double vecsum(const vector<double> &w) {


double sum = 0.0;
vector<double>::const-iterator q = w.begin();
while (q!=w.end()) sum += *q++
return sum;
}

Como es declarado un const_iterator no se le puede asignar un valor


1
vector<double>::const-iterator q;
2
//. . . .
3
*q = z; // error!
Como muchos otros contenedores de las STL, permite hacerun swap con
otro contenedor
1
2
3

vector<double> v,w;
// Llena v y w . . .
v.swap(w);

Equivale a
1
2
3
4
5

vector<double> v,w, tmp;


// Llena v y w . . .
tmp = v;
v = w;
w = tmp;

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 330

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

1
2
3
4

Pero sin hacer copias ni duplicados, o sea es muy eficiente.


se puede borrar elementos o un rango de elementos
Tambien

w.erase(q); // Elimina el elemento en q (ineficiente)


w.erase(p,q); // Elimina todo el rango [p,q) (ineficiente)
w.pop-front(); // Elimina el primer elemnto (ineficiente)
w.pop-back(); // Elimina el ultimo elemento (eficiente)

(y en general en ciencias de la computacion)


se
En toda la documentacion

1
2

utilizan rangos cerrado/abierto [p,q) que quiere decir todos los elementos
desde p a q incluyendo a p pero sin incluir a q.

vector<> como casi todos los otros contenedores soportan asignacion:


por igualdad y distinto).
operator= (deep copy), operator==, (comparacion
Para usarlo

#include <vector>
using namespace std;

Como casi todos los otros contenedores tiene bool v.isempty() (retorna
verdaderi si el contenedor esta vaco).

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 331

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

La clase list
El contenedor lista (list<>) es (como vector<>) un contenedor lineal es
entera.
decir los elementos en la lista se pueden asociar con una posicion
m de la lista en forma
Sin embargo no se puede acceder a la posicion
almacenados en
eficiente (es decir O(1)) ya que los elementos estan
celdas enlazadas.
1
2
3
4

list<double> L;
// pone elementos en L. . .
double z = L[m]; // NO, [ ] s
olo para vectores
double z;

se puede acceder al elemento m-esimo

Solo
haciendo un lazo.
1
double z;
2
list<double>::iterator q = L.begin();
3
for (int j=0; j<m; j++) q++;
4
z = *q; // Accede al elemento m
La lista es doblemente enlazada es decir que se puede avanzar en las dos
direcciones (q++ y q--) eficientemente (O(1)).
Existe otra clase slist<> que es simplemente enlazada, por lo tanto q++ es
O(1), mientras que q-- es O(n) (debe ir al principio y recorrer la lista
Facultad de Ingeniera y Ciencias Hdricas FICH - UNL
((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 332

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

1
2
3
4

hasta encontrar la celda que apunta a q).


de list<> es que permite insertar en cualquier posicion
muy
El interes
eficientemente (O(1))

list<double> L;
// Pone elementos en L. . .
// q apunta a cualquier posici
on en L
q = L.insert(q,w); // Inserta un nuevo elemento en el medio de la lista

refrescada q.
insert retorna la posicion
1
L.insert(q,w); // deja q invalido
2
z = *q; // posible error en tiempo de ejecucion
3
4
q = L.insert(q,w); // OK refrezca q
5
z = *q; // OK!
se debe refrescar el
Para borrar un elemento q = L.erase(q);, tambien
iterator.
1
2

1
2

list<int>::iterator q = L.begin();
while (q!=L.end()) q = L.erase(q);

Equivale a L.clear(), elimina todos los elementos de a uno por el frente.


se puede pasar todo un rango de una lista a otra
Tambien

list<int> L1,L2;
// Pone elementos en L1, y L2

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 333

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

1
2
3
4
5

L1.splice(r,L2,p,q));
r de L1. MUY EFICIENTE
inserta todo el rango [p,q) de L2 en la posicion
(O(1)).
tiene swap. De hecho swap se puede implementar para list
list<> tambien

en terminos
de splice

list<int> L1,L2,tmp;
// Pone elementos en L1, y L2
tmp.splice(tmp.begin(),L1.begin(),L1.end());
L1.splice(L1.begin(),L2.begin(),L2.end());
L2.splice(L2.begin(),tmp.begin(),tmp.end());
es O(1), por lo tanto es tan eficiente como swap. Pero
Toda la operacion
general (es como swap pero para pedazos de lista).
splice() es mas
vector no tiene splice().
Los headers son #include <list> y <slist>

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 334

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

La clase set
Los conjuntos son contenedores que almacenan elementos diferentes
entre s.
1
2
3

set<int> S;
for (int j=0; j<10; j++) S.insert(j);
S.insert(5); // No hace nada (5 ya estaba)

donde se encuentra un elemento


El metodo
find(x) retorna la posicion
dado x, si el elemento no esta retorna S.end()

1
2
3
4

set<int>::iterator q = S.find(x);
if (q!=S.end()) {
// x esta en S y *q==x
}

de diseno
de set.
find() es muy eficiente (O(log n)). Esta es la condicion

Si se declara un set<A> entonces la clase A tiene que tener los requisitos

debe
de antes (ctor por defecto, operador de asignacion).
Pero ademas
tener sobrecargado el operator<. Esto es as ya que el find() es eficiente
porque guarda los elementos ordenados.
Facultad de Ingeniera y Ciencias Hdricas FICH - UNL
((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 335

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

ordenados por
Se puede recorrer los elementos con un iterador, estan
operator<

1
2
3

set<int>::iterator q = S.begin();
while (q!=S.end()) cout << *q++ << " ";
cout << endl;

Imprime todos los elementos ordenados por operator<

El header correspondiente es <set>


Notar que insert() no toma un iterator (como en list vector). En set no se
en particular, ya que el mismo contenedor
inserta en una posicion
mantiene los elementos en un cierto orden.

Hay dos sabores de erase


1
S.erase(q); // Erase de un iterator (debe ser dereferenciable)
2
int z = S.erase(x); // erase de un elemento
El primero toma un iterator que debe ser dereferenciable, elimina el
elemento correspondiente y no retorna nada. El segundo toma un
elemento x y se fija si esta o no en el conjunto. Si esta lo elimina del
conjunto y si no no hace nada. En ambos casos el valor de retorno es el
numero

de elementos efectivamente eliminados, es decir 1 o 0.


Facultad de Ingeniera y Ciencias Hdricas FICH - UNL
((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 336

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

C =AB
1 set difference(a.begin(),a.end(),b.begin(),b.end(),
2
inserter(c,c.begin()));
C =AB
1 set intersection(a.begin(),a.end(),b.begin(),b.end(),
2
inserter(c,c.begin()));
Se pueden utilizar las funciones que realizan las operaciones binarias.
en el header <algorithm>. No son metodos

Estan
de la clase, son
funciones friend.

C =AB
1 C.clear();
2 set union(A.begin(),A.end(),B.begin(),B.end(),
3
inserter(C,C.begin()));
Notar que en principio opera sobre un rango en A y otro en B e inserta la

de los mismos (sin elementos duplicados) en C. De la forma en que


union
estandar

esta llamada arriba hace la operacion


de union.

C =AB
1 C.clear();
Facultad de Ingeniera y Ciencias Hdricas FICH - UNL
((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 337

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

2
3

set-difference(A.begin(),A.end(),B.begin(),B.end(),
inserter(C,C.begin()));

C =AB
1 C.clear();
2 set intersection(A.begin(),A.end(),B.begin(),B.end(),
3
inserter(C,C.begin()));
Las operaciones binarias son muy eficientes O(n log n).

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 338

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

La clase map
Representa una correspondencia entre claves de un conjunto dominio y

1
2
3
4
5
6
7
8
9
10

un conjunto imagen o contradominio. Como si fuera una base de datos


se puede
almacena pares (clave,valor) ordenados por la clave y despues
buscar las asignaciones por la clave.
Ejemplo, sueldos de los empleados

map<int,double> sueldos;
sueldos[13234567] = 23000.34;
sueldos[30245654] = 18356.34;
....
int dni = 34567234;
if (sueldos.find(dni)==sueldos.end()) {
// Este empleado no tiene asignado un sueldo en la tabla. . .
} else {
cout << "el sueldo correspondiente es " << sueldos[dni] << endl;
}

El nombre utilizado para los tipos es key_t para el dominio, range_t. En el

ejemplo anterior key_t es int y range_t es double.


Cuando se itera sobre el map con el lazo tpico

map<int,double>::iterator q = sueldos.begin();

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 339

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

2
3
4
5

while (q!=sueldos.end()) {
cout << "DNI " << q->first << ", sueldo " << q->second << endl;
q++;
}

Notar que los iteradores iteran sobre los pares clave, valor, de hecho son

1
2
3

estruturas de tipo pair<int,double>.


basico

El contenedor pair es el mas


de las STL y permite agrupar dos
elementos de tipo diferente o igual: pair<int,int> dos ints,
pair<int,string>....
Los campos de pair se acceden por los miembros first y second.

pair<int,double> p;
p.first = 23;
p.second = 234.56;

se puede declarar pair<int,double> p(23,45.67);


Tambien
El map tiene un efecto colateral no comun
que es que si indexamos por

una clave que no tiene asignado un valor entonces crea una asginacion
poniendo como imagen el constructor por defecto de range_t
1
2

map<int,string> M;
string z = M[5]; // Asigna z= string vacio !!!

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 340

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

Algoritmos
Permiten operar sobre los diferentes contenedores. Muchas veces en

1
2
3
4

forma transparente, el mismo algoritmo se puede aplicar a diferentes


contenedores.
paradigmatico

Tal vez el mas


y util es sort

vector<double> v;
// Pone elementos en v. . .
// Ordena por valor absoluto
sort(v.begin(),v.end());
sort(p,q) ordena los elementos en el rango [p,q). Notar que no se le pasa
el contenedor, solo dos iteradores.
Si hay que ordenar todo el contenedor hay que pasar v.begin(), v.end()
para listas
Se puede utilizar tambien
internamente ordenados.
Para conjuntos no tiene sentido, ya estan
Para clases (vector<A>) ordena por operator< por lo tanto debe estar
sobrecargado.
Si se quiere ordenar por otro criterio y no se puede modificar el operator<
de comparacion:

se puede pasar una funcion

// Funcion de comparacion por valor absoluto

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 341

en C++ para Ciencia e Ingeniera, por M.Storti, L. Dalcn, Rodrigo Paz


Programacion

bool comp(int x,int y) { return abs(x)<abs(y); }


3
vector<int> v;
4
// Pone elementos en v. . .
5
sort(v.begin(),v.end(),comp);

Es MUY rapido,
O(n log n).
2

Facultad de Ingeniera y Ciencias Hdricas FICH - UNL


((version texstuff-1.2.5-48-gc81615e) (date Wed Jan 21 14:11:47 2015 -0300)
(processed-date Wed Jan 21 14:12:00 2015 -0300))

slide 342

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