Você está na página 1de 129

Programacin C y C++

Programacin
Lenguaje C y C++

M. C. Gastn Dehesa Valencia

Programacin C y C++

Derechos Reservados 2002 por Gastn Dehesa Valencia


Todos los Derechos Reservados. Se autoriza para que este material pueda ser leida
y reproducida por los estudiantes que la requieran.
En este libro se han incluido programas y descripciones grficas por su valor
educacional. Han sido debidamente probados pero no se garantizan para ningn
propsito en particular. El editor no proporciona ninguna garanta o representacin,
ni acepta ninguna responsabilidad con respecto a los programas y descripciones
grficas.
Muchos de los nombres utilizados por los fabricantes o vendedores de software para
distinguir sus productos son marcas registradas. El editor tiene toda la intencin de
proporcionar la informacin 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 ms adelante en esta pgina.

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

Dedico esta obra a mi familia


Por que representan una fuente de
Energa inagotable, que me impulsa
a emprender nuevos proyectos.

Programacin C y C++

Contenido
1.- Introduccin al Lenguaje C
Historia del lenguaje
Estructura de un programa
Compilacin y Ligado
Tipos de Datos y Modificadores
Operadores
Entrada y Salida de Datos
Especificadores de clase de almacenamiento
Ejercicios
2.- Sentencias de control de programa
Sentencias de Seleccin
Sentencias de Iteracin
Sentencias de Salto
Ejercicios
3.- Arreglos y Apuntadores
Que son los arreglos
Arreglos Unidimensionales
Cadenas
Arreglos Bidimensionales
Apuntadores
Punteros y Arreglos
Inicializacin de Apuntadores
Funciones de Asignacin Dinmica
Ejercicios
4.- Funciones y Estructuras
Funciones
Pase de parmetros
Estructuras
Arreglos de Estructuras
Ejercicios
5.- Programacin Orientada a Objetos
Que es la POO
Definicin de una clase
Tipos de Accesos a una clase
Tipos de Usuarios
Relacin entre Usuarios y Tipos de Accesos
Clases Amigas
Datos Estticos
Constructores y Destructores

Programacin C y C++
Ejercicios

6.- Herencia y Polimorfismo


Clases Derivadas
Herencia Simple y Mltiples
Problema y solucin de la Herencia Mltiples
Constructores y Destructores en clases Derivadas
Polimorfismo
Sobrecarga de funciones
Funciones virtuales
Clases Abstractas
Ejercicios

Programacin C y C++

Prologo
Este libro puede ser utilizado como gua para el examen de admisin de la
Maestra en Informtica que el Instituto en Computacin y Electrnica
Dehesa ofrece en lo que se refiere a Programacin.
Este libro esta organizado de la siguiente forma: En los cuatro primeros
captulos se aborda la programacin estndar y en los captulos 5 y 6 los
conceptos bsicos de la programacin orientada a objetos.
Cada tema expuesto viene acompaado de uno o ms 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.
En archivo empaquetado que acompaa al libro encontrar un directorio por
cada unidad con los ejercicios desarrollados.
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 direccin de correo electrnico: gastondv@hotmail.com

Programacin C y C++

Capitulo 1

Introduccin al Lenguaje C

Historia del lenguaje


Estructura de un programa
Compilacin y Ligado
Tipos de Datos y Modificadores
Operadores
Entrada y Salida de Datos
Especificadores de clase de almacenamiento
Ejercicios

Programacin C y C++

HISTORIA DEL LENGUAJE


El Lenguaje C naci en los Laboratorios Bell de AT&T y ha sido
estrechamente asociado con el sistema operativo UNIX, ya que su desarrollo
se realizo en este sistema y debido a que tanto UNIX como el propio
compilador de C y la casi totalidad de los programas y herramientas de
UNIX, fueron escritos en C. Su eficiencia y claridad han hecho que el
lenguaje ensamblador apenas haya sido utilizado en UNIX.
Este leguaje est inspirado en el lenguaje B escrito por Ken
Thompson en 1970 con intencin de recodificar el UNIX, que en la fase de
arranque estaba escrito en ensamblador, en vista a su transportabilidad a otras
maquinas. B era un lenguaje evolucionado e independiente de la mquina,
inspirado en el lenguaje BCPL concebido por Martn Richard en 1967.
En 1972 , Dennis Ritchie, toma el relevo y modifica el lenguaje B,
creando el lenguaje C y rescribiendo el UNIX en dicho lenguaje. La novedad
que proporciono l lenguaje C sobre el B fue el diseo de tipos y estructuras
de datos.
En 1980 Bjarne Stroustrup de los laboratorios Bell de Murray Hill,
New Jersey, inspirado en el lenguaje Simula67 adiciono las caractersticas de
la programacin orientada a objetos (incluyendo la ventaja de una biblioteca
de funciones orientada a objetos) y lo denomino C con clases. Para 1983 dicha
denominacin cambio a la de C++. Con este nuevo enfoque surge la nueva
metodologa que aumenta las posibilidades de la programacin bajo nuevos
conceptos.
Con la popularidad de las microcomputadoras se crearon muchas
implementaciones de C. En lo que se podra decir que era un milagro, los
cdigos fuentes aceptados por la mayora de esas implementaciones eran
altamente compatibles. Sin embargo, como no exista ningn estndar,
aparecieron discrepancias. Para remediar la situacin, el Instituto de
Estndares Americano (ANSI) estableci un comit a mediados de 1983 para
crear un estndar que definiera al lenguaje C. Este comit ANSI termino el
proceso de formalizacin en 1990.
Actualmente muchas empresas se dedican a vender el Compilador del
lenguaje C, dos de estos imperios son:
Microsoft
Borland

Visual C++ Ver 6.0


C++ Builder 5.0

La mayora de los compiladores actuales soportan la programacin en


C Estndar, C Orientado a Objetos y la Programacin Visual.

Programacin C y C++

ESTRUCTURA DE UN PROGRAMA
Un programa escrito en lenguaje C tiene la siguiente estructura, aunque no
necesariamente debe contener todos los puntos:
1.- Definicin de archivos de cabeceras
2.- Definicin de constantes y variables globales
3.- Definicin de Funciones del usuario
4.- Definicin e implementacin del programa principal ( main() )
5.- Implementacin de funciones del usuario.
A manera de ejemplo considrese el siguiente programa:
//*Est_Prog.cpp
//Definicin de archivos de cabecera
#include <conio.h>
#include <stdio.h>
//Definicin de Constantes y Variables Globales
#define PI 3.1416
float Area;
//Definicin de funciones del usuario
void Area_Cir(int R);
//Definicin e implementacin del Programa Principal
void main()
{int Radio;
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();
}
//Implementacin de funciones del Usuario
void Area_Cir(int R)
{
Area= 2*PI*R*R;
}

La idea de presentar un programa no muy pequeo de entrada a


diferencia de como lo hacen otros autores es para que el estudiante en su
primer da conozca gran cantidad de informacin sobre el Lenguaje C.
El programa Est_Pro.cpp contiene las 5 partes del que se compone un
programa escrito en el lenguaje C. en la seccin de Definicin de archivos de
cabecera se presentan los archivos conio.h y el stdio.h ambos son archivos de

Programacin C y C++

cabecera definidos por el lenguaje, existen un gran numero de ellos que


acompaa al compilador segn la versin y fabricante por lo regular hallados
en el directorio \Include, los archivos de cabecera definidos en esta seccin
que pertenezcen al compilador debern estar entre los signos < > y aquellos
que el propio programador cree para sus aplicaciones entre comillas lo
cual le indicara al compilador que busque el archivo en el directorio de
trabajo y no en el directorio por defauld de archivos de cabecera (include).
La siguiente lista muestra algunos de los archivos de cabeceras que
ms se usan as como una breve descripcin de su contenido.
<stdio.h> para uso de funciones de entrada/salida standard.
<iostream.h> para uso de funciones de entrada/salida por flujos.
<conio.h> para uso de funciones de entrada/salida por teclado o
consola
<alloc.h> para la asignacin dinmica de memoria
<graphics> para uso de funciones relacionadas con grficas
<io.h> para uso de funciones de entrada/salida de bajo nivel
<math.h> para uso de funciones matemticas.
<mem.h> para uso de funciones de manipulacin de memoria.
<string.h> para uso de funciones relacionadas con cadenas
<time.h> para uso de funciones de hora y fecha.
Para definir un archivo de cabecera se usa una directiva de
preprocesamiento llamado #include seguido del archivo de cabecera
encerrado entre signos < > segn el lugar donde este se encuentre, de
esta forma el compilador incluir durante la compilacin las variables,
constantes y funciones que se encuentren en el archivo y que sean usados por
el programa en desarrollo.
En la seccin de definicin de constantes y variables globales se encuentra
otra directiva de preprocesamiento conocido como #define que permite
definir la constante, observe que despus del identificador PI no existe un
signo =, aunque el significado es que el identificador PI toma el valor de
3.1416, para la definicin de las variables globales basta con indicar su tipo de
dato y el identificador seguido de punto y coma, aqu se define Area de tipo
real (float), recuerde que una variable global perdura a lo largo de la ejecucin
de todo el programa y puede ser vista, modificable desde cualquier parte del
programa o funcin.
En la seccin de definicin de funciones del usuario se requiere
definir todas las funciones que se implementen por el programador, por que
solo de esta forma el compilador puede conocer de forma adelantada la
existencia de los mismos, es decir antes de llamar a una funcin primero el
compilador necesita saber de su existencia en caso contrario no podra
resolver esta referencia provocando un error en tiempo de compilacin, el
lenguaje C es un lenguaje estructurado lo cual significa que un programa
segn su tamao se dividir en varios mdulos conocidos como funciones, de
esta forma se evita que la funcin principal este saturada de cdigo. En este

10

Programacin C y C++

ejemplo se define solamente una funcin, Area_Cir() sin tipo de retorno


(void) y recibe como parmetro un entero( El radio del circulo).
La funcin principal (main()) es el primero que se ejecuta cuando
inicia un programa, por lo que es indispensable que ste exista, en l se
establece la lgica o secuencia que seguir el programa durante su ejecucin.
Una descripcin de lo que ocurre en el ejemplo es el siguiente:
Se define una variable local Radio de tipo entero
Borra la pantalla
Se Imprimen mensajes en pantalla
Lee un dato de tipo entero almacenndolo en la variable Radio
Llama a la funcin Area_Cir() pasndole como argumento el Radio ledo
Imprime la variable Area calculada en la funcin
Espera la entrada de una tecla para terminar
Como puede observarse el orden de los comandos es el orden o
secuencia en que estos se ejecutan.
Finalmente en la seccin de Implementacin de funciones se tendr
la implementacin de todas las funciones que el programador halla definido
en la seccin correspondiente, en este caso la funcin Area_Cir() solamente
tiene una lnea de cdigo que se encarga de asignar a la variable global Area ,
el resultado de multiplicar 2*3.1416*R*R , si el usuario introdujo un Radio =5
entonces sera: 2*3.1416*5*5.
Si una funcin se define y se llama desde alguna parte del programa y
no esta implementado, se detectara un error en tiempo de enlace y no en
tiempo de compilacin tema que se tratar en la siguiente seccin.

11

Programacin C y C++
COMPILACIN Y LIGADO

Para crear un archivo ejecutable (Cdigo maquina relocalizable) se realiza


mediante dos etapas o tiempos que son: Compilacin y ligado.
Compilacin.- Durante este proceso se examina el o los programas
fuente de la aplicacin, los archivos de cabecera para hallar errores de
sintaxis, de no existir se genera un archivo objeto (.OBJ) por cada programa
fuente.
Ligado.- Durante este proceso se unen todos los programas objetos
del que se conforme la aplicacin, as como los archivos de librera (.LIB)
para formar un solo programa independiente, o programa ejecutable (.EXE).
Para aclarar lo anterior observe la siguiente figura:
Princip.cpp

Archivo2.cpp

stdio.h

conio.h

COMPILACION

Cl.lib

Princip.obj

Archivo2.obj

Mathl.lib

LIGADO
Extern.exe

Figura 1. 1 Proceso de Compilacin y Ligado de un programa en C


La implementacin de las funciones halladas en los archivos de
cabecera predefinidos por el lenguaje se encuentran en libreras (Mathl.lib,
Cl.lib, etc.) incluidos tambin en el software del compilador, por lo que se
integran al programa en tiempo de enlace, es por esta razn que si una funcin
definido por el usuario no esta implementada en el programa ni tampoco en
una librera se detectar en tiempo de enlace.
De lo anterior se deduce entonces que un archivo de cabeceras (*.h) es
diferente de un archivo de libreras (*.Lib), lo cual es muy cierto y veamos
algunas diferencias:
Caracterstica
Archivo de Cabecera
Tipo
Texto
Cuando se usa
Tiempo de Compilacin
Contenido
Definiciones

Archivo de Librera
Binario
Tiempo de ligado
Implementaciones
compiladas

Tabla 1. 1 Diferencias entre un archivo de Cabecera y uno de Librera

12

Programacin C y C++

Es frecuente que se confundan los trminos archivo de librera con


archivo de cabecera, la tabla y dibujo anterior precisamente tiene la finalidad
de hacer notar que son diferentes. Durante la escritura de un programa es
frecuente probar una y otra vez si se esta haciendo lo correcto, para ello se usa
la ejecucin paso a paso de un programa (Depuracin), en ocasiones algunos
archivos de cabecera se cargan en el ambiente de programacin y se debe
tener la precaucin de no modificarlos para no producir incongruencias entre
el archivo de cabecera y el archivo de librera, al final de cuentas estn
directamente relacionados entre si .
TIPOS DE DATOS Y MODIFICADORES
Todo lenguaje de programacin suministra al diseador de software un
conjunto de tipos de datos y un conjunto de instrucciones, el diseador a partir
de estas puede crear nuevos tipos y nuevas instrucciones.
Palabras reservadas
Las palabras reservadas del compilador son todas aquellas palabras que se
usan para especificar tipos de variables, estructuras cclicas, estructuras de
decisin, 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
Tabla 1. 2 Palabras Reservadas del Lenguaje
Las palabras reservadas deben escribirse siempre en minsculas.
Tipos de datos
Un tipo de dato en C es la manera como el compilador almacena la
informacin en la memoria, por ejemplo el sistema operativo MS-DOS es un
sistema de 16 bits, mientras que Windows 98, Windows 2000, Windows NT
son de 32 bits, as que el compilador para cada uno de estos sistemas
operativos almacenara en algunos casos un mismo tipo de dato con longitud
diferente, ms adelante se presenta una tabla de los tipos de datos para un
sistema de 16 bits.

Programacin C y C++

13

C se distingue por ser un lenguaje con demasiados tipos, existen otros


lenguajes como PASCAL que cuentan con unos pocos tipos, esta variedad de
tipos nos obliga a ser demasiado cuidadosos a la hora de usar algunos
operadores de asignacin.
Antes de empezar a describir los tipos disponibles en el lenguaje
estudiemos un poco lo que es una variable.
Las variables siempre pertenecen a un tipo de datos, este tipo de datos
puede ser alguno de los tipos predefinidos por el lenguaje o definido por el
usuario, algunos tipos predefinidos para un sistema de 16 bits son.
Tipos de datos # de Bits
Intervalo
char
8
-127 a 127
int
16
-32768 a 32767
long
32
0 a 4294967295
float
32
Aprox. 6 dgitos de precisin
double
64
Aprox. 12 dgitos de precisin
void
0
Sin valor
Tabla 1. 3 Tipos de Datos Bsicos de un sistema de 16 bits
Midificadores
Los modificadores son palabras reservadas que se le adicionan a los tipos para
modificarles su tamao y/o su rango, estos son:
Signed
unsigned
long
short
Estas son algunas de las combinaciones que se pueden presentar:
Tipo
unsigned char
Char
unsigned int
short int
Int
unsigned long int
long int
Float
double float

# de Bits
Intervalo
8
0 a 255
8
-127 a 127
16
0 a 65535
16
Lo mismo que int
16
-32,768 a 32,767
32
0 a 4,294,967,295
32
-2,147,483,648 a 2,147,483,647
32
3.4E-38 a 3.4E38
64
1.7E-308 a 1.7E308

Tabla 1. 4 Tipos de Datos con modificadores en un Sistema de 16 Bits


Como se puede observar cada tipo tiene un tamao en bits, este tamao
define un rango de operacin que limita los nmeros que se puede almacenar
en una variable. imagnese que se desea disear un programa de nmina que

14

Programacin C y C++

va ha manejar los sueldos de los empleados, piense en el tipo de datos que


usara para la variable sueldo; seguramente pens en un tipo unsigned int, si
observamos la tabla anterior el tipo unsigned int almacena valores entre 0 y
65535, ser el tipo unsigned int el ms apropiado? Bueno tal vez contestar
que no, ya que los sueldos pueden ser superiores a 65535, tal vez el tipo ms
apropiado ser unsigned long que almacena valores entre 0 y 4294967295.
Bueno, pero que pasara si escogiramos el tipo unsigned int para la variable
sueldo, en el momento que almacenemos un valor superior a 65535 el
contenido quedar truncado.
Para el caso de un Sistema Operativo de 32 bits, el compilador
almacenara los datos con tamaos diferentes, este sera el caso:

Tipo
unsigned char
char
unsigned int
short int
int
unsigned long int
long int
float
double float

# de Bits
Intervalo
8
0 a 255
8
-128 a 126
32
0 a 4,294,967,295
16
-32,768 a 32,767
32
-2,147,483,648 a 2,147,483,648
32
Lo mismo que unsigned int
32
Lo mismo que int
32
1.2E-38 a 3.4E381
64
2.2E-308 a 1.8E3082

Tabla 1. 5 Tipos de Datos con moficadores en un sistema de 32 bits


Al examinar la tabla anterior se puede observar que int es lo mismo
que long int mientras que para un sistema de 16 bits estos tienen diferente
longitudes y por lo tanto diferentes intervalos.
Como se deduce en consecuencia que la longitud en bytes de un tipo dato
depende del sistema operativo y del compilador que se use, para conocer con
precisin la longitud en bytes de una variable de un tipo de dato se puede
utilizar el operador sizeof. Por ejemplo:
int x;
x=sizeof(int));

En un compilador operado en el sistema operativo MS-DOS x tomara


el valor de 2, mientras que en Windows 98 el valor de 4.
En este libro con la finalidad de evitar las complicaciones del ambiente
del compilador se abordarn los aspectos bsicos de la programacin estndar
y orientado a objetos usando un compilador que se ejecuta bajo el MS-DOS
(Hasta el capitulo 6), la parte restante del libro estar basado en el ambiente
Windows para conocer la programacin Visual con C++.
Comentarios

Programacin C y C++

15

Un comentario es una secuencia de caracteres utilizada para explicar el cdigo


fuente y no se toma en cuenta durante la compilacin (No se considera como
cdigo). Existen dos formas para definir un comentario:
Secuencia de caracteres encerrados entre los smbolos /* y */
Comienza con los caracteres // y termina al final de la lnea.

