Programacion C
Programacion C
Programación
Lenguaje C y C++
Todos los Derechos Reservados. Se autoriza para que este material pueda ser leida
y reproducida por los estudiantes que la requieran.
Muchos de los nombres utilizados por los fabricantes o vendedores de software para
distinguir sus productos son marcas registradas. El editor tiene toda la intención de
proporcionar la información de la marca registrada acerca de los fabricantes y los
productos mencionados en este libro. Una lista de las designaciones de marcas
registradas se muestra más adelante en esta página.
Marcas Registradas
C++ Builder es una marca registrada por Inprise Corporation.
Turbo C++ es una marca registrada por Borland International, Inc.
MS-Windows™ es una marca registrada por Microsoft Corporation
MS-DOS es una marca registrada por Microsoft Corporation
Visual C++ es una marca registrada por Microsoft Corporation
Contenido
Ejercicios
Prologo
Este libro puede ser utilizado como guía para el examen de admisión de la
Maestría en Informática que el Instituto en Computación y Electrónica
Dehesa ofrece en lo que se refiere a Programación.
Cada tema expuesto viene acompañado de uno o más ejercicios, el nombre del
archivo aparece como comentario al inicio de cada listado de programa. Los
programas que contiene el libro fueron probados usando compiladores de
Borland.
Espero que al terminar de leer este libro se cubran las expectativas planteadas,
cualquier comentario o sugerencia acerca del contenido del material lo puede
hacer a la siguiente dirección de correo electrónico: [email protected]
6 Programación C y C++
Capitulo 1
Introducción al Lenguaje C
• Historia del lenguaje
• Estructura de un programa
• Compilación y Ligado
• Tipos de Datos y Modificadores
• Operadores
• Entrada y Salida de Datos
• Especificadores de clase de almacenamiento
• Ejercicios
Programación C y C++ 7
ESTRUCTURA DE UN PROGRAMA
clrscr();
printf("BIEN BENIDO AL LENGUAJE C");
printf("\n\n CALCULO DEL AREA DE UN CIRCULO");
printf("\n Radio: ");
scanf("%i",&Radio);
Area_Cir(Radio);
printf("\n El Area es; %8.2f",Area);
getch();
COMPILACIÓN Y LIGADO
Princip.cpp Archivo2.cpp
stdio.h conio.h
COMPILACION
Princip.obj Archivo2.obj
Cl.lib Mathl.lib
LIGADO
Extern.exe
Palabras reservadas
Las palabras reservadas del compilador son todas aquellas palabras que se
usan para especificar tipos de variables, estructuras cíclicas, estructuras de
decisión, etc., y que no pueden ser usadas por el usuario como nombre de
variables, de funciones o de nuevos tipos .Estas palabras son las siguientes:
asm delete goto public this
auto do huge register union
break double if return unsigned
case else int Short virtual
carch enum interrupt signet void
char extern long sizeof volatile
class far near static while
const float new struct
continue for private switch
defauld friend protected template
Tipos de datos
Midificadores
Los modificadores son palabras reservadas que se le adicionan a los tipos para
modificarles su tamaño y/o su rango, estos son:
Signed
unsigned
long
short
Estas son algunas de las combinaciones que se pueden presentar:
Como se puede observar cada tipo tiene un tamaño en bits, este tamaño
define un rango de operación que limita los números que se puede almacenar
en una variable. imagínese que se desea diseñar un programa de nómina que
14 Programación C y C++
Comentarios
Programación C y C++ 15
Variables
OPERADORES
Ejemplos:
a).- 8/4*6 8*6/4 28/(3*4)
2*6 48/4 28/12
12 12 2
b).- 3/4*6 3*6/4
0*6 18/4
0 4
c).- (float) 2/4
2.0/4
0.5
d).- -3+4% 5/2
-3+4/2
-3+2
-1
18 Programación C y C++
%f Punto flotante)
%h Entero corto
%o Octal sin signo
%s Cadena de caracteres
%x Hexadecimal sin signo
Ejemplo:
Ejemplo:
20 Programación C y C++
/*ES-Estan.cpp
Muestra el uso de las funciones printf() y scanf()
*/
#include <conio.h>
#include <stdio.h>
void main()
{char Nom[40];
int Edad;
float Peso;
clrscr();
printf("IDENTIFIQUESE POR FAVOR");
printf("\n\n NOMBRE: ");
scanf("%s",Nom);
printf("\n EDAD: ");
scanf("%i",&Edad);
printf("\n PESO: ");
scanf("%f",&Peso);
Observe que al leer las variables Edad y Peso de tipo entero y real
respectivamente se utiliza el operador & que indica dirección, mientras que la
variable Nom que es un arreglo de caracteres (cadena) no lo requiere, la
función printf() hace uso frecuentemente de la secuencia de escape \n para
cambiar de línea, por ejemplo el penúltimo printf() hace que se deje una línea
en blanco.
/*ES-Flujo.cpp*/
#include <conio.h>
#include <iostream.h> //En lugar de stdio.h
void main()
{char Nom[40];
int Edad;
float Peso;
clrscr();
cout<<"IDENTIFIQUESE POR FAVOR";
cout<<"\n\n NOMBRE: ";
cin>>Nom;
cout<<"\n EDAD: ";
cin>>Edad;
cout<<"\n PESO: ";
cin>>Peso;
palabra. Para leer más de una palabra se puede utilizar la función getline() de
la siguiente forma:
cin.getline(Cadena, num);
Donde:
Cadena es cualquier arreglo de caracteres que se haya definido con
anterioridad y que contiene la cadena de entrada.
Num es el número máximo de caracteres que desea leer con getline()
Ejemplo:
cin.getline(Nom, 40); //Se puede almacenar hasta 40 caracteres en Nom
Los ejemplos que se mostraran a partir de esta parte del libro en adelante,
usarán el cout y el cin para la entrada y salida de datos en pantalla. Sin
embargo al abordar el tema de la programación visual se dejará de usar.
Aunque este tema esta ligado más con el tema de Variables se dejo para esta
sección porque se requiere de los conocimientos anteriores para comprenderlo
con más claridad.
• extern
I UNIDAD: 80
II UNIDAD: 90
III UNIDAD: 100
El Promedio es: 90
Creación de Proyectos
• static
Las varibles static son variables permanentes dentro de una función o archivo
según si se declaran como locales o globales respectivamente.
void serie();
void main()
{int x;
clrscr();
for (x=0;x<5;x++)
serie();
getch();
}
26 Programación C y C++
void serie()
{static int cont=0; //Variable Local static
cont=cont+10;
cout<<"\t"<<cont;
}
La salida de este programa será:
10 20 30 40 50
• register
El especificador de almacenamiento register originalmente pedía al
compilador que mantuviera el valor de una variable en un registro de la CPU
en lugar de en memoria, que es donde se almacena normalmente las variables.
Esto significaba que las operaciones debían de realizarse con mayor rapidez.
Actualmente el estándar ANSI simplemente establece “que el acceso al objeto
sea lo más rápido posible”, lo anterior es aplicado a cualquier tipo de dato.
El especificador registers solo puede aplicarse a variables locales y a
los parámetros de una función. Ejemplo:
void imprime_Caracter()
{
register int x;
for (x=0; to N; x++)
cout <<leer_puerto();
}
• auto
Cuando se define una variable sin indicar su especificador, por defauld su
especificador es auto. El especificador de almacenamiento auto declara una
variable con existencia local. Esta es visible solamente en el bloque en el que
es declarada.
28 Programación C y C++
EJERCICIOS RESUELTOS
1.- Usando la entrada salida estándar escribir un programa que calculé el área
de un triangulo a partir de su base y altura usando la formula:
Area=(Base*Altura)/2.
/* Area.cpp */
#include <stdio.h>
#include <conio.h>
void main ()
{
float Altura,Base,Area;
clrscr();
printf ("CALCULA EL AREA DE UN TRIANGULO.");
printf("\n\nTECLEE LA BASE: ");
scanf("%f",&Base);
printf("\nTECLEE LA ALTURA: ");
scanf("%f",&Altura);
Area=(Base*Altura)/2;
printf("\nEl EL AREA ES: %8.2f", Area);
printf("\nPRESIONE <ENTER> PARA TERMINAR");
getch();
}
# include <stdio.h>
# include <conio.h>
void main ()
{
char nombre[40];
float chr, hrst, Sueldo;
clrscr();
printf ("\n CALCULA EL SUELDO DE UN EMPLEADO");
printf ("\n\n NOMBRE DEL EMPLEADO: ");
gets(nombre);
printf ("\n HORAS TRABAJADAS: ");
scanf ("%f", &hrst);
printf ("\n COSTO POR HORA: ");
scanf ("%f",&chr);
Sueldo=hrst*chr;
printf("\n EL SUELDO DE %s es de: $ %8.2f",nombre,Sueldo);
getch();
}
Programación C y C++ 29
/*Preventa.cpp
# include <stdio.h>
# include <conio.h>
void main ()
{
char descripcion[40];
float CosP, Temp, CVenta;
clrscr();
printf ("\n CALCULA EL PRECIO DE VENTA DE UN ARTICULO.");
printf ("\n\n DESCRIPCION DEL ARTICULO: ");
gets (descripcion);
printf ("\n COSTO DE PRODUCCION: ");
scanf("%f", &CosP);
Temp= (CosP+(CosP*1.2));
CVenta=Temp + Temp*.15;
printf("\n EL COSTO DE VENTA DE %s ES: $ %8.2f", descripcion,
CVenta);
getch();
}
C2 = a 2 + b 2.
/* Hipotenu.cpp */
# include <iostream.h>
# include <conio.h>
# include <math.h> //Por las funciones matemáticas
void main ()
{
float A, B, C;
clrscr();
cout<<"CALCULO DE LA HIPOTENUSA";
cout<<"\n CATETO A:" ;
cin>>A;
cout<<"\n CATETO B:";
cin>>B;
C= sqrt (pow(A,2)+pow(B,2));
/*Fahrenhe.cpp */
# include <iostream.h>
# include <conio.h>
void main ()
{
float Fahr, Celsius, Kelvin, Rankine;
clrscr();
cout<<"\n CONVIERTE GRADOS FAHRENHEIT A CELSIUS, KELVIN, Y
RANKINE.";
cout<<"\n GRADOS FAHRENHEIT:";
cin>>Fahr;
Celsius= (Fahr-32)*5/9;
Kelvin=Celsius+273;
Rankine=Fahr+460;
cout<<"\n EQUIVALENCIA A GRADOS ";
cout<<"\n CELSIUS : "<<Celsius;
cout<<"\n KELVIN : "<<Kelvin;
cout<<"\n RANKINE : "<<Rankine;
getch();
}
/*Venta1.cpp /*Venta2.cpp
Proyecto: Venta.prj */ proyecto: Venta.prj */
void Calcula2()
{
Deuda=Interes+Inversion;
}
32 Programación C y C++
EJERCICIOS PROPUESTOS.
Z= 1 / 2Π e –w2/2
Capitulo 2
SENTENCIAS DE SELECCIÓN
A las sentencia de selección tambien se les conoce como sentencia
condicional, entre las que se incluyen if y switch
• if, if-else
#include <conio.h>
#include <iostream.h>
void main()
{int Edad;
clrscr();
cout<<"PROPORCIONE SU EDAD: ";
cin>>Edad;
if (Edad<18)
cout<<"\n Aun es menor de edad";
else
cout<<"\n Es mayor de edad";
getch();
}
Programación C y C++ 35
/*IF2.cp
Encuentra el mayor de 3 números*/
#include <conio.h>
#include <iostream.h>
void main()
{clrscr();
int A=3,B=10,C=15; //Probar con otros valores
int Mayor;
if ((A>B) &&(A>C))
Mayor=A;
else
if ((B>A) && (B>C))
Mayor=B;
else
Mayor=C;
• switch
• Expresión entera, puede ser una constante, una variable, una llamada a
función o una expresión. La sentencia switch no funciona con datos de
tipo coma flotante
• El valor después de cada etiqueta case debe ser una constante entera o
carácter, como 3 o ‘b’, o bien una expresión que se evalúe a una
constante como ‘a’ +’32’.
• Necesita utilizar una sentencia break después de cada conjunto de
sentencias ejecutables. La sentencia break hace que la ejecución del
programa se reanude después del final de la sentencia switch actual. Si
no se utiliza la sentencia break, la ejecución del programa se reanudará
en las siguientes etiquetas case.
• El conjunto de sentencias case no necesita ser encerradas entre llaves.
• Si ninguno de la valores de constante_1, constante_2, etc. Coincide con
el valor de expresión_entera, se ejecutarán las sentencias que vienen a
continuación de la sentencia opcional default.
Ejemplo:
/*Switch.cpp
Calcula el área de figuras Geométricas
usando la Instrucción switch*/
#include <conio.h>
#include <iostream.h>
void main()
{char op;
int L,B,H,R;
float Area;
clrscr();
cout<<" CALCULO DE AREAS";
cout<<"\n 1.- RECTANGULO";
cout<<"\n 2.- TRINGULO";
cout<<"\n 3.- CIRCULO";
cout<<"\n Opcion:";
op=getche();
switch (op)
{
case '1': cout<<"\n\n Lado:";
cin>>L;
Area=L*L;
break;
getch();
}
La salida de una ejecución sería:
CALCULO DE AREAS
1.- RECTANGULO
2.- TRINGULO
3.- CIRCULO
Opcion:2
Base:10
Altura:20
SENTENCIAS DE ITERACIÓN
Entre las sentencias de iteración se incluyen for, while y do-while. Cualquier
sentencia de iteración tiene tres partes importantes que son: Inicialización,
condición e incremento, aunque cada sentencia de iteración debe usarse
preferente según la situación en la mayoría de los casos se puede adaptar
cualquiera de las tres a cualquier situación.
• for
instrucción;
#include <conio.h>
#include <iostream.h>
void main()
{clrscr();
getch();
}
La salida sería:
0 5 10 15
for anidados
Un ciclo for puede colocarse dentro de otro, en este caso el ciclo interno se
ejecutará totalmente cada vez que se ejecute el ciclo que lo contiene.
Ejemplo:
/*for2.cpp
Imprime tabla de multiplicación */
#include <conio.h>
#include <iostream.h>
void main()
{clrscr();
int x,y;
int fin1=6, fin2=5; //Probar con otros valores
for (x=1;x<=fin1;x++)
{
cout<<"\n";
for (y=1;y<=fin2;y++)
cout<<x*y<<"\t";
}
getch();
}
La salida sería:
1 2 3 4 5
2 4 6 8 10
3 6 9 12 15
4 8 12 16 20
5 10 15 20 25
6 12 18 24 30
Por cada valor que toma x en el ciclo for externo se efectúa totalmente el ciclo
for interno es decir y inicialmente toma el valor de 1 y se imprime 1*1=1,
luego y=2 y se imprime 2, y así hasta que y=5 imprime 5, en el siguiente
ciclo la condición se hace falsa dándose por terminado el ciclo interno, pero el
ciclo externo incrementa su valor y ejecuta nuevamente el ciclo interno, este
proceso se sigue hasta que la condición del ciclo externo se hace falsa.
• while
while (condicion)
{
instrucción_1;
instrucción_2;
}
40 Programación C y C++
#include <conio.h>
#include <iostream.h>
void main()
{int ini=50,fin=0,inc=10;
int x=ini; //Inicialización
while (x>fin)
{
cout<<x<<"\t";
x=x-inc; //Decremento
}
}
La salida sería:
50 40 30 20 10
• do-while
Ejemplo:
/*Do-While.cpp
Menu de Opciones */
#include <conio.h>
#include <iostream.h>
void main()
{clrscr();
char op;
do
{ cout<<" MENU";
cout<<"\n 1.-Altas";
cout<<"\n 2.-Bajas";
cout<<"\n 3.-Consultas";
cout<<"\n 4.-Salir";
cout<<"\nOpcion:";
do
{
op=getch();
}
while(op!='1'&&op!='2'&&op!='3'&&op!='4');
//Código adicional
}
while (op!='4');
}
La salida del programa sería:
MENU
1.-Altas
2.-Bajas
3.-Consultas
4.-Salir
Opcion:
SENTENCIAS DE SALTO
C tiene cuatro sentencias que llevan a cabo un salto incondicional: return,
goto, break y continue. De ellas, se puede usar return y goto en cualquier
parte del programa . Las sentencias break y continue se deben usar junto con
una sentencia de ciclo.
• return
La sentencias return se usa para volver de una función. Se trata de una
sentencia de salto porque hace que la ejecución vuelva (salte atrás) al punto en
que se hizo la llamada a la función.
42 Programación C y C++
Return (expresión)
• goto
La sentencia goto se puede usar para realizar ciclos usando una etiqueta, o
para saltar a otra parte de un programa, actualmente no es recomendable su
uso por que hace ilegible el código.
Etiqueta:
Setencia_1;
Sentencia_2;
...
goto Etiqueta;
Donde: Etiqueta es cualquier etiqueta valida anterior o posterior al goto.
Ejemplo:
/*goto.cp */
#include <conio.h>
#include <iostream.h>
void main()
{clrscr();
int x=0;
Inicio:
x++;
cout<<"\n"<<x;
if (x<10)
goto Inicio;
}
• break
La sentencia break tiene dos usos. Se puede usar para finalizar un case en una
sentencia switch. También se puede usar para forzar la terminación inmediata
de una bucle, saltando la evaluación condicional normal del ciclo.
Cuando se encuentra la sentencia break dentro de un ciclo, el ciclo
finaliza inmediatamente.
Programación C y C++ 43
Ejemplo:
/*break.cpp
Lee caracteres hasta que se pulse la tecla <esc> */
#include <conio.h>
#include <iostream.h>
void main()
{ clrscr();
char car;
cout<<"PULSE <Esc> PARA TERMINAR\n\n";
for(;;) //Ciclo infinito
{
car=getche();
if (car==27)
break;
}
}
• continue
/*continue.cpp
Imprime los números del 0 al 50 que sean múltiplos de 4 */
#include <conio.h>
#include <iostream.h>
void main()
{ clrscr();
int x;
for (x=0;x<50;x++)
{
if (x % 4) //Cualquier valor diferente de cero es verdadero
continue;
cout<<x<<" ";
}
}
La salida del programa es:
0 4 8 12 16 20 24 28 32 36 40 44 48
44 Programación C y C++
EJERCICIOS RESUELTOS
/*Alumno.cpp */
#include <stdio.h>
#include <conio.h>
#include <iostream.h>
#define N 3
void main()
{ clrscr();
float Prom,SumCal=0,Cal;
int x;
char Nom[40];
cout<<"DETERMINA SI UN ALUMNO APRUEBA O NO";
cout<<"\n\nNOMBRE DEL ALUMNO: ";
gets(Nom);
for (x=1;x<=N;x++)
{
cout<<"\n CALIFICACION No "<<x<<": ";
cin>>Cal;
SumCal=SumCal+Cal;
}
Prom= SumCal/N;
cout<<"\nEL ALUMNO "<<Nom<<" TIENE EL PROMEDIO DE: "
<<Prom<<" Y ESTA:";
if(Prom>=70)
cout<<"\n\nAPROBADO";
else
cout<<"\n\nREPROBADO";
getch();
}
Programación C y C++ 45
/*Hotel.cpp */
#include <conio.h>
#include <iostream.h>
void main()
{ clrscr();
float CosHabi,Dias,Desc,SubTotal,Total;
cout<<"CALCULA EL COSTO DE UNA HABITACION DE UN HOTEL";
cout<<"\n\nCOSTO DE LA HABITACION: ";
cin>>CosHabi;
cout<<"No. DE DIAS: ";
cin>>Dias;
SubTotal=CosHabi*Dias;
if (Dias<=5)
Desc=0;
else
if (Dias>5 && Dias<=10)
Desc=SubTotal*.10;
else
if (Dias>10 && Dias<=15)
Desc=SubTotal*.15;
else
Desc=SubTotal*.20;
Total=SubTotal-Desc;
cout<<"\nSUB-TOTAL: "<<SubTotal;
cout<<"\nDESCUENTO: "<<Desc;
cout<<"\n _______ ";
cout<<"\nTOTAL: "<<Total;
}
46 Programación C y C++
void main()
{ clrscr();
float SalSem, SalHra, SalTE=0,SalBase;
int Hrs;
char Nom[40];
cout<<"CALCULA EL SALARIO SEMANAL DE UN TRABAJADOR";
cout<<"\n\nNOMBRE DEL TRABAJADOR: ";
gets(Nom);
cout<<"\nNo. DE HORAS TRABAJADAS POR SEMANA: ";
do{ //Valida el intervalo de Hrs permitidas
cin>>Hrs;
}
while(Hrs<0 || Hrs>80);
cout<<"\nSALARIO POR HORA:";
cin>>SalHra;
if (Hrs<=40)
{
SalBase=Hrs*SalHra;
SalSem=SalBase;
}
else
{
SalBase=40*SalHra;
if (Hrs>40 && Hrs <=50)
SalTE=(Hrs-40)*SalHra*2;
else
if (Hrs>50 && Hrs <=60)
SalTE=(Hrs-40)*SalHra*3;
else
SalTE=(Hrs-40)*SalHra*4;
SalSem=SalBase+SalTE;
}
cout<<"\nTRABAJADOR: "<<Nom;
cout<<"\nSALARIO BASE: "<<SalBase;
cout<<"\nSALARIO POR TIEMPO EXTRA: "<<SalTE;
cout<<"\n _______ ";
cout<<"\nSALARIO TOTAL SEMANAL: "<<SalSem;
}
Programación C y C++ 47
x2,y2
/*Rectang.cpp */
#include <conio.h>
#include <iostream.h>
void main()
{ clrscr();
int x,y,x1,y1,x2,y2;
cout<<"DIBUJA UN RECTANGULO EN PANTALLA SEGUN COORDENADAS";
cout<<"\nESCRIBA LAS COORDENADAS X1,Y1,X2,Y2 MODO TEXTO ";
cout<<"SEPARADOS POR UN ESPACIO: \n";
cin>>x1>>y1>>x2>>y2;
EJERCICIOS PROPUESTOS.
2.- Una librería vende libros con las condiciones siguientes: Si el cliente es
tipo 1 se le descuenta el 30%, si el cliente es tipo 2 se le descuenta el 20%, si
el cliente es tipo 3 se le descuenta 10%. Cuando el cliente realiza una compra
se generan los datos siguientes: Nombre del cliente, Tipo de cliente (1,2,3),
cantidad de libros, costo por libro. Elabore un programa que lea estos datos e
imprima: Nombre del cliente, Total a pagar, Descuento y el Neto a pagar.
4.- Elaborar un programa que lea los datos de un estudiante: nombre y tres
calificaciones parciales e imprimir el nombre y la calificación final de
acuerdo a lo siguiente: Para aprobar el curso, debe tener 70 o más en cada
una de las tres calificaciones, la calificación final será el promedio. En caso
de haber reprobado uno o más exámenes ordinarios, la calificación final será
NA (NO ACREDITADO).
6.- Reescriba el programa del ejercicio resulto 1 pero sin usar ciclos
Capitulo 3
Arreglos y Apuntadores
• Que son los arreglos
• Arreglos unidimensionales
• Cadenas
• Arreglos bidimensionales
• Apuntadores
• Punteros y arreglos
• Inicialización de apuntadores
• Funciones de asignación dinámica
• Ejercicios
Los arreglos, punteros y cadenas de caracteres son conceptos relacionados en
el lenguaje C, por esta razón se integran en este capitulo.
50 Programación C y C++
Un arreglo es una colección de variables del mismo tipo que se referencia por
un nombre común. A un elemento específico de un arreglo se accede
mediante un índice. En C todos los arreglos constan de posiciones de
memoria contiguas. La dirección más baja corresponde al primer elemento y
la dirección más alta al último elemento. Los arreglos pueden tener una o más
dimensiones.
ARREGLOS UNIDIMENSIONALES
Tipo nombre[Tamaño];
Tipo nombre[];
Donde: tipo Indica el tipo de datos de los elementos del arreglo.
nombre Es el identificador del arreglo
tamaño Especifica el número de elementos del arreglo. El tamaño
puede omitirse cuando se inicializa el arreglo, cuando se declara como un
parámetro en una función o cuando se hace referencia a un arreglo declarado
en otra parte del programa, es recomendable que el tamaño sea definido como
una constante para garantizar no rebasar el límite del arreglo.
Ejemplo:
#define N 30
int Calif[N];
La declaración de la variable anterior hace que el compilador reserve
espacio de memoria para almacenar 30 datos de tipo entero. En C todos los
arreglos tienen el 0 como índice de su primer elemento, por tanto el primer
elemento de la variable anterior sería Calif[0] y el último elemento Calif[29].
El lenguaje C no checa los límites de un arreglo. Es responsabilidad
del programador realizar este tipo de operaciones para no escribir o modificar
porciones de memoria que no le pertenecen al arreglo.
La cantidad de memoria requerida para guardar un arreglo esta
directamente relacionada con su tipo y su tamaño. Para un arreglo
unidimensional, el tamaño total en bytes se calcula:
Tatal en bytes =sizeof(tipo)*tamaño = sizeof(nombre_ arreglo).
Ejemplo:
float Salario[10];
int Tam;
Tam=sizeof (Salario); //Tam=40
• Inicialización de un arreglo
char Caracter[]={‘a’,’b’,’c’,’d’,’e’,’f’};
char Cadena[11]=”HOLA AMIGOS”;
char Cadena2[]=”PROGRAMACIÓN EN LENGUAJE C”;
/*Arreglo2.cpp.cpp
Visualiza el contenido de un arreglo */
#include <conio.h>
#include <iostream.h>
#define N 4
void main()
{ clrscr();
int Cal[N],x;
Cal[0]=90; Cal[1]=80;Cal[2]=100; Cal[3]=70;
for (x=0;x<N;x++)
cout<<"\t"<<Cal[x];
getch();
}
La salida es
90 80 100 70
/*Arreglo3.cpp.cpp
Determina el número mayor que existe en un arreglo
unidimensional generados aleatoriamente.*/
#include <conio.h>
#include <iostream.h>
#include <stdlib.h> //por random() y randomize()
#define N 10
void main()
{ clrscr();
int Aleat[N],x;
int Mayor=0;
randomize(); //inicializa la semilla
for (x=0;x<N;x++)
{
Aleat[x]=random(100); //genera números aleat. entre 0 y 100
cout<<" "<<Aleat[x];
}
//Encuentra el número mayor en el arreglo
for (x=0;x<N;x++)
if (Aleat[x]>Mayor)
Mayor=Aleat[x];
cout<<"\n\nEl mayor es: "<<Mayor;
}
52 Programación C y C++
El mayor es: 79
/*Arreglo4.cpp
Ordena un arreglo unidimensional en forma ascendente
aplicando el método de selección */
#include <conio.h>
#include <iostream.h>
#define N 10
void main()
{ clrscr();
int A[N]={79,24,59,18,41,37,64,3,23,29}; //Arr. inicializado
int menor,temp,ind,x,y;
for (x=0;x<N-1;x++)
{
menor=A[x];
ind=x;
for (y=x+1;y<N;y++) //Recorre la lista y determina
if (A[y]<menor) //el menor
{
menor=A[y];
ind=y;
}
if (ind!=x) //Intercambia el elemento menor a la posición x
{
temp=A[x];
A[x]=A[ind];
A[ind]=temp;
}
}
for (x=0;x<N;x++)
cout<<" "<<A[x];
getch();
}
La salida del programa es:
3 18 23 24 29 37 41 59 64 79
CADENAS
C no tiene un tipo de dato para cadenas de caracteres. Una cadena de
caracteres es un arreglo unidimensional, en el cual todos sus elementos son de
tipo char, al final del arreglo contiene el carácter nulo ‘/0’. C soporta una gran
variedad de funciones para el manejo de cadenas definidos en el archivo de
cabecera string.h e aquí algunos:
Nombre Función
strcpy(c1,c2) Copia c2 en c1
strcat(c1,2) Concatena c2 al final de c1
strlen(c1,c2) Devuelve la longitud de la cadena
strcmp(c1,c2) Devuelve 0 si c1 y c2 son iguales; menor que 0 si c1<c2;
mayor que 0 si c1>c2
strchr(c1,car) Devuelve un puntero a la primera ocurrencia de car en c1
strstr(c1,c2) Devuelve un puntero a la primera ocurrencia de c2 en c1
Tabla 3. 1.- Funciones para el manejo de cadena
Ejemplos:
/*Cadena.cpp */
#include <string.h>
#include <conio.h>
#include <iostream.h>
void main()
{ clrscr();
int L,x;
char Cad[]="HOLA AMIGO"; //Esta es la cadena
L=strlen(Cad); //Longitud de la cadena
for (x=L-1;x>=0;x--)
cout<<Cad[x];
getch();
}
La salida del programa es:
OGIMA ALOH
/*Cadena2.cpp
Operaciones con cadena */
#include <string.h>
#include <stdio.h>
#include <conio.h>
#include <iostream.h>
#define N 40
void main()
{ clrscr();
int L,x;
char C1[]="INSTITUTO ";
char C2[]="TECNOLOGICO DEL ISTMO";
char C[N];
char Est[N];
strcpy(C,C1); //Copia C1 en C
strcat(C,C2); //Concatena C2 en C
cout<<"\nDonde Estudio el autor de este libro: ";
gets(Est); //En lugar de cin.getline();
if (strcmp(C,Est)==0)
cout<<"\nAcertaste";
else
cout<<"\nNo Acertaste, él estudio en el: "<<C;
getch();
}
La salida es:
ARREGLOS BIDIMENSIONALES
El termino dimensión representa la cantidad de índices utilizados para
referenciar un elemento particular en un arreglo. Los arreglos de más de una
dimensión se conocen como arreglos multidimensionales. La forma más
simple de un arreglo multidimensional es el arreglo bidimensional. Para
definir un arreglo Tabla de enteros bidimensional de tamaño 5,4 se escribiría:
Int Tabla[5][4];
0 1 2 3
0 0 5 10 15
1 20 25 30 35
2 40 45 50 55
3 60 65 70 75
4 80 85 90 95
Tabla[1][2]
Un programa que asigne valores a los elementos del arreglo bidimensional
como en la tabla anterior sería:
/*A_Bidim.cpp
Asigna valores múltiplos de 5 a un arreglo bidimensional */
#define N 5
#define K 4
void main()
{ int Tabla[N][K];
int x,y,cont=0;
for (x=0;x<N;x++)
for(y=0;y<K;y++)
{
Tabla[x][y]=5*cont;
cont++;
}
}
El programa utiliza dos ciclos for para asignar valores a cada uno de
los elementos del arreglo, el for interno controla el 2º. índice (columnas) y el
for externo el primer índice (filas).
Ejemplo:
/*A_Bidim2.cpp
Lee las K calificaciones de N alumnos, calcula sus promedios,
el aprovechamiento del grupo y visualiza los resultados */
#include <conio.h>
#include <iostream.h>
#define N 5
#define K 4
void main()
56 Programación C y C++
{ clrscr();
int Calif[N][K];
float Prom[N], Aprov;
int x,y, Suma1,Suma2=0;
//Visualización
cout<<"\nALUMNO I II III IV Prom";
for (y=0;y<N;y++)
{
cout<<"\n"<<y+1;
for(x=0;x<K;x++)
{
gotoxy(x*5+10,y+N+4);
cout<<Calif[y][x];
}
gotoxy(x*5+10,y+N+4);
cout<<Prom[y];
}
cout<<"\nAprovechamiento : "<<Aprov;
getch();
}
La salida del programa es:
ALUMNO I II III IV
1 70 85 90 80
2 100 90 70 95
3 75 80 85 90
4 70 85 75 100
5 100 100 95 95
Un programa bien escrito debe reunir la característica anterior para adaptarse ante un
cambio sin ninguna o casi ninguna modificación en el código.
Tipo nombre[T1][T2][T3]...[Tn]
APUNTADORES
Dirección de Variable en
memoria memoria
*P 2C00 2C03
2C01
2C02
Car 2C03 ‘A’
Figura 3. 1.- Una variable apuntando a otra
• Declaración de un Apuntador
Tipo * nombre;
Ejemplo:
int *P;
58 Programación C y C++
Ejemplo:
int x=10,y;
int *P;
P=&x; //Asigna la dirección de x a P
y=*P; //Asigna el cont. de lo apuntado por P a y, o sea 10
float x=10;
int *P;
P=&x; //Las variables no son del mismo tipo
• Aritmética de punteros
Existen sólo dos operaciones aritméticas que se pueden realizar con los
punteros: la suma(++) y la resta(--). Cada vez que se incrementa un puntero,
apunta a la posición de memoria del siguiente elemento de su tipo base. Cada
vez que se decrementa, apunta a la posición del elemento anterior. Con
punteros a caracteres , parece una aritmética normal. Sin embargo, el resto de
los punteros aumentan o decrementan en la longitud del tipo de datos a los que
apuntan. Suponiendo los enteros de 2 bytes de longitud, cuando se incrementa
un puntero a entero, su valor aumenta en 2. El siguiente programa ilustra este
ejemplo:
/*Apunta2.cpp
Aritmética de punteros/
#include <conio.h>
#include <iostream.h>
void main()
{ clrscr();
int x;
int *P;
for (x=0;x<5;x++)
{
cout<<P<<" ";
P++; //Incremento
}
}
La salida sería:
0x3dc10000 0x3dc10002 0x3dc10004 0x3dc10006 0x3dc10008
Programación C y C++ 59
/*Apunta3.cpp
Pila de Enteros */
#include <conio.h>
#include <iostream.h>
#define N 5
void main()
{ clrscr();
int Pila[N],Val;
int *P,*Tope;
P=Pila; //Apunta al inicio de la pila
Tope=Pila+N; //Apunta al final de la pila
cout<<"Agregue elementos en la pila, 0 para terminar:\n";
do
{
cin>>Val;
if (Val!=0) //Agrega elementos a la pila
if(P<Tope)
{
*P=Val; //Agrega el elemento
P++; //Incrementa el apuntador
}
else
cout<<"Pila Llena\n";
else //Visualiza el contenido de la pila
{
cout<<"Contenido de la pila\n";
do{
P--;
cout<<*P<<"\t";
}
while (P>Tope-N);
}
}
while (Val!=0);
getch();
}
La salida Sería:
Agregue elementos en la pila, 0 para terminar:
80
60 Programación C y C++
30
95
50
10
40
Pila Llena
0
Contenido de la pila
10 50 95 30 80
PUNTEROS Y ARREGLOS
Existe una estrecha relación entre los punteros y los arreglos, considérese el
siguiente fragmento:
int Arr[10], *Ap;
Ap=Arr;
Aquí Ap ha sido asignado a la dirección del primer elemento del arreglo Arr,
por que el nombre de un arreglo sin índice devuelve la dirección de inicio del
arreglo. Para acceder al tercer elemento del arreglo Arr, se escribe:
Arr[2] ó *(Ap+2);
Ambas sentencias devuelven el tercer valor. Para acceder a los elementos de
un arreglo se puede efectuar por cualquiera de los dos métodos: La indexación
del arreglo ó la aritmética de punteros, la ventaja del segundo método es que
mejora la velocidad. Ejemplo:
/*Apunta4.cpp */
#include <conio.h>
#include <iostream.h>
void main()
{ clrscr();
int Arr[10]={10,20,30,40,50,60,70,80,90,100};
int *Ap,x;
Ap=Arr; //Apunta al inicio del arreglo
*(Arr+2)=999; //Cambia el valor del tercer elemento
for (x=0;x<10;x++)
cout<<" "<<*(Ap+x);
}
La Salida sería:
10 20 999 40 50 60 70 80 90 100
INICIALIZACIÓN DE APUNTADORES
#include <conio.h>
#include <iostream.h>
#include <stdlib.h> //Por las funciones de asignación dinámica
void main()
{ clrscr();
int *P;
P=(int *) malloc(2*sizeof(int)); //Asigna espacio para 2 Ent.
*P=1;
P++;
*P=2;
cout<<*P<<" "<<*(P-1); //Visualiza: 2 1
free(P); //Libera la memoria
}
#include <conio.h>
#include <iostream.h>
void main()
62 Programación C y C++
{ int *P;
P=new int[2]; //Asigna espacio para 2 Enteros (4 bytes)
*P=1;
P++;
*P=2;
cout<<*P<<" "<<*(P-1); //Visualiza: 2 1
delete(P); //libera la memoria
getch();
}
• new
/*As_Dina3.cpp
Verifica la cantidad de memoria dinámica libre */
#include <conio.h>
#include <iostream.h>
void main()
{ clrscr();
char *Cad;
int x;
for (x=1;;x++) //Ciclo infinito
{
Cad=new char[1024]; //Asigna 1 Kbyte de memoria
if (Cad==0)
break;
}
cout<<"Se detecto: "<<x<<" Kbytes de memoria libre";
delete(Cad);
}
La salida es:
Se detecto: 60 Kbytes de memoria libre
• delete
EJERCICIOS RESUELTOS
/*Ganacia.cpp */
#include <conio.h>
#include <iostream.h>
#define N 5
void main()
{ clrscr();
int x,GanTotal=0;
float CosArt[N], Gan[N],Iva[N], Venta[N];
cout<<"CALCULA LA GANANCIA EN LA VENTA DE "<<N<<" ARTICULOS";
cout<<"\nPROPORCIONE EL COSTO DE LOS ARTICULOS\n";
for (x=0;x<N;x++)
{
cout<<"\n"<<x+1<<" : ";
cin>>CosArt[x];
Gan[x]=CosArt[x]*.30; //Ganancia por artículo
Iva[x]=CosArt[x]*.15; //IVA por artículo
Venta[x]=CosArt[x]+Gan[x]+Iva[x]; //Prec.de Venta por art.
GanTotal=GanTotal+Gan[x]; //Ganancia total
}
clrscr();
cout<<"ARTIC. COSTO IVA GANACIA VENTA";
for (x=0;x<N;x++)
cout<<"\n"<<x+1<<"\t"<<CosArt[x]<<"\t"<<Iva[x]<<"\t"
<<Gan[x] <<"\t"<<Venta[x];
cout<<"\n\t\t\t_____\n\tGanancia Total= "<<GanTotal;
getch();
}
64 Programación C y C++
2.- Programa que lea los nombres de N alumnos y los ordene en forma
ascendente aplicando el método de burbuja.
/*Burbuja.cpp */
#include <string.h>
#include <stdio.h>
#include <conio.h>
#include <iostream.h>
#define N 5
void main()
{ clrscr();
char Nom[N][40],Temp[40];
int x,y;
cout<<"ORDENA EN FORMA ASCENDENTE "<<N<<" NOMBRES ";
cout<<"\nPROPORCIONE LOS NOMBRES\n";
for (x=0;x<N;x++)
{
cout<<x+1<<" : ";
gets(Nom[x]);
}
//Método de burbuja
for (x=1;x<N;x++)
for(y=N-1;y>=x;y--)
if(strcmp(Nom[y-1],Nom[y])>0)
{
strcpy(Temp,Nom[y-1]); //Intercambio de elementos
strcpy(Nom[y-1],Nom[y]);
strcpy(Nom[y],Temp);
}
getch();
}
/*OpcionVI.cpp */
#include <conio.h>
#include <iostream.h>
#define N 2 //No. de Alumnos
#define M 5 //No. de Materias
#define S 3 //No. de Sinodales
void main()
{ clrscr();
int CalEs[N][M];
int CalOr[N][S];
float PrEs[N], PrOr[N],PrGrl[N];
int x,y, Sum;
cout<<"PROMEDIO GENERAL DE LOS ALUMNOS PARA LA TITULACION";
for (x=0;x<N;x++)
{ Sum=0;
cout<<"\nCAL. DE LA FASE ESCRITA, ALUMNO No. "<<x+1<<"\n";
for(y=0;y<M;y++)
{
cout<<"MATERIA "<<y+1<<" : ";
cin>>CalEs[x][y]; //Lee Calificaciones fase Escrita
Sum=Sum+CalEs[x][y];
}
PrEs[x]=Sum/M; //Promedio por alumno en la fase Escrita
clrscr();
}
for (x=0;x<N;x++)
{ Sum=0;
cout<<"CALIFICACIONES DE LA FASE ORAL, ALUMNO "<<x+1<<"\n";
for(y=0;y<S;y++)
{
cout<<"SINODAL "<<y+1<<" : ";
cin>>CalOr[x][y]; //Lee Calificaciones fase Oral
Sum=Sum+CalOr[x][y];
}
PrOr[x]=Sum/S; //Promedio por alumno en la fase Oral
PrGrl[x]=(PrEs[x]+PrOr[x])/2;
clrscr();
}
cout<<"\n RESULTADOS";
cout<<"\n MATERIAS SINODALES";
cout<<"\nNo. 1 2 3 4 5 PrEsc. 1 2 3 PrOr PrGrl.";
for (x=0;x<N;x++)
{ cout<<"\n"<<x<<" "<<CalEs[x][0]<<" "<<CalEs[x][1]<<" "<<CalEs[x][2];
cout<<" "<<CalEs[x][3]<<" "<<CalEs[x][4]<<" "<<PrEs[x];
cout<<"\t"<<CalOr[x][0]<<" "<<CalOr[x][1]<<" "<<CalOr[x][2];
cout<<" "<<PrOr[x]<<"\t\t"<<PrGrl[x];
if (PrGrl[x]>=80)
cout<<"\tSI";
else
cout<<"\tNO";
}
}
66 Programación C y C++
/*Ordenar.cpp */
#include <stdlib.h>
#include <conio.h>
#include <iostream.h>
#define N 5 //Numero de elementos
void main()
{ clrscr();
int *Num,x,y,Temp;
Num=new int [N];
if (Num==0) //Verifica si no hay memoria dinámica
{
cout<<"\nNo existe memoria disponible";
exit(0); //Finaliza el programa
}
cout<<"DA DE ALTA UNA SERIE DE "<<N
<<" NUMEROS Y LOS ORDENA\n";
/*Indice.cpp */
#include <conio.h>
#include <iostream.h>
#define N 5 //Número de alumnos
void main()
{ clrscr();
int x, Cal[N];
float NApr=0,NRep=0,IApr,IRep;
cout<<"CALCULA EL INDICE DE APROBACION Y REPROBACION";
cout<<"\nDE "<<N<< " ALUMNOS, PROPORCIONE LAS CALIFIC.\n";
for (x=0;x<N;x++)
{
cout<<x+1<<": ";
cin>>Cal[x];
if (Cal[x]>=70)
NApr++;
else
NRep++;
}
IApr=(NApr/N)*100;
IRep=(NRep/N)*100;
cout<<"\nNo. de Aprobados "<<NApr;
cout<<"\nIndice de aprobacion "<<IApr<<" %";
cout<<"\nNo. de Reprobados "<<NRep;
cout<<"\nIndice de Reprobacion "<<IRep<<" %";
getch();
}
68 Programación C y C++
EJERCICIOS PROPUESTOS
1.- Tomando como base el programa del ejercicio resuelto 1, calcular además
el Costo total , El IVA total y el Precio de Venta Total de los N artículos.
2.- Ordenar en forma descendente una lista de N Nombres aplicando el
método de Inserción
3.- Igual que el ejercicio 2 pero aplicando el método Shell
4.- Considérese la siguiente secuencia de nombres proporcionados al
programa del ejercicio resuelto 2: Ana, Carlos, Zenaido, Raúl, Víctor.
Explique el proceso de ordenamiento.
5.- AGREGAR MAS EJERCICIOS
Programación C y C++ 69
Capitulo 4
Funciones y Estructuras
• Funciones
• Pase de parámetros
• Estructuras
• Arreglos de Estructuras
• Ejercicios
70 Programación C y C++
FUNCIONES
Las funciones son la piedra angular en C y C++. Todo lo que se programa en
C y C++ esta dentro de una función. Esto se debe a que todos los programas
deben incluir la función main(), que es en si misma una función. Aunque C++
esta orientada a objetos, las funciones siguen siendo parte de este estilo de
programación ya que dentro de las clases se hayan un conjunto de funciones,
este tema se tratará más adelante, en este capitulo se va ha destacar la
importancia de la programación modular.
La ejecución de un programa comienza por la función main(), cuando
se llama a una función, el control se pasa a la misma para su ejecución; y
cuando finaliza, el control es devuelto de nuevo al módulo que llamo, para
continuar con la ejecución del mismo a partir de la sentencia que efectuó la
llamada.
Sintaxis:
Tipo_de_retorno Nombre_funcion (Lista de parámetros)
{
cuerpo de la función
}
Donde:
Tipo_de_retorno especifica el tipo de valor que devuelve la sentencia
return de la función. El valor puede ser cualquier tipo válido. Si no se
especifica ningún tipo, el compilador asume que la función devuelve como
resultado un entero, las funciones que no devuelven ningún valor deben tener
el tipo void. La Lista de parámetros es la lista de nombres de variables
separados por comas con sus tipos asociados que reciben los valores de los
argumentos cuando se llama a la función. Una función puede no tener
parámetros en cuyo caso la lista de parámetros esta vacía. Sin embargo,
incluso cuando no hay parámetros se requieren los paréntesis y la lista de
parámetros puede estar sustituida por void.
Ejemplo:
float Area_Triang(int Base, int Altura)
{
float Area;
Area=(Base*Altura)/2;
return(Area);
}
[Variable=]Nombre_Funcion([Lista de argumentos])
Donde:
Variable.- Especifica la variable donde va a ser almacenado el valor devuelto
por la función. La llamada puede prescindir del valor devuelto por la función.
Lista de argumentos.- Es la lista de expresiones separados por comas, Los
valores resultantes son pasados a la función y asignados a sus
correspondientes parámetros, el número de argumentos debe ser igual al
número de parámetros definidos en la función.
Ejemplo:
A=Area_Triang(10,15);
PASE DE PARÁMETROS
forma , los cambios en los parámetros en la función no afectan a las variables que se usan
en la llamada.
Ejemplo:
/*Referen.cpp */
#include <conio.h>
#include <iostream.h>
void Intercambio(int *A, int *B);
void main()
{ int x=10,y=50;
Intercambio(&x, &y); //Llamada por referencia
cout<<x<<" "<<y; //Imprime 50 10
72 Programación C y C++
Ejemplo:
/*Ar_para.cpp
Lee el salario por día de N trabajadores, calcula el total a
pagar por semana a cada trabajador y el monto total.*/
#include <conio.h>
#include <iostream.h>
#define N 5
//Definición de funciones
void Leer(float SD[N]);
void Calcular(float SD[], float SS[]);
void Visualizar(float *SD, float *SS);
void main()
{
float SalDia[N], SalSem[N];
Programación C y C++ 73
Leer(SalDia);
Calcular(SalDia,SalSem);
Visualizar(SalDia,SalSem);
getch();
}
ESTRUCTURAS
Ejemplo:
Supóngase que se desea contar con información de los alumnos de una
Institución:
Programación C y C++ 75
struct Alumnos{
char N_Ctrl[9];
char Nom[40];
char Dir[40];
char Ciudad[40];
char Tel[15];
int Edad;
};
Alumnos A;
Nombre_var_estructura.Dato_miembro;
#include <string.h>
#include <conio.h>
#include <iostream.h>
struct Alumnos{
char N_Ctrl[9];
char Nom[40];
char Dir[40];
char Ciudad[40];
char Tel[15];
int Edad;
76 Programación C y C++
};
void main()
{ clrscr();
Alumnos A; //Definición de una variable estructura
//Asignación de datos
strcpy(A.N_Ctrl,"95190205");
strcpy(A.Nom,"Sanchez L¢pez Juan");
strcpy(A.Dir,"Av. 5 de Mayo No. 37");
strcpy(A.Ciudad,"Juchitan, Oax.");
A.Edad=20;
//Visualización
cout<<"\Los datos del alumno son :";
cout<<"\n"<<A.N_Ctrl;
cout<<"\n"<<A.Nom;
cout<<"\n"<<A.Dir;
cout<<"\n"<<A.Ciudad;
cout<<"\n"<<A.Edad;
getch();
}
ARREGLOS DE ESTRUCTURAS
De la misma forma que se pueden crear arreglos con los tipos de datos básicos
de C (int, char, float) tambien se pueden crear arreglos de estructura. Para
declarar un arreglo de estructuras, se debe definir primero la estructura y
luego declarar una variable arreglo de dicho tipo. Ejemplo:
Alumnos Al[5];
Al[2].Edad=19;
#include <stdio.h>
#include <conio.h>
#include <iostream.h>
#define N 5
char Nom[40];
char Dir[40];
char Ciudad[40];
char Tel[15];
int Edad;
};
void main()
{ clrscr();
Alumnos Al[N]; //Definición del arreglo de estructura
int i;
cout<<"NOMBRE No. COTROL DIRECCION CUIDAD EDAD";
for (i=0;i<N;i++)
{
gotoxy(1,i+2); gets(Al[i].Nom);
gotoxy(18,i+2); gets(Al[i].N_Ctrl);
gotoxy(31,i+2); gets(Al[i].Dir);
gotoxy(50,i+2); gets(Al[i].Ciudad);
gotoxy(62,i+2); cin>>Al[i].Edad;
}
}
#include <string.h>
#include <conio.h>
#include <iostream.h>
struct Producto{
char Prod[40];
float Pr_unid;
78 Programación C y C++
int Cant;
};
void main()
{ clrscr();
Producto P;
strcpy(P.Prod,"Tarjeta Madre Pentium III");
P.Pr_unid=1080;
P.Cant=5;
Visualizar(P);
getch();
}
#include <string.h>
#include <conio.h>
#include <iostream.h>
struct Producto{
char Prod[40];
Programación C y C++ 79
float Pr_unid;
int Cant;
};
void main()
{ clrscr();
Producto P; //Definicón de la variable de estructura
Leer(&P);
Visualizar(P);
getch();
}
EJERCICIOS RESUELTOS
1.- Programa que muestre un menú de opciones en pantalla con las siguientes
opciones: Altas, Bajas, Visualizar y Terminar, para manejar un arreglo de
estructuras de N alumnos con los siguientes datos: Número de control,
nombre, dirección, ciudad, teléfono y edad. En la opción de altas validar si el
registro esta vacío para proceder y si no indicarlo con un mensaje; en el
proceso de bajas caso inverso. Durante la visualización solamente se
mostrarán los registros que ya fueron dados de alta.
/*Alumnos.cpp */
#include <string.h>
#include <stdio.h>
#include <conio.h>
#include <iostream.h>
#define N 10 //10 Alumnos, se puede modificar
void main()
{ char op;
Alumnos A[N]; //Arreglo de estructuras
Formatear(A);
do{
clrscr();
cout<<"MANEJO DE UN ARREGLO DE ESTRUCTURA";
cout<<"\n1.-Altas";
cout<<"\n2.-Bajas";
cout<<"\n3.-Visualizar";
cout<<"\n4.-Terminar";
do{
op=getch();
}
while (op!='1'&&op!='2'&&op!='3'&&op!='4');
Programación C y C++ 81
switch (op){
case '1': Altas(A); //Llamada por referencia
break;
case '2': Bajas(A);
break;
case '3': Visualizar(A);
break;
}
}
while (op!='4');
}
}
}
while(Reg!=0);
}
}
84 Programación C y C++
/*Cajero.cpp */
#include <iostream.h>
#include <conio.h>
void Deposito();
void Saldo();
void Retiro();
float Sal=2500; //Saldo inicial
void main()
{ char op;
do{
clrscr();
cout<<"CAJERO AUTOMATICO";
cout<<"\n1.- Depósito";
cout<<"\n2.- Retiro";
cout<<"\n3.- Saldo";
cout<<"\n4.- Salir";
do{
cout<<"\n\nOpcion:";
op=getch();
}
while (op!='1'&&op!='2'&&op!='3'&&op!='4');
switch(op){
case '1':Deposito();
break;
case '2':Retiro();
break;
case '3':Saldo();
break;
}
}
while (op!='4');
}
/*Escolar.cpp */
#include <string.h>
#include <iostream.h>
#include <conio.h>
#include <stdio.h>
#define N 5 //Población de alumnos
#define G 13 //Grado ó semestres permitidos
#define C 6 //Carreras ó Especialidad
struct Est{
char Nom[40];
int Edad;
int Esp;
int Grado;
};
void Altas();
void Grado();
void Especialidad();
void Inicializa();
86 Programación C y C++
void main()
{ char op;
Inicializa();
do{
clrscr();
cout<<"CONTROL ESCOLAR";
cout<<"\n1.- Altas";
cout<<"\n2.- Consulta por Grado";
cout<<"\n3.- Consulta por Especialidad";
cout<<"\n4.- Salir";
do{
cout<<"\n\nOpcion:";
op=getch();
}
while (op!='1'&&op!='2'&&op!='3'&&op!='4');
switch(op){
case '1':Altas(); //Pasa la direcci¢n de inicio
break;
case '2':Grado();
break;
case '3':Especialidad();
break;
}
}
while (op!='4');
}
cin>>E[reg].Edad;
cout<<"Especialidad:(1 a "<<C<<" ) ";
cin>>E[reg].Esp;
cout<<"Grado:(1 a "<<G<<" ) ";
cin>>E[reg].Grado;
}
else
{
cout<<"\nEl registro tiene datos";
getch();
}
reg++;
}
}
while (reg!=0);
}
getch();
}
getch();
}
88 Programación C y C++
EJERCICIOS PROPUESTOS.
Capitulo 5
QUE ES LA POO
La Programación Orientada a Objetos es una técnica o estilo de programación
que utiliza objetos como bloque esencial de construcción. En la programación
convencional, los programas se dividen en funciones y datos, mientras que en
la POO, un programa se divide en componentes que contienen funciones y
datos, donde cada componente se considera un objeto.
• Objeto
Es cualquier entidad que se pueda imaginar, que contiene datos y funciones. A
los datos se les conoce como datos miembros y a las funciones como
funciones miembros ó métodos .
Sintaxis:
Programación C y C++ 91
Class Nombre{
Dato_miembro1;
Dato_miembro2;
...
función_miembro_1();
función_miembro2();
...
}
Ejemplo:
class Empleado{
char Nom[40];
float Salario;
void Asignar(char *N,float S);
void Calcular();
};
El ejemplo muestra una clase llamada Empleado con los datos miembros Nom
y Salario, y funciones miembros Asignar() y Calcular(), esto es solamente la
definición de la clase, cuando se define una variable de esa clase es cuando se
crea una instancia de la clase o un objeto de la clase. Ejemplo:
Podría pensarse que para asignar el valor de 1500 al dato miembro Salario se
podría realizar de la siguiente manera:
void main()
{
Empleado E; //Definición de un Objeto de la clase Empleado.
E.Salario=1500; //Error
}
Sin embargo dentro de una clase cada uno de sus miembros tienen un control
de acceso, y en este caso si dentro de la clase no se especifica ninguno por
default es del tipo privado, que impide que se pueda manipular desde
cualquier otra parte que no sea la clase misma. Para entender lo anterior
primero analicemos los diferentes tipos de Accesos de una clase
92 Programación C y C++
TIPOS DE USUARIOS
Una vez que se conocen los diferentes tipos de usuarios y los tipos de
acceso, se puede establecer la relación entre los tipos de usuarios y los tipos
de acceso, como se muestra en la siguiente tabla.
public, finalmente los usuarios genéricos tendrán privilegio sobre los datos y
funciones miembros que tengan el tipo de acceso public.
Ejemplo:
/*Clase.cpp */
class Empleado{
char Nom[40];
float Salario;
public:
void Asignar(char *N,float S);
void Calcular();
};
//falta implementación de funciones miembros
void main()
{
Empleado E;
E.Asignar("Juan Pérez",120);
}
Tipo_de_retorno Nombre_Clase::Nombre_Funcion(Lista_de_parámetros)
{
...//Código
}
El siguiente ejemplo muestra la implementación de la función Asignar()
dentro de la clase, y la función Calcular() mediante una implementación
independiente.
/*Clase2.cpp */
#include <string.h>
#include <conio.h>
#include <iostream.h>
class Empleado{
char Nom[40];
float Salario;
public:
//implementación dentro de la clase
void Asignar(char *N,float S) {strcpy(Nom,N);Salario=S;}
void Calcular();
};
//Implementación independiente
void Empleado::Calcular()
{ float S;
S=Salario*7;
cout<<"El salario Semanal de: "<<Nom<<" :"<<S;
}
void main()
{ clrscr();
Empleado E;
E.Asignar("Juan Pérez",120);
E.Calcular();
}
La salida del programa es:
El salario Semanal de: Juan Pérez :840
/*Clase3.cpp */
void main()
{ clrscr();
Empleado *E;
E->Asignar("Juan Pérez",120);
E->Calcular();
getch();
}
CLASES AMIGAS
• Funciones amigas
Una función amiga es una función no miembro de una clase que puede tener
acceso a los datos y funciones miembros privadas de una clase. Las funciones
amigas se declaran anteponiendo la palabra reservada friend a la definición de
la función. Sintaxis:
Classs Nombre_clase{
...
friend tipo_retorno Nombre(Lista de parámetros);
...
}
Ejemplo:
96 Programación C y C++
/*AmigaF.cpp */
#include <conio.h>
#include <iostream.h>
class Prueba{
int z;
public:
int Verz(){return z;}
friend void f1(Prueba *Obj,int a);
};
void main()
{ clrscr();
Prueba P; //Definición del objeto
f1(&P,20); //Llamada a la función amiga
cout<<P.Verz();
getch();
}
Classs Nombre_clase{
...
friend class nombre_clase;
...
}
Programación C y C++ 97
En este caso todas las funciones de la clase amiga pueden acceder a las
partes privadas de la otra clase. Una clase amiga debe ser declarada antes de
que se pueda ser designada como amiga.
Ejemplo:
//Pendiente
DATOS ESTÁTICOS
Un dato miembro estático significa que existe solo una instancia de ese
miembro y es compartido por todos los objetos de una clase , existe incluso si
se define ningún objeto de esa clase. Para definir un dato miembro estático se
le antepone a la definición de la variable la palabra reservada static.
A un dato miembro estático se le asigna una zona fija de
almacenamiento en tiempo de compilación, al igual que una variable global,
por ello se debe definir fuera de la clase.
Ejemplo:
/*Estatic.cpp */
#include <conio.h>
#include <iostream.h>
class Datos{
static int Cont; //Dato miembro estático
int v;
public:
void asignac(int c){Cont=c;}
void asignav(int x){v=x;}
int verc(){return Cont;}
int verv(){return v;}
};
void main()
{ clrscr();
Datos d1,d2; //Creación de dos objetos
d1.asignac(10);
d2.asignac(20);
d1.asignav(255);
d2.asignav(500);
cout<<d1.verc()<<"\t"<<d2.verc();
cout<<"\n"<<d1.verv()<<"\t"<<d2.verv();
}
La salida es:
20 20
255 500
En la función principal se crean dos objetos y cada objeto llama a cada una de
las funciones miembros de la clase para asignar valores a los datos miembros
Cont y v sin embargo, se observa que la salida del programa muestra el mismo
98 Programación C y C++
valor para el dato miembro estático, esto significa que no son variables
distintos para cada objeto que se cree a partir de la clase sino que es el mismo,
mientras que en el caso del dato miembro v los valores son diferentes.
CONSTRUCTORES Y DESTRUCTORES
Las clases pueden tener cualquier número de funciones miembros, pero dos
funciones especiales se pueden declarar: el constructor y el destructor.
C++ ofrece un mecanismo para inicializar objetos, cuando se crean a
través de funciones constructores y un mecanismo correspondiente para
destruir objetos cuando ya no se necesitan dentro de su ámbito a través de una
función destructor.
Los constructores y destructores son funciones miembros especiales
que contienen la mayoría de las clases. Las clases pueden declarar uno o más
constructores para inicializar automáticamente los objetos de las clases. Las
clases pueden también declarar solamente un destructor que se llama para
realizar la limpieza cuando un objeto sale de ámbito. Los constructores y
destructores siguen reglas muy estrictas de sintaxis.
• Constructores
/*Const.cpp */
#include <string.h>
#include <conio.h>
#include <iostream.h>
class Producto{
char *Nom;
int Cantidad;
float Precio;
public:
Producto(); //Primer Constructor
Producto(char *N,int C,int P); //Segundo constructor
void Ver();
};
Programación C y C++ 99
void Producto::Ver()
{
cout<<"\n"<<Nom;
cout<<"\n"<<Cantidad;
cout<<"\n"<<Precio;
}
void main()
{
clrscr();
Producto P,Pro("Disco Duro 20 GBytes",4,1600); //2 objetos
Pro.Ver();
P.Ver();
getch();
}
La salida del programa es:
Disco Duro 20 Gbytes
4
1600
Ninguno
0
0
inicializa los datos miembros con los valores “Ninguno”, 0,0 para Nom,
Cantidad y Precio respectivamente. El segundo objeto llamado Pro con tres
argumentos llama a la segunda función constructora.
• Destructores
Un destructor es una función miembro con igual nombre que la clase, pero
precedido por una carácter (∼). Un destructor realiza la función opuesta de un
constructor, limpiando el almacenamiento asignado a los objetos cuando se
crean. Las funciones destructores tienen las siguientes características:
• Tiene el mismo nombre que la clase, precedido por una tilde (∼)
• No retorna ningún valor
• No tiene parámetros
• Una clase solamente puede tener como máximo un destructor.
• Se llama automáticamente por el compilador cuando el objeto sale de
ámbito.
Ejemplo:
/*Const2.cpp */
class Producto{
char *Nom;
int Cantidad;
float Precio;
public:
Producto(); //Primer Constructor
Producto(char *N,int C,int P); //Segundo constructor
void Ver();
~Producto(){delete (Nom);} //Destructor
};
EJERCICIOS RESUELTOS
1.- Escribir un programa que cuente el número de objetos que se crean a partir
de una clase, usando un dato miembro estático y un constructor.
/*Estatic2.cpp*/
#include <conio.h>
#include <iostream.h>
class Modelo{
static int Cont; //Dato miembro estático
public:
Modelo(){Cont++;} //Constructor
int VerC(){return Cont;}
};
void main()
{ clrscr();
Modelo Ob1,Ob2,Ob3;
cout<<Ob1.VerC(); //Visualiza 3
Modelo Ob4,Ob5;
cout<<"\t"<<Ob1.VerC(); //Visualiza 5
}
#include <conio.h>
#include <iostream.h>
class Rect{
int x1,y1,x2,y2;
public:
Rect(){x1=35;y1=10;x2=45;y2=14;} //Constructor
void Dibujar();
void Asignar(int x,int y,int j,int k){x1=x;y1=y;x2=j; y2=k;}
};
//Implementación independiente
void Rect::Dibujar()
{ int x,y;
for (x=x1;x<x2;x++)
{
gotoxy(x,y1);cout<<"Ä";
gotoxy(x,y2);cout<<"Ä";
}
for (y=y1+1;y<y2;y++)
{
gotoxy(x1,y);cout<<"³";
gotoxy(x2,y);cout<<"³";
}
102 Programación C y C++
gotoxy(x1,y1);cout<<"Ú";
gotoxy(x2,y1);cout<<"¿";
gotoxy(x1,y2);cout<<"À";
gotoxy(x2,y2);cout<<"Ù";
}
void main()
{ clrscr();
Rect R; //Se crea un objeto
R.Dibujar(); //se dibuja con valores por defecto
R.Asignar(30,8,50,16);
R.Dibujar();
getch();
}
/*Cajero2.cpp */
#include <iostream.h>
#include <conio.h>
class Cajero{
float Sal;
public:
Cajero(){Sal=2500;} //Constructor
void Deposito();
void Saldo();
void Retiro();
};
void Cajero::Saldo()
{
clrscr();
cout<<"EL SALDO ES: "<<Sal;
getch();
}
void Cajero::Retiro()
Programación C y C++ 103
{int Cant;
do{
clrscr();
cout<<"BIENBENIDO A LA OPCION DE RETIRO";
cout<<"\n Cantidad: ";
cin>>Cant;
if (Cant>Sal)
{
cout<<"\nRebasa su Saldo";
getch();
}
}
while (Cant>Sal && Sal!=0);
if (Sal!=0)
Sal=Sal-Cant;
Saldo();
}
void main()
{ char op;
Cajero C; //Se crea el objeto
do{
clrscr();
cout<<"CAJERO AUTOMATICO";
cout<<"\n1.- Depósito";
cout<<"\n2.- Retiro";
cout<<"\n3.- Saldo";
cout<<"\n4.- Salir";
do{
cout<<"\n\nOpcion:";
op=getch();
}
while (op!='1'&&op!='2'&&op!='3'&&op!='4');
switch(op){
case '1':C.Deposito();
break;
case '2':C.Retiro();
break;
case '3':C.Saldo();
break;
}
}
while (op!='4');
}
104 Programación C y C++
4.- Escribir un programa que maneje una clase Hora con datos miembros tales
como horas, minutos y segundos y funciones para la asignación visualización
de los datos, deberá contar con dos constructores.
/*Hora.cpp*/
#include <iostream.h>
#include <conio.h>
class Hora{
int Hra;
int Min;
int Seg;
public:
Hora(){Hra=0;Min=0;Seg=0;} //Primer Constructor
Hora(int H,int M,int S); //Segundo constructor
void Asigna();
void Ver();
};
//Implementación de funciones miembros
Hora::Hora(int H,int M,int S)
{
Hra=H;
Min=M;
Seg=S;
}
void Hora::Asigna()
{
cout<<"\nHora: ";
cin>>Hra;
cout<<"Minutos: ";
cin>>Min;
cout<<"Segundos: ";
cin>>Seg;
}
void Hora::Ver()
{
cout<<"\nLa hora es: "<<Hra<<":"<<Min<<":"<<Seg;
}
//Función principal
void main()
{ clrscr();
Hora H(9,14,10); //Creación de un objeto
H.Ver();
H.Asigna();
H.Ver();
getch();
}
Programación C y C++ 105
/*Complejo.cpp */
#include <math.h>
#include <iostream.h>
#include <conio.h>
class Complejo{
int x,y;
public:
Complejo(int x1,int y1){x=x1;y=y1;}
void Asignar();
float MagPolar();
float AngPolar();
};
float Complejo::MagPolar()
{ float Mag;
Mag= sqrt (pow(x,2)+pow(y,2)); //Por Pitagoras
return(Mag);
}
float Complejo::AngPolar()
{ float Ang,temp;
Ang=asin(x/MagPolar())*180/M_PI; //Conversión a grados
return(Ang); //por hallarse en radianes
}
//Función principal
void main()
{ clrscr();
Complejo C(5,5);
cout<<"Magnitud:"<<C.MagPolar()<<" Angulo: "<<C.AngPolar();
C.Asignar();
cout<<"Magnitud:"<<C.MagPolar()<<" Angulo: "<<C.AngPolar();
getch();
}
106 Programación C y C++
EJERCICIOS PROPUESTOS
Capitulo 6
Herencia y Polimorfismo
Clases Derivadas
Herencia Simple y Múltiples
Problema y solución de la Herencia Múltiples
Constructores y Destructores en clases
Derivadas
Polimorfismo
Sobrecarga de funciones
Funciones virtuales
Clases Abstractas
• Ejercicios
La herencia y el polimorfismo son dos características de la programación
Orientada a objetos.
La herencia se aplica para extender y reutilizar el código existente por
medio de la creación de clases a partir de clases ya existentes, conocidos como
clases derivadas.
El polimorfismo permite que los objetos se comporten de diferentes
formas cuando aparentemente se llaman a las mismas funciones.
108 Programación C y C++
CLASES DERIVADAS
Se conoce como clase derivada a aquella clase que se crea a partir de otra u
otras clases ya existentes. La clase derivada hereda las estructuras de datos y
funciones de la clase original. Además, se puede añadir nuevos miembros a
las clases derivadas y los miembros heredados pueden ser modificados.
Una clase utilizada para derivar nuevas clases se le denomina clase
base. Una clase derivada puede ser utilizada como una clase base para derivar
más clases. Por lo consiguiente se puede construir jerarquías de clases ó
árboles de herencia en la que cada clase sirve como base de una nueva clase.
En la siguiente figura se presenta un diagrama de un árbol de herencia.
R_Relle
Herencia Simple
Es aquella en la que cada clase derivada hereda de una única clase base.
Herencia Múltiple
Es aquella en la cual una clase derivada tiene más de una clase base
Programación C y C++ 109
A B
Herencia Simple
C D E F
H
G
Herencia Múltiple
El operador : permite derivar de una clase base. El tipo de acceso puede ser
cualquiera de los tres conocidos public, private o protected.
Ejemplo:
class Punto{ //Clase Base
private:
int x,y;
public:
...
};
La clase Rectang es una clase derivada de la clase base Punto, esto significa
que los datos y funciones miembros que existen en la clase base pertenecen
también a la clase derivada además de los propios, así la clase Rectang
contiene los atributos heredados x, y, además de x2, y2 que son los propios.
110 Programación C y C++
Al especificar el tipo de acceso public sobre una clase base significa que los
miembros heredados pasan a la clase derivada con el mismo tipo de acceso
que fueron definidos en la clase base, es por ello que en la mayoría de los
casos se opta por utilizar al crear una clase derivada este tipo de acceso.
Ejemplo:
/*Acceso.cpp */
#include <conio.h>
#include <iostream.h>
void main()
{
B Obj;
Obj.Asignar(10,20);
Obj.Ver(); //Visualiza 10 20
}
Una clase derivada hereda datos y funciones miembros de su clase base. Los
miembros heredados se pueden utilizar con objetos de clase derivada, Si un
miembro heredado se redefine en una clase derivada , el nombre redefinido
oculta el nombre heredado. Para llamar a un miembro ocultado es necesario
utilizar el operador ::.
Ejemplo:
/*FunOcult.cpp */
#include <conio.h>
#include <iostream.h>
class B{
public:
void Funcion(){cout<<"\nFunción B";} //1a. función
};
class D:public B{
public:
void Funcion(){cout<<"\nFunción D";} //2a. función
void F2();
};
void D::F2()
{
Funcion(); //Llama a la segunda función
B::Funcion(); //Llama a la primera función
}
void main()
{
clrscr();
D Obj;
Obj.F2();
}
112 Programación C y C++
Ejemplo:
/*NoHeren.cpp */
#include <conio.h>
#include <iostream.h>
class Base{
protected:
int b;
public:
Base(int x){b=x;}
};
void main()
{
Derivada Obj(30,50);
Obj.Ver();
}
#include <conio.h>
#include <iostream.h>
class A{
protected:
int a1;
public:
int Vera(){return a1;}
};
class B{
protected:
int b1;
public:
int Verb(){return b1;}
};
void main()
{
C Obj;
Obj.Asigna(10,20,30);
Obj.Ver();
}
114 Programación C y C++
B C
/*Pro_Mul.cpp */
#include <conio.h>
#include <iostream.h>
class A{
protected:
int a1;
};
class B:public A{
};
class C:public A{
};
class D:public B, public C{
public:
void Asignar(int x){a1=x;} //Error de ambigüedad
};
void main()
{
D Obj;
Obj.Asignar(10);
}
El aspecto del árbol de herencia para cada una de estas soluciones sería:
A A A
2ª. Solución
B C B C
1ª. Solución
D D
/*Sol_Mul.cpp */
#include <conio.h>
#include <iostream.h>
class A{
protected:
int a1;
};
class B: virtual public A{
};
class C: virtual public A{
};
class D:public B, public C{
public:
void Asignar(int x){a1=x;} //OK Libre de ambigüedad
};
void main()
{
D Obj;
Obj.Asignar(10);
}
Ejercicio:
El siguiente árbol de herencia, contiene un conjunto de clases con atributos de
tipo entero: a).- Definir las clases, b).- Que atributos tendrían los objetos que
se definan a partir de cada clase.
116 Programación C y C++
A B C
a1,a2 b1 c1
D E F
d1 e1 f1,f2
G
g1
Al crear clases derivadas con una sola clase base, el constructor de la clase
base se llama siempre antes que el constructor de la clase derivada. Además se
dispone de un mecanismo para pasar los valores de los parámetros necesarios
al constructor de la clase base desde el constructor de la clase derivada.
POLIMORFISMO
enviar el mensaje Show() para que se visualice, sin tener que preocuparse de
cada objeto de la lista.
SOBRECARGA DE FUNCIONES
Consiste en definir dos ó más funciones con el mismo nombre aunque con
diferencias en el número o tipo de parámetros que reciben, así la función que
se llame será el que coincida con número y tipo de argumento. Esto permite
que una función se comporte de una forma u otra dependiendo de los
argumentos, de aquí el comportamiento polimórfico. Al permitir que una clase
tenga más de un constructor es un caso de sobrecarga de funciones.
Ejemplo:
/*Sob_Fun.cpp */
#include <string.h>
#include <conio.h>
#include <iostream.h>
class Matematico{
public:
int Sumar(int A, int B){return A+B;}
float Sumar(float A, float B){return A+B;}
char * Sumar(char *A, char *B){strcat(A,B);return A;}
};
void main()
{ Matematico M;
float f1=25.3,f2=34.9;
cout<<"\n"<<M.Sumar(10,20);
cout<<"\n"<<M.Sumar(f1,f2);
cout<<"\n"<<M.Sumar("Hola ", "Amigo");
}
La salida del programa es
30
60.200001
Hola Amigo
FUNCIONES VIRTUALES
La ligadura dinámica tiene sentido en C++, sólo para objetos que son
parte de una jerarquía de clases (herencia).
Circulo
Radio;
virtual float Area();
Cilindro
Altura;
virtual float Area();
/*Polimor.cpp */
#include <conio.h>
#include <iostream.h>
#define PI 3.1416
class Circulo{
protected:
int Radio;
public:
Circulo(int r){Radio=r;} //Constructor
virtual float Area(){return(PI*Radio*Radio);}
};
class Cilindro:public Circulo{
int Altura;
public:
Cilindro(int r, int h):Circulo(r){Altura=h;} //Constructor
float Area(){return(2*PI*Radio*Altura +2*PI*Radio*Radio);}
120 Programación C y C++
};
void main()
{ Circulo C(5); //Objeto Circulo
Cilindro Cl(10,5); //Objeto Cilindro
cout<<"Area del Circulo: "<<Area(C); //Imprime 78.54
cout<<"\nArea del Cilindro: "<<Area(Cl); //Imprime 314.16
}
En C++ las funciones virtuales siguen una regla precisa: la función debe ser
declarada como virtual en la primera clase que esta presente, (en la clase
base). Una función virtual es una función que se declara en la clase base como
virtual y se redefine en una ó más clases derivadas. Las funciones virtuales,
son especiales ya que cuando se accede a una de ellas usando una referencia a
un objeto de una clase derivada, C++ determina en tiempo de ejecución a qué
función llamar en función del tipo de objeto apuntado.
CLASES ABSTRACTAS
Una clase abstracta es aquella que sólo se puede utilizar como clase base; no
se puede utilizar para declarar objetos. Desde el punto de vista del lenguaje ,
una clase es una clase abstracta si tiene al menos una función vitual pura.
Una función virtual pura es aquella cuya declaración no está seguida
por una implementación; es decir, que la clase base no puede implementar y
que se inicializan a cero. Sintaxis:
Virtual void func_pura()=0;
Ejemplo:
Se desea escribir un programa que maneje los datos de los Alumnos y
Maestros según la siguiente tabla:
OBJETOS
Alumno Maestro
Datos Nombre Nombre
Dirección Dirección
No. de Control Plaza
Especialidad Departamento
Funciones Alumnos() Maestro()
void Ver() void Ver()
Se aprecia que los datos Nombre y Dirección, así como la función Ver() son
comunes a los dos objetos, se puede crear una clase genérica al que se le
llame Persona que contenga estos tres miembros, y con la finalizad de darle el
comportamiento polimórfico definir la función Ver() como virtual. En este
caso no se pretende definir ningún objeto de la clase Persona por lo que
deberá ser una clase abstracta, o sea la función Ver() será definida como una
función virtual pura. El árbol de herencia queda de la siguiente forma.
Persona
Nom, Dir;
virtual void Ver()=0
Alumno Maestro
NCtrl, Esp; Plaza, Depto;
void Ver(); void Ver();
#include <string.h>
#include <conio.h>
#include <iostream.h>
char NCtrl[15];
char Esp[30];
public:
Alumno(char *N,char *D,char *Ct,char *E);
void Ver();
};
void Alumno::Ver()
{
cout<<"\n\nDATOS DEL ALUMNO";
cout<<"\n"<<Nom;
cout<<"\n"<<Dir;
cout<<"\n"<<NCtrl;
cout<<"\n"<<Esp;
}
Ver(&A);
}
La salida del Programa es:
EJERCICIOS RESUELTOS
/*RectRell.cpp */
#include <conio.h>
#include <iostream.h>
class Rect{
protected:
int x1,y1,x2,y2;
public:
Rect(){x1=35;y1=10;x2=45;y2=14;} //Constructor
void Dibujar();
void Asignar(int x,int y, int j,int k){x1=x;y1=y;x2=j;y2=k;}
};
//Implementación independiente
void RecRell::Dibujar()
{ int x,y;
Rect::Dibujar(); //¿A Que función se llama?
for (y=y1+1;y<y2;y++) //rellena el rectángulo
for (x=x1+1;x<x2;x++)
{
Programación C y C++ 125
gotoxy(x,y);cout<<Car;
}
}
void main()
{ clrscr();
Rect R; //Objeto de la clase Rect
RecRell Rell; //Objeto de la clase RecRell
R.Asignar(10,8,30,16);
R.Dibujar(); //Dibuja un rectángulo
Rell.Dibujar(); //Dibuja un rectángulo rellenado
Rell.Asignar(50,8,70,16,177);
Rell.Dibujar();
}
♣ Árbol de herencia.
Trabajador
Nom, Dir,
Leer();
Visualizar();
TBase TEventual
SalDía, Ant; HonoHra;
Leer(); Visualizar(); Leer(); Visualizar();
PagarSalario(); PagarSalario();
126 Programación C y C++
#include <conio.h>
#include <stdio.h>
#include <iostream.h>
void Trabajador::Visualizar()
{
cout<<"\n"<<Nom;
cout<<"\n"<<Dir;
}
void TBase::Visualizar()
{
cout<<"\nTRABAJADOR DE BASE";
Trabajador::Visualizar();
cout<<"\n"<<SalDia;
cout<<"\n"<<Ant;
}
void TBase::PagarSalario()
{ float SalSemanal;
SalSemanal=SalDia*7 + Ant*0.02*SalDia*7; //Más el 2% por año
cout<<"\nSalario semanal: "<<SalSemanal;
}
void TEventual::Visualizar()
{
cout<<"\nTRABAJADOR EVENTUAL";
Trabajador::Visualizar();
cout<<"\n"<<HonoHra;
}
void TEventual::PagarSalario()
{ float SalSemanal;
SalSemanal=HonoHra*8*7; //*8d hrs * 7 días
cout<<"\nSalario semanal: "<<SalSemanal;
}
// Programa principal
void main()
{ TBase B; //Objeto Trabajador de Base
TEventual E; //Objeto Trabajador Eventual
B.Leer();
E.Leer();
B.Visualizar();
B.PagarSalario();
E.Visualizar();
E.PagarSalario();
}
128 Programación C y C++
3.- Suponga que en una situación real se hallaron los siguientes objetos con
sus respectivos datos miembros de tipo entero:
Objetos A B C D
b1 b1 b1 b1
Datos a1 a1 a1 d1
miembros a2 d1 d1 d2
b2 b2
c2
Solución:
Base
♣ Árbol de herencia: b1
Der1 Der2
a1 d1
A B D
a2 b2 d2
C
c2
♣ Definición de clases
class Base{ class B: public Der1,public
private: Der2{
int b1; private:
}; int b2;
};
class Der1:public virtual Base{
private: class C: public B{
int a1; int c2;
}; };
EJERCICIOS PROPUESTOS