Sei sulla pagina 1di 106

Laboratorio abo ato o de Programacin og a ac II

Curso 2010-2011
Ingeniero tcnico en informtica de sistemas Grupo A

Yolanda Garca Ruiz


E-mail: ygarciar (at) fdi.ucm.es) Despacho: 228 Tutoras: Mircoles 11:00 13:00, Viernes 10:00 12:00 http://gpd.sip.ucm.es/yolanda/docencia.htm

Requerimientos
Programacin de primero aprobada Programacin g Orientada a Objetos j Estructuras de Datos y de la Informacin
1

Laboratorio de programacin II Programa g


Introduccin a C++ Builder.
Eventos y componentes visuales

Programacin modular. Tipos p abstractos de datos. Tratamiento de excepciones. Programacin orientada a objetos.

Herencia y polimorfismo. Tipos abstractos de datos. Gestin de memoria dinmica.


2

Bibliografa bsica
o Francisco Charte Ojeda. Programacin con C++ Builder 5. Anaya Multimedia, 2000. o H.M. Deitel, P.J. Deitel. C++ Cmo programar. Prentice Hall, , 1999. o R. Lafore. Object-Oriented programming in C++. The White Group Group, 1999 1999. o E. Horowithz, S. Sahni, D. Metha. Fundamentals of data

structures in C++. C++

W H Freemans & Co W.H. Co., 1995. 1995

Bibli Bibliografa f complementaria l t i


Walter Savitch. Resolucin de problemas con C++. Addison Wesley, 2000. James P. Cohoon, Jack W. Davidson. Programacin y diseo en C++. McGraw Hill, 2000. G.L. G L Heileman. H il E t Estructuras t de d datos, d t algoritmos l it y programacin orientada a objetos. McGraw Hill, 1998. Francisco Charte Ojeda Ojeda. Programacin avanzada con C++ Builder 5. Anaya Mulimedia, 2000. Bruce Eckel. Thinking g in C++. http://www.BruceEckel.com p

Mt d de Mtodo d evaluacin l i
Primer p parcial: Prcticas eliminatorias. Examen escrito obligatorio (30%). Examen final de junio: Prcticas eliminatorias. Examen escrito obligatorio (70%). Septiembre i b : Prcticas eliminatorias. l Examen final f l escrito obligatorio (100%). Las prcticas sern en grupos de dos y su entrega y correccin ser en el laboratorio en las fechas que se establezcan. Habr posibilidad de entregar las prcticas en septiembre. Mismo examen (prcticas y otros elementos de evaluacin, en su caso) en todos los grupos y criterios detallados de puntuacin comunes Mismo examen en todos los grupos corregido de forma comunes. horizontal entre todos los profesores de la asignatura. 5

C++ Builder
Surge de Borland C++ y el entorno de desarrollo de Delphi. (El lenguaje de programacin en Delphi es Object Pascal) Lenguaje de programacin: C++ Sucesor del lenguaje de propsito general C. C permite programar tanto a alto como a bajo nivel. C++ extiende y mejora j el lenguaje g j C. Incorpora mecanismos de Programacin Orientada a Objetos. Incorpora una biblioteca estndar que incluye la librera de plantillas (STL) para tipos abstractos de datos.

El leguaje C++ Estructura de los programas


Componente estructural t t l b bsico: i
Directivas de preprocesador Declaraciones globales ( variables globales, funciones, ) funcin main() { secuencia de declaraciones e instrucciones } funcin f1() { secuencia de declaraciones e instrucciones } ... funcin fn() { secuencia de declaraciones e instrucciones }

la funcin

Funciones

Una de d las l funciones ha de ser main

El leguaje C++ Estructura de los programas


Directivas del preprocesador: comienzan por # Directivas para el uso de mdulos: #include NombreModulo Declaraciones globales: constantes, tipos, funciones, ... int main(parmetros) { Secuencia de instrucciones y declaraciones locales return 0; } // valor devuelto // final bloque de cdigo (end) // funcin principal (program) // inicio bloque de cdigo (begin) // terminan con ;

// Para aplicaciones Windows la funcin principal es: WinMain


8

El leguaje C++ Ejemplo


Directiva de preprocesamiento
#include <iostream> using namespace std; int main() { int x, , y; int aux; cin >> x >> y; aux = x; x = y; y = aux; ; cout << x <<y; return 0; }

Declaracin de variables locales Fl j de Flujo d entrada t d

Flujo de salida por estndar (pantalla) << : operador de insercin para flujos de salida Valor que se devuelve al S.O. E l Es la salida lid de d la l funcin f i main. i
9

El lenguaje C++ Consideraciones sintcticas generales


Comentarios: Un fragmento de texto: /* .... */ Una sola lnea de texto: // Final de Instruccin: ; Instrucciones compuestas: { ... } ( begin ... end de Pascal) { Instruccin 1; ....... Instruccin k; }
10

El leguaje C++ Ejemplo Comentarios


Un comentario es cualquier informacin que se escribe el en programa para proporcionar informacin de cualquier tipo.
#include <iostream>

