Professional Documents
Culture Documents
FACULTAD DE CIENCIAS
ESCUELA DE COMPUTACIN
Manual bsico de
Programacin en C++
Seleccin: DZ
ndice
(RECOPILACION I)
Diferencias entre C y C++
(1)
(2)
(3)
(4)
(5)
(6)
(8)
(10)
(11)
(12)
(13)
(15)
(17)
(19)
Arreglos de registros
Definicin de tipos (Typedef)
(21)
Archivos
(22)
Apertura de archivos
Modo texto
Modo binario
Cierre de registros
Escritura y lectura de registros:
Un carcter
Un nmero entero
Una cadena de caracteres
Con formato (CDT)
Registros (material adicional)
Otras funciones para archivos
Deteccin de final de archivo
Prototipos de funcin y verificacin de tipo de dato
Operador de resolucin de alcance unario
(28)
(29)
(RECOPILACION II)
Resumen sobre las libreras de C++
Las clases estndar de C++ para entrada/salida
Declaracin, apertura y cierre de canales para archivo
Modo Descripcin
Como crear clases en C/C++
Control de acceso a miembros (CDA)
Archivos de cabecera
Declaracin de las funciones
Paso de parmetros a una funcin
Funciones constructoras
Funcin destructora
Cuando son llamados los destructores y constructores?
Asignacin por omisin en copia a nivel de miembro en C
Funciones en lnea
Verificacin de tipos en C++
Cmo poner en prctica un TDA con una clase?
Un cdigo fuente en C++
Como leer registros
Pase de parmetros por referencia
Variable booleana en un condicional
Nuevo tipo interesante de arreglo en c
Impresin de arreglo
Libreras9 de C++
Librera stdio.h
(31)
(32)
(33)
(34)
(35)
(36)
(37)
(40)
(41)
clrscr,clreol,gotoxy,textcolor,textbackground,wherex,wherey,getch,getche
9 Las funciones de las librerias de C++ dependen del compilador que se este usando lo recomendable es no
usar funciones que otros compiladores no reconoceran si el programa es para otros. Por ejemplo el void
detalle cumple la funcion de gotoxy()
Librera string.h
strlen , strcpy , strcat , strcmp
Funciones interesantes
fflush(stdin),sizeof,cprintf,kbhit,random,randomize,system
Conversin de tipos en C++ (CDT)
Excepciones en C++
Operaciones con Objetos en C++
ASIGNACIN DE OBJETOS
ARRAY DE OBJETOS
Unidimensional
Bidimensional
DECLARACIN, INICIALIZACIN
PASO DE OBJETOS A FUNCIONES:
OBJETOS DEVUELTOS POR FUCIONES
PUNTEROS A OBJETOS
Funciones Constructoras y Destructoras
CONSTRUCTORES CON PARAMETROS
Sobrecarga de Funciones y Operadores
Prioridad de operadores en C (ver simplificada)
Funciones inline y Automticas2
Utilizacin de Estructuras como Clases2
this, new y delete2
Referencias2
Herencia2
Herencia mltiple2
Funciones Virtuales2
Funciones Amigas2
Tipo de dato referencia2
(44)
(46)
(47)
(48)
(50)
(51)
(52)
(53)
(56)
(62)
(63)
(64)
(66)
(70)
(71)
(73)
(76)
(77)
(79)
(83)
Punteros a estructuras
(88)
(89)
(90)
(91)
ESTRUCTURAS DE ALMACENAMIENTO
UNIONES
(92)
CADENAS EN C++
(93)
MAS SOBRE FUNCIONES EN C++
Definicin de funciones
(94)
(95)
Sobrecarga de funciones
(96)
(97)
(98)
(100)
La sentencia nula en C
Prioridad y asociatividad de operadores en C (ver completa)
(101)
Salida
Uso de flujos para salida de caracteres.
Entrada
(102)
(103)
Manipuladores de C
Palabras reservadas de C (ver completa)
Laboratorio 4
#1 de C++ UCV
4
Laboratorio
#2 de C++ UCV
Sentencias de salto
Sentencias break, continue, goto
SOBRE ALGUNOS OPERADORES (?,::,)
Los backward_warning.h o warning!! de C/C++
(Una cuestin para ignorar y ejecutar el programa)
Estructuras de almacenamiento (EDA)
Manejo de EDA y apuntadores
Gestin dinnica de memoria
Constantes de tipo enumeracin
Diferencias entre POO y POC
La librera para generar tiempo en C++ time.h
Uso del system(cls)
Creacin de un objeto en C++
(Cdigo fuente del void detalle versin final)
Plantilla de men en C++
(Cdigo fuente del programa, una forma muy bsica P.O.O.)
Recursividad en C++
Los ciclos infinitos de C++
Sentencias break, continue
Instrucciones inmediatas
if, else, for,..
Paso de punteros a objetos
Por valor y por referencia.
Lnea de comandos
Ubicacin del programa en la unidad C:
Entrada vs Salida
Archivos
(105)
(106)
(112)
(120)
(121)
(122)
(123)
(125)
(128)
(129)
(130)
(136)
(139)
(140)
(141)
(145)
(148)
(RECOPILACION III)
(149)
(150)
(160)
(165)
(166)
(171)
(174)
(176)
(180)
(184)
(191)
(193)
(199)
(200)
(201,)
1En
muchas sintaxis el TDD se coloca simplemente como <tipo>, <valor_devuelto>. Una funcin
en cualquier lenguaje de programacin, tambin se puede llamar como un: tipo operador.
2 Estudiar
char f1(void);
char f1();
(1)
Tamao
1 byte
2 bytes
4 bytes
8 bytes
Rango de valores
-128 a 127
-32768 a 32767
3'4 E-38 a 3'4 E+38
1'7 E-308 a 1'7 E+308
(3)
Calificadores de tipo
Los calificadores de tipo tienen la misin de modificar el rango de valores de un
determinado tipo de variable. Estos calificadores son cuatro:
signed char
signed int
unsigned char
unsigned int
Tamao
1 byte
2 bytes
Rango de valores
0 a 255
0 a 65535
short char
short int
Rango de valores
-128 a 127
-32768 a 32767
Tamao
1 byte
2 bytes
Rango de valores
-128 a 127
-32768 a 32767
long char
long int
Tamao
4 bytes
10 bytes
Rango de valores
-2.147.483.648 a 2.147.483.647
-3'36 E-4932 a 1'18 E+4932
/*Definimos dos funciones llamadas max(); una que regrese el mayor de dos
enteros y otra que regrese el mayor de dos string.*/
#include <stdio.h>
int max(int a,int b)
{
if(a>d)
return a;
else
return b;
}
char *max(char *a, char *a)
{
if(strcmp(a,b)>0)
return a;
else
return b;
}
int main()
{
printf(max(19,69) = %d\n, max(19,69));
printf(max(abc,def) = %s\n, max(abc,def));
return 0;
}
Comentarios en C/C++
No son tomados en cuenta por el compilador
Comentario de una lnea empiezan con // en adelante
Comentario de texto empiezan con /* y terminan con*/
(5)
Secuencias de escape:
Ciertos caracteres no representados grficamente se pueden representar
mediante lo que se conoce como secuencia de escape. A continuacin vemos una tabla
de las ms significativas:
\n
\b
\t
\v
\\
\f
\'
\"
\o
salto de lnea
retroceso
tabulacin horizontal
tabulacin vertical
contrabarra
salto de pgina
apstrofe
comillas dobles
fin de una cadena de caracteres
Estructuras condicionales en C:
Estructura IF...ELSE
Sintaxis:
if (<condicin>)
<sentencia>;
*/
Sentencia CONTINUE
Se utiliza dentro de un bucle. Cuando el programa llega a una sentencia
CONTINUE no ejecuta las lneas de cdigo que hay a continuacin y salta a la
siguiente iteracin del bucle. Existe otra sentencia, GOTO, que permite al programa
saltar hacia un punto identificado con una etiqueta, pero el buen programador debe
prescindir de su utilizacin. Es una sentencia muy mal vista en la programacin en C.
(6)
Ejemplo:
/* Uso de la sentencia CONTINUE */
#include <stdio.h>
main()
{
int numero=1;
while(numero<=100)
{
if (numero==25)
{
numero++;
continue;
}
printf("%d\n",numero);
numero++;
}
}
Estructura SWITCH
Esta estructura se suele utilizar en los mens, de manera que segn la opcin
seleccionada se ejecuten una serie de sentencias.
Su sintaxis es:
switch (<variable>)
{
case <contenido_variable1>:
<sentencias_1>;
break;
case <contenido_variable2>:
<sentencias_n-1>;
break;
default:
<sentencias_n>;
break;
(7)
switch(dia){
case 1: printf("Lunes"); break;
case 2: printf("Martes"); break;
case 3: printf("Mircoles"); break;
case 4: printf("Jueves"); break;
case 5: printf("Viernes"); break;
case 6: printf("Sbado"); break;
case 7: printf("Domingo"); break;
default: printf(Da incorrecto); break;
}
Cada case puede incluir una o ms sentencias sin necesidad de ir entre llaves, ya
que se ejecutan todas hasta que se encuentra la sentencia BREAK. La variable
evaluada slo puede ser de tipo entero o caracter. default ejecutar las sentencias
que incluya, en caso de que la opcin escogida no exista.
Como hacer Ciclos en C:
Estructura DO...WHILE
Su sintaxis es:
Do
{
<sentencia1>;
<sentencia2>;
}while (<condicin>);
(8)
Ejemplo:
/* Uso de la sentencia DO...WHILE para hacer un men*/
#include <stdio.h>
main()
{
char seleccion;
do{
printf("1.- Comenzar\n");
printf("2.- Abrir\n");
printf("3.- Grabar\n");
printf("4.- Salir\n");
printf("Escoge una opcin: ");
seleccion = getchar(); /*funcin que lee un caracter*/
switch(seleccion){
case '1':printf("Opcin 1");
break;
case '2':printf("Opcin 2");
break;
case '3':printf("Opcin 3");
}
}
}while(seleccion!='4');
Estructura FOR
Su sintaxis es:
for (<inicializacin>;<condicin>;<incremento>)
{
<sentencia1>;
<sentencia2>;
}
El flujo del bucle FOR transcurre de la siguiente forma:
(9)
Estructura WHILE
Su sintaxis es:
while(<condicion>)
{
<Sentencia1>;
<Sentencia2>;
}
Flujo de entrada/salida de C++
C++ ofrece una alternativa a las llamadas de funcin printf y scanf para
manejar la entrada/salida de los tipos y cadenas de datos estndar. As. En lugar de
printf usamos el flujo de entrada de salida cout y el operador <<(colocar en); y en
lugar de scanf usamos el flujo de entrada estandar cin y el operador >>(obtener
de) operadores de insercin y extraccin de flujo, a diferencia de printf y scanf, no
requiere cadena de formato y de especificadores de conversin( especificadores de
formato) para indicar los tipos de datos que son extrados o introducidos.
Para utilizar entradas/salidas de flujo, se debe incluir el archivo de cabecera
iostream.h.
Uso de las sentencias printf y scanf
Sentencia printf ( )
La rutina printf permite la aparicin de valores numricos, caracteres y cadenas
de texto por pantalla. El prototipo de la sentencia printf es el siguiente:
printf(<control>,<arg1>,<arg2>...);
Sentencia scanf ( )
La rutina scanf permite entrar datos en la memoria del ordenador a travs del
teclado. El prototipo de la sentencia scanf es el siguiente:
scanf(<control>,<arg1>,<arg2>...);
Suponiendo que arg1 fuera una variable mientras que arg2 fuera un
especificador de formato se puede indicar al computador con que datos va a
trabajar
Tanto la funcin printf como la funcin scanf trabajan con especificadores de
formato los cuales son:
(10)
%c
%d
%u
%o
%x
%e
%f
%s
%p
Un nico carcter
Un entero con signo, en base decimal
Un entero sin signo, en base decimal
Un entero en base octal
Un entero en base hexadecimal
Un nmero real en coma flotante, con exponente
Un nmero real en coma flotante, sin exponente
Una cadena de caracteres
Un puntero o direccin de memoria
Longitud: especifica la longitud mxima del valor que aparece por pantalla. Si la
longitud es menor que el nmero de dgitos del valor, ste aparecer ajustado a
la izquierda.
/* Declaracin de un arreglo. */
#include <stdio.h>
main()
{
int vector[10],i;
for (i=0;i<10;i++) vector[i]=i;
for (i=0;i<10;i++) printf(" %d", vector[i]);
}
(13)
declaracin o prototipo
void visualizar(int *);
desarrollo de la funcin
void visualizar(int *arreglo)
Su sintaxis es la siguiente:
<tipo> <nombre> [<tamao_1>][<tamao_2>],...,[<tamao_n>];
Una matriz bidimensional se podra representar grficamente como una tabla
con filas y columnas. La matriz tridimensional se utiliza, por ejemplo, para trabajos
grficos con objetos 3D. En el ejemplo puedes ver como se rellena y visualiza una
matriz bidimensional. Se necesitan dos bucles para cada una de las operaciones. Un
bucle controla las filas y otro las columnas.
Ejemplo:
/* Matriz bidimensional. */
#include <stdio.h>
main()
{
int x, i, numeros[3][4];
/* rellenamos la matriz */
for (x=0;x<3;x++)
for (i=0;i<4;i++)
scanf("%d",&numeros[x][i]);
/* visualizamos la matriz */
for (x=0;x<3;x++)
for (i=0;i<4;i++)
printf("%d",numeros[x][i]);
}
Si al declarar una matriz tambin queremos inicializarla, habr que tener en
cuenta el orden en el que los valores son asignados a los elementos de la matriz.
Veamos algunos ejemplos:
int numeros[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
Quedaran asignados de la siguiente manera:
numeros[0][0]=1
numeros[0][1]=2
numeros[0][2]=3
numeros[0][3]=4
numeros[1][0]=5
numeros[1][1]=6
numeros[1][2]=7
numeros[1][3]=8
numeros[2][0]=9
numeros[2][1]=10
numeros[2][2]=11
numeros[2][3]=12
(16)
(17)
Registros y funciones
Podemos enviar un registro a una funcin de las dos maneras conocidas:
(19)
Arreglos de registros
Es posible agrupar un conjunto de elementos de tipo registro en un arreglo.
Esto se conoce como arreglo de registros:
struct trabajador
{
char nombre[20];
char apellidos[40];
int edad;
};
struct trabajador fijo[20];
As podremos almacenar los datos de 20 trabajadores. Ejemplos sobre como
acceder a los campos y sus elementos: para ver el nombre del cuarto trabajador,
fijo[3].nombre;. Para ver la tercera letra del nombre del cuarto trabajador,
fijo[3].nombre[2];. Para inicializar la variable en el momento de declararla lo
haremos de esta manera:
struct trabajador fijo[20] = { {"Jos", "Herrero Martnez", 29 }, {
"Luis", "Garca Snchez", 46 } };
Definicin de tipos
El lenguaje 'C' dispone de una declaracin llamada typedef que permite la
creacin de nuevos tipos de datos. Ejemplos:
typedef int entero;
entero*/
entero a, b = 3;
(21)
Otra forma:
typedef struct
{
char nombre[20];
char apellidos[40];
int edad;
}trabajador datos;
datos fijo, temporal;
Archivos
Por ltimo veremos la forma de almacenar datos que podremos recuperar
cuando deseemos. Estudiaremos los distintos modos en que podemos abrir un archivo,
as como las funciones para leer y escribir en l.
Apertura de archivos
Antes de abrir un archivo necesitamos declarar un puntero de tipo FILE, con el
que trabajaremos durante todo el proceso. Para abrir el archivo utilizaremos la funcin
fopen().
Su sintaxis es:
FILE *<nombre_del_puntero>;
puntero = fopen (<nombre del archivo>, "<modo de apertura>" );
Donde puntero es la variable de tipo FILE, nombre del archivo es el nombre
que daremos al archivo que queremos crear o abrir. Este nombre debe ir encerrado
entre comillas. Tambin podemos especificar la ruta donde se encuentra o utilizar un
arreglo que contenga el nombre del archivo (en este caso no se pondrn las comillas).
Algunos ejemplos:
puntero = fopen("DATOS.DAT","r");
puntero = fopen("C:\\TXT\\SALUDO.TXT","w");
Un archivo puede ser abierto en dos modos diferentes, en modo texto o en
modo binario. A continuacin lo veremos con ms detalle.
Modo texto
w
w+
a
a+
r
r+
Modo binario
wb
w+b
ab
a+b
rb
r+b
FILE *pf;
char letra;
if (!(pf=fopen("datos.txt","r"))) /* controlamos si se produce un
error */
{
printf("Error al abrir el archivo");
exit(0); /* abandonamos el programa */
}
else
{
letra=fgetc(pf);
printf("%c",letra);
fclose(pf);
}
(24)
Un nmero entero:
putw(<variable_entera>,<puntero_archivo>);
Escribe un nmero entero en formato binario en el archivo.
Ejemplo:
FILE *pf;
int num=3;
if (!(pf=fopen("datos.txt","wb"))) /* controlamos si se produce un
error */
{
printf("Error al abrir el archivo");
exit(0); /* abandonamos el programa */
}
else
{
fputw(num,pf);
/*
tambin
podamos
haber
hecho:
fputw(3,pf); */
fclose(pf);
}
(25)
(26)
Con formato:
fprintf(<puntero_archivo>,<formato>,<argumentos>);
Funciona igual que un printf pero guarda la salida en un archivo.
Ejemplo:
FILE *pf;
char nombre[20]="Santiago";
int edad=34;
if (!(pf=fopen("datos.txt","w")))
/* controlamos si se produce un error */
{
printf("Error al abrir el archivo");
exit(0); /* abandonamos el programa */
}
else
{
fprintf(pf,"%20s%2d\n",nombre,edad);
fclose(pf);
}
La funcin fscanf(<puntero_archivo>,<formato>,<argumentos>), lee
los argumentos del archivo. Al igual que con un scanf, deberemos indicar la direccin
de memoria de los argumentos con el smbolo & ( ampersand ).
Un ejemplo:
FILE *pf;
char nombre[20];
int edad;
if (!(pf=fopen("datos.txt","rb")))
/* controlamos si se produce un error */
{
printf("Error al abrir el archivo");
exit(0); /* abandonamos el programa */
}
else
{
fscanf(pf,"%20s%2d\",nombre,&edad);
printf("Nombre: %s Edad: %d",nombre,edad);
fclose(pf);
}
(27)
Registros
fwrite( *buffer,<tamao>,<n de veces>,<puntero_archivo>);
Se utiliza para escribir bloques de texto o de datos, registros, en un archivo. En
esta funcin, *buffer ser la direccin de memoria de la cul se recogern los datos;
tamao, el tamao en bytes que ocupan esos datos y n de veces, ser el nmero
de elementos del tamao indicado que se escribirn.
fread( *buffer,<tamao>,<n de veces>,<puntero_archivo>);
Se utiliza para leer bloques de texto o de datos de un archivo. En esta funcin,
*buffer es la direccin de memoria en la que se almacenan los datos; tamao, el
tamao en bytes que ocupan esos datos y n de veces, ser el nmero de elementos
del tamao indicado que se leern.
Otras funciones para archivos:
el
(28)
(29)
Ejemplo:
int i = 3, j = 50;
intercambio (i, j);
Tambin un parmetro por referencia es un seudnimo (alias) de su
argumento correspondiente. Para indicar que un parmetro de funcin es pasado por
referencia, solo hay que colocar un ampersand (&) despus del tipo del parmetro en
el prototipo de funcin.
Debemos usar apuntadores para pasar argumentos que pudieran ser
modificados por la funcin llamada, y usar referencias a constantes para pasar
argumentos extensos que no sern modificados.
Las variables de referencia deben ser inicializadas en sus declaraciones, y no
pueden ser reasignadas como seudnimos a otras variables.
Cuando se regresa un apuntador o una referencia a una variable declarada en la
funcin llamada, la variable deber ser declarada static dentro de dicha funcin.
Las referencias pueden ser usadas como argumentos de funciones y regresar
valores.
Ejemplo:
int ix;
// ix es una variable en entera
int &rx=ix;
// rx es el alias de ix
ix=1;
// tambien rx ==1
rx=2;
// tambien ix==2
Las referencias se pueden usar para proveer una funcin con un alias de un
argumento real de llamada de funcin. Este permite cambiar el valor del argumento de
llamada de funcin tal como se conoce de otros lenguajes de programacin de llamada
por referencia:
/*U se pasa por valor y S por referencia*/
void mira (int U, int &S)
{
U=42;
S=42;
}
void mar()
{
int U,S;
U=S=1; //inicializacion en una linea
mirar(U,S);
//en este punto S=42 y U=1;
}
(30)
Modo Descripcin
ios::in Es el modo por defecto de los objetos ifstream. Abre un archivo para lectura,
(31)
ios::binary Abre un archivo sobre el que se har E/S en modo binario en lugar de en modo
texto. Usando read() se leen bytes del archivo y se guardan en arreglos de char, y
usando write() se escriben bytes desde arreglos de char en el archivo.
Al finalizar el tratamiento con el archivo debe romperse la conexin
entre el programa y el archivo envindole el mensaje close():
canal_entrada.close();
canal_salida.close();
Las clases ifstream, ofstream y fstream son subclases de la clase istream, ostream y
iostream, respectivamente. Por lo tanto, todas las operaciones para E/S interactiva se
pueden usar para E/S a travs de fichero. Por ejemplo, una vez que se haya declarado
el objeto canal_entrada de tipo ifstream y se ha conectado a un archivo de texto, se
puede leer un valor de l exactamente de la misma forma que hicimos para la E/S
interactiva:
canal_entrada >> variable;
Como crear clases en C/C++
class <nombre_clase>
// miembros de datos
public: //puede ser private o protected
// funciones / objetos miembros
// lista_objetos
(32)
(CDA)
class <nombre_clase>
Una funcin amigo de una clase se define por fuera del alcance de dicha clase,
pero an as tiene el derecho de acceso a los miembros private y protected de la clase.
Se puede declarar una funcin o toda una clase como un friend de otra clase.
Para declarar una funcin como friend de una clase, en la definicin de clase
preceda el prototipo de funcin con la palabra reservada friend. Para declarar una
clase B como amigo de la clase A entre los miembros de la clase A debe existir la
siguiente declaracin:
friend B;
Esto significa que la amistad es concedida y no tomada, es decir, para que la
clase B sea un amigo de la clase A, la clase A debe declarar que la clase B es su amigo.
Tambin la amistad no es ni simtrica ni transitiva, es decir, si la clase A es un amigo
de la clase B, y la clase B es un amigo de la clase C, no es correcto pensar que la clase
B es un amigo de la clase A, que la clase C es un amigo de la clase B , ni que A es un
amigo de la clase C.
Archivos de cabecera
Cada biblioteca estndar tiene su archivo de cabecera correspondiente, que
contiene los prototipos de funcin de todas las funciones de dicha biblioteca, y las
definiciones de varios tipos de datos y de constantes requeridas por dichas funciones.
Por ejemplo la biblioteca estndar encargada de manipular la hora y fecha, se puede
aadir a nuestro programa incluyendo el archivo de cabecera <time.h> El
programador tambin puede crear archivos de cabecera para cada una de las clases
que define en su programa. Para ello, el nombre de dicho archivo deber terminar en
.h y podr ser incluido utilizando la directriz de preprocesador #include. Este archivo
contendr los miembros de datos de la clase y los prototipos de las funciones
pertenecientes a dicha clase.
(33)
(35)
Funcin destructora
Un destructor es una funcin miembro especial de una clase, su nombre est basado
en la tilde (~) seguida por el nombre de la clase. Un destructor de una clase es
llamado automticamente cuando un objeto de una clase se sale de alcance. De hecho
el destructor mismo no destruye el objeto, ms bien ejecuta trabajos de terminacin,
antes de que el sistema recupere el espacio de memoria del objeto con el fin de que
pueda ser utilizado para almacenar nuevos objetos. Un destructor no recibe ningn
parmetro, ni regresa ningn valor. Una clase slo puede tener un destructor la
homonimia de destructores no est permitida. Sintaxis:
~ <nombre_clase> ();
Ejemplo:
class Punto
{
int _x,_y;
public:
Punto()
{
_x = _y = 0;
}
}
Punto(const int x,const int y)
{
_x = desde._x;
_y = desde._y;
}
Punto(){/*Nada que hacer*/}
Ejemplo
//Usamos la funcin inline para calcular el volumen de un
//cubo.
#include <iostream.h>
inline float cubo(const float s){return s*s*s;}
main()
{
cout<<Introduce la longitud del lado de un cubo:
float lado;
cin >>lado;
cout <<El volumen del lado;
cout<<volumen<<es<<cubo(lado)<<\n;
return 0;
}
Verificacin de tipos en C++
int main()
{
//...
printf(x) //C int printf(x)
//C++ es ilegal, ya que printf no esta declarada
return 0;
}
Fallo al devolver un valor de una funcin. Una funcin en C++ declarada con un tipo
determinado de retomo, 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 conversacin 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 constantes 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 [] ="Cazorla";
Ejemplo:
Class Punto
//Declaracion de la clase punto
{
int _x,_y;
//coordenadas del punto
public:
//Principio de la declaracin de la interfase.
void setX(const int val);
void setY(const int val);
int getX(){return _x;}
int getY(){return _y;}
};
//fin class
Punto apunto;
//Definicion del objeto apunto.
/*El objeto apunto puede usar estos metodos para establecer y para
obtener informacin sobre s mismo.*/
apunto.setX(1);
//inicializacion
apunto.setY(1);
/*
x es necesaria a partir de aqu, de modo que la definimos aqu y la
inicializamos con el valor de la coordenada _x de apunto.
*/
int x = apunto.getX();
void Punto::setX(const int val) //definimos el mtodo setX
//mbito de la clase Punto
{
_x = val;
}
void Punto::setY (const int val)
{
_y = val;
}
Comentario
Comenzamos con la definicin de una clase, indicndola con la palabra
reservada class. El cuerpo de la definicin de clase se delimita mediante llaves. La
definicin de clase termina con un punto y coma. En el cuerpo de la definicin existen
partes nuevas: la etiqueta public: y private: se conocen como especificadores de
acceso. Cualquier miembro de datos o funcin miembro declarado despus del
especificador de acceso de miembro) es accesible, siempre que el programa tenga
acceso a un objeto de la clase. Cualquier miembro de datos o funcin miembro
declarada despus del especificador de acceso de miembro private: (y hasta el
siguiente especificador de acceso de miembro) slo es accesible a las funciones
miembro de la clase.
Estos especificadores pueden aparecer varias veces en una definicin de clase.
Por defecto, los elementos de las clases son privados ( private: ).
(38)
(39)
(40)
Apndice
En este captulo y para finalizar veremos los archivos de cabecera, donde
estn declaradas las funciones que utilizaremos ms a menudo.
Librera stdio.h
printf
Funcin: Escribe en la salida estndar con formato.
Sintaxis: printf(<formato>,<arg1>, ...);
scanf
Funcin: Lee de la salida estndar con formato.
Sintaxis: scanf(<formato>,<arg1>, ...);
puts
Funcin: Escribe una cadena y salto de lnea.
Sintaxis: puts(<cadena>);
gets
Funcin: Lee y guarda una cadena introducida por teclado.
Sintaxis: gets(<cadena>);
fopen
Funcin: Abre un fichero en el modo indicado.
Sintaxis: pf=fopen(<fichero> , <modo de apertura>);
fclose
Funcin: Cierra un fichero cuyo puntero le indicamos.
Sintaxis: fclose(<nombre_puntero>);
fprintf
Funcin: Escribe con formato en un fichero.
Sintaxis: fprintf(<nombre_puntero> , <formato> , <arg1> , ...);
fgets
Funcin: Lee una cadena de un fichero.
Sintaxis: fgets(<cadena> , <longitud> , <nombre_puntero>);
Librera stdlib.h
atof
Funcin: Convierte una cadena de texto en un valor de tipo float.
Sintaxis: float <nomb_variable> = atof(<cadena>);
atoi
Funcin: Convierte una cadena de texto en un valor de tipo entero.
Sintaxis: int <nomb_variable>= atoi(<cadena>);
(41)
itoa
Funcin: Convierte un valor numrico entero en una cadena de texto. La base
generalmente ser 10, aunque se puede indicar otra distinta.
Sintaxis: itoa(<nmero> , <cadena> , <base>);
exit
Funcin: Termina la ejecucin y abandona el programa.
Sintaxis: exit(<variable_estado>); /* Normalmente el estado ser 0 */
Librera conio.h
clrscr
Funcin: Borra la pantalla.
Sintaxis: clrscr( ); es lo mismo que system(cls) ;
clreol
Funcin: Borra desde la posicin del cursor hasta el final de la lnea.
Sintaxis: clreol( );
gotoxy
Funcin: Cambia la posicin del cursor a las coordenadas indicadas.
Sintaxis: gotoxy(<columna> , <fila>);
textcolor
Funcin: Selecciona el color de texto (0 - 15).
Sintaxis: textcolor(<variable_color>);
textbackground
Funcin: Selecciona el color de fondo (0 - 7).
Sintaxis: textbackground(<variable_color>);
wherex
Funcin: Retorna la columna en la que se encuentra el cursor.
Sintaxis: <variable_columna>=wherex( );
wherey
Funcin: Retorna la fila en la que se encuentra el cursor.
Sintaxis: <variable_fila>=wherey( );
getch
Funcin: Lee y retorna un nico caracter introducido mediante el teclado por el
usuario. No muestra el carcter por la pantalla.
Sintaxis: char <nomb_variable> =getch();
getche
Funcin: Lee y retorna un nico carcter introducido mediante el teclado por el
usuario.
Muestra el carcter por la pantalla.
Sintaxis: char <nomb_variable> = getche();
(42)
Librera string.h
strlen
Funcin: Calcula la longitud de una cadena.
Sintaxis: int <nomb_variable>=strlen(<cadena>);
strcpy
Funcin: Copia el contenido de una cadena sobre otra.
Sintaxis: strcpy(<cadena_a_sobre_escribir>,<cadena_original>);
strcat
Funcin: Concatena dos cadenas.
Sintaxis: strcat(<cadena_1>,<cadena_2>,,<cadena_n>);
strcmp
Funcin: Compara el contenido de dos cadenas. Si cadena1 < cadena2 retorna
un nmero negativo. Si cadena1 > cadena2, un nmero positivo, y si cadena1 es
igual que cadena2 retorna 0 ( o NULL ).
Sintaxis: int <nomb_variable>=strcmp(<cadena1>,<cadena2>);
Funciones interesantes
fflush(stdin)
Funcin: Limpia el buffer de teclado.
Sintaxis: fflush(stdin);
Prototipo: stdio.h
sizeof
Funcin: Operador que retorna el tamao en bytes de una variable.
Sintaxis: int <nomb_variable_2>= sizeof (nomb_variable_1|TDD);
cprintf
Funcin: Funciona como el printf pero escribe en el color que hayamos activado con
la funcin textcolor sobre el color activado con textbackground.
Sintaxis: cprintf(<formato> , <arg1> , ...);
Prototipo: conio.h
kbhit
Funcin: Espera la pulsacin de una tecla para continuar la ejecucin.
Sintaxis: while (!kbhit( )) /* Mientras no pulsemos una tecla... */
Prototipo: conio.h
random
Funcin: Retorna un valor aleatorio entre 0 y numero_limite-1.
Sintaxis: int <nomb_variable>=random(<numero_limite>);
/* Tambin necesitamos la funcin randomize */
Prototipo: stdlib.h
(43)
randomize
Funcin: Inicializa el generador de nmeros aleatorios. Deberemos llamarlo al inicio
de la funcin en que utilicemos el random. Tambin deberemos utilizar el include
time.h, ya que randomize hace una llamada a la funcin time, incluida en este ltimo
archivo.
Sintaxis: randomize( );
Prototipo: stdio.h
system
Funcin: Ejecuta el comando indicado. Esto incluye tanto los comandos del sistema
operativo, como cualquier programa que nosotros le indiquemos. Al acabar la
ejecucin del comando, volver a la lnea de cdigo situada a continuacin de la
sentencia system.
Sintaxis: system (<comando>); /* p.ej: system("arj a programa"); */
Prototipo: stdlib.h
Conversin de tipos en C++ (CDT)
Entindase CDT en C como el cambio de contexto de un tipo de dato a otro
contexto.
Contexto es la manera en que el computador maneja el dato y opera con l.
En C para realizar por lo general alguna CDT es necesario tener:
Funcin principal
Funcion(es) auxiliares
Apuntador
Expecificador de formato
A simple vista C++ es bastante particular en la CDT y es un poco ms complejo
que Java (porque Java es ms estandarizado), aunque se adquieren mucha
flexibilidad en la programacin. A medida que se le conoce, se puede ir programando
de una manera ms elegante en su cdigo fuente.
La conversiones explcitas se fuerzan mediante moldes (casts). La conversin
forzosa de tipos de C tiene el formato clsico:
SINTAXIS:
(<TDD>)<expresin>;
<TDD>(<expresin>);
(45)
Excepciones en C
Es un mecanismo de gestin de errores incorporado. Permite gestionar y
responder a los errores en tiempo de ejecucin. Las excepciones estn construidas a
partir de tres palabras clave: try, catch y throw. Cualquier sentencia que provoque
una excepcin debe haber sido ejecutada desde un bloque try o desde una funcin que
este dentro del bloque try.
Cualquier excepcin debe ser capturada por una sentencia cath que sigue a la
sentencia try, causante de la excepcin.
SINTAXIS:
try
{
}
<cuerpo>;
catch(<tipo_1 arg>)
{
}
<bloque_1> catch;
catch(<tipo_2 arg>)
{
<bloque_2> catch;
}
catch(<tipo_n arg>)
{
}
<bloque_n> catch;
(46)
EJEMPLO:
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
void main()
{
try{
cout<<"Dentro del bloque try\n";
throw 10;
cout<<"Esto se ejecuta si no hay problemas";
}
catch(int i){
cout<<"Capturado el error "<< i;
cout<<"\n";
}
Sintaxis:
<objeto_destino>=<objeto_origen>;
(47)
EJEMPLO:
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
class miclase{
int a,b;
public:
void obtener(int i, int j){a=i;b=j;}
void mostrar(){cout << a << " "<< b << "\n";}
};
void main()
{
miclase o1,o2;
o1.obtener(10,4);
o2=o1;
o1.show();
o2.show();
getch();
}
INICIALIZACIN:
<nombre_objeto>[<ndice>].funcin(<valores>);
(48)
EJEMPLO: Unidimensional.
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
class ejemplo{
int a;
public:
void pasar(int x){a=x;}
int mostrar() {return a;}
};
void main()
{
ejemplo ob[4];
int indice;
clrscr();
for(indice=0;indice<4;indice++)
ob[indice].pasar(indice);
for(indice=0;indice<4;indice++)
{
cout << ob[indice].mostrar();
cout << "\n";
}
getch();
}
(49)
EJEMPLO: Bidimensional.
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
class bidi{
int a,b;
public:
bidi(int n, int m){a=n;b=m;}
int pasa_a(){return a;}
int pasa_b(){return b;}
};
void main()
{
clrscr();
int fil,col;
bidi objeto[3][2]={
bidi(1,2),bidi(3,4),
bidi(5,6),bidi(7,8),
bidi(9,10),bidi(11,12)};
for(fil=0;fil<3;fil++)
{
for(col=0;col<2;col++)
{
cout << objeto[fil][col].pasa_a();
cout << " ";
cout << objeto[fil][col].pasa_b();
cout << "\n";
}
}
getch();
}
PASO DE OBJETOS A FUNCIONES: Los objetos se pueden pasar a funciones
como argumentos de la misma manera que se pasan otros tipos de datos. Hay que
declarar el parmetro como un tipo de clase y despus usar un objeto de esa clase
como argumento cuando se llama a la funcin. Cuando se pasa un objeto a una
funcin se hace una copia de ese objeto.
Cuando se crea una copia de un objeto porque se usa como argumento para
una funcin, no se llama a la funcin constructora. Sin embargo, cuando la copia se
destruye (al salir de mbito), se llama a la funcin destructora.
(50)
PROTOTIPO DE FUNCIN:
<nombre_funcion>(<objeto>);
EJEMPLO:
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
class objetos{
int i;
public:
objetos(int n){i=n;}
int devol(){return i;}
};
int sqr(objetos o)
{
return o.devol()*o.devol();
}
void main()
{
objetos a(10), b(2);
cout << sqr(a);
cout << sqr(b);
getch();
}
(51)
EJEMPLO:
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>
class ejemplo{
char cadena[80];
public:
void muestra(){cout<<cadena<<"\n";}
void copia(char *cad){strcpy(cadena,cad);}
};
ejemplo entrada()
{
char cadena[80];
ejemplo str;
cout<<"Introducir cadena: ";
cin>>cadena;
str.copia(cadena);
return str;
}
void main()
{
ejemplo ob;
ob=entrada();
ob.muestra();
getch();
}
(52)
EJEMPLO:
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
class miclase{
int a;
public:
miclase(int x);
int get();
};
miclase::miclase(int x)
{
a=x;
}
int miclase::get()
{
return a;
}
void main()
{
clrscr();
miclase obj(200);
miclase *p;
p=&obj;
cout << "El valor del Objeto es " << obj.get();
cout << "El valor del Puntero es " << p->get();
getch();
}
(53)
EJEMPLO:
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
class miclase{
int a;
public:
miclase();
void show();
};
miclase::miclase()
{
a=100;
}
void miclase::show()
{
cout << a;
}
void main()
{
clrscr();
miclase obj;
obj.show();
getch();
}
El complemento de un constructor es la funcin destructora. A esta funcin se la
llama automticamente cuando se destruye el objeto. El nombre de las funciones
destructoras debe ser el mismo que el de la clase a la que pertenece precedido del
carcter ~ (alt+126). Los objetos de destruyen cuando se salen de mbito cuando son
locales y al salir del programa si son globales. Las funciones destructoras no devuelven
tipo y tampoco pueden recibir parmetros.
Tcnicamente un constructor y un destructor se utilizan para inicializar y
destruir los objetos, pero tambin se pueden utilizar para realizar cualquier otra
operacin. Sin embargo esto se considera un estilo de programacin pobre.
(54)
DESARROLLO DE LA FUNCION:
<nombre_clase>::<nombre_funcin>()
{
<cuerpo>;
}
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
class miclase{
int a;
public:
miclase();
~miclase();
void show();
};
miclase::miclase()
{
a=100;
}
miclase::~miclase()
{
cout << "Destruyendo...\n";
getch();
}
void miclase::show()
{
cout << a;
}
void main()
{
clrscr();
miclase obj;
obj.show();
getch();
}
(55)
EJEMPLO:
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
class miclase{
int a;
public:
miclase(int x);
void mostrar();
};
miclase::miclase(int x)
{
cout << "Constructor";
a=x;
}
void miclase::miclase()
{
cout <<"El valor de a es: ";
cout << a;
}
void main()
{
miclase objeto(4);
ob.show();
getch();
}
En C++ dos o ms funciones pueden compartir el mismo nombre en tanto en cuanto difiera
el tipo de sus argumentos o el nmero de sus argumentos o ambos. Cuando comparten el
mismo nombre y realizan operaciones distintas se dice que estn sobrecargadas. Para
conseguir la sobrecarga simplemente hay que declarar y definir todas las versiones
requeridas.
Tambin es posible y es muy comn sobrecargar las funciones constructoras. Hay 3 razones
por las que sobrecargar las funciones constructoras. Primero ganar flexibilidad, permitir
arrays y construir copias de constructores
(56)
EJEMPLO:
#include <iostream.h>
#include <conio.h>
#include <stdio.h>
int abs(int numero);
long abs(long numero);
double abs(double numero);
void main()
{
clrscr();
cout <<"Valor absoluto de -10 "<< abs(-10) <<"\n";
cout <<"Valor absoluto de -10L "<< abs(-10L) <<"\n";
cout <<"Valor absoluto de -10.01 "<< abs(-10.01) <<"\n";
getch();
}
int abs(int numero)
{
return numero<0 ? -numero:numero;
}
long abs(long numero)
{
return numero<0 ? -numero:numero;
}
double abs(double numero)
{
return numero<0 ? -numero:numero;
}
/*EJEMPLO otro programa*/
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
void fecha(char *fecha);
void fecha(int anno, int mes, int dia);
void main()
{
clrscr();
fecha("23/8/98");
fecha(98,8,23);
getch();
}
void fecha(char *fecha)
{
cout<<"Fecha: "<<fecha<<"\n";
}
void fecha(int anno,int mes,int dia)
{
cout<<"Fecha: "<<dia<<"/"<<mes<<"/"<<anno;
}
(57)
PROTOTIPO:
<TDD_devuelto>(<var_1>=<valor>,<var_2>=<valor>,<var_n>=<valor>);
EJEMPLO:
#include<iostream.h>
#include<stdio.h>
#include<conio.h>
void funcion(int a=0, int b=0)
{
cout<<"a: "<< a <<" b: "<< b <<"\n";
}
void main()
{
clrscr();
funcion();
funcion(10);
funcion(20,30);
getch();
}
Es muy similar a la sobrecarga de funciones, un operador siempre se
sobrecarga con relacin a una clase. Cuando se sobrecarga un operador no pierde su
contenido original, gana un contenido relacionado con la clase. Para sobrecargar un
operador se crea una funcin operadora que normalmente ser una funcin amiga a la
clase.
PROTOTIPO:
<TDD_devuelto> <nombre_clase>::<operador> <operador>(<parmetros>)
{
}
<cuerpo>;
(58)
Se pueden realizar cualquier actividad al sobrecargar los operadores pero es mejor que
las acciones de un operador sobrecargado se ajusten al uso normal de ese operador.
La sobrecarga tiene dos restricciones, no puede cambiar la precedencia del operador y
que el numero de operadores no puede modificarse. Tambin hay operadores que no
pueden sobrecargarse.
OPERADORES
.
::
??
.*
(59)
EJEMPLO:
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
class opera{
int x, y;
public:
opera() {x=0;y=0;}
opera(int i, int j) {x=i; y=j;}
void obtenxy(int &i,int &j) {i=x; j=y;}
opera operator+(opera obj);
};
opera opera::operator+(opera obj)
{
opera temp;
temp.x=x+obj.x;
temp.y=y+obj.y;
return temp;
}
void main()
{
opera obj1(10,10), obj2(5,3),obj3;
int x,y;
obj3=obj1+obj2;
obj3.obtenxy(x,y);
cout << "Suma de obj1 mas obj2\n ";
cout << "Valor de x: "<< x << " Valor de y: " << y;
getch();
}
(60)
EJEMPLO:
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
class opera{
int x,y;
public:
opera() {x=0;y=0;}
opera(int i,int j) {x=i; y=j;}
void obtenerxy(int &i, int &j) {i=x; j=y;}
int operator==(opera obj);
};
int opera::operator==(opera obj)
{
if(x==obj.x && y==obj.y)
return 1;
else
return 0;
}
void main()
{
clrscr();
opera obj1(10,10), obj2(5,3);
if(obj1==obj2)
cout << "Objeto 1 y Objeto 2 son iguales";
else
cout << " Objeto 1 y objeto 2 son diferentes";
getch();
}
(61)
EJEMPLO:
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
class opera{
int x, y;
public:
opera() {x=0;y=0;}
opera(int i, int j) {x=i;y=j;}
void obtenxy(int &i, int &j) {i=x; j=y;}
opera operator++();
};
opera opera::operator++()
{
x++;
y++;
}
void main()
{
clrscr();
opera objeto(10,7);
int x,y;
objeto++;
objeto.obtenxy(x,y);
cout<< "Valor de x: " << x <<"
getch();
}
Prioridad de operadores:
()
(Parntesis)
-(unario),/\,\/
(negacin, y , o )
div,mod,*,/
+,-
(suma, resta)
>=,<=,<,>
(Relaciones de orden)
=,
(Relacin)
o,y
(operadores lgicos)
-->
(Asignacin)
(62)
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
inline int valor(int x) { return !(X%2);}
void main()
{
int a;
cout <<"Introducir valor: ";
cin >> a;
if (valor(a))
cout << "Es par ";
else
cout << "Es impar";
}
La caracterstica principal de las funciones automticas es que su definicin es
lo suficientemente corta y puede incluirse dentro de la declaracin de la clase. La
palabra inline no es necesaria. Las restricciones que se aplican a las funciones inline se
aplican tambin para este tipo. El uso ms comn de las funciones automticas es para
funciones constructoras.
Sintaxis
<valor_devuelto><nombre_funcin> (<parmetros>){<cuerpo>;}
(63)
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
class ejemplo{
public:
int valor(int x) { return !(X%2);}
};
void main()
{
int a;
cout <<"Introducir valor: ";
cin >> a;
if (valor(a))
cout << "Es par ";
else
cout << "Es impar";
}
(64)
EJEMPLO:
#include <iostream.h>
#include <stdio.h>
#include <string.h>
#include <conio.h>
struct tipo{
tipo(double b, char *n);
void mostrar();
private:
double balance;
char nombre[40];
};
tipo::tipo(double b, char *n)
{
balance=b;
strcpy(nombre,n);
}
void tipo::mostrar()
{
cout << "Nombre: " << nombre;
cout << ": $" << balance;
if (balance<0.0) cout << "****";
cout << "\n";
}
void main()
{
clrscr();
tipo acc1(100.12,"Ricardo");
tipo acc2(-12.34,"Antonio");
acc1.mostrar();
getch();
clrscr();
acc2.mostrar();
getch();
}
Como ejemplo a lo anterior crearemos el primer programa utilizando objetos y
clases para ver la teora llevada a la prctica. Seguiremos utilizando las mismas
sentencias que usbamos en C, ms adelante los programas tomarn la estructura
exclusiva de C++.
(65)
EJEMPLO:
#include <stdio.h>
#include <conio.h>
class miclase{
int a;
public:
void pasar_a(int num);
int mostrar_a();
};
void miclase::pasar_a(int num)
{
a=num;
}
int miclase::mostrar_a()
{
return a;
}
void main()
{
miclase obj1, obj2;
clrscr();
obj1.pasar_a(10);
obj2.pasar_a(99);
printf("%d\n",obj1.mostrar_a());
printf("%d\n",obj2.mostrar_a());
getch();
}
(66)
1.-
void stock::muestra()
{
cout<<item << "\n";
cout<<"PVP: " << coste;
}
void main()
{
clrscr();
stock obj("tuerca",5.94);
obj.muestra();
getch();
}
//
2.#include <iostream.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>
class stock{
char item[20];
double coste;
public:
stock(char *i,double c)
{
strcpy(this->item,i);
this->coste=c;
}
void muestra();
};
(67)
void stock::muestra()
/*Esta es la continuacin el cdigo*/
{
cout<<this->item << "\n";
cout<<"PVP: " << this->coste;
}
void main()
{
clrscr();
stock obj("tuerca",5.94);
obj.muestra();
getch();
}
Hasta ahora si se necesitaba asignar memoria dinmica, se haca con malloc y
para liberar se utilizaba free. En C++ se puede asignar memoria utilizando new y
liberarse mediante delete. Estos operadores no se pueden combinar unas con otras,
es decir debe llamarse a delete solo con un puntero obtenido mediante new. Los
objetos tambin se les puede pasar un valor inicial con la sentencia new.
SINTAXIS:
#include<iostream.h>
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
class cosas{
int i,j;
public:
void obten(int a,int b){i=a;j=b;}
int muestra(){return i*j;}
};
(68)
Ejemplo:
void main()
{
clrscr();
int *p_var;
p_var=new int;
//p_var=new int(9); se asigna un valor inicial.
cosas *p;
p=new cosas;
if(!p || !p_var)
{
cout<<"Error de asignacion\n";
exit(1);
}
*p_var=1000;
p->obten(4,5);
cout<<"El entero en p_var es: " <<*p_var;
cout<<"\nTotal: " <<p->muestra();
getch();
(69)
Referencias
C++ consta de una particularidad relacionada con los punteros, denominada
referencia. Una referencia es un puntero implcito que se comporta como una
variable normal siendo un puntero. Existen tres modos de utilizar una referencia. Se
puede pasar a una funcin, ser devuelta de una funcin y crearse como una referencia
independiente. Lo que apunta una referencia no puede ser modificado. El caso de las
referencias independientes es muy poco comn y casi nunca se utilizan, en este
manual no se hace referencia a ellas.
En el ejemplo siguiente se compara un programa que utiliza un puntero normal
y otro programa que realiza las mismas operaciones utilizando una referencia que se
pasa a una funcin.
EJEMPLO:
(71)
Herencia Simple
Clase Madre:
Conjunto de
objetos
Clase Hija:
(72)
void main()
/*este cdigo es la continuacin de otro*/
{
derivada obj;
/*obj es una variable de tipo derivada*/
clrscr();
/*se limpia la pantalla*/
obj.obten_x(10); /*se llama al mtodo obten_x heredado en derivada*/
obj.obten_y(20); /*se llama al mtodo obten_y propio de derivada*/
obj.muestra_x();/*se llama al mtodo muestra_x heredado en derivada*/
cout<<"\n";
/*imprime una salida*/
obj.muestra_y(); /*se llama al mtodo muestra_y propio de derivada*/
getch();
/*se lee un carcter*/
}
EJEMPLO: Herencia con acceso privado.
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
class base{
int x;
public:
void obten_x(int a){x=a;}
void muestra_x(){cout<<x <<"\n";}
};
class derivada:private base{
int y;
public:
void obten_xy(int a,int b){obten_x(a);y=b;}
void muestra_xy(){muestra_x();cout<<y<<"\n";}
};
void main()
{
clrscr();
derivada ob;
ob.obten_xy(10,20);
ob.muestra_xy();
// ob.obten_x(10); error,sin acceso.
// ob.muestra_x(); error,sin acceso.
getch();
}
HERENCIA MULTIPLE: Existen dos mtodos en los que una clase derivada
puede heredar ms de una clase base. El primero, en el que una clase derivada puede
ser usada como la clase base de otra clase derivada, crendose una jerarqua de
clases. El segundo, es que una clase derivada puede heredar directamente ms de
una clase base. En esta situacin se combinan dos o ms clases base para facilitar la
creacin de la clase derivada.
(73)
(74)
int c;
public:
deriva_c(int x,int y,int z):deriva_b(x,y){c=z;}
void ver_todo()
{
cout<<ver_a()<<" "<<ver_b()<<" "<<c;
}
};
void main()
{
clrscr();
deriva_c ob(1,2,3);
ob.ver_todo();
cout<<"\n";
cout<<ob.ver_a()<<" "<<ob.ver_b();
getch();
}
El caso de los constructores es un poco especial. Se ejecutan en orden
descendente, es decir primero se realiza el constructor de la clase base y luego el de
las derivadas. En las destructoras ocurre en orden inverso, primero el de las derivadas
y luego el de la base.
EJEMPLO: Mltiple heredando varias clases base.
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
class B1{
int a;
public:
B1(int x){a=x;}
int obten_a(){return a;}
};
class B2{
int b;
public:
B2(int x){b=x;}
int obten_b(){return b;}
};
class C1:public B1,public B2{
int c;
(75)
public:
C1(int x,int y,int z):B1(z),B2(y)
{
c=x;
}
void muestra()
{
cout<<obten_a()<<" "<<obten_b()<<" ";
cout<<c<<"\n";
}
};
void main()
{
clrscr();
C1 objeto(1,2,3);
objeto.muestra();
getch();
}
Funciones Virtuales
Una funcin virtual es miembro de una clase que se declara dentro de una clase
base y se redefine en una clase derivada. Para crear una funcin virtual hay que
preceder a la declaracin de la funcin la palabra clave virtual. Debe tener el mismo
tipo y numero de parametros y devolver el mismo tipo.
Cada redefinicin de la funcin virtual en una clase derivada expresa el
funcionamiento especifico de la misma con respecto a esa clase derivada. Cuando se
redefine una funcin virtual en una clase derivada NO es necesaria la palabra virtual.
EJEMPLO:
#include<iostream.h>
#include<stdio.h>
#include<conio.h>
class base{
public:
int i;
base(int x){i=x;}
virtual void func(){cout<<i<<"\n";}
};
class derivada1:public base{
public:
derivada1(int x):base(x){};
void func(){ cout <<i*i<<"\n";}
};
(76)
PROTOTIPO: (sintaxis)
friend <TDD_devuelto> <nombre_funcin> (<parmetros>);
DESARROLLO:
<TDD_devuelto> < nombre_funcin> (<parmetros>)
{
}
<cuerpo>;
(77)
EJEMPLO:
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
class miclase{
int n,d;
public:
miclase(int i, int j){n=i;d=j;}
friend int factor(miclase ob);
};
int factor(miclase ob)
{
if (!(ob.n%ob.d))
return 1;
else
return 0;
}
void main()
{
miclase obj1(10,2), obj2(3,2);
if(factor(obj1))
cout << "es factor";
else
cout << "no es factor";
getch();
}
(78)
(79)
(80)
*<nombre_de_apuntador>(<variable>);
(81)
La Aritmtica de Apuntadores.
Generalidades:
Las operaciones ms comunes son la asignacin y las relacionales. Por lo
general slo interesa comparaciones de = y !=; raramente necesitaremos comparar
una direccin con otra con los operadores > y <. Algunos lenguajes soportan
aritmtica de punteros, en donde podemos incrementar o decrementar una direccin
de memoria. En el caso de la asignacin, es importante que ambas asignaciones
apunten a elementos del mismo tipo, pues de lo contrario se podran acceder e
interpretar datos de manera errnea. Dos apuntadores son iguales si almacenan la
misma direccin de memoria.
En C solamente se pueden realizar operaciones de incremento y decremento, y
estos es de acuerdo a la longitud de su tipo de base. Por ejemplo supngase que una
mquina particular utiliza direccionamiento de byte, un entero requiere 4 bytes y el
valor de la variable pi (declarada as: int *pi) es 100, es decir, se apunta al entero *pi
en la localidad 100. Entonces el valor de pi-1 es 96, el de pi+1 es 104 y el de pi+2 es
108. El valor de *(pi-1) es el de los contenidos de los 4 bytes 96,97,98, y 99 , el de
*(pi+1) es el del contenido de los byte 104, 105,106 y 107, y el de *(pi+2) es el
entero que esta en los bytes 108,109,110 y 111.
De manera parecida, si el valor de la variable pc (declarada as: char *pc; ) es
igual a 100, y un carcter tiene un byte de longitud, pc-1 refiere a la localidad 99,
pc+1 a la 101 y pc+2 a la 102.
Dado que los punteros son nmeros (direcciones), pueden ser manipulados por
los operadores aritmticos. Las operaciones que estn permitidas sobre 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[l0]; // 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
(82)
(83)
(84)
(85)
(86)
Arreglos y Apuntadores.
A los arrays se accede a travs de los ndices:
int lista [5];
lista [3] = 5;
Las versiones con apuntadores en los arreglos son ms rpidas que la
indexacin comn. La declaracin:
int arr[10]; /*Se declara un arrays en C con diez elementos sin inicializar*/
int *pa,*ptr;
a[0]*/
pa=&a[0];
/*y as establecemos que:*/
/*pa apunta al valor almacenado en a[0]*/
*pa=a[0];
/*y*/
/*pa+1 apunta al valor almacenado en a[1]*/
*(pa+1)=a[1];
/*y as sucesivamente*/
De esta manera se pude manejar mas eficientemente los valores y direcciones
de un arreglo Bi o Unidimensional.
El nombre de un array se puede utilizar tambin como si fuera un puntero al
primer elemento del array.
double a [10];
double *p = a; // p y a se refieren al mismo array.
(87)
M
0
O
1
Y
6
(88)
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 objeto, 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 *) vprr; //Correcto en C++
}
Punteros y cadenas
Las cadenas en C++ se implementan como arrays de caracteres, como
constantes 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 = M profesor;
Los puntos a cadena se declaran:
char s[1]; o bien: char *s;
Punteros a cadenas
Los punteros a cadenas no son cadenas. Los punteros que localizan el primer
elemento de una cadena almacenada.
char *varCadena;
const char *cadenafija;
(89)
Consideraciones prcticas
Todos los arrays en C++ se implementan mediante punteros:
char cadenal[l6] = Concepto Objeto;
char *cadena2 = cadenal;
Las declaraciones siguientes son equivalentes y se refieren al carcter
C:
cadenal[0] = a;
char car = a;
cadena1[0] = car;
Los operadores NEW Y DELETE
C++ define un mtodo para realizar asignacin dinmica de memoria, diferente
del utilizado en 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 new Nombre Tipo y un ejemplo de su aplicacin es:
int *ptrl;
double *ptr2;
ptrl = new int; // memoria asignada para el objeto ptrl
ptr2 = new double; // memoria ampliada para el objeto ptr2
*ptrl = 5;
*ptr2 = 6.55;
Dado que new devuelve un puntero, se puede utilizar ese puntero para inicializar el
puntero de 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 prt1;
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;
}
(90)
(91)
(92)
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 consecuencia, se accede a los elementos
de la unin directamente. La sintaxis de una unin annima es:
union
{
int nuevolD;
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 sobrescribe el valor de x
z = 9.41415; //el valor en z sobrescribe el valor de z
CADENAS EN C++
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 tenan
en un carcter nulo (cero):
char perro[5] = { `m`,`o`,`r`,`g`,`a`,`n`};
// no es una cadena
char gato[5] = { f,e,l,i,n,o,\0,}; // es una cadena
Lectura de una cadena del teclado
#include <iostream.h>
main ()
{
char cad [80];
cout << introduzca una cadena:; // lectura del teclado cm cad;
cin >> cad;
cout << Su cadena es:;
cout << cad;
return 0;
}
(93)
Esta lectura del teclado lee una cadena hasta que se encuentra el primer
carcter blanco. As, cuando se lee Hola que tal la primera cadena, en cad slo se
almacena Hola. Para resolver el problema, utilizar la funcin gets () que lee una
cadena completa leda del teclado. El programa anterior quedara as:
#include <iostream.h>
#include <stdio.h>
main()
{
char cad[80];
cout Introduzca una cadena:;
gets (cad);
cout Su cadena es:; cout << cad;
return 0;
}
Definicin de funciones
La definicin de una funcin es el cuerpo de la funcin que se ha declarado 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;
}
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 formales 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
void
void
void
(94)
fl(int
f2(int
f3(int
f4(int
f5(int
n, int
n, int
n = 2,
n, int
n = 2,
m, int p=0);
m= 1, int p = 0);
int m= 1, int p =0);
m = 1, int p);
int m, int p = 0);
// correcto
// correcto
// correcto
// no correcto
// no correcto
(95)
#include <iostream.h>
int incrementar (int I);
inline incrementar (int i)
{
i ++;
return i;
}
main (void)
{
int i = 0;
while (i < 5)
{
i = incrementar (i);
cout i es: i endl;
}
}
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 argumentos,
o en el tipo que devuelven las funciones, y sus cuerpos son diferentes en cada una de
ellas.
(96)
Ejemplo:
#include <iostream.h>
void suma (char);
void suma (float);
main (void)
{
int i = 65;
float j = 6.5;
char c = a;
suma ( i );
suma ( j ) ;
suma ( c ) ;
}
void suma (char i)
{
cout << Suma interior(char) <<endl;
}
void suma ( float j )
{
cout << Suma interior (float) << endl;
}
El modificador <const>
Constantes:
En C++, los identificadores de variables/constantes se pueden declarar
constantes, significando que su valor no se puede modificar.
Esta declaracin se realiza con la palabra reservada const.
const
const
const
const
(97)
Ejemplo 1:
Paso del array completo.
#include <iostream.h>
void func1 (int x[]); //prototipo de funcin
void main( )
{
int a[3] = {l,2,3};
func1 (a) ; // sentencias
func1 (&a[0]) ; // equivalentes
}
void func(int x[])
{
int i;
for (i = 0; 1 < 3; i + 1)
cout << 1 << x[i]<< \n;
}
Ejemplo 2:
Pasa de a un elemento de un array.
#include <iostream.h>
const int n + 3;
void func2(int x);
void main( )
{
int a[n] = {l,2,3};
func2 (a[2]);
}
void func2(int x)
{
cout << x << \n;
}
(99)
Ejemplos:
int m , n[12];
sizeof(m);
//
sizeof(n);
//
sizeof (15); //
sizeof (int); //
bits).
*/
retorna
retorna
retorna
retorna
4, en maquinas de 32 bits
48, 4 byte x 12 posiciones
4 un entero 15
el tamao en memoria de un int (generalmente 32
La sentencia nula:
La sentencia nula se representa por un punto y coma, y no hace ninguna
accin:
char cad[80]=Cazorla;
int i;
for (i = 0; cad[i] != \0; i++);
(100)
Ejemplo:
a * b/c+d equivale a: (a * b ) / ( c + d )
Sobrecarga de operadores
La mayora de los operadores de C++ pueden ser sobrecargados o redefinidos para trabajar con nuevos tipos de
datos.
Izquierda-Derecha
Derecha-Izquierda
Izquierda-Derecha
Izquierda-Derecha
Izquierda-Derecha
Izquierda-Derecha
Izquierda-Derecha
Izquierda-Derecha
Izquierda-Derecha
Izquierda-Derecha
Izquierda-Derecha
Izquierda-Derecha
Izquierda-Derecha
Derecha-Izquierda
Izquierda-Derecha
(101)
CPU
cout
Entrada binaria
pantalla
Salida de caracteres
Entrada
La entrada se maneja por la clase istream. Existe un objeto predefinido
istream, 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.
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;
}
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 << << y << \n;
}
Manipuladores
Un mtodo fcil de cambiar la anchura del flujo y otras variables de formato es
utilizar un operador especial denominado manipulador. Un manipulador acepta una
referencia de flujo como un argumento y devuelve una referencia al mismo flujo.
El siguiente programa muestra el uso de manipuladores especficamente para
conversiones de nmero (dec, oct, y hex):
#include <iostream.h>
int main ()
{
int i = 36;
cout << dec << i << oct << i << << hex << i << \n;
}
(103)
(104)
continue
default
delete*
do
double
else
enurn
extern
float
for
friend*
goto
if
inline*
int
long
new*
operator*
private*
protected*
public*
register
return
short
signed
sizeof
static
struct
switch
template*
this*
throw*
try
typedef
union
unsigned
virtual*
void
volatile
while
_ds
else
enum
_es
export
extern
far
far
float
for
friend
goto
huge
if
inline
int
interrup
_loadds
long
_near
near
new
operator
pascal
pascal
private
protected
public
register
return
_saveregs
_seg
short
signed
sizeof
_ss
static
struct
switch
template
this
typedef
union
unsigned
virtual
void
volatile
while
signed
sizeof
static
_stcall
struct
switch
thread
_try
typedef
union
unsigned
void
volatile
while
false
mutable
namespace
reinterpretcast
static_cast
true
(105)
typeid
using
wchart
Objetivos:
Laboratorio #1 de C
B) Condicionales e iteradores:
Los condicionales e iteradores son exactamente iguales a los de Java, tenemos:
if
if - else
switch(expresin) case value:
while
do while(condicin)
for
C) Palabras claves:
Java.
Las palabras claves, son exactamente las mismas que se pueden usar en
(107)
E) Funciones y Mtodos
En C las funciones son exactamente iguales a las de Java. Para definir un
mtodo:
void accin(int <parametro1>) { /*hace algo*/ }
Para definir una funcin:
int sumar(int uno, int dos) { return uno + dos; }
Ejercicio:
-g3
Compila el cdigo, de tal manera que el ejecutable va a tener la suficiente
informacin como para poder ser depurado. Por ejemplo:
gcc Factorial.c -o Factorial -g3
3. Uso de la librera stdio.h
salida.
fprintf()
Parmetros:
Flujo al cual va a imprimir (puede ser la salida estndar (consola) o a un
archivo).
Recibe una cadena la cual puede tener expresiones que pueden ser
sustituidas.
Puede recibir las diferentes variables para cumplir el formato dado en la
cadena inicial.
Ejemplo:
fprintf (STDOUT, Vamos a imprimir un entero: %d\n,15);
Para leer:
fscanf()
Parmetros:
Flujo del cual se va a leer (puede ser la entrada estndar (consola) o a un
archivo).
Recibe una cadena la cual puede tener expresiones que se van a leer.
Puede recibir las diferentes variables para cumplir el formato dado en la
cadena inicial.
Ejemplo:
int variable = 0;
fscanf(STDIN,%d,&variable);
%d para entero
%f para flotantes
%c para caracteres
%s para cadenas
%lf para doubles
%llf para long long
(109)
(110)
5. Definir Apuntadores
En C a diferencia de Java nosotros podemos usar directamente los apuntadores
que hacen referencias a los tipos de datos. Se pueden crear apuntador para cada tipo
de dato, incluso los definidos por el programador.
Para definir un apuntador de Persona, se puede hacer de la siguiente manera:
Persona persona1;
Persona ptr*;
ptr = &persona1;
Para acceder a las propiedades de persona por medio del apuntador puede
usarse el operador de dereferenciacin (->)
int cedula = ptr->cedula;
(111)
Laboratorio #2 de C
Archivos en C, Listas simples y C++ bsico
1. Manejo de archivos en C / C++.
C ve cada archivo simplemente como un flujo secuencial de bytes. Cada archivo
termina con una marca de fin de archivo o con un nmero de bytes especifico
almacenado dentro de una estructura de datos administrada y mantenida por el
sistema.
Al abrir un archivo se devuelve un apuntador a la estructura FILE la cual
contiene la informacin necesaria para procesar el archivo.
1.1 Creacin de un archivo de acceso secuencial.
Para referenciar un archivo se crea un apuntador a la estructura FILE la cual
posteriormente se asocia a un archivo.
FILE *puntero;
archivo*/
Modo texto
w crea un archivo de escritura. Si ya existe lo crea de nuevo.
w+ crea un archivo de lectura y escritura. Si ya existe lo crea de nuevo.
a abre o crea un archivo para aadir datos al final del mismo.
a+ abre o crea un archivo para leer y aadir datos al final del mismo.
r abre un archivo de lectura.
r+ abre un archivo de lectura y escritura.
(112)
Modo binario
wb crea un archivo de escritura. Si ya existe lo crea de nuevo.
w+b crea un archivo de lectura y escritura. Si ya existe lo crea de nuevo.
ab abre o crea un archivo para aadir datos al final del mismo.
a+b abre o crea un archivo para leer y aadir datos al final del mismo.
rb abre un archivo de lectura.
r+b abre un archivo de lectura y escritura.
La funcin fopen devuelve, como ya hemos visto, un puntero de tipo FILE. Si
al intentar abrir el archivo se produjese un error (por ejemplo si no existe y lo estamos
abriendo en modo lectura), la funcin fopen devolvera NULL. Por esta razn es mejor
controlar las posibles causas de error a la hora de programar.
Un ejemplo:
FILE *pf;
pf=fopen("datos.txt","r");
if (pf == NULL) printf("Error al abrir el archivo");
1.3 Cierre de un archivo
Una vez que hemos acabado nuestro trabajo con un archivo es recomendable
cerrarlo. Los archivos se cierran al finalizar el programa pero el nmero de estos que
pueden estar abiertos es limitado. Para cerrar los archivos utilizaremos la funcin
fclose( );.
Esta funcin cierra el archivo, cuyo puntero le indicamos como parmetro. Si el
archivo se cierra con xito devuelve 0.
fclose(puntero);
Un ejemplo ilustrativo es:
FILE *pf;
pf = fopen("AGENDA.DAT","rb");
if ( pf == NULL )
printf ("Error al abrir el archivo");
else
fclose(pf);
1.4
c = fgetc (pFile);
if (c == '\n') i++;
} while (c != EOF);
Leer una Estructura:
int fread (void *buffer, size_t size, size_t count, FILE *stream);
Lee un Bloque de datos desde un stream.
Lee un numero count de intems cada uno de un tamao size en bytes desde un stream
y los almacena en un buffer.
El puntero al stream se incrementa segn el numero de bytes ledos, el total debe ser
(size x count);
Parmetros
buffer
Apuntador a la estructura de destino con un tamao mnimo de (size *count) byte.
size
Tamao en bytes para cada intems a ser ledo.
count
Numero de intems a ser ledos, cada uno con tamao size en bytes.
stream
Apuntador a un archivo abierto.
Valor devuelto.
error.
(114)
Parmetros
carcter
Carcter a ser escrito, si es un entero se escribe como entero sin signo.
stream
Apuntador a un archivo abierto.
Escribir estructuras
size_t fwrite(const void *buffer,size_t size,size_t count,FILE *stream );
Escribir un bloque de datos en un stream.
Escribe un numero count de intems, cada uno de tamao size en bytes, desde
la memoria apuntada por buffer, en la posicin actual del stream.
Parmetros.
buffer
Apuntador a la data a ser escrito.
size
Tamao de cada uno de los intems a ser escritos.
count
Nmero de intems a ser escritos, cada uno de tamao size en bytes.
stream
Apuntador a archivo abierto con permiso de escritura.
NOTA: Tambin se pueden usar las funciones fscanf y fprintf dadas en
el laboratorio anterior.
2. Sintaxis C++
La sintaxis de C++ hereda todas las de C, pero tambin incluye soporte de
clases, tipos de datos (bool), etc.
A continuacin veremos como declarar Clases en C++
(115)
2.1 Clases
Las Clases en C++ se declaran de la siguiente forma:
class <NombreDeLaClase> [: public <ClasePadre>] {
private: // <-- modificador de acceso
tipo_dato <atributo1>;
tipo_dato <atributo2>;
public:
int <metodo1>(int <param>); // mtodo no inline
void <metodo2>() { // mtodo inline
//algun cuerpo ...
}static void <metodo3>() { // mtodo esttico
// algo...
}
};
Como pudimos ver en el ejemplo, la declaracin de los atributos de la clase va a ser como
el de cualquier estructura en C.
Para los mtodos existen 3 tipos de declaraciones: los inline, los normales y los
estticos.
Inline: son aquellos mtodos que funcionan como macros, es decir, la llamada
a el mtodo va a ser sustituida por el cdigo que se encuentra dentro de ese mtodo
(esta sustitucin va a estar dada en el cdigo ejecutable).
Static: los mtodos estticos (o de clase) son aquellos que sern invocados sin
tener que crear un objeto (instancia de la clase). Estas normalmente no alteraran el
estado de la clase. Estas pueden ser invocadas usando: Clase.metodo(); .
Normales: los mtodos normales son aquellos que son declarados en la clase,
pero son definidos fuera de ella. Estos se comportaran de la manera que se espera,
cuando se invoca a un mtodo normal, se crea un nuevo ambiente de ejecucin para
este mtodo, una vez que finalice es eliminado.
Para poder definir un mtodo normal fuera de la clase se debe usar el operador
de referenciacin ::. Por ejemplo asumiendo que se declaro la clase
NombreDeLaClase, para definir el metodo1, se hace de la siguiente manera:
(116)
(117)
(118)
Actividad nro 1.
Utilice clases para la Implementacin:
Dado el archivo info.txt el cual contiene la informacin de productos se desea
que usted plantea una estructura de datos para almacenar la informacin de dicho
producto y luego implemente la clase lista con las operaciones InsertarOrdenado() y
EliminarOrdenado() , para dicha estructura.
Una vez creada estas funciones desde la accin principal se va a ir leyendo la
informacin desde el archivo para cada producto y se va a insertar en una lista de
productos la cual debe estar ordenada por cdigo de producto.
Una vez generada la lista se debe dar las opciones de: Eliminar un producto,
Mostrar estado de la lista, Salir de la aplicacin, la aplicacin debe funcionar hasta que
se elija salir, para eliminar un producto se debe solicitar el cdigo del mismo y la lista
debe quedar ordenada.
Formato del archivo info.txt
Cada lnea contiene la informacin de un producto, primero el cdigo el cual es
un entero de 3, luego la descripcin, la cual es una cadena de caracteres de mximo
20 letras, y el precio entero, entre cada valor hay un espacio en blanco.
<cdigo> <espacio> <descripcin> <espacio> <precio>
10 cdrom 85000
15 floppy 30000
2 monitor 350000
(119)
Sentencias de salto:
Sentencias break, continue, goto
La instruccin break interrumpe la ejecucin del bucle donde se ha incluido,
haciendo al programa salir de l aunque la expresin_de_control correspondiente a
ese bucle sea verdadera
La sentencia continue hace que el programa comience el siguiente ciclo del
bucle donde se halla, aunque no haya llegado al final de las sentencia compuesta o
bloque.
La sentencia goto <etiqueta>(es el salto incondicional en ensamblador), hace
saltar al programa a la sentencia donde se haya escrito la etiqueta correspondiente.
Por ejemplo:
Sintaxis:
sentencias
if(condicin)
goto salto;
sentencia_1;
sentencia_2;
}
salto:
sentencia_3;
sentencia_4;
(120)
(122)
Estructuras de almacenamiento:
Manejos de arreglos apuntadores
Una estructura es una forma de agrupar un conjunto de datos de distinto tipo
bajo un mismo nombre o identificador. Por ejemplo, supngase que se desea disear
una estructura que guarde los datos correspondientes a un alumno de primero. Esta
estructura, a la que se llamar alumno, deber guardar el nombre, la direccin, el
nmero de matrcula, el telfono, y las notas en las 10 asignaturas. Cada uno de estos
datos se denomina miembro de la estructura.
El modelo o patrn de esta estructura puede crearse del siguiente modo:
Programa:
struct alumno
{
char nombre[31];
char direccion[21];
unsigned long no_matricula;
unsigned long telefono;
float notas[10];
};
El cdigo anterior crea el TDD alumno (plantilla registro de nombre alumno),
pero an no hay ninguna variable declarada con este nuevo tipo. De hecho este bloque
se declara fuera del main, adems la necesidad de incluir un carcter (;) despus de
cerrar las llaves. Este tipo de declaracin ahorra complejidad en memoria ya que ni
siquiera sus campos ocupan espacio en memoria, a menos que se empiecen a crear
nodos o listas. Luego para declarar dos variables de tipo alumno se debe utilizar la
sentencia:
Programa:
alumno alumno1, alumno2;
donde tanto alumno1, como alumno2 son una estructura, la cual hereda la
forma de la plantilla alumno, que podr almacenar un nombre de hasta 30 caracteres
c/u, una direccin de hasta 20 caracteres c/u, el nmero de matrcula, el nmero de
telfono y las notas de las 10 asignaturas. Tambin podran haberse definido alumno1
y alumno2 al mismo tiempo que se defina la estructura de tipo alumno. Para ello
bastara haber hecho:
Programa:
struct alumno {
char nombre[31];
char direccin[21];
unsigned long no_matricula;
unsigned long telefono;
float notas[10];
}alumno1, alumno2;
(123)
(125)
(126)
#include <iostream.h>
#include <string.h>
void main()
{
char Nombre[50];
cout <<Introduzca su nombre:;
cin >> Nombre;
char *CopiaNombre = new char[strlen(Nombre)+1];
// Se copia el nombre en la variable copianombre
strcpy(CopiaNombre, Nombre);
delete[] CopiaNombre;
}
El siguiente ejemplo reserva memoria dinmicamente para una matriz de
doubles:
#include <iostream.h>
void main()
{
int nfil, ncol, i, j;
double **mat;
//se pide al usuario el tamao de la matriz
cout << Introduzca numero de filas y columnas:
cin >> nfil >> ncol;
// se reserva memoria para el vector de punteros
mat = new double*[nfil];
//se reserva memoria para cada fila
for (i=0; i<nfil; i++)
mat[i] = new double[ncol];
//se inicializa toda la matriz
for (i=0; i<nfil; i++)
for (j=0; j<ncol; j++)
mat[i][j]=i+j;
//se imprime la matriz
for (i=0; i<nfil; i++)
{
for (j=0; j<ncol; j++)
cout << mat[i][j]<< \t;
cout << \n;
}
//se libera la memoria
for (i=0; i<nfil; i++)
{
//se borran las filas de la matriz
delete []mat[i];
//se borra el vector de punteros
delete []mat;
}
}
dia1, dia2;
(129)
if(bandera>155)
{detalle(1,2,0,666);}
while(global<global3)
{
if((global2==0)&(global4>=0))
{
if((tabulacion>(-1))&(tabulacion<6))
{
printf("%c",menu[tabulacion]);
}
else
{
if(tabulacion<22)
{
if(espacio==0)
{
sensor=tabulacion;
sensor=sensor-6;
espacio++;
}
printf("%c",caracter[sensor]); //W
}
else if(tabulacion==23)
{
if(global!=0)
{
if(global%2==0)
{
printf("%c",menu[4]); //O
}
else if((global%2!=0)|(bandera==2))
{
printf("%c",menu[5]);
}
}
else
{
printf("%c",mansu[0]); //O
}
}
else
{
if(global%2==0) //case 24
{
printf("%c",caracter[5]);
}
else if((global%2!=0)|(bandera==2))
{
printf("%c",menu[3]); //O
}
}
}
if(bandera==2)
{
global=78;
}
if(global4==1)
{
global2=1;
}
}
else
{
//W
detalle(0,1,1,0);
global2=0;
}
global++;
}
}
else
{detalle(1,0,0,666);}
}
else
{
if((tabulacion==0)&(espacio==0)&(sensor!=0))
{
espacio=sensor;
tabulacion=bandera;
bandera=-1;
}
else
{
if(espacio>70)
{
sensor=espacio-71;
//se cambio por detalle(2,sensor,1,0);
//en automatico se puede copiar y pegar a gusto
}
detalle(bandera,sensor,1,0);
//en automatico se puede copiar y pegar a gusto
//se cambio por detalle(bandera+1,sensor,1,0);
}
if((espacio<4)&(espacio>-1))
{
printf("%c%d%c",mansu[espacio],tabulacion,mansu[espacio+4]);
}
else if(espacio==4)
{
printf("%d",tabulacion);
}
else if((espacio>4)&(espacio<26))
{
global=espacio-5;
detalle(global,0,0,2);
}
else if((espacio>25)&(espacio<34))
{
global=espacio-26;
printf("%d%c",tabulacion,mansu[global]);
}
else if((espacio>33)&(espacio<50))
{
global=espacio-34;
printf("%d%c",tabulacion,caracter[global]);}
else if(espacio==50)
{printf("%c%c",caracter[0],caracter[8]);
// -.
}
else if(espacio==51)
{
printf("%c%c",caracter[2],caracter[3]);
// =>
}
else if(espacio==52)
{
printf("%c%c",caracter[3],caracter[0]);
//
>}
else if(espacio==53)
{
printf("%c%c",caracter[7],caracter[3]);
//
<>
}
else if(espacio==54)
{
printf("%c%c",caracter[0],caracter[3]);
//
->
}
else if(espacio==55)
{
printf("%c%c%c",caracter[7],caracter[0],caracter[3]);
//
<->
}
else if((espacio>55)&(espacio<59))
{
global=1;
if(espacio==56)
{
printf("%c%c",mansu[global],mansu[global+4]);
//
()
}
if(espacio>56)
{
global++;
if(espacio==57)
{
printf("%c%c",mansu[global],mansu[global+4]);
//
[]
}
if(espacio>57)
{
global++;
printf("%c%c",mansu[global],mansu[global+4]);
//
{}
}}}
else if(espacio==59)
{
printf("%c%c",caracter[1],caracter[0]);
//
*}
else if(espacio==60)
{
printf("%c%c",menu[1],caracter[0]);
//
O}
else if(espacio==61)
{
printf("%c%c%c",mansu[2],caracter[15],mansu[6]);
// [X]
}
else if(espacio==62)
{
printf("%c%c",mansu[6],caracter[0]);
// ]}
else if(espacio==63)
{
printf("%c%c",menu[6],caracter[0]);
// o}
else if(espacio==64)
{
printf("%c%c%c%c%c",caracter[6],menu[6],menu[1],menu[6],caracter[6]); //_oOo_
}
else if(espacio==65)
{
printf("%c%d%c",caracter[14],tabulacion,caracter[14]);
// o|o
}
else if(espacio==66)
{
printf("%c%c%d%c%c",caracter[6],menu[6],tabulacion,menu[6],caracter[6]); // _o*o_
}
else if(espacio==67)
{
printf("%c%c%d%c%c",caracter[0],mansu[2],tabulacion,mansu[6],caracter[0]);
}
else if(espacio==68)
{
printf("%c%c%d%c%c",caracter[0],mansu[3],tabulacion,mansu[7],caracter[0]);
}
else if(espacio==69)
{
printf("%c%c%d%c%c",caracter[0],mansu[1],tabulacion,mansu[5],caracter[0]);
}
else if(espacio==70)
{
printf("%c%c%c%d%c%c%c",caracter[6],menu[6],caracter[14],tabulacion,caracter[14],
menu[6],caracter[6]);
}
if((bandera==(-1)))
{}
else
{
if(espacio<71)
{
detalle(0,1,0,0);
//es en automatico
//se cambio por detalle(0,bandera,0,0);
}
else
{
if(sensor!=0)
{
sensor/=2;
if(sensor%2!=0)
{
sensor=sensor-1;
}
detalle(0,sensor,0,0); //no es automatico
}}}}}
if(bandera==666)
{
//tutorial y capciones del objeto
if((sensor==666)&(espacio==666)&(tabulacion==666))
{
printf("\n\n
TUTORIAL: detalle(x,c,v,z); Version Premiun\n\n");
printf("(x,0,0,0) baja un x numero de lineas en blanco(1)
\n
si x=300...aprox limpia pantalla por arriva\n");
printf("(0,c,0,0) escribe un caracter vacio un c numero de\n
veces(2)\n");
printf("(x,c,1,0) hace (1) y (2) al mismo tiempo\n");
printf("(x,0,0,1) separa segun el valor de x que se ponga x=[0...]\n");
printf("(x,0,0,2) imprime un solo caracter x=[0...]\n");
printf("(x,c,v,z) x numero de opcion 1,c caracter [1], v espaciado(1) 1x1 _[1],\n
z espaciado(2) [1]_\n");
printf("
x=[1,..], c=[1,..], v=[0,..], z=[1,..]\n");
printf("(0,0,v,z) (4)imprime caracteres v especiales,\n
y la opcion z si tienen
numeracion\n");
printf("(0,0,v,0) imprime tambien caracteres v especiales como (4),\n
sin
numeracion z=0\n");
printf("(x,0,0,81>z>2) separa recortando la linea escojida\n
segun el valor de
z\n");
printf("(x,0,0,z=80) coloca una linea semirecortada\n");
printf("(x,0,0,155>z>80) recorta la linea semirecortada segun x\n");
printf("(x,0,0,155) centra la linea de separacion x\n");
printf("(0,0,0,0) accion estable no pasa nada...\n");
printf("\n\n
SOLO: USO de accion en CORRERMENU(c,y1,y2,...,i) =>
detalle(x,c,v,z)\n");
printf("
paramero recomendado para z es 2 por defecto\n");
printf("\n\n
c=70 MAX signos (variable caracter) hace (1) y (2)\n\n
automatic...OK!\n");
printf("\n\n
CODIGO HECHO POR <-/DZ/-> trabaja por mi!\n");
}
else
{
if(tabulacion==1)
{
printf("\n\n
Mal uso de detalle(x,x,x,x)");
if(espacio==0)
{
printf("\n\n
Parametro fuera de alcanze de arreglos\n\n
25-30 caracteres
MAX...\n");
}
if(espacio==1)
{
printf("\n\n
La funcion no asepta parametros negativos\n");
}
if(espacio==2)
{
printf("\n\n
ha pasado al menos un parametro mal bandera debe ser < 155\n");
}}}}}
(135)
<stdlib.h>
/*libreras estndar de C*/
<stdio.h>
/*libreras estndar de C*/
<iostream.h> /*uso del cin y cout por a veces puede arrojar warning*/
<time.h>
<conio.h>
<string.h>
detalle.hpp
//se agrega un archivo de cabecera que es precisamente
//el objeto que se creo anterior mente
int escribir(int,int);
// prototipo de funcin simplificado equivale a
// int escribir(int menu,int liga)
int main()
{
int client,taqui,titu;
char indi;
indi='?';
client=taqui=titu=0;
/* B L O Q U E D E L P R O G R A M A */
escribir(0,0);
//escritura
detalle(1,0,1,0);
//tabulacion
detalle(2,0,0,1);
//separa
detalle(1,4,1,0);
//tabulacion
escribir(0,1);
//escritura
detalle(1,0,0,0);
//tabulacion
detalle(2,0,0,1);
//separa
detalle(1,0,1,0);
//tabulacion
escribir(0,2);
//escritura
escribir(0,3);
//escritura
scanf("%s",&indi);
//lectura de la variable menu
detalle(0,0,0,1);
//separa
switch(indi)
{
//hay solo 3 casos
case '1':
detalle(300,0,0,0);
//limpia la pantaya
detalle(1,4,1,0);
//tabula
escribir(1,0);
//escritura
detalle(1,4,1,0);
//tabula
escribir(1,2);
//escritura
detalle(1,4,1,0);
//tabula
escribir(1,3);
//escritura
detalle(2,0,0,0);
//limpia la pantaya
goto reynapepiada;
//se hace un salto de linea
break;
case '2':
detalle(300,0,0,0);
//limpia la pantaya
escribir(2,0);
//escritura
detalle(2,0,0,0);
//asi se separa
goto reynapepiada;
//se hace un salto de linea
break;
default:
//caso 3 o o una letra!!!
if(indi=='3')
{
/*F I N
B L O Q U E
panconqueso:
detalle(1,4,1,0);
escribir(3,0);
D E L
P R O G R A M A */
//etiqueta 1
//tabula
//escritura
}
else
{
detalle(300,0,0,0);
//limpia la pantaya
detalle(0,4,1,0);
//tabula
if((indi=='4')|(indi=='5')|(indi=='6')|(indi=='7')|(indi=='8')|(indi=='9')|
(indi=='0'))
{
escribir(3,1);
//escritura
}
else
{
escribir(3,2);
//escritura
}
reynapepiada:
//etiqueta 2
detalle(0,0,0,1);
//separa
escribir(2,1);
//escritura
escribir(0,3);
//escritura
scanf("%s",&indi);
//lectura de la variable men
detalle(0,0,0,1);
//separa
if(indi=='1')
{
detalle(300,0,0,0); //limpia la pantaya
main();
//se hace la bendita llamada al main
}
else
{
goto panconqueso;
//se hace un salto de lnea
}}
break;
}
return 0;
}
(138)
Recursividad en C++
Le lenguaje C soporta recursividad, un programa u objeto que se comporta de
manera recursiva, es aquel que se invoca a si mismo un numero finito de veces, para
encontrar una solucion, basara ver el cdigo del objeto detalle del cual se hablo
anteriormente, el cual usa mucha recursividad.
La funcin factorial puede representarse de manera recursiva de manera:
int factorial(int aux)
{
if(aux==0)
{
return(1);
}
else
{
return(aux*factorial(aux-1));
}
}
No obstante la recursividad suele crear problemas cuando se le pasan parmetros
muy altos, adems de ello cada vez que un programa se invoca a si mismo este apila
una cantidad de datos que usara en el siguiente nivel recursivo lo que indica una gasto
en memoria, en ciertos problemas los programas que resuelven recursivamente un
problema especifico encuentran su solucin en un nivel recursivo, sin embargo estos
continan llamndose recursivamente por lo que el valor se pierde en el siguiente
nivel recursivo en tales casos es conveniente el uso de hoyos, es decir que cuando se
encuentre la solucin se haga una llamada al objeto pero que esta caiga en un lugar
vaco, ejemplo con factorial:
Supongamos se la llamada se efecta en el main() de la forma:
factorial(5,0);
{
(139)
do{}while(1);
Progresivos
El contador
aumenta
Ciclos(bucles)
Regresivos
El contador
disminuye
opcion=0;n=4;
while (opcion<n)
//el contador aumenta dependiendo del valor de n
{
printf(" YO ENTRO SIEMPRE ");
opcion++;
if(opcion==2)continue; //se es verdadero la siguentes lineas no se ejecuta
//sino que se inicia el siguiente ciclo
printf("->CON PERMISO");
}
Corrida en fro:
opcin
0
1
2
3
4=n
YO
YO
YO
YO
Cadena1
ENTRO SIEMPRE
ENTRO SIEMPRE
ENTRO SIEMPRE
ENTRO SIEMPRE
Cadena2
"CON PERMISO"
(se salta la lnea)
"CON PERMISO"
"CON PERMISO"
Tanto el while() como el do-while() son como funciones que reciben datos
booleanos 0 es falso y distinto de cero es verdad.
(140)
YO
YO
YO
YO
Cadena1
ENTRO SIEMPRE
ENTRO SIEMPRE
ENTRO SIEMPRE
ENTRO SIEMPRE
Cadena2
"CON PERMISO"
"SIN PERMISO"
"CON PERMISO"
"CON PERMISO"
opcion=0; n=4;
while(opcion<n)
{
printf(" YO ENTRO SIEMPRE ");
opcion++;
if(opcion==2)
{
printf("->SIN PERMISO");
/*si entra aqu ya salio del condicional incluido del sino por lo que pasa a la lnea
despus del continue*/
}
else
continue;
//es equivalente a else{continue};
printf("->CON PERMISO");
}
(141)
Corrida en fro:
opcin
0
1
2
3
4=n
YO
YO
YO
YO
Cadena1
ENTRO SIEMPRE
ENTRO SIEMPRE
ENTRO SIEMPRE
ENTRO SIEMPRE
comparacin
Cadena2
1==2(false)
"SIN PERMISO"
3==2(false)
4==2(false)
printf("YO ESRIBO");
opcion++;
//
ERROR!!!
Este conduce a un ciclo infinito ya que la sentencia continue esta antes del incremento
por lo que cuando opcion=2 es errneo.
Corrida en fro:
opcin
0
1
2
2
2
(2==4)?
YO
YO
YO
YO
YO
Cadena1
ENTRO SIEMPRE
ENTRO SIEMPRE
ENTRO SIEMPRE
ENTRO SIEMPRE
ENTRO SIEMPRE
comparacin
0==2(false)
1==2(false)
2==2(true)
2==2(true)
2==2(true)
Cadena2
YO ESCRIBO
YO ESCRIBO
(se salta la lnea)
(se salta la lnea)
(se salta la lnea)
Este error ocurre porque se esta saltando el incremento por lo que en ciclos la
sentencia continue debe colocarse despus del incremento.
Veamos ahora un ciclo incondicional, con contador, usando la sentencia break.
(142)
n=0;
while(1)
{
opcion++;
/*
.
conjunto de intrucciones que se ejecutaran n veces
.
.
*/
}
if(opcion==n)break;
if(opcion==2)
{
printf("->SIN PERMISO");
break;
}else{
printf("->CON PERMISO");
}
opcin
0
1
2
Cadena1
YO ENTRO SIEMPRE
YO ENTRO SIEMPRE
comparacin
Cadena2
1==2(false)
2==2(true)
"CON PERMISO"*
"SIN PERMISO"
En otros casos:
for(opcion=0;opcion<4;opcion++)
printf("prueba");
cuerpo del for implicito se escribe 4 veces
printf(prueba 2);
fuera del cuerpo del for se escribe una vez
Una instruccin inmediata es el cuerpo implcito restringido a una lnea que se
ubica justo despus de una sentencia con alguna palabra reservada. En donde se ubica
una sola instruccin.
Con bucles como while y do while no es aconsejable el uso de instrucciones
inmediatas.
(144)
Tambin llamado paso por copia, significa que cuando C++ compila
la funcin y el cdigo que llama a la funcin, la funcin recibe una copia de los valores
de los parmetros. Si se cambia el valor de un parmetro, variable local, el cambio
solo afecta a la funcin, la funcin solo recibe una copia de los valores de los
parmetros.
Paso de punteros por referencia
Cuando una funcin debe modificar el valor de parmetro pasado y
devolver este parmetro pasado a la funcin llamadora se ha utilizado el mtodo de
paso parmetro por referencia o direccin.
Ejemplo:
main()
{
int i=6;
func_i(i);
return;
}
func_i(int i)
{
i++;
return; //es igual a return 0;
}
El mtodo por defecto de pasar parmetros por valor es por valor, a menos que se
pasen arrays, ya que los arrays se pasan siempre por direccin.
(145)
struct persona
{
int ID;
persona *prox;
};
main()
{
int A ,*B,*C,*D; //se declara una variable y tres apuntadores a entero
A=7;
//A puede no inicializarse
char *name[10];
//arreglo de apuntadores
char aname[3][4]; //es un arreglo de 2D de 200 elementos.
<TDD> E[n]={g0,g1,g2,g3,.,g(n-1)}; //un arreglo cualquiera n>-1
persona *tipo;
tipo=new persona;
tipo->prox=NULL;
tipo->ID=0;
B=&A;
*B=10;
(146)
(147)
Lnea de comandos:
El siguiente cdigo le indicara la direccin en donde se encuentra su programa:
main(int argc,char **argv)
{
int i;
printf("argc= %d\n",argc);
/*programa que imprime los argumentos de la lnea de comandos*/
for(i=0;i<argum;++i)
{
printf("argc[%d]: %s\n",i,argv[i]);
}
scanf("%d",&i);
}
Entrada / Salida
*Archivos
La primera operacin sobre un archivo antes de usarlo es abrirlo:
FILE *fopen(char *name,char *mode)
Los modos de apertura incluyen:
r lectura
wescritura
ainsertar al final append.
*Para abrir un archivo se debe declarar un (file pointer) que apunta a un escritura del
tipo FILE.
FILE *stream, *fopen();
if((stream=fopen(myfile.dat,r))==NULL)
{
printf(No se pudo abrir el archivo %s\n,myfile.dat);
exit(1); //finaliza la ejecucin del programa en algunos compiladores,
}
(148)
Variables vs Apuntadores
*C es un apuntador de enteros, contiene solo un espacio en memoria no apunta a
nada, NULL por defecto
A es una variable, contiene una direccin en memoria y un valor asignado. Si se le
coloca el & entonces A se convierte en una apuntador que devuelve la direccin de la
variable.
Nota: *C y A ambos son variables. Mientras que C y &A, ambos indican una posicin
de memoria especifica de memoria.
A=*(&A);
El uso del operador & es generalmente para variables mientras que el * es para
apuntadores.
Objeto vs Clase
Si se programa usando una clase implica a la vez que se programa tambin mediante
el uso de objetos, cuando se programa orientado a objetos lo contrario no es cierto
Un objeto se dice que es operativo, una clase no
Una clase constituye un mbito implcito donde se relacionan o no variables y
objetos, mientras que en la programacin orientada a objeto este mbito pareciera no
existir ya que los objetos se relacionan de manera explicita, los pase de variables
llamadas a objetos, variables globales locales, todo lo establece explcitamente el
programador
Si un objeto siempre va a ser una instancia lo que lo hace independiente de la clase,
pero si pertenece a una clase se dice que es un mtodo de una clase, una clase
necesita poseer mtodos
Los objetos son las instancias bsicas a usar en caso de resolver problemas bsicos
como la funcin factorial
Las clases son usadas mas para problemas mas complejos donde el numero de
objetos es numeroso al igual que las variables y se necesita de alguna manera un
mbito que ordene estos mtodos, los relacione, establezca una jerarqua, separe, etc.
por el programador, por ejemplo un problema que abarque el uso de mas de 20
objetos
Cuando se programa orientado a objetos todos los objetos a excepcin de main tienen
la misma jerarqua
Hasta ahora no se conoce si un problema puede resolverse mediante clases o objetos
La programacin orientada a objetos corresponde perfectamente con el mtodo
divide y vencers, desde un enfoque mas bsico que si se usa una clase que los
engloba y los relaciona de manera implcita
(149)
Ejemplo:
class punto
{
public:
int leerx();
//prototipo de una funcin
void fijarx(int); //
accin
private:
int x;
//variables
int y;
};
Otra forma es:
class edad
{
private:
int edadhijo,edadmadre,edadpadre; //datos
public;
edad();
void iniciar (int,int,int); //functiones miembro de la clase
int leerhijo();
int leermadre();
int leerpadre();
}
Prototipo de clases:
Una declaracin de una clase consta de una palabra reservada class y el nombre
de la clase. Una declaracin de la clase se utiliza cuando el compilador necesita
conocer una determinada clase definida totalmente en alguna parte del programa. Por
ejemplo:
class punto; //definida en algn lugar
Objetos de clases:
Una vez que la clase ha sido definida, un programa puede contener una instancia de
una clase, denominado un objeto de una clase.
Formato: nombre_clase identificador;
As la definicin del objeto punto es:
Punto p;
(151)
x es <<p.leer();
El operador punto se utiliza con los nombres de las funciones miembro para especificar
que son miembros de un objeto.
Ejemplo:
class DiaSemana;
DiaSemana Hoy;
Hoy.visualizar();
Se puede asignar un objeto de una clase a otro; por defecto, C++realiza una copia bit
a bit de todos los miembros dato. En otras palabras, todos los miembros fsicamente
contenidos en el rea de datos del objeto fuente se copian en el objeto receptor. Por
ejemplo, el siguiente cdigo crea un punto llamado P2 y lo inicializa con el contenido
de P.
Punto P;
//. . .
Punto P2;
P2=P;
Un principio fundamental en programacin orientada a objetos es la ocultacin de
informacin que significa que a determinados datos del interior de una clase no se
puede acceder por funciones externas de la clase. El mecanismo principal para ocultar
datos es ponerlos en una clase y hacerlos privados. A los datos o funciones privados
solo se puede acceder desde dentro de la clase. Por el contrario las funciones pblicas
son asequibles desde el exterior de la clase.
CLASE
No asequibles
desde el exterior
de la clase
(acceso denegado)
Privado
Datos o funciones
Publico
Asequible desde
el exterior de la
clase
Datos o funciones
M. de la clase
X
X
X
Clase amiga
X
X
X
M. una Subclase
F. no miembro
X
X
Funciones miembro:
Las funciones miembro son funciones que se incluyen dentro de una clase, estos son
llamados tambin mtodos de la clase.
class producto
{
private:
int numerodeproducto;
char nombredelproducto[30];
descrip_producto[80];
float precio_producto, num_unidades;
public:
producto(int, char[],char[],float,float);
void verproducto();
float obtenerpresio();
void actualizarproducto(int)
};
La clase Punto define las coordenadas de un punto en un plano. Por cada dato se
proporciona una funcin miembro que devuelve su valor y una que fija su valor.
class Punto
{
Public:
int leerX(){return x;}
int leery(){return y;}
void FijarX (int valx){x=valx;}
void FijarY (int valy){y=valy;}
private:
int x;
int y;
};
Las funciones miembro de una clase se definen de igual modo que cualquier otra
funcin, excepto que se necesita incluir el operador de resolucion de mbito (o
conocido como operador de alcance unario). :: en la definicin de la funcin (en su
cabecera).
Formato:
<TDD> <nomb_clase>::<nomb_funcion>(<lista de parametro>) {}
Las declaraciones de las funciones en este ejemplo son tambin definiciones ya que se
ha incluido el cuerpo de cada funcin. Si un cuerpo de la funcin consta de una nica
sentencia, muchos programadores sitan el cuerpo de la funcin en la misma lnea en
el nombre de la funcin. Por otra parte, si una funcin contiene mltiples sentencias,
cada una debe ir en una lnea independiente. Por ejemplo:
(154)
class Punto
{
public:
void fijarX(int valx)
{
if((valx>=-100)&&(valx<=100))
x=valx;
else
cerr<<Error: Fijarx() argumento fuera de rango;
}
// . . .
};
Tipos de funciones miembro
Las funciones miembro que pueden aparecer en la definicin de una clase se clasifican
en funcin de tipo de operacin que representan.
*Constructores y destructores, son funciones miembro a las que se llama
automticamente cuando un objeto se crea o se destruye.
*Selectores que devuelven los valores de los miembros dato.
*Modificadores o mutadores que permiten a un programa cliente cambiar los
contenidos de los miembros dato.
*Operadores que permiten definir operadores estndar C++ para los objetos de las
clases.
*Iteradotes que procesan colecciones de objetos, tales como arrays y listas.
Funciones en lnea y fuera de lnea
Hasta ese momento, todas las funciones se han definido dentro del cuerpo de la
definicin de clase. Se denominan definiciones de funcin en lnea (inline). Para el
caso de funciones ms grandes, es preferible codificar solo el prototipo de la funcin
dentro del bloque de la clase y codificar la implementacin de la funcin en el exterior.
Esta forma permite al creador de la clase ocultar la informacin de la funcin al usuario
de la clase proporcionando solo el cdigo fuente del archivo de cabecera, junto con un
archivo de implementacin de la clase precompilada.
class punto
{
public:
void fijarx(int valx);
Private:
int x;
int y;
};
Usuario
(interfaz)
CLASE
(155)
Ejemplo
Definir una clase DiaAnyo que contiene los atributos mes y dia y una funcin miembro
visualizar. El mes se registra como un valor entero en mes (1,Enero,2,Febrero,etc). El
da del mes se registra en la variable entera da. Escribir un programa que haga uso de
la clase y ver su salida.
//uso de la clase DiaAnyo
#include <iostream.h>
class diaAnyo
{
public:
void visualizar();
int mes;
int dia;
};
//programa que usa diaAnyo
int main()
{
diaAnyo, hoy cumpleanyos; //se declaran dos objetos distintos de la clase diaAnyo
cout<<introduzca fecha del dia de hoy: \n;
cout<<introduzca el numero del mes:;
cin>>hoy.mes;
//lecturas
cout<<Introduzca el dia del mes: ;
cin>>hoy.dia;
cout<<Introduzca su fecha de nacimiento: \n;
cout<<introduzca el numero del mes:;
cin<<cumpleanyos.dia;
cout<<Introduzca el dia del mes: ;
cin<<cumpleanyos.mes;
cout<<la fecha de hoy es;
hoy.visualizar(); //llamada a la funcin visualizar
cout<<la fecha de su nacimiento es: ;
cumpleanyos.visualizar();
if((hoy.mes==cumpleaos.mes)&&(hoy.dia==cumpleanyos.dia))
cout<<Feliz cumpleaos! \n;
else
cout<<Feliz dia! \n;
return 1;
}
La implementacin de una funcin miembro externamente a la definicin de la clase,
se hace una definicin de la funcin fuera de lnea. Su nombre debe ser precedido por
el nombre de la clase y el signo de puntuacin :: denominado operador de resolucin
de mbito. El operador :: permite al compilador conocer que fijarx pertenece a la clase
punto y, es por consiguiente, diferente de una funcin global que pueda tener el
mismo nombre o de una funcin que tenga ese nombre que puede existir en otra
clase. La siguiente funcin global, por ejemplo, puede coexistir dentro del mismo
mbito que Punto::FijarX
(156)
(157)
class punto
{
public:
void fijarx(int);
// igual a void fijarx(int nombre_de_variable);
void fijarx(int *); // igual a void fijarx(int *nombre_de_apuntador);
};
Sin embargo esta definicin no siempre es deseable, ya que como la definicin de clase
es tambin la interfaz de la clase, una funcin miembro sin ms informacin que los
TDD de parmetros no proporcionara informacin suficiente sobre como llamar a la
funcin.
class Demo
{
public:
Funciondemo (int,float,char *,int);
};
Si los nombres de los parmetros aparecen tanto en la declaracin como en la
implementacin de la funcin, no es necesario que los nombres sean idnticos pero su
orden tipo si han de serlo:
class punto
{
public:
void girar(int valx,int valy);
// . . .
};
void girar(int x,int y)
{
// . . .
}
Consejo: Es conveniente incluir un comentario de una o dos lneas en la declaracin
de una funcin que indiquen los que hace la funcin y cuales son los valores de
entrada/salida correspondientes.
Implementacin de clases
El cdigo fuente para la implementacin de funciones miembro de una clase es cdigo
ejecutable. Se almacena, por consiguiente, en archivos de texto con extensiones .cp,
.cpp, Normalmente se sita la implementacin de cada clase en un archivo
correspondiente.
Cada implementacin de una funcin tiene la misma estructura general. Obsrvese que
una funcin comienza con una lnea de cabecera que contiene entre otras cosas, el
nombre de la funcin y su cuerpo esta acotado entre una pareja de signos llave.
Las clases pueden proceder de diferentes fuentes:
(158)
*Se pueden declarar e implementar sus clases propias. El cdigo fuente siempre estar
disponible.
*Se pueden utilizar clases de hayan sido escritas por otras personas o incluso que se
han comprado. En este caso, se puede disponer del cdigo fuente o estar limitado a
utilizar el cdigo objeto de la implementacin.
*Se puede utilizar clases de las bibliotecas del mismo programa que acompaan al
software de desarrollo C++. La implementacin de estas clases se proporciona siempre
como cdigo objeto.
En cualquier forma, se debe disponer de las versiones de texto de las declaraciones de
clase para que pueda utilizarlas su compilador.
Archivos de cabecera y de clases:
Las declaraciones de clases se almacenan normalmente en sus propios archivos de
cdigo fuente, independientes de la implementacin de sus funciones miembro. Estos
son los archivos de cabecera que se almacenan con una extensin .h o bien .hpp en el
nombre del archivo.
El uso de archivos de cabecera tiene un beneficio muy importante Se puede tener
disponible la misma declaracin de clases a muchos programas sin nesecidad de
duplicar la declaracin esta propiedad facilita la declaracin de programas en C++, el
cual es un C pero con clases.
Para tener acceso a los contenidos de un archivo de cabecera, un archivo que contiene
la implementacin de las funciones de la clase declarada en el archivo de cabecera o
un archivo que crea objetos de la clase declarada en el archivo de cabecera incluye
(include), o mezcla, el archivo de cabecera utilizando una directiva de compilador, que
se una instruccin al compilador que se procesa durante la compilacin. Las directivas
del compilador comienzan con el signo almohadilla (#).
La directiva que mezcla el contenido de un archivo de cabecera en un archivo que
contiene el cdigo fuente de una funcin es:
#include nombre_archivo
Opciones de compilacin:
Si el archivo de cabecera esta en un directorio diferente entonces se coloca la
ubicacin completa en el include:
Ejemplo:
#include <iostream>
utiliza la biblioteca de clases que soporta entrada/salida
#include \mi_cabezera\cliente.h
(159)
Constructores
Un constructor es una funcin miembro de propsito especfico que se ejecuta
automticamente cuando se crea un objeto de una clase. Un constructor sirve para
inicializar los miembros dato de una clase.
Un constructor tiene el mismo nombre que la propia clase. Cuando se define un
constructor no se puede especificar un valor de retorno, ni incluso vid (un constructor
nunca devuelve un valor). Un constructor puede, sin embargo, tomar cualquier numero
de parmetros (cero o ms).
Reglas:
1- El constructor tiene el mismo nombre de la clase.
2- Puede tener cero, o ms parmetros
3- No devuelve ningn valor.
La clase Rectngulo tiene un constructor con cuatro parmetros:
class Rectangulo
{
private:
int LDerecho;
int LSuperior;
int LInferior;
int LIzquierdo;
public:
Rectangulo(int A,int B,int C,int D); //constructor
//definiciones de otras funciones miembro
};
Cuando se define un objeto, se pasan los valores de los parmetros al constructor
utilizando una sintaxis similar a una llamada normal de la funcin.
Rectangulo rect(25,25,75,75);
Esta definicin crea una instancia del objeto Rectngulo e invoca al constructor de la
clase pasndole los parmetros con valores especificados.
Caso particular
Se puede tambin pasar los valores de los parmetros cuando se crea una instancia de
una clase utilizando el operador new.
Rectangulo *crect = new Rectangulo(25,25,75,75);
El operador new invoca automticamente al constructor del objeto que se crea (sta es
una ventaja importante de utilizar new en lugar de otros mtodos de asignacin de
memoria tales como la funcin malloc).
(160)
Constructor de copia:
Existe un tipo especializado de constructor denominado constructor de copia, que se
crea automticamente por el compilador. El constructor de copia se llama
automticamente cuando un objeto se pasa por valor: se construye una copia local del
objeto que se construye. El constructor de copia se llama tambin cuando un objeto se
declara he inicializa con otro objeto del mismo tipo.
Ejemplo:
Punto P;
Punto T(P);
Punto Q=P;
Por defecto, C++ construye una copia bit a bit de un objeto. Sin embargo, se puede
tambin implementar el constructor de la copia y se utiliza para notificar al usuario
que una copia se ha realizado, normalmente como una ayuda de depuracin.
Regla: si existe un constructor alternativo, C++ no generar un constructor por
defecto. Para prevenir a los usuarios de la clase de crear un objeto sin parmetros, se
puede 1) Omitir el constructor por defecto o bien; 2) Hacer el constructor privado en la
clase.
Ejemplo:
class Punto
{
public:
Punto(int valx,int valy);
private:
Punto();
//
};
...
Punto T; //error el constructor no esta asequible
Inicializacion de miembros en constructores:
No esta permitido inicializar un miembro dato de una clase cuando se define. Por
consiguiente, la siguiente definicin de la clase genera errores:
(162)
class C
{
private:
int T=0;
//Error
const int Cint = 25; //Error
int &Dint = T;
//Error
//
};
No tiene sentido inicializar un miembro dato dentro de una definicin de la clase, dado
que la definicin de la clase indica simplemente el tipo de cada miembro dato y no
reserva realmente memoria. En su lugar, se desea inicializar los miembros dato cada
vez que se crea una instancia especfica de la clase. El sitio lgico para inicializar
miembros datos, por consiguiente, esta dentro del constructor de la clase. El
constructor de la clase inicializa los miembros dato, por consiguiente, est dentro del
constructor de la clase. El constructor de la clase inicializa los miembros dato
utilizando expresiones de asignacin. Sin embargo, ciertos tipos de datos
especficamente constantes y referencias- no pueden ser valores asignados. Para
resolver este problema, C++ proporciona una caracterstica de constructor especial
Conocido como lista inicializadora de miembros que permite inicializar (en lugar de
asignar) a uno o ms miembros dato.
Una lista inicializadota de miembros se sita inmediatamente despus de la lista de
parmetros en la definicin del constructor; consta de un carcter dos puntos, seguido
por uno o ms inicializadores de miembro, separados por comas. Un inicializador de
miembros consta del nombre de un miembro dato seguido por un valor inicial entre
parntesis.
Ejemplo:
class C
{
private:
int T;
const int Cint;
int &Dint;
//
public:
C(int Param): T (Param), Cint(25), Dint(T)
{
//cdigo del constructor
}
//
};
La definicin siguiente crea un objeto:
C CObjeto(0);
(163)
con los miembros dato T y CInt se inicializan a 0 y 25, y el miembro dato CInt se
inicializa de modo que se refiere a T.
Disear y construir una clase contador que cuente cosas. (Cada vez que se produzca
un suceso al contador se incrementa en 1.) El contador puede ser consultado para
encontrar la cuenta actual.
// contador .cpp
// objeto representa una variable contador
#include <iostream>
class contador
{
private:
unsigned int cuenta;
//contar
public:
contador(){cuenta=0;}
//constructor
void inc_cuenta(){cuenta++;}
//cuenta
void leer_cuenta(){return cuenta;} //devuelve cuenta
};
void main()
{
contador c1,c2;
cout<<\nc1 = <<c1.leer_cuenta();
cout<<\nc2 = <<c2.leer_cuenta();
c1.inc_cuenta();
c2.inc_cuenta();
c2.inc_cuenta();
cout<<\nc1 = <<c1.leer_cuenta();
cout<<\nc2 = <<c2.leer_cuenta();
//visualiza de nuevo
La clase Contador tiene un elemento dato: cuenta, del tipo unsigned int (la cuenta
siempre es positivo ya que unsigned acta como un valor absoluto). Tiene tres
funciones miembro contador(); inc_cuenta(), que aade 1 a cuenta; y leer_cuenta();
que devuelve el valor actual de cuenta.
(164)
Destructores
En una clase se puede definir una funcin miembro especial conocida como destructor,
que se llama automticamente siempre que se destruye un objeto de una clase. El
nombre del destructor es el mismo que el nombre de la clase, precedida por el
carcter: .En este manual se le cambiara por .
Al igual que un constructor, el destructor se puede definir sin ningn tipo de retorno
(ni incluso void); al contrario que un constructor, no puede aceptar parmetros. Slo
puede existir un destructor.
Ejemplo:
class Demo
{
private:
int datos;
public:
Demo() {datos=0;}
Demo(){}
};
//constructor
//destructor hall vaco
Regla:
*Los destructores no tienen valor de retorno.
*Tampoco tienen argumentos
El uso mas frecuente del destructor es liberar memoria que fue asignada por el
constructor. Si un destructor no se declara explcitamente, C++ crea un vaco
automticamente.
Si un objeto tiene mbito local, su destructor se llama cuando su control pasa fuera de
su bloque de definicin. Si un objeto tiene mbito de archivo, el destructor se llama
cuando termina el programa principal (main), Si un objeto se asign dinmicamente
(utilizando new y delete), el destructor se llama cuando se invoca el operador delete.
//El destructor notifica cuando se ha destruido un punto
class Punto
{
public:
Punto()
{
cout <<Se ha llamado al destructor de punto \n;
}
// . . .
};
(165)
(166)
? x : x;
? x : x;
? x : x;
? x : x;
Para este tipo de problemas, sin embargo, C++ proporciona un mecanismo ms gil y
potente, las plantillas de funciones. En lugar de escribir las cuatro funciones abs(), se
puede escribir una nica plantilla de funcin, que se decena como:
template <clase <TDD>>
TDD abs(<TDD> x)
{
return (x<0) ? x : x;
};
La palabra reservada template indica al compilador que una plantilla de funcin que se
ha definido. El smbolo tipo indica al compilador que puede ser sustituido por el tipo de
dato apropiado: int, float,,etc.
(167)
(168)
El programa anterior declara una funcin plantilla Func1() y utiliza la funcin con
argumentos enteros (int) o reales (float).
Cuando el compilador va la funcin plantilla, no sucede nada asta que la funcin se
utiliza realmente en el programa. Cuando la funcin Func1() se utiliza por primera
vez, se llama con dos argumentos enteros. El compilador examina la funcin plantilla,
observa que los argumentos se declaran con variables de tipo genricos y se construye
una funcin correspondiente que utiliza enteros como argumentos. El compilador
genera la siguiente funcin real de la funcin plantilla:
Compilador
(169)
//archivo de cabecera
cout<<maximo(e1,e2) = <<max(e1,e2)<<endl;
cout<<maximo(d1,d2) = <<max(d1,d2)<<endl;
cout<<maximo(c1,c2) = <<max(c1,c2)<<endl;
return;
(170)
Funcion_a();
Las variables declaradas en este nivel
son locales y tienen clase de
almacenamiento auto al salir de la
ejecucin, a menos que se utilice la
palabra reservada static. Visible solo
a esta funcin.
variable
local
Las variables con mbito global se denominan variables globales y son definidas
externamente a la funcin (declaracin externa). Las variables globales tienen el
siguiente comportamiento y atributos:
Las variables globales tienen duracin esttica por defecto. El almacenamiento se
utiliza en tiempo de compilacin y nunca desaparece. Por definicin, una variable
global no puede ser una variable auto.
Las variables globales son visibles globalmente en el archivo fuente, se pueden
referenciar por cualquier funcin, a continuacin del punto de definicin del objeto.
(171)
Las variables globales estn disponibles, por defecto, a otros archivos fuente. Esta
operacin se denomina enlace externo.
Variables locales frente a variables globales
Adems de las variables globales, es preciso considerar las variables locales. Una
variable local esta definida solamente dentro del bloque o cuerpo de la funcin y no
tiene significado (vida) fuera de la funcin respectiva. Por consiguiente, si una funcin
define una variable como local, el mbito de la variable esta protegido. La variable no
se puede utilizar, cambiar o borrar desde cualquier otra funcin sin una programacin
especifica mediante el paso de valores (parmetros).
Una variable local es una variable que se define dentro de una funcin.
Una variable global es una variable que puede ser utilizada por todas las funciones de
un programa dado, incluyendo main().
Para construir variables globales en C++, se deben definir fuera de la funcin main().
En la figura siguiente la variable global es x0y la variable local es x1. La funcin puede
realizar operaciones sobre x0, ya que x1 no esta definida fuera del bloque de la funcin
funcion1(). Cualquier intento de utilizar x1 fuera de funcion1() producir un error.
int x0;
funcion1() ;
//variable global
//prototipo funcional (o de funcin)
main()
{
}
Funcion1()
{
int x1;
Examine ahora la figura siguiente. Esta vez existen dos funciones, ambas definen x1
como variable local. Nuevamente x0 es una variable global. La variable x1 solo se
puede utilizar dentro de dos funciones. Sin embargo cualquier operacin sobre x1
dentro de funcion1() no afecta al valor de x1 dentro de funcion2() y viceversa. En
otras palabras, la variable x1 de funcion1() se considera una variable independiente de
la x1 de funcion2().
(172)
int x0;
funcion1();
funcion2();
main()
{
}
funcion1()
{
int x1;
}
funcion2()
{
int x1;
Al contrario que las variables, las funciones son externas por defecto, Es preciso
considerar la diferencia entre definicin de una funcin y declaracin. Si una
declaracin de variable comienza con la palabra reservada extern, no se considera
definicin de variable. Sin esta palabra reservada es una definicin. Cada definicin de
variable es al mismo tiempo una declaracin de variable. Se puede utilizar un variable
solo despus que ha sido declarada (en el mismo archivo). nicamente las definiciones
de variables asignan memoria y pueden por consiguiente, contener inicializaciones.
Una variable solo se define una vez, pero se puede declarar tantas veces como se
desee. Una declaracin de variable a nivel global (externa a las funciones) es valida
desde esa declaracin hasta el final del archivo; una declaracin en el interior de una
funcin es vlida solo en esa funcin. En este punto, considere que las definiciones y
declaraciones de variables globales son similares a las funciones; la diferencia principal
es que se puede escribir la palabra reservada extern en declaraciones de funcin.
La palabra reservada extern se puede utilizar para notificar al compilador que la
declaracin del resto de la lnea no esta definida en el archivo fuente actual, pero esta
localizada en otra parte. El siguiente ejemplo utiliza extern:
(173)
//main.cpp
int Total;
extern int Suma;
extern void f(void);
void main(void);
//MODULO.CPP
int Suma;
void f(void);
(174)
//prototipo de la funcin
void main()
{
Ejemplo_estatica(1);
Ejemplo_estatica(2);
Ejemplo_estatica(3);
}
//ejemplo del uso de una variable esttica:
void Ejemplo_estatica(int llamada)
{
static int Cuenta;
cuenta=1;
cout<<\n El valor de cuenta en llamada n: <<llamada<< es: <<cuenta;
++cuenta;
}
Al ejecutar el programa se visualiza:
El valor de cuenta en llamada n:1 es: 1;
El valor de cuenta en llamada n:2 es: 2;
El valor de cuenta en llamada n:3 es: 3;
Si quita la palabra reservada static de la declaracin de Cuenta, el resultado ser:
El valor de cuenta en llamada n:1 es: 1;
El valor de cuenta en llamada n:2 es: 1046;
En donde no se puede predecir cual es el valor de Cuenta en llamadas posteriores.
Las variables globales se pueden ocultar de otros archivos fuente utilizando el
especificados de almacenamiento de clase static.
Para hacer una variable global privada al archivo fuente (y por consiguiente, no til a
otros mdulos de cdigo) se le hace preceder por la palabra static. Por ejemplo, las
siguientes variables se declaran fuera de las funciones de un archivo fuente:
static
static
static
static
static
int m =25;
char linea_texto[80];
int indice_linea;
char buffer[MAXLOGBUF];
char *pBuffer;
(175)
Las variables anteriores son privadas al archive fuente. Obsrvese este ejemplo:
const OFF=1;
const ON=0;
main()
{
//
}
function_a()
{
//
}
maestro se puede utilizar en function_a() como en main(), en este archivo fuente,
pero no se puede declarar como extern a otro modulo fuente.
Se puede hacer tambin una declaracin de funcin static. Por defecto, todas
las funciones tienen enlace externo y son visibles a otros mdulos de programa.
Cuando se sita la palabra reservada static delante de la declaracin de la funcin, el
compilador hace privada a la funcin al modulo fuente. No se puede, entonces
reutilizar el nombre de la funcin en otros mdulos fuente del programa.
Compilacin separada:
Hasta este momento, casi todos los ejemplos que se han expuesto en el
capitulo se encontraban en un solo archivo fuente. Los programas grandes son ms
fciles de gestionar si se dividen en varios archivos fuente, tambin llamados mdulos,
cada uno de los cuales puede contener una o ms funciones. Estos mdulos se
compilan y enlazan por separado posteriormente con un enlazador, o bien con la
herramienta correspondiente del entorno de programacin. Cuando se divide un
programa grande en pequeos, los nicos archivos que se recompilan son los que se
han modificado. El tiempo de compilacin se reduce, dado que pequeos archivos
fuente se compilan ms rpido que los grandes. Los archivos grandes son difciles de
mantener y editar, ya que su impresin en un proceso lento que utilizara cantidades
excesivas de papel.
(176)
Archivo
Fuente1
Archivo
Fuente2
Archivo
Fuente n
Compilador
Archivo
Objeto1
Enlazador
Archivo
Objeto2
Archivo
Objeto n
Mdulos
Biblioteca
Programa ejecutable
Como regla general, son preferibles las variables locales a las globales. Si
realmente es necesario o deseable que alguna variable, sea global, es preferible
hacerla esttica, lo que significa que ser local en relacin al archivo en que est
especificada.
Ejemplo:
//MODULO.CPP
#include <iostream.h>
main()
{
//MODULO2.CPP
#include <iostream.h>
int n=100;
//definicin de n, tambin declaracin
static int m=7;
void f(int i)
{
n+=i+m;
}
//n=n+1+i+m, n=(100+1)+8+7;
void g(void)
{
cout<<n =<<n<<endl;
}
f y g se definen en el modulo 2 y se declaran en el modulo1. Si se ejecuta el
programa, se produce la salida:
n=116;
Fin de programa.
Se puede hacer una funcin invisible fuera de un archivo fuente utilizando la
palabra reservada static con la cabecera y el prototipo de la funcin.
(178)
item pasado
por:
Valor
Valor
Referencia
Referencia
Cambia item
dentro de la
funcin:
Si
No
Si
No
modifica
parmetros al
exterior
No
No
Si
No
Sin embargo, si se desea cambiar el carcter utilizado por la funcin se puede escribir:
asteriscos(4,0,40,'#');
En donde el argumento implcito (#) anula el carcter por omisin (*);
Otro ejemplo es la funcin funcdef()
char funcdef(int arg1=1,char c='A',float f_val=45.7f);
Se puede llamar a funcdef con cualquiera de las siguientes sentencias:
funcdef(9,'Z',91.5);
funcdef(25,'W');
funcdef(90);
funcdef();
//
//
//
//
->(1)
->(2)
->(3)
->(4)
Sin embargo, no se puede omitir un argumento a menos que se omitan todos los
argumentos a su derecha. Por ejemplo, la siguiente llamada a la funcin no es
correcta:
funcdef( ,'Z',99.99);
// ERROR!!
Se debe tener cuidado y situar cualquier argumento que tenga valores por defecto a la
derecha de una funcin.
f();
f(a);
f(a,b);
f(a,b,c);
La funcin escribir_car tiene dos parmetros. El primero indica el carcter a escribir
(visualizar) y el segundo indica el nmero de veces que este carcter debe escribirse:
void escribir_car(char c,int num=1)
{
for(int i=1; i<=num;i++)
cout<<c;
}
El parmetro num se la ha dado el valor por defecto de 1. Este valor se utilizar
automticamente si se omite el argumento correspondiente en una llamada. Si no se
omite el argumento, se utilizara este valor. Llamadas vlidas son:
(181)
escribir_car('x',4);
escribir_car('y');
// se escribe una x
// se escribe 5 # en una sola lnea
// se escribe 5 % en lneas independientes
(183)
Ejemplo:
int i; //variable global, ambito de programa
static int j;
main()
{
int d,e;
//
}
//mbito de archivo
func(int j)
{
if(j>3)
{
int i;
//mbito de bloque
for(i=0;i<20;i++)
func(i);
//instruccin inmediata a for
printf(HOLA MUNDO); //se escribe una sola vez fuera de dominio
//de for
}
// i no es visible ya.
Obsrvese que func() es una funcin recursiva por definicin se puede llamar a si
misma.
Dato y funcin Pueden o no se lo mismo?
Este es un dilema de la programacin, ya que asta ahora en este manual se ha
definido tanto lo que es un dato y una funcin pero pueden darse casos en la
programacin donde se confunden los conceptos lo cierto es que dicha confusin se
plantea de la forma siguiente:
Una funcin puede ser un dato (es una abstraccin de la funcin), pero una dato no
puede ser una funcin
Respuesta: Por lo tanto un dato y una funcin no son lo mismo.
Estructura de una funcin:
<TDD> <nombre _ funcin> (<lista de parmetros>)
{
//declaracin de variables
//Cuerpo de la funcin
return <expresion>;
//valor devuelto
}
<expresin> puede ser: 0, como en el caso del int main() . Si en lugar de int main(),
fuera una funcin cualquiera cuyo prototipo fuera: int funcion_suma (int a, int b);
sta podra implementarse as:
(185)
Cdigo de escape
(Tambin se conocen como secuencias de escape, vase la pgina 6 de este manual)
Secuencia de escape
\a
\b
\f
\n
\r
\t
\v
\\
\?
\
\000
\x
\0
Significado
Alarma
Retroceso de espacio
Avance de pgina
Retorno de carro y avance de lnea
Retorno de carro
Tabulacin
Tabulacin vertical
Barra inclinada
Signo de interrogacin
Dobles comillas
Nmero octal
Nmero hexadecimal
Cero,nulo (ASCII 0)
Uso
a=b
a*=b
a/=b
a%=b
a+=b
a-=b
a++ (incremento)
a-- (decremento)
a**
Descripcion
Asigna el valor de b a a
a = a*b
a=a/b
a=resto(a/b)
a=a+b
a=a-b
a=a+1
a=a-1
a=a*a
Las expresiones ++a y a++ tienen el mismo efecto, como a-- y --a
Operador de negacin ( ! ) :
if (A!=B)
se lee si a es distinto de b.
(187)
Ejemplo:
bool MayorDeEdad;
MayorDeEdad=true;
MayorDeEdad=(x==y);
*
&
.
->
Accin
Lee o modifica el valor apuntado por la expresin. Se
corresponde con un puntero y el resultado es del TDD
apuntado.
Devuelve un puntero al objeto utilizado como operando, que
debe ser un Ivalue (variable dotada de una direccin de
memoria). El resultado es un puntero de tipo idntico al del
operando.
Permite acceder a un miembro de un objeto agregado (unin,
estructura o clase)
Accede a un miembro de un objeto agregado (unin,
estructura o clase) apuntado por el operando de la izquierda.
Operador condicional ?
El operador condicional, ?: , es un operador ternario que devuelve un resultado cuyo
valor depende de la condicin comprobada. Tiene asosiatividad a derechas.
Al ser un operador ternario requiere tres operndoos. El operador condicional se utiliza
para reemplazar a la sentencia if-else lgica en algunas situaciones. El formato del
operador condicional es:
<expresion_c> ? <expresion_v> : <expresion_f>;
(188)
en ejecucin:
comicion=100;
comicion=0;
equivale a i++;j++;
equivale a i++;j++;k++;
(189)
(190)
//miembro de la clase
//puntero a un miembro
Se pueden utilizar dos operadores diferentes para acceder a miembros de una clase:
1- El operador de acceso a miembro (el operador punto)
c.radio=10.0;
2- El operador de acceso a miembro de la clase (el operador flecha)
ptr_objeto->radio=10.0;
3- Un operador puntero a miembro
ptr_objeto radio=10.0;
*Un constructor es una funcin miembro con el mismo nombre de su clase. Un
constructor no puede devolver un TDD pero puede ser sobrecargado.
class complejo
//
complejo(double a,double y);
complejo(const complejo &c)
Para una clase, x, un constructor con el prototipo, x::x(const x&), se conoce como
constructor de copia.
*Un constructor es una funcin miembro especial que se invoca cuando se crea un
objeto. Se utiliza normalmente para inicializar los atributos de un objeto. Los
argumentos por defecto hacen al constructor ms flexible y util.
*El proceso de crear un objeto se llama instanciacin (creacin de instancia)
*Una funcin miembro constante es una que no puede cambiar los atributos de sus
objetos. Si se desea utilizar objetos de funcin clase const, se debe definir funciones
miembro const.
inline double complejo::real(void) const
{
return result;
}
(192)
};
C c1,c2; //definiciones de objetos
En lugar de:
class C c1,c2;
public:
c()
{
x=-9999;
}
};
void f()
{
C c;
cout<<c.x;
}
// ERROR!!
(193)
//ERROR
}
*Tampoco se pueden especificar argumentos, incluso void, en la declaracin o
definicin del destructor de una clase.
*No se pueden tener dos constructores de la misma clase con los mismos tipos de
argumentos.
*Un constructor de una clase C no puede tener un argumento de un tipo C, pero s
puede tener un argumento de tipo referencia, C&. Este constructor es el constructor de
copia.
5. Inicializadores de miembros.
class C
{
//ERROR
};
int x=5;
class C
{
int x;
public:
C()={x=5;};
};
//correcto
(194)
int main()
{
C c;
c.x=10; // ERROR, x es privado en t
}
Contiene un error, ya que x es privado en C y por consiguiente asequible slo por los
mtodos o amigas de C.
7. No se puede acceder a un miembro dato protegido (protected) fuera de su
jerarqua de clases, excepto a travs de una funcin amiga. Por ejemplo:
class C
// clase base
{
protected:
int x;
};
class D:public C
{
};
int main()
{
C c1;
c1.x=10;
// ERROR, x es protegido
::
?:
sizeof
};
(195)
C::C(C c)
{
}
C::C(C &c)
{
11. Un miembro dato static no se puede definir dentro de una clase, aunque s debe
ser declarado dentro de la declaracin de la clase.
class C
{
static int x=7;
};
class D
{
static int x;
};
// ERROR
(196)
class Empleado
{
public:
Empleado();
Empleado(string n); //se olvida el parmetro salario
//
private:
string nombre;
float salario;
};
15. Referencia a un atributo privado de una clase. Los identificadores declarados
como atributos o funciones privados de una clase no pueden ser referenciados
desde el exterior de la clase. Cualquier intento de referencia producir mensaje
de error similar a:
undefined symbol
16. Fallo por no incluir un archivo de cabecera requerido. Se generan numerosos
mensajes de error por ese fallo de programacin ya que un archivo de cabecera
contiene la definicin de un nmero de los identificadores utilizados en su
programa y el mensaje ms frecuente de stos errores sra:
undefined symbol
17. Fallo por definir una funcin como miembro de una clase. Este error se puede
producir por varias formas:
1- Fallo al prefijar la definicin de la funcin por el nombre de su clase y el
operador de resolucin de mbito (::).
2- Fallo al escribir el nombre de la funcin correctamente.
3- Omisin completa de la definicin de la funcin de la clase.
En cualquiera de los casos el resultado es el mismo; un mensaje de error del
compilador que indica que la funcin llamada no existe en la clase indicada.
is not a member
Ejemplo: Si se invoca a una funcin imprimir del objeto c1 de la clase contador en la
sentencia de C++:
c1.imprimir();
Aparece en el programa cliente; se visualizar el mensaje:
imprimir if not a member of contador
(197)
O bien:
etiq1:
//bloque de instrucciones
goto etiq1; //ciclo indefinido
//etiqueta
//bloque de instrucciones 1
goto etiq2; //itera, continue controlado
//bloque de instrucciones opcional 2
goto etiq1; //salto de linea, break controlado
//bloque de instrucciones opcional 3
goto etiq2; //repite ciclo, puede ser controlada
etiq1:
//etiqueta de final del ciclo
(198)
Conclusiones
El presente manual contiene informacin bsica para aprender a programar en
C++ y adems comprender y gozar de las facilidades que el lenguaje C++ ofrece, el
este lenguaje en materia de programacin es un excelente programa con el nico
defecto de que no es un lenguaje portable, el lenguaje C++ es un lenguaje muy formal
y se pueden hallar muchas formas de escribir cdigos que resuelvan problemas, si se
va a disear programas para otros usuarios se tener en cuenta que ciertas funciones
de C++ pueden no ser reconocidas por otros compiladores.
Las funciones son la base de la construccin de programas en C++. Se utilizan
funciones para subdividir problemas grandes en tareas ms pequeas. El
encapsulamiento de las caractersticas en funciones, hace los programas ms fciles de
mantener. El uso de funciones ayuda al programador a reducir el tamao de su
programa, ya que se puede llamar repetidamente y reutilizar el cdigo dentro de una
funcin.
El entorno de un programa tiene cuatro tipos de mbito: de programa, archivo
fuente, funcin y bloque. Una variable est asociada a uno de esos mbitos y es
invisible (no accesible) desde otros mbitos.
El programa C++. Un buen programa se obtiene combinando Visual C++ 6.0
con Dev C++, que es un compilador de C/C++ estndar y automticamente usa
libreras del Visual C++.
Comando til para el programa: [ Alt Gr+: ] sirve para tener acceso a la
biblioteca del programa.
Insuficiencias del manual:
El manual no presenta informacin acerca la representaciones de interfaz
graficas en C++, tampoco explica en profundidad el comportamiento y creacin de
estructuras de almacenamiento tales como listas, arboles,etc. pero presenta material
abundante sobre punteros, manejo de struct, creacin de objetos, manejo de
variables, llamada a funciones. Lo cual constituyen el conocimiento bsico para
iniciarse en la creacin de estructuras de listas, rboles, presenta adems un enfoque
muy orientado al objeto accin, funcin que se subsana en la recopilacin III donde se
explica con mas detalle lo que son las clases ntese que al comienzo de esta
recopilacin se plantea un debate sobre objeto vs clases muy interesante, se
explica muy poco acerca de los origenes del lenguaje C++ al principio. En fin el
lenguaje C++ es un sper conjunto del lenguaje C como lo podramos catalogar y este
manual se queda corto. Se omiten adems las reglas para la creacin de pseudocdigo
ya que esto no forma parte del lenguaje C++, pero en algunas definiciones a manera
general se tomo en cuenta las reglas de representacin del pseudocodigo por ejemplo
en la recopilacin I. Tambin podra catalogarse de falla el hecho de que algunos
conceptos se repitan en la obra de hecho la recopilacin III es material terico el cual
esta explicado de forma practica en captulos anteriores, y en la recopilacin II
aparezca material que expliquen tpicos ya explicados en la recopilacin I, como
apuntadores, no obstante el manual no se diseo con el objetivo de que se lleve un
orden lineal por lo que se recomienda seleccionar el material adecuado a su nesecidad
de programacin y implementarlo en su programa, sin embargo el manual contiene
diversas lecturas indispensables para programar en C++.
(199)
Bibliografa consultada:
Recopilacin hecha de:
-UCV Profesores: J. Parada #1, J.Jaimes, Robinson, R. Carmona
-Internet.
-Grupo de investigacin UCM.
-GUA DE SINTAXIS DEL LENGUAJE C++:
(ESTNDAR C++ ANSI)
(Fundamentos de Programacin gua de L. J. Aguilar)
-Otros cursos por la Web sobre programacin en C++,
-Cdigos fuentes/guas para laboratorios de C/C++ UCV.
-tecnun CAMPUS TECNOLGICO DE LA UNIVERSIDAD DE NAVARRA
Profesores:
Pal Bustamante
Iker Aguinaga
Miguel Aybar
Luis Olaizola
Iigo Lazacano
-Programacin en Algoritmos, estructuras de datos y objetos L. Joyanes Aguilar
(200)
La clase string
#include <iostream>
#include <string>
using namespace std;
/*
* inicio de la clase String
*
* uso de una clase string
*/
class String
{
public:
String(); //constructores
String(const char * const);
//constructor de copia
String(const String &);
//destructor
~String();
//operadores sobrecargados
/*operador [] que devuelve una referencia a char. Se utiliza en
instrucciones como UnaCadena[3]=\'x\' */
char & operator[] (unsigned short offset);
//operador [] que devuelve un char. No modifica ningun valor \"const\"
char operator[] (unsigned short offset) const;
String operator+ (const String &);
void operator+= (const String &);
String & operator= (const String &);
//metodos generales
unsigned short GetLen() const
{return itsLen;}
const char * GetString() const
{return itsString;}
private:
//constructor privado, se utiliza unicamente desde alguna funcion interna
de la clase
String (unsigned short);
//declaracion de variables
//contiene la cadena
char * itsString;
//contiene la longitud de la cadena
unsigned short itsLen;
};
//constructor predeterminados. Crea una cadena de 0 bytes
String::String()
{
//inicializamos la cadena
itsString=new char[1];
//colocamos como primera posicion de la cadena el final de linea
itsString[0]=\'\\0\';
itsLen=0;
}
//convierte un array de caracteres en una cadena
String::String (const char * const cString)
{
//strlen=devuelve la longitud de una cadena, sin contar con el caracter nulo de
terminacion.
itsLen=strlen(cString);
itsString=new char[itsLen+1];
//llenamos la cadena con el array recibido
for (unsigned short i=0;i<itsLen;i++)
itsString[i]=cString[i];
itsString[itsLen]=\'\\0\';
}
//constructor de copia
//rhs es una referencia al mismo control String
String::String (const String & rhs)
{
itsLen=rhs.GetLen();
itsString=new char[itsLen+1];
for (unsigned short i=0;i<itsLen;i++)
itsString[i]=rhs[i];
itsString[itsLen]=\'\\0\';
}
//destructor
String::~String()
{
delete [] itsString;
itsLen=0;
}
//operador [] sobrecargado
char & String::operator[] (unsigned short offset)
{
if(offset>itsLen)
return itsString[itsLen-1];
else
return itsString[offset];
}
//operador [] sobrecargado
char String::operator[] (unsigned short offset) const
{
if(offset>itsLen)
return itsString[itsLen-1];
else
return itsString[offset];
}
//crea una cadena nueva al agregar a la cadena actual el contenido de rhs
String String::operator+ (const String & rhs)
unsigned short i;
for (i=0;i<itsLen;i++)
temp[i]=itsString[i];
for (unsigned short j=0;j<rhs.GetLen();j++,i++)
temp[i]=rhs[i-itsLen];
temp[totalLen]=\'\\0\';
//modificamos el valor actual de la variable
*this=temp;
//operador igual a
String & String::operator= (const String & rhs)
{
//this es una variable que se pasa ocula y hace referencia al lado derecho de la
asignacion (a=b)
//comprovamos si el apuntador del lado derecho de la asignacin (this) es igual
a la misma referencia
// de memoria que el lado izquerdo de la asignacion.
if(this==&rhs)
return *this;
//eliminamos la referencia actual de la cadena
delete [] itsString;
//cogemos la nueva longitud
itsLen=rhs.GetLen();
itsString=new char[itsLen+1];
for (unsigned short i=0;i<itsLen;i++)
itsString[i]=rhs[i];
itsString[itsLen]=\'\\0\';
return *this;
}
String s4;
//utiliza el constructor \"String(const char * const);\"
s4=\"Porque trabaja esta funcion?\";
cout << \"s4\\t\" << s4.GetString() << endl;
//una cadena char normal
char s5[]=\"Hola mundo!\";
cout << endl << \"s5\\t\" << s5 << endl;
//modificamos el 4 valor de la cadena
s5[3]=\'x\';
cout << \"s5\\t\" << s5 << endl;
//cualquier posicin de memoria... puede contener cualquier caracter
cout << \"s5[100]\\t\" << s5[100] << endl;
}
return 0;