Variables
Es una posicin de memoria de cierta longitud segn el tipo de dato cuyo
valor puede ser modificado a lo largo de la ejecucin de un programa .
Sintaxis:
[clase] tipo identificador[,identificador];
Donde:
clase representa un especificador de clase de almacenamiento (se
explica posteriormente).
tipo determina el tipo de variable (char, int, float, etc.)
identificador Indica el nombre de la variable.
Una variable que se declara al inicio del programa es considerada
como variable global y es accesible desde cualquier parte del programa. Por
lo contrario una variable declarada dentro de una funcin se considera como
variable local y es accesible solamente dentro de este.
Cada variable de un programa, debe declararse antes de ser utilizada.
La declaracin consiste en enunciar el nombre de la variable y asociarle un
tipo. El tipo determina los valores que puede tomar as como las operaciones
que con ella pueden realizarse.
Ejemplos:
int Suma, Promedio;
char Car, Nombre[40];

Una variable puede ser inicializada cuando se declara:


char car = \0 ;
int Incremento = 10;
char Archivo[] = Datos.dbf;

Conversin de Tipos de datos


Cuando se trabaja con datos de diferentes tipos es frecuente mezclarlos
durante una expresin o asignacin, a diferencia de otros lenguajes, C realiza
la conversin de tipos compatibles de manera automtica.
Por ejemplo:
int x=92;
//Se declara la variable x de tipo entero inicializndola con 92
char car=x; //car es de tipo carcter y se le asigna el valor de un entero x

En este ejemplo se da la conversin automtica de tipos, es decir a la


variable car se le asigna el carcter \ , que es el equivalente del cdigo
ASCII.

16

Programacin C y C++

Cuando se presenten casos de conversin de tipos se debe tener en


cuenta que es posible la perdida de datos. Supngase que x=256 en lugar de
92, en este caso car tomara el valor de \0, es decir el carcter nulo. Esto se
debe a que un entero es de 16 bits (en MS-DOS) mientras que un char es 8
bits, por lo tanto los 8 bits ms significativos del entero se perdern.
No todos los compiladores soportan la conversin de tipos durante las
asignaciones, algunos solamente lo soportan durante una expresin este es el
caso del C++ Builder, por ejemplo:
int x;
x= Edit1->Text; //Error No se puede convertir una cadena a entero

Como Edit1->Text es una propiedad de tipo cadena (Arreglo de


caracteres) no se puede llevar a cabo la conversin de manera directa, para
solucionar este problema la asignacin se debe realizar de manera indirecta:
x = Edit1->Text*1; //OK La conversin se da en la expresin.

OPERADORES
Los operadores se utilizan para manipular datos: ejecutan clculos, buscan
igualdades, realizan asignaciones, trabajan con variables y se encargan de
muchas otras tareas que los programadores nunca llevan a cabo. En la
siguiente tabla se presentan los de uso ms comn .
Operador

Descripcin
Ejemplo
OPERADORES ARITMTICOS
+
Adicin
x=x+z;
Sustraccin
x=x-z;
*
Multiplicacin
x=x*z
/
Divisin
x=x/z;
%
Modulo o resto
x=x%z;
OPERADORES LGICOS
&&
AND Lgico
if (x&&0xFF)
||
OR Lgico
if (x||0xFF)
NOT Lgico
If (!Soltero)
!
OPERADORES RELACIONALES
==
Igual que
if (x==y)
Diferente que
!=
<
Menor que
>
Mayor que
<=
Menor o igual que
>=
Mayor o igual que
OPERADORES DE CLASE Y ESTRUCT.
::
Resol. de alcance
Punto::Dibujar()
->
Miembro indirecto P->Dibujar();
.
Miembro directo
P.Borar();

Operador

Descripcin
Ejemplo
OPERADORES DE ASIGNACIN
=
Asignacin
x=10;
+=
Asignar y sumar
x+=10;
-=
Asignar y restar
x-=10;
*=
Asignar y multiplicar x*=10;
/=
Asignar y dividir
x/=10;
&=
Asig. operador AND x&=0x02;
|=
Asignar operador OR x|=0x02;
OPERADORES A NIVEL DE BITS
&
AND a nivel de bits
C=A&B;
|
OR a nivel de bits
XOR a nivel de bits
C=AB;

<<
Desp. a la izquierda
B=A<<3;
>>
Desp. a la derecha
C=A>>2;
~
NOT a nivel de bits
A=~D;
OPERADORES DE APUNTADORES
*
Indireccin
Int *Ap;
&
Direccin
x=&Ap;
OTROS
++
Incremento
x++;
-Decremento
x--;

Tabla 1. 6 Operadores de C++ ms usados

17

Programacin C y C++
Prioridad y orden de Procedencia

La prioridad de los operadores define el orden en que se evala una expresin


cuando tiene distintos operadores. C y C++ tienen reglas especficas para
determinar el orden de evaluacin. Lo ms sencillo de recordar es que la
multiplicacin y divisin tienen prioridad sobre la suma y la resta. A partir de
esto, si una expresin no le resulta clara, tampoco lo ser para alguien que lea
el cdigo, por lo que deber utilizar parntesis para hacer ms explicito el
orden de evaluacin. Por ejemplo:
A= x + y 2 / 2 + z;

Tendr un significado distinto dependiendo de cmo se agrupen los


parntesis:
A= x + (y - 2) / (2 + z);

En la siguiente tabla lista los operadores de C y C++ de mayor a menor


prioridad, y describe como se asocia cada operador (de izquierda a derecha o
de derecha a izquierda). Todos los operadores situados entre lneas tienen el
mismo nivel de prioridad.
Nivel
1
2
3
4
5
6
7
8
9
10
11
12
13
14

Operadores
() [] -> :: .
! ~ ++ -- & *
* / %
+ << >>
< <= > >=
= !=
&

|
&&
||
= *= -= *= %= < <= > >= &= = |=
,

Asociatividad
Izquierda Derecha
Derecha . Izquierda
Izquierda Derecha
Izquierda Derecha
Izquierda Derecha
Izquierda Derecha
Izquierda Derecha
Izquierda Derecha
Izquierda Derecha
Izquierda Derecha
Izquierda Derecha
Izquierda Derecha
Derecha Izquierda
Izquierda Derecha

Tabla 1. 7 Prioridad y Asociatividad de operadores de C++


Ejemplos:
a).- 8/4*6
2*6
12
b).- 3/4*6
0*6
0
c).- (float) 2/4
2.0/4
0.5
d).- -3+4% 5/2
-3+4/2
-3+2
-1

8*6/4
48/4
12
3*6/4
18/4
4

28/(3*4)
28/12
2

18

Programacin C y C++

ENTRADA Y SALIDA DE DATOS (ESTNDAR Y FLUJOS)


Prcticamente todos los programas requieren procesar informacin
proveniente de fuentes externas para obtener la solucin de un problema
especfico. Esta informacin constituye los datos de entrada del algoritmo que
definen nuestro programa y es mediante ellos que se obtendr la salida o
solucin correspondiente:
De ah la importancia de proporcionar adecuadamente los valores o
datos de aquellas variables del programa que deba leer la computadora;
adems de la importancia de incluir mensajes en las ordenes de salida que nos
indiquen la naturaleza o nombre de los resultados obtenidos.
El sistema operativo MS-DOS soporta dos mtodos de entrada y salida de
datos que son:
Entrada y Salida Estndar
Entrada y salida por flujos
El sistema operativo Windows la entrada y salida por pantalla lo hace a
travs de un conjunto de controles visuales, los cuales se analizaran
posteriormente. En esta seccin se analizan los dos primeros mtodos.
Entrada y Salida Estndar
Para la entrada y Salida de datos con formato se utilizan dos funciones
hallados en el archivo de cabecera stdio.h : printf() y scanf().
Salida por pantalla
Printf(char *cadena_de_control, Lista_argumentos);
La cadena de control est formada por dos tipos de elementos . El
primer elemento es el carcter que se mostrar en la pantalla. El segundo
elemento contiene especificadores de formato que definen la forma en que se
muestran los argumentos posteriores. El espicificador de formato empieza
con un % y va seguido por el cdigo del formato. Debe haber exactamente el
mismo nmero de argumentos que especificadores de formato y ambos deben
coincidir en su orden de aparicin de izquierda a derecha.
En la siguiente tabla se muestra una gran variedad de especificadores
de formato.
Cdigo

Formato

%c

Carcter

%d

Entero en decimales con signo

%i

Entero decimales con signo

%e

Notacin cientfica

Programacin C y C++
%f

Punto flotante)

%h

Entero corto

%o

Octal sin signo

%s

Cadena de caracteres

%x

Hexadecimal sin signo

19

Tabla 1. 8 Especificadores de Formato


Ejemplo:
printf(El Lado es: %i El Area del Cuadrado es: %f,Lado, Area);

Si la variable Lado=5 por lo tanto la variable Area=25, as el mensaje sera:


El Lado es: 5 El Area del Cuadrado es: 25

Tambin en la cadena de control pueden existir una serie de caracteres


que permitan formatear la salida, conocidos como secuencia de escape
Secuencia de escape
\a
\b
\f
\n
\r
\t
\v
\\

Accin realizada
Alarma
Retroceso
Avance de pagina
Nueva Linea
Retorno de carro
Tabulacin (horizontal)
Tabulacin (vertival)
Barra inclinada

Tabla 1. 9 Secuencias de Escape


Entrada por teclado
Scanf(char *cadena_de_control, Lista_argumentos);
Esta funcin direcciona automticamente la lectura de valores por el
teclado de la microcomputadora. Como se aprecia el formato es idntico al
printf().
El lenguaje C emplea apuntadores en lectura de toda cantidad
numrica debido a que asigna dichos valores a travs de las direcciones de las
variables, por tal motivo los nombres de ellas van precedidas del smbolo &
(con lo que se indica que se usan apuntadores). En el caso de cadenas, los
nombres de las variables son en si mismos apuntadores y no requieren dicho
smbolo.
Ejemplo:

20

Programacin 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);
printf("\n\n SUS DATOS SON: ");
printf("%s %i %4.2f",Nom,Edad,Peso);
getch();
}
La Salida del programa despus de ejecutarla sera:
IDENTIFIQUESE POR FAVOR
NOMBRE: Juvenal
EDAD:
36
PESO:
50.4
SUS DATOS SON:

Juvenal

36

50.40

Observe que al leer las variables Edad y Peso de tipo entero y real
respectivamente se utiliza el operador & que indica direccin, mientras que la
variable Nom que es un arreglo de caracteres (cadena) no lo requiere, la
funcin printf() hace uso frecuentemente de la secuencia de escape \n para
cambiar de lnea, por ejemplo el penltimo printf() hace que se deje una lnea
en blanco.
Existen en el archivo de cabecera stdio.h una serie de funciones que
permiten especficamente leer y escribir datos de tipo carcter y cadena, no es
la finalidad de este libro profundizar en este tema ms sin embargo se
considera necesario conocer de su existencia. En la siguiente tabla se
sintetizan:
Funcin
getchar()
getche()
getch()
putchar()
gets()
puts()

Operacin
Lee un carcter del teclado; espera un salto de carro.
Lee un carcter con eco; no espera un salto de carro.
Lee un carcter sin eco; no espera un salto de carro.
Escribe un carcter en pantalla.
Lee una cadena del teclado.
Escribe una cadena en pantalla.

Tabla 1. 10 Funciones complementarias de E/S

Programacin C y C++

21

Entrada y Salida por flujos


C++ proporciona el archivo de cabecera iostream.h que contiene funciones
que realizan operaciones de Entrada/Salida, este archivo tiene la ventaja sobre
el stdio.h por ser una implementacin orientada a objetos, dos de estos
objetos son: cin y cout. Donde:
cin Usado para entrada de datos
cout Usado para salida de datos
Para el manejo de de estos dos objetos se utilizan dos operadores:
El operador de insercin (<<) transmite sus argumentos situados a la
derecha hacia el flujo cout.
El operador de extraccin (>>) lee informaciones del flujo cin a la
izquierda del operador y las almacena en las variables indicadas a la
derecha.
A manera de ejemplo rescribiremos el programa ES-Estan.cpp pero en
lugar de usar printf() y scanf() se usara cout y cin.
/*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;
cout<<"\n\n SUS DATOS SON: ";
cout<<Nom<<" "<<Edad<<" "<<Peso;
getch();
}
La Salida del programa despus de ejecutarla sera identica al
a salida del programa ES-Estan.cpp

Cuando se lee un arreglo de caracteres como la variable Nom puede


ocurrir que el usuario escriba ms de una palabra (Una lnea), en cuyo caso no
sera conveniente utilizar cin sola, ya que este solamente tomara la primera

22

Programacin C y C++

palabra. Para leer ms de una palabra se puede utilizar la funcin 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 nmero mximo de caracteres que desea leer con getline()
Ejemplo:
cin.getline(Nom, 40); //Se puede almacenar hasta 40 caracteres en Nom

En la penltima lnea se observa que se pueden concatenar varios operadores


<< en una sola lnea. Otro aspecto importante de los flujos, es que los
operadores << y >> efectan automticamente las conversiones necesarias.
Los ejemplos que se mostraran a partir de esta parte del libro en adelante,
usarn el cout y el cin para la entrada y salida de datos en pantalla. Sin
embargo al abordar el tema de la programacin visual se dejar de usar.
ESPECIFICADORES DE CLASE DE ALMACENAMIENTO
Aunque este tema esta ligado ms con el tema de Variables se dejo para esta
seccin porque se requiere de los conocimientos anteriores para comprenderlo
con ms claridad.
Existen cuatro especificadores de clase de almacenamiento soprtados por C:
extern
static
register
auto
Los especificadores le indican al compilador cmo debe almacenar la
variable. La clase de almacenamiento precede a la declaracin de la variable.
Su forma general es:
[clase] tipo identificador[,identificador];

extern

Dado que C permite enlazar juntos mdulos de un programa, compilados por


separado con el fin de acelerar la compilacin y ayudar a la gestin de grandes
proyectos, debe haber alguna forma de hacer conocer a todos los archivos las
variables globales requeridas por el programa, las variables globales se deben
de declarar slo una vez. Si se declaran dos variables globales con el mismo
nombre en el mismo archivo, el compilador imprimir un mensaje de error
indicando que se ha duplicado un nombre de variable, lo que significa que el
compilador no sabe que variable se va ha usar cada vez. Lo mismo ocurre si
declaran todas las variables globales necesitadas por el programa en cada
archivo. Aunque el compilador no dara ningun mensaje de error en tiempo de

Programacin C y C++

23

compilacin , realmente se intenta crear dos o ms de cada variable. El


problema aparecera al intentar enlazar los modulos. El Enlazador mostrara el
mensaje de error Identificador duplicado por que no sabra que variable
usar. La solucin est en declarar todas las variables globales en un archivo y
usar declaraciones extern en los otros.
Ejemplo:
/*Princip.cpp proyecto:exten.prj
*/
#include <conio.h>
#include <iostream.h>

/*Archivo2.cpp proyecto:exten.prj
*/
#include <conio.h>
#include <iostream.h>

float Prom;

extern float Prom; //Ojo

void Promedio();

void Promedio()
{int C1,C2,C3;
cout<<"\nESCRIBA LAS 3
CALIFICACIONES DEL ALUMNO";
cout<<"\n\nI UNIDAD:
";
cin>>C1;
cout<<"\nII UNIDAD:
";
cin>>C2;
cout<<"\nIII UNIDAD: ";
cin>>C3;
Prom=(C1+C2+C3)/3;
}

void main()
{
clrscr();
cout<<"\nCALCULO DEL PROMEDIO DE
CALIFCACIONES";
Promedio();
cout<<"\n\nEl Promedio es:
"<<Prom;
getch();
}
La Salida del programa despus de ejecutarla sera:
CALCULO DEL PROMEDIO DE CALIFCACIONES
ESCRIBA LAS 3 CALIFICACIONES DEL ALUMNO
I UNIDAD: 80
II UNIDAD: 90
III UNIDAD: 100
El Promedio es: 90

El programa anterior esta compuesto por los archivos Princip.cpp y


Archivo2.cpp la variable global Prom se encuentra dafinida en el archivo
Princip.cpp sin embargo se utiliza tambien en el Archivo2.cpp, para indicar
al compilador que se trata de la misma variable se usa el expecificador extern
en su declaracin. Observe que la funcin Promedio() se define unicamente
en Princip.cpp y se implementa en Archivo2.cpp, esto no trae ningn
problema durante la compilacin porque es durante el enlace que se resuelve
la referencia hacia esta funcin.
Tal vez se preguntar pero como se puede lograr que dos archivos
fuentes conformen un solo programa?. Se puede llevar a cabo con cualquiera
de los dos mtodos: El primero consiste en realizar la compilacin y enlazado
mediante la lnea de comandos del MS-DOS el segundo creando un proyecto
de esta aplicacin para que los detalles los efecte el propio ambiente del
software.
El primer mtodo es un tanto rudimentario ya que consume una gran
cantidad de tiempo para llevarlo a cabo, sin embargo el segundo es mucho
ms eficiente y es el que se explicar a continuacin.

24

Programacin C y C++

Creacin de Proyectos
En la mayora de los ambientes de programacin modernos se considera este
mtodo, los pasos a seguir diferirn unos de otros dependiendo del fabricante
y versin, a manera de ejemplo se explicar como se lleva a cabo la creacin
de proyectos usando el Software de Borland ver. 1.0 para MS-DOS, para
poder compilar y enlazar de manera directa y transparente para el
programador el programa Extern.prj. El nombre que se le da a un proyecto
ser el mismo que tendr el programa ejecutable despues de su compilacin y
ligado. Pasos:
1.- Crear un directorio de trabajo estando en el directorio del compilador
C:\tc>md ejerc-I

2.- Ejecutar el programa del compilador


C:\tc>tc
3.- En el ambiente definir como directorio de trabajo el directorio recien
creado
Seleccionar File | Change dir... y escribir en la caja de dialogos c:\tc\ejerc-I y OK

4.- Crear el proyecto, por defauld se guarda en el directorio de trabajo


Seleccionar Project | Open Project escribir en la caja de dialogos extern.prj y
seleccionar el botn OK

5.- Agregar los archivos fuentes al proyecto


Estando en la ventana project oprimir la tecla <Insert> en la caja de dialogos escribir
el nombre del primer archivo fuente: Princip.cpp y seleccionar el boton Add se
observa como el nombre del archivo aparece ahora en la ventana projects, escribir el
nombre del segundo archivo: Archivo2.cpp y seleccionar Add, este proceso puede
seguir para cada archivo fuente que se desee agregar, para el programa anterior con
esto basta.

6.- Escribir el cdigo en cada programa fuente


Para abrir un archivo fuente que pertenesca al proyecto basta con posicionarse
sobre l en la ventana Project y obrimir <Enter> se abre la venta de edicin donde se
podr escribir todo el cdigo necesario como muestra la siguiente figura, no olvide
guardar los cambios que se realizan

Programacin C y C++

25

Figura 1. 2.- Ventana de BorlandC 1.0 para manejo de proyectos