/* podemos hacer comentarios que ocupen varias lneas */ int main() { int x, y; int aux; // ste es un comentario de una sola lnea cin >> x >> y; ... return 0; }

Podemos escribir l comentarios los i de d dos formas diferentes

11

El lenguaje C++ Consideraciones sintcticas generales


Nombres de los identificadores: Se distingue entre maysculas y minsculas: Cont es distinto de cont. Longitud: entre 1 y 32 caracteres. Primer carcter: una letra o subrayado. , nmeros o subrayados. y Resto de caracteres: letras, El tipo de los identificadores se escribe delante del nombre:
int cont; char Cont;
12

El preprocesador
El preprocesamiento es el primer paso en la etapa de compilacin de un programa (propiedad nica del compilador de C). Los compiladores de C++ proporcionan bibliotecas de funciones. Cada biblioteca de funciones tiene asociada un archivo de definicin que se denomina cabecera. Para utilizar algo de una biblioteca en un programa, programa hay que colocar al principio del programa una directiva de preprocesamiento seguida de la cabecera de la biblioteca . Herramienta que en la mayor parte de los casos acta reemplazando ciertas palabras por cdigo. Las directivas del preprocesador comienzan por el smbolo #.
13

El preprocesador
Las directivas ms usuales son: #include , #define, #undef Directiva #include para utilizar mdulos:
#include <Forms.hpp> #include <iostream> #include MiBiblioteca.h

El nombre entre ngulos indica que el fichero est en el directorio definido por el camino del sistema. El nombre entre comillas indica que debe buscarse en el directorio en curso. Directivas #define y #undef #define indica al preprocesador que una palabra quede reconocible o contenga un valor. La palabra puede usarse en condicionales del preprocesador. La directiva #undef tiene el efecto contrario.

14

El preprocesador
El preprocesador acepta el cdigo fuente como entrada y es responsable de: Quitar los comentarios Interpretar las directivas del preprocesador las cuales inician con #

Modelo de compilacin de C

15

El preprocesador
Ejemplo
Para mostrar datos en la pantalla podemos usar el operador << con el elemento cout Pero para poder usar cout y << debemos incluir la biblioteca donde estn definidos. Esta E t bibli biblioteca t tiene ti como archivo hi de d cabecera iostream.

#include <iostream> int main() { cout << Hola oaa amigos; gos ; return 0; }

Una vez que se incluye el archivo de cabecera, se puede utilizar todo lo que est definido en ella. ella
16

El preprocesador
Incluir ms de una vez un mdulo (unidad) genera errores de compilacin. No se pueden generar ciclos de inclusiones en los archivos cabecera (no es deseable pero haremos declaraciones adelantadas) adelantadas). Incluye slo los mdulos necesarios y en el archivo en que se

necesitan. necesitan

No incluyas en un .h mdulos que slo vas a necesitar en el .cpp.

17

Standard C++ library


Salvo los tipos fundamentales, que tambin admiten ser tratados como clases, los dems tipos definidos en C++ son clases de la biblioteca estndar. As As, los archivos (stream), ) las cadenas de caracteres (string), ) los conjuntos (set), los vectores (vector), estn definidos como clases y por tanto sus valores son instancias (objetos) de ellas. El standard C++ para incluir archivos elimina la extensin. As, para incluir la unidad iostream se escribe: #include <iostream> en lugar de: #include <iostream.h>

18

Standard C++ library


Por compatibilidad con las bibliotecas C, se admite tambin la segunda forma. Pero para utilizar bibliotecas que provienen de C, el estndar C++ introduce el prefijo c. As, en lugar de escribir: # include <stdio.h> escribimos: #i l d < #include <cstdio> tdi > El resultado de incluir un archivo cabecera mediante el estndar C C++ no es exactamente el l mismo que si utilizamos l el l estilo l anterior, ya que sern incluidas versiones ms antiguas. Por tanto, debemos de seguir la forma estndar de incluir los archivos cabecera de la biblioteca estndar.

19

Standard C++ library


Uno de los problemas del uso de bibliotecas es la colisin de identificadores, es decir, , distintas bibliotecas utilizan el mismo nombre para identificadores de funciones, tipos, etc. Para tratar este problema, C++ introduce los namespace, que definen un grupo de identificadores. Casi todos los identificadores de la biblioteca estndar se encuentran en el namespace std d. Para denotar a un identificador incluido en un namespace debemos cualificarlo lifi l con el l nombre b del d l namespace seguido id del d l operador d de d resolucin de alcance (::): std::cin De esta forma, se deshacen las posibles ambigedades.
20

Standard C++ library


Si vamos a utilizar frecuentemente un namespace, por ejemplo el std d, ser mas cmodo d utilizar ili la l instruccin i i

using g namespace p std; ;


que cualificar automticamente todos los identificadores que utilicemos del namespace std. Por compatibilidad, hay una relacin entre los espacios de nombres y la forma de incluir los archivos cabecera de la biblioteca estndar. estndar Si utilizamos el estilo antiguo:

#include <iostream.h>
no hay yq que utilizar los cualificadores.
21

Standard C++ library


Aqu estn algunos nombres de las cabeceras las l viejas i j (de (d C o de d C++ C no estndar) d )y las nuevas (de C++ estndar, que usan namespace std)
C C++ no estndar #include <stdlib.h> #include <math.h> #include <stdio.h> #include <iostream.h> #include <string.h> C++ estndar (using namespace std) #include <cstdlib> #include <cmath> #include <cstdio> #include <iostream> #include <string> Funciones de propsito general Funciones matemticas Manipular p datos de E/S Uso de funciones de E/S Uso de funciones de cadena

El uso ms frecuente en C++ de las directivas del preprocesador es la inclusin de archivos de cabecera, pero tambin se usan para definir macros, nombres b de d constantes, t t etc. t
22

La funcin main
Una funcin C++ es un subprograma que devuelve un valor, un conjunto j t d de valores l o realiza li una tarea t especfica. fi Todo programa C++ tiene una nica funcin main() que es el punto inicial de entrada al programa. Si se intenta declarar dos funciones main() () dentro del programa p g se produce error.
#i l d <iostream> #include <i t > () int main() { ... } #include <iostream> int main() { entrada_datos(); proceso_datos(); return 0; ... }
23

Llamadas a otras funciones

C++: Tipos bsicos


char (8 bits) caracteres, los literales se escriben entre comillas simples:'a' short int (16 bits) nmeros enteros en el intervalo -32768 .. 32767 int y long (32 bits) enteros en el l intervalo l -2147483648 .. 2147483647 float (32 bits) nmeros reales en el intervalo 3.4E-38 3.4E 38 .. 3.4E 3.4E+38 38 double (64 bits) nmeros reales en el intervalo 1.7E-308 .. 1.7E+308 bool b l (8 bits) bit ) valores lgicos true (1)/ false (0) void nada (para indicar que una funcin no devuelve valor).

24

C++: Tipos bsicos


Modificadores de tipos: unsigned, short y long

unsigned g char (8 bits): 0 .. 255 unsigned short int (16 bits): 0 .. 65535 unsigned int (32 bits): 0 .. 4294967295 l long double d bl (80 (8 bits) b )

25

C C++: D Declaracin l i d de variables i bl


tipo lista_variables;
lista_variables es uno o ms identificadores separados por comas. Ejemplos: int i, j, l; unsigned int valor; double variable1, variable1 variable2; int c=0; Operador de asignacin es el smbolo =. Las variables se pueden inicializar al ser declaradas. Las reglas l de d mbito b son como las l de d Pascal. l
26

