El lenguaje C++
A partir del lenguaje C
Entorno de programación
Visual C++
El entorno de programación
 Solución
 Proyecto
 Hola mundo
 Compilar
 Build
 Link
 Debug
Nuevas palabras reservadas
asm
inline
public
virtual
catch
new
template
class
operator
this
delete
private
throw
friend
protected
try
Nueva forma para E/S
 Cualquier compilador de C++, acepta C.
 La biblioteca iostream incluye los operadores cin
y cout (#include <iostream>).
 Ejemplo:
char nombre;
int num=2;
std :: cout << "Introduzca el nombre del archivo " << num << ": ";
std :: cin >> nombre;
Declaración de variables
 En cualquier lugar del bloque:
for (double suma = 0.0, int i = 0; i<n; i++)
suma += a[i]
 Variables const para tamaño de
vectores:
int main() {
const int SIZE = 5;
char cs[SIZE] ;
}
Punteros const
 Apuntan siempre a la misma dirección.
 El valor de la variable apuntada se
puede modificar.
 Se declaran así:
char* const nombre2 = "Ramón";
 Un puntero a variable const no puede
modificar el valor de esa variable.
Punteros a variables const
 Se declaran así:
const char *nombre1 = "Ramón";
 El código: #include <stdio.h>
int main() {
const int i = 2;
int *p;
p = &i;
*p = 3;
printf("i = %d", i);
}
En ANSI C
produce i = 3,
pero en C++ no
compila.
Conversiones explícitas de tipo
 Ejemplo de cast: (C y C++)
return (int) (x/y);
 C++ dispone de otra conversión:
y = double(25);
return int(x/y);
Sobrecarga de funciones
 Funciones distintas con mismo nombre.
 Distinto tipo y/o número de
argumentos.
 No pueden diferir sólo en el tipo de
retorno.
 Tampoco en que un argumento se pase
por valor en una función y por
referencia en la otra.
Parámetros con valores por
defecto
 En C++ se pueden definir valores por defecto
para todos o algunos argumentos formales.
 En la llamada, si no están los argumentos
correspondientes, se toma el valor asignado.
 Los argumentos con valores por defecto deben
estar al final de la lista.
Parámetros con valores por
defecto
 Si se omite un argumento en la
llamada, se deben omitir los siguientes
en la lista.
 Ejemplo:
double modulo(double x[], int n=3);
 En C++ se puede invocar así:
v = modulo(x, n);
v = modulo(x);
Variables de tipo referencia
 Se declaran con el operador '&'.
 Deben ser inicializadas.
 Nombre alternativo para un objeto.
 Utilidades más importantes:
 especificación de argumentos.
 especificación de tipos de retorno.
 sobrecarga de operadores.
Variables de tipo referencia
int i = 1;
int& r = i; // r e i ahora se refieren al
// mismo int
int x = r; // x = 1
r = 2; // i = 2
r++; // i se incrementa a 3
 Ningún operador opera sobre una
referencia.
 El valor de una referencia no se puede
modificar (siempre se referirá al mismo objeto).
 &r es un apuntador al objeto denotado.
Los operadores new y delete
 Hasta ahora variables estáticas o
automáticas.
 Con new y delete se crean y destruyen
variables según la necesidad del
programador.
 Una variable puede traspasar su bloque.
 Se puede crear cualquier tipo de variable con
new y éste retorna un puntero de ese tipo.
 No se necesita conversión de tipo.
Clases, objetos y métodos
 Las clases se pueden ver como una
generalización de las estructuras.
 Son verdaderos tipos de datos definidos
por el usuario.
 Los objetos son las variables de una
determinada clase.
 Los métodos pueden ser funciones u
operadores.
Estructura de un programa
 En los archivos de cabecera (.h), por lo
general, se declara la clase, con los
prototipos de las funciones.
 En un archivo NombreClase.cpp de
implementan los constructores,
funciones y operadores.
 En un archivo main.cpp se define la
función main.
Ejemplo: complejo.h
 Se declaran los campos miembro privados:
class Complejo
{
private:
double real;
double imag;
 Los usuarios de la clase no podrán acceder
con los operadores '.' y '->'.
 Las funciones miembro sí tienen acceso.
Ejemplo: complejo.h
 Se declaran un conjunto de funciones y
operadores miembro en la sección
pública.
 Las tres primeras son los constructores:
public:
// Constructores
Complejo();
Complejo(double, double im=0.0);
Complejo(const Complejo&);
Ejemplo: complejo.h
 El siguiente grupo de funciones permite
dar valor a los campos:
void setData();
void setReal(double);
 O acceder a ellos:
double getReal(){return real;}
double getImag(){return imag;}
Ejemplo: complejo.h
 A continuación se declara la sobrecarga de
los operadores aritméticos, comparación y
asignación (operadores miembro).
Complejo operator+ (const Complejo&);
 Y luego la sobrecarga del operador de
inserción en el flujo de salida (operador
amigo)
friend ostream& operator<< (ostream& const Complejo&);
Sobrecarga de operadores
// operador miembro + sobrecargado
Complejo Complejo::operator+ (const Complejo
&a)
{
Complejo suma;
suma.real = real + a.real;
suma.imag = imag + a.imag;
return suma;
}
Sobrecarga de operadores
 Los operadores y funciones miembro se
indican con el operador de resolución de
alcance '::' (no así los amigos).
 En una sentencia x + y; // x, y complejos
se utiliza el operador sobrecargado.
 x es el argumento implícito.
 y se pasa explícitamente (como argumento formal
a) .
Puntero this
 La sobrecarga de '=' retorna (*this) que
representa al argumento implícito.
 Es una variable predefinida para todas las
funciones (u operadores) miembro.
 Contiene la dirección del objeto
correspondiente.
 Forma de referirse al objeto como tal
(argumento implícito).
Constructores
 Se debe dar valor inicial a las variables
miembro. Esto se hace a través de
constructores.
 Se invocan automáticamente al crear un
objeto de una clase.
 Permiten la encapsulación.
 Tienen el mismo nombre que la clase.
 No tienen valor de retorno (ni siquiera
void).
Inicializadores
 Los constructores inicializan variables.
 C++ permite inicializar variables fuera
del cuerpo de una función.
C_Cuenta::C_Cuenta(double unSaldo, double unInteres):
Saldo(unSaldo), Interes(unInteres) // inicializadores
{ } // En este caso el cuerpo del constructor está
vacío
 Permiten definir variables miembro
const.
Constructor por defecto
 Es un constructor que no necesita que se le
pasen argumentos para inicializar las
variables. Hay dos opciones:
 No tiene argumentos.
 Tiene argumentos, pero todos ellos tienen
asignado un valor por defecto en la declaración.
 Es necesario para declaraciones de la forma
Complejo z; y Complejo datos[100];
Constructor de oficio
 Lo crea el compilador de C++ si el
programador no define ningún
constructor.
 No tiene argumentos, es un constructor
por defecto (no siempre un constructor
por defecto es un constructor de oficio).
 Suelen ser cómodos, correctos y
suficientes.
Constructor de copia
 Se utiliza cuando se debe crear un objeto
a partir otro objeto de la misma clase.
 Tiene un único argumento que es una
referencia constante a un objeto de la
clase.
 El compilador también define un
constructor de copia de oficio si el
programador no lo hace (no funciona
correctamente con punteros).
Constructores y operador de
asignación (=).
z2 = z1;
 Se supone que c1 y c2
existían previamente.
 Se utiliza el operador de
asignación que funciona
como un constructor de
copia.
 Se debe sobrecargar
'='.
Complejo z2 = z1;
 Se invoca al constructor
de copia.
 El constructor de copia
por defecto es una copia
bit a bit.
 Se debe sobrecargar.
Destructores
 Es llamado cuando el objeto va a dejar
de existir.
 Para un objeto local o automático
definido en un bloque, el destructor es
invocado cuando el programa llega al
final del bloque.
 Los objetos creados con new deben ser
explícitamente destruidos.
Clases y funciones friend
 Las funciones miembro (que acceden a las
variables miembro) sólo pueden ser
miembro de una única clase.
 Una función friend de una clase es una
función que no pertenece a la clase, pero
que tiene permiso para acceder a sus
funciones y variables miembro.
 Una clase friend de otra tiene todas sus
funciones amigas de esa segunda clase.
Herencia
class ClaseDerivada: public o private ClaseBase
 Un nombre redefinido oculta el nombre
heredado.
 Hay algunos elementos de la clase base que
no pueden ser heredados:
 Constructores
 Destructores
 Funciones friend
 Funciones y datos estáticos de la clase
 Operador de asignación (=) sobrecargado
Constructores de clases
derivadas
 Debe llamar al constructor de la clase base.
 Se debe especificar un inicializador base.
 Se puede omitir si la clase base cuenta con
un constructor por defecto.
C_CuentaJoven(const char *unNombre, int laEdad,
double unSaldo=0.0, double unInteres=0.0):
C_Cuenta(unNombre, unSaldo, unInteres)
Herencia múltiple
 Una clase puede heredar de una
(herencia simple) o más clases base
(herencia múltiple).
class CuentaEmpresarial:
public Cuenta, public Empresa
Polimorfismo
Funciones Virtuales
 Son funciones distintas con el mismo
nombre, declaradas virtual en la clase
base (ligadura dinámica).
 Funciones convencionales se invocan de
acuerdo al tipo del objeto (en tiempo de
compilación).
 Con funciones virtuales se resuelve en
tiempo de ejecución el problema de la
asignación.
Funciones virtuales
class A {
public:
virtual void mostrar();
}
class B: public A {
public:
void mostrar();
}
A objA;
B objB;
A* ptrA1;
A* ptrA2;
ptrA1 = &objA;
ptrA2 = &objB;
ptrA2->mostrar();
Funciones virtuales puras
 La función virtual de la clase base debe
declararse a pesar de no ser utilizada.
 En este caso no es necesario definirla.
 Se declara como función virtual pura:
virtual funcion1() const = 0;
 No se pueden definir objetos de esa
clase.
 Se pueden definir punteros a esa clase.
Clases abstractas
 Contienen una o más funciones virtuales
puras.
 Si una clase derivada no define una función
virtual pura, la hereda como pura y por lo
tanto también es abstracta.
 Una clase que define todas las funciones
virtuales es una clase concreta.
Entrada/Salida
 Stream o flujo: dispositivo que produce o
consume información.
 Flujos estándares:
 cin: entrada estándar (teclado).
 cout: salida estándar (pantalla).
 cerr: salida de mensajes de error (pantalla).
 Las clases istream, ostream e iostream son
clases que heredan de ios.
Manipuladores
 Variables y/o métodos miembro que
controlan el formato.
 Pueden tener argumentos (iomanip) o
no (iostream).
 Sólo afectan al flujo al que se aplican.
 No guardan la configuración anterior
(como sí lo hacen los indicadores).
Manipuladores
 Ejemplos:
 endl: se imprime un ‘n’ y se vacía el buffer de
salida.
 flush: se vacía el buffer de salida.
 setw(int w): establece la anchura mínima de
campo.
cout << hex << 100;
cout << setw(10) << mat[i][j] << endl;
 El efecto permanece hasta que se
cambia por otro manipulador.
E/S de archivos
 En la biblioteca fstream se definen las
clases ifstream, ofstream y fstream,
que derivan de istream y ostream y a
su vez de la clase ios.
 Ejemplos:
fstream archivo;
archivo.open("datos.dat", ios::in);
ifstream archivo("datos.dat");
Excepciones
 Parte del código puede no ejecutarse
por algún error inesperado.
 Si ocurre una excepción se interrumpe
la normal ejecución del código.
 Se pueden manejar realizando una
acción adecuada para dejar al sistema
en un estado estable.
Excepciones en C++
 Se separa el código para el caso en que
ocurre una situación excepcional y el
que no:
 try: identifica un bloque de código en el
cual puede surgir una excepción.
 throw: causa que se origine una excepción.
 catch: identifica el bloque de código en el
cual la excepción se maneja.
Excepciones en C++
int main(void) {
int counts[] = {34, 54, 0, 27, 0, 10, 0};
int time = 60; // One hour in minutes
for(int i = 0 ; i < sizeof counts /sizeof counts[0] ; i++)
try {
cout << endl << "Hour " << i+1;
if(counts[i] == 0)
throw "Zero count - calculation not
possible.";
cout << " minutes per item: "
<< static_cast<double>(time)/counts[i];
} catch(const char aMessage[]) {
cout << endl << aMessage << endl;
}
return 0;
}
Excepciones en C++
 Cuando la excepción es lanzada (throw)
la secuencia de ejecución continúa con
el bloque catch.
 Después de ejecutarse el código del
bloque catch la ejecución continúa con
la siguiente iteración del for.
 El compilador considera los bloques try
y catch como una única unidad.

El lenguaje C++ (1).ppt

  • 1.
    El lenguaje C++ Apartir del lenguaje C Entorno de programación Visual C++
  • 2.
    El entorno deprogramación  Solución  Proyecto  Hola mundo  Compilar  Build  Link  Debug
  • 3.
  • 4.
    Nueva forma paraE/S  Cualquier compilador de C++, acepta C.  La biblioteca iostream incluye los operadores cin y cout (#include <iostream>).  Ejemplo: char nombre; int num=2; std :: cout << "Introduzca el nombre del archivo " << num << ": "; std :: cin >> nombre;
  • 5.
    Declaración de variables En cualquier lugar del bloque: for (double suma = 0.0, int i = 0; i<n; i++) suma += a[i]  Variables const para tamaño de vectores: int main() { const int SIZE = 5; char cs[SIZE] ; }
  • 6.
    Punteros const  Apuntansiempre a la misma dirección.  El valor de la variable apuntada se puede modificar.  Se declaran así: char* const nombre2 = "Ramón";  Un puntero a variable const no puede modificar el valor de esa variable.
  • 7.
    Punteros a variablesconst  Se declaran así: const char *nombre1 = "Ramón";  El código: #include <stdio.h> int main() { const int i = 2; int *p; p = &i; *p = 3; printf("i = %d", i); } En ANSI C produce i = 3, pero en C++ no compila.
  • 8.
    Conversiones explícitas detipo  Ejemplo de cast: (C y C++) return (int) (x/y);  C++ dispone de otra conversión: y = double(25); return int(x/y);
  • 9.
    Sobrecarga de funciones Funciones distintas con mismo nombre.  Distinto tipo y/o número de argumentos.  No pueden diferir sólo en el tipo de retorno.  Tampoco en que un argumento se pase por valor en una función y por referencia en la otra.
  • 10.
    Parámetros con valorespor defecto  En C++ se pueden definir valores por defecto para todos o algunos argumentos formales.  En la llamada, si no están los argumentos correspondientes, se toma el valor asignado.  Los argumentos con valores por defecto deben estar al final de la lista.
  • 11.
    Parámetros con valorespor defecto  Si se omite un argumento en la llamada, se deben omitir los siguientes en la lista.  Ejemplo: double modulo(double x[], int n=3);  En C++ se puede invocar así: v = modulo(x, n); v = modulo(x);
  • 12.
    Variables de tiporeferencia  Se declaran con el operador '&'.  Deben ser inicializadas.  Nombre alternativo para un objeto.  Utilidades más importantes:  especificación de argumentos.  especificación de tipos de retorno.  sobrecarga de operadores.
  • 13.
    Variables de tiporeferencia int i = 1; int& r = i; // r e i ahora se refieren al // mismo int int x = r; // x = 1 r = 2; // i = 2 r++; // i se incrementa a 3  Ningún operador opera sobre una referencia.  El valor de una referencia no se puede modificar (siempre se referirá al mismo objeto).  &r es un apuntador al objeto denotado.
  • 14.
    Los operadores newy delete  Hasta ahora variables estáticas o automáticas.  Con new y delete se crean y destruyen variables según la necesidad del programador.  Una variable puede traspasar su bloque.  Se puede crear cualquier tipo de variable con new y éste retorna un puntero de ese tipo.  No se necesita conversión de tipo.
  • 15.
    Clases, objetos ymétodos  Las clases se pueden ver como una generalización de las estructuras.  Son verdaderos tipos de datos definidos por el usuario.  Los objetos son las variables de una determinada clase.  Los métodos pueden ser funciones u operadores.
  • 16.
    Estructura de unprograma  En los archivos de cabecera (.h), por lo general, se declara la clase, con los prototipos de las funciones.  En un archivo NombreClase.cpp de implementan los constructores, funciones y operadores.  En un archivo main.cpp se define la función main.
  • 17.
    Ejemplo: complejo.h  Sedeclaran los campos miembro privados: class Complejo { private: double real; double imag;  Los usuarios de la clase no podrán acceder con los operadores '.' y '->'.  Las funciones miembro sí tienen acceso.
  • 18.
    Ejemplo: complejo.h  Sedeclaran un conjunto de funciones y operadores miembro en la sección pública.  Las tres primeras son los constructores: public: // Constructores Complejo(); Complejo(double, double im=0.0); Complejo(const Complejo&);
  • 19.
    Ejemplo: complejo.h  Elsiguiente grupo de funciones permite dar valor a los campos: void setData(); void setReal(double);  O acceder a ellos: double getReal(){return real;} double getImag(){return imag;}
  • 20.
    Ejemplo: complejo.h  Acontinuación se declara la sobrecarga de los operadores aritméticos, comparación y asignación (operadores miembro). Complejo operator+ (const Complejo&);  Y luego la sobrecarga del operador de inserción en el flujo de salida (operador amigo) friend ostream& operator<< (ostream& const Complejo&);
  • 21.
    Sobrecarga de operadores //operador miembro + sobrecargado Complejo Complejo::operator+ (const Complejo &a) { Complejo suma; suma.real = real + a.real; suma.imag = imag + a.imag; return suma; }
  • 22.
    Sobrecarga de operadores Los operadores y funciones miembro se indican con el operador de resolución de alcance '::' (no así los amigos).  En una sentencia x + y; // x, y complejos se utiliza el operador sobrecargado.  x es el argumento implícito.  y se pasa explícitamente (como argumento formal a) .
  • 23.
    Puntero this  Lasobrecarga de '=' retorna (*this) que representa al argumento implícito.  Es una variable predefinida para todas las funciones (u operadores) miembro.  Contiene la dirección del objeto correspondiente.  Forma de referirse al objeto como tal (argumento implícito).
  • 24.
    Constructores  Se debedar valor inicial a las variables miembro. Esto se hace a través de constructores.  Se invocan automáticamente al crear un objeto de una clase.  Permiten la encapsulación.  Tienen el mismo nombre que la clase.  No tienen valor de retorno (ni siquiera void).
  • 25.
    Inicializadores  Los constructoresinicializan variables.  C++ permite inicializar variables fuera del cuerpo de una función. C_Cuenta::C_Cuenta(double unSaldo, double unInteres): Saldo(unSaldo), Interes(unInteres) // inicializadores { } // En este caso el cuerpo del constructor está vacío  Permiten definir variables miembro const.
  • 26.
    Constructor por defecto Es un constructor que no necesita que se le pasen argumentos para inicializar las variables. Hay dos opciones:  No tiene argumentos.  Tiene argumentos, pero todos ellos tienen asignado un valor por defecto en la declaración.  Es necesario para declaraciones de la forma Complejo z; y Complejo datos[100];
  • 27.
    Constructor de oficio Lo crea el compilador de C++ si el programador no define ningún constructor.  No tiene argumentos, es un constructor por defecto (no siempre un constructor por defecto es un constructor de oficio).  Suelen ser cómodos, correctos y suficientes.
  • 28.
    Constructor de copia Se utiliza cuando se debe crear un objeto a partir otro objeto de la misma clase.  Tiene un único argumento que es una referencia constante a un objeto de la clase.  El compilador también define un constructor de copia de oficio si el programador no lo hace (no funciona correctamente con punteros).
  • 29.
    Constructores y operadorde asignación (=). z2 = z1;  Se supone que c1 y c2 existían previamente.  Se utiliza el operador de asignación que funciona como un constructor de copia.  Se debe sobrecargar '='. Complejo z2 = z1;  Se invoca al constructor de copia.  El constructor de copia por defecto es una copia bit a bit.  Se debe sobrecargar.
  • 30.
    Destructores  Es llamadocuando el objeto va a dejar de existir.  Para un objeto local o automático definido en un bloque, el destructor es invocado cuando el programa llega al final del bloque.  Los objetos creados con new deben ser explícitamente destruidos.
  • 31.
    Clases y funcionesfriend  Las funciones miembro (que acceden a las variables miembro) sólo pueden ser miembro de una única clase.  Una función friend de una clase es una función que no pertenece a la clase, pero que tiene permiso para acceder a sus funciones y variables miembro.  Una clase friend de otra tiene todas sus funciones amigas de esa segunda clase.
  • 32.
    Herencia class ClaseDerivada: publico private ClaseBase  Un nombre redefinido oculta el nombre heredado.  Hay algunos elementos de la clase base que no pueden ser heredados:  Constructores  Destructores  Funciones friend  Funciones y datos estáticos de la clase  Operador de asignación (=) sobrecargado
  • 33.
    Constructores de clases derivadas Debe llamar al constructor de la clase base.  Se debe especificar un inicializador base.  Se puede omitir si la clase base cuenta con un constructor por defecto. C_CuentaJoven(const char *unNombre, int laEdad, double unSaldo=0.0, double unInteres=0.0): C_Cuenta(unNombre, unSaldo, unInteres)
  • 34.
    Herencia múltiple  Unaclase puede heredar de una (herencia simple) o más clases base (herencia múltiple). class CuentaEmpresarial: public Cuenta, public Empresa
  • 35.
    Polimorfismo Funciones Virtuales  Sonfunciones distintas con el mismo nombre, declaradas virtual en la clase base (ligadura dinámica).  Funciones convencionales se invocan de acuerdo al tipo del objeto (en tiempo de compilación).  Con funciones virtuales se resuelve en tiempo de ejecución el problema de la asignación.
  • 36.
    Funciones virtuales class A{ public: virtual void mostrar(); } class B: public A { public: void mostrar(); } A objA; B objB; A* ptrA1; A* ptrA2; ptrA1 = &objA; ptrA2 = &objB; ptrA2->mostrar();
  • 37.
    Funciones virtuales puras La función virtual de la clase base debe declararse a pesar de no ser utilizada.  En este caso no es necesario definirla.  Se declara como función virtual pura: virtual funcion1() const = 0;  No se pueden definir objetos de esa clase.  Se pueden definir punteros a esa clase.
  • 38.
    Clases abstractas  Contienenuna o más funciones virtuales puras.  Si una clase derivada no define una función virtual pura, la hereda como pura y por lo tanto también es abstracta.  Una clase que define todas las funciones virtuales es una clase concreta.
  • 39.
    Entrada/Salida  Stream oflujo: dispositivo que produce o consume información.  Flujos estándares:  cin: entrada estándar (teclado).  cout: salida estándar (pantalla).  cerr: salida de mensajes de error (pantalla).  Las clases istream, ostream e iostream son clases que heredan de ios.
  • 40.
    Manipuladores  Variables y/ométodos miembro que controlan el formato.  Pueden tener argumentos (iomanip) o no (iostream).  Sólo afectan al flujo al que se aplican.  No guardan la configuración anterior (como sí lo hacen los indicadores).
  • 41.
    Manipuladores  Ejemplos:  endl:se imprime un ‘n’ y se vacía el buffer de salida.  flush: se vacía el buffer de salida.  setw(int w): establece la anchura mínima de campo. cout << hex << 100; cout << setw(10) << mat[i][j] << endl;  El efecto permanece hasta que se cambia por otro manipulador.
  • 42.
    E/S de archivos En la biblioteca fstream se definen las clases ifstream, ofstream y fstream, que derivan de istream y ostream y a su vez de la clase ios.  Ejemplos: fstream archivo; archivo.open("datos.dat", ios::in); ifstream archivo("datos.dat");
  • 43.
    Excepciones  Parte delcódigo puede no ejecutarse por algún error inesperado.  Si ocurre una excepción se interrumpe la normal ejecución del código.  Se pueden manejar realizando una acción adecuada para dejar al sistema en un estado estable.
  • 44.
    Excepciones en C++ Se separa el código para el caso en que ocurre una situación excepcional y el que no:  try: identifica un bloque de código en el cual puede surgir una excepción.  throw: causa que se origine una excepción.  catch: identifica el bloque de código en el cual la excepción se maneja.
  • 45.
    Excepciones en C++ intmain(void) { int counts[] = {34, 54, 0, 27, 0, 10, 0}; int time = 60; // One hour in minutes for(int i = 0 ; i < sizeof counts /sizeof counts[0] ; i++) try { cout << endl << "Hour " << i+1; if(counts[i] == 0) throw "Zero count - calculation not possible."; cout << " minutes per item: " << static_cast<double>(time)/counts[i]; } catch(const char aMessage[]) { cout << endl << aMessage << endl; } return 0; }
  • 46.
    Excepciones en C++ Cuando la excepción es lanzada (throw) la secuencia de ejecución continúa con el bloque catch.  Después de ejecutarse el código del bloque catch la ejecución continúa con la siguiente iteración del for.  El compilador considera los bloques try y catch como una única unidad.