• No results found

PRINCIPLES FOR EFFECTIVE COUNTERINSURGENCY

Un programa en C++ puede terminar por las siguientes causas: • Sentencia return desde main()

• Llamada a la función exit() desde cualquier función • Llamada a la función abort() desde cualquier función • Por lanzar una excepción no capturada

Por último, queremos destacar la función que aparece en el Código fuente 128.

int atexit(&fnct); // necesita #include <cstdio>

© Grupo EIDOS 9. Organización de código en C++

133

que ejecuta el código de fnct al salir de la correspondiente función. Debemos destacar que el número de llamadas a atexit está limitado en cada programa. Cuando se alcanza ese límite, se devuelve el valor 0.

Ejercicios

1. Definamos la función g como: int g(double x, float* r, int& a) { ... } ¿cuál de las siguientes invocaciones es correcta?

g(x, 2.0, a); g(&x, r, 1); g(x, &r, a); g(1.0, &r); 2. ¿Es correcto el siguiente código? ¿Porqué?

#include <cstdio> #include <iostream> using namespace std; int g (char *a) { return strlen(a); } int main() { char *z = "Visual C++"; int i = g(z);

cout << "i: " << i << endl; return 0;

}

3. ¿Es correcto el siguiente código?

void erase (double); void erase (float); void hh() { erase(1.0); }

4. ¿Es correcto el siguiente código?

void f (int x, double y = 0.0); void f (int x);

void g (int x) { int h = f(x); }

5. ¿Es correcto el siguiente código?

void f (int x, double y = 0.0, int z);

Lenguaje C / C++ / Visual C++ 6 © Grupo EIDOS

134

void f (int z, double y = 0.0, int x = 1);

7. Realizar un programa que calcule el factorial de un número entero a partir de una función recursiva. El factorial de un número N se define por el producto de sí mismo por todos los enteros positivos menores que él hasta 1, es decir: N*(N-1)*...*2*1.

8. Realizar una versión en C++ del programa cal descrito en el ejercicio 10, capítulo 5 (parte C). (Nota: la manipulación de argumentos en la línea de comandos es igual en C y en C++; el ancho del campo de impresión en cout se expresa llamando a la función cout.width(ancho);

antes de usarlo).

9. Crear una función para dividir dos números de doble precisión y que lance una excepción antes de dividir por cero.

10. Utilizar esta función para un programa calculadora que divide dos números introducidos por el usuario. Capture las excepciones lanzadas.

Respuestas a los ejercicios

1. Definamos la función g como: int g(double x, float* r, int& a) { ... } ¿cuál de las siguientes invocaciones es correcta?

g(x, 2.0, a); g(&x, r, 1); g(x, &r, a); g(1.0, &r); Respuesta:

g(x, 2.0, a); g(&x, r, 1); g(1.0, &r);

2. ¿Es correcto el siguiente código? ¿Porqué?

#include <cstdio> #include <iostream> using namespace std; int g (char *a) { return strlen(a); } int main() { char *z = "Visual C++"; int i = g(z);

cout << "i: " << i << endl; return 0;

}

Respuesta: Sí. Porque a es una cadena de caracteres. 3. ¿Es correcto el siguiente código?

© Grupo EIDOS 9. Organización de código en C++

135

void erase (double); void erase (float); void hh() { erase(1.0); }

Respuesta: No. No es posible determinar que función llamar. 4. ¿Es correcto el siguiente código?

void f (int x, double y = 0.0); void f (int x);

void g (int x) { int h = f(x); }

Respuesta: No. No es posible determinar que función sobrecargar. 5. ¿Es correcto el siguiente código?

void f (int x, double y = 0.0, int z);

Respuesta: No. El argumento y debería ser el último de la lista. 6. ¿Es correcto el siguiente código?

void f (int z, double y = 0.0, int x = 1);

Respuesta: Sí.

7. Realizar un programa que calcule el factorial de un número entero a partir de una función recursiva. El factorial de un número N se define por el producto de sí mismo por todos los enteros positivos menores que él hasta 1, es decir: N*(N-1)*...*2*1.

#include <iostream> using namespace std; long fact (int i) {

return (i > 1) ? i * fact (i-1) : 1; }

int main() {

int x;

cout << "Introduce un numero entero: "; cin >> x;

cout << "Factorial de " << x << " = " << fact (x) << endl; }

8. Realizar una versión en C++ del programa cal descrito en el ejercicio 10, capítulo 5 (parte C). (Nota: la manipulación de argumentos en la línea de comandos es igual en C y en C++; el

Lenguaje C / C++ / Visual C++ 6 © Grupo EIDOS

136

ancho del campo de impresión en cout se expresa llamando a la función cout.width(ancho);

antes de usarlo).

#include <iostream> #include <cstdlib> using namespace std; int bisiesto (int year) {

if ( ( year % 4 == 0 && year % 100 != 0 ) || (year % 400 == 0) ) return 1;

return 0; }

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

int i, dia_Ene1, mes, agno, fecha;

int dias_mes[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; char* nombre_mes[] = { "enero", "febrero", "marzo", "abril",

"mayo", "junio", "julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre" };

char _string[60]; if (argc != 3) {

cout << "Uso: ex8 mes año\n"; exit (1);

}

mes = atoi (argv[1]); agno = atoi (argv[2]); if (mes < 1 || mes > 12) {

cout << "Error en la lectura del mes.\n"; exit (1);

}

if (agno < 1900) {

cout << "Error en la lectura del año.\n"; exit (1);

}

// Averiguando el dia de la semana para el año

for (fecha = 1900, dia_Ene1 = 1; fecha < agno; fecha++) {

if (bisiesto (fecha)) dia_Ene1 += 2; else dia_Ene1++;

if (dia_Ene1 >= 7) dia_Ene1 -= 7; }

// 366 dias para un año bisiesto if (bisiesto (agno)) ++dias_mes[1]; for (i = 1; i < mes; i++)

dia_Ene1 = (dia_Ene1 + dias_mes[i-1]) % 7; cout.width (15); cout << nombre_mes[mes-1] << ' '; cout.width (5); cout << agno << endl;

cout << "Dom Lun Mar Mie Jue Vie Sab\n" << "--- --- --- --- --- --- ---\n";

for (fecha = 1; fecha <= dia_Ene1 * 4; fecha++) cout << ' ';

for (fecha = 1; fecha <= dias_mes[mes-1]; fecha++) {

cout.width (3); cout << fecha;

if ((fecha + dia_Ene1) % 7 > 0) cout << ' '; else cout << endl;

© Grupo EIDOS 9. Organización de código en C++

137

cout << endl; return 0; }

9. Crear una función para dividir dos números de doble precisión y que lance una excepción antes de dividir por cero.

struct DividirCero { };

double dividir (double x, double y) {

if (y == 0.0) throw DividirCero; return y/x;

}

10. Utilizar esta función para un programa calculadora que divide dos números introducidos por el usuario. Capture las excepciones lanzadas.

#include <iostream> struct DividirCero { };

double dividir (double x, double y) { DividirCero tmp; if (y == 0.0) throw tmp; return x/y; } int main() { double x, y;

cout << "Introduce 2 números reales para dividirlos: "; cin >> x >> y;

try {

cout << x << " dividido por " << y << " = " << dividir (x, y) << endl;

}

catch (DividirCero) {

cout << "Error grave: intento de division por cero.\n"; }

return 0; }