C C++: V Variables i bl locales l l


S declaran Se d l dentro d del d l cuerpo de d una funcin f i o de d un bloque. bl void fun() { int i=0; ...... if (i == 0) { char c; ...... } ..... }

// local a la funcin

// local al bloque if

// aqu no se conoce a c

27

C++ Pa C++: Parmetros met os y constantes


Parmetros: P Declarados en la cabecera de las funciones (separados por comas). int fun(char dato, , int cont) ) { ..... } Constantes: C t t Se declaran como las variables pero precedidas de const. Se les asigna g valor con el operador p =. Ejemplo const int HorasDia = 24; const int MinutosHora = 60; int Minutos; Minutos = HorasDia * MinutosHora;
28

C++ Asignacin y operadores C++: ope ado es


Asignacin:

variable i bl = expresin; i
Operadores aritmticos: +, -, *, /, % (mdulo para enteros) ++ operador incremento (en una unidad) x=++i; // equivale a i=i+1; x=i; x=i++; // equivale a x=i; i=i+1; -- operador decremento (en una unidad) Operadores relacionales: >, >=, <, <= == (igual) != ( (distinto) )
29

C++: Asignacin y operadores


Operadores Lgicos: && (conjuncin) || (disyuncin) ! (negacin) Conversin Automtica de Tipos: al realizar una operacin entre dos operandos de distinto tipo, el de tipo menor se promociona al de tipo mayor. Tipos de mayor a menor: double, float, long, int, char. Moldes M ld ( (casts): t ) (tipo) expresin Fuerzan a que una expresin sea de un determinado tipo. char c = (char) 2; ;
30

C++: Otras operaciones


Adems de las operaciones anteriores, C++ dispone de un gran conjunto de funciones matemticas.
abs: int int ceil: double double floor: double double fmod: double double double sqrt: double double pow:double double double
#include <math.h> { x = abs(-7) // x vale 7 y = ceil (5.2) // y vale 6 z = floor (5.2) // z vale 5 resto = fmod(5.0, 2.0) // resto vale 1 }

Calcula el valor absoluto de un nmero Calcula el nmero entero mayor o igual que el dado Redondea por defecto el valor de un nmero Calcula el resto de la divisin real de dos nmeros Calcula la raz cuadrada de un nmero Calcula la potencia de un nmero

Los archivos de cabecera que contienen stas funciones son entre otras: cmath float.h
31

Tipos definidos por el programador

typedef tipo nombre; Tipos Enumerados typedef enum { lista_etiquetas } nombre_tipo; enum nombre_tipo { lista_etiquetas } [lista_vars];
Las etiquetas de un tipo enumerado son como constantes enteras, donde la primera etiqueta toma el valor 0, la segunda el 1, etc.
32