7.- Ejecutar el programa
Con las teclas <Ctrl>+<F9> se compila, enlaza y ejecuta el programa si no
aparecen errores.

static

Las varibles static son variables permanentes dentro de una funcin o archivo
segn si se declaran como locales o globales respectivamente.
Variables static locales
Cuando se aplica el modificador static a una variable local, el compilador crea
un almacenamiento permanente para ella de forma muy parecida que cuando
crea almacenamiento para una variable global. La diferencia clave entre una
variable local static y una variable global es que la variable local static es
una variable local que retiene su valor entre llamadas de funciones.
Ejemplo:
/*Estatic1.cpp */
#include <conio.h>
#include <iostream.h>
void serie();
void main()
{int x;
clrscr();
for (x=0;x<5;x++)
serie();
getch();
}

26

Programacin C y C++

void serie()
{static int cont=0;
//Variable Local
cont=cont+10;
cout<<"\t"<<cont;
}
La salida de este programa ser:
10
20
30
40
50

static

Aunque aun no se ha abordado el tema de la instruccin for se utiliza


en el programa para ilustrar el efecto del especificador static. Cuando se llama
a la funcin serie() por primera vez se crea el espacio de almacenamiento para
la variable cont y se inicializa con 0, la siguienta lnea la incrementa a 10 y es
el primer valor que se visualiza despues de un tabulador, en la siguiente
llamada a la funcin serie() como no se destruye la variable cont este retiene
su valor, al incrementarse durante la segunda llamada a la funcin serie()
ahora tendr 20 y as sucesivamente.
De no definir la variable cont como static (int cont=0; ) cada vez que se llame a
la funcin serie() se creara un espacio para el y al finalizar se destruir por lo
que el resultado sera:
10 10 10 10
10
Las variables static son muy importantes en la creacin de funciones
independientes, ya que existen varios tipos de rutinas que deben preservar su
valor entre llamadas. Si no se permitiera usar static entonces habra que usar
variables globales y las variables globales dejan la puerta abierta a posibles
efectos secundarios.
Variables static globales
Cuando se aplica el modificador static a una variable global, se indica al
compilador que cree una variable global conocida nicamente en el archivo en
el que se declara. Esto significa que aunque la variable es global, las rutinas de
otros archivos no la reconocern ni alterarn su contenido directamente,
estando as libre de efectos secundarios.
Ejemplo:
/*Staticg1.cpp, Static.prj */

/*Staticg2.cpp, Static.prj */

#include <conio.h>
#include <iostream.h>

static int cont; //ojo

void Inicia_Semilla(int i);


int serie();
void main()
{int x;
clrscr();
Inicia_Semilla(0);
for (x=0;x<5;x++)
cout<<"\t"<<serie();
getch();
}

void Inicia_Semilla(int i)
{
cont=i;
}
int serie()
{
cont=cont+10;
return(cont);
}

Programacin C y C++

27

En el archivo Staticg2.cpp se define la variable cont como variable global


static, lo cual impide que se pueda acceder desde otro archivo, este ser vista
y modificada solamente en el propio archivo, por eso se requiere de una
funcin adicional para poder inicializarla desde otro archivo. La salida del
programa ser exactamente igual que el archivo Estatic1.cpp aunque usando
una tcnica diferente.
register
El especificador de almacenamiento register originalmente peda 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 deban de realizarse con mayor rapidez.
Actualmente el estndar ANSI simplemente establece que el acceso al objeto
sea lo ms rpido posible, lo anterior es aplicado a cualquier tipo de dato.
El especificador registers solo puede aplicarse a variables locales y a
los parmetros de una funcin. Ejemplo:
void imprime_Caracter()
{
register int x;
for (x=0; to N; x++)
cout <<leer_puerto();
}

En este ejemplo se imprimen N caracteres en pantalla retornados por


una funcin Leer_puerto(), al definir x con el especificador register el ciclo se
lleva a cabo lo ms rpido que se pueda.
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

Programacin C y C++

EJERCICIOS RESUELTOS
1.- Usando la entrada salida estndar 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();
}

2.- Usando la entrada salida estndar escribir un programa que calcule el


sueldo de un empleado, solicitando su nombre, Nmero de horas trabajadas y
el costo por hora.
/* Sueldo.cpp
# 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();
}

Programacin C y C++

29

3.- Programa que calcula el precio de venta de un artculo . El precio de venta


se calcula aadindole al costo el 120% como utilidad y el 15% de impuesto.
/*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();
}

4. Usando la entrada salida por flujos escribir un programa que lee la


longitud de los lados A y B de un triangulo y calcule la hipotenusa (C),
aplicando el teorema de Pitgoras, C 2 = A2 + B2. o sea:
C2 =

a 2 + b 2.

/* Hipotenu.cpp */
# include <iostream.h>
# include <conio.h>
# include <math.h> //Por las funciones matemticas
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));

cout<<"\n LA HIPOTENUSA ES: "<<C;


getch();

30

Programacin C y C++

5.- Programa que lee una temperatura en grados Fahrenheit e imprime su


equivalente en grados Celsius, kelvin, y Rankine. Donde:
Celsius=(Fahrenheit-32)x5/9,

Kelvin=Celsius+273,

Rankine=Fahrenheit+460.

/*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();
}
6.- Utilizando el especificador extern, escriba un programa compuesto por 2

archivos que calcule el costo total de venta de 3 productos.


En el archivo Venta2.cpp deber leer el precio de los 3 productos
vendidos por un comerciante y calcular el total de ventas que tuvo
En el archivo Venta1.cpp deber imprimir el resultado.
/*Venta1.cpp
Proyecto: Venta.prj */

/*Venta2.cpp
proyecto: Venta.prj */

#include <conio.h>
#include <iostream.h>

#include <conio.h>
#include <iostream.h>

float Vta;

extern float Vta;


externa

void func1();
void main()
{
clrscr();
func1();
cout<<"\n EL TOTAL DE
VENTAS ES:$ "<<Vta;
getch();
}

//Variable

void func1()
{
float a,b,c;
cout<<"INTRODUSCA LOS PRECIOS DE
LOS 3 PRODUCTOS:";
cout<<"\n\nPRIMER PRODUCTO: ";
cin>>a;
cout<<"\nSEGUNDO PRODUCTO:";
cin>>b;
cout<<"\nTERCERO PRODUCTO:";
cin>>c;
Vta=a+b+c;
}

Programacin C y C++

31

7.- Utilizando el especificador extern escriba un programa compuesto por 3


archivos que calcule el inters simple y la deuda de un Prstamo a una taza de
inters en N aos:
En el archivo Banco2.cpp Leer la Inversin, La taza de inters y el
nmero de aos, calculando el Inters simple a partir de estos datos
En el archivo Banco3.cpp calcular la deuda acumulada
En el archivo Banco1.cpp mostrar en pantalla tanto el Inters como la
deuda calculados.
/*Banco1.cpp
proyecto: Banco.prj */

/* Banco2.cpp
Proyecto: Banco.prj */

# include <conio.h>
# include <iostream.h>

# include <iostream.h>
extern float Inversion, Interes;

float Inversion,Interes,Deuda;
void Calcula();
void Calcula2();

void Calcula()
{
float Taza;
int N;
cout<<"\nINVERSION :";
cin>>Inversion;
cout<<"\nTAZA DE INTERES : ";
cin>>Taza;
cout<<"\nCUANTOS AOS: ";
cin>>N;
Interes=Inversion*Taza*N;
}

void main()
{
clrscr();
cout<<"CALCULO DE INTERESES\n\n
";
Calcula();
Calcula2();
cout<<"\nLOS INTERESES SON :
"<<Interes;
cout<<"\n\nLA DEUDA SERIA :
"<<Deuda;
getch();
}
// Banco3.cpp
Proyecto: Banco.prj
extern

float Inversion,Interes,Deuda;

void Calcula2()
{
Deuda=Interes+Inversion;
}

32

Programacin C y C++

EJERCICIOS PROPUESTOS.
1. Elaborar un programa que calcule e imprima el costo de un terreno
cuadrado o rectangular, teniendo como datos la anchura, la longitud en
metros, y el costo del metro cuadrado.
2. Una temperatura en grados centgrados (C) se puede convertir a su
equivalente Fahrenheit (F) con la frmula:
F = 9/5 C + 32 .
Elaborar un programa que lea una temperatura en grados centgrados
y obtenga e imprima la temperatura Fahrenheit equivalente.
3. Elabore un programa que lea un nmero de pies y calcule e imprima su
equivalente en yardas, pulgadas, centmetros y metros, de acuerdo con
las siguientes equivalencias:
1 pie = 12 pulgadas, 1 yarda = 3 pies, 1 pulgada =2.54 cms. , 1 metro =
100 cm.
4. Elaborar un programa que lea el artculo y su costo; la utilidad es el
200% y el impuesto es el 15%; calcular e imprimir el artculo, utilidad,
impuesto y precio de venta.
5. Elaborar un programa que lea dos nmeros enteros y positivos e
imprima la media aritmtica, es decir, el punto medio entre los dos
nmeros.
6. Elaborar un programa que lea el radio (r) de una esfera, calcule e
imprima el volumen y el rea.
Area= 4 r2
Volumen = 4/3 r3
7. Elaborar un programa que lea una cantidad de horas e imprima su
equivalente en minutos, segundos y das.
8.- Elaborar un programa que lea el valor de w e imprima el valor de z.
Z= 1 /

2 e w2/2

9.- Elaborar un programa que lea la cantidad de dlares a comprar y el tipo de


cambio en pesos (costo de un dlar en pesos); calcular e imprimir la cantidad a
pagar en pesos por la cantidad de dlares indicada.
10.- Utilizando el especificador extern, escriba un programa compuesto por 2
archivos que calcule la distancia que recorre la luz en un tiempo dado.
En el archivo Luz2.cpp deber leer el tiempo en segundos y calcular
la distancia recorrida (Distancia = Velocidad* Tiempo)
En el archivo Luz.cpp deber imprimir el resultado.

33

Programacin C y C++

Capitulo 2

Sentencias de control de programa

Sentencias de Seleccin
Sentencias de Iteracin
Sentencias de Salto
Ejercicios

En este capitulo se discute el conjunto de sentencias de control de programa


que el lenguaje C soporta .

34

Programacin C y C++

SENTENCIAS DE SELECCIN
A las sentencia de seleccin tambien se les conoce como sentencia
condicional, entre las que se incluyen if y switch
Muchas sentencias de C se basan en una prueba condicional que
determina la accin que se ha de llaver acabo. Una expresin condicional
tiene como resultado un valor cierto o falso. En C cualquier valor distinto de
cero es cierto, incluyendo los nmeros negativos. El 0 es el nico valor falso.

if, if-else

La sintaxis de esta sentencia es:


if (expresion es verdadera)
{
sentencia_1;
sentencias_2;
}

Si al evaluar la expresin, sta es verdadera se ejecutan las sentencias


del bloque (un bloque comienza con { y termina en }), en caso contrario se
ejecutan las sentencias a continuacin del bloque. La clusula else se puede
aadir a la sentencia if cuando la expresin es falsa y se desean ejecutar
sentencias distintas.
if (expresion es verdadera)
{
sentencia_1;
sentencias_2;
}
else
{
sentencia_11;
sentencias_22;
}

Ejemplo:
/*IF.cpp
Determina si una persona es mayor o menor de edad
usando la Instruccin if*/
#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();
}

Programacin C y C++

35

Si el usuario escribe un nmero menor que 18 entonces se muestra el


mensaje Aun es menor de edad y si escribe un nmero igual o mayor que 18
entonces el mensaje ser Es mayor de edad.
Se pueden anidar if evalundose de arriba hacia abajo tan pronto como
se encuentre una condicin cierta, se ejecuta la sentencia asociada con ella y
se pasa por alto el resto de la escala.
Ejemplo:
/*IF2.cp
Encuentra el mayor de 3 nmeros*/
#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;
cout<<"El Mayor es: "<<Mayor;
getch();
}

switch

La sentencia switch permite evaluar una expresin y tomar diversas acciones


en funcin del resultado de la expresin.
Switch (expresin entera)
{
case constante_1:
sentencia_11;
sentencia_12;
...
break;
case constante_2:
sentencia_21;
sentencia_22;
...
break;
...
default:
sentencia_11;
sentencia_12;
...
}

36

Programacin C y C++

La siguientes reglas se aplican en el uso de la sentencia switch

Expresin entera, puede ser una constante, una variable, una llamada a
funcin o una expresin. La sentencia switch no funciona con datos de
tipo coma flotante
El valor despus de cada etiqueta case debe ser una constante entera o
carcter, como 3 o b, o bien una expresin que se evale a una
constante como a +32.
Necesita utilizar una sentencia break despus de cada conjunto de
sentencias ejecutables. La sentencia break hace que la ejecucin del
programa se reanude despus del final de la sentencia switch actual. Si
no se utiliza la sentencia break, la ejecucin 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 expresin_entera, se ejecutarn las sentencias que vienen a
continuacin de la sentencia opcional default.

Ejemplo:
/*Switch.cpp
Calcula el rea de figuras Geomtricas
usando la Instruccin 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;
case '2': cout<<"\n\n Base:";
cin>>B;
cout<<"\n Altura:";
cin>>H;
Area=(B*H)/2;
break;

Programacin C y C++

37

case '3': cout<<"\n\n Radio:";


cin>>R;
Area=2*3.1416*R*R;
break;
default:cout<<"\n\n OPCION NO VALIDA";
}
if ((op>='1')&&(op<='3'))
cout<<"\n El Area es: "<<Area;
getch();
}
La salida de una ejecucin sera:
CALCULO DE AREAS
1.- RECTANGULO
2.- TRINGULO
3.- CIRCULO
Opcion:2
Base:10
Altura:20
El Area es: 100

Dependiendo de la opcin seleccionada por el usuario ser el conjunto


de sentencias que se ejecuten, si el usuario selecciona la opcin 2 entonces
solicita la Base y la Altura del triangulo almacenando los datos en las
variables B y H respectivamente, calcula el Area con la formula (B*H)/2, en
este punto se interrumpe la secuencia de ejecucin de sentencias por la
presencia de la instruccin break, reanudndose este al final del switch donde
se encuentra la instruccin if que evala si la opcin seleccionada esta en el
intervalo de 1 a 3 para desplegar el contenido del Area calculada. El programa
al no limitar los valores posibles que el usuario puede seleccionar
(Validacin), puede introducir cualquier otro valor diferente de 1, 2 3, en
este caso se ejecuta la sentencia hallada despus del default y al final del
programa no se imprimira el Area.

SENTENCIAS DE ITERACIN
Entre las sentencias de iteracin se incluyen for, while y do-while. Cualquier
sentencia de iteracin tiene tres partes importantes que son: Inicializacin,
condicin e incremento, aunque cada sentencia de iteracin debe usarse
preferente segn la situacin en la mayora de los casos se puede adaptar
cualquiera de las tres a cualquier situacin.

for

Cuando se desea ejecutar una sentencia simple o compuesta, repetitivamente


un nmero de veces conocido, la construccin adecuada es la sentencia for.
for(exp_inicializacin; condicin; expresin_incremento)

38

Programacin C y C++
instruccin;

Cuando se encuentra la instruccin for se ejecuta primero la expresin de


inicializacin, no volviendo a ejecutarse ms. Generalmente esta instruccin
realiza la inicializacin de la variable de control de ciclo. Tras esto se prueba
la condicin. Siempre que condicin se evala como verdadero, la instruccin
o instrucciones dentro del ciclo son ejecutados. Despus de entrar en el ciclo
y ejecutar todas las instrucciones dentro de ste se ejecuta
expresin_incremento. Sin embargo si condicin toma el valor Falso, las
instrucciones dentro del ciclo son ignoradas y la ejecucin contina con la
instruccin al final del ciclo.
Cuando se necesitan ejecutar varias instrucciones dentro del ciclo se
hacen necesarias definir el bloque con las llaves {}
Ejemplo:
/*for.cpp
Efecta ciclos segn Ini, Fin, Inc */
#include <conio.h>
#include <iostream.h>
void main()
{clrscr();
int x, Ini=0, Inc=5, Fin=20; //Probar con otros valores
for (x=Ini;x<Fin;x=x+Inc)
cout<<"\t"<<x;
getch();
}

La salida sera:
0

10

15

El programa efecta un total de 5 ciclos, aunque en este ltimo la condicin se


hace falsa por lo que finaliza, transfiriendo el control a la lnea de cdigo que
lee una tecla. La secuencia de eventos es el siguiente:
No. Ciclo
1
2
3
4
5

x
0
5
10
15
20

condicion
0<20
5<20
10<20
15<20
20<20

Accin
Imprime 0
Imprime 5
Imprime 10
Imprime 15
Fin ciclo for..

Programacin C y C++

39

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 multiplicacin */
#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 sera:
1
2
3
4
5
6

2
4
6
8
10
12

3
6
9
12
15
18

4
8
12
16
20
24

5
10
15
20
25
30

Por cada valor que toma x en el ciclo for externo se efecta 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 condicin se hace falsa dndose 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 condicin del ciclo externo se hace falsa.

while

La sentencia while es un ciclo de verificacin preliminar, esto significa que la


condicin es evaluada antes de entrar a ejecutar las instrucciones dentro del
cuerpo del ciclo. Debido a esto se pueden ejecutar de cero a muchas veces.
while (condicion)
{
instruccin_1;
instruccin_2;
}

40

Programacin C y C++

La inicializacin de un ciclo while por lo regular se realiza antes de ella y el


incremento dentro del bloque.
/*While.cpp
Visualiza nmeros en orden descendente */
#include <conio.h>
#include <iostream.h>
void main()
{int ini=50,fin=0,inc=10;
int x=ini;
//Inicializacin
while (x>fin)
{
cout<<x<<"\t";
x=x-inc;
}
}
La salida sera:
50
40
30
20

//Decremento

10

do-while

Difiere tanto de for como de while en que es un ciclo de verificacin


posterior, es decir al ciclo se entra al menos una vez , y la condicin del ciclo
se prueba al cabo de la primera iteracin. Como los ciclos do-while se
ejecutan como mnimo una vez, es mejor utilizarlos en aquellas aplicaciones
en las que se quiere entrar al ciclo.
do
{
Instruccin_1;
Instruccin_2;
}
while(condicin);

Programacin C y C++

41

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');
//Cdigo adicional
}
while (op!='4');
}
La salida del programa sera:
MENU
1.-Altas
2.-Bajas
3.-Consultas
4.-Salir
Opcion:

En este ejemplo se utilizan dos ciclos do-while anidados. El ciclo exterior


controla la terminacin del programa y el ciclo interior valida la opcin
seleccionada por el usuario, de tal forma que si el usuario selecciona una
opcin distinta a las permitidas (1,2,3,4) se vuelve a leer sin salir del ciclo
interior. Solamente si el usuario selecciona la opcin 4 la condicin del ciclo
exterior ser falsa y finalizar, en caso contrario desplegar nuevamente el
men de opciones.
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 funcin. Se trata de una
sentencia de salto porque hace que la ejecucin vuelva (salte atrs) al punto en
que se hizo la llamada a la funcin.

