¡Esta es una revisión vieja del documento!
Podemos definir variables sin signo, por ejemplo integers, incluyendo unsigned antes del tipo de variable:
unsigned int iNum;
Recuerda que en C, para poder usar un método ha de estar su declaración arriba, si esta no está entonces debería estar toda la función (declaración y cuerpo) antes del código que la llama. La declaración consiste en el tipo devuelto, nombre y parámetros entre paréntesis. Además del ;.
Podemos pasar parámetros de referencia a los métodos, para ello después del tipo de parámetro incluiremos un '&':
void Suma (int& ax, int bx) { ax+=bx; }
Con un parámetro de referencia, el dato pasado en la llamada cambia si el método lo cambia. Cuando se llama a esta función, no puede pasarsele números directamente al primer parámetro, es decir algo así Suma(3, 4), sino que hay que pasar una variable (al menos en el primero) Suma(i, 4).
Podemos dar valores por defecto a los parámetros, entonces podemos prescindir de ellos en su llamada:
int Suma (int a, int b=0) { return a + b; } ... Suma (3); // Devolvería 3
Los parámetros de referencia son más eficientes que los convencionales, ya que en los convencionales el parámetro pasado se vuelve a copiar en memoria y se opera con él, con los de referencia no se hace una copia de memoria sino que es la variable la que es pasada al parámetro y el método, si hace un cambio sobre el parámetro, hace que se cambie la variable.
Cuando declaramos un parámetro de referencia constante indicamos que no se hará una copia del dato, sino que se enviará ese dato (referencia), pero este no podrá cambiarse dentro del método (constante):
int Suma (const int& ax, const int& bx).
En c++ existen varios canales de entrada y de salida, los más usados son cout (chanel output) y cin (chanel input), para acceder a ellos debemos incluir iostream (#include <iostream>) y se usan de la siguiente forma:
cout << "Hola mundo";
cout « endl;getline(cin, str);
En algunos compiladores, para poder usar el getline, deberemos hacer un include de <string>. Aún así el cin puede fallar, por ejemplo cuando indicamos que el cin volcará el contenido de lo introducido por pantalla en un double y el usuario mete un carácter. Pero podemos controlarlo, tras usar el cin podemos llamar al método cin.fail(), este te devolverá un bool indicandote si ha sido correcto (false, no ha fallado el cin) o no (true) lo introducido por el usuario. También podemos controlarlo si sabemos que la llamada a cin devuelve otro bool, si este es true es que se ha realizado correctamente, por lo que deducimos que podemos hacer esto: if (cin » doubleVar) {…}
Recuerda que el operador « sobre cout lo que hace es enviar la salida de la derecha al operando izquierdo, es decir un código como el siguiente…
int i = 0; int func () { i++; return i; } ... cout << func() << func() << func() << func();
… devolvería 4321.
int i = atoi(str.c_str());double d = atof(str.c_str());atolsstream):ostringstream myStream; myStream << num << flush; myStriam.str();
Existe otra conversión de integer a ascii (char), se llama atoi y se le pasan 3 parámetros: el integer a convertir, un array de carácteres y la base de la conversión (generalmente 10).
int i = 5; char buffer [33]; itoa (i,buffer,10); printf ("decimal: %s\n",buffer); itoa (i,buffer,16); printf ("hexadecimal: %s\n",buffer); itoa (i,buffer,2); printf ("binary: %s\n",buffer);
Podemos declarar constantes mediante la palabra “const”. Ej.
const double DOLLAR_VALUE = 100;
switch (variable) { valor1: ... break; valor2: ... break; default: }
En C el random lo encontramos en la función rand, sin argumentos. Podemos indicar una nueva semilla para que haga un nuevo número aleatorio pasándole un int.
int a = rand()%2;
int rand_int(int a, int b) { return a + rand() % (b - a + 1); }
double rand_double(double a, double b) { return a + (b - a) * rand() * (1.0 / RAND_MAX); }
srand( (unsigned)time( NULL ) );
rint(d) → Redondea al entero más cercano.#include <librería>#include “fichero.h”class clase;void metodo ();#define COLS = "abcdefgh"; #define TOTAL 10 #define getrandom(min, max) \ ((rand()%(int)(((max) + 1)-(min)))+ (min)) #define MSGBOX(body) MessageBox(NULL,body,"",MB_OK); ... int i = TOTAL; MSGBOX("holaaa!!");
int array[10];int array[] = {1,2,3};
void Probando (int array[]) { ... }
int array[2][2];
int main(int argc, char* argv[]) {...}
int main (int nargs, char* argv[]) { printf("%d\n%s\n", nargs, argv[0]); }
int i = 4; int *a = &i; cout << a << endl; cout << *a << endl;
What does it mean?
int *i=NULL;, de esta forma 'i' no apunta a ningún sitio y podemos usarlo luego en un if: if (i != NULL) ...
if (i) // pregunta si i tiene algo, si es NULL no entrará en el if
int **b = &a;
Esta línea es un puntero a otro puntero.
int i[] = {1,2,3,4}; int *a = i; // *a = i[0]; *a = 33; // i[0] = 33;
*(a + 1) = 23; // i[1] = 23;
new este sí que se mantendrá, por lo que es importante el uso del delete.r = (int*)0x0012f144; r = (int*)55;
int *c = new int; *c = 3;
int iA = 4; // Un integer iA con valor 4 int* pA = &iA; // Un puntero a int llamado pA apunta a la direción de iA int* pB = pA; // Un puntero a int llamado pB apunta donde apunta pA int iB = *pB; // Un integer iB con valor al que apunta pB *pB = 5; // El valor que contiene la dirección donde apunta pB = 5
Al hacer puntero = new <tipo> lo que estamos haciendo es reservar un espacio de memoria para una variable\objeto del tipo indicado y apuntar a ese espacio con el puntero. Aunque el valor no esté inicializado ese espacio es para ese puntero.
int *i = new int; *i = 5; char *a = new char[10];
Al hacer 'delete puntero' el espacio de memoria al que apuntaba antes el puntero queda libre, puede volver a ser asignado.
delete i;
Por lo que si hacemos el siguiente código el resultado resultante podremos comprobarlo:
int *i = new int; *i = 6; delete i; int *a = new int; *a = 50; cout << i << endl;
Lo que se nos mostrará al final por pantalla será 50. Veamos las líneas:
Si quisiesemos eliminar todo un array deberemos usar delete[].
char *a = new char[10]; delete[] a;
Hemos de tener en cuenta que si antes de hacer el 'delete[] a' hemos hecho un incremento de a: a++, el delete dará error.
Podemos desreservar el espacio que ocupan las matrices:
for (i=0; i<files; i++) delete[] x[i]; delete[] x;
Hablando de punteros a arrays:
int* r = new int[10]; r[0] = 3; r[1] = 4;
Es importante no obviar los 'delete', de esta forma liberamos memoria, porque si no el programa podrá llegar a ocupar mucho. Otra de las cosas aconsejadas es asignar NULL al puntero una vez lo hayamos borrado.
Si creasemos un puntero de un integer sin darle ningún valor, este puntero no apuntaría a ningún sitio, por lo que si quisiesemos darle un valor el programa petaría, ya que no podría asignarlo en ningún sitio.
Para que a un puntero podamos dar algún valor debe estar asignado a una posición de memoria, si queremos asignarlo a una nueva posición de memoria debemos reservarla (allocate) antes con malloc, a este se le pasa un tamaño (size_t) y devuelve un puntero void*, por lo que le debemos hacer un cast:
int *num = NULL; num = (int*)malloc(sizeof(int)); *num = 44;
Existen el realloc (vuelve a reservar memoria pero con otro tamaño) y el calloc (para arrays).
if((buffer = (long *)malloc(sizeof(long))) == NULL) exit( 1 );
char* a; a = (char*)malloc(10 * sizeof(char)); *(a + 1) = 'b'; cout << *(a+1);
Cuando dejemos de usar un putero no debemos olvidar liberar la memoria reservada mediante la función 'free'. Para el ejemplo anterior sería algo así:
free(a);
_heapmin()Antiguamente, cuando no existía la clase string, se usaban los arrays de carácteres para almacenar palabras. La definición de un solo carácter sería:
char chr = 'y';
Puedes declarar un array de chars cual string fuere:
char str[] = "Hola amigos!";
Al acabar un array de carácteres, es importante no olvidar añadir: '\0'. Este indica que se ha llegado al fin de la cadena, y si se va a utilizar el array de chars sólo leerá hasta ahí, sino lo leerá todo.
Una cadena de estas puede ser leida como: const char*.
Existen funciones que te permiten trabajar fácilmente con estos tipos de datos:
strcmp → Compara dos cadenas.strcpy → Copia una cadena en otra.strlen → Devuelve el tamaño de la cadena.strtok → Corta la cadena por el carácter especificado.
Otras funciones que pueden sernos de utilidad son las que hacen lo mismo pero con unsigned char:
memcmpmemcpymemmoveUna estructura es una agrupación de datos. Podríamos pensar que son muy parecidas a las clases de C++, pero no es así, ya que sólo son una simple agrupación:
struct lista { int clave; struct lista *sig; string hi; };
Luego para declarar una variable:
lista element;
Y para acceder:
element.hi = "texto";
Hay otra forma de declarar una variable:
lista lst = {1, NULL, "hola"};
De esta forma estamos dando valores a los elementos de la estructura según el orden que tienen, podemos dejar elementos sin dar valores, pero esos deberán ser los últimos, que quedarán con valor NULL.
Si creasemos un puntero a un elemento del tipo lista, para acceder a sus variables internas usaríamos ->.
lista *elem; ... elem->clave = 44;
Una estructura puede contener métodos, y hasta un constructor que será llamado cuando se haga un “new” de dicha estructura:
struct Nodo { int clave; struct Nodo *Next; Nodo(int indx) { this->Next = NULL; this->clave = indx; } };
Son una serie de integers dentro de un bloque con un identificador específico.
Podemos declarar las enumeraciones de la forma siguiente:
enum Dias {Lunes, Martes, Miercoles};
Por defecto Lunes tiene valor 0, Martes 1 y Miercoles 2. Aún así podemos cambiar los valores:
enum Dias {Lunes = 1, Martes = 2, Miercoles = 3};
Luego podemos declarar variables del tipo 'Dias':
Dias hoy;
Y asignarlas:
hoy = Lunes;
No podemos asignar integers a hoy, aunque hoy realmente sea un integer:
hoy = 0; // Error!
Pero sí que podremos hacerlo al revés:
int DiaUno = Lunes;
Y también podemos hacer lo siguiente:
Dias d = Miercoles;
int i = d;
Para asignar a una variable de enumeración un integer, debemos hacer un cast:
Dias d = (Dias)2;
Hay que tener cuidado con los nombres de variables, no podremos repetir los nombres usados dentro de la enumeración ni el identificador de la enumeración.
Para enviar un valor de una enumeración a una función haremos lo siguiente:
void show (Dias d) { cout << d; }
Y también podemos usarlas en if's y switch's:
if (i == Lunes) ... switch (d){ case Lunes: ...
Si hacemos:
enum Dias {Lunes = 2, Martes, Miercoles};
Lunes valdrá 2, Martes 3 y Muercoles 4. Y si hacemos:
enum Dias {Lunes, Martes = 3, Miercoles};
Lunes valdrá 0, Martes 3 y Miercoles 4.
std, y que para usarlo debemos hacer un include.c_str().length() → Devuelve el tamaño de la cadena.insert(str, i) → Inserta la cadena str en la posición i.substr(i1, i2) → Devuelve un string de i2 carácteres a partir de i1.replace(i1, i2, str) → Cambia a partir de i1, i2 carácteres por los de str.erase (i1, i2) → Elimina i1 carácteres a partir de i2.find (str, i) → Indice de la primera aparición de str a partir de i.rfind(str, i) → Igual a find pero hacia atrás.c_str() → Pasa el string a constant char.Podemos concatenar strings mediante el operador '+'.
#include <vector>) podemos usar la clase vector, que corresponde a un array dinámico, un vector es menos óptimo que un array. Recuerda que esta clase está dentro del namespace std.vector<tipo dato> nombreVec;vector<tipo dato> nombreVec[tamaño];vector<int*> array;size() → Devuelve el tamaño del vectorpop_back() → Elimina el último elemento del vectorvector<int> Sumar (vector<double>) {...}
vector<double>& v
Las funciones de C clasificadas por librerías. Para utilizar una tendrás que incluir el .h correspondiente, por ejemplo: #include <math>
tan, atan, sin, asin, cos, acos para cálculos trigonométricos.pow pasándole dos doubles eleva el primero al segundo.sqrt calcula la raíz cuadrada.fabs calcula el valor absoluto.log calcula el logaritmo neperiano y log10 el logaritmo en base 10.fmod calcula el resto de coma flotante de dos doubles.exp calcula la función exponencial.clock tiempo de uso del procesador. La frecuencia en la que se mide este tiempo viene dada por la macro CLOCKS_PER_SEC, por lo que para saber cuantos segundos lleva el ordenador encendido haremos: clock()/(double)CLOCKS_PER_SEC.time, esta función devuelve el tiempo de la máquina; el tipo devuelto es un time_t y el que se le pasa como parámetro una referencia a una variable de este tipo, si esta que se le pasa por parámetro no es NULL colocará en ella tambiénen el resultado.localtime convierte un time_t en un tm, otra estructura de tiempo más legible en la que se especifican los segundos, minutos…mktime hace lo contrario a localtime, convierte un tm en time_t.difftime calcula la diferencia entre dos time_t en segundos expresada en double.A parte de las funciones…
tolower devuelve el char indicado como minúscula.toupper deuvelve el char indicado como mayúscula.… contiene una serie de macros que nos indican mediante un integer (que si es 0 es false):
isalnum (A - Z o a - z) o (0 - 9) isalpha (A - Z o a - z) isascii 0 - 127 (0x00-0x7F) iscntrl (0x7F o 0x00-0x1F) isdigit (0 - 9) isgraph Imprimibles menos ' ' islower (a - z) isprint Imprimibles incluido ' ' ispunct Signos de puntuación isspace espacio, tab, retorno de línea, cambio de línea, tab vertical, salto de página (0x09 a 0x0D, 0x20). isupper (A-Z) isxdigit (0 to 9, A to F, a to f)
Librería con funciones que controlan datos de la 'localidad' de la máquina (si utiliza comas en vez de puntos para los decimales, moneda…).
memchr encuentra un carácter en una cadena.memset copia un valor todo seguido en memoria tantas veces como sea especificado.strpbrk encuentra una cadena en otra.strcpy copia una cadena en otra.memcmp compara porciones de memoria.strtok separa la cadena en porciones.strcmp compara dos cadenas.memcpy hace una copia de una porción de memoria.strcat concatena dos cadenas.strerror convierte un número de error en una cadena de carácteres.div calcula el cociente y el resto de una división devolviendote el resultado en una estructura.abs, labs calculan el valor absoluto en ints.realloc cambia el tamaño asignado a un puntero.atol convierte una cadena en long.atof convierte una cadena en double.atoi convierte una cadena a int.exit finaliza el programa con un estado pasado por parámetro.srand y rand para calcular números aleatorios.system ejecuta un comando.malloc asigna espacio a un puntero.free libera el espacio de un puntero.getenv devuelve un array con los directorios de un path específico.mblen devuelve el tamaño asignado aun puntero.qsort realiza el algoritmo de quicksort sobre un array, has de pasarle un puntero a función que calcule el mayor\menor.strtoul pasa un integer en base x pasado como string a uno en base 10. Los parámetros: el string, NULL, y la base en la que se pasa el valor de entrada. Por ejemplo x en int x = strtoul(“0000110”, NULL, 2); tendría como valor 6.
Para lectura y escritura de datos por canales de entrada salida. Muchas de las funciones de consola equivalen a las de ficheros sólo que el puntero al destino (el fichero) es asignado como stdout, un puntero al stream de salida por defecto. El canal de entrada es stdin.
printf escribe por consola una cadena con el formato especificado.getchar lee un carácter del canal de entrada por defecto.gets lee una cadena del canal de entrada por defecto.putchar muestra un carácter por consola.puts muestra una cadena por consola.scanf lee por consola una cadena.fflush envia al fichero todos los datos que quedan en el buffer.fopen abre un fichero, retorna un FILE (descriptor de este) y se le pasan dos cadenas, la primera la dirección, la segunda el modo de apertura (r (lectura), w (escribe borrando el contenido), a (añade), rb (lectura binaria), wb (escritura binaria), ab (añadir binaria), r+ (fichero de texto para leer y escribir), w+ (crea si no existe y escribe borrando el contenido), a+ (añade sobre un fichero existente o no), lo mismo para rb+, wb+, ab+).fputs escribe una cadea en un fichero. Para carácteres existe fputc. También existen puts y putc.fseek se coloca en una posición de un fichero. Se le pasan por parámetro el FILE, un int de desplazamiento y una de las siguientes macros que definen el orígen: SSEK_CUR si es la posición actual del puntero, SEEK_SET si es la posición inicial del fichero y SEEK_END el final.remove elimina un fichero, este ha de estar cerrado.tmpfile crea un fichero temporal, que será eliminado automáticamente una vez se cierre, su modo es wb+.tmpnam da un nombre válido para un fichero temporal.rename renombra un fichero.fgetc obtiene un carácter de un fichero. También existe getc y fgets que lee una cadena.fclose cierra el fichero.feof indica si el puntero del fichero está al final de este.fread lee una porción de fichero y la coloca en la memoria indicada.fwrite escribe una porción de memoria en un fichero.fprintf escribe en un fichero unos carácteres con el formato indicado.fscanf lee de un fichero mediante un formato de lectura indicado.rewind coloca el puntero del fichero al principio.sscanf lee de una porción de memoria con un formato de lectura indicado.sprintf escribe sobre una porción de memoria con el formato indicado.perror convierte un número de error en una secuencia de carácteres que saca por el canal por defecto de errores. Esta cadena es la dada por la función strerror de string. El número de error viene dado por el retorno de la función y puedes controlarlo incluyendo la errno.h, esta trae una serie de defines sobre los tipos de errores.
A parte de las generalmente conocidas #include o #define, existen directivas para el preprocesador que pueden sernos de utilidad:
Imaginemos clase Producto, declarada en archivo .h. Debemos asegurarnos que el compilador no compila varias veces este .h, no sólo por eficiencia sino también por la posivilidad de que nos dé un error, para ello usaremos las líneas siguientes en el .h:
#ifndef PRODUCT_H #define PRODUCT_H <declaracion de la clase Producto> #endif
Esto es una condición al compilar, que indica si no está definido PRODUCT_H haz…, y lo primero que hace es definirlo para que así cuando se vuelva a llamar no se recompile.
También existe el #if del preprocesador; podemos utilizarlo para, por ejemplo, controlar si se han hecho una serie de defines y si es así ejecutar un código u otro, esto nos sirve para codificar condicionalmente.
#if defined( WIN32 ) && defined( TUNE ) #include <crtdbg.h> _CrtMemState startMemState; _CrtMemState endMemState; #else #include <otros.h> #endif
Otras directivas pero estas no son compatibles con todos los compiladores. Van siempre seguidas de otra directiva que indica la función que hace, por ejemplo once:
#pragma once
Las directivas que pueden seguir a #pragma son:
#ifndef.
Si quieres declarar una variable en un archivo de definiciones (.h) no podrás hacerlo, ya que allí no podrás darle ningún valor. Para ello has de darle el valor en el archivo de código (.cpp).
Aún así, para poder inicializar la variable externamente debemos incluir antes de la declaración la clausula 'extern'. En el archivo .h tendremos:
extern int iVal;
y en el .cpp:
int iVal = 33;
#include<cassert> en unos compiladores, en otros #include <assert.h>assert (i > 3); ← si i no es mayor que 3 el compilador actúa.
Por qué frases tan abstractas como “el compilador actúa” o “debería dar error”? Porque esto va según la config del compilador. Algunos, en código release no hacen caso de los asserts, otros ni en debug. Aún así son muy útiles, ya que generalmente hacen que el programa se pare indicando un error de aserción, donde se encuentra y el por qué.
Si quieres desactivar los assert añade #define NDEBUG.
Para manejar ficheros en C necesitamos un puntero de tipo FILE, este será asignado por la función fopen a la que se le pasa el nombre de fichero y la forma de abertura, esta puede ser:
Para cerrar un fichero usamos la función fclose.
FILE *pf; pf=fopen("AGENDA.DAT","rb"); if ( pf == NULL ) printf ("Error al abrir el fichero"); else fclose(pf);
Para el acceso a ficheros existen una serie de clases que nos facilitan el trabajo. Para poder tener acceso a ellas necesitamos incluir la librería iostream: #include <iostream> (debemos usar también el namespace std) (En algunos compiladores también tendremos que incluir fstream).
La clase que usaremos para leer archivos es ifstream, podemos crear un objeto de esta y llamar a su método open pasandole el nombre del archivo a leer. Se usa como el cin:
ifstream f; f.open("c:\\prueba.txt"); int i; f >> i; cout << i << endl; double d; f >> d; cout << d << endl;
Vamos volcando el contenido sobre las variables del tipo que queramos. Pero cuando vamos a leer strings sólo capturamos palabras, hasta el próximo espacio, por lo que debemos hacer uso del método getline. A getline le pasaremos como canal de entrada nuestro objeto ifstream, recuerda que para usar el getline has de incluir “string”.
string s; getline(f, s); cout << s << endl;
close.unget → se mueve en el fichero a un carácter antesget → recoge el siguiente carácterreadofstream.« o », de esta forma podemos sobreescribir dichos operadores y enviar nuestras clases.ifstream para escribir, todo según los parámetros que le pasemos al método open. Este sigue la siguiente sintaxis: var.open (nombrefichero, ios::modo_apertura);. Y los modos de apertura son:std::ofstream f2; f2.open("fichero2.txt", std::ofstream::out);
seekg (pos, camino); → El puntero se coloca en un apartado del fichero, pos: long posición inicial, camino: hacia donde (ios::beg (al principio), ios::end (al final), ios::cur (posición actual)).var.tellg(); → Coge la posición actual del puntero. Ej. Si hacemos un var.seekg(0, ios::end); y luego recogemos lo que nos devuelva var.tellg(); podremos saber el tamaño del archivo. También podemos crear una cadena de caracteres de ese tamaño y luego volcar el archivo en ella con var.read(cadena creada, tamaño);f2.open("fichero2.txt", ofstream::out | ofstream::trunc);
Podemos programar operadores (+, -, *, ++, +=, ==…) para nuestras clases. Podemos hacerlo de dos formas, la primera internamente en nuestra clase, la segunda globalmente.
Para poder programar un operador haremos: tipodevuelto operatoroperador (parámetros) { }
int operator- (A a) { return a.i - i; }
Ahora podemos hacer int res = objA1 - objA2; y se llamará al restar del objeto objA1 pasándole el 2.
int operator- (A a, A b) { return a.getI() - (b.getI() + 10); }
Aún así, si declaramos este operador de estas dos formas tendremos un problema, y es que cuando hagos el objA1 - objA2 no sabrá a qué función entrar, para ello debemos especificarlo:
b.operator - (a)operator - (a, b) ostream& operator<<( ostream &out, const A &value) { out << value.getI(); return out; }
int RandomInt::operator()() { ... } int RandomInt::operator()(int na, int nb) { ... }
operator int() const { return this->i; }
int i = (int)objA;class A { private: char *abc; public: A() { abc = "abcdefgh"; } char operator[] (int i) { return abc[i]; } };
Luego, al crear un objeto de la clase A, y al pedir, por ejemplo: a[3] recibiríamos 'd'.
void operator delete (void* lista) { cout << ((Lista*)lista)->toString().c_str() << endl; }
Usados para englobar código. Por ejemplo:
namespace Prueba { class F { } }
Este ejemplo declara una clase F dentro del namespace Prueba, podemos acceder a ella mediante Prueba::F.
namespace p = Prueba;
Ahora podemos hacer p::F;
using namespace Prueba; using namespace std;
Ahora ya podemos usar cout o F sin necesidad de poner std:: o Prueba:: delante.
// Fichero .h namespace ns { void func (); }
// Fichero .cpp using namespace ns; void ns::func () { ... }
namespace nm1 { namespace nm2 { ... } } using namespace nm1::nm2;
using std::vector
Cuando declaramos una variable como static, dentro de una función, esa variable conserva el valor con el que ha acabado al salir del método y lo mantendrá cuando vuelva a entrar.
El siguiente ejemplo mostrará 0011:
int func () { static int i = 1; static int num = -1; i++; if (i % 2 == 0) num++; return num; } ... cout << func(); cout << func(); cout << func(); cout << func();
Si quisiesemos definir un valor dentro de una declaración de, por ejemplo, una estructura, deberíamos declarar esa variable como “static”:
struct Queue { static const int ClavesTotal = 10; int anterior, siguiente; int claves[ClavesTotal]; };
Son funciones que insertan su cuerpo en el código donde son llamadas cuando se compila. Pero para ello la función debe cumplir ciertas reglas: No debe contener bucles, switch, o variables estáticas.
try { codigo } catch (<tipo parametro>) { código }throw <objeto>; logic_error, bad_alloc…... throw "Error de conversión"; ... try { ... } catch (char* s) { cout << s << endl; }
typedef int numero;numero i; ← i es un integer Esto nos irá bien cuando el tipo sea largo de declarar:
typedef vector< pair<string, string> > StringMap;
StringMap es del tipo: typedef vector< pair<string, string> >.