Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Curso de C++
Curso de C++
Estilo:
Normal
Activar
Con Clase
C++
Win API 32
HTML y CSS
Grficos
MySQL
Artculos
Listas
<<
<
>
>>
Curso
Info
Bibliotecas
Tabla
Comentario
o
o
o
o
o
Introduccin
1 Toma de contacto
2 Tipos de variables I
3 Funciones I
4 Operadores I
5 Sentencias
6 Declaracin de variables
7 Notacin
8 Cadenas de caracteres
9 Conversin de tipos
10 Variables II: Arrays
11 Objetos III: Estructuras
12 Objetos IV: Punteros 1
13 Operadores II
14 Oper III: Precedencia
15 Funcs II: valor y referencia
16 Variables V: Uniones
17 Variables VI: Punteros 2
18 Operadores IV
19 Definicin de tipos
20 Funciones III: ms cosas
21 Funciones IV: Sobrecarga
22 Operadores V: Sobrecarga
23 El preprocesador
Directiva #define
Directiva #undef
Directivas condicionales
Directivas #ifdef, #ifndef
Directiva #error
o
o
o
o
Directiva #include
Directiva #line
Directiva #pragma
Directiva #warning
24 Funciones V: Recursividad
25 Vbls VII: Almacenamiento
26 Espacios con nombre
27 Clases I: definiciones
28 Declaracin de una clase
29 Constructores
30 Destructores
31 El puntero this
32 Sistema de proteccin
33 Modificadores
34 Ms sobre las funciones
35 Operadores sobrecargados
36 Herencia
37 Funciones virtuales
38 Derivacin mltiple
39 Trabajar con ficheros
40 Plantillas
41 Punteros a miembros
42 Castings en C++
43 Manejo de excepciones
A Codificacin ASCII
B Palabras reservadas
C Bibliotecas estndar
D Trigrafos y smbolos alt.
E Streams
23 El preprocesador
^
Directiva #define
La directiva #define, sirve para definir macros. Las macros suministran un
sistema para la sustitucin de palabras, con y sin parmetros.
^
Sintaxis:
#define identificador_de_macro <secuencia>
Directiva #undef
^
De este modo, la lnea del #define se ignorar si el smbolo NULL ya est definido.
Todas las directivas condicionales deben completarse dentro del mismo fichero.
Slo se compilarn las lneas que estn dentro de las secciones que cumplan la
condicin de la expresin constante correspondiente.
Estas directivas funcionan de modo similar a los operadores condicionales C++. Si
el resultado de evaluar la expresin-constante-1, que puede ser una macro, es
distinto de cero (true), las lneas representadas por seccin-1, ya sean lneas de
comandos, macros o incluso nada, sern compiladas. En caso contrario, si el
resultado de la evaluacin de la expresin-constante-1, es cero (false), la seccin-1
ser ignorada, no se expandirn macros ni se compilar.
En el caso de ser distinto de cero, despus de que la seccin-1 sea preprocesada, el
control pasa al #endif correspondiente, con lo que termina la secuencia
condicional. En el caso de ser cero, el control pasa al siguiente lnea #elif, si existe,
donde se evaluar la expresin-constante-2. Si el resultado es distinto de cero, se
procesar la seccin-2, y despus el control pasa al correspondiente #endif. Por el
contrario, si el resultado de la expresin-constante-2 es cero, el control pasa al
siguiente #elif, y as sucesivamente, hasta que se encuentre un #else o un #endif.
El #else, que es opcional, se usa como una condicin alternativa para el caso en
que todas la condiciones anteriores resulten falsas. El #endif termina la secuencia
condicional.
Cada seccin procesada puede contener a su vez directivas condicionales, anidadas
hasta cualquier nivel, cada #if debe corresponderse con el #endifms cercano.
El objetivo de una red de este tipo es que slo una seccin, aunque se trate de una
seccin vaca, sea compilada. Las secciones ignoradas slo son relevantes para
evaluar las condiciones anidadas, es decir asociar cada #if con su #endif.
Las expresiones constantes deben poder ser evaluadas como valores enteros.
Sintaxis:
#ifdef <identificador>
#ifndef <identificador>
La lnea:
#ifdef identificador
#ifndef identificador
Directiva #error
^
Este ejemplo est extrado de uno de los ficheros de cabecera del compilador GCC:
#ifndef BFD_HOST_64_BIT
#error No 64 bit integer type available
#endif /* ! defined (BFD_HOST_64_BIT) */
Directiva #include
La directiva #include, como ya hemos visto, sirve para insertar ficheros externos
dentro de nuestro fichero de cdigo fuente. Estos ficheros son conocidos como
ficheros incluidos, ficheros de cabecera o "headers".
^
Sintaxis:
#include <nombre de fichero cabecera>
#include "nombre de fichero de cabecera"
#include identificador_de_macro
La diferencia entre escribir el nombre del fichero entre "<>" o """", est en el
algoritmo usado para encontrar los ficheros a incluir. En el primer caso el
preprocesador buscar en los directorios "include" definidos en el compilador. En el
segundo, se buscar primero en el directorio actual, es decir, en el que se encuentre
el fichero fuente, si no existe en ese directorio, se trabajar como el primer caso.
Si se proporciona el camino como parte del nombre de fichero, slo se buscar es el
directorio especificado.
Directiva #line
^
Esta directiva se usa para sustituir los nmeros de lnea en los programas de
referencias cruzadas y en mensajes de error. Si el programa consiste en secciones de
otros ficheros fuente unidas en un slo fichero, se usa para sustituir las referencias
a esas secciones con los nmeros de lnea del fichero original, como si no se hubiera
integrado en un nico fichero.
La directiva #line indica que la siguiente lnea de cdigo proviene de la lnea
"constante_entera" del fichero "nombre_de_fichero". Una vez que el nombre de
fichero ha sido registrado, sucesivas apariciones de la directiva #line relativas al
mismo fichero pueden omitir el argumento del nombre.
Las macros sern expandidas en los argumentos de #line del mismo modo que en
la directiva #include.
La directiva #line se us originalmente para utilidades que producan como salida
cdigo C, y no para cdigo escrito por personas.
Directiva #pragma
^
Sintaxis:
#pragma nombre-de-directiva
Con esta directiva, cada compilador puede definir sus propias directivas, que no
interferirn con las de otros compiladores. Si el compilador no reconoce el nombrede-directiva, ignorar la lnea completa sin producir ningn tipo de error o
warning.
Teniendo lo anterior en cuenta, veamos una de las directivas pragma ms
extendidas en compiladores, pero teniendo en cuenta que no tienen por qu estar
disponibles en el compilador que uses.
Tampoco es bueno usar estas directivas, ya que suelen hacer que el cdigo no sea
portable, es mejor buscar alternativas.
Directiva #pragma pack()
Esta directiva se usa para cambiar la alienacin de bytes cuando se declaran objetos
o estructuras.
Recordemos lo que nos pasaba al aplicar el operador sizeof a estructuras con el
mismo nmero y tipo de campos, aunque en distinto orden.
{
"Tamao de int: "
sizeof(int) << endl;
"Tamao de char: "
sizeof(char) << endl;
"Tamao de estructura A: "
sizeof(A) << endl;
"Tamao de estructura B: "
sizeof(B) << endl;
return 0;
}
de
de
de
de
int: 4
char: 1
estructura A: 10
estructura B: 12
Vemos que ahora la estructura A ocupa exactamente lo mismo que la suma de los
tamaos de sus componentes, es decir, 10 bytes.
Esta directiva funciona como un conmutador, y permanece activa hasta que se
cambie el alineamiento con otra directiva, o se desactive usando la forma sin
parmetros.
Por ejemplo:
struct __attibute__((__packed__)) A {
int x;
char a;
int y;
char b;
};
Esta forma tiene el mismo efecto que el ejemplo anterior, pero tiene algunas
ventajas.
Para empezar, se aplica slo a la estructura, unin o clase especificada. Adems, nos
aseguramos de que o bien el compilador tiene en cuenta este atributo, o nos da un
mensaje de error. Con la directiva #pragma, si el compilador no la reconoce, la
ignora sin indicar un mensaje de error.
El otro atributo, __aligned__ requiere un nmero entero como parmetro, que es
el nmero del que las direcciones de memoria han de ser mltiplos:
struct __attibute__((__aligned__(4))) A {
int x;
char a;
int y;
char b;
};
Directiva #warning
^
Sintaxis:
#warning mensaje_de_aviso
Sirve para enviar mensajes de aviso cuando se compile un fichero fuente C o C++.
Esto nos permite detectar situaciones potencialmente peligrosas y avisar al
programador de posibles errores.
Este ejemplo est extrado de uno de los ficheros de cabecera del compilador GCC:
#ifdef __DEPRECATED
#warning This file includes at least one deprecated or antiquated
header. \
Aprovecho para comentar que una lnea en el editor se puede dividir en varias
aadiendo el carcter '\' al final de cada una. En el ejemplo anterior, todo el texto
entre la segunda y la sexta lnea se considera una nica lnea por el compilador.
[ Arriba ] [ Operadores ] [ Entradas y salidas ] [ Decl. y def. ]
Por Alberto
Valero para la
Web del
Programador
tipo_devuelto
nombre_funcin (parmetros);
la misma, en el que podremos utilizar todo lo visto hasta ahora (declaracin de variables, bucles,
sentencias de control de la lgica, etc.) La manera de utilizar variables o llamar a otras funciones sigue
la misma lgica que en turbo pascal, Podremos utilizar variables globales o variables locales definidas en
la funcin, y podremos llamar a todas la funciones que haya sido previamente declaradas (ojo no es
necesario que hayan sido definidas).
El valor que devuelve la funcin lo indicaremos en el cuerpo de la misma con la palabra
reservada return valor;
Veamos un programa ejemplo que aplique todo esto:
#include<iostream.h>
int factorial(int); //declaramos la funcin factorial.
main( )
//funcin principal del programa.
{
cout<<"Introduce un nmero del que quieras hallar el factorial";
int i;
cin>>i;
cout << "El factorial de " << i << " es: "<< factorial(i);
}
int factorial(int a)
//Ahora definimos la funcin factorial.
{
int aux;
for (int i=1; i<=a; i++)
{
aux = aux*i;
}
return aux;
//valor que devuelve la funcin
}
LA FUNCIN MAIN
Todos los programas en C++ tienen un punto de entrada al programa denominado main(). Esto quiere
decir, que cuando compilamos un programa y lo ejecutamos, el programa buscar el conjunto de
rdenes que vienen dadas pos las sentencias de la funcin main(), y por lo tanto est ser
imprescindible en cualquier programa escrito en C++.
Para nosotros de momento la funcin main no tomar parmetros ni devolver nada, por lo que su
cabecera ser void main(void).
ARGUMENTOS POR OMISIN EN UNA FUNCIN
Todos los parmetros formales de una funcin, o bien algunos de ellos (desde un determinado
parmetro hasta el final), se pueden declarar por omisin. Es decir en la declaracin de la funcin o en
su definicin se especificarn los valores que deberan asumir los parmetros cuando se produzca una
llamada a la funcin y se omitan los mismos para tales parmetros. Por ejemplo, imaginemos la funcin
factorial antes utilizada,
int factorial (int a=10) //definimos el valor por defecto de a en 10.
{
...
}
main( )
{
cout<< factorial ( );
}
Mostrara por pantalla el factorial de 10, ya que no le hemos pasado ningn parmetro (si le
passemos alguno, evidentemente calculara el factorial del parmetro que le passemos.
FUNCIONES EN LNEA
Cuando una funcin se califica en lnea (incline) el compilador tiene la facultad de reemplazar
cualquier llamada a la funcin en el programa fuente, por el cuerpo actual de la funcin. Quiere decir
esto, que el compilador puede tomar la iniciativa de no expandir la funcin, por ejemplo, por ser
demasiado larga.
Con esto conseguimos que el compilador inserte el cdigo de la funcin compilada en el ejecutable cada
vez que la llamemos. Si la funcin se utiliza, por ejemplo diez veces, entonces el cdigo de esa funcin
aparece en el programa diez veces, en lugar de slo una vez, como es el caso de una funcin estndar.
Esta propiedad de C++ reduce el tiempo de ejecucin de los programas, pero aumenta
considerablemente el tamao de los mismos.
La declaracin de las funciones en lnea se hace anteponiendo la palabra inline.
inline int factorial (int a)
Las funciones en lnea si que deben haber sido definidas antes de su utilizacin.
FUNCIONES SOBRECARGADAS
La sobrecarga de funciones es una caracterstica de C++ que hace los programas ms legibles. Consiste
en que un conjunto de funciones que realizan la misma tarea o una tarea muy similar tengan el mismo
nombre, que tal manera que en funcin de los parmetros que le pasemos el compilador sepa en cada
momento cual de ellas debe utilizar.
Por ejemplo, supongamos una funcin llamada suma, esta deber ser diferente si queremos sumar
complejos, de otra en la que queramos sumar enteros, pues bien, en C++ se pueden utilizar dos
funciones llamadas suma como sigue...
typedef complejo int[2]
int suma (int a, int b)
{
return (a+b)
}
complejo suma (complejo a, complejo b)
{
complejo aux;
aux[1]=a[1] + b[1];
aux[2]=a[2]+b[2];
return aux;
}
Hemos definido un tipo de dato que ser complejo formado por un vector de dos elementos, entonces,
si al llamar a la funcin, le pasamos como parmetros dos enteros nos ejecutar el cuerpo de la funcin
que hemos definido primero y en caso de que le pasemos dos variables de tipo complejo ejecutar la
segunda.
Todas las posibilidades que hemos visto hasta ahora de trabajar con funciones, obviamente se pueden
mezclar unas con otras, es decir podramos definir perfectamente dos funciones sobrecargadas que