42

Programacin C y C++
Return (expresin)

Donde: el valor de expresin se devuelve como valor a la funcin.


Se puede usar tantas sentencias return como se quiera en una funcin.
Sin embargo, la funcin termina tan pronto como encuentra el primer return.
Una funcin declarada como void no debe contener una sentencia return. La
funcin exit() definido en el archivo de cabecera stdio.h es parecida a return
aunque este en lugar de afectar a una funcin afecta a todo el programa, ms
adelante en el tema de funciones se podrn apreciar ejemplos.
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 cdigo.
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. Tambin se puede usar para forzar la terminacin inmediata
de una bucle, saltando la evaluacin condicional normal del ciclo.
Cuando se encuentra la sentencia break dentro de un ciclo, el ciclo
finaliza inmediatamente.

Programacin 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

La sentencia continue funciona de una forma algo similar a break. Sin


embargo, en vez de forzar la terminacin, continue, forza una nueva iteracin
del ciclo y salta cualquier cdigo que exista abajo en el bloque.
Ejemplo:
/*continue.cpp
Imprime los nmeros del 0 al 50 que sean mltiplos 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

Programacin C y C++

EJERCICIOS RESUELTOS
1.- Programa para calcula la calificacin final de un alumno, teniendo como
datos N calificaciones parciales (3). Imprime el nombre, la calificacin final y
un comentario de Aprobado si obtiene 70 o ms y Reprobado en caso
contrario.
/*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();

Programacin C y C++

45

2.- En un hotel se hace un descuento del 10% si el cliente se hospeda ms de


5 das, el 15% si se hospeda ms de 10 das y del 20% si se hospeda ms de 15
das. Programa que lee el nmero de das y el precio diario de la habitacin e
imprima el subtotal a pagar, el descuento y el total a pagar.
/*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

Programacin C y C++

3.- Programa que calcula el salario de un empleado, Segn el nmero de horas


trabajadas por semana y el salario por hora. Si el nmero de horas trabajadas
es menor o igual a 40 se paga la cuota normal por hora. Si el nmero de horas
rebasa las 40 horas reglamentarias, el excedente se paga como tiempo extra:
1 a 10 hrs. Extras se paga al doble de la cuota por hora
11 a 20 hrs. Extras se paga al triple de la cuota por hora
21 ms hrs. Extras se paga al cudruple de la cuota por hora
En ningn caso el nmero de horas trabajadas por semana podr ser superior a
80.
/*Salario.cpp */
#include <stdio.h>
#include <conio.h>
#include <iostream.h>
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;
}

Programacin C y C++
4.- Escribir un programa para dibujar un rectngulo en modo texto en la
pantalla, solicitar las coordenadas x1, y1, x2 y y2, segn la siguiente figura:
x1,y1

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;
for (x=x1;x<x2;x++)
//Dibuja Lnea horizontal
{
gotoxy(x,y1);cout<<"";
gotoxy(x,y2);cout<<"";
}
for (y=y1+1;y<y2;y++)
//Dibuja lnea Vertical
{
gotoxy(x1,y);cout<<"";
gotoxy(x2,y);cout<<"";
}
gotoxy(x1,y1);cout<<""; //Para las Esquinas
gotoxy(x2,y1);cout<<"";
gotoxy(x1,y2);cout<<"";
gotoxy(x2,y2);cout<<"";
}

47

48

Programacin C y C++

EJERCICIOS PROPUESTOS.
1.- Elabore un programa para calcular e imprimir el precio de un terreno del
cual se tienen los siguientes datos: largo, ancho y precio por metro cuadrado.
Si el terreno tienen ms de 400 metros cuadrados se hace un descuento de
10%, si el terreno tiene ms de 500 metros cuadrados el descuento es de 17%
y si tiene ms de 1000 el descuento es de 25%.
2.- Una librera 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.
3.- Igual que el ejercicio anterior, pero adems:
Si la cantidad de libros solicitada es mayor que 50, se hace un descuento
adicional de 5%; en caso de ser mayor que 100 el descuento adicional es de
10%.
4.- Elaborar un programa que lea los datos de un estudiante: nombre y tres
calificaciones parciales e imprimir el nombre y la calificacin final de
acuerdo a lo siguiente: Para aprobar el curso, debe tener 70 o ms en cada
una de las tres calificaciones, la calificacin final ser el promedio. En caso
de haber reprobado uno o ms exmenes ordinarios, la calificacin final ser
NA (NO ACREDITADO).
5.- En un almacn de ventas de trajes si se compra uno se hace el 50% de
descuento, si compra 2 el 55%, si compra 3 el 60% y si compra ms de 3 el
65%. Elaborar un programa que lea la cantidad de trajes y el precio unitario
(todos tienen el mismo precio) e imprima el subtotal a pagar, el descuento y
el total a pagar.
6.- Reescriba el programa del ejercicio resulto 1 pero sin usar ciclos
7.- Programa que dibuje una secuencia de N rectangulos (5) a partir de un
rectangulo cuyas coordenadas sean proporcionados por el usuario, los
rectangulos siguientes se irn haciendo ms pequeos en forma proporcional
cada vez.

49

Programacin C y C++

Capitulo 3

Arreglos y Apuntadores

Que son los arreglos


Arreglos unidimensionales
Cadenas
Arreglos bidimensionales
Apuntadores
Punteros y arreglos
Inicializacin de apuntadores
Funciones de asignacin dinmica
Ejercicios

Los arreglos, punteros y cadenas de caracteres son conceptos relacionados en


el lenguaje C, por esta razn se integran en este capitulo.

50

Programacin C y C++

QUE SON LOS ARREGLOS


Un arreglo es una coleccin de variables del mismo tipo que se referencia por
un nombre comn. A un elemento especfico de un arreglo se accede
mediante un ndice. En C todos los arreglos constan de posiciones de
memoria contiguas. La direccin ms baja corresponde al primer elemento y
la direccin ms alta al ltimo elemento. Los arreglos pueden tener una o ms
dimensiones.
ARREGLOS UNIDIMENSIONALES
A los arreglos unidimensionales tambin se les conoce como listas.
Tipo nombre[Tamao];
Tipo nombre[];
Donde: tipo
Indica el tipo de datos de los elementos del arreglo.
nombre Es el identificador del arreglo
tamao Especifica el nmero de elementos del arreglo. El tamao
puede omitirse cuando se inicializa el arreglo, cuando se declara como un
parmetro en una funcin o cuando se hace referencia a un arreglo declarado
en otra parte del programa, es recomendable que el tamao sea definido como
una constante para garantizar no rebasar el lmite del arreglo.
Ejemplo:
#define N 30
int Calif[N];
La declaracin 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 sera Calif[0] y el ltimo elemento Calif[29].
El lenguaje C no checa los lmites 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 tamao. Para un arreglo
unidimensional, el tamao total en bytes se calcula:
Tatal en bytes =sizeof(tipo)*tamao = sizeof(nombre_ arreglo).
Ejemplo:
float Salario[10];
int Tam;
Tam=sizeof (Salario); //Tam=40

Inicializacin de un arreglo

Cuando se crea un arreglo slo se puede utilizar constantes para inicializarlo


e aqu algunos ejemplos:
int Calif[4]={80,90,75,100};
float real[5]={23.45,90.34,70.1,75,10};

Programacin C y C++

51

char Caracter[]={a,b,c,d,e,f};
char Cadena[11]=HOLA AMIGOS;
char Cadena2[]=PROGRAMACIN EN LENGUAJE C;
Para comprender mejor el manejo de los arreglos se presentan a continuacin
algunos ejemplos:
/*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

La asignacin anterior contempla los cuatro elementos del arreglo desde el


ndice 0 hasta el ndice 3, durante la impresin se utiliza la constante N para
limitar el nmero de iteraciones que efecta el ciclo for
/*Arreglo3.cpp.cpp
Determina el nmero 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 nmeros aleat. entre 0 y 100
cout<<" "<<Aleat[x];
}
//Encuentra el nmero mayor en el arreglo
for (x=0;x<N;x++)
if (Aleat[x]>Mayor)
Mayor=Aleat[x];
cout<<"\n\nEl mayor es: "<<Mayor;
}

52

Programacin C y C++

En cada ejecucin del programa la secuencia de nmeros aleatorios cambia, por lo


consiguiente tambin la salida, aqu se presenta una de ellas:
79 24 59 18 41 37 64 3 23 29
El mayor es: 79

/*Arreglo4.cpp
Ordena un arreglo unidimensional en forma ascendente
aplicando el mtodo de seleccin */
#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 posicin 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

El mtodo de ordenacin por seleccin separa el elemento con menor


valor y lo intercambia con el primer elemento. Despus, de los N-1 elementos
se busca el siguiente elemento con menor valor y se intercambia con el
segundo elemento y as sucesivamente. El intercambio contina hasta llegar a
los dos ltimos elementos.

Programacin C y C++

53

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 carcter 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
strcpy(c1,c2)
strcat(c1,2)
strlen(c1,c2)
strcmp(c1,c2)

Funcin

Copia c2 en c1
Concatena c2 al final de c1
Devuelve la longitud de la cadena
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";
L=strlen(Cad);
for (x=L-1;x>=0;x--)
cout<<Cad[x];

//Esta es la cadena
//Longitud de la cadena

getch();
}
La salida del programa es:
OGIMA ALOH

Con la funcin strlen() se calcula la longitud de la cadena, para que en el ciclo


for se inicie a partir del ltimo ndice del arreglo de caracteres,
decrementandolo de uno en uno hasta llegar a cero, en cada ciclo se imprime
un carcter a la vez.

54

Programacin C y C++

/*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:
Donde Estudio el autor de este libro: INSTITUTO POLITECNICO NACIONAL
No Acertaste, l estudio en el: INSTITUTO TECNOLOGICO DEL ISTMO

La lectura de una cadena con la funcin cin.getline() agrega el carcter


cambio de lnea (\n) al final de la cadena por lo que jams abra una
coincidencia con la cadena Concatenada C, en su lugar se usa mejor la funcin
gets() de stdio.h
ARREGLOS BIDIMENSIONALES
El termino dimensin representa la cantidad de ndices utilizados para
referenciar un elemento particular en un arreglo. Los arreglos de ms de una
dimensin se conocen como arreglos multidimensionales. La forma ms
simple de un arreglo multidimensional es el arreglo bidimensional. Para
definir un arreglo Tabla de enteros bidimensional de tamao 5,4 se escribira:
Int Tabla[5][4];
Un arreglo bidimensional puede verse como una tabla, donde el primer
ndice denota el nmero de filas y el segundo el nmero de columnas, as la
declaracin anterior denotara una tabla de 5 filas por 4 columnas.

Programacin C y C++

0
1
2
3
4

0
0
20
40
60
80

1
5
25
45
65
85

2
10
30
50
70
90

55

3
15
35
55
75
95

Tabla[1][2]

Un programa que asigne valores a los elementos del arreglo bidimensional


como en la tabla anterior sera:
/*A_Bidim.cpp
Asigna valores mltiplos 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).
La cantidad de memoria en bytes para almacenar un arreglo
bidimensional, se puede calcular aplicando la siguiente formula.
Tamao en bytes=sizeof(tipo)*tamao del 1er. ndice * tamao del 2. ndice
As la definicin int Tabla[5][4]; requerira: 2*5*4 = 40 Bytes de
memoria.
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

Programacin C y C++

{ clrscr();
int Calif[N][K];
float Prom[N], Aprov;
int x,y, Suma1,Suma2=0;
cout<<"ALUMNO
I
II
III IV\n";
for (y=0;y<N;y++)
{
cout<<y+1;
Suma1=0;
for(x=0;x<K;x++)
{
gotoxy(x*5+10,y+2);
cin>>Calif[y][x];
Suma1=Suma1+Calif[y][x];
}
Prom[y]=Suma1/K;
//Promedio por alumno
Suma2=Suma2+Prom[y];
}
Aprov=Suma2/N;
//Aprovechamiento de grupo
//Visualizacin
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
ALUMNO I II III IV Prom
1
70 85 90 80 81
2
100 90 70 95 88
3
75 80 85 90 82
4
70 85 75 100 82
5
100 100 95 95 97
Aprovechamiento : 86

El programa esta diseado para adaptarse ante el cambio de los valores


de las constantes K y N, si en lugar de 4 unidades se requiere de 5 basta con
modificar este valor y todo funciona a la perfeccin, de igual forma se puede

Programacin C y C++

57

modificar el valor de N, en lugar de 5 alumnos puede modificarse a 10, en el


programa se incluye la instruccin gotoxy() hallado en el archivo de cabecera
conio.h para el control del cursor en la pantalla.
Un programa bien escrito debe reunir la caracterstica anterior para adaptarse ante un
cambio sin ninguna o casi ninguna modificacin en el cdigo.

El lenguaje C permite arreglos de ms de dos dimensiones . El lmite, si lo hay


depende del compilador. La forma general de declaracin de un arreglo
multidimensional es:
Tipo nombre[T1][T2][T3]...[Tn]
Es raro que en algn programa se utilicen los arreglos de tres o ms
dimensiones por la cantidad de memoria que se requiere para almacenarlos.
Ejemplo:
Int Tri[20][10][5];
Requerira de 2*20*10*5 = 2,000 bytes de memoria para almacenarla.
APUNTADORES
Un puntero es una variable que contiene una direccin de memoria.
Normalmente, esa direccin es la posicin de otra variable de memoria. Si una
variable contiene la direccin de otra variable, entonces se dice que la primera
variable apunta a la segunda.

*P

Car

Direccin de
memoria
2C00
2C01
2C02
2C03

Variable en
memoria
2C03

Figura 3. 1.- Una variable apuntando a otra


P es una variable de tipo puntero, que apunta a la direccin de memoria
2C03H, es decir apunta a la variable Car, este ltimo es una variable esttica
que contiene el carcter A.

Declaracin de un Apuntador

Una declaracin de un puntero consiste en un tipo base, un * y el nombre de la


variable. La forma general para declarar una variable puntero es:
Tipo * nombre;
Ejemplo:
int *P;

58

Programacin C y C++

Existen dos operadores especiales de punteros: & y *. El & es un operador


monario (slo necesita un operando) que devuelve la direccin de memoria de
su operando; El *, es el complemento de &, devuelve el valor de la variable
localizada en la direccin que sigue.
Ejemplo:
int x=10,y;
int *P;
P=&x; //Asigna la direccin de x a P
y=*P; //Asigna el cont. de lo apuntado por P a y, o sea 10

Las variables puntero deben apuntar siempre a otra variable de su


mismo tipo, aunque C permite apuntar a una variable de un tipo distinto sin
mensajes de error durante la compilacin en algunos casos, hacerlo sera
incongruente. Ejemplo:
float x=10;
int *P;
P=&x;

//Las variables no son del mismo tipo

Aritmtica de punteros

Existen slo dos operaciones aritmticas que se pueden realizar con los
punteros: la suma(++) y la resta(--). Cada vez que se incrementa un puntero,
apunta a la posicin de memoria del siguiente elemento de su tipo base. Cada
vez que se decrementa, apunta a la posicin del elemento anterior. Con
punteros a caracteres , parece una aritmtica 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
Aritmtica 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 sera:
0x3dc10000 0x3dc10002 0x3dc10004 0x3dc10006 0x3dc10008

Programacin C y C++

59

Al principio el apuntador P apunta a la direccin 0x3dc10000, en el


primer ciclo se incrementa un elemento de tipo entero es decir un incremento
de 2 por lo que ahora apunta a la direccin 0x3dc10002, y as sucesivamente
por cada ciclo.
La direccin inicial de una apuntador no siempre va a ser el mismo en
cada ejecucin del programa, la direccin inicial depender del estado de la
memoria en el momento de la ejecucin, es decir depender del sistema
operativo y los programas de aplicacin cargados. Si al probar el programa
anterior las direcciones no coinciden con los aqu mostrados se debe
precisamente a esta situacin.
El siguiente ejemplo muestra un sencillo programa para manejar una
pila de enteros.
/*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 Sera:
Agregue elementos en la pila, 0 para terminar:
80

60

30
95
50
10
40
Pila Llena
0
Contenido de la pila
10
50
95
30

Programacin C y C++

80

PUNTEROS Y ARREGLOS
Existe una estrecha relacin entre los punteros y los arreglos, considrese el
siguiente fragmento:
int Arr[10], *Ap;
Ap=Arr;
Aqu Ap ha sido asignado a la direccin del primer elemento del arreglo Arr,
por que el nombre de un arreglo sin ndice devuelve la direccin 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 mtodos: La indexacin
del arreglo la aritmtica de punteros, la ventaja del segundo mtodo 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 sera:
10 20 999 40 50 60 70 80 90 100

INICIALIZACIN DE APUNTADORES
Despus de declarar un puntero y antes de asignarle un valor, contiene un
valor desconocido. Si se intenta utilizar el puntero antes de darle el valor ,
probablemente se estrellara no slo el programa sino tambin el sistema
operativo de la computadora.
Un puntero debe ser correctamente inicializado para evitar cualquier
problema, se pueden usar dos mtodos:
Que apunte a una variable esttica
Asignarle memoria dinmica.

Programacin C y C++

61

El primer mtodo consiste en asignarle la direccin de otra variable


previamente definida, ya sea una variable local o global, simple a un arreglo
como en el programa anterior. El segundo mtodo es el que se aborda a
continuacin.
FUNCIONES DE ASIGNACIN DINMICA
La asignacin dinmica es la forma en que un programa puede obtener
memoria mientras se esta ejecutando. A las variables globales se le asigna
memoria en tiempo de compilacin. Las variables locales usan la pila. Sin
embargo, durante la ejecucin de un programa no se pueden aadir variables
globales o locales. Pero hay ocasiones en que un programa necesita usar
cantidades de memorias variables. Por ejemplo: un procesador de textos, una
hoja de clculos, etc.
La memoria dispuesta mediante las funciones de asignacin dinmica
de C se obtienen del montn (La regin de memoria libre que queda entre el
programa y la pila), generalmente contiene una gran cantidad de memoria
libre.
En los programas tradicionales de C, toda asignacin dinmica de
memoria se manipula mediante funciones tales como malloc() y free()
hallados en el archivo de cabecera stdlib.h. La funcin malloc() estable
bloques de memoria, mientras que free() se utiliza para liberar estos bloques
asignados. En C++ se define un mtodo para signar memoria dinmica
utilizando los operadores new y delete.
En el siguiente ejemplo se ilustra un programa para la asignacin dinmica de
memoria en C.
/*As_Dinam.cpp*/
#include <conio.h>
#include <iostream.h>
#include <stdlib.h> //Por las funciones de asignacin dinmica
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
}
El mismo ejemplo pero ahora con new y delete
/*As_Dina2.cpp */
#include <conio.h>
#include <iostream.h>
void main()

62

Programacin 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

El operador new est disponible inmediatamente en C++, de modo que no se


