B.3. CohsIahIes. B.4. Cohversih de Iipos. B.5. Declaracih de variables. B.6. Operadores. B.7. EhIradas y salidas basicas. B.8. SehIehcias. B.9. SehIehcias cohdiciohales: f. B.10. Bucles: sehIehcias repeIiIivas. B.11. PuhIeros (apuhIadores). B.12. Los operadores nev y deIete. B.13. Array. B.14. Ehumeraciohes, esIrucIuras y uhiohes. B.15. Cadehas. B.16. Fuhciohes. B.17. Clases. B.18. Herehcia. B.19. Sobrecarga de operadores. B.20. PlahIillas (tempIates). B.21. Excepciohes. B.22. Espacio de hombres (Namespaces). A P N D I C E B G U A D E S I N T A X I S A N S I / I S O E S T N D A R C + + C++ es considerado un C ms grande y potente. La sintaxis de C++ es una extensin de C, al que se han aadido numerosas propiedades, fundamen- talmente orientadas a objetos. C ANSI 1 ya adopt numerosas caractersticas de C++, por lo que la emigracin de C a C++ no suele ser difcil. En este apndice se muestran las reglas de sintaxis del estndar clsico de C++ recogidas en al Annotated Reference Manual (ARM), de Stroustrup & Ellis, as como las ltimas propuestas incorporadas al nuevo borrador de C++ ANSI, que se incluyen en las versiones 3.0 (actual) y 4.0 (futura) de AT&T C++. B.1. ELEMENTOS DEL LENGUAJE Un programa en C++ es una secuencia de caracteres que se agrupan en componentes lxicos (tokens) que comprenden el vocabulario bsico del lenguaje. Estos componentes de lxico son: palabras reservadas, identifica- dores, constantes, constantes de cadena, operadores y signos de puntuacin. B.1.1. Caracteres Los caracteres que se pueden utilizar para construir elementos del lenguaje (componentes lxicos o tokens) son: a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 + - * / = ( ) { } [ ] < > ! @ = / $ ^ & % - : . , ; ? \ | caracteres espacio (blancos y tabulaciones). B.1.2. Comentarios C++ soporta dos tipos de comentarios. Las lneas de comentarios al estilo C y C ANSI, tal como: /* Comentario estilo C*/, se puede extender /* hasta que aparece la marca de cierre */ // Este tipo de comentario termina al final de la lnea // Slo es posible una lnea de comentario La versin /*...*/ se utiliza para comentarios que excedan una lnea de longitud, y la versin //... se utiliza slo para comentarios de una lnea. Los comentarios no se anidan. B.1.3. Identificadores Los identificadores (nombres de variables, constantes, etc.) deben comenzar con una letra del alfabeto (mayscula o minscula) o con un carcter subra- CONTENDO 1 Se utiliza indistintamente los trminos ANSI C (nombre ingls) y C ANSI, traduccin al espaol muy usada en la vida profesionbal y acadmica. yado y pueden tener uno o ms caracteres. Los caracteres segundo y poste- riores pueden ser letras, dgitos o un subrayado, no permitindose caracte- res no alfanumricos ni espacios. test_prueba //legal X123 //legal multi_palabra //legal var25 //legal 15var //no legal C++ es sensible a las maysculas. Las letras maysculas y minsculas se consideran diferentes. Paga_mes es un identificador distinto a paga_mes Buena prctica de programacin aconseja utilizar identificadores sig- nificativos que ayudan a documentar un programa. nombre apellidos salario precio_neto Edad Longitud Altura Salario_Mes B.1.4. PaIabras reservadas Las palabras reservadas o claves no se pueden utilizar como identificadores, debido a su significado estricto en C++; tampoco se pueden redefinir. La Tabla B.1 enumera las palabras reservadas de C++ segn el ARM 2 . Los diferentes compiladores comerciales de C++ pueden incluir, adems, nuevas palabras reservadas. Estos son los casos de Borland, Micro- soft y Symantec. 564 PROGRAMACIN EN C++. ALGORITMOS, ESTRUCTURAS Y OBJETOS TABLA B.1. Palabras reservadas (Keyvds) de ANS/SO C++ asm* default for new* sizeof typedef auto delete* friend* operator* static typename bool* do goto private* struct union break double if protected* switch unsigned case else inline* public* template* using catch* enum int register this* virtual* char explicit* long return throw* void class* extern mutable* short true* volatile* const false* namespace* signed try* while continue float * Estas palabras no existen en C ANSI. 2 Siglas del libro de Margaret Ellis y Bjarne Stroustrup en el que se definen las reglas de sintaxis del lenguaje C++ estndar, Annotated Reference Manual, Addlson-Wesley, 1992. TABLA B.2. Palabras reservadas de Borlahd C++ 5 __asm __cdecl _ _cs __declspec __ds __es __except _ _export __far __fastcall __finally __huge _ _import __interrupt __loadds __near __pascal _ _rtti __saveregs __seg __ss __stdcall _ _thread __try _asm _cdecl _cs _ds _es _export _far _fastcall _huge _import _interrupt _loadds _near _pascal _saveregs _seg _ss _stdcall asm auto bool break case catch cdecl char class const const_cast continue default delete do double dynamic_cast else enum explicit extern false far float for friend goto huge if inline int interrupt long mutable namespace near new operator pascal private protected public register reinterpret_ cast return short signed sizeof static static_cast struct switch template this throw true try typedef typeid typename union unsigned using virtual void volatile wchar_ t while TABLA B.3. Palabras reservadas de Visual C++ 6 _asm _fastcall public signed _except new unsigned void _virtual_inheritance typedef using directive do throw class default _leave case goto _int8 struct _finally register sizeof auto operator using declaration volatile explicit typeid uuid double mutable const delete long true if _intl6 switch catch reinterpret_cast static template flota return wmain _based private _uuidof dynamic-cast extern typename dl1export man naked const-cast _int32 _multiple try inline _inheritance static-cast this _cdecl _inline while bool for short else false protected virtual enum namespace union dllimport -single-inheritance _try continue _int64 thread char _dec1spec _stdcall break friend int xalloc El comit ANSI ha aadido nuevas palabras reservadas (Tabla B.4). TABLA B.4. Nuevas palabras reservadas de ANS C++ bool false reinterpret_cast typeid cons_cast mutable static_cast using dynamic_cast namespace true wchar_t B.2. Tipos de datos Los tipos de datos en C++ se dividen en dos grandes grupos: integrales (datos enteros) y de coma flotante (datos reales). La Tabla B.5 muestra los diferentes tipos de datos en C++ TABLA B.5. Tipos de daIos simples eh C++ char signed char unsigned char short int long unsigned short unsigned unsigned long float double long double Los tipos derivados en C++ pueden ser: enumeraciones (enum) estructuras (struc) uniones (union) arrays clases (class y struct) uniones y enumeraciones annimas punteros B.2.1. Verificacin de tipos La verificacin o comprobacin de tipos en C++ es ms rgida (estricta) que en C. Usar funciones declaradas. Esta accin es ilegal en C++ y est per- mitida en C: int main () { // ... printf (x); //C: int printf (); //C++ es ilegal, ya que printf no est //permitida devuelve un int return 0; } Fallo al devolver un valor de una funcin. Una funcin en C + + declarada con un tipo determinado de retorno ha de devolver un valor de ese tipo. En C est permitido no seguir la regla. Asignacin de punteros void. La asignacin de un tipo void* a un puntero de otro tipo se debe hacer con una conversin explcita en C + +. En C se realiza implcitamente. Inicializacin de constantes de cadena. En C++ se debe proporcionar un espacio para el carcter de terminacin nulo cuando se inicializan cons- tantes de cadena. En C se permite la ausencia de ese carcter. int main() { //... char car[7] = Cazorla; //legal en C //error en C++ //... return 0; } Una solucin al problema que funciona tanto en C como en C++ es: char car[8] = Cazorla; B.3. CONSTANTES C++ contiene constantes para cada tipo de dato simple (integer, char, etctera). Las constantes pueden tener tres sufijos, u, l y f, que indican tipos unsigned, long y float, respectivamente. Asimismo, se pueden aadir los prefijos o y ox que representan constantes octales y hexadecimales. 456 0456 Ox456 //constantes enteras: decimal, octal, //hexadecimal 1231 123ul //constantes enteras: long, unsigned //long 'B' 'b' '4' //constantes tipo char 3.1415f 3.14159L //constantes reales de diferente posicin cadena de caracteres //constante de cadena Las cadenas de caracteres se encierran entre comillas, y las constantes de un solo carcter se encierran entre comillas simples. //cadena vaca, '\0' Una constante literal es un valor escrito directamente en el programa siempre que se necesite. Por ejemplo, int miEdad = 25; miEdad es una variable de tipo int; 25 es una constante literal. GUA DE SINTAXIS ANSI/ISO ESTNDAR C++ 565 B.3.1. DecIaracin de constantes con const En C++, los identificadores de variables/constantes se pueden declarar cons- tantes, significando que su valor se inicializa pero no se puede modificar. Estas constantes se denominan simblicas. Esta declaracin se realiza con la palabra reservada const. const double PI = 3.1416; const char BLANCO = ' '; const double PI_EG = PI; const double DOBLE_PI = 2*PI; El modificador de tipos const se utiliza en C++ tambin para propor- cionar proteccin de slo lectura para variables y parmetros de funciones. Las funciones miembro de una clase que no modifican los miembros dato a que acceden pueden ser declarados const. Este modificador evita tambin que parmetros parados por referencia sean modificados: void copy (const char* fuente, char* destino); B.3.2. DecIaracin de constantes con define# C++ soporta tambin el mtodo tradicional de declaracin de constantes, aunque ahora est obsoleto. Para declarar una constante por este mtodo se debe realizar con la palabra reservada #define. #define estudiantesPorClave 50 #define PI 3.1416 #define hex 16 B.4. CONVERSIN DE TIPOS Las conversiones explcitas se fuerzan mediante moldes (casts). La con- versin forzosa de tipos de C tiene el formato clsico: (tipo) expresin C++ ha modificado la notacin anterior por una notacin funcional como alternativa sintctica: nombre del tipo (expresin) Las notaciones siguientes son equivalentes: z = float(x); //notacin de moldes en C++ z = (float)x; //notacin de moldes en C B.5. DECLARACIN DE VARIABLES En C ANSI, todas las declaraciones de variables y funciones se deben hacer al principio del programa o funcin. Si se necesitan declaraciones adicionales, el programador debe volver al bloque de declaraciones al objeto de hacer los ajus- tes o inserciones necesarios. Todas las declaraciones deben hacerse antes de que se ejecute cualquier sentencia. As, la declaracin tpica en C++ NombreTipo NombreVariable1, NombreVarible2, ... proporciona declaraciones tales como: int saldo, meses; double clipper, salario; Al igual que en C, se pueden asignar valores a las variables en C++: int mes = 4,dia, anyo = 1995; double salario = 45.675; En C++, las declaraciones de variables se pueden situar en cualquier parte de un programa. Esta caracterstica hace que el programador declare sus variables en la proximidad del lugar donde se utilizan las sentencias de su programa. El siguiente programa es legal en C++ pero no es vlido en C: #include <iostream.h> int main() { int i; for (i=0; i < 100; ++i) cout << i << endl; double j; for (j = 1.7547; j < 25.4675; j+= .001) cout << i << endl; } El programa anterior se podra rescribir, haciendo la declaracin y la definicin dentro del mismo bucle: int main() { for (int i=0; i<100; ++i) cout << i << endl; for (double j - 1.7545; j<25.4675;j += .001) cout << i << endl; } 566 PROGRAMACIN EN C++. ALGORITMOS, ESTRUCTURAS Y OBJETOS B.6. OPERADORES C++ es un lenguaje muy rico en operadores. Se clasifican en los siguientes grupos: Aritmticos. Relacionales y lgicos. Asignacin. Acceso a datos y tamao. Manipulacin de bits. Varios. Como consecuencia de la gran cantidad de operadores, se producen tambin una gran cantidad de expresiones diferentes. B.6.1. Operadores aritmticos C++ proporciona diferentes operadores que relacionan operaciones aritm- ticas. TABLA B.6. Operadores ariImeIicos eh C++ Operador Nombre Propsito Ejemplo + Ms unitario Valor positivo de x x = + y + 5 - Negacin Valor negativo de x X = - y; + Suma Suma x e y z = x + y; - Resta Resta y de x z = x - y; * Multiplicacin Multiplica x por y z = x * y; / Divisin Divide x por y z = x/y; % Mdulo Resto de x dividido por y z = x%y; ++ Incremento Incrementa x despus de usar x++ -- Decremento Decrementa x antes de usar --x EjempIos -i + w; //menos unitario ms unitario a*b/c%d //multiplicacin, divisin, mdulo a+b a-b //suma y resta binaria a=5/2; //a toma el valor 2, si se considera a entero a=5/2; //a toma el valor 2.5, si a es real Los operadores de incremento y decremento sirven para incrementar y decrementar en uno los valores almacenados en una variable. variable++ //postincremento ++variable //preincremento variable- //postdecremento -- variable //predecremento ++a; equivale a a = a +1; --b; equivale a b = b -1; Los formatos postfijos se conforman de modo diferente segn la expresin en que se aplica: b = ++a: equivale a a = a+l; b = a; b = a++; equivale a b = a; a = a+l; int i, j, k = 5; k++; //k vale 6, igual efecto que ++k --k; //k vale ahora 5, igual efecto que k- k = 5; i = 4*k++; //k es ahora 6 e i es 20 k = 5; j = 4 * ++k; //k es ahora 6 e i es 24 B.6.2. Operadores de asignacin El operador de asignacin (=) hace que el valor situado a la derecha del operador se adjudica a la variable situada a su izquierda. La asignacin suele ocurrir como parte de una expresin de asignacin y las conversiones se producen implcitamente. z = b+5; //asigna (b+5) a variable z C++ permite asignaciones mltiples en una sola sentencia. As, a = b+(c=10); equivale a: c=10; a=b+c; Otros ejemplos de expresiones vlidas y no vlidas son: //expresiones legales //expresiones no legales a=5 * (b+a); a+3 = b; double x = y; PI = 3; a=b=6; x++ = y; C++ proporciona operadores de asignacin que combinan operadores de asignacin y otros diferentes, produciendo operadores tales como +=, /=, =, *= y % =. C++ soporta otros tipos de operadores de asignacin para manipulacin de bits. GUA DE SINTAXIS ANSI/ISO ESTNDAR C++ 567 TABLA B.7. Operadores ariImeIicos de asighacih Operador Formato largo Formato corto += x = x + y; x + =y; -= x = x - y; x - =y; *= x = x * y; x * =y; /= x = x / y; x / =y; %= x = x%y; x % =y; EjempIos a += b; equivale a a = a + b; a *= a + b; equivale a a = a * (a+b); v += e; equivale a v = v + e; v -=e; equivale a v = v%e; B.6.3. Operadores Igicos y reIacionaIes Los operadores lgicos y relacionales son los bloques de construccin bsi- cos para construcciones de toma de decisin en un lenguaje de programa- cin. La Tabla B.8 muestra los operadores lgicos y relacionales. TABLA B.8. Operadores lgicos y relaciohales Operador Nombre Ejemplo && AND (y) lgico a && b | | OR (o) lgico C | | d ! NOT (no) lgico !C < Menor que i < 0 <= Menor o igual que i <= 0 > Mayor que j > 50 >= Mayor o igual que j >= 8.5 == Igual a x == '\0' != No igual a c !='/n' ?: Asignacin condicional k = (i < 5)? 1= i; Expresiones equivalentes: n = n+1; n += 1; n++; ++n; El operador ?: se conoce como expresin condicional. La expresin condicional es una abreviatura de la sentencia condicional if_else. La sen- tenca if. if (condicin) variable = expresinl; else variable = expresin2; es equivalente a variable =(condicin) ? expresin1 : expresin2; La expresin condicional comprueba la condicin. Si esa condicin es verdadera, se asigna expresin1 a variable; en caso contrario se asigna expresin2 a variable. RegIas practicas Los operadores lgicos y relacionales actan sobre valores lgicos: el valor falso puede ser o bien 0, o bien el puntero nulo, o bien 0.0; el valor verda- dero puede ser cualquier valor distinto de cero. La siguiente tabla muestra los resultados de diferentes expresiones. x > y 1, si x excede a y, si no 0 x >= y 1, Si x es mayor que o igual a y, si no 0 x < y 1, si x es menor que y, si no 0 x <= y 1, si x es menor que o igual a y, si no 0 x == y 1, si x es igual a y, si no 0 x! = y 1, si x e y son distintos, si no 0 !x 1, si x es 0, si no 0 x || y 0, si ambos x e y son 0, si no 0 EvaIuacion en cortocircuito C++, igual que C, admite reducir el tiempo de las operaciones lgicas; la evaluacin de las expresiones se reduce cuando alguno de los operandos toma valores concretos. 1. Operacin lgica AND (&&). Si en la expresin expr1 && expr2, expr1 toma el valor cero y la operacin lgica AND (y) siempre ser cero, sea cual sea el valor de expr2. En consecuencia, expr2 no se evaluar nunca. 568 PROGRAMACIN EN C++. ALGORITMOS, ESTRUCTURAS Y OBJETOS 2. Operacin lgica OR (|| ). Si expr1 toma un valor distinto de cero, la expresin expr1 || expr2 se evaluar a 1, cualquiera que sea el valor de expr2; en consecuencia, expr2 no se evaluar. B.6.4. Operadores de manipuIacin de bits C++ proporciona operadores de manipulacin de bits, as como operadores de asignacin de manipulacin de bits. TABLA B.9. Operadores de mahipulacih de biIs (btvse) Operador Significado Ejemplo & AND bit a bit x & 128 | OR bit a bit j | 64 XOR bit a bit j 12 NOT bit a bit j << Desplazar a izquierda i << 3 >> Desplazar a derecha j >> 4 TABLA B.10. Operadores de asighacih de mahipulacih de biIs Operador Formato largo Formato reducido &= x = x & y; x & = y; |= x = x | y; x | = y; = x = x ^ y; x = y; <<= x = x << y; x << = y; >>= x = x >> y; x >> = y; EjempIos x Cambia los bits 1 a 0 y los bits 0 a 1 x & y Operacin lgica AND (y) bit a bit de x e y x | y Operacin lgica OR (o) bit a bit de x e y x << y x se desplaza a la izquierda (en y posiciones) x >> y x se desplaza a la derecha (en y posiciones) B.6.5. EI operador sizeof El operador sizeof proporciona el tamao en bytes de un tipo de dato o variable. sizeof toma el argumento correspondiente (tipo escalar, array, re- cord, etc.). La sintaxis del operador es sizeof (nombre_varable | tipo_de_dato) EjempIos int m, n[12]; sizeof(m) //proporciona 4, en mquinas de 32 bits sizeof(n) //proporciona 48 sizeof(15) //proporciona 4 tamanyo = sizeof(long) - sizeof(int); B.6.6. Prioridad y asociatividad de operadores Cuando se realizan expresiones en las que se mezclan operadores diferentes es preciso establecer una precedencia (prioridad) de los operadores y la direccin (o secuencia) de evaluacin (orden de evaluacin: izquierda-dere- cha, derecha-izquierda), denominada asociatividad. La Tabla B.11 muestra la precedencia y asociatividad de operadores. GUA DE SINTAXIS ANSI/ISO ESTNDAR C++ 569 TABLA B.11. Precedehcia y asociaIividad de operadores Operador Asociatividad Prioridad ::.->[]()++-- Izquierda-Derecha 1 ++ -- & (direccin) tipo) ! - ++ sizeof (tipo) Derecha-Izquierda 2 new delete* (indireccin) .* ->* Izquierda-Derecha 3 * / % Izquierda-Derecha 4 + - Izquierda-Derecha 5 << >> Izquierda-Derecha 6 < <= > >= Izquierda-Derecha 7 == != Izquierda-Derecha 8 & Izquierda- Derecha 9 Izquierda-Derecha 10 | Izquierda-Derecha 11 && Izquierda-Derecha 12 || Izquierda-Derecha 13 ?: Derecha-Izquierda 14 = += -= *= /= %= >>= <<= &= /= = Derecha-Izquierda 15 (operador coma) Izquierda-Derecha 16 EjempIo a * b/c +d equivale a (a*b) / (c+d) B.6.7. Sobrecarga de operadores La mayora de los operadores de C++ pueden ser sobrecargados o redefini- dos para trabajar con nuevos tipos de datos. La Tabla B.12 lista los opera- dores que pueden ser sobrecargados. Si se desea visualizar el valor del objeto int llamado i, se escribe la sentencia cout << i; El siguiente programa visualiza en pantalla una frase: #include <iostream.h> int main() { cout << hola, mundo\n; } Las salidas en C++ se pueden conectar en cascada, con una facilidad de escritura mayor que en C. #include <iostream.h> int main() { int i; i = 1099; cout << El valor de i es << i << \n; } Otro programa que muestra la conexin en cascada es #include <iostream.h> int main() { int x = 45; double y = 495.125; char *c = y multiplicada por x=; cout << c << y*x << \n; } B.7.2. Entrada La entrada se maneja por la clase istream. Existe un objeto predefinido is- tream, llamado cin, que se refiere al dispositivo de entrada estndar (el teclado). El operador que se utiliza para obtener un valor del teclado es el operador de extraccin >>. Por ejemplo, si i era un objeto int, se escribir cin >> i; que obtiene un nmero del teclado y lo almacena en la variable i. 570 PROGRAMACIN EN C++. ALGORITMOS, ESTRUCTURAS Y OBJETOS TABLA B.12. Operadores que se puedeh sobrecargar + - * / % & | ! = < > += -= *= /= %= = &= |= << >> >>= <<= == != <= >= && || ++ -- , ->* -> () [] B.7. ENTRADAS Y SALIDAS BSICAS Al contrario que muchos lenguajes, C++ no tiene facilidades incorporadas para manejar entrada o salida. Estas operaciones se realizan mediante rutinas de bibliotecas. Las clases que C + + utiliza para entrada y salida se conocen como flujos. Un flujo es una secuencia de caracteres junto con una coleccin de rutinas para insertar caracteres en flujos (a pantalla) y extraer caracteres de un flujo (de teclado). B.7.1. SaIida El flujo cout es el flujo de salida estndar que corresponde a stdout en C. Este flujo se deriva de la clase ostream construida en iostream. FIGURA B.1. Uso de Ilu|os para salida de caracIeres. Uhidad cehIral cout PahIalla entada bnaa saIda de caactees Un programa simple que lee un dato entero y lo visualiza en pantalla es: #include <iostream.h> int main() { int i; cin >> i; cout << i << \n; } Al igual que en el caso de cout, se pueden introducir datos en cascada: #include <iostream.h> int main() { char c[60]; int x,y; cin >> c >> x >> y; cout << c << << x << z<< y << \n; } B.7.3. ManipuIadores Un mtodo fcil de cambiar la anchura del flujo y otras variables de forma- to es utilizar un operador especial denominado manipulador. Un manipula- dor acepta una referencia de flujo como un argumento y devuelve una refe- rencia al mismo flujo. El siguiente programa muestra el uso de manipuladores especficamen- te para conversiones de nmero (dec, oct, y hex): #include <iostream.h> int main() { int i=36; cout << dec << i << oct << i hex << i <<\n; } La salida de este programa es: 36 44 24 Otro manipulador tpico es endl, que representa al carcter de nueva lnea (salto de lnea), y es equivalente a 'n\'. El programa anterior se puede escribir tambin as: #include <iostream.h> int main() { int i = 36; cout << dec << i << oct << i << << hex << i << endl; } B.8. SENTENCIAS Un programa en C++ consta de una secuencia de sentencias. Existen diver- sos tipos de sentencias. El punto y coma se utiliza como elemento terminal de cada sentencia. B.8.1. Sentencias de decIaracin Se utilizan para establecer la existencia y, opcionalmente, los valores ini- ciales de objetos identificados por nombre. NombreTipo identificador, ...; NombreTipo identificador = expresin, ...; const NombreTipo identificador = expresin, ...; Algunas sentencias vlidas en C++ son: char c1; int p, q = 5, r = a+b; //suponiendo que a y b han sido //declaradas e inicializadas antes const double IVA = 16.0; B.8.2. Sentencias de expresin Las sentencias de expresiones hacen que la expresin sea evaluada. Su for- mato general es: expresin; EjempIos n++; 425; //legal, pero no hace nada a+b; //legal, pero no hace nada n = a < b || b != 0; a += b = 3; //sentencia compleja GUA DE SINTAXIS ANSI/ISO ESTNDAR C++ 571 C++ permite asignaciones mltiples en una sentencia. m = n +(p = 5); equivale a p = 5 m = n + p; B.8.3. Sentencias compuestas Una sentencia compuesta es una serie de sentencias encerradas entre llaves. Las sentencias compuestas tienen el formato: { sentencia sentencia sentencia ... } Las sentencias encerradas pueden ser cualquiera: declaraciones, expre- siones, sentencias compuestas, etc. Un ejemplo es: { int i = 5; double x = 3.14, y = -4.25; int j = 4-i; x = 4.5*(x-y); } El cuerpo de una funcin C++ es siempre una sentencia compuesta. B.9. SENTENCIAS CONDICIONALES: if El formato general de una sentencia if es: if (expresin) if (expresin) { sentencia <secuencia de sentencias> } Si expresin es verdadera (distinta de cero), entonces se ejecuta sen- tencia o secuencia de sentencias; en caso contrario se salta la sentencia. Despus que la sentencia if se ha ejecutado, el control pasa a la siguiente sen- tencia. EjempIo 1 if (a < 0) negativos++; Si la variable a es negativa, se incrementa la variable negativos. EjempIo 2 if (numeroDeDias < 0) numeroDeDias = 0; if ((altura - 5) < 4){ area = 3.14 * radio * radio; volumen = area * altura; } EjempIo 3 if (temperatura >= 45) cout << Estoy en Sonora:Hermosillo, en agosto; cout << Estoy en Veracruz << temperatura << endl; La frase Estoy en Sonora:Hermosillo, en agosto se visualiza cuando temperatura es mayor o igual que 45. La sentencia siguiente se ejecuta siempre. La sentencia if_else tiene el formato siguiente: 1. if (expresin) 2. if (expresin)"{ sentencia1; < secuencia de sentencias 1 > else else sentencia2; < secuencia de sentencias 2 > Si expresin es distinto de cero, la sentencia1 se ejecuta y senten- cia2 se salta; si expresin es cero, la sentencia1 se salta y sentencia2 se ejecuta. Una vez que se ha ejecutado la sentencia if_else, el control pasa a la siguiente sentencia. EjempIo 4 if (Numero == 0) cout << No se calcular la media; else media = total / Numero; EjempIo 5 if (cantidad > 10){ descuento = 0.2; precio = n * precio(1 - descuento); } 572 PROGRAMACIN EN C++. ALGORITMOS, ESTRUCTURAS Y OBJETOS else { descuento = 0; precio = n * Precio; } B.9.1. Sentencias if _eIse anidadas C++ permite anidar sentencias if_else para crear una sentencia de alternati- va mltiple: if (expresin 1) sentencia 1; | {sentenca compuesta} else if (expresin 2) sentencia 2; | {sentencia compuesta} else if (expresion N) sentencia N; | {sentencia compuesta} [else sentencia N+1; | {sentenca compuesta}] EjempIo if (a > 100) if (b <= 0) SumaP = 1; else SumaN = 1; else Numero = 1; B.9.2. Sentencias de aIternativa mItipIe: switch La sentencia switch ofrece una forma de realizar decisiones de alternativas mltiples. El formato de switch es: switch(expresion) { case constante 1: sentencias break; case constante 2: sentencias . . . break; case constante n: sentencias break; default: //opcional sentencias } La sentencia switch requiere una expresin cuyo valor sea entero. Este valor puede ser una constante, una variable, una llamada a funcin o una expresin. El valor de constante ha de ser una constante. Al ejecutar la sentencia se evala expresin, y si su valor coincide con una cons- tante, se ejecutan las sentencias a continuacin de ella; en caso contrario se ejecutan las sentencias a continuacin de default. switch (Puntos) { case 10: nota ='A'; break; case 9: nota = 'B'; break; case 7,8: nota = 'C'; break; case 5,6: nota = 'D'; break; default: nota = 'F'; } B.10. BUCLES: SENTENCIAS REPETITIVAS Los bucles sirven para realizar tareas repetitivas. En C++ existen tres dife- rentes tipos de sentencias repetitivas: while. do. for. B.10.1. Sentencia whiIe La sentencia while es un bucle condicional que se repite mientras la con- dicin es verdadera. El bucle while nunca puede iterar si la condicin comprobada es inicialmente falsa. La sintaxis de la sentencia while es: GUA DE SINTAXIS ANSI/ISO ESTNDAR C++ 573 while (expresin) sentencia; o bien, while (expresin){ < secuencia de sentencias > } EjempIo int n, suma = 0; int i = 1; while (i <= 100) { cout <<Entrar; cin >> n; suma += n; i++; } cout <<La media es << double (suma)/100.0; B.10.2. Sentencia do La sentencia do acta como la sentencia while. La nica diferencia real es que la evaluacin y la prueba de salida del bucle se hace despus que el cuerpo del bucle se ha ejecutado, en lugar de antes. El formato es: do sentencia while (expresion); sentencia siguiente Se ejecuta sentencia y a continuacin se evala expresin, y si es verdadero (distinto de cero), el control se pasa de nuevo al principio de la sentencia do, y el proceso se repite hasta que expresin es falso (cero) y el control pasa a la sentencia siguiente. EjempIo int n, suma = 0; int i = 1; do { cout <<Entrar; cin >> n; suma += n; i++; } while (i <=100); cout << La media es << double(suma)/100.0; El siguiente ejemplo visualiza los cuadrados de 2 a 10: int i = 2; do { cout << i << por << i << = << i * i++ << endl; }while (i < 11); B.10.3. Sentencia for Una sentencia for ejecuta la iteracin de un bucle un nmero determinado de veces. for tiene tres componentes: expresin1 inicializa las variables de control del bucle; expresin2 es la condicin que determina si el bucle realiza otra iteracin; la ltima parte del bucle for es la clusula que incre- menta o decrementa las variables de control del bucle. El formato general de for es: for (expresin1; expresin2; expresin3) sentencia;|{<secuencia de sentencias>}; expresin1 se utiliza para inicializar la variable de control de bucle; a con- tinuacin, expresin2 se evala; si es verdadera (distinta de cero), se eje- cuta la sentencia y se evala expresin3, y el control pasa de nuevo al prin- cipio del bucle. La iteracin contina hasta que expresin2 es falsa (cero), en cuyo momento el control pasa a la sentencia siguiente al bucle. EjempIos 1. for (int i = 0; i < n; i++) //se realizan n iteraciones sentencias 2. Suma de 100 nmeros int n, suma =0; for (int i = 0; i < 100; i++) { 574 PROGRAMACIN EN C++. ALGORITMOS, ESTRUCTURAS Y OBJETOS cout << Entrar; cin >> n; suma += n; } B. 10.4. Sentencias break y continue El flujo de control ordinario de un bucle se puede romper o interrumpir mediante las sentencias break y continue. La sentencia break produce una salida inmediata del bucle for en que se encuentra situada: for (i = 0; i < 100; ++i) { cin >> x; if (x < 0.0) cout << salir del bucle << endl; break; } cout << sqrt (x) << endl; } La sentencia break tambin se utiliza para salir de la sentencia switch. La sentencia continue termina la iteracin que se est realizando y comenzar de nuevo la siguiente iteracin: for (i = 0; i < 100; ++i) cin >> x; if (x < 0.0) continue; B.10.5. Sentencia nuIa La sentencia nula se representa por un punto y coma, y no hace ninguna accin. Advertencia: Una sentencia break puede ocurrir nicamente en el cuerpo de una sentencia for, while, do o switch. Una sentencia continue slo puede ocurrir dentro del cuerpo de una sentencia for, while o do. char cad[80]=Cazorla; int i; for(i=0; cad[i] !='\0'; i++) ; B.10.6. Sentencia return La sentencia return detiene la ejecucin de la funcin actual y devuelve el control a la funcin llamada. Su sintaxis es: return expresion; donde el valor de expresin se devuelve como el valor de la funcin. B.11. PUNTEROS (APUNTADORES) 3 Un puntero o apuntador es una referencia indirecta a un objeto de un tipo especficado. En esencia, un puntero contiene la posicin de memoria de un tipo dado. B.11.1. DecIaracin de punteros Los punteros se declaran utilizando el operador unitario. En las sentencias siguientes se declaran dos variables: n es un entero, y p es un puntero a un entero. int n; //n es un tipo de dato entero int *p; //p es un puntero a un entero Una vez declarado un puntero, se puede fijar la direccin o posicin de memoria del tipo al que apunta. p = &n; //p se fija a la direccin de n Un puntero se declara escribiendo: NombreTipo *NombreVariable GUA DE SINTAXIS ANSI/ISO ESTNDAR C++ 575 3 El trmino puntero es el ms utilizado en Espaa, mientras que en Latinoamrica se suele utilizar apuntador. p 0 1 2 3 4 5 6 7 8 9 Este elemento se puede llamar por: Este elemento se puede llamar por: a[0], *p o bien p[0] a[6], *(p+6) o bien p[6] Una vez que se ha declarado un puntero, p, el objeto al que apunta se escri- be *p y se puede tratar como cualquier otra variable de tipo NombreTipo. int *p, *q, n; //dos punteros a int, y un int n = -25; //n se fija a -25 *p = 105; //*p a 105 *q = n +*p; //*q a 80 C++ trata los punteros a tipos diferentes como tipos diferentes: int *ip; double *dp; Los punteros ip y dp son incompatibles, de modo que es un error escribir dp = ip; //Error, no se pueden asignar punteros a tipos //diferentes Se pueden, sin embargo, realizar asignaciones entre contenidos, ya que se realizara una conversin explcita de tipos. *dp = *ip; Existe un puntero especial (nulo) que se suele utilizar con frecuencia en programas C++. El puntero NULL tiene un valor cero, que lo diferencia de todas las direcciones vlidas. El conocimiento nos permite comprobar si un puntero p es el puntero NULL evaluando la expresin (p==0). Los punteros NULL se utilizan slo como seales de que ha sucedido algo. En otras pala- bras, si p es un puntero NULL, es correcto referenciar *p. B.11.2. Punteros a arrays A los arrays se accede a travs de los ndices: int lista[5]; lista[3] = 5; A los arrays tambin se puede acceder a travs de punteros: int lista[5]; //array de 5 elementos int *ptr; //puntero a entero ptr = lista; //fija puntero al primer elemento del array ptr += 2; //suma 3 a ptr; ptr apunta al 4 elemento *ptr = 5; //establece el 4 elemento a 5 double a[10]; double *p = a; //p y a se refieren al mismo array El nombre de un array se puede utilizar tambin como si fuera un punte- ro al primer elemento del array. 576 PROGRAMACIN EN C++. ALGORITMOS, ESTRUCTURAS Y OBJETOS Si nombre apunta al primer elemento del array, entonces nombre + 1 apunta al segundo elemento. El contenido de lo que se almacena en esa posi- cin se obtiene por la expresin *(nombre+1) B.11.3. Punteros a estructuras Los punteros a estructuras son similares y funcionan de igual forma que los punteros a cualquier otro tipo de dato. struct familia { char *marido; char *esposa; char *hijo; }; familia mackoy; //mackoy estructura de tipo familia familia *p; //p, un puntero a familia p = &mackoy; //p, contiene direccin de mackoy Aunque las funciones no pueden modificar sus argumentos, si un array se utiliza como un argumento de una funcin, la funcin puede modifi- car el contenido del array. p -> marido = Luis MackoY; //iniciacin p -> esposa = Vilma Gonzlez; //iniciacin p -> hijo = Luisito Mackoy; //iniciacin B. 11.4. Punteros a objetos constantes Cuando se pasa un puntero a un objeto grande, pero se trata de que la fun- cin no modifique el objeto (por ejemplo, en caso de que slo se desee visualizar el contenido de un array), se declara el argumento correspon- diente de la funcin como un puntero a un objeto constante. La declara- cin es, const NombreTipo *v; establece v como un puntero a un objeto que no puede ser modificado. Un ejemplo puede ser: void Visualizar(const ObjetoGrande *v); B.11.5. Punteros a void El tipo de dato void representa un valor nulo. En C++, sin embargo, el tipo de puntero void se suele considerar como un puntero a cualquier tipo de dato. La idea fundamental que subyace en el puntero void en C++ es la de un tipo que se puede utilizar adecuadamente para acceder a cualquier tipo de obje- to, ya que es ms o menos independiente del tipo. Un ejemplo ilustrativo de la diferencia de comportamiento en C y C++ es el siguiente segmento de programa. int main() { void *vptr; int *iptr; vptr = iptr; iptr = vptr; //Incorrecto en C++, correcto en C iptr = (int *) vptr; //Correcto en C++ ... } B.11.6. Punteros y cadenas Las cadenas en C++ se implementan como arrays de caracteres, como cons- tantes de cadena y como punteros a caracteres. Constantes de cadena Su declaracin es similar a char *Cadena = Mi profesor; o bien su sentencia equivalente char VarCadena[] = Mi profesor; Si desea evitar que la cadena se modifique, aada const a la declaracin const char *VarCadena = Mi profesor; Punteros a cadenas Los punteros de cadenas no son cadenas. Los punteros que localizan el pri- mer elemento de una cadena almacenada. char *varCadena; const char *Cadenafija; Consideraciones practicas Todos los arrays en C++ se implementan mediante punteros: char cadenal[16]= Concepto Objeto; char *cadena2 = cadena1; Las declaraciones siguientes son equivalentes y se refieren al carcter C: cadena1[0] cadena1 cadena2 B.11.7. Aritmtica de punteros Dado que los punteros son nmeros (direcciones), pueden ser manipulados por los operadores aritmticos. Las operaciones que estn permitidas sobre Los punteros a cadena se declaran: char s[] o bien char *s GUA DE SINTAXIS ANSI/ISO ESTNDAR C++ 577 punteros son: suma, resta y comparacin. As, si las sentencias siguientes se ejecutan en secuencia: char *p; //p contiene la direccin de un carcter char a[10]; // array de diez caracteres p = &a[0]; //p apunta al primer elemento del array p++; //p apunta al segundo elemento del array p++; //p apunta al tercer elemento del array p--; //p apunta al segundo elemento del array Un ejemplo de comparacin de punteros es el siguiente programa: #include <iostream.h> main (void) { int *ptr1, *ptr2; int a[2] = {10,10}; ptr1 =a; cout << ptr1 es << ptr1 << *ptr1 es << *ptr1 << endl; ptr2 = ptr1 + 1; cout << ptr2 es << ptr2 << *Ptr2 es << *ptr2 << endl; //comparar dos punteros if (ptr1 == ptr2) cout << ptr1 no es igual a ptr2 \n; if (*ptr1 == *ptr2) cout << ptr1 es igual a *ptr2 \n; else cout << ptr1 no es igual a *ptr2 \n; } B. 12. LOS OPERADORES new Y deIete C++ define un mtodo para realizar asignacin dinmica de memoria, dife- rente del utilizado en C, mediante los operadores new y delete. El operador new sustituye a la funcin malloc tradicional en C, y el operador delete sustituye a la funcin free tradicional tambin en C; new asigna memoria y devuelve un puntero al objeto ltimamente creado. Su sintaxis es: new NombreTipo y un ejemplo de su aplicacin es: int *ptr1; double *ptr2; ptr1 = new int; //memoria asignada para el objeto ptr1 ptr2 = new double; //memoria ampliada para el objeto ptr2 *ptr1= 5; *ptr2= 6.55; Dado que new devuelve un puntero, se puede utilizar ese puntero para inicializar el puntero en una sola definicin, tal como: int* p = new int; Si new no puede ocupar la cantidad de memoria solicitada, devuelve un valor NULL. El operador delete libera la memoria asignada mediante new. delete ptr1; Un pequeo programa que muestra el uso combinado de new y delete es, #include <iostream.h> void main (void) { char *c; c = new char[512]; cin >> c; cout << c << endl; delete c; } Los operadores new y delete se pueden utilizar para asignar memoria a arrays, clases y otro tipo de datos. int * i; i = new int[2][35]; //crear el array //asignar el array ... delete i; //destruir el array Sintaxis de new y delete: new nombre_tipo new int new char[100] new nombre_tipo inicializador new int(99) new char(C) new nombre_tipo new (char*) delete expresin delete p delete[] expresin delete[] 578 PROGRAMACIN EN C++. ALGORITMOS, ESTRUCTURAS Y OBJETOS B. 13. ARRAYS Un array 4 (matriz, tabla) es una coleccin de elementos dados del mismo tipo que se identifican por medio de un ndice. Los elementos comienzan con el ndice 0. DecIaracion de arrays Una declaracin de un array tiene el siguiente formato: nombreTipo nombreVariable[n] Algunos ejemplos de arrays unidimensionales: int ListaNum[2]; //array de dos enteros char ListaNombres[10] ; //array de 10 caracteres Arrays multidimensionales son: nombretipo nombreVariable[nl] [n2] ... [nx]; El siguiente ejemplo declara un array de enteros 4 10 3 int multidim[4][10][3]; El ejemplo tabla declara un array de 2 3 elementos. int tabla[2][3]; //array de enteros de 2x3 = 6 elementos B.13.1. Definicin de arrays Los arrays se inicializan con este formato: int a[31 = {5, 10, 15}; char cad[5] = {a', 'b', 'c', 'd', 'e'}; int tabla[2][3] = {{1,2,3}{3,4,5}}; Las tres siguientes definiciones son equivalentes: char saludo[5]= hola; char saludo[] = hola; char saludo[5] = {'h', 'o', 'l', 'a', '\o'}; B.14. ENUMERACIONES, ESTRUCTURAS Y UNIONES En C++, un nombre de una enumeracin, estructura o unin es un nombre de un tipo. Por consiguiente, la palabra reservada struct, union o enum no son necesarias cuando se declara una variable. El tipo de dato enumerado designa un grupo de constantes enteros con nombres. La palabra reservada enum se utiliza para declarar un tipo de dato enumerado o enumeracin. La sintaxis es: enum nombre { lista_simbolos }; donde nombre es el nombre de la variable declarada enumerada; lista-smbolos es una lista de tipos enumerados, a los que se asigna valo- res cuando se declara la variable enumerada y puede tener un valor de ini- cializacin. Se puede utilizar el nombre de una enumeracin para declarar una variable de ese tipo (variable de enumeracin). nombre var; Considrese la siguiente sentencia: enum color {Rojo, Azul, Verde, Amarillo}; Una variable de tipo enumeracin color es: color pantalla = Rojo; //Estilo C++ Una estructura es un tipo de dato compuesto que contiene una colec- cin de elementos de tipos de datos diferentes combinados en una nica construccin del lenguaje. Cada elemento de la coleccin se llama miembro y puede ser una variable de un tipo de dato diferente. Una estructura repre- senta un nuevo tipo de dato en C++. 1. Los arrays se pueden pasar como argumentos a funciones. 2. Las funciones no pueden devolver arrays. 3. No est permitida la asignacin entre arrays. Para asignar un array a otro se debe escribir el cdigo para realizar las asignaciones elemen- to a elemento. GUA DE SINTAXIS ANSI/ISO ESTNDAR C++ 579 4 En Latinoamrica, este trmino se traduce al espaol por la palabra arreglo. La sintaxis de una estructura es: struct nombre { miembros }; Un ejemplo y una variable tipo estructura se muestra en las siguientes sentencias: struct cuadro{ int i; float f; }; struct cuadro nombre; //Estilo C cuadro nombre; //Estilo C++ Una unin es una variable que puede almacenar objetos de tipos y tamaos diferentes. Una unin puede almacenar tipos de datos diferentes, slo puede almacenar una cada vez, en oposicin a una estructura que alma- cena simultneamente una coleccin de tipos de datos. La sintaxis de una unin es: union nombre { miembros }; Un ejemplo de estructura es: union alfa { int x; char c; }; Una declaracin de una variable estructura es: alfa w; El modo de acceder a los miembros de la estructura es mediante el ope- rador punto: u.x = 145; u.c = 'z'; C + + admite un tipo especial de unin llamada unin annima, que declara un conjunto de miembros que comparten la misma direccin de memoria. La unin annima no tiene asignado un nombre, y en consecuen- cia se accede a los elementos de la unin directamente. La sintaxis de una unin annima es: union { int nuevoID; int contador; }; Las variables de la unin annima comparten la misma posicin de memoria y espacio de datos. int main() { union{ int x; float y; double z; }; x = 25; y = 245.245; //el valor en y sobreescribe el valor de x z = 9.41415; //el valor en z sobreescribe el valor de z } B.15. CADENAS Una cadena es una serie de caracteres almacenados en bytes consecutivos de memoria. Una cadena se puede almacenar en un array de caracteres (char) que termina en un carcter nulo (cero, \0). char perro[5] = {m, o, r, g, a, n}; //no es una cadena char gato[5] = {f, e, l, i, s, \0}; //es una cadena Lectura de una cadena deI tecIado #include <iostream.h> main() { char cad[80]; cout <<Introduzca una cadena:; //lectura del teclado cin >> cad; cout <<Su cadena es:; cout << cad; return 0; } 580 PROGRAMACIN EN C++. ALGORITMOS, ESTRUCTURAS Y OBJETOS Esta lectura del teclado lee una cadena hasta que se encuentra el primer carcter blanco. As, cuando se lee Sierra Mgina. Jan, en cad slo se almacena Sierra. Para resolver el problema se utiliza la funcin gets (), que lee una cadena completa leda del teclado. El programa anterior se escribe as para leer toda la cadena introducida: #include <iostream.h> #include <stdio.h> main() { char cad[80]; cout << Introduzca una cadena:; gets(cad); cout << Su cadena es:; cout << cad; return 0; } B.16. FUNCIONES Una funcin es una coleccin de declaraciones y sentencias que realizan una tarea nica. Cada funcin tiene cuatro componentes: 1) su nombre; 2) el tipo de valor que devuelve cuando termina su tarea; 3) la informacin que toma al realizar su tarea, y 5) la sentencia o sentencias que realizan su tarea. Cada programa C++ tiene al menos una funcin: la funcin main. B.16.1. DecIaracin de funciones En C + + se debe declarar una funcin antes de utilizarla. La declaracin de la funcin indica al compilador el tipo de valor que devuelve la funcin y el nmero y tipo de argumentos que toma. La declaracin en C++ se denomi- na prototipo: tipoNombreFuncion (lista argumentos); Ejemplos vlidos son: double Media(double x, double y); void Print(char* formato, ...); extern max(const int*, int); char LeerCaracter(); B.16.2. Definicin de funciones La definicin de una funcin es el cuerpo de la funcin, que se ha declara- do con anterioridad. double Media(double x, double y) //Devuelve la media de x e y { return (x+y)/2.0; } char LeerCaracter(); //Devuelve un carcter de la entrada estndar { char c; cin >> c; return c; } B.16.3. Argumentos por omisin Los parmetros formales de una funcin pueden tomar valores por omisin, o argumentos cuyos valores se inicializan en la lista de argumentos forma- les de la funcin. int Potencia (int n, int k=2); Potencia(256); //256 elevado al cuadrado Los parmetros por omisin no necesitan especificarse cuando se llama a la funcin. Los parmetros con valores por omisin deben estar al final de la lista de parmetros: void func1 (int i=3, int j); //ilegal void func2 (int i, int j=0, nt k=0); //correcto void func3 (int i=2, int j, int k=0); //ilegal void ImprimirValores (int cuenta, double cantidad=0.0); Llamadas a la funcin ImprimirValores son: ImprimirValores (n,a); ImprimirValores (n); //equivalente a ImprimirValores (n, 0.0) Otras declaraciones y llamadas a funciones son: GUA DE SINTAXIS ANSI/ISO ESTNDAR C++ 581 double f1(int n, int m, int p=0); //legal double f2(int n, int m=1, int p=0); //legal double f3(int n=2, int m=1, int p=0); //legal double f4(int n, int m=1, int p); //ilegal double f5(int n=2, int m, int p=0); //ilegal B.16.4. Funciones en Inea (inIine) Si una declaracin de funcin est precedida por la palabra reservada inli- ne, el compilador sustituye cada llamada a la funcin con el cdigo que implementa la funcin. inline int Max(int a, int b) { if (a>b) return a; return b; } main () { int x = 5, y = 4; int z = Max(x,y); } Los parmetros con valores por omisin deben entrar al final de la lista de parmetros: las funciones f1, f2 y f3 son vlidas, mientras que las funciones f4 y f5 no son vlidas. Las funciones en lnea (inline) evitan los tiempos suplementarios de las llamadas mltiples a funciones. Las funciones declaradas en lnea deben ser simples, con slo unas pocas sentencias de programa; slo se pueden llamar un nmero limitado de veces y no son recursivas. inline int abs(int i); inline int min(int v1, int v2); int mcd(int v1, int v2); Las funciones en lnea deben ser definidas antes de ser llamadas: #include <iostream.h> int incrementar(int i); inline incrementar(int i) { i++; return; } main (void) { int i = 0; while (i < 5) { i = incrementar(i); cout << i es: << i << endl; } } B.16.5. Sobrecarga de funciones En C++, dos o ms funciones distintas pueden tener el mismo nombre. Esta propiedad se denomina sobrecarga. Un ejemplo es el siguiente: int max (int, int); double max (double, double); o bien este otro: void sumar (char i); void sumar (float j); Las funciones sobrecargadas se diferencian en el nmero y tipo de argu- mentos, o en el tipo que devuelven las funciones, y sus cuerpos son dife- rentes en cada una de ellas. #include <iostream.h void suma (char); void suma (float); main (void) { int i = 65; int i = 6.5; suma(i); suma(j); } void suma(char i) { cout << Suma interior(char) << endl; } void suma(float j) { cout << Suma interior (float) << endl; } 582 PROGRAMACIN EN C++. ALGORITMOS, ESTRUCTURAS Y OBJETOS B.16.6. EI modificador const El modificador de tipos const se utiliza en C++ para proporcionar protec- cin de slo lectura para variables y parmetros de funciones. Cuando se hace preceder un tipo de argumento con el modificador const para indicar que este argumento no se puede cambiar, al argumento al que se aplica no se puede asignar un valor ni cambiar. void copig (const char * fuente, char* dest); void func_demo (const int i); B.16.7. Paso de parmetros a funciones En C++ existen tres formas de pasar parmetros a funciones: 1. Por valor. La funcin llamada recibe una copia del parmetro, y este parmetro no se puede modificar dentro de la funcin: void intercambio (int x, int y) { int aux = y; y = x; x = aux; } //... intercambio (i, j); //las variables i, j no se intercambian 2. Por direccin. Se pasa un puntero al parmetro. Este mtodo permi- te simular en C/C++ la llamada por referencia, utilizando tipos pun- teros en los parmetros formales en la declaracin de prototipos. Este mtodo permite modificar los argumentos de una funcin. void intercambio (int*x, int*y) { int aux = *y; *y = *x; *x = aux; } //... intercambio (&i, &j); //i, j se intercambian sus valores 3. Por referencia. Se pueden pasar tipos referencia como argumentos de funciones, lo que permite modificar los argumentos de una funcin. void intercambio (int &x, int &y); { int aux = y; y = x; x = aux; } //... intercambio (i, j); //i, j intercambian sus valores B.16.8. Paso de arrays Los arrays se pasan por referencia. La direccin del primer elemento del array se pasa a la funcin; los elementos individuales se pasan por valor. Los arrays se pueden pasar indirectamente por su valor si el array se define como un miembro de una estructura. //Paso del array completo. Ejemplo 1 #include <iostream.h> void func](int x[]); //prototipo de funcin void main(){ int a[3] = {1,2,3}; func1(a); //sentencias func1(&a[0]); //equivalentes } void func(int x[]){ int i; for (i = 0; i < 3; i+1) cout << i << x[i] << '\n'; } El siguiente ejemplo pasa un elemento de un array: #include <iostream.h> { const int N=3; void func2(int x); void main() { int a[N] = {1,2,3}; func2(a[2]); } void func2(int x) { cout << x << '\n'; } Si se necesita modificar un argumento de una funcin en su interior, el argumento debe ser un tipo referencia en la declaracin de la funcin. GUA DE SINTAXIS ANSI/ISO ESTNDAR C++ 583 B.17. CLASES Una clase es un tipo definido por el usuario que contiene un estado (datos) y un comportamiento (funciones que manejan los datos). Una clase es como una estructura (struc) en C con la diferencia de que contiene funciones incorporadas. Adems, una clase puede tener algunos miembros que sean privados y a los que no se puede acceder desde el exterior de la clase. Esta propiedad se llama encapsulamiento y es un medio til para ocultar detalles que el resto del programa no ve. Las clases son distintas de los objetos que definen la clase como un tipo. Las clases en C++ son comparables a los tipos primitivos tales como int, char y double y un nombre de clase puede aparecer en cualquier texto que puede hacerlo int, char y double. Un objeto, en contraste, es como un valor de un entero individual, un carcter o de coma flotante. Un objeto tiene un estado particular, mientras que una clase es una descripcin gene- ral del cdigo y los datos y no contiene informacin. Por cada clase puede haber muchos objetos. Un objeto se conoce normalmente como una instan- cia o un ejemplar. Sintaxis Se puede declarar una clase en C++ utilizando class, struct o union: class | struct | union nombre[declaraciones_clase_base] { declaraciones } [definiciones_de_objeto]; |, indica que una de las tres palabras reservadas se debe utilizar al principio de la declaracin. [ ], el contenido de su interior es opcional. Cada una de las tres palabras reservadas, class, struct y union, crea una clase con estas diferencias: El nivel de acceso a miembros por omisin es privado si se utiliza class. El nivel de acceso a miembros es pblico si se utiliza union o struct. Las palabras reservadas struct y class crean un tipo similar a una estructura en C. Una union crea un tipo en la que todos los miembros datos comienzan en la misma direccin en memoria. class CCad{ private: char *pDatos; int nLongitud; public: CCad(); //Constructor -CCad(); //Destructor char *obtener(void) {return pDatos;} int obtenerlongitud(void) {return nLongitud;} char * copy(char * s); char * cat(char * s); } B.17.1. Constructor Un constructor es una funcin miembro que se llama automticamente cuando se crea un objeto; su nombre es el mismo que el nombre de la clase. Cuando se crean objetos dinmicamente, se utilizan new y delete en vez de malloc y free. Los constructores no tienen tipo de retorno (ni incluso void). La propia clase es el tipo de retorno implcito. Los constructores son como otras funciones miembro, aunque no se heredan. Es conveniente que los constructores sean declarados como pblicos para que el resto del pro- grama tenga acceso a ellos. class CDibujo { private: long coste; int nEstrellas; CCad sDirector; public: //Constructores CDibujo(); CDibujo(long c, int n, CCad dir); CDibujo() {delete[ ];} / / destructor }; //definicion de los constructores CDibujo::CDibujo() { } CDibujo::CDibujo(long c, int n, CCad dir){ coste = c; nEstrellas = n; sDirector = dir; } B.17.2. Constructor por omisin El constructor por omisin en cada clase es el constructor que no tiene argu- mentos. C++ lo invoca automticamente en las siguientes situaciones: cuan- 584 PROGRAMACIN EN C++. ALGORITMOS, ESTRUCTURAS Y OBJETOS do se define un objeto de la clase sin argumentos, cuando un array de obje- tos se declara con miembros no inicializados, o cuando el operador new se utiliza, pero no se especifica ningn argumento. La sintaxis de un construc- tor por omisin es: class() vector::vector () { ... } vector::vector(int i = 0) { ... } class Punto { public: Punto() } x = 0; y = 0; } private: int x; int y; }; C++ crea automticamente un constructor por omision cuando no exis- te otro constructor. B.17.3. Constructor de copia Este constructor se crea automticamente por el compilador. El constructor de copia se llama automticamente cuando se pasa un objeto por valor; se construye una copia local del objeto. El formato es: tipo: : tipo (const tipo& x) Punto::Punto (const Punto &p2) { cerr << Se llama al constructor de copia.\n; x = p2.x; y = p2.y; return *this; } el parmetro p2 no se puede modificar por la funcin. B.17.4. Arrays de objetos de cIases Un array de objetos de clases es til cuando se requieren instancias mlti- ples de la misma clase. As por ejemplo, si se define un array de objetos Punto llamado figura, el constructor por omisin Punto se llama para cada miembro del array Punto figura[3]; B.17.5. Destructores Un destructor es una funcin miembro especial que se llama automtica- mente cuando se desea borrar un objeto de la clase. El nombre de un des- tructor es el nombre de la clase, precedido por el carcter ~ (tilde). Si no se declara explcitamente un destructor C++ crea automticamente uno vaco. class Punto{ public: ~Punto() { cout << Destructor Punto llamado \n; } //... }; Un destructor no tiene parmetros, ni incluso void y no tiene tipo de retorno. Una clase puede tener slo un constructor. B.17.6. CIases compuestas Cuando una clase contiene miembros dato que son por s mismos objetos de otras clases, se denomina clase compuesta. class DatosAcademicos { //...}; class Direccion { // ...}; class Estudiante{ public: Estudiante() } LeerId(0); LeerNotaMedia(0.0); } void LeerId(long); void LeerNotaMedia(float); private: long id; DatosAcademicos da; Direccion dir; float NotaMedia; }; GUA DE SINTAXIS ANSI/ISO ESTNDAR C++ 585 B.17.7. Funciones miembro Las funciones miembro son funciones declaradas dentro de una clase. En consecuencia, ellas tienen acceso a miembros public, private y pro- tected de esa clase. Si se definen dentro de la clase, se tratan como fun- ciones inline y se tratan tambin como funciones sobrecargadas. class vector { public: vector(int n = 50); //constructor por defecto vector (const vector& v) //constructor de copia vector(const int a[ ], int n); ... int teo() const { return(size-1); } //funcin miembro en lnea private: ... }; Las funciones miembro se invocan normalmente mediante el uso de operadores punto (.) o bien ->. vector a (5O) , b; vector* ptr_v = &b; int teo15 = a.teo(); teo15 = ptr_v -> teo() B.17.8. Funciones miembro constante Una funcin miembro constante es aquella que garantiza no se modifica el estado del objeto de la clase til. class Punto { public: Punto (int xval, int yval); int LeerX() const; void Fijarx (int xval); //... }; La palabra reservada const debe aparecer tambin en la implementa- cin de la funcin int Punto::LeerX() const { return x; } B.17.9. Funciones cIases amigas (friend) Una amiga (friend) de una clase tiene acceso a todos los miembros de esa clase. Si una funcin F, amiga de una clase C, utiliza un objeto de la clase C, es como si todos los miembros de C fueran declarados pblicos. El tipo ms comn de amigo de una clase es una funcin. Las clases tambin pueden ser amigas de otras clases. Para declarar una funcin como amiga de una clase, se ha de incluir un prototipo de la funcin interior a la declaracin de la clase, precedida de la palabra reservada friend. class nombre { ... friend prototipo_de_funcion; ... }; para declarar una clase como amiga, se utiliza la siguiente sintaxis: class nombre { ... friend class nombre_clase; }; Funcion amiga class Estudiante; class Empleado { public: Empleado (long idVal); friend void RegistrarEstudiante (Estudiante &S, Empleado &E, float tasa); private: long id; //nmero de matrcula float PagoTasa; }; CIase amiga class clase_1 { friend class clase_2; //... }; class clase_2 { friend class clase_3; }; 586 PROGRAMACIN EN C++. ALGORITMOS, ESTRUCTURAS Y OBJETOS B.17.10. EI puntero this Dentro de una funcin miembro, la palabra reservada this es el nombre de un puntero implcito al objeto actual. Cuando se desea utilizar el puntero oculto en el cdigo de la funcin miembro, se utiliza la palabra reservada this. La mayora de las veces, el uso de this es innecesario, ya que C++ supone el uso de this siempre que se refiera a miembros dato. Cpunto::fijar(double nuevox, double nuevoy) { x = nuevox; //x significa lo mismo que this-> x y = nuevoy; //y significa lo mismo que this-> y } B.18. HERENCIA Una herencia es una relacin es-un entre dos clases, en la que una nueva clase se deriva de otra clase denominada clase base. La nueva clase, se denomina clase derivada. La relacin es-un se manifiesta como un estu- diante de doctorado es-un estudiante que est escribiendo una tesis. Sintaxis class nombre_clase_derivada: (public|protected|private) clase_base { declaraciones }; clase_base es el nombre de la clase del que se deriva la clase actual derivada los especificadores de acceso pueden ser public, pro- tected o private. Un miembro public es accesible a travs de su mbito; los miembros de clase_base se heredan sin modificacin en su estado. Un miembro privado (private) es accesible a otras funciones miembro dentro de su propia clase. Un miembro protegido (protected) es accesible a otras funciones miembro dentro de su clase y a cualquier clase derivada de ella. Los modificadores de acceso se pueden utilizar dentro de una declaracin de una clase en cualquier orden y con cualquier frecuencia. class D : public A { ... }; La herencia mltiple permite que una clase sea derivada de ms de una clase base. En el siguiente ejemplo, D es la clase derivada, y Bl, B2 y B3 son clases base. class D : public B1, public B2, private B3 { ... }; La palabra reservada virtual es un especificador de funcin que pro- porciona un mecanismo para seleccionar en tiempo de ejecucin la funcin miembro apropiada a partir de la clase base y clases derivadas class D : public virtual B1, public virtual B2 { ... }; class Estudiante : public virtual Persona { //... class Empleado : public virtual Persona { //... B.19. SOBRECARGA DE OPERADORES La sobrecarga de operadores se refiere a la tcnica que permite proveer un nuevo significado a los operadores estndar tales como =, < <, ... Dicho de otro modo, se pueden definir funciones operador para sus clases. Una funcin operador es una funcin cuyo nombre consta de la palabra reservada operator seguida por un operador binarlo o unitario con el for- mato: operator operador // Sobrecarga de operadores aritmticos y // de asignacin class Punto } //... public: //... Punto operator * (const Punto& p); Punto operator / (const Punto& p); Punto operator += (const Punto& p); //... }; //implementacin de funcin miembro sobrecargada //p1 * p2 inline Punto Punto::operator * (const Punto& p) { return Punto (x * p.x, y * p.y, z * p.z); } //p1 / p2 ... GUA DE SINTAXIS ANSI/ISO ESTNDAR C++ 587 Una vez declarada y definida la clase se pueden escribir expresiones tales como: Punto p, q, r; //... r = p * q; //multiplicacin //... r = p + = q; //asignacin encadenada y aritmtica //... B.19.1. Funciones operador unitario @operando @, operador El compilador evala la expresin llamando a una de las siguientes fun- ciones, dependiendo de la que est definida: tipo_retorno tipo::operator@() tipo_retorno operator@ (tipo) Dependiendo del propio, la expresin que utiliza un operador unitario puede ser de la forma operator@ B.19.2. Funciones operador binario Se puede escribir una funcin operador binario para un operador (tal como +, , *, ) que C++ acepta como un operador binario operando1@ operando2 @ operador el compilador evala la expresin llamando a una de las siguientes funcio- nes, dependiendo de en cul est definida tipo_retorno tipo1::opera tor@ (tipo2) tipo_retorno tipo2::operator@ (tipo1, tipo2) tipol y tipo2 son los tipos de operando1 y operando2, respectiva- mente. B.19.3. Funciones operador de asignacin La declaracin de esta funcin es: class & clase::operator = (const clase &) Un ejemplo que ilustra una funcin operador de asignacin class Cpunto { private: double x, y; public: Cpunto& operator = (const Cpunto& punto); ... }; B.19.4. Operadores de incremento y decremento Los operadores incremento (+ +) y decremento ( ) siguen la mayora de las reglas de los operadores unitarios, pero tambin pueden ser prefijo y postfijo. Los siguientes ejemplos ilustran las versiones prefijas y postfijas del operador de incremento (+ +). class Cpunto { private: double x, y; public: Cpunto& operator++(); //prefijo Cpunto operator++(int); //postfijo }; class P { public: void operator++(int); void operator--(int); }; B.20. PLANTILLAS (tempIates) La palabra reservada template se utiliza para implementar tipos parametrizados o plantillas. C++ reconoce dos tipos de plantillas: planti- llas de clases y plantillas de funciones. Sintaxis template < argumentos_plantilla > //plantilla de clase declaracin_de_clase template < argumentos_plantilla > //plantilla de funcin definicin_funcin < argumentos_plantilla > es class arg_nombre 588 PROGRAMACIN EN C++. ALGORITMOS, ESTRUCTURAS Y OBJETOS B.20.1. PIantiIIas de funciones Una plantilla de funcin debe tener al menos un tipo de parmetro, pero puede tener ms. Su formato es: template <classT> tipo-retorno nombre-funcin(T parmetro) T es un parmetro de plantilla template <class T> void Presentar (const T &valor) { cout << valor; } Una funcin plantilla puede tener parmetros adicionales template <class T> void Intercambio(T& x, T& y) { T aux; aux = x; x = y; y = aux; } int m, n; Estudiante S1; Estudiante S2; //... Intercambio(m, n); //llamada con enteros Intercambio(S1, S2); //llamada con estudiantes B.20.2. PIantiIIas de cIases Las plantillas de clases ofrecen la posibilidad de generar nuevas clases. Los tipos ms comunes de plantillas son clases contenedoras, tales como arrays, listas y conjuntos. Cada plantilla puede trabajar con una variedad de tipos de datos. El formato bsico para definir una plantilla de clase es: template <class T> class MiClase { //... }; T puede ser un tipo o una expresion. Las plantillas se instancian para crear clases a partir de ellas. MiClase <int> x; MiClase <Estudiante> miEstudiante; Una plantilla puede tener mltiples parmetros template <class T1, class T2> class Circulo { //... private: Tl x; T2 y; T2 radio; }; //... Circulo <int, long> c; Circulo <unsigned, float> D; Un ejemplo clsico es una Pila de datos template <class T> class pila { T *pilap; int longitud; int indice; public: T sacar(void) {return pilap[--indice];} void meter(T item){pilap[indice++] = item; } ... }; Esta plantilla se puede instanciar del modo siguiente: pila<int> elementos(30); //pila de enteros pila<CCad> cadenas(20); //pila de objetos Ccad B.21. EXCEPCIONES El manejo o manipulacin de excepciones es el mecanismo para detectar y manipular excepciones. Un manipulador de excepciones es un bloque de cdigo que procesa condiciones de error especficas. Una excepcin es, casi siempre, un error en tiempo de ejecucin, tal como falta de memoria, fallo al abrir un archivo, errores de rango de subndice o divisin por cero. GUA DE SINTAXIS ANSI/ISO ESTNDAR C++ 589 En C++, cuando se genera una excepcin, el error no se puede ignorar o terminar el programa. Un programa lanza o dispara (throws) una excep- cin en el punto en que se detecta el error. Cuando sucede esto, un progra- ma C++ busca automticamente el manipulador de excepciones, que res- ponde a la excepcin de algn modo apropiado. Esta respuesta se denomina capturar una excepcin (catching). Si no se puede encontrar un manipu- lador de excepciones el programa terminar. B.21.1. Lanzamiento de excepciones Pueden ocurrir muchos tipos diferentes de excepciones, de modo que cuando se lanza una excepcin, una expresin throw excepcin (o slo throw) identifica el tipo de excepcin. La sintaxis adopta dos formatos: throw throw expresin //lanzamiento de una excepcin, creando un subndice //est fuera de rango const unsigned LongArray = 500; unsigned i; . . . if (i > = LongArray) //es el subndice vlido throw ErrorRango; La palabra reservada try, junto con las sentencias que le siguen ence- rradas entre llaves, se llama un bloque try. Debe ser seguido inmediatamen- te por uno o ms manejadores de excepciones. Cada manejador de excep- ciones comienza con la palabra reservada catch seguida por un bloque que contiene sentencias. try { lista_de_sentencias } catch (lista_de_parmetros){ lista_de_sentencias } catch (lista_de_parmetros){ lista_de_sentencias } B.21.2. Manejador de excepciones Un bloque catch se conoce tambin como manejador de excepciones y se parece a una declaracin de funcin de un argumento sin un tipo de retorno. catch (const char* mensaje) { cerr << mensaje << endl; exit(1); } B.21.3. Especificacin de excepciones Sintcticamente, una especificacin de excepciones es parte de una decla- racin de funciones y tiene el formato: cabecerafuncin throw (lista de tipos) La lista de tipos son los tipos que pueden tener una sentencia throw expresin dentro de la llamada de la funcin; si la lista es vaca, el compi- lador puede suponer que ninguna sentencia throw se ejecutar por la fun- cin, bien directa o bien indirectamente void demo() throw(int, desbordamiento); void nodemo(int i) throw(); As, una declaracin de funcin: void Demo() throw (A, B) { //... } se tratar del siguiente modo: void Demo() { try { //... llamada a Demo() } catch (A) throw; } catch (B) } //... } catch (...) { //unexpected } 590 PROGRAMACIN EN C++. ALGORITMOS, ESTRUCTURAS Y OBJETOS Si una funcin no est especificada con una declaracin throw puede lanzar cualquier excepcin. La declaracin throw() indica que una funcin no lanza ninguna excepcin. Si una funcin lanza una excepcin que no est en su declaracin, se llama a la funcin unexpected. En la mayora de las implementaciones, unexpec- ted llama a terminate que llama a abort. La funcin set_unexpected permite definir el manejo de excepciones no previstas. Todas estas declaracio- nes de funciones se encuentran en al archivo except o bien except.h. B.21.4. Excepciones en Ia bibIioteca estndar Las excepciones de la biblioteca estndar se derivan de la clase base excep- tion. Dos de las clases derivadas son logic_error y runtime_error. Los errores de tipo lgico incluyen bad_cast, out_of range y bad_ typeid, y los errores de tiempo de ejecucin incluyen range_error, overflow_error y bad_alloc. class logic_error: public exception { public: logic_error; { const string & que_arg; //... } }; EjempIo de excepcion Iogica Los errores lgicos informan de un problema que es detectable antes de que un programa se ejecute class doman-error : public logic_error { public: domain_error { const string & que_arg } }; EjempIo de excepcion de tiempo de ejecucion Los errores en tiempo de ejecucin ocurren durante la ejecucin del pro- grama class range_error : public runtime-error { public: range_error; { const string & que_arg; } }; B.21.5. Resumen de sintaxis de excepciones throw valor; try { sentencias { catch (tipo_excepcin){ sentencias } try { sentencias } catch (dec_argumentos1) { sentencias } catch (dec_argumentos2) { sentencias } ... throw; B.22. ESPACIO DE NOMBRES (Namespaces) Un espacio de nombres (namespace) es un mecanismo para expresar agru- pamientos lgicos. Es decir, si algunas declaraciones se pueden agrupar lgicamente de acuerdo a algn criterio, se pueden poner en un espacio de nombres comn que expresen dicho hecho. La palabra reservada namespa- ce define un espacio de nombres namespace nombre { cuerpo_espacio_de_nombres } Este formato crea un espacio de nombre con el calificador nombre. Den- tro de los caracteres llave ({ }), cuerpo_espacio_de_nombres puede incluir variables, definiciones de funciones y prototipos, estructuras, clases, GUA DE SINTAXIS ANSI/ISO ESTNDAR C++ 591 enumeraciones (enum), definiciones de tipos (typedef) o bien otras definiciones de espacios de nombres. Obsrvese que un espacio de nombre no termina con un punto y coma. Las definiciones de espacio de nombres aparecen en archi- vos de cabecera y en mdulos independientes con definiciones de funciones. EjempIo namespace Rojo { int j; void imprimir(int i) {cout << Rojo::imprimir() << i << endl;} } namespace Azul { int j; void imprimir(int); } void sub1() {...} //puede acceder a espacio de nombres //Azul y Rojo void sub() {...} //puede acceder a espacio de nombres //Azul y Rojo Los espacios de nombre Rojo y Azul tienen dos miembros con el mismo nombre: entero j y funcin imprimir() (normalmente estas defi- niciones no podran convivir en un espacio global, pero un espacio de nom- bre elimina ese problema). Un espacio de nombre puede incluir definiciones de funciones y prototipos de funciones. Las definiciones de funciones de sub1() y sub2() tienen acceso a todos los miembros del espacio de nom- bres Rojo y Azul. B.22.1. Extensiones Los espacios de nombre son extensibles; es decir, se pueden aadir declara- ciones posteriores a espacios de nombre definidos anteriormente. Las exten- siones del espacio de nombres pueden aparecer tambin en archivos inde- pendientes de la definicin original del espacio de nombre. namespace Azul{ //definicin original de espacio de nombre int j; void imprimir (int); } namespace Azul{ //extensin del espacio de nombre char car; char bufer[20]; } ... B.22.2. Acceso a Ios miembros de un espacio de nombre El operador de resolucin de mbito proporciona acceso a miembros de un espacio de nombre. nombre_espacio_de-nombre::nombre_miembro nombre_espacio_de_nombre es un cualificador de espacio de nombre definido con anterioridad y nombre_miembro debe estar declarado dentro de nombre_espacio_de_nombre. void Azul::imprimir(int k){ cout << Azul::imprimir() = << k << endl; } El operador de resolucin de mbito asocia imprimir() con el espacio de nombre Azul; sin el mismo, el compilador define imprimir() como una funcin global. B.22.3. Espacio de nombre sin nombres Es muy til, en ocasiones, envolver un conjunto de declaraciones en un espacio de nombre simplemente para proteger frente a la posibilidad de conflictos de nombres. El formato es: namespace { cuerpo_nombre_de_espacio } Todos los miembros definidos en cuerpo_nombre_de_espacio estn en un espacio de nombre sin nombre que se garantiza nico para cada uni- dad de traduccin. B.22.4. Directivas using El acceso a los miembros de espacio de nombre puede tener dificultades, especialmente con calificadores de espacio de nombre largos y espacios de nombre anidados. Las directivas using proporcionan acceso a todos los miembros del espacio de nombre sin un cualificador de espacio de nombre y el operador de mbito. El formato es: using namespace nombre; 592 PROGRAMACIN EN C++. ALGORITMOS, ESTRUCTURAS Y OBJETOS El cualificador nombre debe ser un nombre de espacio definido anterior- mente. Pueden aparecer las directivas using en mbitos locales y globales. B.22.5. DecIaraciones using Las directivas using hacen a todos los miembros del espacio de nombre accesibles sin cualificacin. En contraste, las declaraciones using cualifi- can slo miembros individuales de espacio de nombre. El formato es: using nombre_espacio_de_nombre::nombre-miembro; namespace Negro{ //define espacio de nombre Negro int j; void imprimir(int); char car; } namespace Blanco{ int j; void imprimir(int); double vision; } using Blanco::vision; B.22.6. AIias de espacio de nombres Los alias de espacio de nombres crean nombres sinnimos de espacio de nombres. Es buena prctica utilizar alianzas cuando un espacio de nombre tiene un nombre largo. El formato es: namespace nombre_alias = nombre_de_espacio; EjempIo namespace Universidad_Pontificia-deSalamanca_enMadrid{ //... } Universidad_Pontificia_deSalamanca_enMadrid::String c3 = Fundacin; Universidad_Pontificia_deSalamanca_enMadrid::String c4 = Pablo VI; El cdigo anterior es poco prctico en cdigo real; un alias corto resuel- ve el inconveniente // uso de alias para abreviaturas namespace UPSAM = Universidad_Pontificia_deSalamanca_enMadrid; UPSAM::String c3 = Fundacin; UPSAM::String c4 = Pablo VI; namespace Geometria{ struct Punto { double x, y; }; double pendiente (Punto, Punto); } El espacio de nombres incluye un tipo Punto y una funcin pendien- te. La implementacin del archivo geometria.c // geometria.c #include geometria.h namespace Geometria { // extensin de espacio de nombre Punto origen = {0, 0}; } double Geometria::pendiente (Punto p1, Punto p2){ double dy = p2.y - p1.y; double dx = p2.x - p1.x; if (dx = = 0) throw pendiente() : pendiente no definida; return dy / dx; } Una extensin del espacio de nombre ha aadido un miembro origen a Geometria. La funcin pendiente() calcula la pendiente de los puntos pl y p2 y levanta una excepcin de cadena de caracteres si el denominador de la pendiente es cero. B.22.7. Espacio de nombres anidados Los espacios de nombres son ilegales en el interior de funciones, pero pue- den aparecer en otras definiciones de espacio de nombre. namespace Exterior int i, j; namespace Interior const int Max = 20; char car; char bufer[Max]; void imprimir(); } } GUA DE SINTAXIS ANSI/ISO ESTNDAR C++ 593 El acceso a los miembros de un espacio de nombres anidados se resuel- ve con el operador de resolucin de mbito (::) void Exterior::Interior::imprimir() { for (int i = 0; i < Max; i++) //i es local al bucle for cout << bufer[i] << ; cout << endl; } B.22.8. Un programa compIeto con espacio de nombres El archivo de cabecera geometria.h define un espacio de nombre para una biblioteca de geometria (geometria). #ifndef GEOMETRIAH #define GEOMETRIAH // archivo geometria.h Aplicacin. Utilizar el espacio de nombre Geometria para calcular pen- dientes de las variables Punto. #include <iostream.h> #include geometria.h namespace Geo = Geometria; //alias using Geo::Punto; using Geo::pendiente; namespace { Punto origen = {10, 10}; } int main() { try { Punto a = {3, 5} Punto b = {6, 10}; cout << La lnea ab tiene la pendiente << pendiente(a,b) << endl; cout << La linea origen_a tiene la pendiente << pendiente (origen,a) << endl; } catch (char *msg) { cout << msg << endl; return 1; } return 0; } #endif Al ejecutar el programa se obtendr: La lnea ab tiene la pendiente 1.66667 La lnea origen_a tiene la pendiente 0.714286 594 PROGRAMACIN EN C++. ALGORITMOS, ESTRUCTURAS Y OBJETOS