Tipos enumerados
Ejemplo typedef unsigned char caracter; typedef enum {rojo, {rojo verde, verde azul} colores; caracter dato; colores color; ; // enum colores {rojo, verde, azul} color; ..... color = verde; Como subrango de los enteros: color=color+1; color=1; ;
33

Regist os Registros
typedef struct { tipo nombre_campo; tipo nombre_campo; ..... } nombre_tipo; struct t t nombre_tipo b i { tipo nombre_campo; tipo nombre_campo; nombre campo; ....... } [lista_vars]; [lista vars];
34

Registros
Ejemplo typedef struct { string calle; int numero; } tdireccion; ...... tdireccion nueva; nueva calle = "Castellana"; nueva.calle Castellana ; nueva.numero = 32; ......... R f Referencia i al los campos d de una estructura: con el operador .

35

Arrays
typedef tipo_elem tipo elem nomb_tipo[num1]....[numN]; nomb tipo[num1] [numN]; tipo elem var[num1]....[numN]; tipo_elem var[num1] [numN];
// en este caso no se puede definir el tipo. Los ndices quedan definidos en el intervalo 0..numI-1 Los arrays no se pueden asignar. Los identificadores de tipo array se comportan como referencias al primer elemento del array.

36

Arrays
Ejemplo: typedef int Tvector[20]; Tvector vector1, vector2; vector1[3] = 32; vector2=vector1; // ERROR de compilacin typedef int Tmatriz[3][2]; // 3 elementos de 2 Tmatriz matriz = {{1, 1}, {2, 4}, {3, 9}}; // matriz[0][0] = 1 ; matriz[0][1] = 1 ; // matriz[1][0] = 2 ; matriz[1][1] = 4 ; // matriz[2][0] = 3 ; matriz[2][1] = 9 ; Referencia a las componentes de un array: con el operador [ndice]
37

Arrays y y c-strings g
En C, las cadenas de caracteres son arrays de tipo char terminados en el carcter nulo '\0' \0 ((char)0). Por tanto son de longitud acotada. const int MaxNomb=41; typedef unsigned char tNombre[MaxNomb]; tNombre Cadena= "cadena al estilo C\0esta parte no vale"; Cadena[0] [ ] = 'C'; Cadena[18] = ' '; Cadena[19] = '\0';

38

Operaciones para los c-strings c strings


Dada la naturaleza de los c-strings, directamente no se pueden asignar, ni comparar, ni concatenar, pero podemos utilizar las funciones que realizan estas operaciones: strcpy(str1,str2), copia str2 en str1. strcat(str1,str2), aade str2 a str1. strcmp(str1,str2), compara str1 con str2 devolviendo 0, menor que 0 o mayor que 0 si str1 es igual, menor o mayor que str2, respectivamente. strlen(str), devuelve la longitud de str sin contar el carcter nulo de terminacin. Los c-string pueden utilizarse con los operadores << y >>, y con el mtodo getline(c-str,len,sep) (arch.getline(c-str,len,sep)).
39

Ope aciones para Operaciones pa a los c-strings c st ings


Las clases string y AnsiString: En la biblioteca estndar de C++ tenemos la clase string (< t i >) y en la (<string>) l VCL la l clase l A iSt i . Estas AnsiString E t d dos clases l no son compatibles entre si, pero podemos compatibilizarlas con los mtodos c_str() _ () q que aplicado p a un string g (C++ ( o Builder) ) devuelve la cadena en formato c-string: string.c_str(). Ambas clases admiten notacin de arrays para acceder a sus elementos: string desde 0 hasta length-1, y AnsiString desde 1 hasta Length, y operadores de comparacin, concatenacin, etc.

40

C C++: I Instrucciones t i d de control t l


Para resolver problemas complejos, nos puede interesar que dependiendo de los valores de los datos, se ejecuten unas instrucciones u otras otras. Las instrucciones condicionales nos van a permitir representar ste tipo de comportamiento. IF SWITCH En otroS casos, casos nos encontraremos con la necesidad de repetir una instruccin instrucciones un nmero determinado de veces. En stos casos utilizaremos instrucciones de control iterativas repetitivas (ciclos). (ciclos) WHILE DO-WHILE FOR
41

I t Instruccin i condicional di i l if
if (condicin) instruccin if (condicin) instruccin else instruccin
Ejemplo: if (x>y) { x=x-y; z=1; } else { y=y-x; z=2; }
si no ? bool EsPar( int valor){ condicin if (valor % 2 == 0) return true; else return false; Instruccin(es )1 Instruccin(es )2 }

si

condicin Instruccin (es )

no

42

Instruccin condicional switch


(similar a case de Pascal) switch (expresin) { case constante1: secuencia de instrucciones [break;] case constante2: secuencia de instrucciones [break;] default: secuencia de instrucciones }

43

Instruccin condicional switch


Ejemplo: switch ( mes ) { // enum meses{....} mes; case abril: case j junio: case septiembre: case noviembre: num_dias di = 30; 30 break; b k case febrero: num_dias _ = 28; break; default: num_dias = 31;} Se ejecutan todas las instrucciones desde la primera constante que coincida con el valor de la expresin, hasta encontrar un break o hasta el final de la instruccin switch it h.
44

Instruccin iterativa while


(similar a while/do de Pascal) ( )
Inicializacin Se realiza antes de la instruccin while

while (condicin) instrucciones


si
?

Ejemplo: int a[N]; int c; ............. int i=0; while (( ((i < N) ) && ( (c != a[i])) [ ])) { i++;} }
Comprobacin Se comprueba el valor de la variable antes de comenzar la repeticin

no

condicin Accin(es)

Actualizacin Se realiza dentro del cuerpo del bucle durante cada iteracin

45

I t Instruccin i iterativa it ti do/while d / hil


(como repeat/until ( p de Pascal p pero negando g la condicin de terminacin) )

do instruccin while (condicion);


Ejemplo: int i=0; do { // repeat presentar_datos(a[i]); i++; } while (i <N); //until (i>=N)
no

Accin(es)
?

condicin

si

46

I t Instruccin i iterativa it ti f for


for (inicializacin; condicin; incremento) instruccin
Se pueden incluir varias inicializaciones e incrementos, separndolas por comas. Tambin pueden omitirse. Ejemplo: for (i=0; i<num _columnas; i++) f (j=0; for (j 0 j j<num_filas; fil j++) j ) c[i][j] = a[i][j] + b[i][j]; for (i=0, valor=9; i<10; i++, valor--) t[i]=valor;
i inf i f
si
?

i sup

Accin(es) ii+1

47

F Funciones i
Una funcin es una serie de instrucciones escritas independientemente del programa principal. Este subprograma est ligado al programa principal mediante un proceso de transferencia/retorno.
Programa Principal Transferencia El control de ejecucin se pasa al subprograma en el momento en que se requieren sus servicios. Transferencia/retorno / de control y datos Retorno El control de ejecucin se devuelve al programa principal cuando el subprograma termina
48

funcin

F Funciones i
Declaracin de una funcin (prototipo o cabecera):

tipo-resultado nombre-fun ( lista-de-parmetros );


Los parmetros de la lista se separan por comas. En la lista de parmetros de los prototipos no es obligatorio el nombre de los parmetros t ( (el l tipo ti s). ) Definicin ( (implementacin) p ) de una funcin:

tipo-resultado nombre-fun ( lista-de-parmetros ) { declaraciones locales instrucciones return t expresin; i }

49

Funciones
Prototipos y ficheros de cabecera Es costumbre o u b que qu los o prototipos p o o po de d las a funciones u o incluidas u da en las a bibliotecas del lenguaje se agrupen en ficheros especficos, los denominados ficheros de cabecera, que son ficheros de texto en los que se agrupan todas las declaraciones que se utilizan en la biblioteca.

MisFunciones.h

MisFunciones.cpp

Fichero de cabecera

Biblioteca: Contiene las implementaciones de las funciones del fichero de cabecera.

Contiene prototipos de funciones funciones, definicin de estructuras estructuras, macros y clases clases.
50

F Funciones i
Prototipos y ficheros de cabecera
El hecho de tener agrupados los prototipos en un fichero de gran utilidad, , porque p q solo es preciso p incluir dicha cabecera es de g librera mediante la directiva ya conocida include al principio del programa
#include <MisFunciones.h> <MisFunciones h> .

A As podemos d estar t seguros de d que todos t d los l prototipos t ti estarn t presentes De otro modo tendramos que escribirlos manualmente en cada programa que usara funciones de la librera
51

F nciones Funciones
El resultado l d de d una funcin f i se devuelve d l con la l instruccin i i

return expresin;
que adems termina la ejecucin de la funcin. A diferencia de Pascal, no se distingue entre procedimientos y f funciones: i l procedimientos los di i se implementan i l como funciones f i cuyo tipo de resultado es void (no necesitan la instruccin return). Podemos declarar una funcin inline, para que las llamadas sean sustituidas por su cdigo. En el .h se declara y se implementa: inline tipo-resultado nombre-fun (

lista-de-parmetros ) {...}
52

F nciones Funciones

Es muy importante en la fase de diseo de un algoritmo, utilizar nombres que nos permitan intuir la tarea que realizan las funciones, sobre todo a la hora de mantener y modificar programas.

53

F nciones Funciones
... void main() { int numero, absoluto; float raiz; cin >> numero; if (numero > 0 ) raiz i = sqrt t ( numero ) else { absoluto = abs (numero) numero = cubo( absoluto ) } cout << raiz; }
float sqrt (int a) { float m; . return m; }

int abs (int a) { . return ...; }

Transferencia/retorno de control y datos

float cubo (int a) { . return ...; }

54

Parmetros por valor y por referencia Por defecto los parmetros son por valor. Para indicar que un parmetro formal es por referencia (VAR en Pascal), se escribe el carcter & detrs del nombre del tipo. Adems los parmetros t por referencia f i pueden d declararse d l constantes, t t anteponiendo const al nombre del tipo. void Cuadrado (int Factor, int& Resultado) { Resultado = Factor * Factor; Factor =1; } int N,C=2; N C=2; Cuadrado(8,N); // Modifica N Cuadrado(C,N); ( , ); // No modifica C Cuadrado(C,4); // ERROR

Funciones

55

Parmetros por valor y por referencia

Funciones

Paso de parmetros por valor


Cuando se llama a la funcin, funcin se pasa solo el valor de la variable. Este mtodo tambin se llama paso por copia. El compilador hace una copia de los parmetros. Esto implica que cualquier modificacin en el valor de los parmetros no se mantiene cuando termina la funcin. funcin Utilizaremos ste mtodo cuando no necesitemos que se modifiquen los parmetros con los que se llama.

56

Parmetros por valor y por referencia

Funciones

Paso de parmetros por referencia


Tambin se llama paso por direccin. Cuando se llama a la funcin, se pasa la direccin de memoria donde se encuentra almacenada la variable parmetro. t El compilador no hace copia, no reserva memoria para los p parmetros. Usaremos ste mtodo cuando necesitamos que la funcin modifique el valor de los parmetros y que devuelva el valor modificado. modificado Para pasar un parmetro por referencia, hay que poner el operador de direccin & detrs del tipo del parmetro. parmetro
57

Funciones
int Cuadrado ( int Factor, const int& Resultado) { Resultado = Factor * Factor; // Error de compilacin return Factor * Factor; } ..... int N N,C=2; C=2; N = Cuadrado(8,C); En las funciones sin parmetros es necesario el uso de los parntesis tanto en la definicin como en las llamadas.
58

F Funciones i
Parmetros de entrada: deben ser por valor o por referencia constantes. Parmetros de salida: deben ser por referencia o el resultado de la funcin. Parmetros de entrada/salida: deben ser por referencia.

59

Parmetros de tipo array


En C++ los identificadores de arrays son referencias que apuntan a la primera componente del array. Por tanto: no se puede hacer asignacin entre arrays y el paso de parmetros de un array siempre es por referencia referencia, y permite modificar los elementos del array. Para impedirlo debemos declararlo const. Podemos declarar parmetros para arrays sin especificar el tamao, en cuyo caso el tamao se debe pasar tambin por parmetro. void funArray( int A[], int Long); void funArray( const char A[], int Long);

60

Sobrecarga de funciones y argumentos implcitos


En C++ es posible definir diferentes funciones con el mismo nombre pero con un nmero y/o tipo diferente de parmetros formales (sobrecarga de funciones).

Debido a la conversin de tipos y a los argumentos implcitos, implcitos la resolucin de la sobrecarga puede dar problemas.

61

Sobrecarga S b d de f funciones i y argumentos implcitos


Cuando hacemos una llamada a una funcin sobrecargada, el p es capaz p de saber a cual de ellas nos estamos compilador refiriendo analizando los parmetros que pasamos a la funcin Proceso denominado Resolucin de sobrecarga

int area ( int a, a int b ); float area (int radio ); int area ( float c, float d, float e );

void main() { int m; m = area( 2 , 3 ); m = area( 2.3 , 8.3, 7.0 ); }

62

Sobrecarga S b d de f funciones i y argumentos implcitos


Resolucin de sobrecarga: El compilador aplica ciertas reglas para verificar cual de las declaraciones se ajusta mejor al nmero y tipo de los argumentos utilizados. Busca mxima concordancia d ! Si el compilador encuentra que dos funciones distintas concuerdan, entonces se produce un error: existe ambigedad. Los L valores l devueltos d l por las l funciones f i no son tenidos id en cuenta a efectos del mecanismo de sobrecarga.

63

Sobrecarga S b d de f funciones i y argumentos implcitos


Adems es posible definir valores por defecto para los g (argumentos ( g implcitos), p ) en los ltimos parmetros p argumentos de la lista de parmetros.
void sobrecargada ( int X, X int Y=1); void sobrecargada ( int X); void sobrecargada (); void id sobrecargada b d ( double d bl X, X int i t Y=1); Y 1) ..................
sobrecargada(); sobrecargada(2); b d (2) sobrecargada(2, 2); sobrecargada(2.3); sobrecargada(( float ) 2);
64

A chi os Archivos
En C++ los archivos son secuencias (flujos) de bytes (caracteres) terminadas con la marca EOF (ctr-z para DOS, VMS y ctr-d ctr d para Unix, Unix Mac). Mac) La funcin que determina si hemos alcanzado el final del archivo (a diferencia de Pascal) devuelve cierto una vez leda la marca EOF, aunque este valor una vez ledo no se puede usar. C++ no impone ninguna estructura a los archivos, por tanto debemos gestionarlos en el programa. programa Los dos mecanismos conocidos para esta gestin son: mediante archivos de acceso secuencial (ficheros de texto, datos de longitud variable con formato) y mediante archivos de acceso aleatorio (ficheros binarios de registros, datos de longitud fija).

65

Archivos
La biblioteca estndar de C++ define una jerarqua de clases para el tratamiento de E/S, tanto estndar como de archivos, como flujo (stream) de bytes. Parte de esta jerarqua es: i b ios_base istream ifstream ostream iostream ofstream

ft fstream
Stream == flujo j o corriente de datos Conexin por la que circulan los datos (tuberas): Operadores: <<, >>
66

E/S estndar
Incluyendo el archivo cabecera <iostream> tenemos acceso a las clases istream, ostream e iostream, as como a las variables cin y cout de tipos istream y ostream respectivamente que se corresponden con la E/S estndar de la respectivamente, consola. Las variables cin y cout (as como las de tipo archivo), contienen un objeto de la correspondiente clase, que utilizaremos a travs de sus mtodos y operadores. El operador de insercin << (cout<<expresin;) y el operador de extraccin >> (cin >> variable;), estn definidos f ambos para los tipos de datos fundamentales y son extensibles para los dems datos mediante la sobrecarga. g
67

E/S estndar
El mtodo getline(c-str, long, sep) lee en c-str long-1 caracteres o p. Por ejemplo: hasta que encuentre el separador sep char A[N]; cin getline(A M); cin.getline(A,M);

// M<=N

se leern en A los M siguientes caracteres, salvo que se encuentre antes EOF, O o salto l de d lnea l (\n, (\ separador d implcito). l ) El mtodo ignore(long, g ( g, sep p) es similar a g getline, pero p los caracteres no se almacenan. Otros operadores son: endl y flush (salto de lnea y vaciado de buffer standar) 68

A hi Archivos
Adems tenemos la funcin getline(istream&,string&) getline(istream& string&), que lee en el string los siguientes caracteres hasta el salto de lnea (que se consume pero no se guarda): getline(cin,s); Para detectar el final de archivo se dispone del mtodo eof(): if (cin.eof()) ..... Incluyendo el archivo cabecera <fstream> tenemos acceso a as c clases ases ifstream st ea , o ofstream st ea y fstream st ea pa para a archivos a c os de las entrada, salida y de entrada/salida, respectivamente. Las clases fstream fstream derivan de las correspondientes clases stream y por tanto heredan todos sus mtodos y operadores. Adems la funcin getline admite parmetros de tipo ifstream gracias al polimorfismo. polimorfismo
69

Archivos
Ejemplo: copia de un fichero en aplicacin de consola // proyconsola.cpp "File/New/Console Wizard" //---------------------------------------------------#pragma hdrstop // importamos las cabeceras #include <iostream> // entrada/salida estndar #include <string> // de la biblioteca estndar #include <fstream> // entrada/salida de archivos //----------------------------------------------------#pragma argsused using namespace std; /* para nombrar los elementos importados sin cualificarlos con std:: */
70

Archivos
int main(int argc, char* argv[]) { string S; cout << "Nombre del fichero a copiar \n"; ; cin >> S; ifstream ent; ent.open(S.c_str()); // archivo de lectura cout << "Nombre del fichero copia \n"; cin >> S; ofstream sal; sal.open(S.c_str()); // archivo de escritura while (getline(ent, S) ) // elimina el salto de lnea sal << S << endl; // se aade //... ent.close(); sal.close(); cout<<"copiado, t " i d adios"<<endl; di " dl getline(cin,S); return 0; }
71

Lectura de archivos de texto


Pascal var ent: text; assign(ent, ...); Reset(ent); // eof(ent) Read(ent,var); Read(ent,v1,..,vk); d( 1 k) Readln(ent,string); Close(ent); C++ ifstream ent; // o fstream ent.open(...); //ent.open(...,ios::in); // ent.eof() ent>>var; ent>>v1>>...>>vk; 1 k getline(ent,string); // o ent.getline(c-str,long); t tli ( t l ) ent.close();
72

Escritura en archivos de texto


Pascal var sal: text; assign(sal, ...); Rewrite(sal); i ( l) // Append(sal); W it ( l Write(sal,var); ) Writeln(sal,v1,..,vk); Close(ent); C++ ofstream sal; // o fstream sal.open(...); //sal.open(...,ios::out); // sal.open(...,ios::out| ios::app); sal<<var; l<< sal<<v1<<...<<vk<<endl; //'\n' sal close(); sal.close();

73

Archivos de lectura
#include <ifstream> // o <fstream> using namespace std; ifstream ent; // o ifstream ent(entrada.dat); ent.open(entrada.dat); // en cuyo caso esta instruccin sobra if (!ent.fail()) { int num; while (ent >> num){ // tratamiento del dato ledo en la variable num } ent.close(); l () } Si la variable ent la declaramos de tipo fstream, entonces debemos indicar que la apertura es para lectura: fstream ent; ent.open p ( (entrada.dat, ios::in) );
74

Archivos de escritura
#include <ofstrem> // o <fstream> using g namespace p std; ofstream sal; // o ofstream sal(salida.dat); sal.open(salida.dat); // en cuyo caso esta instruccin sobra if (!sal.fail()) (!sal fail()) { int num; while (darvalor(num)) sal << num; // Cuidado! sal<<num<< ; sal.close(); } Si la variable sal la declaramos de tipo fstream, entonces debemos indicar que la apertura es para escritura: fstream sal; sal.open p ( (salida.dat, , ios::out);
75

Archivos de escritura

El modo de apertura out, destruye todo el contenido previo del archivo. Si queremos escribir aadiendo al final debemos indicar adems el modo app:

sal.open(salida.dat,ios::out|ios::app);

76

A chi os Archivos
P Prcticamente i todos d los l mtodos d y operadores d pueden d usarse como condiciones booleanas para determinar si han tenido xito. Adems podemos preguntar con los mtodos: eof(), fail(), bad() y good(). d() , el archivo queda q en estado de Cuando el final del archivo se lee, error, que podemos restaurar con el mtodo clear(). Lectura y escritura de bytes (char) mediante los mtodos: read(arrayBytes,numBytes) write(arrayBytes,numBytes)

77

A hi Archivos
Utilizando el cursor (en bytes):

int tellp(); int tellg();

// en modo escritura p de put // en modo lectura g de get

como flujo de bytes, tell nos devuelve el lugar donde se encuentra el cursor.

seekp(numbytes,desde); seekp(numbytes desde); seekg(numbytes,desde);


mueve el cursor numbytes bytes desde el principio (desde==ios::beg), el final (desde==ios::end) o desde la posicin actual (desde desde==ios::cur ios::cur).
78

Lectura de archivos binarios con tipo de tamao fijo


Pascal var ent:file of tipo; t: tipo assign(ent, ...); Reset(ent); // eof(ent) Read(ent t); Read(ent,t); Close(ent); C++ ifstream ent; // o fstream tipo t; ent.open(..., ios::binary); // ent.eof() ent read( (char ent.read( (char*)&t )&t, sizeof(tipo) ); ent.close();
79

Escritura de archivos binarios con tipo de tamao fijo


Pascal var sal:file of tipo; t: tipo assign(sal, ...); Rewrite(sal); Write(sal,t); Close(sal); C++ ofstream sal; // o fstream tipo t; sal.open(..., ios::binary); sal.write( (char*)&t, sizeof(tipo) ); sal close(); sal.close();

80

A chi os Archivos
Ejemplo: modificacin de un archivo de productos
// TRegProducto es un struct de tamao fijo, // con clave, , nombre, , stock y precio p // TIndiceClaves es una tabla de Claves/Posicin fstream datos; datos.open(..., ios::in|ios::out|ios:binary); TIndiceClaves claves; TRegProducto prod; int pos, i; inicia(claves); ( ) i=0; while ( datos.read((char*) &prod, sizeof(prod)) ) { inserta(claves,prod.clave,i); i++; }
81

Archivos
Ejemplo: datos.clear(); d t l () while(pedirModif(prod)) if (buscapos(claves,prod.clave,pos)) (b ( l d l )) { datos.seekp(pos*sizeof(prod)); d datos.write((char*)&prod, i (( h *) d sizeof(prod)); i f( d)) } datos.close(); libera(claves);

82

P t Punteros y memoria i dinmica di i


Podemos distinguir tres clases de variables atendiendo a la gestin de la asignacin de memoria: Variables estticas (globales): existen durante toda la ejecucin del programa. Se les asigna memoria al comenzar la ejecucin y se libera al terminar. terminar Se accede a la memoria asignada a travs del identificador de variable declarado. Variables automticas (locales, parmetros): existen durante la ejecucin del bloque de cdigo en el que estn declaradas. Se les asigna memoria al entrar en el bloque y se libera al salir de l. Esta gestin es automtica y se realiza en la pila (stack). Se accede a la memoria asignada a travs del identificador de variable declarado. declarado
83

Punteros y memoria dinmica

Variables dinmicas (annimas): se gestionan por el programa mediante variables de tipo puntero (direcciones de memoria). El programa es responsable de asignarles memoria y de liberarla. liberarla Esta gestin se realiza en el montn (heap) con ayuda del sistema de gestin de memoria (operadores new y delete para punteros). Se accede a la memoria asignada a partir del identificador de variable de tipo puntero declarado, utilizando los operadores del p puntero. p tipo

84

P t Punteros
Una variable de tipo p p puntero ( (un p puntero) ) es una variable que contiene como valor una direccin de memoria de otra variable (esttica, automtica o dinmica). El tipo de variable a la que puede apuntar un puntero se establece en la declaracin de la variable puntero. Declaracin de un puntero: Detrs del tipo se coloca el operador *: Tipo * IdVar; int * Pnum; int Num; // puntero a variables de tipo Tipo // puntero a variables de tipo int // variable de tipo int

85

Punteros
El operador & (& Variable): Devuelve la direccin de memoria asignada a la variable a la que se aplica. PNum = &Num; El operador * (*Puntero): Para acceder a la variable apuntada por un puntero se antepone el operador * (operador de indireccin) al puntero. puntero Num y *PNum son la misma variable. El operador * tambin sirve para declarar variables de tipo puntero. t
86

Punteros
Hasta ahora hemos visto variables que almacenan datos; los punteros almacenan direcciones de otras variables. Un puntero puede apuntar a cualquier variable de su tipo o a nada. Para indicar que un puntero no contiene ninguna g direccin tenemos la constante NULL, compatible con todos los tipos. Es preciso inicializar las variables de tipo puntero antes de su uso. La inicializacin proporciona al puntero una direccin de memoria i a la l que apuntar. int * Pnum = NULL; int * Pnum = &Num;
87

P t Punteros
El p puntero NULL apunta p a la direccin 0. El puntero NULL no es una direccin de una variable en memoria. El puntero NULL proporciona al programa una manera de saber si un p puntero apunta p a una direccin vlida. Para poder usar el puntero nulo NULL, podemos hacer una de estas dos cosas:

d fi i l en la definirlo l cabecera b de d nuestro t programa:


# define NULL 0

incluir alguno de los archivos de cabecera donde ya se encuentra definido:


# include <stdio.h> <stdio h> # include <string.h> <string h>
88

Punteros
int Num = 10; int* PNum; PNum = &Num; // Usamos el puntero para modificar el valor

*PNum = 5; // Num tambin se ha modificado Si usamos el operador de indireccin(*) con un puntero a NULL, NULL se producir un error en ejecucin. ejecucin

89

Punteros
int Num = 10; int* PNum; PNum = &Num; / Mostramos el valor apuntado por PNum ShowMessage("*PNum=" + IntToStr(*PNum)); // Usamos el puntero para modificar el valor *PNum = 5; // Num tambin se ha modificado ShowMessage("*PNum=" + IntToStr(*PNum)); ShowMessage("Num=" + IntToStr(Num)); Si usamos el l operador d d de i indireccin(*) di i (*) con un puntero a NULL, se producir un error en ejecucin.

90

Punteros
Podemos acceder a los miembros de una estructura apuntada por un puntero mediante el operador ->: TStructura* PtrStructura; PtrStructura->campo p es equivalente q a *PtrStructura.campo p struct tdireccion { String calle; int numero; }; tdireccion dir1; tdireccion* pdir1; ; dir1.calle = "Castellana"; pdir1 = &dir1; *pdir1.numero = 43; pdir1->calle pdir1 >calle = "Castellana"; Castellana ;
91

Punteros
Podemos acceder a los miembros de una estructura apuntada por un puntero mediante el operador ->: TStructura* PtrStructura; PtrStructura->campo p es equivalente q a *PtrStructura.campo p struct tcds { String titulo; int numcanciones; }; tcds cd1; tcds* pcd1; cd1.titulo= Dirty y work"; ; pcd1 = &cd1; *pcd1.numcanciones = 12; pdcd1->titulo pdcd1 >titulo = El El piano piano"; ;
92

Punteros
0 1
"18 Tracks" 18 20,5 "12122001"

mis_cds =

"El p piano" 15 18 18112003"

..

"Dirty work" 10 12,75 "10091998"

tcds mis_cds[9]; tcds *p = NULL; p = mis_cds; mis cds;

NULL

for (int i = 0; i<10; i++) { cout << (*p).titulo; cout << (*p).precio; (*p) precio; p++; }

for (int i = 0; i<10; i++) { cout << p->titulo; p >titulo; cout << p->precio; p++; }

93

Asignacin dinmica
La asignacin esttica de memoria a una estructura de datos puede ser inadecuada: No se conoce de antemano la cantidad de espacio que se precisa. No hay suficiente espacio para tener en memoria todos los datos a la vez. Aunque los punteros pueden usarse para acceder a direcciones de variables estticas, estticas su principal utilidad es la asignacin dinmica de memoria. Es posible solicita solicitar memoria memo ia al sistema en tiempo de ejecucin. ejec cin La memoria asignada dinmicamente, cuando ya no es precisa, hay que liberarla para que pueda ser reutilizada.
94

Los operadores p new y delete


El operador new solicita en ejecucin un espacio de y tamao viene determinado p por el tipo p del memoria cuyo puntero con que se invoca.

new TipoDatos;
Crea una variable dinmica en el heap del tipo TipoDatos y devuelve su direccin. Si no hay suficiente espacio contiguo en el l heap h se produce d una excepcin i (d (del l tipo ti bad_alloc) b d ll ).

TipoDatos* Puntero=new TipoDatos;


El operador delete libera la memoria asociada a la variable apuntada por el puntero con el que se invoca.

d l t Puntero; delete P t
la variable apuntada por Puntero se libera y Puntero queda indefinido.

95

Los operadores p new y delete


int Num=22; int* PNum; int PNum = new int; ; *PNum=Num; // Lo modificamos *PNum = 5; delete PNum; PNum=NULL;

96

Los operadores p new y delete


int Num=22; int* PNum; int PNum = new int; ; *PNum=Num; // Mostramos el valor apuntado por PNum ShowMessage("*PNum=" + IntToStr(*PNum)); // Lo modificamos y lo volvemos a mostrar *PNum = 5; ShowMessage("*PNum=" + IntToStr(*PNum)); ShowMessage("Num=" + IntToStr(Num)); delete PNum; PNum=NULL;
97

Ot os operadores Otros ope ado es para pa a punteros p nte os


El operador = L asignacin La i i entre punteros permite i compartir i memoria. i Los operadores == y != Permiten e te co comprobar p oba s si dos pu punteros te os apu apuntan ta o no oa al mismo s o sitio.

int * P1; int * P2; P1 = new int; P2 = new int; P2 = P1; // Basura! delete P1; // Peligro! P1 = NULL; if (P2 == NULL) P2 = new int i t; else delete P2; // !! P1 = new int; P1 = NULL; // Basura!
98

Punteros y estructuras enlazadas (tipos recursivos)


struct t t tNodo{ tN d { int _dato; tN d * _sigNodo; tNodo* i N d };
// o bien

typedef struct tNodo{ int _dato; tN d * _sigNodo; tNodo* i N d } tNodo;


99

Punteros P t y estructuras t t enlazadas l d (tipos recursivos)


tNodo* Lista=NULL; Lista = new tNodo; Lista->_dato=1; Lista->_sigNodo Lista sigNodo=new new tNodo; Lista->_sigNodo->_dato=2; Lista->_sigNodo->_sigNodo=NULL; tN d * Aux=Lista->_sigNodo; tNodo* A Li t i N d for (int i=3; i<10; i++) { Aux->_sigNodo=new g tNodo; ; Aux=Aux->_sigNodo; Aux->_dato=i; Aux > sigNodo NULL; } Aux->_sigNodo=NULL;
100

Punteros y paso de parmetros


bool insertaPrimerElem(tNodo*[&] List, int dat) { ; tNodo* Aux=List; try { List=new tNodo; // POR VALOR NO FUNCIONA List->_dato=dat; List->_sigNodo=Aux; return true; } catch(...) { List=Aux; return false; } } b l insertaUltimoElem( bool i t Ulti El (tNodo*& tN d *& List, Li t int i t dat) d t) {.....} { }
101

Arrays dinmicos Los operadores new[] y delete[]


El operador new[] permite especificar (entre corchetes, a continuacin del tipo), el nmero de elementos del tipo base que se desean crear.

Tipo* Puntero=new Tipo[N];


El acceso a las posiciones reservadas se realiza como si se tratase de un array.

Puntero[i]=Valor;
El operador delete[] permite indicar que lo que se libera es un array, colocando unos corchetes vacos a continuacin del p operador.

delete[] Puntero;

102

Los operadores new[] y delete[]

int * PANum; PANum = new int[5000]; // Inicializamos y Mostramos dos elementos PANum[1] = 5; PANum[7] = 10; ShowMessage(PANum[1]= + IntToStr(PANum[1]) + \nPANum[7]= + IntToStr(PANum[7])); d l t [] PANum; delete PAN PANum=NULL;
103

Problemas en la gestin d memoria de i di dinmica i


Podemos distinguir dos clases de errores: Generacin de basura (variables dinmicas no liberadas): La generacin de basura no genera errores ni de compilacin ni de ejecucin. Es responsabilidad del programador liberar todas las variables dinmicas q que cree cuando stas dejen j de utilizarse. Acceso a la memoria apuntada por un puntero a NULL o indefinido Genera indefinido: G errores en ejecucin, j i pero es mucho h mas fcil detectar los problemas con NULL. No dejar nunca indefinida una variable puntero.

104

Problemas en la gestin de memoria dinmica


La herramienta CodeGuard integrada en el entorno Builder: Nos ayuda a depurar la gestin de memoria dinmica del programa generando cdigo extra programa, extra, que recarga el tiempo de ejecucin. Para ello hay que compilar la aplicacin con la opcin del CodeGuard activada: Project->Options->CodeGuard->validation (marcar). Una vez puesta a punto la aplicacin hay que volver a compilar con el CodeGuard desactivado. Adems de indicarnos el mal uso punteros durante la ejecucin j del programa, p g , al final genera g de los p un archivo de texto con el nombre del proyecto y extensin cgl (Code Guard Log) con un informe, en el que consta toda la basura que ha a dejado el e programa. p og a a
105

Punteros a funciones
typedef int (* ( TFunEnt) (int); void ApliFunArray(int A[], A[] int Long, Long TFunEnt F) { for (int i i=0; 0; i<Long; i++) A[i] = F(A[i]); // (*F)(A[i]) } int sig(int N) { return N+1; } ApliFunArray(AEnt, 56, sig); TFunEnt Fun = sig;
106

Potrebbero piacerti anche