necesita utilizar ningn archivo de cabecera; new se puede utilizar con dos
formatos:
new tipo
Asigna un nico elemento
new tipo[Nmero_elementos]
Asigna un Arreglo.
Siempre que se asigne memoria, es necesario comprobar antes de usar
el puntero, el valor devuelto por new, si no existe memoria disponible, el
operador new proporciona el valor 0 NULL. Ejemplo:
/*As_Dina3.cpp
Verifica la cantidad de memoria dinmica 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

El programa realiza un ciclo for infinito, en cada ciclo asigna 1 Kbyte de


memoria dinmica a la variable Cad , cuando la memoria se agota el operador
new retorna un 0 asignndosele a Cad, y es cuando el ciclo deja de ejecutarse
por la presencia de la sentencia break. El valor de x se muestra en pantalla,
indicando la cantidad de memoria asignada.

Programacin C y C++

63

delete

El operador delete libera la memoria asignada con new.


delete direccin
El operador delete toma como argumento un puntero. El bloque de memoria
apartado por este puntero se libera, es decir, se devuelve al sistema operativo
para que pueda ser reutilizada.

EJERCICIOS RESUELTOS
1.- Un vendedor de equipo de computo desea saber la ganancia total por la
venta de N partes de computadoras. Escribir un programa que lea el costo de
compra de cada uno de los N artculos, calcule el costo de venta agregndole
el 35% de ganancia ms el 15% de IVA sobre el precio de compra y visualice
los resultados en forma de tabla.
/*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 artculo
Iva[x]=CosArt[x]*.15;
//IVA por artculo
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

Programacin C y C++

2.- Programa que lea los nombres de N alumnos y los ordene en forma
ascendente aplicando el mtodo 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]);
}
//Mtodo 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);
}
cout<<"\nLOS NOMBRES ORDENADOS SON: ";
for (x=0;x<N;x++)
cout<<"\n"<<x+1<<" : "<<Nom[x];
getch();
}

3.- Un grupo de 5 asesores desean conocer los promedios finales obtenidos


por N alumnos de cierta especialidad que desean titularse por la opcin VI,
este consiste en un examen escrito y un examen oral. En el examen escrito
cada uno de los asesores registra la calificacin obtenido por el alumno
durante la asesora de su materia, en el examen oral solamente intervienen 3
asesores que dictaminan mediante un conjunto de criterios previamente
establecido la calificacin del alumno. Escribir un programa que muestre en
forma de tabla, cada uno de los alumnos, las calificaciones en la fase escrita,
el promedio en la fase escrita, las calificaciones en la fase oral, el promedio en
la fase oral y el promedio general, e indicar con SI a los alumnos que
aprueben y NO a los alumnos que reprueben. Para poder aprobar el examen
se debe tener un promedio general superior o igual a 80%.

Programacin C y C++

65

/*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

Programacin C y C++

4.- Utilizando apuntadores y asignacin dinmica de memoria construya un


programa para dar de alta una serie de N nmeros, comprobar la existencia de
memoria al hacer la asignacin dinmica, al finalizar el programa mostrar los
nmeros ordenados en forma ascendente utilizando el mtodo de burbuja.
/*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 dinmica
{
cout<<"\nNo existe memoria disponible";
exit(0);
//Finaliza el programa
}
cout<<"DA DE ALTA UNA SERIE DE "<<N
<<" NUMEROS Y LOS ORDENA\n";
for (x=0;x<N;x++)
//Alta de la serie de nmeros
{
cout<<"No. "<<x+1<<": ";
cin>>*Num;
//Asigna el numero
Num++;
//Incrementa el apuntador
}
Num=Num-N;
//Apunta al primer elemento
for (x=1;x<N;x++)
//Mtodo de burbuja
for(y=N-1;y>=x;y--)
if(*(Num+y-1)>*(Num+y))
{
Temp=*(Num+y-1);
//Intercambio de elementos
*(Num+y-1)=*(Num+y);
*(Num+y)=Temp;
}

for (x=0;x<N;x++)
//Imprime el contenido del apuntador
{
cout<<"\n "<<*Num;
Num++;
}
delete(Num);
getch();

Programacin C y C++

67

5.- El Maestro de la materia de Programacin III desea conocer el ndice de


Aprobacin y Reprobacin de su grupo de N alumnos, la calificacin mnima
que se considera como aprobatoria es de 70%. Escribir un programa que lea
las calificaciones del grupo de alumnos visualice el Nmero de alumnos
aprobados, el ndice de aprobacin, el nmero de alumnos reprobados y el
ndice de reprobacin.
/*Indice.cpp */
#include <conio.h>
#include <iostream.h>
#define N 5

//Nmero 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

Programacin C y C++

EJERCICIOS PROPUESTOS
1.- Tomando como base el programa del ejercicio resuelto 1, calcular adems
el Costo total , El IVA total y el Precio de Venta Total de los N artculos.
2.- Ordenar en forma descendente una lista de N Nombres aplicando el
mtodo de Insercin
3.- Igual que el ejercicio 2 pero aplicando el mtodo Shell
4.- Considrese la siguiente secuencia de nombres proporcionados al
programa del ejercicio resuelto 2: Ana, Carlos, Zenaido, Ral, Vctor.
Explique el proceso de ordenamiento.

5.- AGREGAR MAS EJERCICIOS

69

Programacin C y C++

Capitulo 4

Funciones y Estructuras

Funciones
Pase de parmetros
Estructuras
Arreglos de Estructuras
Ejercicios

70

Programacin 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 funcin. Esto se debe a que todos los programas
deben incluir la funcin main(), que es en si misma una funcin. Aunque C++
esta orientada a objetos, las funciones siguen siendo parte de este estilo de
programacin ya que dentro de las clases se hayan un conjunto de funciones,
este tema se tratar ms adelante, en este capitulo se va ha destacar la
importancia de la programacin modular.
La ejecucin de un programa comienza por la funcin main(), cuando
se llama a una funcin, el control se pasa a la misma para su ejecucin; y
cuando finaliza, el control es devuelto de nuevo al mdulo que llamo, para
continuar con la ejecucin del mismo a partir de la sentencia que efectu la
llamada.
Sintaxis:
Tipo_de_retorno Nombre_funcion (Lista de parmetros)
{
cuerpo de la funcin
}
Donde:
Tipo_de_retorno especifica el tipo de valor que devuelve la sentencia
return de la funcin. El valor puede ser cualquier tipo vlido. Si no se
especifica ningn tipo, el compilador asume que la funcin devuelve como
resultado un entero, las funciones que no devuelven ningn valor deben tener
el tipo void. La Lista de parmetros 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 funcin. Una funcin puede no tener
parmetros en cuyo caso la lista de parmetros esta vaca. Sin embargo,
incluso cuando no hay parmetros se requieren los parntesis y la lista de
parmetros puede estar sustituida por void.
Ejemplo:
float Area_Triang(int Base, int Altura)
{
float Area;
Area=(Base*Altura)/2;
return(Area);
}

La funcin Area_Tring retorna un valor real (observe la sentencia


return), y recibe como parmetro dos enteros. Las variables que se definan en
el interior de la funcin son considerados como variables locales, estos
incluyen a los parmetros, por lo que se crean cuando se llama a la funcin y
perduran solamente durante la ejecucin de la misma, destruyndose en el
momento de finalizar, excepto si tienen el especificador static.

Programacin C y C++

71

Llamada a una funcin


La llamada a una funcin tiene la forma:
[Variable=]Nombre_Funcion([Lista de argumentos])
Donde:
Variable.- Especifica la variable donde va a ser almacenado el valor devuelto
por la funcin. La llamada puede prescindir del valor devuelto por la funcin.
Lista de argumentos.- Es la lista de expresiones separados por comas, Los
valores resultantes son pasados a la funcin y asignados a sus
correspondientes parmetros, el nmero de argumentos debe ser igual al
nmero de parmetros definidos en la funcin.
Ejemplo:
A=Area_Triang(10,15);
La llamada a la funcin Area_Triang enva como argumentos los
valores 10 y 15, y se almacenan en las variables Base y Altura
respectivamente que estn definidos como parmetros en la implementacin
de la funcin, dentro de la funcin se realiza el calculo y el resultado se
retorna, asignndosele a la variable A.
PASE DE PARMETROS
Se pueden pasar argumentos a las funciones de dos formas:
Llamada por valor
Llamada por referencia
El primer mtodo copia el valor de un argumento en el parmetro de la funcin. De esta
forma , los cambios en los parmetros en la funcin no afectan a las variables que se usan
en la llamada.

La llamada por referencia copia la direccin del argumento en el


parmetro. Dentro de la funcin se usa la direccin para acceder al argumento
usado en la llamada. Esto significa que los cambios hechos a los parmetros
afectan a la variable usada en la llamada a la funcin.
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);
cout<<x<<" "<<y;

//Llamada por referencia


//Imprime 50 10

72

Programacin C y C++

}
void Intercambio(int *A, int *B)
{
int temp;
temp=*A;
*A=*B;
*B=temp;
}

La funcin Intercambio() recibe como parmetros dos punteros A y B


e intercambia sus contenidos. Desde la funcin main() se encuentran
definidos las variables x, y con los valores 10 y 50 respectivamente, al llamar a
la funcin intercambio se pasan como argumentos sus direcciones,
anteponiendo a cada variable el operador &, al retorno de la funcin los
valores de x, y se encuentran intercambiados.
Cuando se desee modificar el argumento se recomienda efectuar
una llamada por referencia y si no se desea modificar el argumento
entonces se har una llamada por valor.

Pase de arreglos como parmetros

Cuando se usa un arreglo como argumento de una funcin, slo se pasa la


direccin del arreglo, no una copia del arreglo entero. Cuando se llama a una
funcin con un nombre de un arreglo, se pasa a la funcin un puntero al
primer elemento del arreglo, esto significa que la declaracin del parmetro
debe ser un tipo puntero compatible. Existen tres formas de declarar un
parmetro que va a recibir un puntero a un arreglo:
Como un arreglo determinado
Como un arreglo indeterminado (sin tamao)
Como un puntero
Ejemplo:
/*Ar_para.cpp
Lee el salario por da 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
//Definicin de funciones
void Leer(float SD[N]);
void Calcular(float SD[], float SS[]);
void Visualizar(float *SD, float *SS);
float Monto=0;
void main()
{
float SalDia[N], SalSem[N];

//Variable global

Programacin C y C++

73

Leer(SalDia);
Calcular(SalDia,SalSem);
Visualizar(SalDia,SalSem);
getch();
}
void Leer(float SD[N])
//Arreglo como parmetro determinado
{ clrscr();
int x;
cout<<"Proporcione el Salario Diario del Trabajador No. 1 al
"<<N<<"\n";
for (x=0;x<N;x++)
{
cout<<x+1<<" : ";
cin>>SD[x];
}
}
void Calcular(float SD[],float SS[]) //Como arreglo Indet.
{ int x;
for (x=0;x<N;x++)
{
SS[x]=SD[x]*7;
Monto=Monto+SS[x];
}
}
void Visualizar(float *SD,float *SS)
//Como apuntador
{ int x;
cout<<"\nTrabajador S/Diario
S/Semanal";
for (x=0;x<N;x++)
cout<<"\n\t"<<x+1<<"\t"<<SD[x]<<"\t"<<SS[x];
cout<<"
Monto: "<<Monto;
}
La salida del programa sera:
Proporcione el Salario Diario del Trabajador No. 1 al 5
1 : 80
2 : 90
3 : 70
4 : 90
5 : 80
Trabajador S/Diario S/Semanal
1
80
560
2
90
630
3
70
490
4
90
630
5
80
560 Monto: 2870

El ejemplo Ar_param.cpp contiene tres funciones, que ilustran las diferentes


formas de definir una arreglo como parmetro. En cada caso el compilador de
C convierte la definicin apropiadamente para recibir un puntero a entero.
Una explicacin general del programa es el siguiente:

74

Programacin C y C++

En la funcin principal se definen los arreglos SalDia y SalSem de tipo


entero y tamao N (5), estas variables son locales a la funcin principal por lo
que no pueden ser vistas desde otra funcin, cuando se crean los arreglos por
defauld se inicializan con el valor de 0 para cada uno de sus elementos, La
primera funcin que se llama es la funcin Leer(), enviando como argumento
el arreglo SalDia (la direccin de su primer elemento), dentro de la funcin se
le asigna por el usuario desde teclado valores a cada uno de sus elementos, al
retornar de la funcin el arreglo SalDia, ahora ya tiene asignado valores,
mientras que el arreglo SalSem aun no, ambos arreglos son enviados como
argumento a la funcin Calcular(), que utiliza los valores del arreglo SalDia
para calcular el salario semanal y almacenarlos en el arreglo SalSem que ms
tarde sern usados para su visualizacin en pantalla.
Se puede observar en cada implementacin de las funciones que el
nombre de los identificadores de los arreglos difieren del nombre que tienen
desde donde se hacen las llamadas, sin embargo por el hecho de que las
llamadas se hacen por referencia (Una direccin) es posible modificar el
contenido de los argumentos dentro de la funcin.
De las tres formas que se puede declarar un parmetro que va a recibir
un puntero a un arreglo, la ms comn es como un puntero, esto se permite
porque cualquier puntero se puede indexar usando [] como si fuese un
arreglo.
ESTRUCTURAS
Una estructura es un conjunto de datos relacionados entre s y referenciado
bajo un nico nombre. Cada elemento de una estructura recibe el nombre de
Dato miembro.
Sintaxis para la definicin de una estructura:
struct etiqueta{
Tipo varible1;
Tipo variable2;
Tipo variable3;
.
.
.
};
Etiqueta.- Es un identificador de la estructura que va a representar un
nuevo tipo de datos definido por el programador, en el interior se definen cada
uno de los datos miembros (variables), al finalizar la estructura lleva ; que
ndica que es el final de la sentencia.
Ejemplo:
Supngase que se desea contar con informacin de los alumnos de una
Institucin:

Programacin C y C++

75

struct Alumnos{
char N_Ctrl[9];
char Nom[40];
char Dir[40];
char Ciudad[40];
char Tel[15];
int Edad;
};
Hasta el momento solo se ha definido la estructura ms no se ha
declarado una variable de tipo estructura, para hacerlo sera:
Alumnos A;
Cuando se declara una variable de tipo estructura es cuando el
compilador reserva espacio en memoria para almacenar la estructura, la
cantidad de memoria requerida ser igual a la suma de la memoria requerida
por cada uno de sus datos miembros, en este caso se requerira un total de 146
bytes (9+40+40+40+15+2).
La definicin de la estructura representa un nuevo tipo de dato, por lo
que se pueden declarar a partir de ella el nmero de variables que se deseen.
Ejemplo:
Alumnos A2,A3,An;
Los elementos individuales de la estructura se referencan utilizando el
operador . (operador punto). Sintaxis:
Nombre_var_estructura.Dato_miembro;
Por ejemplo, el siguiente cdigo asigna la edad 20 al dato miembro
Edad de la variable estructura A:
A.Edad=20;
El ejemplo completo para asignar y visualizar los datos a una estructura
Alumnos se muestra a continuacin:
/*Estruct.cpp*/
#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

Programacin C y C++

};
void main()
{ clrscr();
Alumnos A; //Definicin de una variable estructura
//Asignacin de datos
strcpy(A.N_Ctrl,"95190205");
strcpy(A.Nom,"Sanchez Lpez Juan");
strcpy(A.Dir,"Av. 5 de Mayo No. 37");
strcpy(A.Ciudad,"Juchitan, Oax.");
A.Edad=20;
//Visualizacin
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 bsicos
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];
Se declara un arreglo de estructura de 5 elementos del tipo Alumnos,
esto reserva 730 bytes (146*5) en memoria RAM para su almacenamiento.
Para acceder a una determinada estructura , se indexa el nombre de la
estructura . Ejemplo:
Al[2].Edad=19;
El cdigo anterior asigna la edad 19 a la estructura 3 de su dato miembro
Edad (Recuerde que los ndices de los arreglos inician con 0)
Parar aclarar el uso de los arreglos de estructura he aqu un ejemplo que
asigna datos a cada uno de los datos miembros de un arreglo de estructura.
/*Estruct2.cpp*/
#include <stdio.h>
#include <conio.h>
#include <iostream.h>
#define N 5
struct Alumnos{
char N_Ctrl[9];

//definicin de la estructura

Programacin C y C++

77

char Nom[40];
char Dir[40];
char Ciudad[40];
char Tel[15];
int Edad;
};
void main()
{ clrscr();
Alumnos Al[N];
//Definicin 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;
}
}

Como N es igual a 5 el arreglo de estructura se crea de 5 elementos, por cada


ciclo que ejecuta la sentencia for se asignan valores a cada uno de los datos
miembros de la estructura, as se asignaran datos a los 5 elementos que
contiene el arreglo de estructura (Al[0],Al[1],Al[2],Al[3] y Al[4]).

Pase de estructuras a funciones

Los ejemplos que se han presentados sobre estructuras y arreglos de


estructuras, se han definido como variables locales a la funcin main() y se
han usado solamente dentro de esta funcin, cuando se requiere usarlos en
otras funciones se requiere de pasar la estructura como argumento a la
funcin. Existen los mismos dos mtodos vistos anteriormente en el tema de
pase de parmetros:
Llamada por valor
Llamada por referencia
Cuando se pasa una estructura como argumento a una funcin por valor, se
pasa una copia de la estructura integra, lo cual significa que todos los cambios
realizados en los contenidos de la estructura dentro de la funcin a la que se
pasa no afectan a la estructura utilizada como argumento.
Ejemplo:
/*Estruct3.cpp */
#include <string.h>
#include <conio.h>
#include <iostream.h>
struct Producto{
char Prod[40];
float Pr_unid;

78

};

Programacin C y C++
int Cant;

void Visualizar(Producto Pr);


void main()
{ clrscr();
Producto P;
strcpy(P.Prod,"Tarjeta Madre Pentium III");
P.Pr_unid=1080;
P.Cant=5;
Visualizar(P);
}

getch();

void Visualizar(Producto Pr)


{
cout<<"\n"<<Pr.Prod;
cout<<"\n"<<Pr.Pr_unid;
cout<<"\n"<<Pr.Cant;
}

//Parmetro por valor

En la funcin main() se crea la variable de estructura P del tipo


Producto y se asignan valores a cada uno de sus datos miembros Prod,
Pr_unid y Cant posteriormente se llama a la funcin Visualizar() y se le pasa
como argumento la estructura P, esto significa que en la funcin Visualizar()
se recibe una copia de la estructura asignndose a la variable Pr para su
impresin en pantalla, si dentro de la funcin se modificara un dato miembro,
no afectara al argumento P , es decir los valores asignados a cada uno de los
datos miembro de P seguiran iguales al retorno de la funcin Visualizar().
Observe la forma en que se define el parmetro de estructura en la
funcin Visualizar(), es la forma general de la definicin de una variable, es
decir primero se escribe el tipo de dato, en este caso es Producto y
posteriormente la variable (Pr), el nombre de la variable como parmetro
puede o no ser diferente del argumento, aunque en ambos casos son
diferentes.
Llamada por referencia.- Cuando se desee modificar el contenido de la
estructura que se usa como argumento en la llamada a una funcin se debe
optar por una llamada por referencia. En este caso se pasa la direccin de
inicio de la estructura a la funcin anteponiendo a la variable el operador &,
dentro la funcin la estructura debe definirse como un apuntador.
Ejemplo:
/*Estruct4.cpp */
#include <string.h>
#include <conio.h>
#include <iostream.h>
struct Producto{
char Prod[40];

79

Programacin C y C++
float Pr_unid;
int Cant;
};
void Leer(Producto *Pr);
void Visualizar(Producto Pr);
void main()
{ clrscr();
Producto P;
Leer(&P);
Visualizar(P);
getch();
}

