Documentos de Académico
Documentos de Profesional
Documentos de Cultura
la EIF 200
programación Fundamentos de Informática
por objetos
Guía para
estudiantes
Indice ............................................................................................................................................... 2
Introducción .................................................................................................................................... 4
Paradigma de la Orientación a objetos .......................................................................................... 6
Objetos ......................................................................................................................................... 8
Definición ................................................................................................................................ 8
Vista ........................................................................................................................................... 10
Estado de un objeto ................................................................................................................... 12
Interfaz de un objeto .................................................................................................................. 12
Abstracción ................................................................................................................................ 17
Clases ............................................................................................................................................ 19
Concepto .................................................................................................................................... 19
Creación ..................................................................................................................................... 21
Zona del nombre .................................................................................................................... 22
Zona de los atributos ............................................................................................................. 22
Zona de los métodos .............................................................................................................. 24
Atributos, campos y variables .................................................................................................. 25
Encapsulamiento ........................................................................................................................ 30
Ejercicios ................................................................................................................................... 33
Métodos ..................................................................................................................................... 39
Implementación ......................................................................................................................... 41
Tipos de datos básicos ........................................................................................................... 41
Sintaxis y semántica .............................................................................................................. 42
Sintaxis para la definición de clases ..................................................................................... 43
Identificadores ....................................................................................................................... 43
Palabras reservadas .............................................................................................................. 45
Campos .................................................................................................................................. 45
Variables................................................................................................................................ 45
Constantes ............................................................................................................................. 47
Comentarios .......................................................................................................................... 48
Bloque de código ................................................................................................................... 48
Bibliotecas ............................................................................................................................. 49
Expresiones y Operadores ..................................................................................................... 49
Operador de asignación .................................................................................................... 51
Prioridad de los operadores .............................................................................................. 53
Métodos ................................................................................................................................. 54
Parámetros de los métodos ............................................................................................... 58
Cuerpo del método ............................................................................................................ 58
Sobrecarga de métodos ..................................................................................................... 59
Constructores .................................................................................................................... 61
Convenciones de código ................................................................................................... 66
Creación de objetos: instancias ............................................................................................ 67
Ejemplos: ............................................................................................................................... 68
1. Clase Temperatura. ................................................................................................. 68
2. Clase Peso ............................................................................................................... 69
2 Guía estudiantes Fundamentos de Informática Mora, Coto,Caamaño y Vargas
3. Clase Triángulo. ...................................................................................................... 70
4. Clase Numero. ......................................................................................................... 73
5. Clase Fecha. ............................................................................................................ 74
Estructuras de control alternativas. ...................................................................................... 76
Estructura de control alternativa simple (if) ..................................................................... 76
Integridad de los objetos ................................................................................................... 80
Estructura de control alternativa múltiple (switch case) .................................................. 85
Caso de estudio: clase Triángulo .......................................................................................... 87
Estructuras de control iterativas ........................................................................................... 88
Estructura de control for ................................................................................................... 88
Estructura de control while ............................................................................................... 89
Estructura de control do-while .......................................................................................... 90
Ejercicios ............................................................................................................................... 92
Clases contenedoras .............................................................................................................. 93
Arreglos unidimensionales ................................................................................................ 93
Búsqueda ......................................................................................................................... 105
Búsqueda binaria............................................................................................................. 106
Ordenamiento .................................................................................................................. 108
Ordenamiento por burbujas ............................................................................................ 108
Ordenamiento por inserción............................................................................................ 110
Ordenamiento por selección............................................................................................ 111
Arreglos bidimensionales ................................................................................................ 113
Ejemplos: ......................................................................................................................... 115
Referencias Bibliográficas ....................................................................................................... 124
Querido estudiante al leer este documento encontrará una guía de estudio y apoyo que le
permitirán introducirse en el paradigma de la programación basada en objetos, exclusivamente
creada para el curso EIF 200 Fundamentos de Informática, según el enfoque definido para este
ciclo lectivo. Enfoque que ha sido el producto de la iniciativa de la Asamblea de Académicos de
la Escuela de Informática y de más de cinco años de trabajo en la cátedra del curso.
Este material ha sido desarrollado por los autores como una iniciativa personal, contando
con el aporte de muchos profesores que han pasado por la cátedra dejando huella; con el único fin
de ir consolidando un conjunto de terminología e información básica, estándar para el curso. Sin
embargo no puede considerarse como un documento terminado, más bien solicitamos su
colaboración mediante recomendaciones para mejorarlo y así facilitar el acceso a esta
información de nuevos estudiantes que se incorporen al curso cada año.
Se ha planteado como una guía de estudio para el estudiante; es por esta razón que
encontrará una lista de definiciones de distintos autores con distintos estilos de decir las cosas,
para que usted pueda formarse un criterio más amplio, además encontrará pequeñas listas de
ejemplos, ejercicios y una que otra estrategia para su propio aprendizaje.
Lo más importante en este curso es que el estudiante pueda conocer la importancia que
tiene la conceptualización del entorno, que pueda “visualizar” los objetos y clases en el
planteamiento de un problema y que finalmente pueda “diseñar” adecuadamente una clase,
identificando sus características y comportamientos, según el uso que vaya a dársele.
Esta es la primera versión de una guía para estudiantes, nos comprometemos a seguir en
el proceso de construcción y mejora continua. Todo el material presentado es usado
exclusivamente con fines académicos. Nos ponemos a su disposición para cualquier consulta,
duda o posibilidades de mejora.
La Programación Orientada a Objetos (POO o OOP por sus siglas en inglés de Object
Oriented Programming) como paradigma, "es una forma de pensar, una filosofía, de la cual surge
una cultura nueva que incorpora técnicas y metodologías diferentes. Pero estas técnicas y
metodologías, y la cultura misma, provienen del paradigma, no lo hacen.”… (Greiff,1994).
Primero, el uso del modelo OO nos ayuda a explotar el poder expresivo de todos los
lenguajes de programación basados en objetos y los orientados a objetos, como Smalltalk,
Object Pascal, C++, CLOS, Ada, y recientemente Java.
Segundo, el uso del modelo OO alienta la reutilización no sólo del software, sino de
diseños completos.
Tercero, produce sistemas que están construidos en formas intermedias estables y por
ello son más resistentes al cambio en especificaciones y tecnología.
El mismo autor considera que el principal beneficio del Diseño Orientado a Objetos (DOO)
es que da un mecanismo para formalizar el modelo de la realidad.
Definición
3. “es una conceptualización de algo que puede ser real o abstracto, tangible o
intangible”
6. “Un objeto es una cosa que podemos percibir por algún sentido y sobre la que se
puede accionar y carece de autonomía de acción. La consideración de algo como
objeto depende del ámbito en el cual se está definiendo al mismo.”. Wikipedia
a. un objeto simple: es un objeto que se puede concebir con sólo atributos simples: por
ejemplo un objeto Vehículo puede estar formado por atributos simples tales como
nombre del dueño, peso, longitud, marca, modelo, entre otros.
b. un objeto complejo: es un objeto que además de objetos simples, está compuesto de
otros objetos, es decir sus atributos son otros objetos. Por ejemplo un objeto Vehículo
(en otra circunstancia) puede estar formado por atributos simples como nombre del
dueño, peso, etc y otros que son objetos, tales como (chasis, llantas, motor, puertas,
ventanas, faros, carrocería, entre otros).
De esta forma cada objeto debe ser visualizado dentro de un contexto para describirlo
adecuadamente y de esta forma empezamos a introducir el tema de vista o entorno,
Vista
Una vista permite establecer los objetos en el entorno y su relación o interacción con los
demás objetos existentes, y los objetos existen en la medida que tienen algún tipo de relación con
otros objetos. Es decir una vista nos permite visualizar los componentes del entorno, de tal
manera que podamos identificar los objetos y las posibles interrelaciones entre ellos.
Una vista nos permite determinar el contexto en el que el objeto se desempeña, lo cual es
muy importante porque permite “definir” o diseñar el objeto.
Cuando se observa a nuestro alrededor se tiene una VISTA de los objetos que están
cerca o lejos. Pero hay que entender que los objetos existen en la medida que tienen algún tipo
de relación con otros objetos.
Esto muestra lo indispensable que es pensar primero en la vista: en para qué se quiere el
objeto, como se comporta dentro del contexto, para luego poder pensar en que característica se
requiere que tenga el mismo.
Ejemplo: el siguiente es un ejemplo clásico de vista ¿Qué relación podría existir entre
un Ejecutivo (objeto 1) y su celular (objeto 2).?. la relación es que el ejecutivo usa el celular
para establecer una comunicación con otra persona o sino para hacer cálculos matemáticos o
ingresar a Internet…. etc. Por otro lado: ¿Qué relación podría existir entre un caníbal (objeto 1)
y un celular (objeto 2).?. el caníbal usa un celular como si se tratara de un proyectil para cazar a
una presa o para aliñar la cena.
Aunque si bien es cierto, ambos usan el mismo objeto: un celular, el sentido de la relación
es muy diferente, visualizar el uso del objeto es muy importante, para un Ejecutivo hay mucha
diferencia entre un celular y una piedra, no es así para un caníbal.
Estado de un objeto
Un objeto siempre debe tener un estado que lo caracteriza y que puede cambiar de un
momento a otro. Todo objeto tiene un estado inicial y el estado de un objeto está íntimamente
relacionado con el valor de sus atributos. Por ejemplo, si un objeto Persona tiene como atributos
nombre, dirección, edad y altura, un estado inicial podría ser:
nombre: “Carmen”,
dirección: “Heredia”,
edad: 20,
altura: 1.65
Interfaz de un objeto
Existen formas de comunicación entre los objetos, donde se utilizan diversos canales en
esa comunicación, tanto de entrada como de salida, y de tipo visual, auditivo, entre otros.
La interfaz de un objeto viene dada por el conjunto de órdenes a las que puede responder.
A continuación se dan algunos ejemplos, que también como muchas otras cosas en este
paradigma, podemos pensar diferente con respecto a ellos, pero la discusión siempre es
enriquecedora.
Tabla 3. Interacción entre objetos del mismo tipo. Elaboración propia
el objeto Hijo ha recibido un mensaje procedente del objeto Madre. El objeto hijo
responde al mensaje o evento ocurrido mediante una acción: buscar aspirinas.
La madre no tiene que decirle al hijo dónde debe buscar, es responsabilidad del hijo
resolver el problema como considere más oportuno. Al objeto madre le basta con
haber emitido un mensaje.
El hijo, como objeto responsable de un cometido, sabe lo que debe hacer hasta conseguir
una aspirina. Para ello entra en relación con un nuevo objeto, la Farmacéutica, quien responde al
mensaje o evento de petición del objeto Hijo con la búsqueda de la aspirina. El objeto
Farmacéutica es ahora el responsable de la búsqueda de la aspirina. El objeto Farmacéutica
lanza un mensaje al objeto Hijo solicitando el pago del importe, y el objeto Hijo responde a tal
evento con la acción de pagar.
Como ve en esta situación los objetos se diferencian de los demás por un conjunto de
características o propiedades, y por un conjunto de acciones que realizan en respuesta a unos
eventos que se originan en otros objetos o en el entorno.
Existen grupos de objetos que se unen para montar un escenario o una situación en
particular. De esta forma podemos decir que hay grupos de objetos que actúan como un todo, o
sea como si fuera un solo paquete, por ejemplo se tiene:
La abstracción es la forma como yo veo lo que es relevante en una vista. Cada persona
puede ver cosas diferentes y depende de su formación y de la concepción en la manera de ver las
cosas. No todos somos iguales a la hora de abstraer lo más relevante. Cada uno tiene formas
parcializadas de ver las cosas, de ahí la dificultad o belleza de nuestra profesión, debemos captar
la vista (y mejorarla, optimizarla) del usuario (o varios usuarios).
Una abstracción se centra en la vista externa de un objeto, de modo que sirva para
separar el comportamiento esencial de un objeto, de su implementación. Definir una abstracción
significa describir una entidad del mundo real, no importa lo compleja que pueda ser, y a
continuación utilizar esta descripción para su implementación en un programa.
Objetos Características
Persona (oficina) (nombre, cedula, correo-electrónico, teléfono).
Factura (Pulpería)
Factura (Supermercado)
Concepto
Una clase:
Engloba todas las características de un conjunto particular de objetos.
Es un conjunto de objetos que tienen una estructura común y un comportamiento común.
Por tanto la clase es una abstracción del concepto objeto. Un objeto es una instancia de
una clase (Booch, 1996).
Describen un conjunto de objetos que comparten los mismos atributos, operaciones y
relaciones. Es común encontrar muchos objetos en un sistema que esencialmente son
similares a otros salvo en los valores de sus atributos. Por ejemplo: empleados de una
fábrica. Cada uno de esos objetos son miembros de la misma clase Empleado.
“El origen del concepto de clase viene dándose desde los tipos de datos abstractos en el
año 1966 por parte de los Noruegos Dahl y Nygaard ”. (Joyanes,1996).
“Se define como una entidad que declara objetos similares”. (Joyanes,1996).
“Son plantillas para crear objetos de una misma estructura”. (Joyanes,1996).
Es un modelo de comportamiento de un tipo de objeto que existirá durante la ejecución de
un programa orientado a objetos.
Es una plantilla o molde que define los atributos y métodos que tendrán los objetos de esa
clase.
Un objeto es una entidad concreta que existe en el tiempo y el espacio, una clase
representa sólo una abstracción.
Es importante enfatizar que cada clase deberá tener independencia con respecto a otras
clases, y entender que es altamente probable que las clases estén relacionadas, pero cada una por
sí misma debe tener bajo acoplamiento:
“…grado de interdependencia entre las unidades de software (módulos, funciones,
subrutinas, bibliotecas, etc.) de un sistema informático. El acoplamiento da la idea de lo
dependiente que son las unidades de software entre sí, es decir, el grado en que una
unidad puede funcionar sin recurrir a otras.
Por ejemplo, dos funciones son absolutamente independientes entre sí (es decir, el nivel
más bajo de acoplamiento) cuando una puede hacer su trabajo completamente sin
recurrir a la otra. En este caso se dice que ambas están desacopladas.
El consenso general es que debe haber bajo acoplamiento entre las unidades de software
para lograr una buena programación o un buen diseño. O sea, mientras menos
dependientes sean entre sí las partes que constituyen un sistema informático, mejor será
el resultado. Obviamente es imposible un desacoplamiento total de las unidades.
El bajo acoplamiento permite:
Mejorar la mantenibilidad de las unidades de software.
Aumentar la reutilización de las unidades de software.
Evitar el efecto onda, ya que un defecto en una unidad puede propagarse a otras,
haciendo incluso más difícil de detectar dónde está el problema.
Minimiza el riesgo de tener que cambiar múltiples unidades de software cuando
se debe alterar una. (Wikipedia)
Creación
b. La zona de los atributos, que son las características que todo objeto de la clase debe
tener, y que definen su estado.
c. Y por último la zona de los métodos que son las acciones o comportamientos únicos
que los objetos pueden tener cuando son creados.
Zona de Atributos
Para realizar esta tarea se deben conocer muy bien los problemas a resolver, de esta forma
habrá entornos que conocen muy bien y eso facilita la abstracción y otros que no y requieren
buscar ayuda de expertos. Algunos ejemplos son:
Ejemplo: Dependiendo del tipo de problema que se tenga que modelar, la clase
Persona puede ser diferente. En un problema (diseño de ropa a la medida) puede interesar
solamente las medidas de la persona: cintura, pecho, cuello, etc. En otro problema nos puede
interesar solamente el número de trabajos diferentes que puede realizar una persona, en otro
problema nos puede solo interesar la capacidad física de resistencia de la persona, en fin, los
atributos de la clase Persona pueden variar de un problema a otro o de una empresa a otra, aunque
sea la misma clase Persona. Todo depende el tipo de problema que se tenga, los atributos pueden
ser muy diferentes aunque las clases se llamen igual.
Es importante que el estudiante entienda que hay objetos complejos que están formados
por otros objetos. Así que no es de extrañar que los atributos de estos objetos sean objetos
también, sin embargo el detalle completo de este tema se verá en el siguiente curso EIF 201
Programación I.
Ejemplo: se puede definir una clase Triángulo en la que sus atributos son objetos, es decir
tendrá 3 atributos que serán a su vez objetos de la clase Punto o la misma clase Triángulo se
podría definir con 3 atributos simples: lado1, lado2, lado3, donde cada lado es un número real, o
se podría definir la clase Triángulo con base y altura, 2 atributos simples, ¿de qué dependerá esta
definición de la clase Triángulo? Como ya se ha dicho: del uso que se le debe dar a la clase, del
Por ejemplo si el objeto es un Robot, dicho robot puede tener métodos o comportamientos
muy diversos, tales como: robotVuela(), robotCome(), robotDispara(), robotCorre(),
robotLLora(), etc.
Bola
tipo: int radio:real
color: int material: string
rebotar ( )
pintar ( )
desinflar ( )
Este diagrama representa en UML una clase que se utilizará para la creación de objetos
tipo Bola, con tipo, radio, color y materiales como sus características (atributos) y con
comportamientos como son rebotar(), pintar () y desinflar().
El tema de campos, variables y tipos de datos está íntimamente ligado con los atributos en
principio y después se verá que también está ligado con los métodos. De alguna manera los
atributos definen el estado de un objeto, y para almacenar los atributos de un objeto debemos
definir campos que permitan representarlos adecuadamente.
Cada uno de los campos que corresponda a un atributo está unido a un tipo de dato, al
declararlo se debe escribir el tipo de dato que le corresponde, esto se hace con dos propósitos:
que la computadora conozca cómo y cuanto espacio de memoria asignar a cada campo
que se declare, esto es que la computadora asigne espacios de memoria adecuados y
porque es necesario saber en todo momento el tipo de dato que usa cada campo, para
reconocer que se están haciendo las cosas correctamente. Por ejemplo, si tengo que
sumar dos campos, esperaría que se sumaran número con número y no cadenas de
caracteres con elementos de tipo de dato numérico. Este tipo de mezclas podría dar un
error de compilación o peor aún no da error y podríamos no darnos cuenta de lo que en
realidad quedo como resultado de la suma, de ahí la importancia de conocer bien el
problema a resolver.
Sin embargo este tema se detallará más adelante. Figura 6. Clase Persona
A) La factura tiene atributos o cualidades únicas que juntas forman lo que se conoce como
factura. A la hora de extraer sus atributos hay que hacer la pregunta. ¿ Qué es lo que “tiene”
una factura ?. esto permite saber cuáles son sus atributos. La factura tiene:
Título de la Empresa
Número de factura
Cliente
cédula Jurídica
línea de detalle del producto (a su vez este tiene características)
a. cantidad solicitada del producto
b. nombre del producto
c. precio costo unitario del producto
impuesto de venta
total
B) En este punto se enfatiza en ¿Cuáles son las actividades que se realizan?. y se enlistan las
siguientes, por ejemplo:
Ya en este punto el estudiante tiene las herramientas básicas para visualizar objetos,
clasificarlos en clases y describirlos adecuadamente según el uso que se les vaya a dar.
Los insectos se caracterizan por tener seis patas y el cuerpo dividido en cabeza, tórax y
abdomen. Los insectos más numerosos son los abejones, en segundo lugar están las
avispas y las hormigas y en el tercer lugar se encuentran las mariposas. Los abejones, las
avispas y las hormigas pertenecen al Orden Himenóptero y las mariposas pertenecen al
Orden Lepidóptero. Dentro del orden lepidóptero, existen dos grandes grupos de
mariposas: las diurnas y las nocturnas. Es importante especificar que cada insecto se
alimenta de distintos tipos de flores
La idea principal de este proceso de análisis debe ser identificar sustantivos, verbos y
adjetivos, pensando que los sustantivos se pueden clasificar como clases, los adjetivos como
atributos y los verbos como comportamientos, de esta manera en el ejemplo anterior vemos los
sustantivos subrayados, los adjetivos en itálica y los verbos en negrilla
Este proceso no es 100% seguro, se requiere de experiencia, sin embargo una variante que
podría mejorar el proceso de identificar finalmente las clases, sería que intente pasar los
Abejon Insectos
-caracteristicas: String
-orden: String
-posicionCantidad: Integer Avispa
-tipoFlor: Integer
+pertenece()
+alimenta()
Mariposa
Hormiga
-grupo: String
Encapsulamiento
Es la capacidad que tienen los objetos de construir una cápsula a su alrededor, ocultando
la información que contienen (aquella que es necesaria para su funcionamiento interno,
pero innecesaria para los demás objetos).
Los niveles de encapsulación están heredados de los niveles de C++,. En este curso se
estarán usando algunos de estos niveles, no todos con el objetivo de nuevo de centrarnos en el
desarrollo y comprensión del tema, es por esta razón que sólo usaremos los siguientes:
(-) Privado: es el más fuerte. Lo que se defina como privado es totalmente invisible
(excepto para clases friends en terminología C++)
(+) Públicos: Los atributos u operaciones públicos son visibles a otras clases (cuando se
trata de atributos se está transgrediendo el principio de encapsulación.)
OBS: en este curso sólo se trabajará con declaración de atributos privados y métodos
públicos, es decir TODOS los atributos son privados y todos los métodos públicos, esto por
considerarlo un asunto de no quedarnos en detalles del POO que no aportan en este momento a
la resolución de problemas. Las consideraciones diferentes a estas son realizadas en el siguiente
curso de programación. De aquí en adelante ya el estudiante diseña las clases en UML usando
esta terminología (+,-).
Ejemplo:
Suponga un punto en un plano cartesiano (x,y). Si se modela ese punto como un objeto,
entonces se puede crear una clase Punto que pueda generar objetos tipo punto. Por ejemplo el
punto (3,2) ya sería una instancia particular de la clase Punto. En general hasta ahora las clases
deben tener tres cosas básicas:
Primero: Un nombre
Segundo: atributos
Tercero: métodos.
A continuación algunos ejercicios que permiten ejercitar las destresas adquiridas, la idea
es que en cada ejercicio se haga el diseño de las clases con la declaración de atributos y métodos:
Ejercicio No.1. Cierta Universidad desea un programa computacional que le ayude a administrar
las calificaciones finales de sus estudiantes. Para cada estudiante se registra su matrícula, nombre,
apellidos, semestre, la cantidad de materias que cursa y por cada materia se guarda el nombre y
una calificación final. La universidad distingue tres tipos de estudiantes especiales: los candidatos
a graduarse, los condicionados, los de posgrado. En el caso de los primeros se debe guardar su
fecha de graduación y el semestre se debe poner en –1 para identificar que se ha graduado, en el
caso de los segundos se debe guardar cuántas materias está cursando que no corresponden a su
programa académico y el semestre en que estuvo condicionado. En el último caso se guarda su
lugar de trabajo y escuela de origen.
Ejercicio No. 2. Una empresa de multimedios financia diferentes publicaciones en los medios
de comunicación más conocidos: la radio, la televisión y la prensa escrita. Todas las
publicaciones tienen un título y una persona responsable de la dirección de la publicación. Tienen
además un código numérico que las identifica unívocamente. Tanto los programas de radio como
los de la televisión poseen una duración determinada en minutos junto con una hora de inicio, así
como el nombre de la emisora correspondiente. Además, existe un espacio disponible para los
comerciales.
En los programas de radio, este tiempo se mide en minutos al aire (por ejemplo, “La Venganza
será terrible” tiene 23 minutos de propagandas). Para la televisión, se mide en cantidad de
comerciales por tanda (por ejemplo, “Hora Clave” tiene siete propagandas en cada tanda). Cada
programa televisivo puede tener además un número diferente de tandas comerciales. Los
programas de radio necesitan por otra parte un responsable de la musicalización. En cuanto a las
publicaciones por medios escritos, la empresa posee dos tipos: diarios y revistas. Las
publicaciones escritas tienen un editor responsable, una cantidad de páginas, un precio y un año
de publicación. Los diarios que se imprimen son semanales o quincenales, se cobra una pequeña
cantidad de recargo por envíos al interior, y se registra la semana y mes de publicación. Las
revistas poseen el mes de publicación, el número y el título de la nota de tapa.
Ejercicio No. 4. Una empresa de recambios de piezas de coches necesita una aplicación para
gestionar sus ventas. Esta empresa compra las piezas a distintos proveedores para después
venderlas a los talleres. Cada pieza de recambio tiene un código que la identifica y un único
proveedor que puede proporcionarla. También tiene un precio de compra al proveedor y un
precio de venta a los talleres. Las operaciones que se quieren hacer sobre la pieza son modificar
los dos precios, comprarla y venderla. Los proveedores con los que trabaja la empresa tienen
datos de contacto como teléfono, dirección, nombre del proveedor y CIF. La empresa quiere
poder dar de alta nuevos proveedores y obtener sus datos de contacto. Además, la empresa quiere
mantener la información de los talleres con los que trabaja: su nombre, CIF, teléfono y dirección.
Quiere poder acceder a todos estos datos.
Ejercicio No 7. Se trata de construir un sistema que controle una máquina para reciclar latas,
botellas y cajas de botellas. La máquina puede ser utilizada por varias personas a la vez. El
sistema registra cuántos elementos devuelve cada usuario e imprime un recibo con el valor de los
elementos devueltos y el total a pagar al usuario. El sistema también lo utiliza un operador que
desea conocer el número de elementos de cada tipo que se han introducido durante el día.
También debe poder actualizar los valores de los elementos. El sistema llamará al operador
cuando se acabe el papel de los recibos o si detecta algún problema con los elementos
introducidos. Para el uso de la máquina los trabajadores disponen de una tarjeta de identificación
que deben introducir en la máquina antes de su uso. Cuando el usuario introduce la tarjeta la
máquina le pide su contraseña personal. El usuario proporciona su contraseña y la máquina
comprueba los datos. Cuando la validación es correcta, la máquina muestra un mensaje indicando
al usuario que puede comenzar a reciclar elementos. Cada vez que el usuario recicla un elemento
Ejercicio No 10. Una empresa desea una aplicación para gestionar los salarios de sus empleados.
La empresa paga a sus empleados una cantidad de dinero por diferentes conceptos teniendo cada
uno distintas características. Algunos conceptos están libres de impuestos, mientras que otros
están sujetos a cierta retención por parte de Hacienda. Calcular el sueldo de un empleado no es
más que sumar todos los conceptos netos correspondientes (es decir, restado las retenciones
cuando sea necesario). Los conceptos libres de cargas son debidos a trabajos de diversa índole,
por lo que se le asocia una descripción del trabajo y número de horas invertidas. En cuanto a los
conceptos sujetos a retención, el Ministerio de Hacienda se lleva un porcentaje. Estos conceptos
se clasifican en: el sueldo base, los complementos y el trabajo extra. El sueldo base de cada
empleado tiene un código numérico que lo identifica. Los complementos del sueldo tienen,
además del porcentaje de retención mencionado, un
Impuesto especial que varía para cada tipo de complemento. Los complementos que se tienen en
cuenta son: complemento de destino, complemento de cargo y complemento de antigüedad. Para
el complemento de destino se anotará el destino actual (ciudad y sucursal), para el complemento
de cargo se anota el propio cargo (jefe, directivo o empleado) y, finalmente, asociado al
complemento de antigüedad está el número de años.
El concepto de trabajo extra tiene en cuenta el número de horas extra que ha realizado el
trabajador además de la justificación (fin de proyecto, guardia, otros). Dada la excepcionalidad de
las horas extra, Hacienda aplica un porcentaje especial como impuesto.
En este curso se ha establecido, con fines didácticos, que los atributos se definan como
privados, al declararlos de esta foma la única manera de acceder a ellos es mediante los métodos
set<Atributo>() y get<Atributo>(). SOLO de esta forma los atributos pueden ser accedidos,
además estos son necesarios pues pueden hacer verificaciones muy importantes y útiles en
algunas situaciones, por ejemplo imagine un atributo que sea el denominador de una clase
Fracción, este nunca puede ser 0, daría serios problemas de definición y de compilación, de esta
forma es muy útil definir un método setDenomindor(), de tal forma que verifique siempre que el
atributo va a ser cambiado, que se haga correctamente, el código puede ser:
3) Métodos de cálculo: son métodos de una clase encargados de llevar a cabo los cálculos
necesarios.
4) Métodos privados: son métodos que sólo pueden ser accedidos desde métodos de la clase.
Ejemplo: utilizando la clase Punto, se muestran los métodos que corresponden en el diagrama
de UML, observe que los atributos son privados y los métodos públicos, con excepción del
destructor:
Punto
-x: real
-y: real
+Punto()
+Punto(real a)
+Punto(real a, real b)
+setX()
+setY()
+getX()
+getY()
+distancia(real a, real b)
+distanciaOrigen()
~Punto()
En la mayoría de los lenguajes se brinda un conjunto de tipos de datos que son necesarios
en la escritura de las aplicaciones, a éstos se les denominan tipos de datos básicos o primitivos y
entre éstos no deben faltar los tipos de datos para representar enteros, reales, caracteres, cadenas
de caracteres y lógicos.
Sintaxis y semántica
Hay dos aspectos que determinan si una secuencia de símbolos es correcta: la sintaxis y la
semántica.
Las reglas de sintaxis son las que permiten determinar de que manera los símbolos del
vocabulario pueden combinarse para escribir código que por su forma sea correcto.
Así, por ejemplo, en el lenguaje natural son las reglas de la sintaxis las que nos permiten
determinar que la siguiente secuencia no es correcta:
La semántica por su parte guarda una estrecha relación con las acciones o instrucciones.
Esta permite determinar el significado de la secuencia de símbolos para que se lleve a cabo la
acción por la computadora. También a través de las reglas semánticas pueden ser detectados
De forma similar son las reglas semánticas las que permiten determinar si una secuencia
de símbolos no forma un código correcto, aunque no tenga errores sintácticos.
Con esta idea en mente se irán describiendo las reglas sintácticas y semánticas para una
adecuada implementación de una clase, y de una vez se incluirán algunas convenciones básicas,
como son la indentación y el uso de identificadores nemotécnicos:
class <NombreClase>
{
<miembros>
}; // esto es un comentario para indicar que este punto es muy importante
De este modo se define una clase con nombre <NombreClase> cuyos miembros (atributos
y métodos) son los que se definen en <miembros>, estos estarán presentes en cada uno de los
objetos o instancias de la clase. <NombreClase> debe ser un identificador de la clase que
realmente la represente, es decir que sea significativo, y además debe ir en singular y en
mayúscula como parte de las convenciones.
Identificadores
Los identificadores son nombres simbólicos que se forman mediante una secuencia de letras
y dígitos y en C tienen que cumplir con las siguientes convenciones:
El primer carácter de un identificador tiene que ser siempre una letra o un guión bajo
(subrayado), el carácter subrayado se considera como una letra más.
Los identificadores son utilizados para nombrar las diferentes entidades presentes en una
clase.
Ejemplos:
Tabla 12. Ejemplos de variables.
Identificador Estado Observación
edad correcto
_salario correcto
Algunos principios importantes sobre el uso de los identificadores que deben tenerse en
cuenta son:
Algunos lenguajes son case sensitive, C lo es, esto es que las mayúsculas y las minúsculas
no son lo mismo, de esta manera los identificadores que apenas se diferencian en una mayúscula
ya son diferentes, por ejemplo: Color es distinto de color.
Palabras reservadas
Campos
Son datos comunes a todos los objetos de una determinada clase, corresponden a atributos
de la clase y su sintaxis de definición es:
<TipoDato> <nombreAtributo>;
El <nombreAtributo> puede ser cualquier identificador que cumpla con las reglas
establecidas y no coincida con el nombre de otro miembro previamente definido en la clase, pero
por convención debe ser nemotécnico, es decir debe representar muy bien el contenido que va a
almacenar.
Variables
Las variables son entidades de los programas que se utilizan para conservar valores
durante la ejecución de éstos. Las variables permiten representar valores que no necesariamente
Una variable es una abstracción9 de una zona de memoria que se utiliza para representar y
conservar valores de un determinado tipo. Una variable debe tener un tipo asociado que es
precisamente el tipo de los valores que ella puede Figura 9. Diagrama clase Persona
+Persona()
declaración de variables. +Persona(string, string)
+Persona(strin, string, annoNac)
Los atributos (como concepto del modelo OO) +setNombre(string)
+setDireccion(string)
+setAnnoNacimiento(int)
pueden ser considerados como un caso particular de +getNombre()
+getDireccion()
variable teniendo en cuenta que éstos pueden conservar +getAnnoNacimiento()
+edad(int)
valores durante la ejecución de las aplicaciones. +toString()
~Persona()
Se pueden definir variables dentro del cuerpo de un
método, las cuales se pueden calificar como variables
locales, pues solo podrán ser accedidas dentro del cuerpo del método, algo similar sucede con las
variables que constituyen parámetros de un método.
string nombre;
string apellidos;
int annoNacimiento;
int unAño;
En la mayoría de los lenguajes las variables tienen que ser definidas antes de ser
utilizadas. Toda variable tiene que ser definida una única vez en un mismo bloque o segmento de
código y a partir de esta definición puede ser utilizada todas las veces que se desee.
Las variables son declaradas escribiendo su tipo, seguido de algún espacio en blanco y
luego el identificador de la misma terminando con un punto y coma. En caso de que se desee
definir más de una variable entonces los identificadores de las mismas tienen que ser separados
por coma. Al declarar una variable se está informando al compilador de su tipo y de su
identificador propiamente.
Ejemplo:
class Persona
{
string nombre, apellidos;
int añoNacimiento;
…………
};
Constantes
Las constantes se utilizan para representar datos que no cambian durante toda la
aplicación. A las constantes también se les asocia un tipo de datos. Una constante también puede
ser definida como una variable cuyo valor es determinado durante el proceso de compilación.
Como convención se definirán las constantes en mayúscula.
Las constantes se definen como variables normales, ya sean campos o variables locales
(exceptuando los parámetros) pero precediendo el nombre de su tipo la palabra reservada const y
dándoles siempre un valor inicial al declararlas. Es decir, con esta sintaxis:
Comentarios
// identificación de la clase
// atributos …
// método de consulta o acceso …
*/
Bloque de código
En el caso particular de las clases, el bloque de código que agrupa las responsabilidades
de la misma comienza inmediatamente después de <NombreClase>.
La mayoría de los lenguajes cuentan con una biblioteca de funciones que permiten a los
programadores trabajar con código que ya ha sido probado y que funciona. Además, a partir de
estas funciones y clases el programador puede crear nuevas clases que extiendan o usen su
funcionalidad y se integren a la perfección con el resto de las clases.
Expresiones y Operadores
Un operador es un carácter o grupo de caracteres que actúa sobre uno, dos o más operandos
para realizar una determinada operación con un determinado resultado. Los operadores pueden
ser unarios, binarios y ternarios según actúen uno, dos o tres operandos respectivamente.
Llamaremos operandos a un valor constante o literal, al contenido de una variable, al resultado
de la invocación de un método, al resultado de la evaluación de una operación, etc.
Los operadores aritméticos: suma (+), resta (-), producto (*), división (/) y módulo (%).
También se incluyen operadores de menos unario (-) y más unario (+).
Los operadores lógicos permiten realizar las operaciones lógicas típicas: and (&& y &),
or (|| y |), not (!) y xor (^).
Para la concatenación de cadenas se puede usar el mismo operador que para realizar
sumas, ya que se redefine su significado para que cuando se aplique entre operandos que
sean cadenas o que sean una cadena y un carácter lo que haga sea concatenarlos. Por
Seguidamente se muestran los tipos de datos básicos y las operaciones que se pueden
realizar sobre ellos:
Si se desea obtener el valor exacto de la división de 5 entre 2 se tiene que expresar al menos
uno de los valores como constante del dominio de los números reales: 5.0 / 2 (5 / 2.0 ó 5.0 / 2.0).
Una expresión es una combinación de operaciones sobre operandos (valores) que nos
permite obtener nuevos valores. Una expresión también puede ser definida como un operando o
la aplicación de operadores sobre operandos.
<variable> = <expresión>;
Ejemplos:
int temperatura;
uint edadJuan;
temperatura = -5;
uint edadPedro = 23;
edadJuan = edadJuan + 2;
edadPedro = edadPedro + 1;
float peso = 60.5;
char letra = 'a';
string nombreJuan = “Juan“;
string nombrePedro, nombreAna;
nombrePedro = nombreJuan;
nombreAna = “Ana“;
bool existe = true;
Es posible relacionar la propia definición de las variables con el primer valor que se le
asigna, en este caso se le llama inicialización, por ejemplo:
Además de los elementos presentados con anterioridad, el operador de asignación tiene otra
serie de funcionalidades como se muestra a continuación:
Las dos líneas anteriores son equivalentes, pues el operador compuesto += lo que hace es
asignar a su primer operando el valor que tenía más el valor de su segundo operando. Como
se ve, permite compactar bastante el código.
Aparte del operador de asignación compuesto +=, también existen operadores de asignación
compuestos para la mayoría de los operadores binarios ya vistos, como por ejemplo: +=, -=,
*=, /=, %=, &=.
Otros dos operadores de asignación incluidos son los de incremento(++) y decremento (--)
Estos operadores permiten, respectivamente, aumentar y disminuir en una unidad el valor de
la variable sobre el que se aplican. Así, estas líneas de código son equivalentes:
peso = peso + 1; // Sin asignación compuesta ni incremento
peso += 1; // Usando asignación compuesta
peso++; // Usando incremento
La ventaja de usar los operadores ++ y -- es que en muchas máquinas son más eficientes
que el resto de formas de realizar sumas o restas de una unidad, pues el compilador puede
traducirlos en una única instrucción en código máquina.
El resultado de una expresión depende del orden en que se ejecutan las operaciones. Si no
existiese un orden de prioridad entre los operadores, la siguiente expresión:
3 + 4 * 2;
Con el objetivo de que el resultado de cada expresión sea claro e inequívoco es necesario
definir reglas que definan el orden en que se ejecutan las expresiones. Existen dos tipos de reglas
para determinar este orden de evaluación: las reglas de precedencia y las de asociatividad.
Para la evaluación de las expresiones se aplican las siguientes reglas cuando existe más de
un operador:
Cuando existen operadores de diferente prioridad se evalúan primero los que tengan
mayor prioridad, a continuación los de la prioridad siguiente y así sucesivamente.
Las dos reglas anteriores quedan sin efecto cuando se incluyen paréntesis. En este caso
la parte de la expresión encerrada entre paréntesis se evalúa primero siguiendo a su vez
estas tres reglas.
Precedencia Asociatividad
() [] izquierda a derecha
++ -- ! + (unuario) – (unario) derecha a izquierda
* / % izquierda a derecha
+ – izquierda a derecha
< <= > >= izquierda a derecha
== != izquierda a derecha
&& & izquierda a derecha
|| | izquierda a derecha
?: derecha a izquierda
= += -= *= /= %= &= |= derecha a izquierda
, izquierda a derecha
Fuente: Elaboración propia
Métodos
Los métodos son bloques de instrucciones que pueden devolver algún valor cuando se
ejecutan. Invocar a un método hace que las instrucciones del mismo se ejecuten. En las
instrucciones es posible acceder con total libertad a la información almacenada en los campos de
la clase a la cual pertenece el método.
< Tipo devuelto > < Nombre simbólico del método > ([<Parámetros>])
{
< Cuerpo del método >
Opcionalmente todo método puede recibir en cada llamada una lista de parámetros a los que
podrá acceder en la ejecución de las <instrucciones> del mismo. En <Parámetros> se indican los
tipos y nombres de estos parámetros y es mediante estos nombres con los que se deberá referirse
a ellos en el cuerpo del método.
Aunque los objetos que puede recibir el método como parámetro pueden ser diferentes cada
vez que se solicite su ejecución (llamado), siempre han de ser de los mismos tipos y seguir el
orden establecido en <Parámetros>.
La sintaxis usada para llamar a los métodos de un objeto es la misma que se utiliza para
acceder a sus campos, solo que además tras el nombre del método que se desea invocar habrá que
indicar entre paréntesis cuales son los valores que se desea dar a los parámetros. O sea se escribe
de la siguiente forma:
Los términos método y función suelen usarse de forma indistinta, pero hay una diferencia.
Un método es una función contenida en una clase. Una función suele ser un grupo de
instrucciones que no está contenido en una clase y que suele estar en un lenguaje, como C o C++.
En algunos lenguajes como C# no se puede añadir código fuera de una clase. Todos los métodos
se encierran en una clase.
class Persona
{
prívate:
// campos que corresponden a atributos …
string nombre;
string apellidos;
int annoNacimiento;
public:
// constructor sin parámetros
Persona ()
{
nombre = “ Indefinido”;
apellidos= “Indefinido”;
annoNacimiento = 0;
}
// constructor con 2 parámetros
Persona (string nom, string ape)
{
nombre = nom;
apellidos= ape;
annoNacimiento = 0;
}
// constructor con 3 parámetros
Persona (string nom, string ape, int annoNac) {
nombre = nom;
apellidos= ape;
annoNacimiento = annoNac;
}
// método de consulta o acceso …
void setNombre (string nom){
Este ejemplo muestra la implementación haciendo uso de los distintos métodos que
conforman una clase.
El método edad() para cumplir con su responsabilidad de retornar el valor de la edad (con
relación a un año determinado) de cualquier Persona necesita saber el año de nacimiento (resuelto
a través del campo annoNacimiento), además necesita conocer con respecto a que año va a
calcularse dicha edad y esto es desconocido en principio, además puede ser que en un momento
quisiera saber la edad de una persona en el año actual o hace 5 años. Es por ello que aseguramos
que le está faltando información al método edad() para cumplir con la respectiva responsabilidad
asignada. La referida información que está faltando es la que se completa a través del parámetro
int unAño.
Los parámetros son definidos entre paréntesis a continuación del nombre de la clase. Un
método puede contener varios parámetros (lista de parámetros) o ninguno. En caso de contener
una lista de parámetros, cada uno de ellos va antecedidos por su tipo y separados por coma. En
caso contrario la lista de parámetros estaría vacía.
En caso de que el método no tenga que retornar ningún valor, simplemente no hay que usar
el return dentro del cuerpo, y se especifica void en el encabezado de la declaración del método
como < Tipo devuelto >.
Sobrecarga de métodos
Suponga que una alternativa para el método edad() de la clase Persona es poder calcular
la edad de una instancia de Persona a través del valor retornado por el reloj interno de la máquina
(el año en este caso).
Lo interesante de este planteamiento es que ahora la propuesta del método edad() dispone
de toda la información para dar un resultado ya que el año a comparar sería obtenido desde el
reloj interno de la máquina.
Suponga que se quieren brindar las dos facilidades, una que calcule la edad a partir de un
año dado y otra que la calcule a partir del año actual adquirido a través del reloj de la máquina.
Evidentemente esta propuesta conlleva a interrogantes interesantes, pues como se ha decidido
brindar las dos facilidades se tienen que definir dos métodos para acceder a estas de forma
independiente, puesto que sus propuestas de solución difieren notablemente.
¿Qué nombres llevarán estos métodos? Como ambos métodos están definidos con el
objetivo de calcular la edad de una instancia de Persona el nombre más lógico con el cual se debe
hacer referencia a cada uno de ellos debe ser edad(), pues otro nombre se contradice con lo que
59 Guía estudiantes Fundamentos de Informática Mora, Coto,Caamaño y Vargas
realmente hace o con el objetivo para lo cual fue diseñado. Luego en la clase Persona existirían
dos métodos con igual identificador, tipo devuelto y solo con la diferencia de que uno necesita de
un parámetro para establecer con respecto a que año se calcularía la edad, mientras que el otro no
necesita del parámetro porque la calcula respecto al año actual tomado del reloj de la máquina.
En una misma clase se pueden definir varios métodos con el mismo nombre siempre y
cuando tomen diferente número o tipo de parámetros, o que en caso extremo si tienen igual
número y tipo de parámetros se diferencien en el orden de los mismos.
Ejemplo:
class A
{
…
int f(int x, int y){...}
int f(string x, int y){...}
int f(int x, int y, int z){...}
int f(int y, string x){...}
int f(int a, int b){...}
}
El ejemplo anterior consta de 5 definiciones del método f. Las cuatro primeras son
aceptadas por el lenguaje, ya que difieren en el tipo, la cantidad u orden de los parámetros. El
último caso no es correcto pues solo se diferencia del primero en los identificadores de los
parámetros. Este produce un error semántico puesto que existe un método previamente definido
que tiene dos parámetros enteros. Es decir, el nombre de los parámetros, no establece diferencia
alguna para la signatura de distintos métodos.
A la posibilidad de disponer de varios métodos con el mismo nombre, pero con diferente
lista de parámetros es lo que se conoce como sobrecarga de métodos, cuando se les invoca el
compilador podrá determinar a cual llamar a partir de los parámetros pasados en la llamada.
Ejemplo
class A
{
…
int f(int x, int y){...}
string f(int x, int y){...}
}
Suponga que a1 es una instancia de A. ¿Qué sucedería con una instrucción de la forma
a1.f(2, 4)?
Evidentemente, no se sabría a cual de las dos variantes de método llamar pues como ya se
mencionó el tipo devuelto no establece diferencias en la llamada a los métodos.
La sobrecarga de métodos se establece entre métodos con igual identificador y diferente
signatura.
Constructores
Los constructores de una clase son métodos especiales que se definen como componentes
(responsabilidades) de ésta y que contienen código a ejecutar cada vez que se cree un objeto de
ese tipo. Éste código suele usarse para la inicialización de los atributos del objeto a crear, sobre
todo cuando el valor de éstos no es constante o incluye acciones más allá de una asignación de
valor. La sintaxis básica de definición de constructores consiste en definirlos como cualquier otro
método pero dándoles el mismo nombre que la clase a la que pertenecen y no indicando el tipo de
valor de retorno.
No tiene sentido que un constructor devuelva objetos por lo que incluir en su definición
un campo <TipoDevuelto> se considera erróneo (incluyendo void).
<nombreTipo>([<parámetros>])
{
Figura 11. Dagrama de la clase Circunferencia
<código>
} Circunferencia
-x: float
-y: float
Ejemplo: Diseñar una clase para representar circunferencias,-radio:
según el
float siguiente UML
+Circunferencia()
+Circunferencia(float, float, float)
+setX(float)
class Circunferencia +setY(float)
+setRadio(float)
{ +getX()
+getY()
prívate: +getRadio()
float x, y; +area()
+longitud()
float radio; ~Circunferencia()
public:
Circunferencia () Fuente: Elaboración propia
{
x = y = radio =0;
}
Circunferencia (float a, float b, float r)
{
x = a;
y = b;
radio = r;
}
void setX(float a){
x = a;
}
void setY(float b){
y = b;
}
void setRadio(float r){
radio = r;
}
float getX ( ){
return (x);
}
float getY ( ){
return (y);
}
float getRadio ( ){
62 Guía estudiantes Fundamentos de Informática Mora, Coto,Caamaño y Vargas
return (radio);
}
float area()
{
return 3.14159 * radio * radio;
}
float Longitud()
{
return 2 * 3.14159 * radio;
}
}
double Area()
{
return Math.PI * radio * radio;
}
Si se decide cambiar la precisión (usar por ejemplo 3.1415926) se tendrían que hacer
modificaciones en todos los lugares donde aparece la secuencia de dígitos.
La última de estas ventajas trae consigo una problemática: ¿Cómo modificar una constante
de una clase ya definida? Esto no es posible pues en principio no se debe contar con el código
Ejemplo:
clase Circunferencia
{
prívate:
float x, y;
float radio;
float Area()
{
return PI * radio * radio;
}
float Longitud()
{
return 2 * PI * radio;
}
}
Persona (string nom, string ape, int annoNac) // constructor con 3 parámetros
{
nombre = nom;
apellidos= ape;
Tiempo de vida de las variables: Es el tiempo durante el cual se puede hacer referencia a la
variable y va desde su creación hasta que dejan de existir. Para el caso de los campos de los
objetos, estos existen durante toda la vida de los objetos. Pero en el caso de las variables locales
(ejemplo, los parámetros), su tiempo de vida es mas limitado pues dejan de existir después que
finalice el bloque de instrucciones al que pertenece.
Alcance o ámbito: Este concepto esta relacionado con la visibilidad de las variables y
especifica desde que código es posible hacer referencia a la variable.
Lo que supuestamente podría dar un error por una posible redefinición de la variable nombre
(por ejemplo) no sucede, puesto que la definición del parámetro se realiza en un bloque más
interno que la del campo. El parámetro, durante su tiempo de vida, oculta al campo.
Para solucionar esta problemática, C++ ofrece la palabra reservada this, que permite
referenciar al objeto en curso y uno de sus usos es diferenciar campos y parámetros (entre otros
usos, que se detallarán en cursos siguentes) con iguales identificadores, en el ámbito que sea
necesario como se muestra en el siguiente ejemplo:
class Persona
{
string nombre;
string apellidos;
uint annoNacimiento;
La palabra reservada this identifica al objeto en curso o actual, o sea, al objeto para el cual
se está ejecutando el código del método en cuestión. Esto permite que a través de this se haga
referencia a las responsabilidades de este objeto y no de algún otro.
Convenciones de código
Las llaves de apertura (“{”) se colocarán siempre en una sola línea, inmediatamente después
de la línea de la instrucción que da pie a su uso y con la misma indentación de dicha
instrucción y las de cierre (“}”) se colocarán de igual forma en una sola línea coincidiendo
con su respectiva llave de apertura.
Los operadores se separarán siempre de los operandos por un carácter "espacio". La única
excepción para esta regla es el operador de acceso a los componentes de objetos y clases (“.”)
que no será separado.
Utilizar comentarios, pero éstos seguirán un formato general de fácil portabilidad y que no
incluya líneas completas de caracteres repetidos. Los que se coloquen dentro de bloques de
código deben aparecer en una línea independiente indentada de igual forma que el bloque de
código que describen.
Para manipular objetos o instancias de tipos de dato que no sean básicos también se
utilizan variables, los objetos tienen que ser creados (tómese por crear un objeto el hecho de
reservar memoria para almacenar los valores de todos sus campos). La creación de objetos se
hace mediante sus métodos constructores. Para efectos del curso sólo vamos a construir objetos
estáticos, pues se ha dejado el tema de punteros para el siguiente curso. De esta manera la
sintaxis sería:
El <tipo de dato objeto> corresponde a una clase definida, se usará como un tipo de dato,
sólo que en este caso se está definiendo un objeto, que será nobmrado mediante el nombre
definido en <variable>. La lista siguiente [(<lista de argumentos>)] es opcional, depende del
constructor que se decida usar, para la clase Persona veamos algunos ejemplos:
{
…….
Persona Juan;
Persona Pedro (“Pedro”, “Pérez”);
Persona Ana ( “Ana”, “Soto”, 1990);
Pedro.setNombre (“Juan”);
67 Guía estudiantes Fundamentos de Informática Mora, Coto,Caamaño y Vargas
….
}
Al ser las variables objeto estáticas se destruyen al terminar el ámbito en que fueron
definidas.
Ejemplos:
1. Clase Temperatura.
Diseñe e implemente una clase Temperatura con la capacidad para almacenar un valor de
temperatura en grados Celsius (C) y obtener su correspondiente en grados Fahrenheit (F)
(F = C * 9 / 5 + 32).
Temperatura
-graCelsius
+Temperatura()
+Fahrenheit()
~Temperatura()
class Temperatura
{
private:
double celsius;
public:
Temperatura (double unaTempCelsius)
{
double Fahrenheit()
{
return thiscelsius * 9.0 / 5 + 32;
}
~Temperatura ()
{
}
}
2. Clase Peso
Diseñe e implemente una clase Peso con que almacena un peso en libras y puede obtener
su equivalente en kilogramos y gramos. (Una libra equivale a 0.453592 kilogramos)
Analizando el enunciado anterior queda explícito que al menos tenemos que implementar una
responsabilidad para almacenar el valor de un peso en libras, el cual también constituye un dato o
información por lo que se implementa a través de una variable; por otra parte se debe poder
obtener la conversión de este valor a gramos y kilogramos donde evidentemente también
intervienen acciones u operaciones por lo que estamos en presencia de dos métodos. En la
implementación de estos métodos veremos como hecho significativo la reusabilidad de código
puesto que si se dispone de una expresión para la conversión a kilogramos, se utiliza el valor
convertido en kilogramos para la conversión a gramos.
Peso
-libras: real
+Peso(real)
+kilogramos()
+gramos()
~Peso()
float Gramos()
{
/* aquí se reutiliza código puesto que se llama al método Kilogramos()
en vez de colocarse explícitamente la expresión para el cálculo de este
*/
return Kilogramos() /1000;
}
~Peso ()
{
}
}
3. Clase Triángulo.
En este ejemplo se implementa una clase llamada Triangulo. Todo triangulo está
compuesto por tres líneas coplanares (que se encuentran en el mismo plano) y que cada línea
tiene una determinada longitud. Así que un triángulo está compuesto por tres líneas cuyas
longitudes representan una terna. Se sabe que una terna es la unión de tres números, por ejemplo
3, 4, 5 es una terna pitagórica, ya que representan las medidas de un triangulo rectángulo. Sin
Entonces para hablar de un triángulo, basta con referirse a tres números que cumplan cierta
condición específica. De ahí que crear y escribir una clase que tenga tres valores pueden
representar los lados de un triángulo.
Triangulo
-lado1: float
-lado2: float
-lado3: float
+Triangulo()
+Triangulo(float, float, float)
+setLado1()
+setLado2()
+setLado3()
+getLado1()
+getLado2()
+getLado3()
-esTriangulo()
+area()
+perimetro()
+Operation1()
~Triangulo()
Según la descripción anterior se definirá una clase Triángulo de esa forma, sin embargo
pueden darse distintas definiciones de la misma, según el uso que se la dará a la clase.
Título: Triángulo.
Atributos: longitudes de tres líneas cualesquiera, área, perímetro.
NOTA: El área y el perímetro se pueden obtener de la longitud de las tres líneas, por lo que no se
consideran para tener un campo, pues pueden ser calculados en cualquier momento, lo cual
facilita el proceso de mantenimiento de la correctitud de los datos, si fueran campos cada vez
que cambia una longitud habría que cambiar los campos de área y perímetro, pero al ser
calculados sólo se llama a los métodos cuando se necesiten.
#include <iostream>
#include <math.h>
using namespace std;
class Triangulo {
private:
float lado1;
float lado2;
float lado3;
public:
// método constructor sin parámetros
Triangulo( ){
this lado1 = 0;
this lado2 = 0;
thislado3 = 0;
}
// método constructor con parámetros
Triangulo ( float primero, float segundo, float tercero){
thislado1 = primero;
thislado2 = segundo;
thislado3 = tercero;
}
// métodos set
void setLadoUno(float primero){
thislado1 = primero;
}
void setLadoDos (float segundo){
thislado2 = segundo;
// fin de la clase
En este ejemplo la realización de los demás métodos requieren una mayor explicación,
como veremos más adelante.
4. Clase Numero.
Definiremos una clase Numero útil para el propósito de esta guía, pues permitirá definir y
explicar métodos y estructuras de programación. El propósito de la misma es tener una clase para
cada número y definir varios métodos clásicos, como par(), abundante(), etc.
Numero
-num: uint
+Numero()
+Numero(uint)
+esPar()
+esAbundante()
+........()
+........()
#include <iostream>
using namespace std;
class Numero {
private:
uint num;
public:
// método constructor sin parámetros
Numero ( ){
thisnum = 0;
}
// método constructor con parámetros
Numero( uint num){
thisnum = num;
}
// métodos set
void setNum( uint num){
thisnum = num;
}
// métodos obtener
uint getNum ( ){
return (thisnum);
} Figura 15. Diagrama de clase Fecha
};
// fin de la clase Fecha
-dia: int
-mes: int
-anno: int
5. Clase Fecha.
+Fecha()
Se define una clase Fecha que debe mantener el día, +Fecha(int, int, int)
hora y año. Es una clase que podemos usar mucho +setDia(int)
+setMes(int)
en relación con otras clases. +setAnno(int)
+getDia()
+getMes()
+getAnno()
class Fecha +annoBisiesto()
+diaMes()
{ +incrementaDia()
~Fecha()
prívate:
int día, mes, año;
public:
Fecha () Fuente: Elaboración propia
{
~Fecha() {
// se destruye la instancia
}
}
if (<condición>)
<bloque de instrucciones>;
En el ejemplo podemos usar esta instrucción determinando el cálculo del área y perímetro
siempre y cuando el triángulo lo sea, para esto hayque comprobar que asi sea mediante un
método que sólo será usado por otros métodos en la clase, determinar si la terna es un triángulo,
de tal manera:
float perimetro ( ){
if (esTriangulo())
return (thislado1 + this lado2 + thislado3);
}
En este último método se hace un cálculo que ya fue calculado en el perímetro() por lo
que se podría mejorar el código de tal manera que se llame:
float area ( ){
float s;
if (esTriangulo()) {
s = (perímetro())/2;
return (sqrt( s*(s- thislado1)*(s- thislado2)*(s- thislado3)));
}
}
De esta manera sólo si la terna conforma un triángulo se harán los cálculos pertinentes,
más adelante se verán otras formas más elegantes de determinar si es un triángulo, desde los
constructores directamente, para evitar estas preguntas.
if (<condición>)
<bloque de instrucciones 1>;
else
<bloque de instrucciones 2>;
if (<condición>)
<bloque de instrucciones 1>;
[else
<bloque de instrucciones 2>;]
Nota: Vale aclarar que un bloque de instrucciones puede comenzar a su vez con otro if.
Continuando con el ejemplo del triángulo, el método que determina si una terna es un
triángulo requieren una estructura más compleja, como se verá a continuación:
Cómo este método sólo se usará por otros métodos de la clase, es posible definirlo como
un método privado.
Ejemplo: Según la clase Fecha definida anteriormente se requiere que les permita a sus objetos
incrementarse en un día. Este algoritmo es muy simple, siempre y cuando el objeto Fecha no se
encuentre en el último día de su respectivo mes pues en este caso únicamente es necesario
incrementar el día. Determinar si el mencionado objeto Fecha se encuentra en el último día de su
respectivo mes nos lleva a una acción intermedia que es determinar los días del mes.
Un posible algoritmo para retornar los días de un mes se resume a devolver 30 en el caso
de los meses 4, 6, 9, 11; cuando el mes sea 2 se devuelve 28 si el año no es bisiesto y 29 en caso
contrario; finalmente se retorna 31 para el resto de los meses.
class Fecha
{
prívate:
}
Note que en el caso de que el valor de un mes sea 2, debe verificarse otra condición, en
este caso si el año es o no bisiesto. Esto es lo que se conoce como if anidado, es decir un if como
parte de otro if. Esto muestra la capacidad de la instrucción alternativa if para expresar el caso de
que una sentencia que sigue a un if sea a su vez otro if, o que la sentencia que sigue a un else sea
otro if, y esta circunstancia puede repetirse varias veces de forma que se disponga de una serie de
decisiones anidadas.
Una vez que se dispone del método díasMes() se puede implementar entonces el método
incrementaDía(). El algoritmo en este caso consiste en determinar si el día de la Fecha en
cuestión coincide con el último día de su respectivo mes (método DíasMes), en caso negativo
apenas se incrementa el día en 1 y en caso contrario día toma valor 1 y el mes también se
incrementa en 1 exceptuando cuando es 12 (diciembre), que entonces toma valor 1 (enero) y año
se incrementa en 1.
void incrementaDía()
{
if (día != díasMes())
día++;
else
…..
fecha1.día ( 32);
fecha1.mes( 2);
La integridad de los objetos Fecha se ha perdido porque existe total acceso a las variables
de los objetos Fecha y porque el constructor “no se preocupa” por verificar que se garantice la
integridad durante la creación del objeto, es decir, los objetos se crean independientemente de
que los valores de inicialización no correspondan con datos que garanticen objetos del dominio
Fecha.
Este control sobre el acceso a los campos se logra a través del mecanismo de
encapsulamiento, el cual se consigue añadiendo modificadores de acceso en las definiciones de
los miembros y tipos de datos. Estos modificadores constituyen palabras reservadas del lenguaje
que se les anteponen para indicar desde que código puede accederse a ellos, entendiendo por
acceder cualquier cosa que no sea definirlo.
En caso de no especificarse modificador alguno, se considera por defecto u omisión que los
miembros de un tipo de dato sólo son accesibles desde código situado dentro de la definición del
mismo tipo. En C++ y para los efectos de este curso se utilizan los siguientes modificadores:
public: indica que la componente puede ser accedida desde cualquier código (+).
private: sólo puede ser accedido desde el código de la clase a la que pertenece. Es lo
considerado por defecto (-).
fecha1.día (32);
Ejemplo: ¿Cómo podría ahora juan suministrar la información sobre su fecha de nacimiento?
Esto no es posible, pues se le oculta por completo a los clientes el acceso a las responsabilidades
de Fecha que almacenan sus respectivos valores. Para solucionar esto se deben definir los
métodos modificadores y accesores de los que hablamos anteriormete que retornan el valor de las
respectivas variables.
Entonces a partir de este momento, se tendría acceso a los valores de las variables día, mes y año
a través de sus respectivos métodos de acceso como se muestra seguidamente:
{
fecha1.setDía(valor);
fecha1.setMes(valor);
fecha1.setAño(valor);
fecha1.getDía();
fecha1.getMes();
fecha1.getAño();
}
Para controlar la integridad de los campos en cuanto a los valores que pueda recibir, se
debe llevar a cabo una programación que verifique las condiciones dentro de las propios métodos.
En el ejemplo siguiente se muestra otro refinamiento de la clase Fecha a partir de la verificación
de las condiciones en su constructor.
En este caso la precondición que tienen que cumplir los clientes de la clase Fecha (y que
será verificada por el constructor) es que la terna de valores día/mes/año a pasar en el constructor
como parámetro, permita formar una instancia de dicho dominio de objetos. La post-condición a
cumplir por el constructor de Fecha es garantizar la creación correcta del objeto. En este caso, si
no se cumplen las condiciones, el constructor ha decidido crear un objeto con valores
preestablecidos poco comunes (1/1/1880) que garanticen la integridad del mismo.
Ejemplo: implementar una variante del método díasMes() de la sección anterior donde se
invierta el orden de evaluación de los dos últimos casos más generales.
Con el objetivo de hacer más legibles y claros los códigos de implementación de los
algoritmos donde se tienen múltiples casos, la mayoría de los lenguajes brinda una instrucción de
alternativa múltiple (switch case) cuya sintaxis se muestra seguidamente:
switch (<expresión>)
{
case <valor 1>: <bloque de instrucciones 1>
[break]
case <valor 2>: <bloque de instrucciones 2>
[break]
Los valores indicados en cada rama del switch han de ser expresiones constantes que
produzcan valores de algún tipo básico entero, de una enumeración, de tipo char o de tipo string.
Además, no puede haber más de una rama con el mismo valor.
Para ejemplificar esta nueva estructura sintáctica se define a continuación una variante del
método díasMes()
int díasMes()
{
switch (mes)
{
case 4: return 30;
case 6: return 30;
case 9: return 30;
case 11: return 30;
case 2 : if (bisiesto( ))
return 29;
else
return 28;
default: return 31;
}
En el caso que varias ramas coincidan en sus respectivos bloques de instrucciones, éstas
se pueden agrupar como se muestra seguidamente, en una nueva versión del métdo:
int díasMes()
{
switch (mes)
{
case 4: case 6: case 9: case 11: return 30;
case 2 : if (bisiesto( ))
return 29;
else
return 28;
default: return 31;
}
Para implementar el algoritmo que determina la clasificación del triángulo es evidente que se
tiene un análisis de casos con tres subdominios: los tres lados iguales (equilátero), solamente dos
lados iguales (isósceles) y los tres lados diferentes (escaleno).
string clasifica()
{
if (lado1 == lado2 && lado2 == lado3)
return "Equilátero";
else
if (lado1 == lado2 || lado2 == lado3 || lado3 == lado1)
return "Isósceles";
Uno de los ciclos más conocidos y usados es el basado en la instrucción for y que suele
estar controlado por un contador o variable de control y que tiene la siguiente sintaxis:
<instrucciones 1>; se ejecutará una sola vez al inicio del ciclo, generalmente se realizan
inicializaciones y declaraciones de variables.
<expresión>; es evaluada en cada ciclo y en dependencia del valor que devuelva, dependerá
que el bucle continúe ejecutándose (valor de la evaluación true) o no (false).
<instrucciones 2>; es ejecutado siempre en cada ciclo al terminar de ejecutar todas las
instrucciones que pertenecen al bucle for en cuestión. Por lo general puede contener
alguna actualización para las variables de control.
while <condición>
<instrucciones>
Ejemplo: siempre en la clase Numero, considere la suma de los números pares que van del
campo num a un número dado como parámetro al método.
do
<instrucciones>
while <condición>;
Ejemplo: Con base en la clase Número, vamos a diseñar un método que determine cuál es el
int menor ( ) {
int potencia2 = 1; // variable que almacena las potencias de 2
int n = 0; // variable que irá contando las veces que se eleva a la potencia de 2
do
potencia = potencia * 2; // se calcula una nueva potencia
n ++; // se incrementa n
Una clase contenedora como la palabra lo dice contiene un conjunto de datos del mismo
tipo.
En este apartado detallaremos clases que contienen una secuencia de valores del mismo
tipo (todos del mismo tipo, sin embargo el tipo puede ser cualquiera: tipos básicos u objetos),
siendo significativo el orden (posición en la secuencia) entre ellos.
Arreglos unidimensionales
De forma general para declarar un arreglo se colocan corchetes vacíos entre el tipo y el
nombre de la variable como se muestra a continuación:
temperaturas 28 -5
notas 5 4 3 4 5
nombres “Ana”
Para acceder a los elementos de un arreglo se utilizan índices (variables enteras) como se
muestra a continuación, que se cambia el valor de la primera posición del arreglo temperatura:
Es importante tomar en cuenta que el índice de los arreglos en lenguajes como C++
comienza en cero (0), esto significa que el primer elemento de un arreglo tendrá siempre índice
cero (0), mientras que el último elemento tiene como índice la longitud del mismo (cantidad de
elementos) menos uno.
Los arreglos una vez creados son estáticos, es decir no pueden cambiar su tamaño.
En este ejemplo se define una clase contenedora con un arreglo de tamaño fijo, por
simplicidad, para trabajar métodos clásicos de manipulación de arreglos, con 3 constructores
diferentes como ejemplos y al ser la definición de vector privada, se definen métodos set y get
para usar las posiciones del arreglo cuando estas son accedidas desde el main() :
class Contenedor
{
private:
int vector[5];
public:
Contenedor (){ // constructor de inicializa las 5 posiciones con cero
for(int i=0;i<5;i++)
vector[i]=0;
}
Contenedor (int a){ // constructor que inicializa todas las posiciones con el valor
// recibido
for(int i=0;i<5;i++)
vector[i]=a;
}
Contenedor (int a, int b,int c, int d,int e) {
vector [0]=a;
vector [1]=b;
vector [2]=c;
vector [3]=d;
vector [4]=e;
}
setPos(int i, int valor) {
vector [i]= valor;
}
getPos (int i) {
return vector[i];
}
};
int main()
{
Contenedor A;
Contenedor A1(5);
Contenedor B(4,6,8,9,2);
….
}
void mostrar(){
for(int i=0;i<5;i++) // observe el uso de vector en métodos de la clase
cout<< "elemento "<<i<<" es: "<<vector [i]<<endl;
}
int sumaVector(){
int suma = 0;
for (int i=0; i< 5; i++)
suma = suma + vector [i];
return suma;
}
int valorMax() {
int max = vec[0];
for(int i=1; i<5; i++)
if (vec[i]>max) {
max=vec[i];
}
return max;
}
Otra versión de este método es la siguiente, en esta hay menos variables, ¿será más difícil
de entender?:
int posMax(){
int pos=0;
for (int i=1; i<5; i++)
if (vector[i]>vector[pos]) {
pos= i;
}
return pos;
}
6. Ejercicio: escriba un método que devuelva el valor mínimo del vector y otro que devuelva la
posición en la cual ocurre el valor mínimo del vector.
7. Escriba un método que intercambie los valores máximo y mínimo del vector
void intercambiaMaxMin() {
int i,j, aux;
i = posMax(); // observe el llamado a métodos dentro de métodos de la clase
j = posMin();
aux= vector [i];
vector [i]=vector [j];
vector [j]=aux;
}
void intercambiaMaxMin(){
int aux;
aux = valorMax();
97 Guía estudiantes Fundamentos de Informática Mora, Coto,Caamaño y Vargas
vector [posMax()] = valorMin();
vector [posMin()] = aux;
}
8. Escriba un método para invertir los elementos del vector, para realizarlo de manera más fácil
y modular, se diseña un método que invierte dos posiciones
void invierteVector() {
int k=4,i=0;
while (i<k ) {
intercambiaPos( i, k)
i++;
k--;
}
}
void invierteVector(){
int k,i;
for(i=0,k=4; i<k; i++,k--) {
intercambiaPos( i, k)
}
}
class Contenedor
{
private:
int vector[5];
public:
Contenedor (){ // constructor de inicializa las 5 posiciones con cero
for(int i=0;i<5;i++)
}
int posMax(){
// ejercicio
}
void intercambiaMaxMin(){
int aux;
aux = valorMax();
vector [posMax()] = valorMin();
vector [posMin()] = aux;
}
void intercambiaPos ( int i, int j) {
int temp;
temp = vector [i];
vector [i] = vector [j];
vector [j]=temp;
}
void invierteVector(){
int k,i;
for(i=0,k=4; i<k; i++,k--) {
intercambiaPos( i, k)
}
};
int main() {
Contenedor A;
Contenedor A1(5);
Contenedor B(4,6,8,9,2);
cout<<"Vector A : "<<endl;
A.mostrar();
cout<<”la suma de los elementos de B es:” << B.sumaVector()<<endl;
cout<<"El elemento máximo del vector B es: " << B.valorMax() << endl;
B.invierteVector();
cout<<"El vector B invertido queda como: "<<endl;
system (“pause”);
El ejemplo anterior plantea un arreglo de tamaño fijo, como paso inicial para entender el
acceso a un arreglo, sin embargo este tipo de arreglos no es muy útil en situaciones de la vida
real, por eso que es necesario definir un arreglo que manteniendo las reglas de definición de C,
pueda adaptarse a distintos tamaños de arreglos, la estrategia será definir un arreglo de largo
máximo, y dependiendo de cada solución se definirá una cantidad y un tamaño según la
necesidad, obviamente todavía no es la solución óptima en eficiencia pues el excedente en
tamaño es desperdicio de memoria, pero se verá posteriormente una mejor estrategia, de nuevo
utilizando punteros, que no es tema del curso.
#include <iostream>
class Contenedor {
private:
int vector[100]; // se define 100 como el máximo permitido
int tamano; // cada solución puede definir un tamaño diferente
int cantidad; // cantidad mantiene el número real de elementos al momento, nunca
// puede ser mayor a tamaño
public:
Contenedor ( ) {
cantidad=0;
tamano= 10;
for (int i=0;i< tamano;i++){
vector [i]=0;
}
}
Contenedor (int n) {
cantidad=0;
tamano= n;
for (int i=0; i< tamano; i++){
vector [i] = 0;
}
}
int setCantidad( int can){
}
~Vector ( ) { }// toda la memoria es estática
};
Con la definición de esta clase vamos a trabajar otros métodos, dejando claro que pueden
resolverse con cualquiera de los dos esquemas, pero para efecto de usar un contenedor más
flexible, seguiremos usando esta nueva definición, y para ello resolveremos varios problemas:
2. Escriba un método que elimine el último elemento del vector, en este caso se establece que
hay un elemento menos, aunque realmente sigue estando ahí, pero ningún método tendrá
acceso a él, pues todos están ajustados a la variable cantidad.
4. Escriba un método que permita eliminar el elemento en la posición pos del arreglo.
system("pause");
return 0;
}
Búsqueda
Búsqueda binaria
Intervalo de búsqueda
vector 2 4 7 8 10 12 13
0 1 2 3 4 5 6
elem 7
IZQ DER
Intervalo de búsqueda
Valores 2 4 7 8 10 12 13
0 1 2 3 4 5 6
Elem 7
IZQ DER
Tomar el 4 y compararlo con el 7, como el 4 es menor hay que buscarlo hacia la derecha.
Intervalo de búsqueda
Valores 2 4 7 8 10 12 13
0 1 2 3 4 5 6
Elem 7
IZQ DER
En este esquema de búsqueda se realiza siempre la misma acción que es buscar el número
en un intervalo que varía en dependencia de si el número buscado sea mayor o menor que el que
ocupa la posición del medio.
El algoritmo cuenta con dos condiciones de término o fin, la primera que se encuentre el
número y la segunda que el número no esté (esta condición se puede cumplir analizando que el
intervalo en el que hay que buscar tenga longitud positiva).
Ordenamiento
Cuando se habla de ordenar lo primero que viene a la mente es ordenar números, pero en
la vida diaria ordenamos distintos tipos de objetos siguiendo diversos criterios.
Por ejemplo las palabras mesa, computadora y artista se pueden ordenar por orden
alfabético
o por su longitud
Se verán en este curso los métodos o algoritmos más comúnmente usados, para que el
estudiante se haga una idea del proceso que llevan a cabo cada uno de ellos.
El método más usado para ordenar listas de elementos no demasiado grandes es el método
de burbujas. La idea básica que hay detrás del nombre es imaginar que el arreglo a ordenar se
Se hacen repetidos pases sobre el arreglo desde el final hacia el principio. Si dos objetos
adyacentes están desordenados entonces se intercambian de posición. El efecto de esta operación
es que en el primer pase el objeto menos “pesado” es llevado hacia la primera posición; en el
segundo pase, el segundo objeto menos pesado (que no es más que el menos “pesado” de los que
quedan) es llevado a la segunda posición. De forma general en el pase i-ésimo, el i-ésimo objeto
menos “pesado” es llevado a la posición i.
void burbujas () {
int aux;
for (int i = 0; i <= cantidad - 2; i++)
for (int j = cantidad - 1; j >= i+1; j--) {
if (vector[j] < vector[j-1]) {
aux= vector [j]
vector [j]= vector [j-1]
vector [j-1]=aux
}
}
}
Si se aplica el método de burbujas para ordenar los números {8, 4, 5, 9, 7, 2} se puede ver
en la figura como queda el arreglo después de cada pasada, la línea indica que los elementos que
están por encima de ella ya están ordenados y en su posición.
4 8 4 4 4 4
5 4 8 5 5 5
9 5 5 8 7 7
7 9 7 7 8 8
2 7 9 9 9 9
Inicio i =1 i =2 i =3 i =4 i =5
void insercion () {
int aux;
for (int i = 1; i <= cantidad - 1; i++) {
int j = i ;
while ( j >= 1 && vector [j] < vector[j-1]) {
aux= valores[j]
vector [j]= vector [j-1]
8 4 4 4 4 2
4 8 5 5 5 4
5 5 8 8 7 5
9 9 9 9 8 7
7 7 7 7 9 8
2 2 2 2 2 9
Inicio i =2 i =3 i =4 i =5 i =6
El método es el siguiente:
void ordenaSeleccion() {
int i, k, posMenor, temp;
for(k = 0; k < cantidad-1; k++) {
posMenor = k;
for(i = k+1; i < cantidad; i++) {
if(vector [i] < vector [posMenor]) {
posMenor = i;
if (posMenor != k) { // intercambio
temp = vector [posMenor];
111 Guía estudiantes Fundamentos de Informática Mora, Coto,Caamaño y Vargas
vector [posMenor] = vector [k];
vector [k] = temp;
}
}
}
}
}
Los arreglos descritos anteriormente, en los que se puede acceder a sus elementos
utilizando un solo índice se denominan arreglos unidimensionales, vectores o de una sola
dimensión. De la misma forma, si se tiene más de un índice, se denominan arreglos
multidimensionales.
Tómese como ejemplo la siguiente tabla que representa una abstracción o simulación de
cómo se pudiesen representar los arreglos bidimensionales, aunque realmente en memoria no se
representan de esa forma, en general se conocen como arreglos con filas (horizontales) y
columnas (verticales).
columnas
1 2 3
filas
4 5 6
char tabla1[6][10];
class Contenedor{
private:
int matriz[tam][tam];
public:
Contenedor (){ // constructor predefinido
for (int i = 0; i<tam; i++)
for (int j = 0; j<tam ; j++)
matriz[i][j]=0;
}
Contenedor (int a){ // constructor para inicializar todas las posiciones con el valor a
for (int i = 0; i<tam; i++)
for (int j = 0; j<tam ; j++)
matriz[i][j]= a;
}
void llenarMatriz() {
int valor;
for (int i = 0; i<tam;i++)
for (int j = 0; j<tam;j++) {
cout<<"valor["<<i<<"]["<<j<<"]: ";
cin>>valor;
setPos(i,j,valor);
}
int main(){
Contenedor mat1;
114 Guía estudiantes Fundamentos de Informática Mora, Coto,Caamaño y Vargas
Contenedor mat2(5);
cout<<"Llenando la matriz"<<endl;
mat1.llenarMatriz();
}
Ejemplos:
void mostrar()
for (int i = 0; i<tam;i++) {
for (int j = 0; j<tam;j++) {
cout<<matriz[i][j]<<" ";
}
cout<<endl;
}
cout<<endl;
}
int suma() {
int suma = 0;
for (int i = 0; i<tam;i++)
for (int j = 0; j<tam;j++)
suma = suma + matriz[i][j];
return suma;
}
float promedio() {
return (float) suma() / (tam*tam); // casting
}
4. Escriba un método que multiplique todos los elementos de la matriz por un escalar (recibido
como parámetro)
5. Escriba un método que reciba como parámetro int elem y que retorne true si un elemento
determinado se encuentra en la matriz y false si no.
7. A la suma de los elementos de la diagonal principal de una matriz cuadrada se le llama traza
de la matriz. Escriba un método que calcule la suma de los elementos de la diagonal principal
de la matriz.
int sumaDiagonal(){
int i = 0, suma=0;
for (i=0; i< tam; i++){
suma = suma + matriz[i][i];
}
return suma;
}
8. Una matriz se dice que es la matriz identidad si tiene todos sus elementos nulos excepto los
de la diagonal principal que son iguales a 1. Escriba un método que retorne true si la matriz
es la matriz identidad y false si no.
9. Una matriz A de tamaño mxn se dice que es una matriz simétrica si:
m=n y
si cumple que A [x][y] = A[y][x] para 1<= x<= m y 1<= y <= n.
bool esSimetrica() {
for(int i = 0;i <tam;i++) {
for(int j = 0;j < i ;j++)
if (matriz[i][j]!=matriz[j][i])
return false;
}
return true;
}
10. Escriba un método que busque un elemento determinado en una matriz e indique cuantas
veces lo encuentra.
12. Defina un método que calcule la suma de los elementos de la diagonal inversa de la matriz.
int sumaDiagonalInversa(){
int suma=0;
for (int i=0; i<tam; i++)
suma = suma + matriz[i][(tam-1)-i];
return suma;
}
void llenarMatriz() {
int valor;
for (int i = 0; i<tam;i++)
for (int j = 0; j<tam;j++) {
cout<<"valor["<<i<<"]["<<j<<"]: ";
cin>>valor;
setPos(i,j,valor);
}
void mostrar()
for (int i = 0; i<tam;i++) {
for (int j = 0; j<tam;j++) {
cout<<matriz[i][j]<<" ";
}
cout<<endl;
}
cout<<endl;
}
int suma() {
int suma = 0;
for (int i = 0; i<tam;i++)
for (int j = 0; j<tam;j++)
suma = suma + matriz[i][j];
return suma;
}
float promedio() {
return (float) suma() / (tam*tam); // casting
}
void multiplicarEscalar (int escalar){
for (int i = 0; i<tam;i++)
for (int j = 0; j<tam;j++)
matriz[i][j] = matriz[i][j] *escalar;
}
bool encuentraElem (int num) {
for(int i = 0;i <tam;i++) {
for(int j = 0;j <tam;j++)
if (matriz[i][j]== num)
return true;
}
int sumaDiagonalInversa(){
int suma=0;
for (int i=0; i<tam; i++)
suma = suma + matriz[i][(tam-1)-i];
return suma;
}
~Matriz() { // memoria estática }
};
int main(){
int valor, x,y;
Contenedor mat1;
Contenedor mat2(5);
cout<<"Llenando la matriz"<<endl;
mat1.llenarMatriz();
if (mat1.esIdentidad())
cout <<"La matriz SI es la matriz identidad "<<endl;
else
cout <<"La matriz NO es la matriz identidad "<<endl;
if (mat1.esSimetrica())
cout <<"La matriz SI es simetrica "<<endl;
else
cout <<"La matriz NO es simetrica "<<endl;
mat1.buscaPosMinimo(x,y);
cout<< "La posicion del valor minimo en la matriz es ["<<x<<"]["<<y<<"]"<<endl;
Todos los ejercicios se han trabajado con una matriz cuadrada, es decir de tam* tam, sin
embargo se puede hacer un cambio pequeño pero significativo en el cual los ejercicios pueden
adaptarse a matrices que no son cuadradas, por ejemplo definir como constantes fil =n y col =m,
con n y m números enteros definidos. Veamo un ejemplo de clase contenedora definida de esta
manera, con uno de los métodos resueltos anteriormente, se dejará el main() como ejercicio, por
no tener mayor dificultad:
class Contenedor{
private:
int matriz[fil][col];
public:
Contenedor (){ // constructor predefinido
for (int i = 0; i<fil; i++)
for (int j = 0; j<col ; j++)
matriz[i][j]=0;
}
122 Guía estudiantes Fundamentos de Informática Mora, Coto,Caamaño y Vargas
Contenedor (int a){ // constructor para inicializar todas las posiciones con el valor a
for (int i = 0; i<fil; i++)
for (int j = 0; j<col ; j++)
matriz[i][j]= a;
}
void setPos (int i, int j, int valor) {
matriz[i][j] = valor;
}
int getPos (int i, int j) {
return matriz[i][j];
}
void llenarMatriz() {
int valor;
for (int i = 0; i<fil;i++)
for (int j = 0; j<col;j++) {
cout<<"valor["<<i<<"]["<<j<<"]: ";
cin>>valor;
setPos(i,j,valor);
}
void mostrar()
for (int i = 0; i<fil;i++) {
for (int j = 0; j<col;j++) {
cout<<matriz[i][j]<<" ";
}
cout<<endl;
}
cout<<endl;
}
int suma() {
int suma = 0;
for (int i = 0; i<fil;i++)
for (int j = 0; j<col;j++)
suma = suma + matriz[i][j];
return suma;
}
Jacobson, I. (1998). Applying UML in The Unified Process. Presentación. Rational Software.
Presentación disponible en http://www.rational.com/uml como UMLconf.zip
Martín, J.; Odell, J. (1994). Análisis y Diseño Orientado a Objetos. Editorial Prentice Hall, 1era
edición, México.