//Definicn de la variable de

estructura

void Leer(Producto *Pr)


//Parmetro por referencia
{
strcpy(Pr->Prod,"Tarjeta Madre Pentium III");
Pr->Pr_unid=1080;
Pr->Cant=5;
}
void Visualizar(Producto Pr)
{
cout<<"\n"<<Pr.Prod;
cout<<"\n"<<Pr.Pr_unid;
cout<<"\n"<<Pr.Cant;
}

//Parmetro por valor

El ejemplo Estruct4.cpp hace exactamente lo mismo que el ejemplo


Estruct3.cpp con la diferencia de que la asignacin de valores a los datos
miembros de la estructura P se realiza a travs de la funcin Leer()
envindosele como argumento la direccin de inicio de la estructura P, es
decir mediante una llamada por referencia. Observe la forma en que se define
el parmetro de estructura en la funcin Leer(), se define como un apuntador,
para acceder a un dato miembro de la estructura en lugar de utilizar el
operador . ahora se utiliza el operador -> .
Obviamente que si una variable de estructura en lugar de que sea
definido como variable local, se define como variable global, no abra
necesidad del pase de parmetros a la funcin, sin embargo esto trae la
desventaja de degradar la portabilidad del programa o la independencia de la
funcin as como producir posibles efectos secundarios.
Cuando se trate de una arreglo de estructura, la nica forma de pasar la
variable como argumento, es mediante una llamada por referencia. Ejemplo:
Alumnos A[10];
Altas(A);

//Arreglo de estructura
//Llamada por referencia

Se supone que la estructura Alumnos fue previamente definido as que A es un


arreglo de estructura, al usar nicamente el nombre del arreglo sin ndice, en

80

Programacin C y C++

realidad se trata de la direccin de inicio del arreglo, la segunda lnea por lo


tanto es una llamada por referencia, que no debe confundirse con una llamada
por valor, en este caso se trata de un arreglo y en el ltimo una estructura
simple.

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: Nmero de control,
nombre, direccin, ciudad, telfono y edad. En la opcin de altas validar si el
registro esta vaco para proceder y si no indicarlo con un mensaje; en el
proceso de bajas caso inverso. Durante la visualizacin solamente se
mostrarn 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

struct Alumnos{
//definicin de estructura
char N_Ctrl[9];
char Nom[40];
char Dir[40];
char Ciudad[40];
char Tel[15];
int Edad;
};
//definicin de funciones del usuario
void Formatear(Alumnos A[N]);
void Altas(Alumnos A[N]);
void Bajas(Alumnos A[N]);
void Visualizar(Alumnos A[N]);
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');

Programacin C y C++

switch (op){
case '1': Altas(A);
//Llamada por referencia
break;
case '2': Bajas(A);
break;
case '3': Visualizar(A);
break;
}
}

}
while (op!='4');

//formatea todos los registros desde 0 hasta N-1


void Formatear(Alumnos A[N])
{ int x;
for(x=0;x<N;x++)
{
strcpy(A[x].N_Ctrl,"\n");
strcpy(A[x].Nom,"\n");
strcpy(A[x].Dir,"\n");
strcpy(A[x].Ciudad,"\n");
strcpy(A[x].Tel,"\n");
A[x].Edad=0;
}
}
//Da de alta el registro si esta vaco, valida el intervalo
void Altas(Alumnos A[N])
{ int Reg;
do{
do{
clrscr();
cout<<"No. de reg. entre 1 y "<<N<<",0 Para term. :";
cin>>Reg;
}
while (Reg<0 || Reg>N);
if(Reg!=0 )
if(A[Reg-1].Edad==0)
{
cout<<"\nNombre: ";
gets(A[Reg-1].Nom);
cout<<"No. de Control: ";
gets(A[Reg-1].N_Ctrl);
cout<<"Direcin ";
gets(A[Reg-1].Dir);
cout<<"Ciudad ";
gets(A[Reg-1].Ciudad);
cout<<"Telefono: ";
gets(A[Reg-1].Tel);
cout<<"Edad: ";
cin>>A[Reg-1].Edad;
}
else
{
cout<<"\nRegistro Ocupado";
getch();

81

82

Programacin C y C++
}
}
while(Reg!=0);

}
//Da de baja el registro si esta ocupado, valida el intervalo
void Bajas(Alumnos A[N])
{ int Reg;
do{
do{
clrscr();
cout<<"PROCESO DE BAJAS";
cout<<"\nNo. de registro entre 1 y "<<N<<", 0 Para
terminar :";
cin>>Reg;
}
while (Reg<0 || Reg>N);
if(Reg!=0 )
if(A[Reg-1].Edad!=0)
{
strcpy(A[Reg-1].N_Ctrl,"\n");
strcpy(A[Reg-1].Nom,"\n");
strcpy(A[Reg-1].Dir,"\n");
strcpy(A[Reg-1].Ciudad,"\n");
strcpy(A[Reg-1].Tel,"\n");
A[Reg-1].Edad=0;
cout<<"\n Registro "<<Reg<<" dado de baja ";
getch();
}
else
{
cout<<"\nRegistro Vaco";
getch();
}
}
while(Reg!=0);
}
//Visualiza la estructura en forma de tabla si ya fue dada de
alta
void Visualizar(Alumnos A[N])
{ int x,y=2;
clrscr();
cout<<"No. Nombre
No.Ctrl Direccin
Ciudad
Telefono Edad";
for (x=0;x<N;x++)
if (A[x].Edad!=0)
{
gotoxy(1,y);cout<<x+1<<" "<<A[x].Nom;
gotoxy(17,y);cout<<A[x].N_Ctrl;
gotoxy(27,y);cout<<A[x].Dir;
gotoxy(44,y);cout<<A[x].Ciudad;
gotoxy(59,y);cout<<A[x].Tel;
gotoxy(69,y);cout<<A[x].Edad;
y++;
}
getch();

Programacin C y C++
}

83

84

Programacin C y C++

2.- Programa que simule un cajero automtico de un banco. Al iniciar el


programa presentar una pantalla con las siguientes opciones: Deposito,
Retiro, Saldo y Salir. El saldo inicial deber ser igual a $2,500.00. Despus de
realizar un deposito y un retiro se mostrar el saldo actualizado, verificando
que no se permita retirar una cantidad superior al saldo, si esto ocurre se
deber mostrar el mensaje correspondiente.
/*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.- Depsito";
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');
}
void Deposito()
//Proceso de Deposito
{int Cant;
clrscr();
cout<<"BIENBENIDO A LA OPCION DE DEPOSITO";
cout<<"\n Cantidad: ";
do{
cin>>Cant;
}
while(Cant<=0);
Sal=Sal+Cant;
Saldo();
}

Programacin C y C++

85

void Saldo()
//Visualiza el Saldo
{
clrscr();
cout<<"EL SALDO ES: "<<Sal;
getch();
}
void Retiro()
//Proceso de Retiro
{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();
}

3.- Una institucin de nivel superior cuenta con 6 carreras especialidades,


cada especialidad puede tener un mximo de 13 grados semestres y desea
llevar el control de alumnos para manejar los datos tales como nombre del
alumno, edad, especialidad y grado. Escribir un programa que permita dar de
alta una poblacin de N alumnos y consultas por especialidad y grado.
/*Escolar.cpp */
#include <string.h>
#include <iostream.h>
#include <conio.h>
#include <stdio.h>
#define N 5
//Poblacin de alumnos
#define G 13
//Grado semestres permitidos
#define C 6
//Carreras Especialidad
struct Est{
char Nom[40];
int Edad;
int Esp;
int Grado;
};
Est E[N];
void
void
void
void

//Variable global.-

Altas();
Grado();
Especialidad();
Inicializa();

Arreglo de estructura

86

Programacin 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 direccin de inicio
break;
case '2':Grado();
break;
case '3':Especialidad();
break;
}
}
while (op!='4');
}
void Inicializa() //Inicializa la estructura
{ int x;
for (x=0;x<N;x++)
{
strcpy(E[x].Nom,'\0');
E[x].Edad=0;
E[x].Esp=0;
E[x].Grado=0;
}
}
void Altas()
//Proceso de Alta
{ int reg;
do{
clrscr();
cout<<"PROCESO DE ALTAS";
cout<<"\n Registro del 1 al "<<N<<"
do{
cin>>reg;
}
while (reg>N || reg<0);
if (reg!=0)
{
reg--;
if (E[reg].Edad==0)
{
cout<<"\nNombre: ";
gets(E[reg].Nom);
cout<<"Edad: ";

0 para terminar: ";

Programacin C y C++
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);
}
void Grado()
//Consulta por Grado
{ int gr,x;
clrscr();
cout<<"CONSULTA POR GRADO";
cout<<"\n GRADO DEL 1 al "<<G<<" : ";
do{
cin>>gr;
}
while (gr>G || gr<0);
cout<<"\nLOS ALUMNOS DEL "<<gr<<" GRADO SON:";
cout<<"\n\nNombre
Edad
Especialidad";
for (x=0;x<N;x++)
if (E[x].Grado==gr)
cout<<"\n"<<E[x].Nom<<"\t\t"<< E[x].Edad<<"\t\t"<<
E[x].Esp;
getch();
}
void Especialidad()
//Consulta por Especialidad
{ int es,x;
clrscr();
cout<<"CONSULTA POR ESPECIALIDAD";
cout<<"\n\n ESPECIALIDAD DEL 1 al "<<C<<" : ";
do{
cin>>es;
}
while (es>C || es<0);
cout<<"\nLOS ALUMNOS DE LA ESPECIALIDAD "<<es<<" SON:";
cout<<"\nNombre
Edad
Grado";
for (x=0;x<N;x++)
if (E[x].Esp==es)
cout<<"\n"<<E[x].Nom<<"\t\t"<< E[x].Edad<<"\t\t"<<
E[x].Grado;
}

getch();

87

88

Programacin C y C++

EJERCICIOS PROPUESTOS.
1.- Complementar el ejercicio resuelto Cajero.cpp para que ante un deposito
la cantidad no rebase los $3,000.00 y ante un retiro no sea superior a
$2,000.00 en cada proceso.
2.- Complementar el ejercicio resuelto Escolar.cpp para que adems de las
opciones que maneja contenga la opcin de Bajas.
3.- Rescribir el programa Alumnos.cpp , con un ligero cambio: En lugar de
que la variable de tipo estructura sea una variable local a la funcin main()
que sea una variable global.
4.- En una tienda de videos se desea llevar el control de las pelculas para
tener a la mano los siguientes datos: Titulo, duracin, mes y ao de compra.
Escribir un programa que una vez dado de alta cada una de las N pelculas, los
muestre ordenados por su fecha de compra.
5.- Programa para calcular el rea de las siguientes figuras geomtricas:
Rectngulo, Circulo, Trapecio. Por cada figura se contar con una funcin
que retornar el rea calculada, usar un men de opciones.
6.- Una tienda de ferretera desea contar con informacin de los artculos que
vende tales como: Nombre, Precio unitario y Existencia, Si la existencia esta
por debajo del punto de pedido (PP = 3), deber generar una ficha de compra
que contenga los Nombres y cantidades (PP + 6) de artculos que desea
adquirir.

89

Programacin C y C++

Capitulo 5

Programacin Orientada a Objetos

Que es la POO
Definicin de una clase
Tipos de Accesos a una clase
Tipos de Usuarios
Relacin entre Usuarios y Tipos de
Accesos
Clases Amigas
Datos Estticos
Constructores y Destructores
Ejercicios
La programacin Orientada a Objetos a revolucionado la tcnica del
anlisis y diseo de programas, la mayora de lenguajes de
programacin actuales utiliza esta tcnica, de aqu la importancia de
conocerlo. En esta unidad y el siguiente se abordan los conceptos
bsicos para poder utilizarlo.

90

Programacin C y C++

QUE ES LA POO
La Programacin Orientada a Objetos es una tcnica o estilo de programacin
que utiliza objetos como bloque esencial de construccin. En la programacin
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 mtodos .
Un objeto tiene tres propiedades que son: Estado, Comportamiento e
Identidad, El estado es el valor que guardan los datos miembros en un
instante dado, el comportamiento esta definido por el conjunto de funciones
miembro que tenga el objeto, es decir la serie de operaciones que se pueden
realizar con l, la identidad es lo que hace un objeto diferente uno de otro.
Ejemplo:
Objeto
Datos
Funciones
Persona
Nombre
Comer()
Ciudad
Trabajar()
Edad
Dormir()
Peso
Si los datos miembros tienen asignados valores tales como:
Nombre = Juvenal, Ciudad = Juchitan, Oax., Edad = 35 y Peso = 50
representaran en su conjunto el estado del objeto. Las tres funciones seran el
comportamiento que pudiera tener ese objeto, finalmente el objeto Persona es
muy amplio por que podramos hablar de: Amelia, Daniel, Ranulfo, etc. Cada
una de esta personal son distintas unas de otra y por tanto representaran la
identidad. En el lenguaje C la identidad bsicamente estara definida por un
bloque de memoria, en cada bloque de memoria se almacenara un objeto
distinto.
Los datos y las funciones se encapsulan en una nica entidad, conocida
como clase (class) en el lenguaje C.
DEFINICIN DE UNA CLASE
Una clase es un estructura de datos definido por el programador que adems
de contar con datos miembros, contiene tambin funciones miembros, es por
ello que se dice una clase es la evolucin de una estructura.
Sintaxis:

Programacin C y C++

91

Class Nombre{
Dato_miembro1;
Dato_miembro2;
...
funcin_miembro_1();
funcin_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
definicin 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:
Empleado E; //Definicin de un Objeto de la clase Empleado.
Observe la sintaxis que es exactamente igual que la sintaxis para la definicin
de una variable, en el tema de estructuras se observaron varios ejemplos
similares.
Un objeto es por lo tanto una variable de un clase en particular. Para acceder a
un dato miembro de la clase o a una funcin miembro de la clase se usa el
operador . (operador punto) al igual que una estructura si el objeto es esttico
y si es un puntero entonces se usa el operador -> (Operador flecha).
Podra pensarse que para asignar el valor de 1500 al dato miembro Salario se
podra realizar de la siguiente manera:
void main()
{
Empleado E;
//Definicin 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

Programacin C y C++

TIPOS DE ACCCESOS A UNA CLASE


Existen tres niveles de privilegio de acceso que se asocian con una palabra
reserva que son:
Tipo de Acceso Palabra reservada
1.- Privado
private
2.- Protegido
protected
3.- Publico
public
Tabla 5. 1 Tipos de Acceso de una clase
TIPOS DE USUARIOS
El cdigo de un programa puede hallarse en diferentes puntos y segn
el lugar donde se encuentre se le conoce como una clase de usuario, que puede
ser:
La propia Clase
Clases derivadas
Usuarios genricos
Toda funcin que se encuentre definido dentro de una clase se le conoce
como usuarios de la propia clase, y las funciones que se encuentren en una
clase derivada (Se trata en el tema de Herencia) se les conoce como usuarios
de la clase derivada, finalmente una funcin que no pertenezca ni a la propia
clase ni a una clase derivada se le conoce como usuario genrico, tal es el
caso de la funcin main() o cualquier otra que se utilice en el programa como
complemento del mismo.
RELACIN ENTRE USUARIOS Y TIPOS DE ACCESOS
Una vez que se conocen los diferentes tipos de usuarios y los tipos de
acceso, se puede establecer la relacin entre los tipos de usuarios y los tipos
de acceso, como se muestra en la siguiente tabla.
Tipo de Acceso

Tipos de Usuarios
La propia Clase
Clases derivadas
Usuarios gener.
*
Private
*
*
Protected
*
*
*
Public
Tabla 5. 2.- Relacin entre usuarios y tipos de accesos
La tabla se puede interpretar de la siguiente forma, Los usuarios que
son considerados como la propia clase tendrn privilegios sobre todos los
datos y funciones miembros de la clase, independientemente del tipo de
acceso, los usuarios de clases derivadas solamente tendrn privilegios sobre
los datos y funciones miembros que tengan el acceso del tipo protected y

Programacin C y C++

93

public, finalmente los usuarios genricos tendrn privilegio sobre los datos y
funciones miembros que tengan el tipo de acceso public.
Tener privilegios sobre un dato o funcin miembro, significa poder
usarlos. Ahora se puede entender por que el objeto que se define en la funcin
main() no puede directamente acceder a un dato miembro de la clase si este
dato tiene el tipo de acceso private. Para poder tener el privilegio se requiere
definir un tipo de acceso public.
En la practica por lo regular se acostumbra definir a los datos
miembros de la clase con el tipo de acceso private y a las funciones miembros
como public y la forma de acceder a los datos como usuario genrico se hace
a travs de las funciones miembros.
Ejemplo:
/*Clase.cpp */
class Empleado{
char Nom[40];
float Salario;
public:
void Asignar(char *N,float S);
void Calcular();
};
//falta implementacin de funciones miembros
void main()
{
Empleado E;
E.Asignar("Juan Prez",120);
}

En la definicin de la clase Empleado al principio no se define ningn tipo de


acceso, esto significa que los datos Nom y Salario tienen un tipo de acceso
private y por lo tanto solo se podrn acceder desde la propia clase. Las
funciones Asignar() y Calcular() tienen el tipo de acceso public, es decir se
pueden acceder desde cualquier parte del programa, incluyendo la funcin
main(), sin embargo dentro de la funcin principal despus de crear el objeto y
llamar a la funcin miembro Asignar() mediante la sintaxis conocida pasando
los dos argumentos necesarios, se detecta un error pero ahora en tiempo de
enlace porque ninguna de las funciones se encuentran implementados.
Una funcin miembro de la clase se puede implementar de dos formas:
Implementacin dentro de la definicin de la clase
Implementacin independiente.
La implementacin dentro de la definicin de la clase se realiza
inmediatamente despus de definir la funcin, mientas que un implementacin
independiente se realiza fuera de la definicin de la clase siguiendo la
siguiente regla de sintaxis:

94

Programacin C y C++

Tipo_de_retorno Nombre_Clase::Nombre_Funcion(Lista_de_parmetros)
{
...//Cdigo
}
El siguiente ejemplo muestra la implementacin de la funcin Asignar()
dentro de la clase, y la funcin Calcular() mediante una implementacin
independiente.
/*Clase2.cpp */
#include <string.h>
#include <conio.h>
#include <iostream.h>
class Empleado{
char Nom[40];
float Salario;
public:
//implementacin dentro de la clase
void Asignar(char *N,float S) {strcpy(Nom,N);Salario=S;}
void Calcular();
};
//Implementacin independiente
void Empleado::Calcular()
{ float S;
S=Salario*7;
cout<<"El salario Semanal de: "<<Nom<<" :"<<S;
}
void main()
{ clrscr();
Empleado E;
E.Asignar("Juan Prez",120);
E.Calcular();
}
La salida del programa es:
El salario Semanal de: Juan Prez :840

En general se recomienda una implementacin dentro de la clase


cuando el cdigo de la funcin es pequeo (de 1 a 4 lneas de cdigo), y la
implementacin independiente cuando el cdigo asociado a la funcin es ms
grande.
En el programa clase2.cpp se implementa dentro de la clase Empleado
la funcin Asignar() que recibe como parmetro el nombre y el salario de un
empleado, mediante un puntero a carcter N y un dato real S ambos son
asignados a los datos miembros Nom y Salario respectivamente. Observe
como los datos miembros que tienen acceso privado pueden accederse desde
una funcin que se encuentra en la misma clase. Por otro lado la funcin
Calcular() se implementa de manera independiente , este calcula el salario
semanal a partir del salario diario asignado previamente al dato miembro

Programacin C y C++

95

Salario guardando el resultado en una variable local S que se utiliza para la


visualizacin en pantalla. Las variables locales de una funcin miembro de
una clase no son considerados como datos miembros de la clase.
Las funciones de la clase se pueden llamar desde cualquier otra parte
en el orden que el programador decida o convenga, as en la funcin main()
primero se llama a la funcin Asignar() para que los datos miembros se
inicialicen y posteriormente a la funcin Calcular() que calcula y visualiza el
resultado. Recuerde que para acceder o llamar a una funcin miembro de una
clase se usa el operador . si el objeto es esttico y el operador -> si es
dinmico, el programa Clase2.cpp usa el operador . para llamar a una funcin
miembro por que el objeto se define como una variable esttica. El siguiente
fragmento de cdigo muestra el mismo programa solamente que ahora en la
funcin mian() se define el objeto como una variable de tipo puntero
(dinmico).
/*Clase3.cpp */
void main()
{ clrscr();
Empleado *E;
E->Asignar("Juan Prez",120);
E->Calcular();
getch();
}

CLASES AMIGAS
Una clase puede conceder privilegios de acceso a sus zonas privadas a
otra funcin o clase. Tal acceso se debe indicar explcitamente declarando la
otra clase o funcin miembro del tipo amiga (friend). Las amigas se tratan
como si fueran miembros de la clase, y tienen acceso no restringido a las
zonas privadas y publicas de los objetos.

Funciones amigas

Una funcin amiga es una funcin 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 definicin de
la funcin. Sintaxis:
Classs Nombre_clase{
...
friend tipo_retorno Nombre(Lista de parmetros);
...
}
Ejemplo:

96

Programacin 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);
};
//Implementacin de funcin amiga
void f1(Prueba *Obj, int a)
{
Obj->z=a;
}
void main()
{ clrscr();
Prueba P;
f1(&P,20);
cout<<P.Verz();
getch();
}

//Definicin del objeto


//Llamada a la funcin amiga

Como la funcin f1() se declara como amiga de la clase Prueba se


puede acceder al miembro privado z. Se puede apreciar en la implementacin
de la funcin f1() que no obedece a la regla de sintaxis para la implementacin
independiente de una funcin miembro de la clase, precisamente porque una
funcin amiga no es una funcin miembro de la clase. Este es solo un
mecanismo para conceder con todos los derechos sobre los datos y funciones
miembros privados y pblicos de la clase.
Para poder acceder a los datos miembros privados de una clase en una
funcin amiga se requiere pasar como argumento un objeto de asa clase para
que a travs de l se pueda acceder al dato miembro privado, por ello la
funcin f1() tiene como parmetros un puntero a un objeto de la clase Prueba
y un dato de tipo entero.
Las razones fundamentales para utilizar funciones amigas es que
algunas funciones necesitan acceso privilegiado a ms de una clase.
Si todas las funciones miembro de una clase son funciones amigas de
una segunda clase, entonces la segunda clase debe definirse como amiga de la
primera. Sintaxis:
Classs Nombre_clase{
...
friend class nombre_clase;
...
}

Programacin 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 ESTTICOS
Un dato miembro esttico significa que existe solo una instancia de ese
miembro y es compartido por todos los objetos de una clase , existe incluso si
se define ningn objeto de esa clase. Para definir un dato miembro esttico se
le antepone a la definicin de la variable la palabra reservada static.
A un dato miembro esttico se le asigna una zona fija de
almacenamiento en tiempo de compilacin, 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 esttico
int v;
public:
void asignac(int c){Cont=c;}
void asignav(int x){v=x;}
int verc(){return Cont;}
int verv(){return v;}
};
int Datos::Cont;

//Definicin del dato miembro esttico

void main()
{ clrscr();
Datos d1,d2;
//Creacin 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 funcin 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

Programacin C y C++

valor para el dato miembro esttico, 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 nmero 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
travs de funciones constructores y un mecanismo correspondiente para
destruir objetos cuando ya no se necesitan dentro de su mbito a travs de una
funcin destructor.
Los constructores y destructores son funciones miembros especiales
que contienen la mayora de las clases. Las clases pueden declarar uno o ms
constructores para inicializar automticamente los objetos de las clases. Las
clases pueden tambin 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

Un constructor es una funcin que permite inicializar los datos miembros


cuando se crean el objeto. Se caracteriza por:
Tener el mismo nombre de la clase que inicializa
No retornar ningn valor
Puede admitir parmetros como cualquier otra funcin
Pueden existir ms de un constructor, e incluso no existir
Si no se define ningn constructor de una clase, el constructor genera uno por
defecto. El constructor por defecto no tiene parmetros y simplemente asigna
ceros a los datos miembros de la clase.
Ejemplo:
/*Const.cpp */
#include <string.h>
#include <conio.h>
#include <iostream.h>
class Producto{
char *Nom;
int
Cantidad;
float Precio;
public:
Producto();
Producto(char *N,int C,int P);
void Ver();
};

//Primer Constructor
//Segundo constructor

99

Programacin C y C++
//Implementacin de funciones miembros
Producto::Producto()
{
Nom=new char[50];
strcpy(Nom,"Ninguno");
Cantidad=0;
Precio=0;
}
Producto::Producto(char *N,int C,int P)
{int L;
L=strlen(N);
Nom=new char[L];
strcpy(Nom,N);
Cantidad=C;
Precio=P;
}
void Producto::Ver()
{
cout<<"\n"<<Nom;
cout<<"\n"<<Cantidad;
cout<<"\n"<<Precio;
}
void main()
{
clrscr();
Producto P,Pro("Disco Duro 20 GBytes",4,1600);
Pro.Ver();
P.Ver();
getch();
}
La salida del programa es:
Disco Duro 20 Gbytes
4
1600
Ninguno
0
0

//2 objetos

El programa Const.cpp consta de una clase llamada Producto con 2


constructores, el primer constructor no tiene ningn parmetro mientras que el
segundo constructor cuenta con tres parmetros, ambos constructores e
inclusive la funcin Ver() se encuentran implementados de manera
independiente, siguiendo la regla de sintaxis ya conocida, observe que
efectivamente los constructores llevan el mismo nombre que la clase, que no
retornan ningn valor, que pueden tener parmetros y que existe ms de uno.
Cuando se define un objeto de la clase Producto, segn el nmero y
tipo de argumentos que contenga, ser la funcin constructora que se llamar,
as en la funcin main() al definir primeramente el objeto P sin ningn
argumento el compilador llama a la primera funcin constructora que

100

Programacin C y C++

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 funcin constructora.
En ambos constructores se asigna memoria dinmica al dato miembro
Nom y no se observa en ningn lugar del cdigo que se libere, de no hacerlo
cada vez que el programa se ejecute desperdiciara este espacio de memoria, el
lugar apropiado para liberar esta memoria es en una funcin destructor, tema
que se trata a continuacin.

Destructores

Un destructor es una funcin miembro con igual nombre que la clase, pero
precedido por una carcter (). Un destructor realiza la funcin opuesta de un
constructor, limpiando el almacenamiento asignado a los objetos cuando se
crean. Las funciones destructores tienen las siguientes caractersticas:
Tiene el mismo nombre que la clase, precedido por una tilde ()
No retorna ningn valor
No tiene parmetros
Una clase solamente puede tener como mximo un destructor.
Se llama automticamente 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
};

Este fragmento de cdigo es una pequea modificacin a la clase


Producto del programa Const2.cpp, se incluye un destructor implementado
dentro de la misma funcin. El programa puede funcionar con el resto del
cdigo sin ningn problema por que el destructor no se debe llamar en
ninguna parte del programa, ms bien el compilador lo llama en forma
automtica cuando los objetos P y Pro salen de mbito, es decir cuando
finaliza la funcin main()

Programacin C y C++

101

EJERCICIOS RESUELTOS
1.- Escribir un programa que cuente el nmero de objetos que se crean a partir
de una clase, usando un dato miembro esttico y un constructor.
/*Estatic2.cpp*/
#include <conio.h>
#include <iostream.h>
class Modelo{
static int Cont;
//Dato miembro esttico
public:
Modelo(){Cont++;}
//Constructor
int VerC(){return Cont;}
};
int Modelo::Cont=0;

//Definicin e inicializacin

void main()
{ clrscr();
Modelo Ob1,Ob2,Ob3;
cout<<Ob1.VerC();

//Visualiza 3

Modelo Ob4,Ob5;
cout<<"\t"<<Ob1.VerC(); //Visualiza 5
}

2.- Programa para dibujar rectngulos en modo texto.


/*Rectang.cpp */
#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;}
};
//Implementacin 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

Programacin 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();
}

3.- Rescribir el ejercicio resuelto Cajero.cpp presentado en el capitulo


anterior pero ahora utilizando las tcnicas de la programacin Orientada a
objetos.
/*Cajero2.cpp */
#include <iostream.h>
#include <conio.h>
class Cajero{
float Sal;
public:
Cajero(){Sal=2500;}
void Deposito();
void Saldo();
void Retiro();
};

//Constructor

//Implementacin de funciones miembros


void Cajero::Deposito()
{int Cant;
clrscr();
cout<<"BIENBENIDO A LA OPCION DE DEPOSITO";
cout<<"\n Cantidad: ";
do{
cin>>Cant;
}
while(Cant<=0);
Sal=Sal+Cant;
Saldo();
//Llamada a una funcin miembro
}
void Cajero::Saldo()
{
clrscr();
cout<<"EL SALDO ES: "<<Sal;
getch();
}
void Cajero::Retiro()

Programacin C y C++
{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.- Depsito";
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');
}

103

104

Programacin 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 asignacin visualizacin
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();
};
//Implementacin 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;
}
//Funcin principal
void main()
{ clrscr();
Hora H(9,14,10); //Creacin de un objeto
H.Ver();
H.Asigna();
H.Ver();
getch();
}

Programacin C y C++

105

5.- Programa que permita convertir nmeros en su forma rectangular a polar.


Crear una funcin que devuelva la magnitud y otra el ngulo en grados
/*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();
};
//Implementacin independiente de funciones miembros
void Complejo::Asignar()
{
cout<<"\ncoordenada en el eje X: ";
cin>>x;
cout<<"Coordenada en el eje Y: ";
cin>>y;
}
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; //Conversin a grados
return(Ang);
//por hallarse en radianes
}
//Funcin 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

Programacin C y C++

EJERCICIOS PROPUESTOS
1.- A partir del ejercicio resuelto 2 (Rectang.cpp) realice las modificaciones
necesarias para dibujar una secuencia de 10 rectngulos en la pantalla
iniciando por uno pequeo, hasta terminar con el ltimo que llene totalmente
la pantalla, repetir este proceso cclicamente hasta que se pulse la tecla <Esc>.
2.- Rescribir el ejercicio resuelto Escolar.cpp y Alumnos.cpp presentado en el
capitulo anterior pero ahora utilizando las tcnicas de la programacin
Orientada a objetos.
3.- Explique que constructor utiliza el objeto creado en el ejercicio resuelto
Hora.cpp, y cual utilizara si se crea el siguiente objeto: Hora H2; en cada
caso que valores toman los datos miembros.
4.- Complementar el ejercicio resuelto Complejo.cpp para que adems de
convertir nmeros en su forma rectangular a polar haga tambin conversin de
polar a rectangular.

Programacin C y C++

107

Capitulo 6

Herencia y Polimorfismo
Clases Derivadas
Herencia Simple y Mltiples
Problema y solucin de la Herencia Mltiples
Constructores y Destructores en clases
Derivadas
Polimorfismo
Sobrecarga de funciones
Funciones virtuales
Clases Abstractas
Ejercicios
La herencia y el polimorfismo son dos caractersticas de la programacin
Orientada a objetos.
La herencia se aplica para extender y reutilizar el cdigo existente por
medio de la creacin 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

Programacin 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. Adems, se puede aadir 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
ms clases. Por lo consiguiente se puede construir jerarquas 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.
Punto
Circulo

Clase base
Rectang

Clases Derivadas

R_Relle

Figura 6. 1.- rbol de herencia


Esta figura se basa en la idea de la herencia, donde cada uno de los
crculos o elipses representan una clase. ndica que las clases Circulo y
Rectang son clases derivadas de la clase base Punto y que a su vez la clase
R_Relle es una clase derivada de la clase base Rectang.
Los programadores de POO pueden crear bibliotecas de clases tiles
que sern el ncleo de muchos programas, como en el caso de los lenguajes
visuales, que ya traen una serie de libreras para el manejo de ventanas,
mens, cajas de dilogos, grficos, bases de datos, etc. El usuario puede
utilizar el contenido de esas bibliotecas de clases para crear nuevas clases o su
aplicacin, minimizando de esta forma el tiempo de desarrollo.
HERENCIA SIMPLE Y MLTIPLES
Dependiendo de cuantas clases bases tenga una clase derivada se pueden
distinguir en el lenguaje C++ como: Herencia simple herencia mltiple.
Herencia Simple
Es aquella en la que cada clase derivada hereda de una nica clase base.
Herencia Mltiple
Es aquella en la cual una clase derivada tiene ms de una clase base

109

Programacin C y C++

En la siguiente figura se muestra un rbol de herencia donde se presentan los


dos tipos de herencia.
A

Herencia Simple
C

Herencia Mltiple

Figura 6. 2.- Herencia simple y Mltiple


La declaracin de una clase derivada tiene la siguiente regla de sintaxis:
class Nombre_Derivada : <Tipo de acceso> clase base{
...
}
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{
private:
int x,y;
public:
...
};

//Clase Base

class Rectang: public Punto{ //Clase derivada


int x2,y2;
public:
Dibujar();
...
};
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
tambin a la clase derivada adems de los propios, as la clase Rectang
contiene los atributos heredados x, y, adems de x2, y2 que son los propios.

110

Programacin C y C++

Tipo de acceso a la clase base


Cuando una clase hereda de otra, la clase derivada hereda los datos y
funciones pblicos y protegidos de la clase base. Por consiguiente, solo tiene
que especificar los datos y funciones adicionales a la clase derivada, sin
embargo segn el tipo de acceso en la derivacin, ser la forma en que se
reciban los datos y funciones miembros en la clase derivada.
Tipo de Acceso
Descripcin
Los tipos de acceso definidos en las clase base son los
:public clase base
mismos en clase derivada
Todos los datos y funciones miembros de la clase base
:private clase base
se convierten en privados para la clase derivada.
:protected clase base Los miembros public y protected de la clase base son
miembros protegidos de la clase derivada. Los
miembros private de la clase base son privados a la
clase derivada.
Tabla 6. 1.- Tipos de Acceso durante la derivacin
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 mayora 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>
class A{
public:
int a1;
};

//Clase Base
//Cambiar a private y compilar

class B:public A{
//Clase derivada
int b1;
public:
void Asignar(int a,int b){a1=a;b1=b;}
void Ver(){cout<<a1<<" "<<b1;}
};
void main()
{
B Obj;
Obj.Asignar(10,20);
Obj.Ver();
}

//Visualiza 10

20

En este ejemplo la clase B se deriva de la clase A con acceso publico. La clase


A solamente tiene el atributo a1 con tipo de acceso publico. Es decir se hereda
desde la clase derivada. Si en lugar de que el tipo de acceso sea publico fuera

111

Programacin C y C++

protegido, tambin se heredara en la clase derivada, sin embargo si se cambia


a privado ya no.
En la implementacin de las funciones Asignar() y Ver() de la clase
derivada B observe como se accesa directamente al dato miembro a1 que
pertenece a la clase base A como si fuera parte de la clase B, esto se puede
hacer porque la clase B hereda el atributo de la clase base A.
En la derivacin privada, los miembros pblicos, privados y protegidos
de la clase base no son accesibles por las funciones miembros de la clase
derivada, ni por los usuarios genricos ni las otras clases derivadas.
En la derivacin protegida los miembros pblicos y protegidos de la
clase base se comportan como miembros protegidos de la clase derivada.
Estos miembros no son accesibles por los usuarios genricos, pero las clases
que se deriven posteriormente podrn acceder a estos miembros normalmente.

Que cosas se heredan y que cosas no

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<<"\nFuncin B";}
};
class D:public B{
public:
void Funcion(){cout<<"\nFuncin D";}
void F2();
};
void D::F2()
{
Funcion();
B::Funcion();
}
void main()
{
clrscr();
D Obj;
Obj.F2();
}

//1a. funcin

//2a. funcin

//Llama a la segunda funcin


//Llama a la primera funcin

112

Programacin C y C++

Una clase derivada hereda todos los datos y funciones miembros de la


clase base excepto los siguientes:
1. Constructores
2. Destructores
3. Funciones amigas
4. Funciones estticas
5. Datos estticos
Si en una clase base de una clase derivada se encuentran cualquiera de los
componentes anteriores se debe tener presente que desde la clase derivada no
se podrn acceder de manera directa.
Ejemplo:
/*NoHeren.cpp */
#include <conio.h>
#include <iostream.h>
class Base{
protected:
int b;
public:
Base(int x){b=x;}
};
class Derivada:public Base{
int d;
public:
Derivada(int x, int y){Base(x);d=y;} //Error No encontrado
void Ver(){cout<<b<<" "<<d;}
};
/*Forma correcta de poder llamar a un constructor
de una clase base
Derivada::Derivada(int x, int y):Base(x)
{
d=y;
}
*/
void main()
{
Derivada Obj(30,50);
Obj.Ver();
}

En la implementacin del constructor de la clase Derivada, se intenta


llamar al constructor de la clase Base, pero el compilador detecta el error por
no poder encontrarlo, la forma correcta de poder llamar a un constructor de
una clase base desde una clase derivada es hacerlo en el constructor de la clase
derivada utilizando el operador : al final de la definicin del constructor como

113

Programacin C y C++

se muestra en el programa NoHeren.cpp. Para poder ejecutar el programa se


debe comentar la implementacin del constructor dentro de la clase y eliminar
el comentario de la implementacin independiente.
Sintaxis de Herencia Multiple
Class Nombre_Derivada : <Tipo de acceso> clase base1, | <Tipo de acceso>
clase base2,|...| <Tipo de acceso> clase basen {
...
}
Ejemplo: Definicin del siguiente rbol de herencia
class A{
};
class B{
};
class C: public A, public B{
};

// Herencia Multiple

En este ejemplo la clase C se deriva de la clase A y B, los atributos que


pudieran tener cada una de las clases base, los tendra tambin la clase
derivada, adems de los propios.
Ejemplo:
/*Multiple.cpp */
#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;}
};
class C:public A,public B{
int c1;
public:
void Asigna(int x,int y,int z){a1=x;b1=y;c1=z;}
void Ver(){cout<<Vera()<<" "<<Verb()<<" "<<c1;}
};
void main()
{
C Obj;
Obj.Asigna(10,20,30);
Obj.Ver();
}

114

Programacin C y C++

PROBLEMA Y SOLUCIN DE LA HERENCIA MLTIPLES


La herencia mltiple puede introducir ambigedades cuando se heredan de
dos clases base que a su vez contiene ambas la misma clase base. Ejemplo:
A

En este caso la clase D hereda de manera indirecta los atributos de la clase A


por dos rutas diferentes, provocando que los atributos de A se creen por
duplicado. El compilador no sabra cual es la copia que se estara
referenciando.
Ejemplo:
/*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 ambigedad
};
void main()
{
D Obj;
Obj.Asignar(10);
}

La clase A contiene el atributo a1 que se hereda por separado a las clases B y


C, hasta aqu todo esta bien, sin embargo cuando la clase D hereda de las
clases B y C el atributo a1 se hereda por duplicado, es por eso que el
compilador detecta el error en la funcin Asignar(). Este problema puede tener
dos soluciones.

115

Programacin C y C++

1. Referenciar el atributo correctamente usando el operador :: en lugar de


hacerlo directamente: Ejemplo: C::a1=x; B::a1=x;
2. Crear una sola instancia de la clase base heredada de manera indirecta.
El aspecto del rbol de herencia para cada una de estas soluciones sera:
A

A
2. Solucin

1. Solucin
D

Aunque las dos soluciones se pueden utilizar, la primera puede


confundir al programador, mientras que la segunda se convierte en la ms
idnea porque elimina totalmente la ambigedad que pudiera existir.
Para implementar la segunda solucin las clases derivadas que
producen la interseccin con la clase base deben heredar virtualmente de
la clase base (Se utiliza la palabra reservada virtual).
Ejemplo:
/*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 ambigedad
};
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 tendran los objetos que
se definan a partir de cada clase.

116

Programacin C y C++

a1,a2

b1

c1

d1

e1

f1,f2

G
g1

a).- Definicin de clases


class A{
protected:
int a1,a2;
};
class B{
protected:
int b1;
};
class C{
protected:
int c1;
};
class D: virtual public A {
protected:
int d1;
};
b).- Atributos de los Objetos

A
T
R
I
B
U
T
O
S

A
a1
a2

B
b1

class E: virtual public A, public B{


Protected:
Int e1;
};
class F: public C{
Protected:
Int f1,f2;
};
class G: public D, public E, public F{
Int e1;
};

C
c1

OBJETOS
D
a1
a2
d1

E
a1
a2
b1
e1

F
c1
f1
f2

G
a1
a2
b1
d1
e1
c1
f1
f2
g1

El ejercicio anterior da algunas ideas sobre el procedimiento para el desarrollo


de programas reales Orientados a Objetos, aunque el orden no es el apropiado.

Pasos para el desarrollo de un Programa Orientada a Objetos

1.- Descripcin de un problema real


2.- Obtencin de los objetos que existen en el dominio del problema
3.- Definicin de los miembros de cada objeto

Programacin C y C++

117

4.- Desarrollo del rbol de herencia


5.- Definicin e implementacin de clases y funciones miembros
6.- Aplicacin que use las clases.
Al finalizar este capitulo se presenta un ejemplo, donde se podr apreciar cada
uno de estos pasos, por lo pronto se continuar con las bases.
CONSTRUCTORES Y DESTRUCTORES EN CLASES DERIVADAS
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. Adems se
dispone de un mecanismo para pasar los valores de los parmetros necesarios
al constructor de la clase base desde el constructor de la clase derivada.
Derivada::Derivada(int x, int y):Base(x)

En este ejemplo el dato de tipo entero x se pasa al constructor de la clase base,


este mtodo se ampla de un modo lgico para el caso de clases base
mltiples.
Derivada::Derivada(int x, int y, int w):Base1(x),Base2(w)

Aqu se llama al constructor Base1 y se le pasa el valor entero x y el


constructor Base2 el valor entero w. Al igual que con herencia simple, los
constructores de la clase base se llaman antes que se ejecute el constructor de
la clase derivada. El orden en que se ejecutan los constructores de las clases
bases, es el orden en que estn listados en la declaracin de la clase derivada.
En el ejemplo anterior primero se ejecuta Base1 y luego Base2.
La relacin entre el destructor de la clase derivada y el destructor de la clase
base se mantiene. El destructor de la clase derivada se llama primero que el
destructor de la clase base. Los destructores de la clase base se llaman en
orden inverso al que los objetos base se crearon.

POLIMORFISMO
El polimorfismo es la propiedad por la cual los objetos que pertenecen a
clases diferentes pueden responder al mismo mensaje (funcin) de diferentes
formas. Por ejemplo, supngase que se dispone de las clase Rectngulo,
Circulo, Triangulo, Cilindro, cuyos objetos representan las figuras
geomtricas, los objetos de estas clases pueden contener una funcin Area()
que calcule el rea correspondiente. Sin embargo la respuesta al mensaje area
ser diferente para cada uno de los objetos. Una caracterstica esencial del
polimorfismo es que se pueden enviar mensajes sin conocer la clase de objeto
recipiente. Por ejemplo se puede tener una lista de los posibles objetos que
pueden aparecer en la pantalla, para visualizar cualquiera de ellos basta con

118

Programacin C y C++

enviar el mensaje Show() para que se visualice, sin tener que preocuparse de
cada objeto de la lista.
En C++, el polimorfismo se implementa por medio de sobrecarga de
funciones y con funciones virtuales.
SOBRECARGA DE FUNCIONES
Consiste en definir dos ms funciones con el mismo nombre aunque con
diferencias en el nmero o tipo de parmetros que reciben, as la funcin que
se llame ser el que coincida con nmero y tipo de argumento. Esto permite
que una funcin se comporte de una forma u otra dependiendo de los
argumentos, de aqu el comportamiento polimrfico. Al permitir que una clase
tenga ms 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

En la clase Matemtico se define la funcin Sumar() sobrecargada (tres


veces), permitiendo sumar dos enteros, dos reales concatenar dos cadenas.
FUNCIONES VIRTUALES
Las funciones miembro virtuales son similares a las funciones miembro
ordinarias con la diferencia importante de que las llamadas a las funciones
virtuales se enlazan dinmicamente (ligadura dinmica) en tiempo de
ejecucin (en lugar de en tiempo de compilacin) a la funcin que llama.

Programacin C y C++

119

En C++ por defecto, las funciones tienen ligadura esttica; si se desea


ligadura dinmica se debe preceder a la declaracin de la funcin la palabra
reservada virtual.
virtual float Area()
La ligadura dinmica tiene sentido en C++, slo para objetos que son
parte de una jerarqua de clases (herencia).

Supngase que se desea un programa para calcula el rea de crculos y


cilindros, aplicando las formulas correspondientes:
rea del Circulo = PI*Radio*Radio
rea del Cilindro = 2*PI*Radio*Altura + 2*PI*Radio*Radio
El rbol de herencia quedara como se muestra en la siguiente figura.
Circulo
Radio;
virtual float Area();

Cilindro
Altura;
virtual float Area();

Figura 6. 3.- Funciones virtuales


El programa completo se muestra en el siguiente listado, conteniendo las
funciones virtuales y el comportamiento polimrfico.
/*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

Programacin C y C++

};
//funcin que proporciona el comportamiento polimrfico
float Area (Circulo Obj)
{
return(Obj.Area()); //Segn el objeto recibido es la funcin
}
// que se llama
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 funcin debe ser
declarada como virtual en la primera clase que esta presente, (en la clase
base). Una funcin virtual es una funcin que se declara en la clase base como
virtual y se redefine en una ms 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 ejecucin a qu
funcin llamar en funcin del tipo de objeto apuntado.

CLASES ABSTRACTAS
Una clase abstracta es aquella que slo 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 funcin vitual pura.
Una funcin virtual pura es aquella cuya declaracin no est seguida
por una implementacin; es decir, que la clase base no puede implementar y
que se inicializan a cero. Sintaxis:
Virtual void func_pura()=0;
El uso de una clase abstracta no es estrictamente necesaria, la ventaja
de una clase abstracta reside en la elegancia de combinar las caractersticas
comunes de una serie de clases especiales en una clase base que no se utiliza
para crear un objeto.
Una clase abstracta se utiliza en los casos donde exista polimorfismo,
partiendo del echo de que las funciones virtuales que existan en el rbol de
herencia solamente se debe definir en la clase base, si esta clase base es una
clase genrica y no se requiere la definicin de objetos a partir de ella
entonces se debe definir como clase abstracta.

Programacin C y C++

121

Ejemplo:
Se desea escribir un programa que maneje los datos de los Alumnos y
Maestros segn la siguiente tabla:

Datos

Funciones

Alumno
Nombre
Direccin
No. de Control
Especialidad
Alumnos()
void Ver()

OBJETOS
Maestro
Nombre
Direccin
Plaza
Departamento
Maestro()
void Ver()

Se aprecia que los datos Nombre y Direccin, as como la funcin Ver() son
comunes a los dos objetos, se puede crear una clase genrica al que se le
llame Persona que contenga estos tres miembros, y con la finalizad de darle el
comportamiento polimrfico definir la funcin Ver() como virtual. En este
caso no se pretende definir ningn objeto de la clase Persona por lo que
deber ser una clase abstracta, o sea la funcin Ver() ser definida como una
funcin virtual pura. El rbol de herencia queda de la siguiente forma.
Persona
Nom, Dir;
virtual void Ver()=0

Alumno
NCtrl, Esp;
void Ver();

Maestro
Plaza, Depto;
void Ver();

El listado del programa es:


/*Abstrac.cpp */
#include <string.h>
#include <conio.h>
#include <iostream.h>
class Persona{
//Clase Abstracta
protected:
char Nom[40];
char Dir[40];
public:
Persona (char *N, char *D){strcpy(Nom,N); strcpy(Dir,D);}
virtual void Ver()=0;
//Funcin virtual pura
};
class Alumno: public Persona{

122

Programacin C y C++

char NCtrl[15];
char Esp[30];
public:
Alumno(char *N,char *D,char *Ct,char *E);
void Ver();
};
//Implementacin de funciones miembros de la clase Alumno
Alumno::Alumno(char *N,char *D,char *Ct,char *E):Persona(N,D)
{
strcpy(NCtrl,Ct);
strcpy(Esp,E);
}
void Alumno::Ver()
{
cout<<"\n\nDATOS DEL ALUMNO";
cout<<"\n"<<Nom;
cout<<"\n"<<Dir;
cout<<"\n"<<NCtrl;
cout<<"\n"<<Esp;
}
class Maestro:public Persona{
char Plaza[30];
char Depto[40];
public:
Maestro(char *N,char *D,char *P,char *Dp);
void Ver();
};
//Implementacin de funciones miembro de la clase Maestro
Maestro::Maestro(char *N,char *D,char *P,char *Dp):Persona(N,D)
{
strcpy(Plaza,P);
strcpy(Depto,Dp);
}
void Maestro::Ver()
{
cout<<"\n\nDATOS DEL MAESTRO";
cout<<"\n"<<Nom;
cout<<"\n"<<Dir;
cout<<"\n"<<Plaza;
cout<<"\n"<<Depto;
}
//Funcin que proporciona el comportamiento polimrfico
void Ver(Persona *P)
//El parmetro debe ser un apuntador
{
P->Ver();
}
void main()
{ //Persona P; //Error no se puede crear un objeto
Alumno A("Juan Prez","Av. Jurez", "93190203", "Informtica");
Maestro M("Juvenal","Av. Hidalgo","Titular A","Sistemas y Computacin");

Ver(&M);

Programacin C y C++

123

Ver(&A);
}
La salida del Programa es:
DATOS DEL MAESTRO
Juvenal
Av. Hidalgo
Titular A
Sistemas y Computacin
DATOS DEL ALUMNO
Juan Perez
Av. Juarez
93190203
Informtica

En la funcin principal main() se puede apreciar en la primera lnea el


intento de definir un objeto de la clase Persona(), pero el compilador detecta
el error por provenir de una clase abstracta, es por ello que aparece
comentado.
Despus de crear los dos objetos A y M con cada uno de los
parmetros requeridos por sus correspondientes constructores, se llama a la
funcin Ver() en dos ocasiones, en la primera se le pasa como argumento la
direccin del objeto M, en la en la segunda llamada la direccin del objeto A,
esta funcin proporciona el comportamiento polimrfico por que segn el
objeto que reciba como parmetro, ser a la funcin que llamar en tiempo de
ejecucin. As primero despliega los datos del maestro y luego los datos del
alumno.

124

Programacin C y C++

EJERCICIOS RESUELTOS
1.- Complementar el ejercicio resuelto Rectang.cpp desarrollado en el
capitulo anterior, para que adems de la clase Rect (Rectngulo) contenga
tambin otra clase deriva que le permita dibujar rectngulos rellenados.
/*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;}
};
//Implementacin independiente de funciones
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<<"|";
}
gotoxy(x1,y1);cout<<"";
gotoxy(x2,y1);cout<<"";
gotoxy(x1,y2);cout<<"";
gotoxy(x2,y2);cout<<"";
}
class RecRell:public Rect{
char Car;
public:
RecRell():Rect(){Car='';}
//Llama al constructor base
void Dibujar();
void Asignar(int x,int y, int j,int k,char c);
};
//Implementacin independiente
void RecRell::Dibujar()
{ int x,y;
Rect::Dibujar();
//A Que funcin se llama?
for (y=y1+1;y<y2;y++)
//rellena el rectngulo
for (x=x1+1;x<x2;x++)
{

Programacin C y C++

125

gotoxy(x,y);cout<<Car;

}
void RecRell::Asignar(int x,int y, int j,int k,char c)
{
Rect::Asignar(x,y,j,k);
Car=c;
}
void main()
{ clrscr();
Rect R;
//Objeto
RecRell Rell;
//Objeto
R.Asignar(10,8,30,16);
R.Dibujar();
//Dibuja
Rell.Dibujar();
//Dibuja
Rell.Asignar(50,8,70,16,177);
Rell.Dibujar();
}

de la clase Rect
de la clase RecRell
un rectngulo
un rectngulo rellenado

2.- Resuelva el siguiente problema, aplicando los pasos para el desarrollo de


un programa orientado a objetos:
Una empresa desea generar fichas de su personal de base y eventual.
Solucin:
Obtencin de objetos: Trabajador de base y Trabajador Eventual
Datos y funciones miembros de los objetos:
TrabajadorBase
TrabajadorEventual
Nombre
Nombre
Datos
Direccin
Direccin
Salario/da
Honorario/hora
Aos de antigedad
Leer()
Leer()
Funciones
Visualizar()
Visualizar()
PagarSalario()
PagarSalario()
rbol de herencia.

TBase
SalDa, Ant;
Leer(); Visualizar();
PagarSalario();

Trabajador
Nom, Dir,
Leer();
Visualizar();

TEventual
HonoHra;
Leer(); Visualizar();
PagarSalario();

126

Programacin C y C++

Definicin e implementacin de las clases


/*Trabaj.cpp */
#include <conio.h>
#include <stdio.h>
#include <iostream.h>
//Definicin de las Clases
class Trabajador{
private:
char Nom[40];
char Dir[40];
public:
void Leer();
void Visualizar();
};
class TBase:public Trabajador{
float SalDia;
int Ant;
public:
void Leer();
void Visualizar();
void PagarSalario();
};
class TEventual:public Trabajador{
float HonoHra;
public:
void Leer();
void Visualizar();
void PagarSalario();
};
//Implementacin de funciones miembros de la clase Trabajador
void Trabajador::Leer()
{
cout<<"\nNOMBRE: ";
gets(Nom);
cout<<"DIRECCION: ";
gets(Dir);
}
void Trabajador::Visualizar()
{
cout<<"\n"<<Nom;
cout<<"\n"<<Dir;
}
//Implementacin de funciones miembros de la clase TBase
void TBase::Leer()
{
cout<<"\nDATOS DEL TRABAJADOR DE BASE";
Trabajador::Leer();
cout<<"SALARIO DIARIO: ";
cin>>SalDia;

127

Programacin C y C++
cout<<"AOS DE SERVICIO: ";
cin>>Ant;
}
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;
cout<<"\nSalario semanal: "<<SalSemanal;
}

//Ms el 2% por ao

//Implementacin de funciones miembros de la clase TEventual


void TEventual::Leer()
{
cout<<"\nDATOS DEL TRABAJADOR EVENTUAL";
Trabajador::Leer();
cout<<"SALARIO POR HORA: ";
cin>>HonoHra;
}
void TEventual::Visualizar()
{
cout<<"\nTRABAJADOR EVENTUAL";
Trabajador::Visualizar();
cout<<"\n"<<HonoHra;
}
void TEventual::PagarSalario()
{ float SalSemanal;
SalSemanal=HonoHra*8*7;
//*8d hrs * 7 das
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

Programacin C y C++

3.- Suponga que en una situacin 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
Construir el rbol de herencia y definir las clases.
Solucin:
rbol de herencia:

Base
b1

Der1
a1

A
a2

Der2
d1

B
b2

D
d2

C
c2

Definicin de clases
class Base{
private:
int b1;
};
class Der1:public virtual Base{
private:
int a1;
};
class Der2: public Base{
private:
int d1;
};
class A:public Base,public Der1{
int a2;
};

class B: public Der1,public


Der2{
private:
int b2;
};
class C: public B{
int c2;
};
class D: public Der2{
int d2;
};

129

Programacin C y C++

EJERCICIOS PROPUESTOS
1.- Cual es la salida en pantalla del programa RectRell.cpp
2.- Muestre un ejemplo de la salida en pantalla del programa Trabaj.cpp
3.- Modifique el ejercicio resuelto Trabaj.cpp te tal forma que se utilice
polimorfismo mediante funciones virtuales (Deber proporcionar la misma
salida en pantalla).
4.- Suponga que en una situacin real se hallaron los siguientes objetos con
sus respectivos datos miembros de tipo entero:
Objetos
Atributos

A
a1
d1
b1
a2

B
a1
c1
b1
b2

C
a1
c1
c2

D
a1
d1
d2

Construir el rbol de herencia y definir las clases.


5.- Proponer un problema y resolverlo aplicando los pasos para el desarrollo
de un programa orientado a objetos.
|

Você também pode gostar