Вы находитесь на странице: 1из 240

Material preparado por Rodrigo Sandoval U en Marzo 2004

PONTIFICIA UNIVERSIDAD CATLICA DE CHILE


ESCUELA DE INGENIERA
DEPARTAMENTO DE CIENCIA DE LA COMPUTACIN
IIC 1102 INTRODUCCIN A LA PROGRAMACIN



Introduccin a la
Programacin
Orientada a Objeto
en C#



Introduccin a la Programacin (Orientada a Objetos) Rodrigo Sandoval U.
IIC 1102 Pgina: 1
Introduccin
La presente documentacin contiene la materia vista en el curso IIC1102, Introduccin a la Programacin,
dictado por el Departamento de Ciencia de la Computacin, de la Escuela de Ingeniera de la Pontificia
Universidad Catlica de Chile, particularmente en su versin Orientada a Objeto, del ao 2004.
Por qu ensear programacin?
Dentro de una formacin cientfica-analtica, hay tres objetivos principales que se persiguen con este
curso.
Primero, desarrollar las habilidades de los alumnos para resolver problemas de complejidad ms
avanzada. Es adecuado adquirir la capacidad de analizar un problema, luego descomponerlo en partes,
para finalmente describir una solucin con detalle. Esencialmente se fomenta el desarrollo de un
pensamiento lgico, que posteriormente resulta en un importante aporte en las habilidades
organizacionales.
En segundo lugar, dar a los alumnos una nocin del potencial y limitaciones de la tecnologa
computacional. Aprender a programar es una de las maneras ms efectivas de lograr un contacto
profundo con los computadores que hoy forman parte importante de la sociedad. Esto permite lograr el
efecto de entender que no es el computador lo ms importante, sino que la inteligencia que el
programador y usuarios eficiente aportan.
Finalmente, escribir programas y disear soluciones debe ser entretenido. No debe menospreciarse la
sensacin de satisfaccin que se logra al completar un interesante y desafiante proyecto de
programacin.
Qu incluye este curso?
Este curso aborda temas tan extensos como La Resolucin de Problemas, donde se analizan
estrategias metodolgicas que permiten analizar un problema y plantear una solucin estructurada, as
como detalles sintcticos de la programacin en el lenguaje C#, que forma parte de la plataforma .NET de
Microsoft. En el proceso, diversos captulos se enfocan en problemticas puntuales que son cubiertas de
una u otra manera por los diferentes lenguajes de programacin, pero que en esta ocasin se revisan en
funcin de C#.
Destaca tambin un fuerte nfasis en la revisin de algoritmos de resolucin de problemas especficos,
como son los captulos de Algoritmos Numricos, Recursividad, Ordenamiento y Bsqueda.








Material preparado por Rodrigo Sandoval U en Marzo 2004,
basado en los apuntes de clase del curso IIC1102, ao 2003, de M. Nussbaum, Marcos Seplveda, et.al
Los ejemplos fueron adaptados por MSR Lab del DCC de la Escuela de Ingeniera de la P. Universidad Catlica de Chile

PONTIFICIA UNIVERSIDAD CATLICA DE CHILE
ESCUELA DE INGENIERA
DEPARTAMENTO DE CIENCIA DE LA COMPUTACIN
IIC 1102 INTRODUCCIN A LA PROGRAMACIN
Profesor: Rodrigo Sandoval U.

Captulo I - Resolucin de Problemas

1 CONCEPTOS DE RESOLUCIN DE PROBLEMAS.................................................................................... 1
1.1 EL PROCESO DE RESOLUCIN DE PROBLEMAS.................................................................................................1
1.2 DEFINICIONES.................................................................................................................................................1
1.2.1 Problema................................................................................................................................................ 1
1.2.2 Objeto..................................................................................................................................................... 2
1.2.3 Instancia................................................................................................................................................. 2
1.2.4 Modelo ................................................................................................................................................... 2
1.3 ALGORITMOS..................................................................................................................................................2
1.3.1 Qu es un Algoritmo?........................................................................................................................... 2
1.3.2 Cmo se especifican o describen los algoritmos?................................................................................ 3
1.3.3 Existe un nico algoritmo de solucin? ............................................................................................... 3
1.3.4 Qu es una metodologa?..................................................................................................................... 3
1.3.5 Las soluciones tambin pueden tener problemas ................................................................................... 4
2 ORIENTACIN A OBJETOS ........................................................................................................................... 5
2.1 TERMINOLOGA BSICA DE LA PROGRAMACIN ORIENTADA A OBJ ETO ........................................................6
3 ESTRATEGIAS PARA LA SOLUCIN DE PROBLEMAS.......................................................................... 7
3.1 METODOLOGA DE RESOLUCIN DE PROBLEMAS............................................................................................7
3.2 DESCRIPCIN GRFICA DE SOLUCIONES.........................................................................................................8
3.2.1 Diagrama de Casos de Uso - UML........................................................................................................ 8
3.2.2 Diagrama de Clases UML................................................................................................................... 9
3.2.3 rboles de Decisin ............................................................................................................................. 10
3.2.4 Ejemplo: rbol de Decisin: Qu hago el sbado por la noche?...................................................... 10
3.3 EJ EMPLOS DE APLICACIN DE LA METODOLOGA.........................................................................................11
3.3.1 Simulando la Ejecucin de un Penal.................................................................................................... 11
3.3.2 Simulando la preparacin de un pastel................................................................................................ 14
3.3.3 Cambio de neumtico desinflado ......................................................................................................... 16
3.3.4 Llamada Telefnica.............................................................................................................................. 18


Intro a la Prog. Resolucin de Problemas Rodrigo Sandoval U.
IIC 1102 Pgina: 1
1 Conceptos de Resolucin de Problemas
Resolver problemas no es trivial, pues es necesario comprender qu se quiere resolver, encontrar las
herramientas adecuadas para resolver el problema, y luego implementar la solucin con las herramientas
disponibles.
1.1 El proceso de resolucin de problemas

1.2 Definiciones
1.2.1 Problema
Un problema es una abstraccin de la realidad para la cual nos interesa conocer una solucin,
entendiendo que una solucin altera el estado inicial del problema, llevndolo a un estado deseado. Es
decir, una solucin es un procedimiento o mtodo para establecer el mecanismo de transformacin del
mundo que nos lleve a satisfacer ciertos requerimientos.

Intro a la Prog. Resolucin de Problemas Rodrigo Sandoval U.
IIC 1102 Pgina: 2
1.2.2 Objeto
El mundo est compuesto de objetos fsicos y simblicos. Los objetos en programacin OO son
elementos simblicos que representan objetos fsicos del mundo real.
En particular se utiliza el trmino clase para describir un tipo de objeto en particular, que tiene ciertas
caractersticas comunes.
1.2.3 Instancia
Una instancia es un objeto especfico que se puede relacionar con otras instancias u objetos del mismo
tipo o de otro tipo. Especficamente, una instancia es un objeto de una clase especfica.
1.2.4 Modelo
Toda estructura que se utiliza para dar razn y abstraer de la realidad a un conjunto de acciones o
fenmenos que guardan entre s ciertas relaciones.
El ejemplo ms simple de un modelo es una instancia, la que no tiene relacin alguna mas que la de ella
misma con su objeto respectivo.
Modelos ms complejos son los arreglos, registros, archivos y combinaciones de stos. Los lenguajes de
programacin normalmente proveen varias combinaciones (no todas) de modelos ms complejos. Un
enfoque ms reciente (aos 90) para la resolucin de problemas, se basa en la utilizacin de Objetos,
estableciendo un esquema en que cada elemento del mundo real se representa con mayor precisin y
fidelidad, logrando as soluciones modulares (compuestas por partes hasta cierto punto independientes,
que potencialmente pueden reutilizarse en otros modelos) y con encapsulacin (que logra ocultar la
complejidad de soluciones en ciertos mdulos, evitando que los participantes de la solucin tengan que
dominar cada parte de sta). A este esquema se le conoce como Orientacin a Objetos.
El diseo e implementacin de un modelo son fundamentales para la solucin de un problema
computacional.

1.3 Algoritmos
1.3.1 Qu es un Algoritmo?
Un algoritmo es un procedimiento detallado y preciso para resolver un problema en pasos (o etapas),
cada uno de los cuales toma un tiempo finito.
Los algoritmos se especifican en trminos de un conjunto de operaciones bsicas, en las que se
involucran diferentes objetos que forman parte de la solucin. Se manipulan las variables del algoritmo y,
en general, cambiar el mundo en que se desarrolla el problema. Algunas de estas operaciones permiten
tambin controlar el flujo de ejecucin del algoritmo. Llevando a cabo las operaciones que componen el
algoritmo, segn su estructura de control, obtendremos la solucin para el problema en cuestin.
El flujo de las operaciones especifica la secuencia en que se llevan a cabo las actividades:
Toma de decisiones: La secuencia se decide de acuerdo a ciertas condiciones que dependen de
los datos del algoritmo.
Iteracin: Permite especificar la repeticin de operaciones, tambin en forma controlada por
condiciones que dependen de los datos.
Al describir un algoritmo es necesario ser lo ms preciso posible, de modo que sea sencillo implementar
el procedimiento especificado. En primer lugar, es necesario definir una serie de operaciones bsicas y
objetos con las cuales se har la especificacin.
Intro a la Prog. Resolucin de Problemas Rodrigo Sandoval U.
IIC 1102 Pgina: 3
Luego, a partir de los objetos y operaciones definidas, se procede a enumerar los pasos que componen el
algoritmo. En esta etapa se puede emplear los componentes bsicos de control de flujo (decisin e
iteracin).
La principal destreza que se debe desarrollar para escribir algoritmos consiste en poder abstraer un
problema y conceptualizarlo de modo que se pueda expresar su solucin en trminos de las operaciones
bsicas entre objetos que se definieron. Para esto nos apoyaremos en la descomposicin en partes y
subproblemas ms simples, las cuales tambin requieren de cierto grado de conceptualizacin.
An cuando muchos algoritmos resulten simples al final, el proceso para llegar a ellos puede ser muy
complicado. Existen varios enfoques que se pueden seguir para elaborar un algoritmo a partir de la
definicin del problema:
Buscar similitud con otros problemas
Utilizar ejemplos conocidos
Utilizar algoritmos genricos conocidos
Conceptualizar actividades y objetos participantes
Descomponer en subproblemas
La metodologa presentada en este curso hace uso de los dos ltimos, aunque en algunos casos
recurriremos al resto como apoyo.
1.3.2 Cmo se especifican o describen los algoritmos?
Para especificar un algoritmo puede utilizar el "lenguaje natural" y tambin el "pseudocdigo" (casi
cdigo).
El lenguaje natural debe utilizar una cantidad suficiente de palabras en frases cortas, pero con sentido
completo como para que el algoritmo especificado quede claro.
El pseudocdigo suele ser muy utilizado cuando se est diseando un algoritmo que resuelve algn
problema computacional, abstrayendo varios detalles de la sintaxis rgida de algn cdigo o lenguaje de
programacin, como es el caso del lenguaje C#.
1.3.3 Existe un nico algoritmo de solucin?
Para cualquier problema, pueden existir varios algoritmos de solucin, tantos como personas que quieran
resolverlos. No existe un algoritmo "nico" de solucin para un problema dado. Ello de ninguna manera
quiere decir que estos algoritmos distintos producen soluciones distintas. Aunque ellos sean distintos,
todos ellos pueden ofrecer el mismo resultado de solucin.
Inclusive un mismo algoritmo que quiere ser implementado mediante algn cdigo de computadora puede
ser implementado de distintas maneras, tantas como personas que lo implementen.
1.3.4 Qu es una metodologa?
Aplicacin coherente de un conjunto de operaciones ordenadas con que se pretende obtener un
resultado. Se puede decir que una metodologa es como un algoritmo genrico.
Se aplicar entonces una metodologa que empezando de un problema, llegue a la especificacin de un
algoritmo de solucin.
Existen muchas metodologas para encontrar una solucin a un problema. En este curso se adoptar la
metodologa descrita ms adelante, para contar con un lenguaje comn que pueda dar lugar a su
entendimiento por todos aquellos que lo quieran analizar. Esta estrategia en particular se focaliza en el
anlisis del problema para luego describir una solucin donde se identifican los objetos involucrados y
Intro a la Prog. Resolucin de Problemas Rodrigo Sandoval U.
IIC 1102 Pgina: 4
una secuencia de pasos, o algoritmo, que establece las relaciones entre los objetos, alcanzando el
objetivo buscado.
Una especificacin de un algoritmo de solucin, puede presentar problemas: que el algoritmo resuelva
ms de lo que el problema pide (aunque esto por lo general no es perjudicial) o que el algoritmo no
resuelva todo lo que el problema requiere.
1.3.5 Las soluciones tambin pueden tener problemas

Para resolver estos problemas es necesario entonces validar la solucin y/o especificar limitaciones del
algoritmo de solucin. A veces esta tarea puede ser compleja, debido que para validar la solucin y
conocer sus limitaciones hay que ser exhaustivo con el anlisis o seguimiento de la especificacin del
algoritmo, considerando todos los casos posibles.
Los casos posibles que generalmente no resuelven todas las partes del problema dado, son los casos
extremos, como por ejemplo datos nulos si se trata de nmeros, datos negativos si se trata de
operaciones aritmticas con nmeros positivos, o por ejemplo para la receta de cocina que se utilice
"huevos" pasados en lugar de frescos, etc.
Tanto para el diseo de un algoritmo de solucin a un problema dado, como para su validacin se
requiere experiencia. PARA TENER EXPERIENCIA ES NECESARIO TENER PRCTICA EN LA
RESOLUCION DE PROBLEMAS. PARA TENER PRCTICA ES NECESARIO RESOLVER MUCHOS
PROBLEMAS.
Intro a la Prog. Resolucin de Problemas Rodrigo Sandoval U.
IIC 1102 Pgina: 5
2 Orientacin a Objetos
En aos recientes se ha adoptado, ms que una tcnica, un enfoque basado en lo que genricamente se
denomina Objeto, a diferencia de esquemas tradicionales, denominados Procedurales, en los cuales la
solucin se especifica como una secuencia de pasos y subpasos.
En el esquema de Orientacin a Objetos se parte de la premisa El Mundo Real est compuesto de
Objetos que interactan, y no es un mundo procedural, en que todo ocurre secuencialmente.
La Programacin Orientada a Objetos tiene como punto medular el uso de objetos, que en realidad son
estructuras lgicas que representan elementos o entidades del mundo real. Esta representacin se basa
en los siguientes aspectos:
Se usan nombres que permiten hacer una rpida asociacin con el correspondiente objeto. Por
ej: para representar un vehculo, se puede definir un objeto o entidad denominado Auto.
Para representar el estado del objeto, se utilizan variables, denominadas atributos o
propiedades, que almacenan diferentes valores que pueden ir cambiando en el tiempo. Por ej: el
auto puede estar representado por cilindraje, velocidad, etc.
Para describir el comportamiento del objeto y cmo ste interacta con otros de su mismo tipo o
de otro tipo, se definen mtodos, que corresponden a acciones especficas del objeto, una vez
ms, simulando el mundo real. Por ej: avanzar, frenar, abrir la puerta delantera derecha, etc.


El objeto Automvil en el mundo real.


Representacin Lgica del Automvil Clase Automvil.
Atributos:
- Cilindraje
- Cantidad de Puertas
- Velocidad a la que se desplaza
Mtodos (acciones):
- Avanzar
- Frenar
- Cambiar Velocidad
- Abrir Puerta N
Intro a la Prog. Resolucin de Problemas Rodrigo Sandoval U.
IIC 1102 Pgina: 6
El enfoque OO es una evolucin natural de un concepto establecido en la programacin procedural, que
se denomin Tipo de Dato Abstracto, siguiendo una intencin de modularizar y a la vez encapsular la
complejidad de implementacin de la lgica de un programa.
Ms en detalle, la abstraccin de datos es una metodologa que permite aislar la implementacin de un
tipo de datos compuesto a partir de tipos bsicos. La idea es estructurar los programas de modo que
trabajen sobre datos abstractos, sin conocer su implementacin. Los programas deben usar los tipos de
datos de manera que no se hagan suposiciones sobre los datos que no sean estrictamente necesarias
para cumplir con la tarea involucrada.
Cul es la ventaja de esto? Si tenemos que saber siempre cmo estn implementados los tipos de
datos, nuestros programas dependern de esa implementacin. Esto quiere decir que si se producen
cambios en la implementacin del tipo de datos, ser necesario cambiar el programa para que siga
funcionando. Para poder hacer uso de estos datos, sin conocer su implementacin, se define una interfaz
que especifica cmo se puede interactuar con estos datos u objeto.
Adicionalmente, la otra gran ventaja del esquema de orientacin a objetos es la posibilidad de reutilizar
partes de una solucin para resolver un segundo problema, donde se comparte parte de la lgica resuelta
en el primer problema. Esta es una facultad tremendamente importante en la ingeniera de software
actual, donde se busca disminuir el esfuerzo involucrado en la implementacin de soluciones a problemas
de cada da mayor complejidad.
Consideremos el caso de un auto. Somos capaces de conducir distintos autos, de distintas marcas,
modelos y aos, sin tener necesidad de saber cmo funciona cada uno de sus componentes. De hecho,
no todos los autos tienen los mismos componentes. Incluso, los componentes que son comunes, a pesar
de tener la misma funcionalidad, difieren en marcas, modelos, rendimiento, costo, etc. En resumen, la
implementacin es distinta pero tienen la misma funcionalidad.
De manera similar, una implementacin particular de un tipo de datos es independiente de los programas
que lo usan. Lo nico que es intocable es la interfaz.
Volviendo al ejemplo del auto, todas las marcas y modelos poseen algo en comn: Una forma de uso
establecida por parmetros de operacin y por la forma de entregar esos parmetros (forma de usar el
volante, el acelerador, el freno, etc). Nadie comprara un auto en que el freno se encuentre a la derecha
del acelerador, o que el volante funcione girando el auto a la derecha cuando se mueve hacia la
izquierda.

2.1 Terminologa Bsica de la Programacin Orientada a Objeto
- Objeto: entidad lgica que representa un objeto segn lo conocemos los humanos en el mundo
real.
- Clase: un tipo de objeto, descripcin lgica que especifica caractersticas comunes a todos los
objetos de un tipo comn, por ejemplo Vehculo describe genricamente todos los objetos de
ese tipo.
- Instancia: un objeto particular de una clase especfica. Tambin se los conoce como objetos
propiamente tales. Una instancia tiene su propio nombre y se diferencia de otras instancias de la
misma clase, por los valores que puedan tener sus atributos en un instante en particular.
- Atributos o Propiedades: son variables de estado, cuyo valor se asocia a una instancia en
particular de una clase de objeto.


Intro a la Prog. Resolucin de Problemas Rodrigo Sandoval U.
IIC 1102 Pgina: 7
3 Estrategias para la Solucin de Problemas
Tomando en cuenta el objetivo de aprender a enfrentar problemas de cierto nivel de complejidad, se hace
necesario contar con una estrategia de resolucin, que permita, estructuradamente y predeciblemente,
enfrentar y entender el problema y plantear una solucin entendible y que claramente se enfoque en
resolver el problema planteado.
En la literatura existen numerosas estrategias, todas enfocadas con mayor nfasis a cierto tipo de
problemas. A continuacin se presenta una metodologa de resolucin de problemas de tipo genrico,
que ser el puntal para este curso.
3.1 Metodologa de Resolucin de Problemas
El proceso que permite obtener una solucin a un problema puede dividirse en las siguientes etapas:
1. Definicin del problema (planteamiento original)
El primer paso: Definicin del Problema, busca definir el contexto en que se establece el
problema, indicando el alcance u objetivo que se pretende atacar. Este paso se
descompone en tres partes:
1.1. Conceptualizacin. Conceptualizar el mundo o contexto en que ocurre el problema. Cualquier
suposicin sobre el dominio del problema debe ser descrita aqu. Adems, debe quedar claro cul es la
informacin que se conoce relativa al problema (entradas del algoritmo).
1.2. Objetivo. Determinar el objetivo que se quiere alcanzar, en forma cualitativa (descripcin de lo que
se desea) y cuantitativa (forma en que se medir el logro alcanzado).
1.3. Elementos involucrados. Especificar los elementos activos (usuarios) y pasivos (recursos
disponibles y/o modificables) que estn involucrados en el problema.
2. Conceptualizacin de la solucin
El segundo paso: Conceptualizacin de la solucin, se focaliza en una descripcin de
los elementos involucrados en la solucin al problema planteado. Esta seccin se enfoca
en un esquema de orientacin a objeto, ya que el ncleo de esta definicin no son las
acciones a tomar, propiamente tales, sino que los objetos que estarn involucrados en la
solucin. A su vez, esta descripcin de elementos se descompone en tres partes:
2.1. Entidades involucradas. Haciendo un paralelo con el problema en el mundo real que se est
representando, se determinan cules son las entidades que participan en la solucin del problema,
indicando su funcionalidad bsica. Las entidades que son muy complejas pueden definirse en base a
otras ms simples.
2.2. Clases de Objetos. Para cada una de las entidades descritas en el punto anterior debe definirse un
tipo de objeto que la implemente, tambin llamado clase. La definicin de cada clase debe incluir
nicamente la funcionalidad del tipo (para qu sirve?) y la interfaz (cmo se usa?). La interfaz se
define en trminos de un conjunto de mtodos con parmetros claramente establecidos. Tambin
deben mencionarse las limitaciones de cada una de las clases.
2.3. Instancias. Deben definirse las instancias de cada clase que se emplearn en la solucin del
problema, indicando el uso particular que se dar a cada una. A su vez, debe especificarse aquellos
datos simples adicionales que estarn involucrados en la solucin.

3. Especificacin del algoritmo
El tercer paso: se especifica una secuencia de pasos principales (no detallados), en que
las distintas instancias interactan para producir el objetivo esperado. Se detalla paso
por paso el procedimiento principal, donde incluso se especifica algunos valores iniciales
de las instancias requeridas.
Intro a la Prog. Resolucin de Problemas Rodrigo Sandoval U.
IIC 1102 Pgina: 8
Especificar la secuencia de actividades que conforman la solucin del problema. Esta especificacin debe
ser autocontenida y debe estar dada en trminos de las entidades/objetos definidos en (2).
Cada uno de los pasos del algoritmo podr ser una operacin simple o alguna operacin sobre uno de las
instancias de los objetos.

4. Validacin de la Solucin
El cuarto paso: habiendo definido el problema y descrito una solucin se hace un estudio
de los posibles escenarios en que la solucin puede funcionar. Los escenarios se definen
en funcin de los rangos de valores que los parmetros de la solucin pueden recibir.
4.1. Dominios. Especificar un conjunto de problemas tipo y sus soluciones, los cuales
caracterizan el dominio del problema. Debe haber un problema para cada posible dominio.
4.2. Ejecucin. Ejecutar el algoritmo obtenido en (3) para cada uno de los problemas que representan
los distintos dominios, validando que se obtengan las soluciones especificadas, es decir, que se
alcancen los objetivos propuestos en cada caso.

5. Limitaciones del algoritmo
Identificacin de puntos dbiles y escenarios en los cuales el algoritmo no funciona o tiene deficiencias
(condiciones crticas).

3.2 Descripcin Grfica de Soluciones
La idea de las representaciones grficas, o diagramas, es apoyar la descripcin que se hace, tanto de las
problemas y modelos, como de sus soluciones. En estas descripciones grficas se intenta ilustrar, ya sea
con metforas visuales o con grficos descriptivos las diferentes condiciones que se imponen sobre la
situacin a odelar y que requiere ser resuelta, as como de los elementos que componen su solucin.
Particularmente como apoyo a los procesos de diseo de soluciones Orientadas a Objeto, se ha
desarrollado en los ltimos aos un lenguaje de modelamiento, llamado directamente Lenguaje de
Modelamiento Unificado (Unified Modeling Language UML), que consisten en la conjuncin de
diferentes tcnicas tradicionales, en un enfoque ms actualizado con la tecnologa actual.
En este contexto slo se analizarn algunos tipos de diagramas manejados en UML, que permiten tanto
describir los requerimientos de las soluciones que debern ser diseadas, as como los elementos que
componen y definen el modelo de solucin a un problema dado.
3.2.1 Diagrama de Casos de Uso - UML
El primer tipo de diagrama utiliza elementos grficos muy simples para describir las
funcionalidades de una solucin requerida, a nivel macro. En estos diagramas se identifican:
- Actores: elementos que interactan con la solucin, lo que incluye tanto a usuarios,
como a elementos externos al sistema o aplicacin, como son bases de datos
externas, archivos, u otros sistemas.
- Funcionalidades o Casos de Uso, que describen una operacin o un conjunto de
operaciones que se pueden gatillar por parte de un usuario o de otro actor, y
que producen un resultado medible.
- Cada actor puede activar un caso de uso (es decir, su decisin inicia el
funcionamiento descrito por dicho caso de uso), o bien, el actor puede recibir la
accin de un caso de uso iniciado por otro lado. Esto se representa por una flecha
unidireccional, que indica quin activa a quin.
Actor1
Caso de Uso
Intro a la Prog. Resolucin de Problemas Rodrigo Sandoval U.
IIC 1102 Pgina: 9
Tomemos por ejemplo el caso de un cajero automtico. En este caso, consideraremos que el programa
que reside en el cajero es la aplicacin a describir, y que los actores involucrados son: un usuario o
cliente que acudir al cajero, y el sistema central que tiene los datos de las cuentas corrientes de los
clientes.
En este modelo, un cliente efecta dos posibles acciones sobre el cajero: Consulta de Saldo y Retiro de
Dinero. El cajero a su vez requiere consultar los datos al sistema central para ambos casos, y en
particular en el retiro de dinero, adicionalmente actualiza el saldo del cliente en el mismo sistema central.


3.2.2 Diagrama de Clases UML
En aquellas soluciones en las que se definen clases que representan objetos del mundo real, pero
estructurados y especificados de una manera precisa en el modelo, se utiliza el diagrama de clases
donde no slo se identifican grficamente cada una de las clases (o tipos de objetos) que interactan en
la solucin, sino que adems se especifican detalles como los elementos que componen cada una de
estas clases y cmo se relacionan entre ellas. Este esquema, totalmente dependiente de la modelacin al
estilo Orientacin a Objeto, permite definir en forma visual el diseo de la solucin. Entre las relaciones
que este tipo de diagrama permite definir entre clases, resultan relevantes dos: la herencia entre clases, y
la composicin de clases dentro de otras.
En estos diagramas se reconocen bsicamente los siguientes objetos:
- Clases: con sus respectivos elementos componentes. Estas se representan por
un rectngulo que interiormente describe los componentes, lo que se ver en
detalle ms adelante.
- Relacin de Herencia: identificada por una flecha de lnea slida y una punta
triangular vaca, que va desde la clase derivada a la clase padre.
- Relacin de Composicin: que define que una clase contiene una o ms instancias de otra clase,
y se identifica por una lnea slida, que puede terminar en flecha con
punta abierta, e incluye un rombo en la mitad, donde se describe la
cardinalidad (o cuntas instancias de la clase referenciada estn
contenidas en cada instancia de la clase contenedora o compuesta).
En el siguiente ejemplo, se representa en forma simple la siguiente situacin. Se tiene una clase
Vehculo, que representa genricamente los vehculos de cualquier tipo. De ella se derivan dos clases, el
Camin, y la Motocicleta. A su vez existe una 4 clase, que representa un automotora, que en realidad
contiene varias instancias de vehculos, ya sean camiones o motocicletas. Por ello, en este diagrama, la
clase Vehculo es la central, y de ella se derivan las otras clases.

Clase: Vehculo
0 . . 1 *
Intro a la Prog. Resolucin de Problemas Rodrigo Sandoval U.
IIC 1102 Pgina: 10
Clase: Camin
Clase: Vehculo
Clase: Motocicleta
Clase: Automotora
0..1 *


3.2.3 rboles de Decisin
Los rboles de decisin son una herramienta grfica muy til para representar algoritmos en los que
estn involucradas una gran cantidad de decisiones a lo largo de su ejecucin.
El objetivo es ilustrar la forma en que el algoritmo va evolucionando conforme se van tomando
decisiones, normalmente sobre la base de informacin suministrada por el usuario. Cada punto de
decisin se representa con una caja rectangular, en la cual se describe brevemente los aspectos a
considerar para tomar dicha decisin.
Una vez que se conocen los criterios para tomar la decisin en uno de estos puntos, se seala con
flechas las distintas posibilidades hacia donde evolucionara el algoritmo, llevando el desarrollo de la
ejecucin hacia otro punto de decisin. Para identificar las posibles opciones, se etiquetan las flechas.
Las posibilidades pueden ser mltiples, producindose varias bifurcaciones en cada punto de decisin, o
simplemente dos, en cuyo caso se obtendra un rbol binario. Este es el caso del ejemplo que se muestra
a continuacin.
Al llegar al ltimo nivel, es decir, cuando ya no hay decisiones que tomar, se ha obtenido una solucin y
el algoritmo ha concluido. A estos nodos dentro del rbol se les conoce como hojas, o tambin como
nodos terminales.

3.2.4 Ejemplo: rbol de Decisin: Qu hago el sbado por la noche?
Para ilustrar el uso de los rboles de decisin, se presenta un rbol que gua a un usuario a tomar una
decisin sobre qu hacer el sbado por la noche. La profundizacin en el rbol se lleva a cabo de
acuerdo a las respuestas que va dando el usuario a las interrogantes que se le plantean. Cuando se llega
a un nodo terminal en el rbol (hoja), el usuario recibe una recomendacin sustentada en el desarrollo de
la interaccin.
Intro a la Prog. Resolucin de Problemas Rodrigo Sandoval U.
IIC 1102 Pgina: 11



3.3 Ejemplos de Aplicacin de la Metodologa
3.3.1 Simulando la Ejecucin de un Penal
Este primer ejemplo ilustra la situacin de ejecucin de un penal de ftbol, reconociendo los elementos
involucrados en esta situacin y cmo se relacionan para producir un resultado.
1. Definicin del problema
Conceptualizacin: El problema consiste en ejecutar un penal, donde un jugador patea la pelota hacia el
arco y el arquero trata de detenerla. Particularmente se pretende determinar si al ejecutar un penal, el gol
fue convertido o fue atajado. En este caso, un usuario indicar la direccin en que patea el jugador y la
direccin en que se lanza el arquero. Si ambas direcciones coinciden, se considera penal atajado. Si no
coinciden, se considera penal convertido.
Objetivo: El objetivo es determinar para una combinacin de direcciones en que se patea la pelota y se
lanza el arquero, ingresadas por el usuario, si el penal fue convertido o no.
Elementos Involucrados: Elementos activos, el usuario que indicar las direcciones respectivas.
Elementos pasivos, el jugador y la direccin en que lanzar, y el arquero y la direccin en que se lanzar.

Intro a la Prog. Resolucin de Problemas Rodrigo Sandoval U.
IIC 1102 Pgina: 0
2. Conceptualizacin de la solucin
Entidades Involucradas: Dos objetos esenciales se reconocen en este problema: el jugador y el arquero.
Clases de Objetos: En este caso particular, ambas entidades se representan cada una por su respectiva
clase.
Clase Jugador: Representa a un jugador que lanzar la pelota tratando de convertir el penal.
Atributos: El nmero en su camiseta, y la direccin en que lanzar.
Mtodos: patear la pelota
Clase Arquero: Representa a un jugador que intentar impedir que el gol sea convertido.
Atributos: la direccin en que se lanza para atajar.
Mtodos: Lanzarse a atajar.
Instancias Involucradas: en este caso slo se necesita una instancia de la clase Jugador, que representa
a quien ejecutar el penal, y adicionalmente se requiere una nica instancia de la clase Arquero, ya que
slo uno de ellos participa en el penal.



3. Especificacin del algoritmo
Siguiendo el procedimiento de ejecucin de un penal, se involucra al usuario para hacerle las preguntas
del caso.
1. Se instancia el jugador (j1), y se instancia el arquero (a1)
2. Se le pregunta al usuario la direccin en que patear el jugador se asigna a la instancia j1
3. Se le pregunta al usuario la direccin en que se lanzar el arquero se asigna a la instancia a1
4. Se invoca el mtodo Patear del objeto j1
5. Se invoca el mtodo Lanzarse del objeto a1
6. Se comparan ambas direcciones.
Atributos:
- Nmero
- Direccin
Mtodos:
- Patear
Atributos:
- Direccin
Mtodos:
- Lanzarse
Intro a la Prog. Resolucin de Problemas Rodrigo Sandoval U.
IIC 1102 Pgina: 13
a. Si coinciden, se indica al usuario que el penal fue atajado.
b. Si no coinciden, se indica al usuario que el gol fue convertido.

4. Validacin de la Solucin
Dominios: Los posibles dominios que existen en el contexto de este problema se constituyen a partir de
los valores de direccin que el usuario puede ingresar. Es decir, los escenarios posibles se conforman de
las 4 diferentes combinaciones de direcciones para ambos jugadores: der-der; izq-izq; izq-der; der-izq.
Validacin: revisando las cuatro posibles combinaciones de valores indicados por el usuario, se llega en
todos ellos a un resultado predecible por el algoritmo principal, por lo que se valida su ejecucin.

5. Limitaciones
Si los valores ingresados por el usuario no son controlados, entonces se podra asumir que el programa
podra tener un comportamiento incoherente.

Posibles soluciones:

Versin de Consola

Versin Windows


Intro a la Prog. Resolucin de Problemas Rodrigo Sandoval U.
IIC 1102 Pgina: 14
3.3.2 Simulando la preparacin de un pastel
En este ejemplo se emplea la metodologa de solucin de problemas para definir e implementar los pasos
necesarios para simular la solucin a un problema simple: hornear y servir un pastel de fruta.
1. Definicin del problema
Conceptualizacin: El problema consiste en preparar un pastel de alguna fruta especfica, de acuerdo a
cierta receta, y servirlo a cierta cantidad de comensales.
Se recibir como entrada la receta para hornear, es decir, la cantidad de huevos, harina y mantequilla
que se emplear, la fruta con que se cubrir el pastel y la cantidad correspondiente, as como el tiempo
que debe permanecer en el horno. Adicionalmente, se recibe el nmero de comensales que disfrutarn
del producto final, para poder cortarlo y servirlo.
Objetivo: El objetivo es poder seguir la receta proporcionada de modo que podamos obtener como
resultado un pie de fruta que podamos repartir a los comensales.
Elementos involucrados: El nico elemento activo ser la persona que llevar a cabo el proceso (el
cocinero). Los elementos pasivos involucrados son la receta del pastel: sus ingredientes y cantidades
(huevos, harina, mantequilla, fruta). En este caso, los comensales podran considerarse como elementos
pasivos, pues no participan de la solucin (existen, pero simplemente esperan).

2. Conceptualizacin de la solucin
Entidades Involucradas: el objeto principal es la receta del pastel, que ser preparado durante el
proceso. La receta se compone de las cantidades respectivas de cada ingrediente, adems del tiempo de
horneado, el tipo de fruta, y los trozos en que deber partirse.
Clases de Objetos: la nica clase requerida es pastel, la cual se define con ciertas propiedades privadas,
y algunos mtodos pblicos. Las propiedades privadas son las cantidades de huevos, harina,
mantequilla, y fruta, el tiempo de horneado, el tipo de fruta, y la cantidad de pedazos. Todos ellos son
datos numricos a excepcin del tipo de fruta, que es de tipo texto.
El proceso de hornear y servir el pastel abarca varias etapas. En primera instancia se debe obtener la
receta a emplear. Esto consiste en especificar la cantidad de huevos, mantequilla y harina, as como el
tipo y la cantidad de fruta que se utilizar. El segundo paso consiste en preparar la base del pie,
mezclando la cantidad especificada de huevos, harina y mantequilla. Luego, la base es horneada durante
cierto tiempo (lo cual tambin es parte de la receta). El siguiente paso es preparar la fruta con la que se
cubrir la base. Finalmente, se procede a cortarlo y servirlo a todos los comensales. Por esto, los
mtodos de esta clase son:
MezclarBase(): Se toman las cantidades definidas de huevos, harina y mantequilla y se mezclan para
lograr la base.
HornearBase(): Segn el tiempo definido, que representa la cantidad de minutos que deber permanecer
la base en el horno, este proceso se encarga de hornear la base durante dicho tiempo.
PrepararFruta(): Usando el tipo o nombre de la fruta que se emplear para cubrir la base, y la cantidad
(en gramos) de dicha fruta que debe emplearse (segn la receta), este proceso prepara la cubierta.
CortarServir(): Tomando el tipo de fruta con que se cubri el pastel y la cantidad de invitados
establecidos, este proceso se encarga de cortar el pastel en tantos pedazos como comensales haya y lo
sirve para que los invitados lo puedan comer. El tipo de fruta es necesario para que al servirlo a los
comensales se les pueda indicar qu tipo de pie van a comer.
Instancias: En el contexto de nuestro problema, ser necesario representar una variable u objeto de clase
Pastel, que representa el pastel a preparar en base a su receta (huevos, harina, mantequilla, fruta), el
tiempo que debe permanecer el pie en el horno, y la cantidad de comensales que lo disfrutarn. El
nombre de esta instancia: pas.

Intro a la Prog. Resolucin de Problemas Rodrigo Sandoval U.
IIC 1102 Pgina: 15

3. Especificacin del algoritmo
El algoritmo presentado a continuacin emplea la instancia de la clase definida y llama secuencialmente a
los mtodos respectivos para resolver nuestro problema. En este caso no fue necesario emplear
operaciones de control de flujo, pues el algoritmo se puede especificar en forma totalmente secuencial.
Algoritmo:
1. Crear la receta del Pastel, obteniendo del usuario los ingredientes: huevos, harina,
mantequilla, tipo, fruta y tiempo, y la cantidad de pedazos en que se debe cortar.
2. MezclarBase()
3. HornearBase()
4. PrepararFruta()
5. CortarServir()

La implementacin en C# de este algoritmo resulta bastante simple. Basta con implementar e invocar el
mtodo para cada una de las tareas involucradas. Esta funcin simular el proceso que debe llevar a
cabo la tarea. Las primeras lneas del algoritmo involucran la creacin de la instancia, junto con la entrada
de datos por parte del usuario del programa (debe proporcionar los valores apropiados para las
propiedades de esta instancia).

4. Validacin de la Solucin
Dominios: Los posibles dominios que existen en el contexto de este problema se constituyen a partir de
los distintos valores de entrada que pueden recibirse del usuario. Es decir, distintos tipos de fruta,
distintas cantidades para cada ingrediente, distintos tiempos en el horno y distintas cantidades de
comensales.
Validacin: Debe ejecutarse (verbalizarse su ejecucin) el algoritmo para los dominios definidos, es decir,
cambiando valores para cada dato de entrada, y verificando que se puede alcanzar el objetivo buscado.
A priori, no hay validacin de las cantidades numricas indicadas, por lo que el algoritmo funcionara, an
cuando se ingresen valores que no tengan sentido de acuerdo al contexto, como por ejemplo usar
cantidades de minutos negativas o cero, o nombres incongruentes de frutas.

5. Limitaciones de la Solucin
En principio, no hay limitaciones evidentes en el caso de la solucin planteada en este ejemplo, ya que el
programa funcionara incluso con nmeros incoherentes (nmeros negativos, nulos) en los valores
indicados por el usuario.
Atributos:
- Huevos
- Harina
- Mantequilla
- Fruta
- Tiempo de horneado
- Tipo de fruta
- Cantidad pedazos
Mtodos:
- MezclarBase()
- HornearBase()
- PrepararFruta()
- CortarServir()
Intro a la Prog. Resolucin de Problemas Rodrigo Sandoval U.
IIC 1102 Pgina: 16
3.3.3 Cambio de neumtico desinflado
Un auto queda detenido en la carretera al desinflrsele un neumtico. Para tratar este problema particular
se aplicar la metodologa para la solucin de problemas presentada anteriormente.
1. Definicin del problema
Conceptualizacin: El problema tiene lugar en una carretera, en donde un auto se ha quedado parado,
pues uno de sus 4 neumticos se ha desinflado. El auto cuenta con las herramientas necesarias para que
el conductor pueda cambiar el neumtico, as como tambin con un neumtico de repuesto en buenas
condiciones. El nico dato de entrada con que se cuenta es la posicin del neumtico desinflado, es
decir, en cul de las cuatro ruedas ocurri el percance.
Objetivo: Cualitativamente, el objetivo es cambiar el neumtico desinflado por el de repuesto, de modo
que el auto pueda andar. Cuantitativamente, el logro del objetivo puede medirse verificando que los 4
neumticos estn inflados.
Elementos involucrados: Existe un nico elemento activo que es el conductor del auto. Adems, existen
los siguientes elementos pasivos, que formaran parte del equipamiento del auto:
Maletero
Ruedas, una de las cuales tiene el neumtico desinflado
Pernos que sujetan cada rueda
Neumtico de repuesto, en buenas condiciones, ubicado en maletero del auto
Gata hidrulica en el maletero del auto
Llave de cruz en el maletero del auto

2. Conceptualizacin de la solucin
Entidades Involucradas: el objeto principal es claramente el auto. Es esta entidad la que contiene todos
los elementos relevantes de manejar en esta solucin, como son las ruedas, el maletero, y todos los
elementos dentro de l, necesarios para el cambio de rueda.
Clases de Objetos: la nica clase requerida en este caso, es Auto, la cual es descrita por medio de
ciertos atributos y mtodos.
Los atributos se definen directamente en funcin de los elementos pasivos requeridos en la solucin, ms
un atributo indicando la rueda que est desinflada: maletero, gata hidrulica; llave de cruz; un perno (su
nmero: 1, 2, 3, 4); neumtico desinflado; neumtico de repuesto.
El mtodo constructor de esta clase recibir como parmetro el N del neumtico desinflado.
Los otros mtodos, se pueden resumir en las siguientes actividades:
- Retirar y colocar cosas
- Aflojar y apretar pernos
- Subir y bajar el auto con la gata
De esa manera, se podran definir los siguientes mtodos:
- Retirar "algo" de un "lugar"
- Colocar "algo" en un "lugar"
- Aflojar "un determinado perno"
- Apretar "un determinado perno"
- Subir auto desde "una determinada posicin"
- Bajar auto desde "una determinada posicin"
Intro a la Prog. Resolucin de Problemas Rodrigo Sandoval U.
IIC 1102 Pgina: 17
Los trminos resaltados en cursiva corresponden a variables de entrada (parmetros) que proporcionan
generalidad a las operaciones. Por ejemplo, el primer mtodo puede emplearse para retirar el neumtico
de repuesto del maletero, pero tambin para retirar la llave de cruz del maletero y un perno de la rueda.
Una definicin ms formal involucra especificar claramente cules son los parmetros con los que trabaja
cada operacin. As, la lista definitiva de operaciones ser la siguiente:
- Retirar
Parmetros: Lo que se desea retirar y el lugar de dnde se retirar
- Colocar
Parmetros: Lo que se desea colocar y el lugar dnde se colocar
- Aflojar perno
Parmetros: La posicin de la rueda, el nmero de perno que se desea aflojar.
- Apretar perno
Parmetros: La posicin de la rueda, el nmero de perno que se desea apretar, y la herramienta
que se usar
- Subir auto
Parmetros: La posicin de la rueda en donde se desea subir el auto y la herramienta (gata) que
se usar
- Bajar auto
Parmetros: Ninguno.
Instancias: En el contexto del problema la nica instancia necesaria es una de la clase Auto, que
simplemente se llamar auto1, la cual contiene todos los atributos necesarios para representar la
situacin.

3. Especificacin del algoritmo
El algoritmo presentado a continuacin emplea las operaciones (tareas) definidas anteriormente para
resolver el problema de cambiar el neumtico desinflado. Se resalta los argumentos de cada operacin.
La nica operacin elemental que se emplea para cambiar el flujo de control de las tareas es la iteracin.
Algoritmo:
Considere N como la posicin del neumtico desinflado (dato de entrada), referenciado como 1, 2, 3, 4.
1. Declarar instancia de Auto, con N como parmetro.
2. Auto.Retirar( gata hidrulica, del maletero )
2. Auto.Retirar( llave de cruz, del maletero )
3. Itere sobre cada perno P = 1,2,3,4
3.1. Auto.Aflojar( perno P, en rueda N)
4. Auto.Subir( posicin N )
5. Itere sobre cada perno P = 1,2,3,4
5.1. Auto.Retirar( perno P, de rueda N)
6. Auto.Retirar( neumtico D, de rueda N)
7. Auto.Retirar( neumtico R, del maletero )
8. Auto.Colocar( neumtico R, en rueda N)
9. Auto.Colocar( neumtico D, en maletero )
10. Itere sobre cada perno P = 1,2,3,4
Intro a la Prog. Resolucin de Problemas Rodrigo Sandoval U.
IIC 1102 Pgina: 18
10.1. Auto.Colocar( perno P, en rueda N )
11. Auto.Bajar()
12. Itere sobre cada perno P = 1,2,3,4
12.1. Auto.Apretar( perno P, en rueda N )
13. Auto.Colocar( llave de cruz, en maletero )
14. Auto.Colocar( gata hidrulica, en maletero )

4. Validacin del algoritmo
Dominios: Los posibles dominios que existen en el contexto de este problema se constituyen a partir del
neumtico que se haya desinflado. Por ejemplo, un posible dominio ser aquel en que el neumtico
desinflado es el de la rueda izquierda delantera.
Validacin: Ejecutando el algoritmo para cualquiera de los cuatro neumticos del auto puede verificarse
que la parametrizacin de las operaciones elementales permite alcanzar el objetivo buscado.
Al final de la ejecucin del algoritmo, para cualquier dominio (es decir, considerando cualquiera de los
cuatro neumticos), el auto contar con todos sus neumticos inflados y por consiguiente podr andar.
5. Limitaciones del algoritmo
El desarrollo del algoritmo se hizo para un auto que tuviera 4 pernos sujetando cada rueda. Sin embargo,
puede modificarse para recibir este valor como un dato de entrada.
Por simplicidad se dejaron de lado algunas consideraciones, como por ejemplo, abrir y cerrar el maletero,
transportar los neumticos y las herramientas, etc. Adems, la solucin presentada se aplica nicamente
a autos que cuenten con cuatro neumticos.


3.3.4 Llamada Telefnica
Se desea conceptualizar el problema de efectuar una llamada telefnica en un telfono pblico que
recibe monedas de $10, $50 y $100. El costo mnimo de la llamada es de $100 por 5 minutos. El proceso
se inicia desde que se levanta el auricular y finaliza cuando se cuelga. Se aplicar la metodologa para la
solucin de problemas presentada anteriormente.

1. Definicin del problema
Conceptualizacin: El problema tiene lugar en cualquier telfono pblico que acepta monedas de $10,
$50 y $100, con un costo de llamada mnima de $100 por 5 minutos. Supondremos que el aparato
funciona apropiadamente y que el usuario cuenta con suficientes monedas, de cualquier denominacin,
para completar su llamada. Los datos de entrada son: 1) el nmero de telfono que se desea marcar, y 2)
las monedas que lleva consigo la persona que har la llamada.
Objetivo: Cualitativamente, el objetivo es que el usuario pueda completar su llamada. Cuantitativamente,
el logro del objetivo puede verificarse si el tiempo de duracin de la llamada del usuario es mayor que
cero.
Elementos involucrados: Existe un nico elemento activo, que es el usuario que realiza la llamada.
Adems, existen los siguientes elementos pasivos:
- Un telfono pblico en buen estado, que funciona en la forma que se indic. El telfono tiene los
siguientes componentes:
Intro a la Prog. Resolucin de Problemas Rodrigo Sandoval U.
IIC 1102 Pgina: 19
o Ranura para insertar monedas
o Auricular
o 10 teclas numricas (una con cada dgito)
o Ranura para devolucin de monedas
- Un conjunto de monedas que se compone de:
o Un subconjunto de monedas de $10, que puede ser vaco
o Un subconjunto de monedas de $50, que puede ser vaco
o Un subconjunto de monedas de $100, que puede ser vaco

2. Conceptualizacin de la solucin
Entidades: Para efectos prcticos y funcionales, el problema global de efectuar la llamada telefnica
puede descomponerse en las siguientes tareas actividades: Manipular el auricular (levantarlo y colgarlo);
Manipular las monedas (recolectarlas, ponerlas en la ranura, recuperarlas cuando son devueltas);
Escuchar en el auricular (por el tono de marcar, de llamada en proceso, de conexin aceptada, o de
ocupado); Marcar un nmero en el teclado del telfono; Hablar.
El problema se describe en la relacin que un usuario hace entre la manipulacin de un telfono y sus
dispositivos, y un conjunto de monedas desde el cual saca la cantidad requerida para realizar las
llamadas.
Clases: Las nicas dos clases que permiten definir la solucin a este problema son Telefono, y Bolsillo,
los cuales en forma explcita verbalizan su representacin de la realidad. Adicionalmente se define un tipo
de dato especial, que representa un conjunto particular de monedas. Cada una de las clases formales se
compone de atributos y mtodos como se describe a continuacin:
Clase Telefono
Atributos:
- costo de la llamada, en este caso siempre valdr $100, por lo que podra manejarse como
una constante.
- tiempo: Corresponde al tiempo que el usuario ha hablado con al telfono que marc.
Mtodos pblicos
o LevantarAuricular(): representa la accin de tomar el auricular, que provoca la activacin del
telfono y la peticin de tono.
o DepositarMonedas(monedas): deposita el conjunto de monedas indicado en el telfono.
o ColgarAuricular(): representa la accin de devolver el auricular a su posicin de cuelgue,
desactivando as el telfono.
o EscucharAuricular(): representa la accin de detectar el tono que tiene el telfono. Como
retorno, devuelve el tono esuchado, identificando uno de los siguientes valores: TONO,
CONEXION EXITOSA y OCUPADO, DESCONEXION (este tono se escucha cuando se ha
esperado por un tiempo determinado y nadie contesta el telfono marcado).
o RecuperarMonedas(): permite recuperar las monedas sobrantes, retornando como resultado
el conjunto de estas monedas.
o Marcar(numero): Esta operacin marca en el teclado numrico cada uno los dgitos del
nmero al que se desea llamar.
Variables locales:
D: almacena los dgitos del nmero al que se desea hablar.
Intro a la Prog. Resolucin de Problemas Rodrigo Sandoval U.
IIC 1102 Pgina: 20
Algoritmo:
1. Iterar sobre cada una de los dgitos D del nmero que se desea marcar
1.1 Presionar en el teclado numrico el nmero correspondiente al dgito D
o Hablar(): Esta operacin permite que el usuario hable con la persona a la que llam. Por cada
segundo hablado se incrementa en 1 el tiempo de la llamada. Cuando se han cumplido 5
minutos (300 seg.) se debe introducir $100 para seguir hablando.
Variables propias:
tiempo: almacena el tiempo que se ha hablado hasta el momento.
MB: monedas en el bolsillo seleccionadas. Corresponde a las monedas que el usuario posee.
MS: monedas seleccionadas. Corresponde a las monedas que el usuario utilizar para
efectuar la llamada.
Algoritmo:
1. Al comienzo tiempo es 0 seg.
2. Iterar mientras se desee seguir hablando
2.1 Hablar un segundo.
2.2 Incrementar en 1 la variable tiempo.
2.3 Si tiempo tiene el valor 300 seg.
2.3.1 Recolectar monedas para una llamada de $100 desde conjunto de monedas
MB y almacenarlas en el conjunto de monedas MS.
2.3.2 Depositar monedas del conjunto MS en el telfono.
2.3.3 Devolver tiempo a 0 seg.

Clase Bolsillo
Mtodos pblicos
o RecolectarMonedas(monto): recolecta una combinacin de monedas de $100, $50, y $10,
que sumen el monto indicado. Como retorno entrega el conjunto de monedas seleccionadas.
Variables locales:
- monto recolectado: almacena el valor de las monedas que se han seleccionado hasta el
momento.
Algoritmo:
1. Al comienzo el monto recolectado es $0.
2. Iterar hasta que el monto recolectado sea el indicado
2.1 Seleccionar del bolsillo del usuario una moneda (una de las de mayor valor
que tenga) y pasarla al conjunto de monedas seleccionadas
2.2 Sumar el monto de la nueva moneda con el monto recolectado
3. Devolver el conjunto de monedas seleccionadas.

Instancias: En el contexto del problema que se intenta resolver, se necesitarn las siguientes instancias:
- El aparato telefnico que se utilizar para la llamada
- El bolsillo que contiene las monedas
Intro a la Prog. Resolucin de Problemas Rodrigo Sandoval U.
IIC 1102 Pgina: 21
- Adicionalmente ser necesario representar como dato el nmero de telfono que se desea
marcar. La variable que lo denotar ser Num.
- Por otro lado, es necesario representar las monedas seleccionadas desde el bolsillo. Esto se
har con la variable MS.
- tono: Corresponde al tono escuchado en el telfono.
- intentos: Corresponde al nmero de intentos que ha hecho el usuario.

3. Especificacin del algoritmo
El algoritmo presentado a continuacin emplea las clases e instancias definidas anteriormente para
resolver el problema de hacer una llamada telefnica. En este caso, para controlar el flujo de las
operaciones se emplea iteracin y decisin.
Adems, con el objetivo de que el usuario no se quede indefinidamente intentando hacer la llamada, en
caso de ocupado o que no contesten, se harn nicamente 3 intentos y si no se logra la llamada se
abandonar el proceso y el problema no podr ser resuelto.
Algoritmo:
Considere Num como el nmero que el usuario desea marcar, T como el telfono donde se har la
llamada, y B como el bolsillo que contiene las monedas con que har la llamada.
Inicialmente la variable intentos valdr 0. Iterar los siguientes pasos mientras intentos sea menor que 3.
1. MS = B.RecolectarMonedas(100)
Se recolectan las monedas para una llamada de $100 desde el conjunto de monedas en el
bolsillo B y se almacenan en el conjunto de monedas MS.
2. T.LevantarAuricular().
3. T.DepositarMonedas(MS).
4. tono = T.EscucharAuricular(),
se repite hasta que tono sea TONO.
5. T.Marcar(Num)
6. tono = T.EscucharAuricular().
7. Mientras tono CONEXION EXITOSA o DESCONEXION.
a. tono = T.EscucharAuricular().
8. Si tono = CONEXION EXITOSA entonces
a. T.Hablar().
b. T.ColgarAuricular().
9. Por el contrario, si tono = DESCONEXION u OCUPADO entonces
a. T.ColgarAuricular().
b. MS = T.RecuperarMonedas().
c. Incrementar variable intentos en uno.

4. Validacin del algoritmo
Dominios: Los posibles dominios que ser necesario analizar se constituyen a partir de las siguientes
caracterizaciones:
o Las distintas combinaciones de monedas que pueden formarse para llevar a cabo la llamada.
Intro a la Prog. Resolucin de Problemas Rodrigo Sandoval U.
IIC 1102 Pgina: 22
o El telfono al que se llama est ocupado.
o No contestan en el telfono al que se llama.
o Al hacer la llamada se obtiene una respuesta satisfactoria.
o Llamadas de menos de 5 minutos y llamadas de ms de 5 minutos.
o Distinto nmero de intentos al hacer la llamada (1, 2, 3).
Validacin: La validacin debe llevarse a cabo tomando en consideracin los dominios definidos en el
punto anterior. Para cada uno de ellos debe probarse que el algoritmo es correcto, es decir, que funciona
de acuerdo a las especificaciones originales.

Material preparado por Rodrigo Sandoval U en Marzo-Agosto 2004
Basado en la documentacin del curso IIC1102, ao 2003, de Miguel Nussbaum y Marcos Seplveda et. al.

PONTIFICIA UNIVERSIDAD CATLICA DE CHILE
ESCUELA DE INGENIERA
DEPARTAMENTO DE CIENCIA DE LA COMPUTACIN
IIC 1102 INTRODUCCIN A LA PROGRAMACIN
Profesor: Rodrigo Sandoval U.

Captulo II Introduccin al Lenguaje C#

1 EL LENGUAJE C# Y EL FRAMEWORK DE .NET ...................................................................................... 1
1.1 MICROSOFT .NET FRAMEWORK 1.1...............................................................................................................1
1.1.1 Lenguajes de Programacin .................................................................................................................. 1
1.1.2 Common Language Runtime (CLR) ....................................................................................................... 2
1.1.3 Biblioteca de clases de .Net.................................................................................................................... 2
1.2 ESTRUCTURA DE UN PROGRAMA EN C#...........................................................................................................2
1.2.1 Ejemplo de un programa en C# ............................................................................................................. 2
1.3 IDENTIFICADORES...........................................................................................................................................3
1.3.1 Algunas consideraciones al definir identificadores ............................................................................... 4
1.3.2 Ejemplos de identificadores ................................................................................................................... 4
1.4 DECLARACIN DE CLASES Y SUS ELEMENTOS................................................................................................6
1.4.1 Visibilidad/accesibilidad de una clases y sus miembros ........................................................................ 6
1.4.2 Elementos de una Clase ......................................................................................................................... 7
1.4.3 Campos................................................................................................................................................... 7
1.4.4 Tipos de Datos........................................................................................................................................ 8
1.4.5 Mtodos o Funciones ........................................................................................................................... 11
1.4.6 Sintaxis de la llamada a las Funciones definidas ................................................................................ 12
1.4.7 La funcin principal Main() y los programas en C#............................................................................ 13
1.4.8 Ejemplo en C# de la simulacin de compra de un boleto en el metro. ................................................ 13
1.5 EXPRESIONES................................................................................................................................................15
1.5.1 Expresiones Aritmticas....................................................................................................................... 15
1.5.2 Operadores Compuestos ...................................................................................................................... 17
1.5.3 Expresiones Relacionales, Lgicas o Booleanas ................................................................................. 18
1.5.4 Precedencia de todos los operadores................................................................................................... 19
1.6 INSTRUCCIONES............................................................................................................................................20
1.7 OPERADOR DE ASIGNACIN..........................................................................................................................20
1.8 CONVERSIN DE TIPOS (TYPE CASTING)........................................................................................................22
1.9 ENTRADA Y SALIDA......................................................................................................................................23
1.9.1 Salida con Formato: Console.WriteLine.............................................................................................. 23
1.9.2 Entrada con Formato: Console.ReadLine y Console.Read.................................................................. 26
1.10 COMENTARIOS, INDENTACIN Y OTROS ASPECTOS VISUALES.....................................................................27
1.10.1 Comentarios ......................................................................................................................................... 27
1.10.2 Indentacin (indexacin) y otros aspectos visuales ............................................................................. 27
1.10.3 Algunos consejos.................................................................................................................................. 28

Intro. Prog. Orientada a Objeto Sintaxis en C# Rodrigo Sandoval U.
IIC 1102 Pgina: 1
1 El Lenguaje C# y el Framework de .NET
C#(pronunciado C Sharp) es el nuevo lenguaje de propsito general orientado a objetos creado por
Microsoft para su nueva plataforma .NET.
Microsoft.NET es el conjunto de nuevas tecnologas en las que Microsoft ha estado trabajando estos
ltimos aos con el objetivo de mejorar tanto su sistema operativo como su arquitectura de desarrollo
anterior, para obtener una plataforma con la que sea sencilla la construccin de software.
La plataforma .NET ofrece numerosos servicios a las aplicaciones que para ella se escriban, como son un
recoleccin de basura, independencia de la plataforma, total integracin entre lenguajes (por ejemplo, es
posible escribir una clase en C#que derive de otra escrita en Visual Basic.NET que a su vez derive de
otra escrita en Cobol)
Como se deduce del prrafo anterior, es posible programar la plataforma .NET en prcticamente
cualquier lenguaje, pero Microsoft ha decidido sacar uno nuevo porque ha visto conveniente poder
disponer de un lenguaje diseado desde 0 con vistas a ser utilizado en .NET, un lenguaje que no cuente
con elementos heredados de versiones anteriores e innecesarios en esta plataforma y que por tanto sea
lo ms sencillo posible para programarla aprovechando toda su potencia y versatilidad.
C#combina los mejores elementos de mltiples lenguajes de amplia difusin como C++, J ava, Visual
Basic o Delphi. De hecho, su creador Anders Heljsberg fue tambin el creador de muchos otros lenguajes
y entornos como Turbo Pascal, Delphi o Visual J ++. La idea principal detrs del lenguaje es combinar la
potencia de lenguajes como C++con la sencillez de lenguajes como Visual Basic, y que adems la
migracin a este lenguaje por los porgramadores de C/C++/J ava sea lo ms inmediata posible.
Adems de C#, Microsoft propociona Visual Studio.NET, la nueva versin de su entorno de desarrollo
adaptada a la plataforma .NET y que ofrece una interfaz comn para trabajar de manera cmoda y visual
con cualquiera de los lenguajes de la plataforma .NET (por defecto, C++, C#, Visual Basic.NET y
J Script.NET, aunque pueden aadirse nuevos lenguajes mediante los plugins que proporcionen sus
fabricantes).
1.1 Microsoft .NET Framework 1.1
El Framework de .Net es una infraestructura sobre la que se rene todo un conjunto de lenguajes y
servicios que simplifican enormemente el desarrollo de aplicaciones. Mediante esta herramienta se ofrece
un entorno de ejecucin altamente distribuido, que permite crear aplicaciones robustas y escalables. Los
principales componentes de este entorno son:
Lenguajes de compilacin
Biblioteca de clases de .Net
CLR (Common Language Runtime)
Actualmente, el Framework de .Net es una plataforma no incluida en los diferentes sistemas operativos
distribuidos por Microsoft, por lo que es necesaria su instalacin previa a la ejecucin de programas
creados mediante .Net. El Framework se puede descargar gratuitamente desde la web oficial de Microsoft
(ver link de descarga en los recursos del final).
1.1.1 Lenguajes de Programacin
.Net Framework soporta mltiples lenguajes de programacin y aunque cada lenguaje tiene sus
caractersticas propias, es posible desarrollar cualquier tipo de aplicacin con cualquiera de estos
lenguajes. Existen ms de 30 lenguajes adaptados a .Net, desde los ms conocidos como C#(C Sharp),
Visual Basic o C++hasta otros lenguajes menos conocidos en el mundo microsoft como son Perl o
Cobol.
Intro. Prog. Orientada a Objeto Sintaxis en C# Rodrigo Sandoval U.
IIC 1102 Pgina: 2
1.1.2 Common Language Runtime (CLR)
El CLR es el verdadero ncleo del Framework de .Net, ya que es el entorno de ejecucin en el que se
cargan las aplicaciones desarrolladas en los distintos lenguajes, ampliando el conjunto de servicios que
ofrece el sistema operativo estndar Win32. La herramienta de desarrollo compila el cdigo fuente de
cualquiera de los lenguajes soportados por .Net en un mismo cdigo, denominado cdigo intermedio
(MSIL, Microsoft Intermediate Language). Para generar dicho cdigo el compilador se basa en el
Common Language Specification (CLS) que determina las reglas necesarias para crear cdigo MSIL
compatible con el CLR.
1.1.3 Biblioteca de clases de .Net
Cuando se est programando una aplicacin muchas veces se necesitan realizar acciones como
manipulacin de archivos, acceso a datos, conocer el estado del sistema, implementar seguridad, etc. El
Framework organiza toda la funcionalidad del sistema operativo en un espacio de nombres jerrquico de
forma que a la hora de programar resulta bastante sencillo encontrar lo que se necesita.
Para ello, el Framework posee un sistema de tipos universal, denominado Common Type System (CTS).
Este sistema permite que el programador pueda interactuar los tipos que se incluyen en el propio
Framework (biblioteca de clases de .Net) con los creados por l mismo (clases). De esta forma se
aprovechan las ventajas propias de la programacin orientada a objetos, como la herencia de clases
predefinidas para crear nuevas clases, o el polimorfismo de clases para modificar o ampliar
funcionalidades de clases ya existentes.
Este resumen fue extrado de: http://www.desarrolloweb.com/articulos/1328.php?manual=48
1.2 Estructura de un programa en C#
La declaracin de un programa en C#se centra en la definicin de clases que estarn involucradas en la
lgica de la solucin. Este programa puede contener cuantas clases se estime necesarias, y al menos
una de ellas debe contener el algoritmo principal o Main().
En pocas palabras, la estructura general y simplificada de un programa en C#es la siguiente: se declaran
las libreras cuyas clases se referencian en el programa, luego se declaran las clases requeridas con
todos sus detalles, y finalmente, la clase principal (que en muchos casos es la ms simple y de corta
declaracin), cuyo principal y a veces nico contenido es el mtodo Main(), tambin conocido como
algoritmo principal. Este Main() es obligatorio en todo programa, y ser llamado en forma implcita cuando
la ejecucin del programa d inicio.
[declaracin de namespaces o libreras de clases (externas) requeridas]

[declaracin clase 1]
[declaracin clase 2]
...
[declaracin clase N o principal]
[algoritmo principal o Main()]
En la declaracin de un programa, todos los elementos definidos se etiquetan con nombres propios, que
se conocen como identificadores. Estos identificadores son asignados arbitrariamente por el
programador, siempre cumpliendo algunas reglas que se describen a continuacin.
1.2.1 Ejemplo de un programa en C#
El programa ms simple de todos: Hola Mundo, el cual slo contiene una clase principal.
Intro. Prog. Orientada a Objeto Sintaxis en C# Rodrigo Sandoval U.
IIC 1102 Pgina: 3
using System; // Referencia al namespace de clases y mtodos ms usado

// Se declara una clase nica y exclusivamente para alojar el Main().
class MainApp {

// Funcin principal, Main()
public static void Main() {

// Escribe el texto a la consola.
Console.WriteLine("Hola Mundo, estoy hecho en C#!");
Console.ReadLine(); // Espera un ENTER para cerrar
}
}
Como se ve en el trozo de cdigo anterior, todo en C#pertenece a una clase, y por ende, obliga
totalmente a tener un enfoque orientado a estos objetos.

1.3 Identificadores
Los identificadores son los nombres con que se identifica a los distintos objetos dentro de un
programa, como ser:
Clases.
Instancias.
Namespaces.
Funciones o mtodos.
Variables, campos o propiedades.
Constantes.
Estructuras de datos.
En C#, los identificadores siguen las reglas para identificadores recomendados en el Anexo 15 del
Unicode Standard, es decir, cada identificador puede contener:
Letras (las del alfabeto maysculas y minsculas, menos la , y las acentuadas). No es
posible emplear acentos o caracteres especiales del alfabeto espaol.
Dgitos numricos (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
Smbolo de subrayado ( _ )
Adicionalmente, en casos especiales, se puede utilizar el smbolo @ al comienzo de un
identificador, cuando ste es una de las palabras claves. Sin ese smbolo, ningn identificador
puede ser igual al conjunto de palabras reservadas del lenguaje C#.
Ntese, que a diferencia de otros lenguajes, C#as como sus antecesores (C, J ava, etc.) son
sensibles a las maysculas, es decir, se considera var1 y VAR1, e incluso Var1, son
identificadores totalmente distintos.

Intro. Prog. Orientada a Objeto Sintaxis en C# Rodrigo Sandoval U.
IIC 1102 Pgina: 4
Las palabras reservadas en C#son las siguientes.
abstract event New struct
as explicit Null switch
base extern object this
bool false operator throw
break finally out true
byte fixed override try
case float params typeof
catch for private uint
char foreach protected ulong
checked goto public unchecked
class if readonly unsafe
const implicit ref ushort
continue in return using
decimal int sbyte virtual
default interface sealed volatile
delegate internal short void
do is sizeof while
double lock stackalloc
else long static
enum namespace string

1.3.1 Algunas consideraciones al definir identificadores
En la prctica, la letra de subrayado ( _ ) se emplea para dar mayor legibilidad a nombres
compuestos por varias palabras. Adems, se acostumbra emplear letras minsculas para nombrar a las
variables y las maysculas se usan al comienzo de una palabra en funciones declaradas con
identificadores compuestos.
Se recomienda elegir nombres que sean representativos del elemento (atributo o mtodo) que se
defina o del valor que la variable guarde. Por ejemplo, una variable que guardar la edad de un empleado
podra llamarse edad_empleado o edad, y no simplemente xyz, aunque ste es un identificador vlido y el
programa funcionar correctamente este nombre.
1.3.2 Ejemplos de identificadores
Los siguientes son todos identificadores vlidos en C#.
Intro. Prog. Orientada a Objeto Sintaxis en C# Rodrigo Sandoval U.
IIC 1102 Pgina: 5
puntero
nombre_empleado
area
TAMANO_STRING
EdadEmpleado
potencia10
i
For
iF
While
Nombre
nombre
Los siguientes son identificadores invlidos. Entre parntesis se indica por qu.
nombre-empleado (no se puede usar el guin, slo el subrayado)
telfono (no se pueden usar caracteres especiales del Espaol)
while (sta es una palabra reservada del lenguaje C#)
Intro. Prog. Orientada a Objeto Sintaxis en C# Rodrigo Sandoval U.
IIC 1102 Pgina: 6
1.4 Declaracin de Clases y sus Elementos
Todos los elementos en cualquier programa en C#pertenecen a una clase. Por ello, lo primero que
siempre se debe hacer es declarar cada una de las clases que se requerirn. Eventualmente es factible
declarar un programa con una nica clase, que contendr su funcin principal.
La sintaxis para la declaracin de una clase tiene la siguiente forma:
[modificadores] class <classname> [: nombreclasebase]
{
[cuerpo de la clase]
}[;]

Ejemplo bsico:
class persona
{
private string nombre;
private int edad;

public void ImprimirNombre()
{
Console.WriteLine(Nombre: {0}, nombre);
}
}

La lnea base de la declaracin de una clase describe el nombre, los modificadores y atributos, y la clase
desde la cual se est heredando. Aqu se identifican como opcionales todos aquellos elementos entre
corchetes. Los modificadores pueden ser: public, private, o nada. El nombre de la super clase o clase
base, es cualquier nombre que se haya asignado a otra clase.
1.4.1 Visibilidad/accesibilidad de una clases y sus miembros
Cada clase puede pertenecer a un grupo de clases llamado Namespace. A su vez, cada clase se
compone de elementos, como atributos y mtodos, que forman parte del cuerpo de su declaracin y que
se revisan en la siguiente seccin.
Cada uno de stos, ya sea la clase o bien los atributos o mtodos, pueden ser acotados en su visibilidad
o accesibilidad, lo cual limita su uso desde mbitos fuera de la clase o del namespace. Dicho de otra
manera, si una clase contiene elementos que son privados, stos son slo visibles para los otros
elementos dentro de la misma clase, pero no para otros objetos de otras clases. Por el contrario, si la
clase contiene elementos pblicos, stos pueden ser visibles desde instancias de otras clases.
Para determinar la visibilidad o accesibilidad que se tendr a un elemento en particular, se antepone el
trmino: private o public, para explicitar su condicin. En el caso de las clases, al no explicitar nada, se
asume que son public. Por el contrario, en el caso de los elementos de una clase, como atributos o
mtodos, al no explicitar nada, se asumen como private. Por lo tanto, en la declaracin del ejemplo
bsico de clase anterior, la clase persona, es pblica en su mbito; sus dos atributos, nombre y edad
son explcitamente declarados como privados, y finalmente el mtodo ImprimirNombre es
implcitamente privado, al no haberse declarado expresamente su accesibilidad.
Intro. Prog. Orientada a Objeto Sintaxis en C# Rodrigo Sandoval U.
IIC 1102 Pgina: 7
1.4.2 Elementos de una Clase
El cuerpo de la declaracin de la clase se compone de los miembros de sta. Entre los miembros se
encuentran campos, propiedades, mtodos, constantes, operadores, entre otros varios elementos.
Campos: son aquellos atributos de la clase, definidos por un tipo de dato y un identificador. En el ejemplo
bsico anterior, nombre es un campo de tipo string (cadena de texto), que es privado a la clase.
Mtodos: secuencias de instrucciones que actan sobre los datos del objeto, o valores de los campos.
Propiedades: se les conoce tambin como campos inteligentes, ya que son mtodos que se ven como
campos de la clase. Esto permite que al utilizar una instancia de esta clase se logre un mayor nivel de
abstraccin, ya que no se requiere saber si se accesa un campo directamente o se est ejecutando un
mtodo de acceso.
Constantes: tal como lo sugiere su nombre, se trata de campos que no pueden ser modificados durante
la ejecucin del programa. El valor de la constante se declara junto con la definicin de la clase, por lo
que es un valor que debe ser conocido previamente a la ejecucin del programa. Una alternativa para
definir campos de valor fijo es usar el modificador readonly, que permite inicializar el valor de un campo
en el constructor de la clase, para luego quedar fijo para cualquier efecto posterior.
Estos ltimos dos tipos de elementos se vern en detalle en el captulo IV, Programacin OO con C#.
1.4.3 Campos
Para poder resolver un problema empleando un computador es necesario contar con algn mecanismo
para almacenar datos en forma temporal. Esto se logra con las variables, las que en el caso de ser parte
de una clase, se les conoce como campos o atributos.
En C#, las variables reciben nombres que respetan las reglas de los identificadores. Adems, toda
variable debe tener un tipo de dato asociado, que define bsicamente la clase de dato que se
almacenar en ella y la forma en que deber ser tratado.
Como se ver ms adelante, toda variable debe ser declarada previamente a su uso dentro del
programa, y esto debe hacerse respetando una sintaxis establecida.
En resumen: Una variable es un objeto que almacena un dato, es asociado a un identificador y a un
tipo.
La forma genrica es la siguiente:

<modificador> <tipo> <identificador> [= <valorInicial>] ;

Donde <tipo> puede ser: int, float, char, entre otras posibilidades. [] significa opcional.
<valor_inicial> puede corresponder a una constante del tipo entero, real, caracter, arreglo, etc.
<modificador> puede ser una de las siguientes posibilidades: public, protected, private, static,
const, readonly; que corresponden a descripciones del comportamiento de esta variable en relacin al
resto de los elementos del programa.
Ejemplos de declaraciones de variables:
int numero;
char sigla;
string nombre;

Ejemplos de declaraciones de variables asociadas a un dato:
Intro. Prog. Orientada a Objeto Sintaxis en C# Rodrigo Sandoval U.
IIC 1102 Pgina: 8
int numero = 10;
char sigla = G;
string nombre = Juan;

Ejemplos de declaraciones de variables con modificadores:
public int numero = 10; // Visible para otros objetos
private char sigla = G; // Invisible para otros objetos
const string nombre = Juan; // Valor fijo, constante

Los modificadores private, public, protected definen la visibilidad que tendrn otros objetos de tener
acceso a dichos campos. Por otro lado, const, readonly, se refieren a la factibilidad de poder modificar el
valor del campo una vez inicializado o definido. Finalmente, static define el comportamiento de todas las
instancias de la misma clase, y el tratamiento que puedan tener sobre el campo en cuestin.
1.4.4 Tipos de Datos
Cada uno de los distintos objetos que son manipulados dentro de un programa tiene asociado un tipo de
datos. Desde el punto de vista de almacenamiento o para llevar a cabo operaciones sobre estos objetos,
es necesario tratarlos de distinta manera. As, la mayora de los lenguajes de programacin separan
aquellos objetos que son caracteres de los que son nmeros enteros y nmeros con decimales.
Para la plataforma .NET, los tipos de datos bsicos son los siguientes, varios de los cuales sirven para
representar cantidades numricas, y otros para representar texto y otros.
Categora Nombre de la Clase Descripcin Tipo de Dato C#
Nmero
Entero
Byte Entero sin signo (de 8 bits). Valores de 0 a 256. byte
SByte Entero (de 8 bits). Valores de -127 a 128. sbyte
Int16 Entero (de 16 bits). Valores de -32767 a 32768. short
Int32 Entero de 32 bits int
Int64 Entero de 64 bits long
UInt16 Entero sin signo de 16 bits.. ushort
UInt32 Entero sin signo de 32 bits. uint
UInt64 Entero sin signo de 64 bits. ulong
Nmeros
reales
(con
decimales)
Single Nmero con decimales de precisin simple (32
bits).
float
Intro. Prog. Orientada a Objeto Sintaxis en C# Rodrigo Sandoval U.
IIC 1102 Pgina: 9
Double Nmero con decimales con precisin doble (64
bits)
double
Lgicos Boolean Un valor booleano, verdadero o falso
(true/false)
bool
Otros Char Un carcter o smbolo Unicote (16 bits) char
Decimal Un valor decimal de 96 bits decimal
Class
objects
Object La raz de la jerarqua de objetos. object
String Una cadena de caracteres inmutable, de largo
fijo.
string


En el caso del lenguaje de programacin C#, los tipos de datos ms empleados son:
Los tipos enteros: int, short y long para manipular nmeros enteros.
Los tipos reales: float y double.
El tipo: char (a,z,?,$,@,G,7, etc.; en total los 256 caracteres del cdigo ASCII) para
caracteres, letras y smbolos.
As como algunos ms complejos como los strings y arreglos.
Es importante recordar que todo objeto dentro de un programa tiene un tipo de datos asociado, y es
necesario tener esta asociacin en mente a la hora de manipular, almacenar, operar y hasta desplegar en
pantalla dicho objeto.
1.4.4.1 Tipos enteros
Las variables de tipos de datos enteros pueden almacenar nicamente valores numricos sin
decimales. Si se intenta almacenar un valor con decimales en una variable entera, se producir un
truncamiento del valor.
El tipo entero bsico es int. Existen adems las variantes short que permite almacenar valores ms
pequeos (con el consiguiente ahorro de espacio en memoria), y el long, que soporta nmeros ms
grandes (pero con mayor gasto de memoria).
El valor mximo que se puede almacenar en las variables de cada uno de estos tipos depende de la
arquitectura del computador y del compilador que se estn empleando.
Constantes de Tipo Entero
Para declarar valores constantes de tipo entero, hay que reconocer si se trata de enteros de tipo int, o
long. Por ejemplo, la inicializacin de las siguientes dos variables considera un valor escrito como
constante entera, diferenciando que para el int, se usa un nmero simple y para el long, se agrega una L
al final:
int n1 = 10;
long n2 = 120390L;

Intro. Prog. Orientada a Objeto Sintaxis en C# Rodrigo Sandoval U.
IIC 1102 Pgina: 10
1.4.4.2 Tipos reales
Las variables de tipos de datos reales pueden almacenar valores numricos con decimales.
El tipo real bsico es float. Existe tambin la variante double, que permite almacenar valores en
doble precisin, ms grandes y con mayor cantidad de decimales. Sin embargo, el uso de este tipo
provoca un mayor gasto de memoria que si se empleara el tipo bsico float. La cantidad de
decimales, as como el valor mximo que se puede almacenar en variables de estos tipos depende de la
arquitectura del computador y del compilador que se estn empleando.
Constantes de Tipo Real
Al igual que en el caso de los enteros, los valores constantes de tipo real se diferencian en su declaracin
al identificarse como float o double, an cuando ambos usan valores decimales en su declaracin. El
caso de los floats requiere agregar una F al final, tal como se indica en el siguiente ejemplo:
float n1 = 10.0F;
double n2 = 120.390;
1.4.4.3 Caracteres: Tipo de datos char
Las variables de tipos de datos char, pueden almacenar un caracter del cdigo ASCII extendido
(256 caracteres). En realidad, lo que se guarda no es el caracter en s, sino el cdigo correspondiente.
Por lo tanto, puede verse al tipo char como un subtipo del tipo int, que puede almacenar enteros
entre 0 y 255. De hecho, las expresiones de tipo char pueden manipularse como enteros.
Las constantes de tipo char se representan delimitadas por comillas simples. As, para escribir el
caracter que representa la letra A mayscula escribimos:
'A'
El hecho de que las expresiones de tipo char se consideren como enteros permite llevar a cabo
conversin de tipos entre expresiones char y expresiones int. Por ejemplo, es posible llevar a
cabo las siguientes asignaciones, las cuales son todas equivalentes y almacenan en la variable
correspondiente la letra A mayscula (cdigo ASCII 65).
char ch;
int i;

ch = 65;
i = 'A';

ch = 'A';
i = 65;
Adems, puede emplearse el smbolo \ para denotar caracteres mediante su cdigo ASCII. Con esta
notacin, el caracter 'A' puede representarse tambin como '\65'
Esta notacin es muy til para representar caracteres especiales, que no aparecen en los teclados y no
se pueden ver en la pantalla. Este es el caso del caracter nulo (ASCII 0): '\0', el cual se emplear
ms adelante para indicar el final de los strings. As, las siguientes son representaciones
equivalentes en C para el caracter constante que representa la letra A mayscula:
'A'
65
'\65'
Intro. Prog. Orientada a Objeto Sintaxis en C# Rodrigo Sandoval U.
IIC 1102 Pgina: 11
La preferencia en usar la tercera notacin y no la segunda es por simple claridad, para dejar bien claro
que se est manipulando un caracter y no un nmero (aunque para el C es lo mismo).
Otros caracteres especiales que se pueden representar mediante esta notacin son:
'\n': Caracter de nueva lnea (a veces usado en Console.WriteLine, ms
adelante)
'\t': Tabulador (tambin til en Console.WriteLine)
'\\': Caracter \ (esta es la nica forma de especificarlo)
Ms interesante resulta la manera de organizar los caracteres como cadenas de char, de manera que
puedan manipularse cadenas de texto (string). Las cadenas de texto se especifican entre comillas
dobles: "iic1102 seccin".
1.4.5 Mtodos o Funciones
Una funcin, genricamente se describe como un conjunto de instrucciones (posiblemente
acompaadas de algunos datos temporales), que llevan a cabo una subtarea dentro de un programa ms
complejo. Un mtodo es una funcin que pertenece a una clase en particular.
Por ejemplo, dentro de un programa que convierte una lista de temperaturas expresadas en grados
Fahrenheit, a grados Celsius, podramos definir una funcin que haga una de las conversiones, y la
emplearamos varias veces para lograr completar nuestra tarea.
Tenemos entonces que las funciones dentro de un programa cumplen con subtareas, para las
cuales es necesario suministrarles algunos datos de entrada, y luego de completadas, recibiremos
como resultado algunos datos de salida. Para el caso de una funcin que calcula el rea de un crculo,
la entrada que requiere la funcin sera el radio del crculo, y la salida que arrojara luego del cmputo
sera el valor para el rea. Este hecho se ilustra en el diagrama que se muestra abajo, en el que podemos
ver la tarea de transformacin de datos que cumple una funcin: La alimentamos con una entrada y
recibimos una salida en respuesta.
Por otra parte, para especificar el proceso de transformacin que debe llevar a cabo la funcin, es
necesario emplear las instrucciones del lenguaje de programacin. Es necesario respetar algunas pautas,
tanto para la especificacin de los parmetros de entrada, como del valor de retorno, pero la estructura
general es la misma.
1.4.5.1 Sintaxis de la definicin de Funciones o Mtodos
La sintaxis general de definicin de mtodos es la siguiente:
<accesibilidad> <tipo_retorno> <nombre_funcin> ( <lista_parmetros> ) {
<declaracin_de_variables_locales> ;
<cuerpo_de_la_funcin> ;
return (<valor_retorno>) ;
}
<accesibilidad>se refiere a la visibilidad que tienen otras partes de un programa para ejecutar el mtodo.
Las posibilidades son public, private, protected, lo cual define la accesibilidad que se tiene a este mtodo
desde otras clases.
<tipo_retorno> es el tipo del valor que devolver la funcin. Es posible definir funciones que no
devuelven ningn valor (para por ejemplo definir funciones que solo imprimen valores o ciertos
mensajes en pantalla, para los que no es necesario que devuelva valor alguno). Para definirlos o
declararlos, se utiliza como tipo de retorno la palabra reservada void. A estas funciones se las conoce
tambin como procedimientos, porque no devuelven ningn valor.
<nombre_funcin> debe ser sustituido por un identificador que corresponde al nombre con que se
invocar la funcin posteriormente (o llamada de la funcin). Debe ser un identificador vlido. El valor de
retorno de la funcin es asociado al nombre de la funcin.
Intro. Prog. Orientada a Objeto Sintaxis en C# Rodrigo Sandoval U.
IIC 1102 Pgina: 12
<lista_parmetros>corresponde con una lista de variables denotadas por identificadores asociados a un
tipo, cada uno representa un parmetro de entrada. La lista de parmetros puede ser vaca pero los
parntesis deben aparecer.
La <declaracin_de_variables_locales> se refiere a variables locales que podrn ser utilizadas
nicamente dentro de la funcin. Fuera de ella, no sern reconocidas.
El <cuerpo_de_la_funcin>es una lista de instrucciones, separadas por punto y coma.
<valor_retorno>, debe ser una expresin (constante, aritmtica, lgica del tipo que se especific como
<tipo_retorno>, y establece la expresin que retornar la funcin una vez que haya terminado.
1.4.5.2 Ejemplos: Definicin de Funciones
Funcin que convierte temperaturas
Funcin que calcula el rea de un crculo


// Funcin que recibe una temperatura expresada en grados Fahrenheit y
// retorna su equivalente en grados Celsius. El argumento de entrada es
// farenheit de tipo int. El valor de retorno tambin es de tipo int.
// La frmula de conversin es C=(F-32)*(5/9). Puede ocurrir truncamiento.
int celsius(int fahrenheit) {
return((fahrenheit-32.0)*(5.0/9.0));
}

// Funcin que recibe una temperatura expresada en grados Celsius y retorna
// su equivalente en grados Faherenheit. El argumento de entrada es celsius
// de tipo int. El valor de retorno tambin es de tipo int.
// La frmula de conversin es F=32+(C*9/5). Puede ocurrir truncamiento.
int fahrenheit(int celsius) {
return((celsius*9.0/5.0)+32.0);
}


// Funcin que calcula el rea de un crculo dado su radio. Tanto el
// argumento de entrada (radio) como el valor de retorno es de tipo
// float. La frmula implementada es A=Pi*R*R.
float area(float radio) {
return(3.14 * radio * radio);
}
1.4.6 Sintaxis de la llamada a las Funciones definidas
La sintaxis general de las llamadas a las funciones definidas es la siguiente:

<variable> = <nombre_funcin> ( <lista_parmetros> ) ;
<variable> corresponde a una variable denotada por un identificador del mismo tipo del valor que
devolver la funcin.
<nombre_funcin>es el identificador que corresponde al nombre con que se invoca a la funcin.
<lista_paramtros>debe corresponder a una lista de variables denotadas por identificadores asociadas a
un tipo, o expresiones de un tipo. Ya sean variables o expresiones, stas deben corresponder en cuanto
a cantidad, posicin y tipos a las variables que se definieron como parmetros de entrada en la definicin
de la funcin. Representan los valores que se entregan como entrada a la funcin. Si en la definicin de
la funcin no se us parmetro alguno, entonces en la llamada tampoco debe escribirse ninguna
expresin o variable, pero los parntesis deben aparecer.
Intro. Prog. Orientada a Objeto Sintaxis en C# Rodrigo Sandoval U.
IIC 1102 Pgina: 13

// Llamada a la Funcin que recibe una temp. expresada en grados Fahrenheit y
// retorna su equivalente en grados Celsius. El argumento de entrada es
// fahrenheit de tipo int. El valor de retorno tambin es de tipo int.
// La frmula de conversion es C=(F-32)*(5/9). Puede ocurrir truncamiento.
int grados_celsius ;
grados_celsius = celsius(int fahrenheit) ;

// Llamada a la Funcin que recibe una temp. expresada en Celsius y retorna
// su equivalente en grados Faherenheit. El argumento de entrada es celsius
// de tipo int. El valor de retorno tambin es de tipo int.
// La formula de conversin es F=32+(C*9/5). Puede ocurrir truncamiento.
int grados_farenheit ;
grados_farenheit = fahrenheit(31) ;

// Llamadas a la funcin que calcula el rea de un crculo dado su radio.
// Tanto los argumento de entrada (radio) como el valor de retorno son
// del tipo float. La frmula implementada es calculo_area = Pi*R*R.
float calculo_area ;
float radio = 5.56 ;

calculo_area = area(5.56) ;
calculo_area = area(radio) ;

1.4.7 La funcin principal Main() y los programas en C#
Un programa en C#, est formado por una o ms clases, que a su vez cuentan con una o ms
funciones compuestas de varias instrucciones. Estas funciones que realizan una tarea en particular
con los parmetros de entrada, devuelven valores que corresponden a sus resultados, que a su vez son
utilizados en otras funciones o mtodos.
El computador debe empezar a ejecutar en algn orden estas instrucciones. En el caso de un
programa, se comienza por referenciar los namespaces usados, que van en las primeras lneas con la
sintaxis using namespace; Luego se registran todas las clases definidas, con sus atributos y mtodos,
y luego se llega a la funcin Main(). Esta funcin consta tambin de declaraciones, instrucciones y
llamadas a las definiciones de otras funciones e instanciaciones de clase. El orden de ejecucin de las
instrucciones dentro de la funcin Main() es secuencial de arriba a abajo y es as como es posible
recin seguir la ejecucin del resto de las funciones.
1.4.8 Ejemplo en C#de la simulacin de compra de un boleto en el metro.

using System;

class Boleteria {

const int precio1 = 190;
const int precio2 = 250;
const int precio3 = 290;

private int cambio = 0;


public void ComprarBoleto(int valor, int dinero_en_mano) {
Console.WriteLine("Alcanzo {0} pesos al vendedor.", dinero_en_mano);
cambio = dinero_en_mano - valor;
}

Intro. Prog. Orientada a Objeto Sintaxis en C# Rodrigo Sandoval U.
IIC 1102 Pgina: 14
public int PreguntarHorario() {
int hora;
Console.WriteLine("Que horario es (1 = baja, 2 = media, 3 = alta ) ? ");
hora = int.Parse(Console.ReadLine());
return(hora);
}

// PrecioBoleto: indica el valor del boleto, segn la hora indicada
public int PrecioBoleto(int hora) {
int precio = 0;
if (hora == 1) precio = 190;
if (hora == 2) precio = 250;
if (hora == 3) precio = 290;
Console.WriteLine("Para la hora baja el precio del boleto es {0} ", precio);
return(precio);
}

public void TomarCambio() {
Console.WriteLine("Recibo cambio de {0} pesos", cambio);
}

}

class Bolsillo {

private int en_la_mano = 0;


public void SacarMonedas(int moneda) {
Console.WriteLine("Tomo una moneda de {0} de mi bolsillo ", moneda);
en_la_mano = en_la_mano + moneda;
}

public int EnLaMano() {
return (en_la_mano);
}
}



class MainApp {

static void Main() {

Boleteria boleteria = new Boleteria();
Bolsillo bolsillo = new Bolsillo();
int hora;
int valor;

hora = boleteria.PreguntarHorario();
valor = boleteria.PrecioBoleto(hora);

// Se sacan las monedas ($300) del bolsillo
bolsillo.SacarMonedas(100);
Console.WriteLine("Tengo {0} pesos en la mano ", bolsillo.EnLaMano());
bolsillo.SacarMonedas(100);
Console.WriteLine("Tengo {0} pesos en la mano ", bolsillo.EnLaMano());
bolsillo.SacarMonedas(100);
Console.WriteLine("Tengo {0} pesos en la mano ", bolsillo.EnLaMano());

boleteria.ComprarBoleto(valor, bolsillo.EnLaMano());

boleteria.TomarCambio();

Console.WriteLine("Gracias por su compra. Presione Enter para terminar");
Console.ReadLine();
}
}

Intro. Prog. Orientada a Objeto Sintaxis en C# Rodrigo Sandoval U.
IIC 1102 Pgina: 15



1.5 Expresiones
Se conocen como expresiones los valores que son manipulados dentro de un programa. Estos valores
pueden surgir como resultado de efectuar operaciones, como valores de retorno de las funciones,
al extraerlos de las variables, o simplemente pueden ser constantes expresadas directamente
dentro del cdigo del programa.
Las expresiones, al igual que el resto de las entidades dentro de un programa, tienen asociado un tipo de
datos. Este tipo indicar la forma en que podremos manipular la expresin, por ejemplo, en cules
variables podremos almacenar su valor.
Existe un conjunto de operadores para cada tipo de datos, de manera que siempre es posible construir
una nueva expresin a partir de una o varias ya existentes. Tenemos, por ejemplo, operadores
aritmticos para construir expresiones numricas, y operadores lgicos para construir expresiones
booleanas.
1.5.1 Expresiones Aritmticas
Las expresiones aritmticas son valores numricos, de tipos enteros o reales. Pueden ser
constantes, resultados de operaciones aritmticas como sumas o multiplicaciones, contenido de variables
numricas, o combinaciones de las anteriores unidas mediante operadores aritmticos.
Operadores binarios:
+ Suma

- Resta

* Multiplicacin

/ Divisin

% Mdulo (slo sobre tipos de nmeros enteros)
Intro. Prog. Orientada a Objeto Sintaxis en C# Rodrigo Sandoval U.
IIC 1102 Pgina: 16
Operadores unitarios:
- Signo negativo

++ Incremento

-- Decremento
Precedencia:
++ -- -(unitario)

* / %

+ -
Asociatividad:
Por la izquierda

Intro. Prog. Orientada a Objeto Sintaxis en C# Rodrigo Sandoval U.
IIC 1102 Pgina: 17
Expresiones
Los operandos pueden ser variables o constantes numricas. Sin embargo, los operadores unarios ++y -
- fueron pensados para aplicarse a variables y el operador unario - a constantes.
operando operador-binario operando

operador-unario operando

Caso particular:
++ -- (notacin pre o postfija)

Ejemplos de expresiones aritmticas:
2 + 3 * 2 * tiene precedencia sobre + (Resultado: 8)
(2 + 3) * 2 los parntesis alteran la precedencia (Resultado: 10)
-2 / x si x vale cero se producir un error de ejecucin
x++ notacin postfija (retorna el valor antes del incremento)
++x notacin prefija (retorna el valor despus del incremento)
2 - 1 + 3 asociatividad por la izquierda: 4
15 % 6 operador mdulo o residuo (Resultado: 3)
-x le cambia el signo al contenido de x
3 * 4 % 5 igual precedencia, pero asociativa a izq. (Retorna: 2)
3 * (4 % 5) los parntesis alteran la precedencia (Retorna: 12)
1 + 15 % 6 % tiene precedencia mayor (Retorna: 4)

El resultado de una operacin siempre debe ser almacenado en otra variable, o utilizado en alguna
funcin como parmetro.
Ej:
class MainApp {
static void Main() {
int a, b, c;
c = a + b; // Correcto
Console.WriteLine({0}, a + b); // Correcto
a + b; // Error
}
}
1.5.2 Operadores Compuestos
Un operador compuesto es una combinacin entre un operador binario, junto con un operador de
asignacin (=). La sintaxis general es:
x op= y;
lo cual es totalmente equivalente a
x = x op y;
Intro. Prog. Orientada a Objeto Sintaxis en C# Rodrigo Sandoval U.
IIC 1102 Pgina: 18
Por ejemplo:
int a, b;
b = 10; a = 3;
a += b;
Console.WriteLine({0}, a); // Imprime 13
1.5.3 Expresiones Relacionales, Lgicas o Booleanas
Este tipo de valores se emplea para dirigir al programa por un determinado flujo de ejecucin
dependiendo de la evaluacin a verdadero o falso de una expresin lgica. En C#se conoce el tipo
booleano como bool.
Operadores binarios:
&& AND (hace la conjuncin lgica de dos valores bool).
|| OR (hace la disyuncin lgica de dos valores bool).
Operadores unitarios:
! NOT lgico

Operadores relacionales o de comparacin:
Este tipo de operadores permite comparar el valor de dos expresiones de cualquier tipo, devolviendo
como resultado un valor booleano (entero).
== igual

!= distinto

< menor

<= menor o igual

> mayor

>= mayor o igual

Precedencia:
La precedencia est establecida por el siguiente orden de evaluacin. La asociatividad se aplica de
izquierda a derecha, para operadores con igual precedencia.
< <= >= >

== !=

&&

||

Intro. Prog. Orientada a Objeto Sintaxis en C# Rodrigo Sandoval U.
IIC 1102 Pgina: 19
Expresiones
Los operandos de las expresiones booleanas son valores booleanos, incluyendo aquellos que resulten de
la comparacin mediante los operadores relacionales mencionados anteriormente. Pueden emplearse
parntesis para dejar clara la precedencia de evaluacin.
operando operador-lgico-binario operando

operador-lgico-unario operando

Ejemplos de expresiones booleanas:
x Verdadero cuando el contenido de la variable x
es true.

!x Verdadero cuando el contenido de la variable x
es false.

true Verdadero siempre.

true || x Verdadero siempre, no importa lo que sea x.

false Falso siempre.

false && x Falso siempre, no importa lo que sea x.

(x > 5) && !y Verdadero cuando el contenido de la variable x
es mayor que 5, y el contenido de y es false.

(x==1) Verdadero si el valor de la variable x es 1.

5 == 6 retorna Falso.
4 > = 2 Retorna Verdadero.
((4 % 2 == 0) || (4 % 3 == 0)) && false
1.5.4 Precedencia de todos los operadores
Mxima
( ) [ ] - -
! ~ ++ --
* / %
+ -
<<
< <= >= >
== =
&
|
&&
||
= += -= /=
Mnima
Intro. Prog. Orientada a Objeto Sintaxis en C# Rodrigo Sandoval U.
IIC 1102 Pgina: 20
1.6 Instrucciones
Las instrucciones son las rdenes que reconoce un computador mientras se encuentra ejecutando un
programa. De hecho, un programa es una secuencia de instrucciones que al ejecutarse resuelve algn
problema para el usuario.
Los programas estn escritos en un lenguaje de programacin, el cual define el conjunto de instrucciones
vlidas que podemos utilizar al escribirlos.
En nuestro caso emplearemos el lenguaje de programacin C#, por lo que ser necesario que
estudiemos las instrucciones que componen dicho lenguaje. A lo largo del curso vamos a ir introduciendo
estas instrucciones de manera paulatina, hasta llegar a cubrir un subconjunto bastante importante del
lenguaje.
Las instrucciones disponibles pueden clasificarse dentro de alguna de las siguientes categoras:
Secuenciales
Ejemplos: declaraciones de variables, asignaciones, llamado a funciones, salida
(Console.WriteLine) y entrada (Console.ReadLine)
Control de flujo (o decisin)
Ejemplos: if, switch
Iteracin
Ejemplos: for, while, do-while, foreach

Sintaxis
La sintaxis de las instrucciones en C#vara bastante dependiendo de cada instruccin. En general, toda
instruccin debe ir terminada por un punto y coma, de la siguiente manera:
<instruccion>;
Existen instrucciones complejas que pueden abarcar varias lneas, y que pueden contener otras
instrucciones dentro de ellas en forma subordinada. Adems, las instrucciones se pueden agrupar en
bloques, delimitados por corchetes: {}, de la siguiente manera:
{
<instruccion1> ;
<instruccion2> ;
...
<instruccionN> ;
}
1.7 Operador de Asignacin
El operador de asignacin ( =) permite almacenar datos en las variables. Es un operador binario, que
requiere que su primer operando (el del lado izquierdo) sea una variable. El segundo operando (el del
lado derecho) puede ser otra variable, un valor constante, o una expresin en general. La sintaxis general
de este operador es la siguiente:
<variable>= <expresion>;
En caso de que el valor asignado sea una constante, el resultado de esta operacin es que el valor
expresado se almacenar en la variable especificada al lado izquierdo.
Intro. Prog. Orientada a Objeto Sintaxis en C# Rodrigo Sandoval U.
IIC 1102 Pgina: 21
Si el valor asignado es otra variable, se har una copia del valor almacenado en la segunda variable y se
almacenar en la variable del lado izquierdo. Si se trata de una expresin, sta se evaluar previamente y
su resultado se almacenar en la variable indicada.
En todo caso, es necesario tener en cuenta algunas consideraciones sobre los tipos de las variables y de
los valores que se estn asignando. Ms adelante se tratarn los aspectos relativos a la conversin de
tipos.
Ejemplos
indice = 0;
Se almacenar el valor 0 en la variable indice
suma = a+b;
Se obtendr la suma de las variables a y b, y el resultado se almacenar en la variable
suma
NuevaX = ViejaX;
El valor de la variable ViejaX se copiar a la variable NuevaX
j = (i = 9)
Asigna el valor de 9 a las variables i y j
1.7.1.1 Ejemplo: Intercambio del contenido de dos variables (vasos)
En este ejemplo ilustraremos la problemtica de intercambiar el contenido de dos variables. Al igual que
cuando nos enfrentamos al problema de intercambiar el contenido de dos vasos, en este caso ser
necesario emplear un tercer elemento de almacenamiento (variable o vaso), para guardar temporalmente
durante el intercambio uno de los contenidos.
El problema del intercambio del contenido de dos variables puede plantearse de manera similar al
problema de intercambiar el contenido de dos vasos llenos. La solucin en ambos casos es simple: Se
necesita de un tercer elemento de almacenamiento (vaso o variable) para el almacenamiento temporal
del contenido.

Intro. Prog. Orientada a Objeto Sintaxis en C# Rodrigo Sandoval U.
IIC 1102 Pgina: 22

using System;

class MainApp {

static void Main() {
int var1, var2; // Variables enteras que sern intercambiadas
int aux; // Variable auxiliar necesaria para hacer el intercambio
var1 = 10; // Asigna valores a las variables
var2 = 30;

// Imprime el valor inicial de las variables, antes del intercambio
Console.WriteLine("var1 contiene {0} y var2 contiene {1}", var1, var2);

aux = var1; // Paso 1: El valor inicial de var1 se guarda en aux
var1 = var2; // Paso 2: El contenido de var2 se pasa a var1
var2 = aux; // Paso 3: El valor inicial de var1 se pasa a var2

// Imprime el valor final de las variables, luego del intercambio
Console.WriteLine("var1 contiene {0} y var2 contiene {1}", var1, var2);

Console.Write("Presione ENTER para terminar."); Console.ReadLine();
}
}

1.8 Conversin de Tipos (Type Casting)
El lenguaje C#permite cambiar el tipo de datos de las expresiones en el momento de llevar a cabo las
asignaciones. Por ejemplo, si se asigna una expresin entera a una variable de tipo real, el valor de la
expresin se convertir primero al tipo real antes de llevar a cabo la asignacin. Este resulta ser el caso
ms simple de una conversin de tipos, pero existen algunas situaciones en las que se requiere de cierta
atencin especial:
De un tipo real a uno entero
Se trunca el valor a su parte entera. La parte decimal se pierde.
Asignaciones entre char e int
Puesto que en C#se manejan los caracteres mediante su cdigo ASCII (que es un
nmero entero), este tipo de asignaciones funciona en general sin problemas.

La forma de realizar la conversin es requerida en forma explcita por C#. Esto se hace siguiendo la
siguiente sintaxis:
(<tipo>) <expresion>
Ejemplo:
int a = 2;
float b;
b = a; // Error: no se puede convertir implcitamente int en float
b = (int) a; //Correcto

Ejemplos
parte_entera = 7/4;
Como todos los valores involucrados son int, a la variable parte_entera se le asignar el
Intro. Prog. Orientada a Objeto Sintaxis en C# Rodrigo Sandoval U.
IIC 1102 Pgina: 23
resultado de la divisin pero truncado: 1
(int)(7.0/4.0)
El resultado de esta expresin tambin es 1
7.0/4.0
El resultado de la divisin ser exacto, con todos los decimales
7.0/4
Se convierte el 4 a 4.0 y la divisin arroja decimales
x = 7.0/4.0
El resultado de la divisin tendr decimales, pero si la variable x es de tipo entero al
asignar el valor habr truncamiento.
(float)1
Convierte 1 a tipo float, resultando en 1.0

1.9 Entrada y Salida
La mayor parte de los programas interactan con el usuario durante su ejecucin. De esta forma, el
usuario puede suministrar al programa sus datos de entrada, y puede recibir de ste los resultados
obtenidos.
Para llevar a cabo esta interaccin es necesario contar con instrucciones destinadas para tal efecto. C#
incluye un conjunto de instrucciones destinadas a llevar a cabo entrada y salida de datos. Quiz las de
mayor uso son las orientadas a la entrada y salida de datos con formato (namespace System).
Para llevar a cabo salida con formato contamos con la instruccin Console.WriteLine y
Console.Write, las cuales permiten desplegar en la pantalla del computador informacin de
variados tipos, permitindonos a la vez especificar la forma en que dichos datos debern aparecer
(formato).
Ambas instrucciones utilizan una serie de caracteres de conversin para especificar el formato que
deber tener la informacin de salida. De este modo ser posible interpretarla correctamente.
Para obtener entradas con formato disponemos de la instruccin Console.ReadLine y
Console.Read, las cuales permiten capturar desde el teclado del computador informacin de
variados tipos.
1.9.1 Salida con Formato: Console.WriteLine
La funcin Console.WriteLine, permite desplegar datos en la pantalla, con la posibilidad de
especificar el formato con que se desea que aparezcan. Esta instruccin se diferencia de
Console.Write, en que la primera incluye un cambio de lnea al final, permitiendo comenzar en una
nueva lnea al siguiente llamado a la misma instruccin, mientras que la segunda no hace un cambio de
lnea al terminar.
Sintaxis General:
Console.WriteLine("cadena-de-formato",<lista_de_argumentos>);
La cadena de formato debe ir delimitada por comillas dobles, y debe incluir una referencia y eventual
especificacin de conversin por cada argumento en la lista de argumentos. El texto que se incluya en la
cadena de formato aparecer durante el despliegue, y cada especificacin de conversin ser
reemplazada por el correspondiente argumento.
Intro. Prog. Orientada a Objeto Sintaxis en C# Rodrigo Sandoval U.
IIC 1102 Pgina: 24
La lista de argumentos consiste de una secuencia de expresiones que se desean desplegar. Las
expresiones pueden ser variables, constantes u operaciones que deben resolverse antes del despliegue.
Tambin es posible especificar llamados a funciones que devuelvan algn valor.
1.9.1.1 Referencia a la Lista de Argumentos
En la cadena de formato, se indican los ndices referenciados a la lista de argumentos, especificando el
orden en que se mostrarn estos elementos. El primer elemento de la lista corresponde al ndice 0, el
segundo al 1, y as sucesivamente. Si por ejemplo se requiere mostrar tres datos en pantalla, se puede
hacer de la siguiente manera:
int a = 1, b = 2, c = 3;
Console.WriteLine(Los valores son: {0}, {1}, {2}, a, b, c);
La salida en pantalla de esto sera:
1, 2, 3
Siempre es posible saltarse la cadena de control, cuando el valor a imprimir es uno solo y no se requiere
mayor texto. Para imprimir slo la variable a, se usa:
Console.WriteLine(a);
1.9.1.2 Especificaciones de Formato
Es posible definir cmo se requiere mostrar el valor de una variable en la lista de argumentos, de modo
de controlar la esttica de los resultados en pantalla. Este formato depender del tipo de dato que se
quiera mostrar, y del espacio que quiera dedicarse en pantalla, lo que ayuda a tabular y organizar la
informacin en pantalla en forma ms precisa.
La forma de indicar un especificador de formato es agregando informacin en el par de llaves para la
referencia de la lista de argumentos, de la forma: {indice:formato}.
indice siempre referencia, desde el 0, al primero, segundo, ... elemento de la lista.
Formato puede ser uno de los siguientes:
- C o c, para formato monetario (tomado de la configuracin de Windows)
- D o d, para nmeros enteros (decimales).
- E o e, para nmeros en formato de exponente (ej: 1.234E+005)
- F o f, para nmeros reales, con parte decimal
- G o g, para formato general.
- N o n, similar a F, pero con la separacin de miles.
- P o p, porcentaje.
- R o r, round-trip o viaje redondo, que se usa en nmeros reales. Garantiza que un valor
numrico convertido a string ser re-transformado de vuelta sin perder informacin.
- X o x, nmero en formato hexadecimal (ej: 1A24C)

Ejemplo:
int a = 123456;
Console.WriteLine({0:C}, a); // $123,456.00
Console.WriteLine({0:D}, a); // 123456
Console.WriteLine({0:E}, a); // 1.23456E+005
Console.WriteLine({0:F}, a); // 123456.00
Console.WriteLine({0:G}, a); // 123456
Intro. Prog. Orientada a Objeto Sintaxis en C# Rodrigo Sandoval U.
IIC 1102 Pgina: 25
Console.WriteLine({0:N}, a); // 123,456.00
Console.WriteLine({0:P}, a); // 12,345,600.00 %
Console.WriteLine({0:X}, a); // 1E240

Para especificar una cantidad definida de ceros en la parte decimal, se acompaa el formato con un
nmero que representa la cantidad de ceros.
Ejemplo:
int a = 123456;
Console.WriteLine({0:F5}, a); // 123456.00000

Para controlar el espacio en que esta informacin se despliega en pantalla, se puede especificar una
cantidad de espacios que el dato utilizar en pantalla, e incluso la alineacin. Esto se especifica de la
forma: {indice:espacio}
Espacio siempre toma el valor de un nmero entero, positivo o negativo, de acuerdo a las siguientes
condiciones:
Nmero negativo, indica que el campo debe ajustarse a la izquierda.
Nmero positivo, indica que el campo debe ajustarse a la derecha.
El nmero indicado en espacio, indica la cantidad de espacios en total que debe ocupar el
campo.
Ejemplo:
int a = 123456;
Console.WriteLine({0,-15:F5}, a); // 123456.00000
Console.WriteLine({0,15:F5}, a); // 123456.00000
Console.WriteLine({0,10}, a); // 123456

Dentro de la expresin de conversin pueden especificarse las siguientes secuencias que tienen un
significado especial:
\n - Para provocar que el cursor cambie de lnea
\t - Para producir una tabulacin en el despliegue
\ASCII - Despliega el caracter con el cdigo ASCII suministrado

Ejemplos:
Console.WriteLine("El valor de la variable x es: {0}", x);
Desplegar: El valor de la variable x es: 100 (si x contena un valor igual a 100), y
avanzar a la siguiente lnea luego del despliegue
Console.WriteLine("El valor de dos + cinco es: {0}", 2+5);
Desplegar: El valor de dos + cinco es: 7 y avanzar a la siguiente lnea luego del
despliegue

Console.WriteLine("El rea de un circulo con radio {0:F2} es {1:F2}",
radio, area);
Desplegar: El area de un circulo con radio 1.00 es 3.14 (suponiendo los valores
indicados para las variables) y avanzar a la siguiente lnea luego del despliegue
Intro. Prog. Orientada a Objeto Sintaxis en C# Rodrigo Sandoval U.
IIC 1102 Pgina: 26
1.9.2 Entrada con Formato: Console.ReadLine y Console.Read
La funcin Console.ReadLine, al igual que Console.Read, permite capturar datos desde el
teclado, distinguiendo entre ambas por la necesidad de agregar un ENTER al final del ingreso en el caso
de la primera.
Sintaxis General:
string texto;
texto = Console.ReadLine();
Usualmente se requiere transformar esta entrada de datos en algn tipo ms razonable de acuerdo al
contexto del ejemplo y para ello se utilizan los mtodos nativos de conversin desde texto de los tipos de
dato numricos. En dichos casos, la sintaxis es:

<tipo> numero;
numero = <tipo>.Parse(Console.ReadLine());
La primitiva Parse(), recibe un string y lo transforma en un valor acorde con el tipo de dato referenciado.

Ejemplos:
int edad;
Console.Write(Ingrese su edad: );
edad = int.Parse(Console.ReadLine());
Espera un entero que ser almacenado en la variable edad.

float nota;
Console.Write(Ingrese su nota: );
nota = float.Parse(Console.ReadLine());
Espera un nmero real (con decimales) que ser almacenado en la variable nota.

string nombre;
Console.Write(Ingrese su Nombre: );
edad = Console.ReadLine();
Espera un texto (string) que ser almacenado en la variable nombre.



Intro. Prog. Orientada a Objeto Sintaxis en C# Rodrigo Sandoval U.
IIC 1102 Pgina: 27
1.10 Comentarios, Indentacin y Otros Aspectos Visuales
1.10.1 Comentarios
Con el objetivo de hacer los programas ms legibles, es importante la incorporacin de comentarios que
ayuden a comprender lo que hizo el programador. Es importante documentar dentro del programa
cualquier aspecto que no quede claro de la simple lectura del cdigo. Los comentarios son
IMPRESCINDIBLES.
Con este fin, el lenguaje ofrece la posibilidad de incluir dentro del programa cualquier texto que pretenda
comentar el cdigo escrito. Este texto puede abarcar una o varias lneas, y debe incluirse dentro de los
delimitadores mostrados a continuacin.
Sintaxis General:
// Comentario simple siempre se separan por lneas,
// debiendo comenzar cada nueva lnea con otro par de //


/* Comentario si se usa el asterisco con slash, se puede
seguir en varias lneas sin volver a declarar en cada lnea
el smbolo de comentarios ... hasta que se termina con */


Ejemplos:
/* Programa para calcular ...
Escrito por ...

Este ejemplo se refiere al algoritmo que permite calcular el valor
de la frmula con los parmetros ...
*/

int radio; // Guarda el radio del circulo que se usa como referencia

/* La siguiente funcin calcula el rea de un crculo */
float area(float radio) { ...

1.10.2 Indentacin (indexacin) y otros aspectos visuales
A pesar de que el lenguaje de programacin C#ofrece una amplia libertad en cuanto a la forma en que
pueden escribirse los programas, es necesario establecer algunas normas que ayuden a hacer los
programas ms legibles, y por lo tanto ms fciles de comprender y modificar. Aunque no es posible
ofrecer una lista exhaustiva de todas las decisiones de formato que un programador debe enfrentar al
escribir sus programas, intentaremos establecer algunas pautas, y el resto lo dejaremos para ser
percibido a lo largo del curso al estudiar los ejemplos.
Ahora bien, las normas aqu mostradas no son absolutas, y reflejan nicamente las preferencias del
autor. Existen muchas otras, quiz hasta mejores. Lo importante aqu es adoptar un estndar y respetarlo
al mximo posible. De esta forma escribiremos programas correctos, no slo en cuanto a su
funcionalidad, sino tambin en cuanto a su apariencia.
Intro. Prog. Orientada a Objeto Sintaxis en C# Rodrigo Sandoval U.
IIC 1102 Pgina: 28
1.10.3 Algunos consejos
Dnde poner los corchetes?
funcion (argumentos) {
...
}

Cmo indentar el cdigo?
Los programas normalmente tienen una estructura jerrquica (por niveles), y es importante
destacarla al escribirlos. Esto se logra mediante indentacin, es decir, dejando algunos espacios
entre el cdigo que esta en un nivel y el del siguiente nivel. Pero cundo indentar?. Lo ms
sencillo es mirar los ejemplos. Una regla sencilla es que cada vez que se abran corchetes se
estar creando un nuevo nivel y por lo tanto es necesario indentar. Por ejemplo:
static void Main () {
...
while (...) {
...
for (...) {
...
}
...
}
...
}

Para ponerle nombre a las cosas
Trate siempre de que el nombre ayude a comprender la funcin del objeto que est identificando.
Por ejemplo, una variable que almacena la edad de un empleado podra llamarse Edad, o mejor
an EdadEmpleado, y no simplemente x. Las funciones deben tener nombres activos, como
CalculaPension, y no simplemente Pension, o peor an un nombre sin sentido. Cuanto ms
significativos sean los nombres, menor ser la cantidad de comentarios que deber incluir.
Cundo poner comentarios?
Es importante iniciar todo programa con un comentario en el que se explica lo que hace el
programa de manera general, cules son sus entradas y cules sus salidas, as como las
restricciones que tiene, si es que existen. Toda funcin deber tener un comentario similar.
Adems, aquellas variables cuyo nombre no sea lo suficientemente explcito, debern tener un
comentario sobre su objetivo en la declaracin. Por ejemplo:
/* Programa para ...
El programa lee del usuario ...
... y le devuelve como respuesta ...
Restricciones: No es posible ...
*/

int x; /* Almacena el valor para ... */

int EdadEmpleado; /* Obvio: No hace falta comentario */


/* Funcion para .... */
...

/* Funcion para .... */
Intro. Prog. Orientada a Objeto Sintaxis en C# Rodrigo Sandoval U.
IIC 1102 Pgina: 29
...

/* Funcion principal: Hace lo siguiente ... */
main() {

/* Dentro del codigo tambien puede haber comentarios,
para explicar aspectos que pueden ser dificiles de
comprender */
}

Material preparado por Rodrigo Sandoval U en Marzo y Agosto 2004

PONTIFICIA UNIVERSIDAD CATLICA DE CHILE
ESCUELA DE INGENIERA
DEPARTAMENTO DE CIENCIA DE LA COMPUTACIN
IIC 1102 INTRODUCCIN A LA PROGRAMACIN
Profesor: Rodrigo Sandoval U.

Captulo III Programacin Orientada a Objetos


1 PROGRAMACIN ORIENTADA A OBJETOS............................................................................................. 1
1.1 CONCEPTOS EN ORIENTACIN A OBJETOS......................................................................................................1
1.1.1 Clase....................................................................................................................................................... 1
1.1.2 Objeto..................................................................................................................................................... 1
1.1.3 Relaciones .............................................................................................................................................. 2
1.1.4 Herencia................................................................................................................................................. 3
1.1.5 Polimorfismo.......................................................................................................................................... 3
1.2 LENGUAJ ES ORIENTADOS A OBJETOS .............................................................................................................4
1.3 EJ EMPLO: VEHCULOS HERENCIA Y POLIMORFISMO....................................................................................5


Introduccin a la Programacin Orientada a Objetos Rodrigo Sandoval U.
IIC 1102 Pgina: 1
1 Programacin Orientada a Objetos
Un enfoque ms reciente (aos 90) para la resolucin de problemas, se basa en la utilizacin de
Objetos, estableciendo un esquema en que cada elemento del mundo real se representa con mayor
precisin y fidelidad, logrando as soluciones modulares (compuestas por partes, hasta cierto punto,
independientes, que potencialmente pueden reutilizarse en otros modelos) y con encapsulacin (que
logra ocultar la complejidad de soluciones en ciertos mdulos, evitando que los participantes de la
solucin tengan que dominar cada parte de sta).
La interaccin entre los objetos se conceptualiza como el paso de mensajes (llamados a los mtodos),
que hacen que estos objetos reaccionen, cambiando su estado y condiciones.
Una de las principales razones que avalan la programacin OO, es la mantenibilidad del software
desarrollado bajo este esquema. Su necesidad se fue viendo cada vez ms evidente a medida que
programas de cientos de lneas de cdigo se ponan en produccin y cualquier modificacin mayor
significaba un proceso traumtico de revisin, entendimiento, modificaciones y pruebas. El enfoque OO
naci en parte de la idea de resolver esta problemtica, aislando la complejidad en mdulos hasta cierto
punto independientes, que son individualmente ms fciles de mantener.
1.1 Conceptos en Orientacin a Objetos
En este contexto se definen los objetos como estructuras de software para representar elementos del
mundo real, relacionndolos a travs de una descripcin del estado del objeto mediante variables o
propiedades, y su comportamiento mediante mtodos o funciones.
1.1.1 Clase
Una clase es un Tipo de Objeto, definiendo todas aquellas caractersticas: campos o atributos y
mtodos o acciones, comunes a todos los objetos de este tipo. Cada clase, por ende, se define en base a
elementos que la componen, que en definitiva establecern la diferencia entre un objeto y otro.
Los atributos o campos, son elementos que pueden ir tomando diferentes valores a lo largo de la vida del
objeto, an cuando algunos de stos puedan ser definidos como constantes.
Los mtodos hacen uso de los atributos de la clase, as como de otros elementos propios, para
determinar una secuencia de instrucciones descrita en forma de algoritmo.
Adicionalmente, es factible definir la accesibilidad que se tendr desde otros objetos a los elementos de
dicha clase. Para ello se establece que stos pueden ser pblicos (visibles) o privados (slo visibles
desde los mtodos componentes de la clase).
1.1.2 Objeto
En una implementacin OOP (Object Oriented Programming), se llaman Instancias a todas aquellos
objetos distintos, de una misma clase, que se usen en un momento determinado. Cada objeto se
identifica individualmente por su nombre (nombre de la instancia) y se define un estado representado por
los valores de sus atributos en un momento particular del tiempo.
Introduccin a la Programacin Orientada a Objetos Rodrigo Sandoval U.
IIC 1102 Pgina: 2

Diagrama que ilustra un programa compuesto de 4 objetos diferentes,
los cuales interactan entre ellos, como lo indican las flechas.
1.1.3 Relaciones
La relacin entre los objetos puede ir ms all que un simple esquema de mensajes entre ellos. Existen
relaciones ms poderosas, que se define como Tipo de, Es un, Parte de, Tiene un.
Por ejemplo, hablando de figuras geomtricas, se puede definir la clase Punto, con coordenadas x,y.
Esto, en un pseudo-lenguaje OO se ve de la siguiente manera:
Clase Punto {
atributos:
int x, y

metodos:
setX(int nuevoX)
getX()
setY(int nuevoY)
getY()
}

Evolucionando la idea un poco ms all, se pueden definir figuras geomtricas en base a la definicin de
punto, como sera el caso de un crculo, que tiene un centro (un punto) y un radio.
Clase Circulo {
atributos:
int x, y, radio

metodos:
setX(int nuevoX)
getX()
setY(int nuevoY)
getY()
setRadio(nuevoRadio)
getRadio()
}

Introduccin a la Programacin Orientada a Objetos Rodrigo Sandoval U.
IIC 1102 Pgina: 3
En este caso, ambas clases tienen dos atributos comunes: x, y. Ambas ofrecen prcticamente los mismos
mtodos, y es la clase Circulo la que define un nuevo elemento y mtodos asociados.
Por ello, se puede definir que Circulo es un Tipo de Punto, aun cuando es ms especializado que el
Punto en si. Si declaramos una instancia de tipo Circulo, nos encontraremos con que esta instancia tiene
los mismos elementos que un Punto, por lo que se asume que Circulo Es un Punto tambin.
Declarando una tercera clase:
Clase Figura {
atributos:
Circulo circulo1
Triangulo triangulo1

metodos:
set(Punto donde)
}
Nos encontramos con que en el caso de Circulo y Triangulo (una clase definida equivalentemente a
Circulo), ambas son Parte de Figura, y que a su vez, Figura Tiene un Circulo y un Triangulo.
1.1.4 Herencia
La herencia nos permite establecer relaciones Es un Tipo de y Es un entre clases. En el ejemplo del
punto, la declaracin del Circulo en base a la declaracin previa de Punto se vera:

Clase Circulo heredando de Punto {
atributos:
int radio

metodos:
setRadio(nuevoRadio)
getRadio()
}

De esta manera, esta relacin de herencia asume que todo lo que sea vlido en Punto, lo ser tambin
en Crculo. Por ello, un Circulo tendra como atributos el radio, y tambin, x e y, al igual que los mtodos
respectivos.
De esa manera, la herencia se define como el mecanismo que permite que una clase A herede
propiedades de una clase B. Los objetos de la clase A (llamada Clase Derivada o Subclase) tienen
acceso a atributos y mtodos de la clase B (llamada Super Clase), sin necesidad de volver a definirlos.
1.1.5 Polimorfismo
La definicin de polimorfismo en este contexto se basa en la posibilidad de utilizaar un mismo nombre
para diferentes propsitos, que aunque relacionados, son ligeramente distintos. La idea del polimorfismo
es permitir el uso de un nombre en una clase especfica de accin. Dependiendo de qu tipo de datos se
est utilizando para trabajar, una instancia especfica del caso general se ejecuta.
Hay diversas formas de establecer polimorfismo con los lenguajes orientados a objeto: Reutilizacin de
nombres de atributos y mtodos, y la sobrecarga de mtodos.
Introduccin a la Programacin Orientada a Objetos Rodrigo Sandoval U.
IIC 1102 Pgina: 4
1.1.5.1 Reutilizacin de Nombres
En el ejemplo anterior del Punto, se podra definir el mtodo Mover(x,y), que mueve el punto a una nueva
direccin x,y. Esta misma funcin podra ser implementada en un objeto Triangulo, donde la funcin sera
exactamente la misma desplazar la figura a una nueva posicin pero actuara de una manera distinta,
ya que el objeto en s es distinto, an cuando el mismo nombre de mtodo (Mover) sea utilizado.
De esa manera, si el nombre del mtodo resulta ser lo suficientemente explcito para representar la
operacin lgica que ejecuta, este nombre se puede reutilizar en la definicin de otras clases, incluso en
casos en que una clase que implementa el mtodo, herede de otra clase que tambin lo implementa, de
esa manera aprovechando el nombre, pero estableciendo una nueva versin de su funcionamiento.
1.1.5.2 Sobrecarga de Mtodos
Cuando el mismo nombre de un mtodo se utiliza ms de una vez dentro de una misma clase,
usualmente se diferencia por los parmetros que recibe. Tal es el caso de la declaracin de constructores
de las clases, donde pueden existir diversas versiones de stos, cada uno diferencindose del otro por
los parmetros (el tipo de los parmetros, la cantidad, y el orden en que se entregan).

1.2 Lenguajes Orientados a Objetos
Segn varios autores, el inters por la OO surgi en el contexto de la crisis del software de los aos 70 (la
falta de reusabilidad de software). Al hablar de la OO, se suelen identificar las siguientes ventajas:
Desarrollo rpido de sistemas.
Mejora en la calidad y legibilidad del cdigo.
Facilidad de mantenimiento.
Aprovechamiento del poder de los LOOP.
Reusabilidad de software y diseos.
Produccin de sistemas ms resistentes al cambio.
La OOP y los LOOP juegan un papel importante dentro de las tecnologas OO. Segn la literatura, el
trmino objeto emergi paralelamente en varios campos de la Informtica a principios de los aos 70,
para hacer referencia a nociones superficialmente distintas aunque relacionadas. La identificacin de la
importancia de la composicin de sistemas en niveles de abstraccin, la ocultacin de informacin y el
desarrollo de mecanismos de tipos de datos abstractos en los aos 70 tuvieron una gran influencia en el
desarrollo de la OOP, aunque existe cierta polmica sobre como exactamente estos avances dieron lugar
a lo que hoy en da se considera como OOP. El LOOP Simula apareci en 1962 (y ms tarde Simula67
en 1967) y, aunque no fue muy utilizado, ha sido reconocido como el primer LOOP, incorporando los
conceptos de clase y objeto.
El concepto de OOP propiamente dicho fue presentado por Alan Kay, uno de los inventores de Smalltalk
(el primer LOOP popular), algunos aos ms tarde:
Todo es un objeto que almacena datos y al que se le puede hacer peticiones.
Un programa es un conjunto de objetos que intercambian mensajes.
Cada objeto tiene su propia memoria que est compuesta por otros objetos.
Cada objeto tiene un tipo de mensajes que puede recibir y procesar.
Todos los objetos de un cierto tipo pueden procesar los mismos mensajes.
Se trata de una caracterizacin muy general que no se puede aplicar a muchos de los LOOP ms
utilizados hoy en da. Smalltalk tena estas caractersticas y fue concebido con el objetivo de ser un
LOOP dinmico, que permitiera la adicin de nuevas clases, objetos y comportamiento sobre la marcha.
Introduccin a la Programacin Orientada a Objetos Rodrigo Sandoval U.
IIC 1102 Pgina: 5
En las actas del congreso HOPL II editadas en 1993 por la ACM (Association of Computing Machinery),
Kay defini la OOP en trminos de una clula que permite el flujo de informacin en las dos direcciones,
pero en la cual lo que est dentro est oculto desde fuera. En 1985 apareci el LOOP Eiffel, diseado
para mejorar la productividad y calidad de programas OO, pero no fue muy utilizado.
Para que la OOP se estableciera como un paradigma era necesario que los programadores lo adoptaran.
Por eso fue muy efectiva la modificacin de un LP ya existente para incorporar los conceptos (y
beneficios) de la OOP, sin perder la posibilidad de reutilizar cdigo fuente, como ocurri con C++(que es
una extensin de C que incluye los conceptos OO).
Otros LP han sido expandidos tambin para incorporar estos conceptos: Modula2 se convirti en
Modula3, Ada en Ada95, Lisp en CLOS (Common Lisp Object System) va Flavors, COBOL en Object
COBOL, etc. Como ejemplos de LOOP de nueva creacin se pueden destacar Python, J ava y C#.
Actualmente se pueden identificar unos 140 LOOP que se usan de alguna forma u otra.
Otra manera de ver la OOP es como la evolucin natural de la programacin imperativa, desde la
programacin sin estructura, pasando por la programacin procedural y modular. En primer lugar, la
programacin sin estructura es la ms sencilla y cada programa consiste en una secuencia de
instrucciones que operan sobre datos globales o comunes a todas las partes del programa. Lo que ocurre
es que, segn va creciendo el programa, van surgiendo problemas. Por ejemplo, si se necesita la misma
secuencia de instrucciones en varias partes del programa, hay que copiarla. Para evitar este problema,
se empezaron a extraer estas secuencias, a darles un nombre, y a ofrecer una tcnica para llamarlas y
devolver el flujo de control desde ellas al programa principal junto con los resultados. As aparecieron los
procedimientos y funciones y la programacin procedural.
Con la incorporacin del paso de parmetros y procedimientos dentro de otros, se podan escribir
programas con ms estructura y menos probabilidades de errores. As, en vez de ver un programa como
una secuencia de instrucciones, se poda contemplar como una secuencia de llamadas a procedimientos.
La extensin natural de este tipo de programacin consisti en agrupar en mdulos procedimientos
comunes a varios programas, y as surgi la programacin modular. En ella cada mdulo tiene sus
propios datos y estado, que se modifican con las llamadas al mdulo. Por ltimo, como se ver a
continuacin, la OOP soluciona algunos de los problemas de la programacin modular: puede haber
simultneamente mltiples versiones de un mismo objeto y cada una es responsable de su propia
creacin y destruccin.

1.3 Ejemplo: Vehculos Herencia y Polimorfismo
Se da mucho en casos en que se requiere representar modelos jerrquicos derivados del mundo real,
en que los objetos involucrados tienen una relacin de origen entre ellos. Tal es el caso en este ejemplo,
donde se definen tres clases, dos de las cuales se podran definir como casos particulares de la clase
principal, o ms bien clases derivadas de la superclase.
public class Vehiculo {
public int ruedas; // Cantidad de ruedas
public int puertas; // Cantidad de puertas
// Mtodos
....
public void Avanzar()
{
...
}
}

Introduccin a la Programacin Orientada a Objetos Rodrigo Sandoval U.
IIC 1102 Pgina: 6
public class Camion : Vehiculo { // Herencia explcitamente declarada
public int tara;
public int carga;
// Mtodos
....
public void Avanzar()
{
...
}
}
public class Moto : Vehiculo { // Herencia explcitamente declarada
public int cilindraje;
// Mtodos
....
public void Avanzar()
{
...
}
}

En el ejemplo anterior se puede ver que se implementa:
- Herencia de clases. Al declarar la clase Camion, y tambin la clase Moto, como derivaciones de
una misma clase base: Vehiculo. Es importante recordar que esta herencia impone que tanto el
Camion como la Moto son Vehiculo.
- Polimorfismo. Tanto la clase base, como sus derivadas implementan un mtodo de nombre
Avanzar(). Este mtodo en forma lgica tiene posiblemente el mismo significado en los tres
casos, sin embargo, al estar definido en tres clases distintas, cada una de ellas puede definir su
propia implementacin, haciendo que su funcionamiento detallado difiera en todos los casos.
Llama particularmente la atencin que al re-definir el mtodo Avanzar() de la clase base, en las
clases derivadas, se reemplaza el funcionamiento de esta clase original.
PONTIFICIA UNIVERSIDAD CATLICA DE CHILE
ESCUELA DE INGENIERA
DEPARTAMENTO DE CIENCIA DE LA COMPUTACIN
IIC 1102 INTRODUCCIN A LA PROGRAMACIN
Profesor: Rodrigo Sandoval U.

Captulo IV Programacin Orientada a Objetos en C#


1 PROGRAMACIN ORIENTADA A OBJETOS EN C#................................................................................. 1
1.1 NAMESPACES..................................................................................................................................................1
1.1.1 Referencia de Namespaces..................................................................................................................... 1
1.1.2 Creacin de Namespaces ....................................................................................................................... 2
1.2 CONSTRUCTORES............................................................................................................................................2
1.2.1 Sintaxis de Definicin de Constructores ................................................................................................ 2
1.2.2 Llamado entre constructores de clases heredadas................................................................................. 3
1.3 ELEMENTOS ESTTICOS..................................................................................................................................4
1.4 PROPIEDADES..................................................................................................................................................5
1.5 CLASES ABSTRACTAS......................................................................................................................................6
1.6 SOBRECARGA DE MTODOS HEREDADOS.........................................................................................................7
1.7 SOBRECARGA DE OPERADORES (+, -, ...)..........................................................................................................8
2 SOLUCIONES ORIENTADAS A OBJETO..................................................................................................... 9
2.1 EJ EMPLO: NMEROS RACIONALES CLASES ABSTRACTAS, HERENCIA, OPERADORES, PROPIEDADES. .........9
2.2 EJ EMPLO: EJ ECUCIN DE UN PENAL HERENCIA, PROPIEDADES, SOBRECARGA MTODOS HEREDADOS.....12
2.2.1 Ejecucin de un penal Versin Consola............................................................................................ 14
2.2.2 Ejecucin de un penal Versin Windows .......................................................................................... 15


Material preparado por Rodrigo Sandoval U en Agosto 2004

Intro. Prog. Programacin OO en C# Rodrigo Sandoval U.
1 Programacin Orientada a Objetos en C#
Siguiendo la idea de la programacin orientada a objetos, y tomando como base la plataforma .NET y el
lenguaje C#, a continuacin se muestran algunas potencias de este lenguaje en implementar objetos con
ciertas particularidades adicionales a lo que otros lenguajes ofrecen.
1.1 Namespaces
En los programas en diversos lenguajes, particularmente en los que se basan en un esquema orientado a
objetos, se preferencia fuertemente la referencia a libreras externas, compuestas de elementos (en este
caso de clases), que pueden resolver algunos elementos de tipo general en el programa en desarrollo.
1.1.1 Referencia de Namespaces
En C# particularmente, se hace referencia a una serie de colecciones de clases que resuelven
funcionalidades requeridas por casi todos los programas. Estas colecciones de clases externas, que
pueden haber sido programadas y compiladas en forma individual y ajena al programa que las referencia,
se conocen en ingls como Namespaces.
Un ejemplo extremadamente omnipresente de namespace es la referencia System, el cual es una
coleccin de clases relacionadas con el sistema (computador) de uso bastante frecuente. Entre sus
clases ms recurridas en los ejemplos de este curso, se encuentra la clase Console, que hace referencia
a los mtodos de escritura y lectura hacia la pantalla y desde el teclado (que componen la console).
Para hacer referencia a un namespace, se hace uso de la directiva using (que es un equivalente al
#include del lenguaje C).
Es decir, un programa que hace acceso a la consola, y que referencia al namespace System, se ve as:
using System;

cl ass Mai nPr ogr am{

/ / El mt odo Mai n( ) es el al gor i t mo pr i nci pal .
publ i c st at i c voi d Mai n( ) {

/ / Escr i be t ext o en l a consol a.
Consol e. Wr i t eLi ne( " Hol a Mundo! " ) ;
Consol e. ReadLi ne( ) ; / / Esper a Ent er par a t er mi nar
}
}
Muchos de los namespaces incluidos en el framework de .NET, se referencian con nombres fuertes, es
decir, que son nombrados de una forma que indirectamente estructuran una organizacin. Es as, como
aparte del recurrido namespace System, existen otros que semnticamente se derivan de l, como es el
que provee las clases para el acceso a archivos (con mtodos similares a la clase Console), que se
conoce como System.IO. Si bien es un namespace totalmente distinto, su nombre completo, compuesto
de dos partes separadas por un punto, da una referencia semntica de su relacin con el namespace
System.
IIC 1102 Pgina: 1
Intro. Prog. Programacin OO en C# Rodrigo Sandoval U.
1.1.2 Creacin de Namespaces
Por otro lado, cada programador puede crear sus propios namespaces, donde en forma lgica se
agrupan clases que se complementan en su funcionalidad. Para ello, la declaracin es de la siguiente
forma.
namespace MiLibreria {
cl ass Cl ase1 {
. . .
}
cl ass Cl ase2 {
. . .
}
}
El uso de este namespace en un programa compuesto por otros archivos requiere la compilacin
conjunto, o bien la creacin de una librera dinmica (DLL), que se referencia en el segundo archivo, que
contiene el programa principal.

1.2 Constructores
Los constructores son un tipo particular de mtodos pertenecientes a una clase. El constructor es siempre
y nicamente invocado al instanciar una clase y proporcionan la capacidad de especificar las acciones a
tomar para inicializar la instancia en particular. El constructor es un concepto establecido en
prcticamente todos los lenguajes de programacin OO, incluyendo C#.
En pocas palabras, el propsito del constructor es concentrar la lgica de inicializacin de una instancia
cuando sta es creada. En muchos casos se define que el constructor recibe ciertos parmetros que
condicionan esta inicializacin, y que muchas veces se traducen en valores iniciales para los atributos de
la instancia.
1.2.1 Sintaxis de Definicin de Constructores
La declaracin de los constructores es la siguiente:
public <Nombr eCl ase> (<Li st aPar met r os>) {
<i nst r ucci ones>
}
Por definicin, los constructores son pblicos, ya que son ejecutados al instanciar la clase, sin
importar si sus otros elementos son pblicos o privados. Por ello, siempre se indica public.
Valor de retorno no se declara. No son void, ni ningn otro tipo de dato, ya que por definicin
conceptual del constructor, slo devuelve una instancia creada del objeto o clase que representa.
El nombre del constructor es siempre el nombre de la clase respectiva.
Puede recibir los parmetros que se estimen convenientes en cada caso. Es incluso factible
definir ms de un constructor para una misma clase, cambiando slo los parmetros recibidos.
Esto cae en la categora de sobrecarga de mtodos, en este caso sobrecarga de constructores.
Como cuerpo del constructor, se puede incluir cualquier tipo de instruccin vlida en cualquier
mtodo miembro de la clase. Slo es importante recordar que estas instrucciones, por definicin
conceptual, estn destinadas a la inicializacin de los elementos de la clase.

Ejemplo:
IIC 1102 Pgina: 2
Intro. Prog. Programacin OO en C# Rodrigo Sandoval U.
cl ass Per sona {
st r i ng nombr e;
i nt edad;

publ i c Per sona( st r i ng n, i nt e) {
nombr e = n;
i f ( e >= 0)
edad = e;
el se
edad = 0;
}
}

Al instanciar un objeto de esta clase, dado que el nico constructor declarado es el que recibe dos
parmetros, obligatoriamente se deben pasar los dos parmetros requeridos. Esto se vera as:
cl ass Mai nApp {
st at i c voi d Mai n( ) {
Per sona p1 = new Persona(Juan, 30);
. . .
}
}

1.2.2 Llamado entre constructores de clases heredadas
En el caso de haberse implementado herencia entre clases, el llamado entre constructores an puede ser
invocado y controlado. Para efectos prcticos, el uso de la palabra clave base() es sinnimo de llamar la
ejecucin del constructor de la clase base.
Esto se ve en el siguiente ejemplo, cuyo cdigo completo se encuentra en los ejemplos de este captulo,
unas pginas ms adelante.
cl ass Raci onal : Numer oCompuest o {

publ i c Raci onal ( i nt n, i nt d) / / Const r uct or de l a cl ase der i vada.
: base(n,d) // Se llama al constructor de la clase base.
{
. . . / / I ni ci al i zaci n par t i cul ar de l a cl ase der i vada
}
Aqu se ve que la clase Racional hereda de NumeroCompuesto, que a su vez cuenta con su propio
constructor. Al declarar el constructor de la clase derivada, que en este caso recibe los mismos dos
parmetros de la clase base, se pasan directamente estos dos parmetros a la ejecucin del constructor
de la clase base, dejando la lgica de ste intacta.
El siguiente ejemplo muestra una herencia de tres niveles y el llamado a los constructores respectivos. Al
probar este ejemplo se puede ver en pantalla el orden de ejecucin de los tres constructores respectivos.
usi ng Syst em;

cl ass Base {
publ i c Base( i nt n) { / / Const r uct or
Consol e. Wr i t eLi ne( " Const r uct or Base: {0}" , n) ;
}
}

IIC 1102 Pgina: 3
Intro. Prog. Programacin OO en C# Rodrigo Sandoval U.
cl ass Her edada1 : Base {
publ i c Her edada1( i nt n) : base( n) { / / Const r uct or
Consol e. Wr i t eLi ne( " Const r uct or Her edada1: {0}" , n) ;
}
}

cl ass Her edada2 : Her edada1 {
publ i c Her edada2( ) : base( 1) { / / Const r uct or
Consol e. Wr i t eLi ne( " Const r uct or Her edada2" ) ;
}
}


cl ass Mai nApp {
st at i c voi d Mai n( ) {
Her edada2 h2 = new Her edada2( ) ;
Consol e. ReadLi ne( ) ;
}
}

1.3 Elementos estticos
Una instancia (de objeto) se diferencia de otra por los valores de sus respectivos atributos que puedan
tener en un cierto momento. Es decir, cada instancia mantiene una copia de cada uno de los atributos
definidos para su clase. Sin embargo, es factible declarar tanto atributos como mtodos que no son
instanciados por cada objetivo individualmente, sino que son compartidos por todas las instancias de la
clase correspondiente.
Para declarar cules de los elementos de una clase (atributos, mtodos), son compartidos conjuntamente
por todas las instancias de la clase, se le antepone la palabra clave static en su declaracin.
Para ilustrar el concepto, el siguiente ejemplo declara una clase Producto, todas cuyas instancias tendrn
diferentes valores para los atributo codigo y precio, sin embargo, el mtodo CalcularValor() se basa en un
porcentaje de margen, que es comn para todas las instancias. De esa manera, modificar el valor de este
atributo es factible de hacerse en cualquiera de las instancias de la clase, y ese cambio se refleja para
todas las instancias.
usi ng Syst em;

cl ass Pr oduct o {
st r i ng codi go;
i nt pr eci o;
static float margen;

publ i c Pr oduct o( st r i ng c, i nt p) { codi go = c; pr eci o = p; }

publ i c voi d Cambi ar Mar gen( f l oat m) { mar gen = m; }

publ i c f l oat Cal cul ar Val or ( ) {
r et ur n( ( f l oat ) pr eci o*( 1+mar gen) ) ;
}
}

cl ass Mai nApp {
st at i c voi d Mai n( ) {
Pr oduct o p1 = new Pr oduct o( " P001" , 30) ;
IIC 1102 Pgina: 4
Intro. Prog. Programacin OO en C# Rodrigo Sandoval U.
Pr oduct o p2 = new Pr oduct o( " P002" , 10) ;
Pr oduct o p3 = new Pr oduct o( " P003" , 20) ;

p1. Cambi ar Mar gen( 0. 15F) ; / / Se apl i ca a p1, p2, p3

Consol e. Wr i t eLi ne( " Val or es: {0}; {1}; {2}" ,
p1. Cal cul ar Val or ( ) , p2. Cal cul ar Val or ( ) ,
p3. Cal cul ar Val or ( ) ) ;

p1. Cambi ar Mar gen( 0. 10F) ; / / Se apl i ca a p1, p2, p3

Consol e. Wr i t eLi ne( " Val or es: {0}; {1}; {2}" ,
p1. Cal cul ar Val or ( ) , p2. Cal cul ar Val or ( ) ,
p3. Cal cul ar Val or ( ) ) ;

Consol e. ReadLi ne( ) ;
}
}

Como resultado en pantalla se vera:
Valores: 34,5; 11,5; 23
Valores: 33; 11; 22

El mismo concepto static es aplicable a los mtodos de las clases, estableciendo aquellos mtodos que
seran independientes de la instancia particular. Esto es comnmente usado en la sobrecarga de
operadores, por ejemplo, lo cual se ve ms adelante en este captulo.
Aqu cabe sealar con claridad que es sta precisamente la razn por la cual el mtodo Main() siempre
se declara static.

1.4 Propiedades
Tomando en cuenta la caracterstica privada de casi todos los atributos que se definen para una clase
las buenas prcticas de programacin fomentan declarar como private todos los atributos de las clases
se hace necesario ofrecer cierta visibilidad controlada sobre los valores de estos atributos. Esta visibilidad
se describe como la obtencin del valor de cada uno de los atributos, como la eventual facultad de
modificar dicho valor. Reiterando, si los atributos son privados, ninguna de stas dos funcionalidades est
disponible desde otras clases.
Una manera clsica en la programacin orientada a objeto de resolver esta visibilidad, an manteniendo
el control sobre lo que se puede ver o modificar de un atributo, se utilizan mtodos que definen una u otra
de estas funcionalidades.
Tal sera el caso en el siguiente ejemplo.
cl ass Per sona {
pr i vat e i nt edad;
publ i c i nt get Edad( ) { r et ur n( edad) ; }
publ i c voi d set Edad( i nt e) { i f ( e>0) edad = e; }
}
IIC 1102 Pgina: 5
Intro. Prog. Programacin OO en C# Rodrigo Sandoval U.
En esta clase Persona se distingue el nico atributo privado edad, que evidentemente no es visible
fuera de la clase. Por otro lado, dos mtodos ofrecen la visibilidad sobre dicho atributo, denominados
getEdad() y setEdad(). El primero de ellos es un ejemplo muy simple de un mtodo que al ser declarado
pblico es visible fuera de la clase, y como esencial funcionamiento, retorna el valor del atributo cuando
es invocado. A su vez, el segundo de ellos modifica el valor del atributo privado, siempre y cuando el
nuevo valor cumpla cierta condicin (en este caso sea nmero mayor que cero).
La combinacin de las tres declaraciones permite establecer un atributo privado, pero accesible bajo
control por medio de sus mtodos.
Esta problemtica fue enfrentada por los diseadores del lenguaje C#, lo que ofrecieron una solucin ms
eficiente, siempre manteniendo el objetivo presente: dar visibilidad controlada sobre atributos privados.
Esta solucin se basa en la denominadas Propiedades, que si bien no tienen la misma declaracin de un
mtodo, semnticamente ofrecen lo mismo que los mtodos: ejecucin de instrucciones relacionadas con
los atributos.
Su declaracin se basa en tres aspectos: su declaracin (identificador), que no lleva parntesis, su
declaracin de funcionalidad de visibilidad (get) y la de modificacin (set).
En este caso, el mismo ejemplo anterior quedara.
cl ass Per sona {
pr i vat e i nt edad;
public int Edad {
get { return(edad); }
set { if(value>0) edad = value; }
}
}
En esta segunda versin del mismo ejemplo, utilizando la sintaxis de propiedades de C#, se identifica la
declaracin de dos elementos solamente: el atributo privado, y la propiedad pblica. Esta declaracin
tiene las siguientes caractersticas:
- El identificador para la propiedad es distinto al del atributo, pero por convencin se utiliza uno
muy similar (por ejemplo diferenciando slo por la primera letra mayscula) y no lleva parntesis
como los mtodos.
- Se puede declarar el bloque get o el set, slo uno de ellos o ambos. Es decir, al declarar una
propiedad slo con bloque get, implcitamente se est indicando que la propiedad no acepta
modificacin de valor por asignacin.
- En el bloque set, la manera de identificar el valor que se quiere asignar al respectivo atributo es
por el uso de la palabra clave value, que en este contexto se toma como el valor (sea cual sea
su tipo de dato correspondiente) que se asigna a la propiedad y por ende, al atributo.


1.5 Clases abstractas
Al usar el modificador abstract al declarar una clase, se indica que sta est pensada exclusivamente
para servir como clase base de otras que heredarn su definicin bsica. Por definicin, estas clases
abstractas no pueden ser instanciadas (no se pueden declarar instancias de dichas clases, slo
heredarlas). An as, una clase abstracta puede contener mtodos abstractos (pensados en ser
implementados en versiones definitivas en las clases derivadas), o bien mtodos formalmente
implementados, pensados en ser utilizados como tales en las clase derivadas (tpicamente el caso de las
propiedades centrales de esta clase base).
IIC 1102 Pgina: 6
Intro. Prog. Programacin OO en C# Rodrigo Sandoval U.
abst r act cl ass Per sona {
pr ot ect ed st r i ng nombr e;
pr ot ect ed i nt edad;

. . .

public void MostrarDatos() { }
}

cl ass Al umno : Per sona {
i nt numer o;

public void MostrarDatos() {
Consol e. Wr i t eLi ne( {0}, {1}, {2}, nombr e, edad, numer o) ;
}
}

1.6 Sobrecarga de mtodos heredados
Aprovechando uno de los principales conceptos de la programacin orientada a objeto, llamado
Polimorfismo, en este caso representado por la sobrecarga de mtodos, mediante la redeclaracin de un
mtodo en una clase heredada, se deben considerar ciertos aspectos de diseo, que expliciten esta
situacin.
Por ejemplo, si se da un ejemplo de herencia como el siguiente, donde una clase base representa a una
persona en particular, mientras que la heredada representa un alumno de una universidad, se puede
hacer la siguiente definicin del mtodo MostrarDatos().
cl ass Per sona {
pr ot ect ed st r i ng nombr e;
pr ot ect ed i nt edad;

. . .

/ / En l a cl ase base, el mt odo Most r ar Dat os( ) no t i ene
/ / cdi go, ya que no i nt er esa i mpl ement ar su l gi ca.
/ / Si n embar go, se decl ar a vi r t ual , expl i ci t ando que
/ / l a l gi ca de est e mt odo deber ser i mpl ement ada
/ / por l as cl ases der i vadas.
publ i c vi r t ual voi d Most r ar Dat os( ) { }
}

cl ass Al umno : Per sona {
. . .

/ / En l a cl ase der i vada, el mt odo Most r ar Dat os( ) debe
/ / ser expl ci t ament e una sobr ecar ga del mi smo de l a
/ / cl ase base. Par a el l o, se decl ar a over r i de.
publ i c over r i de voi d Most r ar Dat os( ) {
Consol e. Wr i t eLi ne( Nombr e: , t hi s. nombr e) ;
Consol e. Wr i t eLi ne( Edad: , t hi s. edad) ;
}
}

IIC 1102 Pgina: 7
Intro. Prog. Programacin OO en C# Rodrigo Sandoval U.
1.7 Sobrecarga de operadores (+, -, ...)
Conociendo la posibilidad de definir mtodos con sobrecarga, existe en C#la particularidad de poder re-
definir el funcionamiento de algunos operadores estndar, como son los operadores matemticos (+, -, * ,
/), sobre objetos de tipo ms complejo que los numricos bsicos. En el siguiente ejemplo se define un
nuevo tipo de dato, en la forma de una clase, que representa los nmeros complejos, compuestos por
una parte real y otra imaginaria. En este caso se re-define la operacin suma, identificada por el smbolo
+.
cl ass Compl ej o {
pr i vat e i nt r eal , i mag;
publ i c Compl ej o( i nt r , i nt i ) { r eal = r ; i mag = i ; }

public static Complejo operator+(Complejo c1, Complejo c2) {
Complejo c = new Complejo(c1.real+c2.real, c1.imag+c2.imag);
return c;
}
}
Con esta declaracin ya es factible armar una expresin con el operador de suma (+) entre dos instancias
de la clase Complejo. Un ejemplo ms completo de este concepto se ve ms adelante, en la implantacin
de la clase Racional, como representante de los nmeros racionales.
IIC 1102 Pgina: 8
Intro. Prog. Programacin OO en C# Rodrigo Sandoval U.
2 Soluciones Orientadas a Objeto
2.1 Ejemplo: Nmeros Racionales Clases Abstractas, Herencia, Operadores,
Propiedades.
Para este ejemplo, se toma como referencia todos aquellos tipos de nmeros que estn compuestos por
diferentes partes. Tal es el caso de los nmeros complejos, compuestos de una parte real y otra
imaginaria, o de los puntos en el espacio bidimensional, compuestos de dos coordenadas en la forma
(x,y), y tambin los nmeros racionales, compuestos por un numerador y un denominador.
En este caso, es precisamente el caso de los nmeros racionales el que se quiere revisar. Como
propsito final se pretende contar con una implementacin del nmero racional lo suficientemente
completa como para trabajar en forma transparente con ellos en un programa principal.
Como ejemplo se muestra a continuacin un ejemplo de cmo podra utilizarse esta definicin de
Racional, conociendo slo los mtodos y caractersticas pblicas. Conociendo esta interfaz es posible
emplear este tipo de objetos para resolver problemas en los que es necesario manipular nmeros
racionales. Como puede verse, no es necesario conocer la implementacin, de hecho, hasta el
momento no sabemos cmo se representan los datos ni cmo estn escritas las funciones que
componen la interfaz.
Tipo de Dato (clase) Racional. Cada Racional est compuesto por un numerador y un denominador
Declaracin Racional r =new Racional(n1, n2);
Mtodos Bsicos Numerador(): entrega el valor entero del numerador del racional
Denominador(): entrega el valor entero del denominador del racional
Imprimir(): muestra en pantalla el racional en la forma (n/d)
Operadores Suma (+), resta (-), multiplicacin (*), divisin (/)
Teniendo clara esta informacin, se puede proceder a declarar un algoritmo principal en un programa,
utilizando extensivamente los Racionales, sin necesariamente conocer su definicin real ni su
composicin.
usi ng Syst em;

cl ass Raci onal { . . . . }

cl ass Mai nApp {

st at i c voi d Mai n( ) {
Raci onal r 1 = new Raci onal ( 2, 3) ;
Raci onal r 2 = new Raci onal ( 4, 5) ;

Consol e. Wr i t e( " r 1 es " ) ; r 1. I mpr i mi r ( ) ; Consol e. Wr i t eLi ne( ) ;
Consol e. Wr i t e( " r 2 es " ) ; r 2. I mpr i mi r ( ) ; Consol e. Wr i t eLi ne( ) ;

Raci onal r 3 = r 1 + r 2;
Consol e. Wr i t e( " r 1 + r 2 es " ) ; r 3. I mpr i mi r ( ) ; Consol e. Wr i t eLi ne( ) ;
r 3 = r 2 - r 1;
Consol e. Wr i t e( " r 1 - r 2 es " ) ; r 3. I mpr i mi r ( ) ; Consol e. Wr i t eLi ne( ) ;
r 3 = r 2 * r 1;
Consol e. Wr i t e( " r 1 * r 2 es " ) ; r 3. I mpr i mi r ( ) ; Consol e. Wr i t eLi ne( ) ;
r 3 = r 2 / r 1;
Consol e. Wr i t e( " r 1 / r 2 es " ) ; r 3. I mpr i mi r ( ) ; Consol e. Wr i t eLi ne( ) ;

Consol e. Wr i t e( " Pr esi one ENTER. " ) ; Consol e. ReadLi ne( ) ;
}
}
IIC 1102 Pgina: 9
Intro. Prog. Programacin OO en C# Rodrigo Sandoval U.
La verdadera implementacin de la clase Racional, evidentemente define una serie de elementos
internos, que resuelven la problemtica, pero la idea siempre es no requerir conocerla con detalle, sino
que slo saber usarla en un programa como el anterior.
Para este ejemplo, la implementacin pasa por la definicin de una clase abstracta base, que
precisamente representa todos aquellos tipos de nmeros compuestos de dos partes. La clase
NumeroCompuesto define dos partes que lo componen. J unto con ello, se definen propiedades de
acceso controlado a estas dos partes y el correspondiente constructor, que las inicializa con dos valores
pasados como parmetros.
Teniendo esa clase base, se define la clase derivada: Racional, que hace la relacin entre las dos partes
de NumeroCompuesto, con el numerador y denominador. Es importante destacar en este ejemplo, que
los componentes internos de la clase base, NumeroCompuesto, no son visibles en la clase derivada,
aunque si lo son las propiedades que controlan el acceso. Haciendo buen uso de stas, se logra definir la
lgica de la implementacin de esta clase derivada.
Adicionalmente, la clase Racional re-define los operadores bsicos de nmeros: suma, resta,
multiplicacin y divisin, de modo que sea an ms natural utilizar en un programa externo este tipo de
dato definido.
El siguiente Diagrama de Clases en UML refleja esta relacin entre Racional y NumeroCompuesto.


En este diagrama, los elementos que se enumeran con un smbolo -, son privados, los que tienen + son
pblicos, y los que anteponen un # son protegidos.
El cdigo completo de estas dos clases se encuentra a continuacin, que es totalmente consecuente con
el algoritmo principal anteriormente indicado:
usi ng Syst em;

/ / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
/ / Numer oCompuest o: un t i po de nmer o genr i co compuest o por dos par t es ( en est e cont ext o)
/ / En est e caso se t r at a de una cl ase abst r act a: def i ni da excl usi vament e par a ser her edada
/ / y no par a ser i nst anci ada.
/ / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
abst r act cl ass Numer oCompuest o {

pr i vat e i nt par t e1; / / par t e1 y par t e2 son i nvi si bl es al ext er i or de l a cl ase
pr i vat e i nt par t e2; / / i ncl uso en l as cl ases der i vadas que l a her edan.

pr ot ect ed Numer oCompuest o( i nt p1, i nt p2) { / / Const r uct or
par t e1 = p1; par t e2 = p2;
}

// Definicin de las propiedades de la clase NumeroCompuesto
pr ot ect ed i nt Par t e1 {
get { r et ur n ( par t e1) ; }
set { par t e1 = val ue; }
}
pr ot ect ed i nt Par t e2 {
get { r et ur n ( par t e2) ; }
set { par t e2 = val ue; }
}
}

IIC 1102 Pgina: 10
Intro. Prog. Programacin OO en C# Rodrigo Sandoval U.
/ / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
/ / Raci onal : her edando l as car act er st i cas de Numer oCompuest o ( dos par t es)
/ / : en est e caso r el aci onando par t e1- >numer ador . . . par t e2- >denomi nador
/ / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /

cl ass Raci onal : NumeroCompuesto {

publ i c Raci onal ( i nt n, i nt // Constructor de la clase: inicializacin d)
: base( n, d) // se llama al constructor de la clase base.
{
}

/ / Mt odos bsi cos: acceso a l as par t es del nmer o Raci onal .
/ / Est o t ambi n se puede hacer con el f or mat o de Pr opi edades
publ i c i nt Numer ador ( ) { r et ur n( t hi s. Par t e1) ; }
publ i c i nt Denomi nador ( ) { r et ur n( t hi s. Par t e2) ; }

/ / Mt odo si mpl e: i mpr i me en pant al l a el nmer o con sus par t es.
publ i c voi d I mpr i mi r ( ) { Consol e. Wr i t e( " {0}/ {1}" , t hi s. Par t e1, t hi s. Par t e2) ; }



// Sobrecarga de operadores: +, -, *, /

/ / Suma de Raci onal es: l a suma de l as mul t i p. cr uzadas / mul t i pl i caci n denom.
publ i c st at i c Raci onal oper at or +( Raci onal r 1, Raci onal r 2)
{
Raci onal r = new Raci onal (
r 1. Numer ador ( ) *r 2. Denomi nador ( ) + r 1. Denomi nador ( ) *r 2. Numer ador ( ) ,
r 1. Denomi nador ( ) *r 2. Denomi nador ( ) ) ;
r et ur n r ;
}

/ / Rest a de Raci onal es: l a r est a de l as mul t i p. cr uzadas / mul t i pl i caci n denom.
publ i c st at i c Raci onal oper at or - ( Raci onal r 1, Raci onal r 2)
{
Raci onal r = new Raci onal (
r 1. Numer ador ( ) *r 2. Denomi nador ( ) - r 1. Denomi nador ( ) *r 2. Numer ador ( ) ,
r 1. Denomi nador ( ) *r 2. Denomi nador ( ) ) ;
r et ur n r ;
}

/ / Mul t i pl i caci n de Raci onal es: mul t i pl i caci n numer ador es / mul t i pl i caci n denom.
publ i c st at i c Raci onal oper at or *( Raci onal r 1, Raci onal r 2)
{
Raci onal r = new Raci onal (
r 1. Numer ador ( ) *r 2. Numer ador ( ) ,
r 1. Denomi nador ( ) *r 2. Denomi nador ( ) ) ;
r et ur n r ;
}

/ / Di vi si n de Raci onal es: mul t i pl i caci ones cr uzadas.
publ i c st at i c Raci onal oper at or / ( Raci onal r 1, Raci onal r 2)
{
Raci onal r = new Raci onal (
r 1. Numer ador ( ) *r 2. Denomi nador ( ) ,
r 1. Denomi nador ( ) *r 2. Numer ador ( ) ) ;
r et ur n r ;
}
}

IIC 1102 Pgina: 11
Intro. Prog. Programacin OO en C# Rodrigo Sandoval U.
2.2 Ejemplo: Ejecucin de un Penal Herencia, Propiedades, Sobrecarga
Mtodos Heredados.
Profundizando un ejemplo del captulo 1, la ejecucin del lanzamiento penal en ftbol se puede modelar
desde un enfoque totalmente orientado a objeto, una vez que se han entendido los elementos
involucrados. Simplificando en este caso, se requiere de dos jugadores, los cuales si bien comparten
parte de los elementos que los definen, tienen ciertos comportamientos y elementos que los diferencian.
De tal manera, se hace una definicin de la clase J ugador genrico, que representa lgicamente a
cualquier jugador. J unto a esta definicin, se declara el rbitro. Y como derivado del J ugador genrico
aparecen el Pateador y el Arquero.
Esta estructura de objetos se refleja en el siguiente Diagrama de Clases en UML. Todas estas clases
estn contenidas dentro del Namespace Deportes.Futbol.



El cdigo que representa esta definicin, contenido en el namespace Deportes.Futbol, se encuentra a
continuacin. Cabe destacar que ninguna de las clases es abstracta, por lo que cualquiera de ellas podra
ser instanciada, y por ende, conformar un equipo completo, o dos para un partido oficial.
namespace Depor t es. Fut bol {

/ / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/ / cl ase Ar bi t r o
/ / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
publ i c cl ass Ar bi t r o {
publ i c st r i ng Pi t ar ( ) {
r et ur n ( " PRI I I P! " ) ;
}
}


/ / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/ / cl ase J ugador : r epr esent a a cual qui er j ugador de l a cancha
/ / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
publ i c cl ass J ugador {
pr i vat e i nt di r ecci on; / / 1: i zqui er da; 2: der echa
pr i vat e i nt numer o;

publ i c J ugador ( i nt di r ) {
i f ( di r <1 | | di r >2 ) di r = 1;
di r ecci on = di r ;
numer o = 2;
}
publ i c J ugador ( i nt di r , i nt num) {
i f ( di r <1 | | di r >2 ) di r = 1;
di r ecci on = di r ;
IIC 1102 Pgina: 12
Intro. Prog. Programacin OO en C# Rodrigo Sandoval U.
numer o = num;
}

publ i c i nt Di r {
get { r et ur n( di r ecci on) ; }
set { i f ( val ue<1 | | val ue>2 ) di r ecci on = 1;
el se di r ecci on = val ue; }
}
publ i c i nt Numer o { get { r et ur n( numer o) ; } }

publ i c st r i ng Di r ecci on {
get {
i f ( di r ecci on == 1) r et ur n( " i zqui er da" ) ;
i f ( di r ecci on == 2) r et ur n( " der echa" ) ;
r et ur n( " - " ) ;
}
}

publ i c vi r t ual st r i ng J ugada( ) { r et ur n( " " ) ; }
}


/ / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/ / cl ase Pat eador , der i vada de J ugador :
/ / Repr esent a a un j ugador que pat ear un t i r o l i br e o penal
/ / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
publ i c cl ass Pat eador : J ugador {

publ i c Pat eador ( i nt di r ) : base( di r , 9) {}

publ i c st r i ng Pat ear ( ) {
r et ur n( " J ugador " + Numer o. ToSt r i ng( ) +
" pat ea haci a l a " + Di r ecci on) ;
}
publ i c over r i de st r i ng J ugada( ) { r et ur n( Pat ear ( ) ) ; }
}


/ / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/ / cl ase Ar quer o, der i vada de J ugador :
/ / Repr esent a a un ar quer o que se l anzar par a at aj ar un t i r o
/ / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
publ i c cl ass Ar quer o : J ugador {

publ i c Ar quer o( i nt di r ) : base( di r , 1) {}

publ i c st r i ng Lanzar se( ) {
r et ur n( " Ar quer o se l anza haci a l a " + Di r ecci on) ;
}

publ i c over r i de st r i ng J ugada( ) { r et ur n( Lanzar se( ) ) ; }
}
}

IIC 1102 Pgina: 13
Intro. Prog. Programacin OO en C# Rodrigo Sandoval U.
Teniendo implementada la lgica de los participantes de esta ejecucin de penales, en este namespace
Deportes.Futbol, se puede aprovechar e incluir en cualquier programa que implemente un algoritmo
principal, que haga referencia y uso de estas clases.
De tal manera, a continuacin se entregan dos posibles implementaciones de la ejecucin del penal, una
versin simple de Consola, donde se le preguntan las opciones al usuario, y una segunda donde la lgica
de operacin es exactamente la misma, pero se interacta con el usuario por medio de una ventana de
Windows.
2.2.1 Ejecucin de un penal Versin Consola
El siguiente cdigo corresponde a la clase principal del programa, donde se hace referencia al
namespace que define los jugadores que participan. Aqu se reconoce un Main() que tiene el algoritmo
principal, interactuando con el usuario por medio de la consola.

usi ng Syst em;
usi ng Depor t es. Fut bol ;


cl ass CMai n {
publ i c st at i c voi d Mai n( ) {
i nt di r 1, di r 2;
Consol e. Wr i t eLi ne( " LANZAMI ENTO DE UN PENAL" ) ;
Consol e. Wr i t e( " I ndi que di r ecci n en que l anza el j ugador ( 1: i zq; 2: der ) : " ) ;
di r 1 = i nt . Par se( Consol e. ReadLi ne( ) ) ;
Consol e. Wr i t e( " I ndi que di r ecci n a l a que se l anza el ar quer o ( 1: i zq; 2: der ) : " ) ;
di r 2 = i nt . Par se( Consol e. ReadLi ne( ) ) ;

Ar bi t r o b = new Ar bi t r o( ) ;
Pat eador p = new Pat eador ( di r 1) ;
Ar quer o a = new Ar quer o( di r 2) ;

Consol e. Wr i t eLi ne( b. Pi t ar ( ) ) ;
Consol e. Wr i t eLi ne( p. J ugada( ) ) ;
Consol e. Wr i t eLi ne( a. J ugada( ) ) ;

i f ( p. Di r ecci on == a. Di r ecci on) Consol e. Wr i t eLi ne( " El penal f ue at aj ado! " ) ;
el se Consol e. Wr i t eLi ne( " El gol f ue conver t i do! " ) ;

Consol e. ReadLi ne( ) ;
}
}
Para poder generar un archivo penales.exe que contenga la lgica de ambos archivos separados (el
namespace Deportes.Futbol en el archivo futbol.cs y el algoritmo principal en penales.cs), se debe
ejecutar una compilacin de dos entradas de la siguiente forma (archivo build.bat). Los tres archivos
deben estar en el mismo directorio.
@%WI NDI R%\ Mi cr osof t . NET\ Fr amewor k\ v1. 1. 4322\ csc. exe / out : . \ penal es. exe f ut bol . cs penal es. cs
@pause
Compilando, aparece el archivo penales.exe, y al ejecutarlo se ve la siguiente consola:

IIC 1102 Pgina: 14
Intro. Prog. Programacin OO en C# Rodrigo Sandoval U.
2.2.2 Ejecucin de un penal Versin Windows
Utilizando como base el mismo namespace Deportes.Futbol, sin hacer ni una sola modificacin, se
reaprovecha su lgica en la implementacin de una versin equivalente a la de consola, esta vez
logrando que la interaccin con el usuario se realice por medio de controles Windows, es decir,
elementos grficos con los que el usuario manifiesta sus preferencias.
La ventaja de la arquitectura en base a componentes en la Programacin Orientada a Objeto, es
precisamente la capacidad de reutilizacin de elementos (lgica de funcionamiento), ya implementada, en
otras soluciones.
A continuacin se incluye el cdigo fuente de la clase principal de este programa en versin Windows, la
cual mantiene la misma lgica operativa de la versin de consola. Este ejemplo en particular, a diferencia
del anterior, presenta muchas ms lneas de cdigo y mtodos adicionales, cuyo propsito es
especficamente trabajar con los objetos grficos de la ventana de Windows con la que interacta el
usuario, dejando la lgica de decisin sobre el problema de ejecucin del penal, en un mtodo final,
invocado al activar el botn del usuario.

usi ng Syst em;
usi ng Syst em. Dr awi ng;
usi ng Syst em. I O;
usi ng Syst em. Wi ndows. For ms;
usi ng Syst em. Di agnost i cs;


usi ng Depor t es. Fut bol ;


namespace Depor t es. Fut bol . Penal {

/ / / <summar y>
/ / / Vent ana de si mul aci n de l a ej ecuci n de un penal ,
/ / / donde se el i ge l a di r ecci n en que l anza el pat eador
/ / / y l a que se l anza el ar quer o.
/ / / Segn eso, cal cul a si el penal f ue conver t i do o at aj ado.
/ / / </ summar y>
publ i c cl ass Vent anaPenal es : For m{

Pat eador p;
Ar quer o a;

pr i vat e Label l bTi t ul o;
pr i vat e Label l bPat eador ;
pr i vat e Label l bAr quer o;
pr i vat e Label l bResul t ado;
pr i vat e ComboBox cbPat eador ;
pr i vat e ComboBox cbAr quer o;
pr i vat e But t on bt Ej ecut ar ;

publ i c Vent anaPenal es( ) {
p = new Pat eador ( 1) ;
a = new Ar quer o( 1) ;

cbPat eador = new ComboBox( ) ;
cbAr quer o = new ComboBox( ) ;
bt Ej ecut ar = new But t on( ) ;
l bResul t ado = new Label ( ) ;
l bPat eador = new Label ( ) ;
l bAr quer o = new Label ( ) ;
l bTi t ul o = new Label ( ) ;
t hi s. SuspendLayout ( ) ;

l bTi t ul o. Fl at St yl e = Syst em. Wi ndows. For ms. Fl at St yl e. Popup;
l bTi t ul o. Font = new Syst em. Dr awi ng. Font ( " Mi cr osof t Sans Ser i f " , 12F,
Syst em. Dr awi ng. Font St yl e. Bol d, Syst em. Dr awi ng. Gr aphi csUni t . Poi nt , ( ( Syst em. Byt e) ( 0) ) ) ;
l bTi t ul o. Locat i on = new Syst em. Dr awi ng. Poi nt ( 16, 16) ;
IIC 1102 Pgina: 15
Intro. Prog. Programacin OO en C# Rodrigo Sandoval U.
l bTi t ul o. Name = " l bTi t ul o" ;
l bTi t ul o. Si ze = new Syst em. Dr awi ng. Si ze( 250, 32) ;
l bTi t ul o. TabI ndex = 5;

l bPat eador . Fl at St yl e = Syst em. Wi ndows. For ms. Fl at St yl e. Popup;
l bPat eador . Font = new Syst em. Dr awi ng. Font ( " Mi cr osof t Sans Ser i f " , 8F,
Syst em. Dr awi ng. Font St yl e. Regul ar , Syst em. Dr awi ng. Gr aphi csUni t . Poi nt , ( ( Syst em. Byt e) ( 0) ) ) ;
l bPat eador . Locat i on = new Syst em. Dr awi ng. Poi nt ( 16, 55) ;
l bPat eador . Name = " l bPat eador " ;
l bPat eador . Si ze = new Syst em. Dr awi ng. Si ze( 120, 20) ;
l bPat eador . TabI ndex = 6;
l bAr quer o. Fl at St yl e = Syst em. Wi ndows. For ms. Fl at St yl e. Popup;
l bAr quer o. Font = new Syst em. Dr awi ng. Font ( " Mi cr osof t Sans Ser i f " , 8F,
Syst em. Dr awi ng. Font St yl e. Regul ar , Syst em. Dr awi ng. Gr aphi csUni t . Poi nt , ( ( Syst em. Byt e) ( 0) ) ) ;
l bAr quer o. Locat i on = new Syst em. Dr awi ng. Poi nt ( 16, 80) ;
l bAr quer o. Name = " l bPat eador " ;
l bAr quer o. Si ze = new Syst em. Dr awi ng. Si ze( 120, 20) ;
l bAr quer o. TabI ndex = 7;

cbPat eador . Dr opDownWi dt h = 112;
cbPat eador . Locat i on = new Syst em. Dr awi ng. Poi nt ( 140, 53) ;
cbPat eador . Name = " cbPat eador " ;
cbPat eador . Si ze = new Syst em. Dr awi ng. Si ze( 112, 21) ;
cbPat eador . TabI ndex = 1;
cbPat eador . Sel ect edI ndexChanged += new
Syst em. Event Handl er ( t hi s. cbPat eador _Sel ect edI ndexChanged) ;

cbAr quer o. Dr opDownWi dt h = 112;
cbAr quer o. Locat i on = new Syst em. Dr awi ng. Poi nt ( 140, 78) ;
cbAr quer o. Name = " cbAr quer o" ;
cbAr quer o. Si ze = new Syst em. Dr awi ng. Si ze( 112, 21) ;
cbAr quer o. TabI ndex = 2;
cbAr quer o. Sel ect edI ndexChanged += new
Syst em. Event Handl er ( t hi s. cbAr quer o_Sel ect edI ndexChanged) ;

bt Ej ecut ar . Locat i on = new Syst em. Dr awi ng. Poi nt ( 160, 110) ;
bt Ej ecut ar . Name = " bt Ej ecut ar " ;
bt Ej ecut ar . Si ze = new Syst em. Dr awi ng. Si ze( 90, 24) ;
bt Ej ecut ar . TabI ndex = 3;
bt Ej ecut ar . Text = " Ej ecut ar " ;
bt Ej ecut ar . Cl i ck += new Syst em. Event Handl er ( t hi s. bt Ej ecut ar _Cl i ck) ;

l bResul t ado. Fl at St yl e = Syst em. Wi ndows. For ms. Fl at St yl e. Popup;
l bResul t ado. Font = new Syst em. Dr awi ng. Font ( " Mi cr osof t Sans Ser i f " , 12F,
Syst em. Dr awi ng. Font St yl e. Regul ar , Syst em. Dr awi ng. Gr aphi csUni t . Poi nt , ( ( Syst em. Byt e) ( 0) ) ) ;
l bResul t ado. Locat i on = new Syst em. Dr awi ng. Poi nt ( 8, 140) ;
l bResul t ado. Name = " l bResul t ado" ;
l bResul t ado. Si ze = new Syst em. Dr awi ng. Si ze( 264, 64) ;
l bResul t ado. TabI ndex = 4;

/ / Di mensi onami ent o y est i l o de l a vent ana.
t hi s. Aut oScal eBaseSi ze = new Syst em. Dr awi ng. Si ze( 5, 13) ;
t hi s. Cl i ent Si ze = new Syst em. Dr awi ng. Si ze( 280, 215) ;
t hi s. Cont r ol s. AddRange( new Syst em. Wi ndows. For ms. Cont r ol [ ] {
l bTi t ul o, l bPat eador , l bAr quer o, bt Ej ecut ar , cbPat eador ,
cbAr quer o, l bResul t ado }) ;
t hi s. Name = " Vent anaPenal es" ;
t hi s. Text = " Ej ecuci n de Penal " ;
t hi s. ResumeLayout ( f al se) ;


cbPat eador . I t ems. Add ( " I zqui er da" ) ;
cbPat eador . I t ems. Add ( " Der echa" ) ;
cbPat eador . Sel ect edI ndex = 0;
cbAr quer o. I t ems. Add ( " I zqui er da" ) ;
cbAr quer o. I t ems. Add ( " Der echa" ) ;
cbAr quer o. Sel ect edI ndex = 0;
l bTi t ul o. Text =" Ej ecuci n de Penal " ;
l bPat eador . Text =" Pat eador pat ea haci a l a" ;
l bAr quer o. Text =" Ar quer o se l anza a l a" ;
l bResul t ado. Text =" ( Penal an no ej ecut ado) " ;
IIC 1102 Pgina: 16
Intro. Prog. Programacin OO en C# Rodrigo Sandoval U.
}


/ / / <summar y>
/ / / Al gor i t mo pr i nci pal de l a apl i caci n.
/ / / Se abr e una vent ana par a pedi r l os dat os al usuar i o y ej ecut ar .
/ / / </ summar y>
[ STAThr ead]
st at i c voi d Mai n( )
{
Appl i cat i on. Run( new Vent anaPenal es( ) ) ;
}

pr i vat e voi d bt Ej ecut ar _Cl i ck( obj ect sender , Syst em. Event Ar gs e) {
lbResultado.Text = p.Patear() + "\n" + a.Lanzarse();
if(p.Direccion == a.Direccion)
lbResultado.Text += "\nEl penal fue atajado ";
else
lbResultado.Text += "\nEl penal fue convertido!";
}



p voi d cbPat eador _Sel ect edI ndexChanged( o r i vat e bj ect sender , Syst em. Event Ar gs e) {
p.Dir = cbPateador.SelectedIndex + 1;
}
pr i vat e voi d cbAr quer o_Sel ect edI ndexChanged( obj ect sender , Syst em. Event Ar gs e) {
a.Dir = cbArquero.SelectedIndex + 1;
}
}
}
Para poder crear el ejecutable de este programa, es necesario realizar una compilacin que incluya
ambos cdigos fuentes: el namespace Deportes.Futbol (futbol.cs), y el Main() para la ventana Windows
(penales.cs). En este caso particular se definin una arquitectura de compilacin diferentes: primero se
compila futbol.cs, produciendo como resultado un archivo independiente de tipo .NET Module. Luego se
compila el archivo principal, tomando en la compilacin el mdulo compilado anterior, produciendo en la
suma el ejecutable final. Esta idea se refleja en el siguiente archivo build.bat, en este caso de tres lneas:
una para cada compilacin y un pause final.
@%WINDIR%\Microsoft.NET\Framework\v1.1.4322\csc.exe /target:module /debug+/d:TRACE futbol.cs
@%WINDIR%\Microsoft.NET\Framework\v1.1.4322\csc.exe /target:winexe /debug+ /d:TRACE /addmodule:futbol.netmodule
/r:System.Windows.Forms.dll /r:System.Drawing.dll /r:System.dll penales.cs
@pause
Finalmente, al producirse el archivo penales.exe como resultado de esta compilacin en etapas, al
ejecutarlo aparece la ventana de interaccin con el usuario que finalmente podra usarse para simular la
ejecucin del penal segn las opciones seleccionadas por el usuario.

IIC 1102 Pgina: 17
Material preparado por Rodrigo Sandoval U en Marzo 2004,
basado en los apuntes de clase del curso IIC1102, ao 2003, de M. Nussbaum, Marcos Seplveda, et.al

PONTIFICIA UNIVERSIDAD CATLICA DE CHILE
ESCUELA DE INGENIERA
DEPARTAMENTO DE CIENCIA DE LA COMPUTACIN
IIC 1102 INTRODUCCIN A LA PROGRAMACIN
Profesor: Rodrigo Sandoval U.

Captulo V Control de Flujo


1 CONTROL DE FLUJO....................................................................................................................................... 1
2 DECISIN O SELECCIN............................................................................................................................... 2
2.1 INSTRUCCIN IF ..............................................................................................................................................2
2.1.1 Ejemplo: Qu hago el sbado por la noche? (Implementacin) .......................................................... 3
2.2 INSTRUCCIN SWITCH.....................................................................................................................................6
2.2.1 Ejemplo: Conversin a letras de una cantidad de dos dgitos ............................................................... 7
3 ITERACIN......................................................................................................................................................... 9
3.1 INSTRUCCIN WHILE.......................................................................................................................................9
3.1.1 Ejemplo: Tabla de conversin de temperaturas (Fahrenheit-Celsius) .................................................. 9
3.1.2 Ejemplo: Esperando el Ao Nuevo ...................................................................................................... 10
3.2 INSTRUCCIN DO-WHILE...............................................................................................................................12
3.3 INSTRUCCIN FOR.........................................................................................................................................13
3.3.1 Ejemplo: Clculo de x a la n (uso restringido del for)......................................................................... 15
3.3.2 Ejemplo: Conversin a letras de cantidades numricas (uso general del for)..................................... 16
3.4 INSTRUCCIN FOREACH................................................................................................................................19
3.5 EQUIVALENCIA LGICA ENTRE INSTRUCCIONES DE ITERACIN....................................................................19
3.5.1 Ejemplos: Programa con funciones equivalentes y Ciclos anidados ................................................... 21
3.6 ITERACIONES CON ANIDAMIENTO.................................................................................................................24


Intro Prog. Orientada a Objeto Control de Flujo Rodrigo Sandoval U.
IIC 1102 Pgina: 1
1 Control de Flujo
Los algoritmos normalmente requieren modificar el flujo de ejecucin de las instrucciones que lo
componen. Esto se lleva a cabo mediante decisin e iteracin.
La decisin permite especificar la ejecucin condicional de ciertas instrucciones. La condicin que se
considera para tomar la decisin est basada en el estado actual de la ejecucin, es decir, en las
entradas del programa, las instrucciones ejecutadas hasta ahora y, en general, en el contenido de las
variables.
Los lugares dentro del programa en que se toman las decisiones se conocen como puntos de control de
flujo, o simplemente, puntos de decisin.
Como referencia puede consultarse la seccin que trata los rboles de decisin y, en particular, el
ejemplo Qu hago el sbado por la noche?, donde se ilustra una situacin en la que es necesario tomar
decisiones durante la ejecucin de un algoritmo.
El lenguaje de programacin C#cuenta con dos instrucciones que permiten especificar decisin dentro
de un programa:
if-else
switch
Por otra parte, la iteracin permite controlar mediante expresiones lgicas la repeticin de una o varias
instrucciones dentro del programa. Los bloques con las instrucciones que se repiten se conocen como
ciclos o loops. La expresin que controla la ejecucin del ciclo se conoce como condicin de control.
El lenguaje de programacin C#cuenta con cuatro instrucciones para especificar iteraciones, y aunque
stas son lgicamente equivalentes (ver ejemplos ms adelante), sus diferencias radican principalmente
en la forma en que se controla la continuacin o terminacin del ciclo (especificacin y verificacin). Las
instrucciones son:
while
do-while
for
foreach


Intro Prog. Orientada a Objeto Control de Flujo Rodrigo Sandoval U.
IIC 1102 Pgina: 2
2 Decisin o Seleccin
2.1 Instruccin if
La instruccin if permite decidir si una porcin de cdigo (una o ms instrucciones) se debe ejecutar,
tomando como criterio para la decisin el valor de una expresin lgica. Alternativamente, permite elegir
entre dos porciones de cdigo, de acuerdo a la evaluacin de la expresin de control.
Sintaxis:
if ( expresion-evaluacin )
instruccin ;


if ( expresion-evaluacin ) {
...
Bloque de instrucciones
...
}


if ( expresion-evaluacin )
instruccin1 ;
else
instruccin2 ;


if ( expresion-evaluacin ) {
...
Bloque de instrucciones 1
...
}
else {
...
Bloque de instrucciones 2
...
}
Los bloques de instrucciones consisten en una secuencia de instrucciones terminadas en punto y coma.
Al ejecutarse una instruccin if, se evaluar la expresin de evaluacin o expresin booleana (que
resulta en Verdadero o Falso) suministrada en los parntesis, y dependiendo de su valor (verdadero o
falso, es decir, true o false), se tomar una de las siguientes acciones:
Si la expresin es verdadera, se ejecutar la instruccin o bloque de instrucciones que viene
despus de la condicin, pero antes de la seccin else (si es que existe). Una vez hecho esto,
se continuar la ejecucin en la siguiente instruccin despus del if.
Si la expresin es falsa, y no se incluy la partcula else dentro de la instruccin, el if pasar
desapercibido, es decir, no se ejecutar las instrucciones contenidas en l, sino que la ejecucin
continuar en la siguiente instruccin despus del if.
Intro Prog. Orientada a Objeto Control de Flujo Rodrigo Sandoval U.
IIC 1102 Pgina: 3
Si la expresin es falsa, y existe una partcula else dentro del if, se ejecutar la instruccin o
bloque de instrucciones que viene despus del else. Una vez hecho esto, se continuar la
ejecucin en la siguiente instruccin despus del if.
Es posible escribir if anidados, es decir, incluir otras instrucciones if dentro de las instrucciones a
ejecutar al evaluar una primera instruccin if.

Ejemplos:
1. int edad;
int viejitos = 0;

if (edad > 80) {
// Esto se ejecuta si la variable edad tiene un valor mayor a 80
viejitos++;
Console.WriteLine("Ud. no califica para descuento de adolescente);
}
else {
// Esto se ejecuta si la variable edad tiene un valor <= 80
Console.WriteLine("Bienvenido, Ud. cuenta con un descuento de $15);
}


2. int salario, credito;

if (salario > 1000000)
credito = 5000000;
else if (salario > 500000)
credito = 2000000;
else if (salario > 100000)
credito = 1000000;
else
credito = 0;


2.1.1 Ejemplo: Qu hago el sbado por la noche? (Implementacin)
Se presenta una implementacin (empleando la instruccin if) del rbol de decisin para saber qu
hacer el sbado por la noche.
Para ilustrar el uso de los rboles de decisin, se presenta un rbol que gua a un usuario a tomar una
decisin sobre qu hacer el sbado por la noche. La profundizacin en el rbol se lleva a cabo de
acuerdo a las respuestas que va dando el usuario a las interrogantes que se le plantean. Cuando se llega
a un nodo terminal en el rbol (hoja), el usuario recibe una recomendacin sustentada en el desarrollo de
la interaccin.
Intro Prog. Orientada a Objeto Control de Flujo Rodrigo Sandoval U.
IIC 1102 Pgina: 4



using System;

class MainApp {

public static void Main() {
string respuesta;

Console.WriteLine("Veamos qu hacer el sbado por la noche... ");

Console.Write("Desea quedarse en casa? (s/n): ");
respuesta = Console.ReadLine();

if (respuesta=="s") {
Console.Write ("Le gusta ver TV? (s/n): ");
respuesta = Console.ReadLine();

if (respuesta=="s") {
Console.Write("Hay algn programa bueno esta noche? (s/n): ");
respuesta = Console.ReadLine();
if (respuesta=="s")
Console.WriteLine("Sugerencia: Coma cabritas y vea el programa de hoy");
else
Console.WriteLine("Sugerencia: Arriende una pelicula");
}
Intro Prog. Orientada a Objeto Control de Flujo Rodrigo Sandoval U.
IIC 1102 Pgina: 5
else {
Console.Write("Le gusta leer? (s/n): ");
respuesta = Console.ReadLine();

if (respuesta=="s")
Console.WriteLine("Sugerencia: Tmese un vinito y lea un buen libro");
else
Console.WriteLine("Sugerencia: Vaya a dormir! ...Buenas noches");

}
}

else {
Console.Write ("Le gusta bailar? (s/n): ");
respuesta = Console.ReadLine();
if (respuesta=="s") {
Console.Write("Le gusta la msica tropical? (s/n): ");
respuesta = Console.ReadLine();

if (respuesta=="s")
Console.WriteLine("Sugerencia: Vaya a la discotheque El Merengazo");
else
Console.WriteLine("Sugerencia: Vaya a la discotheque Los Tarros");
}

else {
Console.Write("Le gusta ir al cine? (s/n): ");
respuesta = Console.ReadLine();

if (respuesta=="s")
Console.WriteLine("Sugerencia: Vaya a ver una pelcula");
else
Console.WriteLine("Sugerencia: Vaya a un pub y tmese un Pisco Sour");
}
}
Console.Write("Presione ENTER para terminar."); Console.ReadLine();
}
}

Ejemplo de ejecucin:
Veamos que hacer el sbado por la noche...
Desea quedarse en casa? (s/n): s
Le gusta ver TV? (s/n): n
Le gusta leer? (s/n): s
Sugerencia: Tmese un vinito y lea un buen libro

Veamos que hacer el sbado por la noche...
Desea quedarse en casa? (s/n): n
Le gusta bailar? (s/n): s
Le gusta la msica tropical? (s/n): n
Sugerencia: Vaya a la discotheque Los Tarros
Intro Prog. Orientada a Objeto Control de Flujo Rodrigo Sandoval U.
IIC 1102 Pgina: 6
2.2 Instruccin switch
La instruccin switch permite decidir cul bloque de instrucciones se debe ejecutar, de una serie de
bloques disponibles, tomando como criterio para la decisin el valor de una expresin. La expresin
suministrada se compara con una serie de valores constantes que etiquetan los bloques de instrucciones,
y cuando se logra un valor igual se inicia la ejecucin en ese punto.
Sintaxis:
switch ( expresin ) {
case constante1 : {
...
Bloque de instrucciones 1
...
break;
}
case constante2 : {
...
Bloque de instrucciones 2
...
break;
}
...
case constanteN : {
...
Bloque de instrucciones N
...
break;
}
default : { // Opcional
...
Bloque de instrucciones N+1
...
}
}
Los bloques de instrucciones consisten en una secuencia de instrucciones terminadas en punto y coma.
Al ejecutarse una instruccin switch, se evaluar la expresin suministrada en los parntesis, y se
comparar su valor con cada una de las constantes dadas, empezando por la primera y descendiendo.
Dependiendo de estos valores puede ocurrir lo siguiente:
Si se encuentra una constante igual al valor de la expresin, la ejecucin continuar en el bloque
de instrucciones asociado con la constante, y seguir de ah en adelante hasta terminar el caso
particular del switch, el cual debe terminar en instruccin break u otra de salto de flujo
(como continue o return). Una vez hecho esto, la ejecucin continuar en la siguiente instruccin
despus del switch.
Si no se encuentra ninguna constante que sea igual al valor de la expresin, y no se incluy la
seccin default, la instruccin pasar inadvertida (no se ejecutar ninguna de las
instrucciones contenidas en ella), y la ejecucin continuar en la siguiente instruccin despus
del switch.
Intro Prog. Orientada a Objeto Control de Flujo Rodrigo Sandoval U.
IIC 1102 Pgina: 7
Si no se encuentra ninguna constante que sea igual al valor de la expresin, pero existe un
bloque de instrucciones asociado con la partcula default, la ejecucin continuar en ese
bloque. Una vez hecho esto, la ejecucin seguir en la siguiente instruccin despus del
switch.
Es posible escribir switch anidados, es decir, incluir otras instrucciones switch dentro de
las instrucciones a ejecutar al evaluar una primera instruccin switch.
Ejemplos: Clsico uso en un men de opciones
Console.WriteLine(Con qu desea pagar?);
Console.WriteLine(1) Efectivo);
Console.WriteLine(2) Cheque);
Console.WriteLine(3) Tarjeta Crdito);
Console.WriteLine(4) MasterCard);

opcion = int.Parse(Console.ReadLine());

switch( opcion ) {
case 1: Console.WriteLine(Slo con billetes nuevos); break;
case 2: Console.WriteLine(Adjunte su cdula al cheque); break;
case 3: Console.WriteLine(Entrguenos su tarjeta, por favor); break;
default: Console.WriteLine(Lo siento, pero no manejamos ese medio);
}

2.2.1 Ejemplo: Conversin a letras de una cantidad de dos dgitos
Programa que convierte una cantidad de dos dgitos a letras, en la forma en que sera til, por ejemplo,
para escribir un cheque. El programa es una versin muy simple que soporta slo cantidades entre 30 y
99 (no se consideran excepciones). El programa pide al usuario que ingrese una cantidad entre 30 y 99, y
le devuelve por pantalla el equivalente en letras. No se tratan los nmeros entre 1 y 29 por simplicidad,
dado que entre estos valores se presentan mltiples reglas de excepcin. Si no se respeta esta
restriccin se obtendrn resultados sin sentido
using System;

class MainApp {
public static void Main() {
int cantidad; // cantidad a convertir
int decenas; // numero de decenas en la cantidad a convertir
int unidades; // numero de unidades en la cantidad a convertir

Console.Write("Ingrese un numero entero entre 0 y 99: ");
cantidad = (int) Console.Read();

decenas = cantidad / 10;
unidades = cantidad % 10;

if(decenas == 1)
{
switch(unidades)
{
case 0: {Console.Write("Diez ); break;}
case 1: {Console.Write("Once ); break;}
case 2: {Console.Write("Doce ); break;}
case 3: {Console.Write("Trece ); break;}
Intro Prog. Orientada a Objeto Control de Flujo Rodrigo Sandoval U.
IIC 1102 Pgina: 8
case 4: {Console.Write("Catorce ); break;}
case 5: {Console.Write("Quince ); break;}
case 6: {Console.Write("Dieciseis ); break;}
case 7: {Console.Write("Diecisiete); break;}
case 8: {Console.Write("Dieciocho ); break;}
case 9: {Console.Write("Diecinueve); break;}
}
}
else{
switch(decenas) {
case 2:
{
if (unidades == 0) Console.Write("Veinte");
else Console.Write("Veinti");
break;
}
case 3: { Console.Write("Treinta"); break; }
case 4: { Console.Write("Cuarenta"); break; }
case 5: { Console.Write("Cincuenta"); break; }
case 6: { Console.Write("Sesenta"); break; }
case 7: { Console.Write("Setenta"); break; }
case 8: { Console.Write("Ochenta"); break; }
case 9: { Console.Write("Noventa"); break; }
}

if(unidades>0 && decenas>2) Console.Write(" y ");

switch(unidades) {
case 0: { Console.Write("); break; }
case 1: { Console.Write("uno ); break; }
case 2: { Console.Write("dos ); break; }
case 3: { Console.Write("tres ); break; }
case 4: { Console.Write("cuatro); break; }
case 5: { Console.Write("cinco ); break; }
case 6: { Console.Write("seis ); break; }
case 7: { Console.Write("siete ); break; }
case 8: { Console.Write("ocho ); break; }
case 9: { Console.Write("nueve ); break; }
}
}
Console.Write("\nPresione ENTER para terminar."); Console.ReadLine();
}
}

Ejemplo de ejecucin:

Ingrese un numero entero entre 0 y 99: 32
Treinta y dos


Intro Prog. Orientada a Objeto Control de Flujo Rodrigo Sandoval U.
IIC 1102 Pgina: 9
3 Iteracin
3.1 Instruccin while
La instruccin while permite repetir una instruccin o un bloque de instrucciones, tantas veces como
sea necesario, mientras una determinada expresin lgica sea verdadera. Si la expresin es falsa
inicialmente, la instruccin while no tiene efecto alguno, es decir, no ejecuta ninguna de las
instrucciones subordinadas.
Ms adelante se presenta una equivalencia lgica de las tres instrucciones para especificar iteracin con
que cuenta el lenguaje de programacin C.
Sintaxis:

while ( expresin-lgica )
instruccin ;


while ( expresin-lgica ) {
...
Bloque de instrucciones
...
}
Los bloques de instrucciones consisten en una secuencia de instrucciones terminadas en punto y coma.
Al ejecutarse la instruccin while, se evaluar la expresin booleana suministrada en los parntesis, y
si su valor es verdadero, se ejecutarn la o las instrucciones subordinadas. Una vez hecho esto, la
condicin es reevaluada y se procede de la misma manera. Cuando la condicin se vuelve falsa, en la
siguiente evaluacin se dar la instruccin while por terminada.
Las instrucciones subordinadas al while pueden ser compuestas, es decir, otras instrucciones while,
if, etc.
Si la condicin nunca se vuelve falsa, la instruccin nunca terminar y, dependiendo de las instrucciones
incluidas en el ciclo, se generara un error de ejecucin que detendra el programa, o podra ser que el
programa itere indefinidamente hasta ser detenido en forma manual.
Ejemplos:
1. num = 0;
while (num < 50) {
// Esto se ejecuta en cada iteracin, hasta que num = 50
if ( (num % 2) == 0 )
Console.WriteLine("El nmero {0} es par", num);
else
Console.WriteLine("El nmero {0} es impar", num);
num++;
}

3.1.1 Ejemplo: Tabla de conversin de temperaturas (Fahrenheit-Celsius)
Programa que genera una tabla de equivalencias Celsius-Fahrenheit, desde -15 hasta 50 grados Celsius.
Se emplea una funcin de conversin para llevar a cabo los clculos.
Intro Prog. Orientada a Objeto Control de Flujo Rodrigo Sandoval U.
IIC 1102 Pgina: 10
using System;

class Temperatura {

// Funcin que recibe una temperatura expresada en grados Celsius y retorna
// su equivalente en grados Faherenheit. El argumento de entrada es celsius
// de tipo float. El valor de retorno tambin es de tipo float.
// La frmula de conversin es F=32+(C*9/5)
***************************************************************************/
public float fahrenheit(float celsius) {
return((celsius*9/5)+32);
}
}

class MainApp {

static void Main () {
Temperatura temp = new Temperatura();
float centigrados = (float) -15.0; // Temperatura en grados Celsius, inicialmente -15

// Imprime el encabezado de la tabla con un formato que le da buena apariencia
// Refirase a la descripcin de Console.WriteLine para mayor detalle
Console.WriteLine("{0,15} {1,15}", "Celsius", "Fahrenheit");

// Ciclo que genera la tabla. La variable centgrados vale inicialmente -15, y
// dentro del ciclo se va a ir incrementando en paso de 5 grados, hasta llegar
// hasta 50: Ver la condicin de control del while. En cada iteracin del
// ciclo se imprime el valor en centgrados y su equivalente fahrenheit.
// Observe que la conversin se lleva a cabo directamente al imprimir.
while (centigrados <= 50.0) {
// Imprime la fila de la tabla: Centgrados - Fahrenheit
Console.WriteLine("{0,15:F2} {1,15:F2}", centigrados, temp.fahrenheit(centigrados));

// Incrementa centigrados para la siguiente iteracin
centigrados = centigrados + 5;
}
Console.WriteLine("Presione ENTER para terminar."); Console.ReadLine();
}
}


Ejemplo de ejecucin:
Celsius Fahrenheit
-15.00 5.00
-10.00 14.00
-5.00 23.00
0.00 32.00
5.00 41.00
10.00 50.00
15.00 59.00
20.00 68.00
25.00 77.00
30.00 86.00
35.00 95.00
40.00 104.00
45.00 113.00
50.00 122.00
3.1.2 Ejemplo: Esperando el Ao Nuevo
Este programa es una simulacin de un cronmetro para la espera del ao nuevo. El programa pide al
usuario la fecha y hora actuales, y cuenta los segundos hasta la llegada del primero de enero del
siguiente ao. Los segundos se simulan como iteraciones en un ciclo. Una vez llegada la fecha esperada
imprime un mensaje que incluye la cantidad de segundos que esper (es decir, la cantidad de iteraciones
Intro Prog. Orientada a Objeto Control de Flujo Rodrigo Sandoval U.
IIC 1102 Pgina: 11
que complet). En esta simulacin se toman las medidas pertinentes para detectar y tratar en forma
especial los aos bisiestos.

Ejemplo de ejecucin:



using System;


class Agno {

private int agno;

// Constructor de la clase. Inicializa el valor del ao
public Agno(int a) { agno = a; }

//////////////////////////////////////////////////////////////////////////////
// Funcin que recibe como argumento un ao y devuelve un nmero entero que
// indica si es bisiesto o no. Si el ao pasado es bisiesto la funcin
// retorna true, y en caso contrario false. Para saber si un ao es bisiesto
// basta con analizar si es divisible por 4 y no por 100 (empleando mdulo).
//////////////////////////////////////////////////////////////////////////////
public bool bisiesto()
{
if ((agno % 4 == 0) && (agno % 100 != 0)) return(true);
else return(false);
}
}

class MainApp {

static void Main()
{
int d, m, a, hh, mm, ss; // Hora y fecha actuales
long contador = 0; // Contador de segundos

Console.WriteLine("Ingrese la fecha actual.");
Console.Write("Ingrese el da: "); d = int.Parse(Console.ReadLine());
Console.Write("Ingrese el mes: "); m = int.Parse(Console.ReadLine());
Console.Write("Ingrese el ao: "); a = int.Parse(Console.ReadLine());
Console.Write("Ingrese la hora: "); hh = int.Parse(Console.ReadLine());
Console.Write("Ingrese minutos: "); mm = int.Parse(Console.ReadLine());
Console.Write("Ingrese segundos: "); ss = int.Parse(Console.ReadLine());

Agno year = new Agno(a); // Se inicializa la instancia de ao

// Este ciclo simula la ocurrencia de un segundo en cada iteracin. La variable
// contador (inicialmente en 0) se incrementa en cada vuelta, para lograr tal
// efecto. Cada vez que pasa un segundo se verifica si es necesario actualizar
// el estado de las variables que mantienen la hora, minutos, da, mes y ao.
// La condicin para salir del ciclo es llegar (o estar) al primero de enero.

while (d!=1 || m!=1) { // Da=1 y Mes=1 -> 1 enero!
ss++; // Se aumenta el contador de segundos
if (ss==60) {
ss = 0; mm++;
if (mm==60) {
mm=0; hh++;
Intro Prog. Orientada a Objeto Control de Flujo Rodrigo Sandoval U.
IIC 1102 Pgina: 12
if (hh==24) {
hh = 0; d++;

// Verifica si hay cambio de mes, considerando las excepciones:
// Abril, Junio, Septiembre y Noviembre tienen solo 30 das
// Febrero tiene 28 das excepto en los aos bisiestos
// El resto de los meses tienen 31 das
if ( (d==29 && m==2 && !year.bisiesto()) ||
(d==30 && m==2 && year.bisiesto()) ||
(d==31 && (m==4 || m==6 || m==9 || m==11)) ||
(d==32) ) {
d=1; m++;
if (m==13) {
m=1; a++;
}
}
}
}
}
contador++;
}

Console.WriteLine("Feliz ao {0,4} !!!", a);
Console.WriteLine("Transcurrieron {0} segundos", contador);
Console.WriteLine("Presione ENTER para terminar.");
Console.ReadLine();
}
}

3.2 Instruccin do-while
La instruccin do-while permite repetir una instruccin o un bloque de instrucciones, tantas veces
como sea necesario, mientras una determinada expresin lgica sea verdadera. A diferencia de la
instruccin while, la condicin se verifica una vez ejecutadas las instrucciones subordinadas, por lo
que si la expresin es falsa inicialmente, y permanece as, el cuerpo del ciclo se ejecutar una vez (con
while no se ejecutara).
Sintaxis:
do
instruccin ;
while ( expresin-lgica );


do {
...
Bloque de instrucciones
...
} while ( expresin-lgica );

Los bloques de instrucciones consisten en una secuencia de instrucciones terminadas en punto y coma.
Al ejecutarse la instruccin do-while, se ejecutarn la o las instrucciones subordinadas. Una vez
hecho esto, se evala la expresin booleana suministrada en los parntesis, y si su valor es verdadero,
se volvern a ejecutar las instrucciones subordinadas y se proceder de la misma manera. Cuando la
condicin se vuelve falsa, en la siguiente evaluacin se dar la instruccin do-while por terminada.
Intro Prog. Orientada a Objeto Control de Flujo Rodrigo Sandoval U.
IIC 1102 Pgina: 13
Las instrucciones subordinadas al do-while pueden ser compuestas, es decir, otras instrucciones
do-while, while, if, etc.
Si la condicin nunca se vuelve cero, la instruccin nunca terminar y, dependiendo de las instrucciones
incluidas en el ciclo, se generara un error de ejecucin que detendra el programa, o podra ser que el
programa itere indefinidamente hasta ser detenido en forma manual.
Ejemplos:
1. do {
// Esto se ejecuta en cada iteracin del ciclo
...
Console.Write ("Desea continuar? (s/n): ");
respuesta = Console.ReadLine();
} while (respuesta != n);

Programas de ejemplo: Ver ejemplos en captulo de Algoritmos Numricos

3.3 Instruccin for
La instruccin for permite repetir una instruccin o un bloque de instrucciones, tantas veces como sea
necesario, mientras una determinada expresin lgica sea verdadera. Permite adems especificar
instrucciones de inicializacin (que se ejecutarn una nica vez antes de empezar las iteraciones), as
como instrucciones que deben ejecutarse al finalizar cada iteracin, pero antes de empezar la siguiente.
Al igual que la instruccin while la condicin se verifica antes de ejecutar las instrucciones
subordinadas, por lo que si la expresin es falsa inicialmente, la instruccin no tendr efecto alguno, es
decir, no se ejecuta ninguna de las instrucciones subordinadas.
Ms adelante se presenta una equivalencia lgica de las tres instrucciones para especificar iteracin con
que cuenta el lenguaje de programacin C.
Sintaxis:
for ( inicializacin ; expresin-booleana ; actualizacin
)
instruccin ;


for ( inicializacin ; expresin-booleana ; actualizacin
) {
...
Bloque de instrucciones
...
}
Los bloques de instrucciones consisten en una secuencia de instrucciones terminadas en punto y coma.
Tanto el componente de inicializacin como el de actualizacin corresponde a una instruccin, o a varias
separadas por comas. Cualquiera de los componenentes en los parntesis se puede omitir, incluso los
tres, pero los separadores (punto y coma) deben aparecer siempre.
Al ejecutarse la instruccin for, en primera instancia se ejecutar la seccin de inicializacin.
Posteriormente se evaluar la condicin y, en caso de ser verdadera (no cero), se ejecutarn la o las
instrucciones subordinadas. Una vez cumplido esto, se ejecutar la seccin de actualizacin y se volver
a verificar la condicin. Cuando la condicin se vuelve falsa (es decir, cero), en la siguiente evaluacin se
dar la instruccin for por terminada.
Intro Prog. Orientada a Objeto Control de Flujo Rodrigo Sandoval U.
IIC 1102 Pgina: 14
Las instrucciones subordinadas al for pueden ser compuestas, es decir, otras instrucciones for, do-
while, while, if, etc.
Si la condicin nunca se vuelve cero, la instruccin nunca terminar y, dependiendo de las instrucciones
incluidas en el ciclo, se generara un error de ejecucin que detendra el programa, o podra ser que el
programa itere indefinidamente hasta ser detenido en forma manual.
El uso normal que se le da a la instruccin for es para implementar ciclos en los cuales se conoce de
antemano, o al menos se puede determinar antes del ciclo, la cantidad de iteraciones que son
necesarias. En este caso, se emplea una variable de control (contador de iteraciones) que se inicializa en
la seccin de inicializacin y se modifica (por ejemplo, incrementndola) en la seccin de actualizacin.
Ejemplos:
1. Se conoce de antemano la cantidad de iteraciones:

for (i = 0 ; i < 100 ; i++)
Console.WriteLine("{0}", i);


2. Ciclo infinito:

for (;;) {
...
instrucciones
...
}


3. Programa de uso del For
using System;

class MainApp {
static void main() {
int rep;
for (rep=1;rep<=20;rep=rep+5)
// repite de 5 en 5 ascendente
Console.WriteLine("rep ascendente: {0}",rep);
for (rep=20;rep>=1;rep=rep-5)
// repite de 5 en 5 descendente
Console.WriteLine("rep descendente: {0},rep);
}
}

Salida del programa:
rep ascendente: 1
rep ascendente: 6
rep ascendente: 11
rep ascendente: 16
rep descendente: 20
rep descendente: 15
rep descendente: 10
rep descendente: 5

Intro Prog. Orientada a Objeto Control de Flujo Rodrigo Sandoval U.
IIC 1102 Pgina: 15
3.3.1 Ejemplo: Clculo de x a la n (uso restringido del for)
Programa que calcula x**n (n-sima potencia de x), empleando un ciclo for. Se implementa una funcin
que recibe dos argumentos, la base y el exponente, y devuelve el valor indicado. Para probar la funcin,
el programa solicita al usuario los valores de la base y el exponente, lleva a cabo el clculo utilizando la
funcin, y finalmente devuelve el resultado por pantalla.

using System;

class Calculo {

//////////////////////////////////////////////////////////////////////////
// Funcin que calcula la n-sima potencia de un nmero x, ambos valores
// recibidos como argumentos de entrada de tipo float. El valor de retorno
// tambin es float. No se controla la validez de los argumentos.
// Clculo: x**n = x * x * ... * x (n veces)
//////////////////////////////////////////////////////////////////////////
public double potencia(double x, double n)
{
int i; // Contador del nmero de multiplicaciones realizadas
double pot; // Acumulador para el resultado
pot = x; // Se inicia la acumulacin del resultado con x (la base)

// Ciclo que lleva a cabo el calculo: i variar de 2 a n
for (i=2; i<=n; i++)
// Se multiplica el acumulado actual una vez ms por la base (x)
pot = pot * x;
// Devuelve como valor de retorno el resultado acumulado
return(pot);
}

}

class MainApp {

//////////////////////////////////////////////////////////////////////////
// Pide al usuario una base x y un exponente n, y calcula el valor de x**n
// (n-sima potencia de x), devolviendo el resultado por pantalla.
//////////////////////////////////////////////////////////////////////////
static void Main() {
float xbase; // Base empleada para el clculo, dado por el usuario
int exponente; // Exponente empleado para el clculo, dado por el usuario
Calculo cal = new Calculo();

// Solicita y lee del usuario los valores de base y exponente
Console.Write("Ingrese el valor de x: ");
xbase = float.Parse(Console.ReadLine());
Console.Write("Ingrese el valor de n: ");
exponente = int.Parse(Console.ReadLine());

// Devuelve el resultado de x**n, llevando a cabo en forma directa el
// llamado a la funcin que realiza el clculo en si. Emplea 2 decimales.
Console.WriteLine("Resultado de x**n: {0}", cal.potencia(xbase, exponente));

Console.WriteLine("Presione ENTER para terminar"); Console.ReadLine();
}
}

Ejemplo de ejecucin:

Ingrese el valor de x: 2
Ingrese el valor de n: 8
Resultado de x**n: 256


Intro Prog. Orientada a Objeto Control de Flujo Rodrigo Sandoval U.
IIC 1102 Pgina: 16
Ingrese el valor de x: 8
Ingrese el valor de n: 15
Resultado de x**n: 4747562057728
3.3.2 Ejemplo: Conversin a letras de cantidades numricas (uso general del for)
Programa que convierte una cantidad numrica en su equivalente en letras, en la forma en que sera til,
por ejemplo, para escribir un cheque. Es una versin mejorada del ejemplo de uso de switch, presentado
anteriormente, pero con menos restricciones y, en general, un mejor funcionamiento. Se permiten
cantidades de hasta 9 dgitos, aunque la ampliacin a ms dgitos es bastante simple.
El programa solicita al usuario la cantidad en cuestin y le devuelve el equivalente. Existen algunas
excepciones que no fueron consideradas para no complicar demasiado el ejemplo.
Se permiten cantidades de hasta 9 dgitos, aunque la ampliacin a ms dgitos es bastante simple. El
programa solicita al usuario la cantidad en cuestin y le devuelve el equivalente. Existen algunas
excepciones que no fueron consideradas para no complicar demasiado el ejemplo. No se mostrar el
desarrollo completo de la metodologa estudiada, sino tan solo la descomposicin en funciones del
problema general, el algoritmo resultante y el cdigo equivalente en el lenguaje de programacin C#.
El problema de la conversin a letras puede simplificarse si se descompone en funcionalidades ms
independientes, las cuales se implementarn posteriormente como funciones en C#:
Unidades
Decenas
Centenas
Milenios (que agrupa desde los cien mil a los mil)
Millones

Finalmente, el mtodo que transforma el nmero a texto, se define como
toString2()


/////////////////////////////////////////////////////////////////////////
//
// Curso: IIC1102 - Introduccin a la Programacin Orientada a Objetos
// Profesor: Rodrigo Sandoval U.
//
// Ejemplo de transformacin de nmeros a texto.
//
//////////////////////////////////////////////////////////////////////////

using System;

class Numero {

private long num;

public Numero(string numero) { this.num = int.Parse(numero); }

string Unidad(long Unidades) {
switch(Unidades) {
case 1: { return("uno" ); }
case 2: { return("dos" ); }
case 3: { return("tres" ); }
Intro Prog. Orientada a Objeto Control de Flujo Rodrigo Sandoval U.
IIC 1102 Pgina: 17
case 4: { return("cuatro" ); }
case 5: { return("cinco" ); }
case 6: { return("seis" ); }
case 7: { return("siete" ); }
case 8: { return("ocho" ); }
case 9: { return("nueve" ); }
}
return("");
}

string Decenas(long Diez, long Uni) {
switch(Diez) {
case 0: { return(""); }
case 1: { if(Uni >= 6) { return("dieci"); }
else {
switch(Uni) {
case 0: { return("diez"); }
case 1: { return("once"); }
case 2: { return("doce"); }
case 3: { return("trece"); }
case 4: { return("catorce"); }
case 5: { return("quince"); }
default: return ("");
}
}
}
case 2: { if(Uni==0) return("veinte"); else return("veinti"); }
case 3: { if(Uni==0) return("treinta"); else return("treinta y "); }
case 4: { if(Uni==0) return("cuarenta"); else return("cuarenta y "); }
case 5: { if(Uni==0) return("cincuenta");else return("cincuenta y "); }
case 6: { if(Uni==0) return("sesenta"); else return("sesenta y "); }
case 7: { if(Uni==0) return("setenta"); else return("setenta y "); }
case 8: { if(Uni==0) return("ochenta"); else return("ochenta y "); }
case 9: { if(Uni==0) return("noventa"); else return("noventa y "); }
}
return("");
}

string Centenas(long Cien, long Diez, long Uni) {
if (Cien==1 && Diez==0 && Uni==0) return("cien");
else {
switch(Cien) {
case 1: { return ("ciento" ); }
case 2: { return ("doscientos" ); }
case 3: { return ("trescientos" ); }
case 4: { return ("cuatrocientos"); }
case 5: { return ("quinientos" ); }
case 6: { return ("seiscientos" ); }
case 7: { return ("setecientos" ); }
case 8: { return ("ochocientos" ); }
case 9: { return ("novecientos" ); }
}
}
return("");
}

string Milenios(long CienMil, long DiezMil, long Mil) {
string resultado = "";
if(CienMil!=0)
resultado = resultado + Centenas (CienMil,DiezMil,Mil);

if(DiezMil!=0)
resultado = resultado + " " + Decenas (DiezMil,Mil);
Intro Prog. Orientada a Objeto Control de Flujo Rodrigo Sandoval U.
IIC 1102 Pgina: 18

if(Mil>0 && Mil!=1)
resultado = resultado + Unidad(Mil);

else if(DiezMil>1 && Mil>0) resultado = resultado + " un";

if(CienMil!=0 || DiezMil!=0 || Mil!=0)
resultado = resultado + " mil";

return (resultado);
}

string Millones(long Millon) {
switch(Millon) {
case 1: { return ("un millon" ); }
case 2: { return ("dos millones" ); }
case 3: { return ("tres millones" ); }
case 4: { return ("cuatro millones"); }
case 5: { return ("cinco millones" ); }
case 6: { return ("seis millones" ); }
case 7: { return ("siete millones" ); }
case 8: { return ("ocho millones" ); }
case 9: { return ("nueve millones" ); }
}
return ("");
}

public string toString2() {
long nUni, nDec, nCen, nMil, n10Mil, n100Mil, nMill;

nMill = num/1000000;
n100Mil = num/100000 - nMill*10;
n10Mil = num/10000 - n100Mil*10 - nMill*100;
nMil = num/1000 - n10Mil*10 - n100Mil*100 - nMill*1000;
nCen = num/100 - nMil*10 - n10Mil*100 - n100Mil*1000 - nMill*10000;
nDec = num/10 - nCen*10 - nMil*100 - n10Mil*1000 - n100Mil*10000 - nMill*100000;
nUni = num - nDec*10 - nCen*100 - nMil*1000 - n10Mil*10000
- n100Mil*100000 - nMill*1000000;

return(Millones(nMill) + " " + Milenios(n100Mil,n10Mil,nMil) + " " +
Centenas(nCen,nDec,nUni) + " " + Decenas(nDec,nUni) +
Unidad(nUni));
}
}


class MainApp {

static void Main() {
Console.Write("Ingrese un nmero (hasta 9.999.999): ");
Numero num = new Numero(Console.ReadLine());

Console.WriteLine("{0}", num.toString2());

Console.WriteLine("Presione ENTER para terminar ... "); Console.ReadLine();
}
}

Ejemplo de ejecucin:
Ingrese un Numero: 3686041
tres millones seiscientos ochenta y seis mil cuarenta y uno
Intro Prog. Orientada a Objeto Control de Flujo Rodrigo Sandoval U.
IIC 1102 Pgina: 19
Ingrese un Numero: 2568
dos mil quinientos sesenta y ocho

3.4 Instruccin foreach
La instruccin foreach repite un grupo de instrucciones definidas, para cada elemento dentro de un
arreglo o dentro de una coleccin de objetos. Esta instruccin se usa para iterar a travs de la coleccin
para obtener la informacin requerida, pero no debe ser utilizada para cambiar los contenidos de la
coleccin del arreglo, ya que puede producir efectos laterales no deseados. La declaracin tiene la
siguiente forma:
foreach (tipo identificador in expresin)
instrucciones

using System;
class MainClass
{
public static void Main()
{
int impares = 0, pares = 0;
int[] arr = new int [] {0,1,2,5,7,8,11};

foreach (int i in arr) {
if (i%2 == 0)
pares++;
else
impares++;
}

Console.WriteLine("Hay {0} impares y {1} pares.", impares, pares);
}
}
Ms ejemplos de esta instruccin se ven en una siguiente seccin, dedicada a los Arreglos o Arrays.

3.5 Equivalencia Lgica entre Instrucciones de Iteracin
Las tres instrucciones con que cuenta el lenguaje de programacin C para la especificacin de iteracin
son lgicamente equivalentes. Esto quiere decir que un ciclo escrito empleando una de las
instrucciones puede reescribirse empleando otra sin que hayan cambios en la ejecucin del programa (su
semntica).
Para ilustrar este hecho, se muestra a continuacin un ciclo escrito con la instruccin for, y la forma en
que se reescribira empleando las otras dos instrucciones de iteracin. Los bloques son secuencias de
instrucciones.
Empleando for:
for (bloque1; condicin; bloque2) {
bloque3
}

// Instrucciones de bloque1 y bloque2 separadas por coma
// Instrucciones de bloque3 separadas por punto y coma
Intro Prog. Orientada a Objeto Control de Flujo Rodrigo Sandoval U.
IIC 1102 Pgina: 20

Empleando while:
bloque1
while (condicin) {
bloque3
bloque2
}

// Instrucciones de los bloques separadas por punto y
coma

Empleando do-while:
bloque1
if (condicin)
do {
bloque3
bloque2
} while (condicin);

// Instrucciones de los bloques separadas por punto y
coma
// Por qu es necesario el if?

Finalmente, se muestra otro ejemplo de la equivalencia lgica entre las instrucciones de iteracin. A
continuacin se presenta un ciclo escrito mediante do-while, y la forma como se reescribira empleando
while.
Empleando do-while:
do {
bloque
} while (condicin);


// Instrucciones del bloque separadas por punto y coma
Empleando while:
bloque
while (condicin) {
bloque
}

// Instrucciones del bloque separadas por punto y coma
// Por qu se debe repetir el bloque (afuera y adentro)?
Intro Prog. Orientada a Objeto Control de Flujo Rodrigo Sandoval U.
IIC 1102 Pgina: 21
3.5.1 Ejemplos: Programa con funciones equivalentes y Ciclos anidados
Ejemplo 1: Equivalencia de Ciclos en Funcin Cuadrado()
Este programa muestra la equivalencia lgica entre las funciones cuadrado, cuadrado1 y cuadrado2, para
imprimir (dibujar) en pantalla un cuadrado.

using System;

class Cuadrado {

public void cuadrado(int longitud)
{
int a,b;
for (a=1;a<=longitud;a++) { // ciclo externo
for (b=1;b<=longitud;b++) // ciclo interno
Console.Write("*");
Console.WriteLine(); // salto de lnea
}
}

public void cuadrado1(int longitud)
{
int a=1,b;

while (a<=longitud) { // ciclo externo
b=1;
while (b<=longitud) { // ciclo interno
Console.Write ("*");
b++;
}
Console.WriteLine(); // salto de lnea
a++;
}
}

public void cuadrado2(int longitud)
{
int a,b;
a=1;

if (longitud>=1) {
do { // ciclo externo
b=1;
if (longitud>=1) {
do { // ciclo interno
Console.Write ("*");
b++;
} while (b<=longitud);
Console.WriteLine(); // salto de lnea
a++;
}
} while (a<=longitud);
}
}
}

Intro Prog. Orientada a Objeto Control de Flujo Rodrigo Sandoval U.
IIC 1102 Pgina: 22
class MainApp {

static void Main()
{
Cuadrado cuad = new Cuadrado();

cuad.cuadrado(5); Console.ReadLine();
cuad.cuadrado1(5); Console.ReadLine();
cuad.cuadrado2(5); Console.ReadLine();
}
}



Ejemplo de ejecucin:
*****
*****
*****
*****
*****


Ejemplo 2: Equivalencia de Ciclos en Series de Letras
Las funciones serie_letras1, hasta serie_letras6 son equivalentes e imprimen una serie de letras
using System;

class Letras {

public void serie_letras1(char a, char b, char c, char d)
{
int letra1,letra2;

for (letra1=a; letra1<=b; letra1++)
for (letra2=c; letra2<=d; letra2++)
Console.WriteLine("{0} {1} ",(char) letra1,(char) letra2);
}

public void serie_letras2(char a,char b, char c, char d)
{
int letra1,letra2;

for (letra1=a; letra1<=b; letra1++)
for (letra2=c; letra2<=d; letra2++)
Console.WriteLine("{0} {1} ",(char) letra1,(char) letra2);
}

public void serie_letras3(int a,int b, int c, int d)
{
int letra1,letra2;

for (letra1=a; letra1<=b; letra1++)
for (letra2=c; letra2<=d; letra2++)
Console.WriteLine("{0} {1} ", (char) letra1, (char) letra2);
}

Intro Prog. Orientada a Objeto Control de Flujo Rodrigo Sandoval U.
IIC 1102 Pgina: 23
public void serie_letras4(int a,int b, int c, int d)
{
int letra1,letra2;

for (letra1=a; letra1<=b; letra1++)
for (letra2=c; letra2<=d; letra2++)
Console.WriteLine("{0} {1} ",(char) letra1,(char) letra2);
}

public void serie_letras5()
{
int letra1,letra2;

for (letra1='A'; letra1<='C'; letra1++)
for (letra2=68;letra2<=69;letra2++)
Console.WriteLine("{0} {1} ",(char) letra1,(char) letra2);
}

public void serie_letras6()
{
int letra1,letra2;

letra1 = 65; // 65 ==> 'A'

while (letra1<='C') {
letra2 = 'D';
while (letra2<=69) {
Console.WriteLine("{0} {1} ",(char) letra1,(char) letra2);
letra2++;
}
letra1++;
}
}
}

class MainApp {

static void Main()
{
Letras let = new Letras();

let.serie_letras1('A','C','D','E'); Console.ReadLine();
let.serie_letras2('A','C','D','E'); Console.ReadLine();
let.serie_letras3('A','C','D','E'); Console.ReadLine();
let.serie_letras4('A','C','D','E'); Console.ReadLine();
let.serie_letras5(); Console.ReadLine();
let.serie_letras6(); Console.ReadLine();
}
}


Ejemplo de ejecucin
A D
A E
B D
B E
C D
Intro Prog. Orientada a Objeto Control de Flujo Rodrigo Sandoval U.
IIC 1102 Pgina: 24
C E
3.6 Iteraciones con Anidamiento
Dentro de las instrucciones que se pueden incluir en un ciclo se encuentran a su vez, otros ciclos, es
decir, instrucciones while, do-while, y for. Este tipo de construcciones, en las que se incluye
una instruccin de repeticin dentro del cuerpo de otra se conoce como iteracin anidada.
En una iteracin anidada, en cada iteracin del ciclo exterior, se completa un grupo de iteraciones del
ciclo interior. Considere, por ejemplo, el siguiente fragmento de cdigo:

for (i=1; i<=3; i++)
for (j=1; j<=5; j++)
Console.WriteLine("{0} {1}, i, j);

El ciclo exterior se ejecutar 3 veces, haciendo variar la variable i por los valores 1,2,3. En cada una de
estas iteraciones se ejecutar un ciclo de 5 iteraciones (el for interior), en el que se variar la variable j
por los valores 1,2,3,4,5. De esta forma, por cada valor que toma la variable i, la variable j tomar todos
sus valores. As, la instruccin Console.WriteLine se ejecutar 15 veces (3x5), y la salida de este
programa sera algo como:
1 1
1 2
1 3
1 4
1 5
2 1
2 2
2 3
2 4
2 5
3 1
3 2
3 3
3 4
3 5
Es posible anidar cualquier cantidad de instrucciones de iteracin, prcticamente hasta que la
implementacin del compilador lo soporte. Sin embargo, demasiados niveles de anidamiento pueden
volver el programa difcil de leer, por lo que se recomienda seguir reglas claras de indentacin, que hagan
el cdigo ms legible.
Ms adelante en la materia se muestran ejemplos en los que se emplean instrucciones de iteracin
anidadas.

Material preparado por Rodrigo Sandoval U en Marzo 2004,
basado en los apuntes de clase del curso IIC1102, ao 2003, de M. Nussbaum, Marcos Seplveda, et.al
Los ejemplos fueron preparados por el MSR Lab del Depto de Ciencia de la Computacin, Escuela de Ingeniera

PONTIFICIA UNIVERSIDAD CATLICA DE CHILE
ESCUELA DE INGENIERA
DEPARTAMENTO DE CIENCIA DE LA COMPUTACIN
IIC 1102 INTRODUCCIN A LA PROGRAMACIN
Profesor: Rodrigo Sandoval U.

Captulo VI Algoritmos Numricos


1 ALGORITMOS O MTODOS NUMRICOS................................................................................................. 1
1.1 EJ EMPLO: CLCULO DE E MEDIANTE SERIE INFINITA ......................................................................................1
1.2 EJ EMPLO: CLCULO DE E A LA X, MEDIANTE SERIE, COMPARANDO CON FUNCIN EXP() ................................2
1.3 EJ EMPLO: CLCULO DE A ELEVADO A LA X (A**X), MEDIANTE SERIES, CON LA MXIMA PRECISIN POSIBLE4
1.4 EJ EMPLO: MTODO DE NEWTON PARA ENCONTRAR CEROS DE FUNCIONES ....................................................6
1.4.1 Implementacin...................................................................................................................................... 7


Intro. Prog. Orientada a Objeto Algoritmos Numricos Rodrigo Sandoval U.
IIC 1102 Pgina: 1
1 Algoritmos o Mtodos Numricos

Los mtodos numricos permiten resolver problemas obteniendo aproximaciones para las
soluciones mediante algoritmos iterativos.
Estos algoritmos reciben el nombre de algoritmos numricos.
Las aproximaciones resultan de mucha utilidad cuando las soluciones analticas o algebraicas resultan
muy difciles o hasta imposibles de obtener empleando mtodos tradicionales. Los computadores ayudan
en gran manera, al facilitar la programacin de los algoritmos basados en iteracin.
En esta seccin se presentan ejemplos de estos mtodos.
1.1 Ejemplo: Clculo de e mediante serie infinita
Programa que calcula el valor de la constante e, base de los logaritmos neperianos. Se hace una
aproximacin empleando la siguiente serie infinita:
e = 1 + 1/1! + 1/2! + 1/3! + 1/4! + ...
El clculo se detiene cuando el valor acumulado de e, no se logra diferenciar (por la precisin del
computador), del valor calculado en la iteracin anterior. Es decir, cuando el siguiente trmino a sumar es
tan pequeo que el computador lo considera como un cero.
El factorial, representado por ! en la serie, se implementa en el programa mediante una funcin.
Una vez que se calcula la aproximacin, el programa despliega el valor encontrado, as como el nmero
de iteraciones que se emplearon para obtenerlo, es decir, la cantidad de trminos de la serie que fue
necesario sumar para llegar a la aproximacin.

/***************************************************************************
* Ejemplo: Calculo de la constante e mediante una serie infinita
***************************************************************************/

using System;

/***************************************************************************
* Funcin que calcula el factorial de su argumento. Tanto el argumento de
* entrada (x) como el valor de retorno son de tipo double. No se hacen
* controles sobre la validez del argumento, cuyo valor debe ser > 0.
* Cualquier valor de entrada 0 o negativo arrojara un resultado de 1.
* Formula del factorial: x! = 1 * 2 * 3 * ... * (x-1) * x
***************************************************************************/
public class CCalculateE
{
public double iter;

public CCalculateE() { iter = 1; }

private double mFactorial(double x)
{
double i; // Factor actual de multiplicacin: 2, 3, ..., x
double fact = 1.0; // Acumulador para el resultado, inicialmente 1

// Ciclo en el que se calcula el factorial: i variara de 2 a x
for (i=2.0; i<=x; i++)
// Se multiplica el acumulado actual por el factor actual (i)
fact = fact * i;

// Devuelve como valor de retorno el resultado acumulado
return(fact);
}

public double mGetE()
{
Intro. Prog. Orientada a Objeto Algoritmos Numricos Rodrigo Sandoval U.
IIC 1102 Pgina: 2
double e = 1,
eanterior;

do{
eanterior = e;
e += 1/mFactorial(iter);
iter++;
}while( e != eanterior);

return e;
}
}
/***************************************************************************
* Programa que calcula el valor de la constante e, base de los logaritmos
* neperianos. Se emplea una aproximacin de la siguiente serie infinita:
* e = 1 + 1/1! + 1/2! + 1/3! + 1/4! + ...
* El clculo se detiene cuando el valor acumulado de e, no se logra
* diferenciar (por la precisin del computador), del valor calculado
* en la iteracin anterior.
***************************************************************************/
public class CMain
{
public static void Main()
{
CCalculateE ce = new CCalculateE();

Console.WriteLine("El valor de E es: {0}",ce.mGetE());
Console.WriteLine("Se emplearon {0} iteraciones.",ce.iter);
}
}

Ejemplo de ejecucin:

Valor de e:
2.718281828459045534884808148490265011787000000000
Se emplearon 19 iteraciones
1.2 Ejemplo: Clculo de e a la x, mediante serie, comparando con funcin exp()
Programa que calcula e**x (e elevado a la x), haciendo una aproximacin mediante una serie infinita. Se
siguen sumando trminos mientras la diferencia entre el valor aproximado y el valor devuelto por la
funcin exp() de la biblioteca math de C, sea mayor que una precisin dada por el usuario. La serie
empleada es:
Serie empleada: e**x = 1 + (x**1 / 1!) + (x**2 / 2!) + (x**3 / 3!) + ...
El factorial, representado por !, y el operador de potencia, representado por **, se implementan en el
programa mediante funciones.
Una vez obtenida la aproximacin, el programa despliega el valor calculado, y el nmero de iteraciones
que se emplearon para llegar a l, es decir, el nmero de trminos que fue necesario sumar.

/***************************************************************************
* Ejemplo: Calculo de e**x (e elevado a la x), empleando serie infinita *
***************************************************************************/
using System;

public class CEelevadoX
{
public double iter;
public double res;
public double exacto;
public double precision;

Intro. Prog. Orientada a Objeto Algoritmos Numricos Rodrigo Sandoval U.
IIC 1102 Pgina: 3
// Constructor de la clase CEelevadoX
public CEelevadoX(double pres)
{
precision = pres;
iter = 1;
res = 1;
}
// Miembro privado ya que solo se usa dentro de la clase
private double mFactorial(double x)
{
double i;
double fact = 1;

for (i=2.0; i<=x; i++) fact = fact * i;

return(fact);
}

// Miembro privado ya que solo se usa dentro de la clase
private double mPotencia(double x, double n)
{
double i;
double pot;

pot = x;

for (i=2; i<=n; i++) pot = pot * x;

return(pot);
}

// Miembro pblico ya que se llama desde afuera de la clase para calcular e**x
public double mGetEX(double power)
{
exacto = Math.Exp(power);

do {
res += mPotencia(power,iter)/mFactorial(iter);
iter++;
} while((exacto - res) >= precision);

return res;
}
}

public class CMain
{
public static void Main()
{
double pres,x;

Console.Write("Ingrese la potencia: ");
x = Double.Parse(Console.ReadLine());
Console.Write("Ingrese la precisin: ");
pres = Double.Parse(Console.ReadLine());

// Nueva instancia de la clase CEelevadoX
CEelevadoX ex = new CEelevadoX(pres);
ex.mGetEX(x);

Console.WriteLine("El valor de e^x de System.Math es: {0}",ex.exacto);
Console.WriteLine("El valor de e^x con {0} iteraciones y precisin de {1} es: {2}",
ex.iter,ex.precision,ex.res);
}
}



Intro. Prog. Orientada a Objeto Algoritmos Numricos Rodrigo Sandoval U.
IIC 1102 Pgina: 4
Ejemplo de ejecucin:

Ingrese el valor de x: 5
Ingrese la precision para el calculo de e(x): 0.01

Valor exp(x) de <math.h>: 148.413159102576600000000000000000000000000000000000

Calculo de e(x) con precision 1.000000e-002:
148.410210275043060000000000000000000000000000000000
Se emplearon 17 iteraciones

Ingrese el valor de x: 5
Ingrese la precision para el calculo de e(x): 0.000001

Valor exp(x) de <math.h>: 148.413159102576600000000000000000000000000000000000

Calculo de e(x) con precision 1.000000e-006:
148.413158521647740000000000000000000000000000000000
Se emplearon 23 iteraciones


1.3 Ejemplo: Clculo de a elevado a la x (a**x), mediante series, con la mxima
precisin posible
Programa que calcula a**x (a elevado a la x), haciendo una aproximacin mediante una serie, con la
mxima precisin que el lenguaje C puede calcular, esto es, hasta que los resultados alcanzados por la
serie converjan en un mismo valor. Se siguen calculando trminos de la serie mientras no exista
diferencia entre un valor aproximado y el siguiente valor aproximado. La serie empleada es:
a**x = 1+x*logE(a)+((x*logE(a))**2)/2!+((x*logE(a))**3)/3! + ...
Elevar un nmero a una potencia, es representado en el texto por ** (lo cual no es una sintaxis vlida en
C#).
Una vez obtenida la aproximacin, el programa despliega el valor calculado.
// Clculo de a elevado a la x (a**x) con la mxima precisin posible en C#.
// los valores de a y x deben ser mayores que cero
// se sabe que a**x = 1 + x * logE(a) + ((x * logE(a))**2)/2! + ((x * logE(a))**3)/3! + ...
// y que logE(x) = 2 [(x-1)/(x+1) + 1/3((x-1)/(x+1))**3 + 1/5((x-1)(x+1))**5 - ...
//
// Recuerde que: (a**n) = a * (a**(n-1))

using System;

public class CAElevadoX
{
private double mLogE(double x)
{
double basem,bas,res,resa,rep;

bas = (x-1.0)/(x+1.0);
basem = bas;
res = bas;
rep = 3.0;

do
{ resa = res;
basem = basem * bas * bas;
res = res + (1/rep)*basem;
rep += 2.0;
} while (res != resa);

return(2*res);
}

Intro. Prog. Orientada a Objeto Algoritmos Numricos Rodrigo Sandoval U.
IIC 1102 Pgina: 5
private double mFactorial(int x)
{
int i;
double fact = 1;

for (i=2; i<=x; i++) fact = fact * i;

return fact;
}

public double mPower(double a, double x)
{
double res,resa,bas,basem;
int rep;
bas = x * mLogE(a);
basem = bas;
rep = 2;
res = bas;

do
{
resa = res;
basem = basem * bas;
res += ( basem / mFactorial(rep) );
rep++;
} while (res != resa);

return(1+res);
}
}

public class CMain
{
public static void Main()
{
double a,x;

Console.Write("Ingrese la base: ");
a = Double.Parse(Console.ReadLine());
Console.Write("Ingrese la Potencia: ");
x = Double.Parse(Console.ReadLine());

CAElevadoX ax = new CAElevadoX();

Console.WriteLine("La respuesta es: {0}",ax.mPower(a,x));
}
}


Ejemplo de ejecucin:

Introducir valores: 2 3
valores de a: 2.00000 y x: 3.00000
resultado 8.00000

Intro. Prog. Orientada a Objeto Algoritmos Numricos Rodrigo Sandoval U.
IIC 1102 Pgina: 6
1.4 Ejemplo: Mtodo de Newton para encontrar ceros de funciones
Existen ecuaciones cuya solucin mediante tcnicas algebraicas tradicionales pueden resultar muy
difciles de obtener. Un ejemplo es la ecuacin:
ln x + 3x = 10.8074
Como se mencion anteriormente, los mtodos numricos ofrecen una alternativa para resolver este tipo
de problemas, permitiendo obtener aproximaciones a las soluciones reales. En esta seccin se presenta
un algoritmo que implementa el Mtodo de Newton para encontrar soluciones a ecuaciones del tipo f (x)
= 0.
La funcin para la cual se quieren encontrar los ceros ser definida mediante una directiva de
precompilacin #define parametrizada, con lo cual ilustraremos la potencialidad de este tipo de
definiciones. El usuario debe suministrar una aproximacin inicial de la solucin, que llamaremos x1.
Entre ms cercana est esta aproximacin inicial de la solucin, ms rpido llegar el programa a un
resultado. Nuestro algoritmo es iterativo, y se detiene cuando la diferencia entre dos aproximaciones
sucesivas est dentro de una precisin o tolerancia dada por el usuario. Es decir:

La frmula bsica empleada en el mtodo de Newton para generar la siguiente aproximacin para la
solucin es:

El algoritmo que aqu se presenta hace tambin una aproximacin numrica para la derivada f ' (x),
obteniendo entonces la siguiente ecuacin:
Intro. Prog. Orientada a Objeto Algoritmos Numricos Rodrigo Sandoval U.
IIC 1102 Pgina: 7


1.4.1 Implementacin
La funcin a la que se quiere encontrar el cero se define en el programa mediante la siguiente definicin:
public double f(double x) { return Math.Log(x) + 3*x - 10.8074; }
El resto de la implementacin es bastante sencilla, y muy similar a otros ejemplos mostrados
anteriormente.


using System;

public class CNewton
{
public double iter;
public double precision;

public CNewton(double pres)
{
iter = 0;
precision = pres;
}

public double f(double x) { return Math.Log(x) + 3*x - 10.8074; }

public double mGetAnswer(double x1)
{
double di, xi1,xi;

xi1 = x1;

do{
xi = xi1;
di = 0.0001 * xi;
xi1 = xi - di * (f(xi) / (f(xi+di)-f(xi)));
iter++;
} while(Math.Abs(xi1-xi) >= precision);

return xi1;
}
}

/***************************************************************************
* Programa que calcula x tal que f(x) = 0, empleando el mtodo de Newton.
* El proceso contina mientras el valor calculado mantenga una diferencia
* con el valor obtenido en la iteracin anterior que sea mayor que una
* precisin dada por el usuario.
***************************************************************************/

public class CMain
Intro. Prog. Orientada a Objeto Algoritmos Numricos Rodrigo Sandoval U.
IIC 1102 Pgina: 8
{
public static void Main()
{
double x,pres;

Console.Write("Ingrese el valor de x: ");
x = Double.Parse(Console.ReadLine());
Console.Write("Ingrese la presicion: ");
pres = Double.Parse(Console.ReadLine());

CNewton nw = new CNewton(pres);

Console.WriteLine("La respuesta es: {0}", nw.mGetAnswer(x));
Console.WriteLine("Para x: {0} con {1} iteraciones", x,nw.iter);
}
}

Ejemplo de ejecucin:

Ingrese el valor de X1: 10
Ingrese la precision para el calculo de x: 0.000001

Calculo de x con precision 1.000000e-006:

x = 3.213360870175253400000000000000000000000000000000
f(x) = 0.000000000000000000
Se emplearon 4 iteraciones.

PONTIFICIA UNIVERSIDAD CATLICA DE CHILE
ESCUELA DE INGENIERA
DEPARTAMENTO DE CIENCIA DE LA COMPUTACIN
IIC 1102 INTRODUCCIN A LA PROGRAMACIN
Profesor: Rodrigo Sandoval U.

Captulo VII Arreglos y Enumeraciones en C#

1 ARREGLOS......................................................................................................................................................... 1
1.1 DECLARACIN DE ARREGLOS UNIDIMENSIONALES........................................................................................2
1.2 USO DE ARREGLOS UNIDIMENSIONALES.........................................................................................................3
1.2.1 Funciones ms comunes con arreglos.................................................................................................... 4
1.2.2 Foreach para el manejo de arreglos...................................................................................................... 5
1.2.3 Ejemplos de declaracin y uso de arreglos............................................................................................ 6
1.2.4 Ejemplo: Clculo de mnimo, mximo y promedio de una lista de notas de estudiantes....................... 7
1.2.5 Ejemplo: Programa de simulacin de conjuntos con arreglos .............................................................. 9
2 ARREGLOS MULTIDIMENSIONALES....................................................................................................... 13
2.1 DECLARACIN DE MATRICES........................................................................................................................13
2.2 USO DE MATRICES........................................................................................................................................14
2.2.1 Obteniendo Dimensiones de una Matriz .............................................................................................. 14
2.2.2 Ejemplos de uso de Matrices................................................................................................................ 14
2.2.3 Foreach en matrices............................................................................................................................. 14
2.2.4 Ejemplo: Clculo de las notas finales de un curso (mnimo, mximo, promedio) ............................... 15
2.2.5 Ejemplo: Multiplicacin de Matrices Cuadradas ................................................................................ 18
3 .......................................................................................................................................... 23 ENUMERACIONES


Material preparado por Rodrigo Sandoval U en Marzo 2004,
basado en los apuntes de clase del curso IIC1102, ao 2003, de M. Nussbaum, Marcos Seplveda, et.al

Intro. Prog. Orientada a Objeto Arreglos y Enumeraciones Rodrigo Sandoval U.
1 Arreglos
Los arreglos son estructuras de datos complejas (en el sentido de que no son atmicas) que agrupan
datos de un mismo tipo en particular, llamado el tipo base del arreglo. El tipo base de un arreglo puede
ser cualquiera de los tipos bsicos de C#, o incluso algunos tipos complejos como las clases.
Un arreglo es tambin ejemplo de un modelo. Un arreglo puede considerarse como ejemplo de una
variable compuesta capaz de almacenar uno o ms datos al mismo tiempo.

La sintaxis del lenguaje permite referirse a cada uno de los elementos que constituyen el arreglo
empleando ndices. Esto es posible pues los elementos del arreglo estn numerados en forma jerrquica
y consecutiva, empezando en 0 en cada dimensin.
El siguiente grfico ilustra un ejemplo de un arreglo llamado numeros, cuya posicin 0 almacena el valor
10, la posicin 1 el valor de 21, etc. Este arreglo en total almacena n+1 elementos. El valor de n, depende
de la memoria que pueda tener el computador y el tipo de elementos que se almacenen en el arreglo.

IIC 1102 Pgina: 1
Intro. Prog. Orientada a Objeto Arreglos y Enumeraciones Rodrigo Sandoval U.
Los arreglos, al igual que el resto de las variables se identifican con un nombre. Al emplear ese nombre,
se hace referencia a la estructura de datos como un todo, es decir, con todos sus elementos. El lenguaje
interpreta dicho nombre como un puntero. Cuando se utiliza el nombre del arreglo en forma indexada, es
decir, combinado con ndices, se hace referencia a un elemento particular, del tipo base, dentro de la
estructura compleja.
Importante: El lenguaje C#no controla la validez de los ndices que se emplean para referenciar un
arreglo. Esto quiere decir que es posible cometer errores graves y difciles de detectar en este sentido.
Ms adelante se presenta un ejemplo en este sentido.
1.1 Declaracin de Arreglos Unidimensionales
Los arreglos, al igual que las dems variables deben declararse antes de poder utilizarlas, y cumplen con
las mismas reglas de alcance y vida.
Los arreglos de una sola dimensin reciben tambin el nombre de vectores. La sintaxis de la declaracin
de un arreglo unidimensional es la siguiente:
<tipo-base>[] <identificador>;
Observaciones:
El <tipo-base> puede ser cualquiera de los tipos bsicos del lenguaje, o incluso algunos
complejos como estructuras.
El <identificador>es el nombre que distinguir el arreglo.
Los corchetes [] son obligatorios y denotan que el identificador descrito, del tipo-base indicado,
es un arreglo (lista de elementos del tipo base).
En esta declaracin NO se define el tamao que tendr el arreglo (aunque se puede determinar
las dimensiones, lo que se ver ms adelante).
El tamao del arreglo se determina en una segunda declaracin, que puede ir en la siguiente lnea, como
se muestra a continuacin.
<identificador> = new <tipo-base> [<NumElementos>]
En esta declaracin, se dimensiona el arreglo con una cantidad determinada de elementos, todos
correspondientes a tipo-base.

Es posible hacer la declaracin del arreglo y su dimensionamiento en una misma sentencia:
<tipo-base>[] <identificador> = new <tipo-base>[<NumElementos>]

Adicionalmente es factible declarar, dimensionar, e inicializar un arreglo con todos sus elementos, en una
sola declaracin:
<tipo-base>[] <identificador> = {valor1, valor2, ..., valorN};
Esta ltima declaracin implcitamente dimensiona el arreglo para almacenar los N elementos descritos,
por lo que no se requiere dimensionarlo aparte.
Es decir:
Con los valores indicados entre llaves {} se inicializarn los elementos del arreglo.
Los valores deben ser del <tipo-base>del arreglo.

IIC 1102 Pgina: 2
Intro. Prog. Orientada a Objeto Arreglos y Enumeraciones Rodrigo Sandoval U.
Tambin es factible declarar, dimensionar, e inicializar un arreglo con todos sus elementos, en una sola
declaracin, pero slo indicando un subconjunto de los valores que el arreglo puede guardar:
<tipo-base>[] <identificador> =
new <tipo-base>[N] {valor1, ..., valorM};
... donde M<N, y N debe ser una expresin constante, como por ejemplo 10. Es factible hacer una
declaracin donde M>N, en cuyo caso, el real dimensionamiento del arreglo se regir por M.
Algunos ejemplos:
// Arreglo para 10 enteros
int [] numeros;
numeros = new int[10];

// Arreglo para 10 enteros
int [] numeros = new int[10];

// Arreglo para 10 enteros
int [] numeros = { 1, 1, 1, 2, 3, 5, 2, 5, 3, 4 };

1.2 Uso de Arreglos Unidimensionales
Los elementos de un arreglo son variables del tipo base del vector, por lo que se utilizan de la misma
manera en expresiones y dems instrucciones, como la asignacin. Por ejemplo, para asignar un valor a
un elemento de un arreglo basta con escribir:
<arreglo>[indice] = <expresion>;
donde <arreglo> es el nombre de la variable e indice hace referencia a la posicin del elemento al que se
le quiere asignar el <expresion>. La referencia de valores en un arreglo, se indexa desde el 0 al N-1.
Importante: Puesto que los arreglos son estructuras complejas (es decir, no bsicas), no es posible
asignar un arreglo a otro mediante una simple asignacin (=). Para hacer esto es necesario escribir
un ciclo y asignar elemento a elemento.
Como se mencion anteriormente, el lenguaje C# no controla la validez de los ndices que se
emplean para referenciar un arreglo. Esto quiere decir que es posible cometer errores muy difciles de
detectar en este sentido. Es necesario prestar especial inters a los valores que toman los ndices para
evitar estos problemas.
Por ejemplo, la siguiente porcin de cdigo compila sin problemas (es decir, sin errores
sintcticos), pero probablemente produzca un error en tiempo de ejecucin al referenciarse
posiciones inexistentes del arreglo.

// Las posiciones con ndices del 10 al 19 son invlidas.
int[] arreglo = { 1,1,1,1,1,1,1,1,1,1 }; // 10 elementos
int i;
for (i=0; i<20; i++)
arreglo[i] = 0; // Error para i >= 10
IIC 1102 Pgina: 3
Intro. Prog. Orientada a Objeto Arreglos y Enumeraciones Rodrigo Sandoval U.
Tambin es comn cometer estos errores olvidando que las posiciones de los arreglos estn
numeradas a partir del ndice cero. Es decir, en un arreglo de tamao N las posiciones estn
numeradas de 0 a N-1.
1.2.1 Funciones ms comunes con arreglos
En C#, los arreglos se representan con un tipo especfico, y por ello cuentan con sus propios atributos y
mtodos especficos. Por ejemplo, para obtener el largo (la cantidad de elementos dimensionados) de un
arreglo, o para ordenarlo.
El Largo de un Arreglo
En el caso de los arreglos unidimensionales, el tamao o cantidad de elementos se obtiene con la
propiedad Length.
int [] numeros = { 1,2,3,4,5,6 }
Console.WriteLine(Largo: {0}, numeros.Length);

Ordenamiento de un Arreglo
En el caso de los arreglos que sean de uno de los tipos predefinidos (int, float, char, etc.), es factible
ordenarlos en forma creciente, aprovechando el mtodo bsico Sort() de la clase Array:
int [] numeros = { 4,5,2,3,1,6 }
Array.Sort(numeros); // 1,2,3,4,5,6

Revertir el Orden de un Arreglo
En el mismo caso en que se pueda ordenar un arreglo, se puede reordenar exactamente al revs de
cmo est, aprovechando el mtodo bsico Reverse() de la clase Array:
int [] numeros = { 1,2,3,4,5,6 }
Array.Reverse(numeros); // 6,5,4,3,2,1

Ejemplo de Manipulacin de Arreglos
using System;

class Arreglo {
int[] numeros;

public Arreglo(int [] arreglo) {
numeros = new int[arreglo.Length];
for (int i=0; i<numeros.Length; i++)
numeros[i] = arreglo[i];
}

public void Ordenar() { Array.Sort(numeros); }

public void Reordenar() { Array.Reverse(numeros); }

public void Imprimir() {
foreach(int i in numeros)
Console.Write("{0} ",i);
Console.WriteLine();
}
IIC 1102 Pgina: 4
Intro. Prog. Orientada a Objeto Arreglos y Enumeraciones Rodrigo Sandoval U.

}

class MainApp {

static void Main() {
int[] numeros = { 2,5,6,1,3,4 };
Arreglo a = new Arreglo(numeros);

a.Imprimir();
a.Ordenar();
a.Imprimir();
a.Reordenar();
a.Imprimir();
Console.ReadLine();
}
}

1.2.2 Foreach para el manejo de arreglos
Existe esta sentencia de control de flujo, especialmente diseada para este tipo de estructuras, donde se
manejan listas de elementos, todos del mismo tipo. Foreach depende de la definicin previa de un arreglo
de elementos del mismo tipo, los cuales puede recorrer individualmente sin conocer el tamao
explcitamente (como se requiere en otras instrucciones, por ejemplo en el for).
La sintaxis de uso es:
foreach ( <tipo> <variable> in <arreglo> ) {
<instrucciones>
}
Donde:
<tipo>es el tipo bsico de los elementos contenidos en el arreglo.
<arreglo>es el arreglo de elementos a revisar.
<variable> es un identificador de una variable local del foreach() que se usar para ver un
elemento del arreglo en cada iteracin.

Ejemplo:
using System;
class MainClass {

public static void Main() {
int impares = 0, pares = 0;
int[] arr = new int [] {0,1,2,5,7,8,11};

foreach (int i in arr) {
if (i%2 == 0)
pares++;
else
impares++;
}
Console.WriteLine("Hay {0} impares y {1} pares.", impares, pares);
IIC 1102 Pgina: 5
Intro. Prog. Orientada a Objeto Arreglos y Enumeraciones Rodrigo Sandoval U.
Console.ReadLine();
}
}
A continuacin se incluyen ejemplos, tanto de declaracin y uso de arreglos, como del uso de foreach.
1.2.3 Ejemplos de declaracin y uso de arreglos
En todos los casos, A es el nombre de la variable declarada:
1. Declaracin de un arreglo de 50 enteros:
int[] A = new int[50];

2. Declaracin de un arreglo de 100 caracteres:
char[] A = new char[100];

3. Declaracin e inicializacin de un arreglo de 10 enteros:
int[] A = { 2, 5, 8, 100, 1, 2, 100, 5, 5, 5 }

4. Inicializacin parcial: El resto se inicializa e
int[] A = new int[100] { 25, 5, 100, 25, 5 }
n cero:

5. Declaracin e inicializacin de un arreglo de 10 caracteres:
char[] A = { 'a', 'z', 'E', 'e', 65, '\65', '@', 'U', '*', '\n' }

6. Asignando un va
A[5] = 200;
lor a la sexta posicin de un arreglo de enteros:

7. Imprimiend
int i;
o un arreglo de 100 enteros mediante un ciclo for:
for (i=0; i<100; i++)
Console.Write("{0} ", A[i]);

8. Imprimiendo un arreglo de 100 enteros mediante un ciclo foreach:

Console.Write("{0} ", i);
foreach (int i in A)

9. Leyendo del usuario el contenido de un arreglo de 20 enteros,
mediante un ciclo for:
int i;
for (i=0; i<20; i++)
A[i] = int.Parse(Console.ReadLine());

10. Una funcin que recibe un arreglo de enteros como argumento
y calcula el promedio:
int promedio(int[] A) {
int prom = 0;
foreach( int i in A )
prom = prom + i;
return(prom/A.Length);
}

11. Llamando una funcin que recibe un arreglo de enteros como
parmetro:
int prom; int[] A;
...
prom = promedio(A);
IIC 1102 Pgina: 6
Intro. Prog. Orientada a Objeto Arreglos y Enumeraciones Rodrigo Sandoval U.
1.2.4 Ejemplo: Clculo de mnimo, mximo y promedio de una lista de notas de
estudiantes
Se desea calcular el promedio, mnimo y mximo de una lista de notas correspondientes a un curso. Se
recibir el nmero de alumnos y la nota correspondiente a c/u, y se entregan los resultados en la pantalla.
1. Definicin del problema
1.1 Conceptualizacin: El problema consiste en calcular el promedio, mnimo y mximo de una lista
de notas de un curso. Cada alumno tiene una nota en el curso. Se supone que el usuario conoce a
priori la cantidad de alumnos del curso y que entregar los datos en forma correcta.
1.2 Objetivo: El objetivo es obtener el promedio, el mximo, y el mnimo de las notas del curso.
1.3 Elementos involucrados: Los nicos elementos involucrados son las notas, la cantidad de
alumnos, el promedio, el mnimo y el mximo. Como elemento activo, el usuario que conoce las notas
en detalle.
2. Conceptualizacin de la solucin
2.1 Entidades: El Curso es la nica entidad relevante, la cual se conceptualiza como la agrupacin
de notas correspondientes a los alumnos.
2.2 Clases: La clase Curso, ser la representacin de las notas de un curso cuyo promedio se quiere
calcular. Esta clase se compone de los siguientes:
Atributos de la Clase Curso
notas: un arreglo que almacenar todas las notas (en forma de nmero real, con decimales)
promedio (PROM): el valor resultante del promedio de notas del curso
minimo (MIN): el valor de la mnima de todas las notas del curso
maximo (MAX): el valor de la mnima de todas las notas del curso
Mtodos de la Clase Curso
Curso: (constructor) obtiene los valores de todas las notas ingresadas por el usuario. El algoritmo
de este mtodo es:
1. Obtener la cantidad de alumnos: N
2. Iterar para cada uno de los N alumnos
2.1 Obtener la nota del alumno
Calcular: recorre la lista de notas, calculando el mnimo, el mximo y el promedio de estos
valores. El algoritmo de este mtodo es:
0. Se declara una variable local: SUMA
1. Inicialmente la suma de notas, SUMA, es 0, el mximo, MAX, es 1, y el mnimo, MIN, es 7
2. Iterar para cada para cada uno de los N alumnos
2.1 Agregar a SUMA la nota del alumno
2.2 Si la nota del alumno es mayor que MAX
2.2.1 MAX es ahora la nota del alumno
2.3 Si la nota del alumno es menor que MIN
2.3.1 MIN es ahora la nota del alumno
3. El promedio, PROM es SUMA dividido por N
Mostrar: muestra en pantalla los valores de promedio, mnimo y mximo
IIC 1102 Pgina: 7
Intro. Prog. Orientada a Objeto Arreglos y Enumeraciones Rodrigo Sandoval U.

2. 3 Instancias:
La nica instancia requerida es notas1, de la clase Curso.

3. Especificacin del Algoritmo
Algoritmo:
1. Declarar instancia de curso
2. Obtener las notas para el curso
3. Calcular el promedio, mnimo y mximo
4. Mostrar los resultados
4. Validacin
Es importante analizar casos extremos en los que el usuario pueda ingresar valores poco usuales. Por
ejemplo, si la cantidad de alumnos es cero o si es muy grande. Esto es particularmente importante para
validar el programa en C#. Por lo tanto, deben definirse dominios de validacin que representan estas
situaciones.
Adems, deben considerarse dominios que incluyan distintos valores para las notas. Por ejemplo, varias
notas distintas y repetidas, todas las notas iguales, etc. Tambin debe definirse un dominio en el que el
nmero de estudiantes es uno, pues podra presentar algn problema.
5. Limitaciones
Las limitaciones de este algoritmo se presentan principalmente en su implementacin en el lenguaje de
programacin C#. Dado que se va a utilizar un arreglo para almacenar las distintas notas, el mximo
nmero de notas que podrn ingresarse estar limitado por la dimensin mxima factible de almacenar
en un arreglo, aunque dado el caso de C#y el contexto, se asumo que la cantidad de notas difcilmente
ser tan grande.
Por otra parte, no se planean controles de validez sobre los nmeros que ingresa el usuario, de modo
que se supone que se ingresarn valores correctos, en el rango de 1 a 7. De no ser as, el
comportamiento del programa no est definido (es decir, puede pasar cualquier cosa).
Tambin se supone que el nmero de alumnos es mayor que cero, o el comportamiento del programa no
est definido. Por ejemplo, si se ingresa como nmero de alumnos un cero, esto producir una divisin
por cero al calcular el promedio.

////////////////////////////////////////////////////////////////
// Programa que lee del usuario una lista de notas correspondientes a los
// alumnos de un curso, y calcula el promedio, mnimo y mximo. Se ilustra
// el uso de arreglos para el almacenamiento de la informacin de entrada.
// Este programa podra reescribirse sin el uso de arreglos: Como?
////////////////////////////////////////////////////////////////
using System;

class Curso {

const float MAX_NOTA = 7.0F; // Las expresiones tipo float requieren una F al final
const float MIN_NOTA = 1.0F;

float[] notas;
float promedio;
float minimo;
float maximo;

public Curso() {
int n;
Console.Write("Ingrese el nmero de alumnos en la seccin: ");
n = int.Parse(Console.ReadLine());

IIC 1102 Pgina: 8
Intro. Prog. Orientada a Objeto Arreglos y Enumeraciones Rodrigo Sandoval U.
notas = new float[n];

for(int i=1; i<=n; i++) {
Console.Write("Ingrese la nota {0}: ", i);
notas[i-1] = float.Parse(Console.ReadLine());
}
}

public void Calcular() {
float suma = 0;

minimo = MAX_NOTA;
maximo = MIN_NOTA;

foreach( float nota in notas ) {
if (minimo>nota) minimo = nota;
if (maximo<nota) maximo = nota;
suma += nota;
}
promedio = suma / notas.Length;
}

public void Mostrar() {
Console.WriteLine("Promedio de las {0} notas = {1}", notas.Length, promedio);
Console.WriteLine("Mnimo de las {0} notas = {1}", notas.Length, minimo);
Console.WriteLine("Mximo de las {0} notas = {1}", notas.Length, maximo);
}
}

class MainApp {

static void Main() {
Curso c = new Curso();
c.Calcular();
c.Mostrar();
Console.ReadLine();
}
}

Ejemplo de ejecucin:
Ingrese el nmero de alumnos en la seccin: 5
Ingrese la nota 1: 5,6
Ingrese la nota 2: 5,8
Ingrese la nota 3: 6,2
Ingrese la nota 4: 4,6
Ingrese la nota 5: 5,1
Promedio de las 5 notas = 5,46
Mnimo de las 5 notas = 4,6
Mximo de las 5 notas = 6,2

1.2.5 Ejemplo: Programa de simulacin de conjuntos con arreglos
////////////////////////////////////////////////////////////////
// Programa de simulacin de operaciones sobre conjuntos de
// elementos del tipo entero, se pueden considerar todos los
// nmeros enteros positivos y negativos, excepto el 0
////////////////////////////////////////////////////////////////

using System;

class Conjunto {
IIC 1102 Pgina: 9
Intro. Prog. Orientada a Objeto Arreglos y Enumeraciones Rodrigo Sandoval U.
const int MAX_NUMS = 20;

int[] numeros;

// Constructor.
// Se considera que toda posicin del arreglo que tiene un
// 0, no es un elemento del conjunto entonces un arreglo de
// n posiciones con valores 0, es un conjunto vaco
public Conjunto () {
numeros = new int[MAX_NUMS];
Limpiar();
}

public int Elemento(int n) { return(numeros[n-1]); }

public void Limpiar() { for (int i=0; i<MAX_NUMS; i++) numeros[i] = 0; }

public void Cargar() {
int i = 0;

Console.WriteLine("CARGA DE DATOS (0 para terminar)");
do {
Console.WriteLine("Ingrese el elemento {0} del conjunto ",i+1);
Agregar(int.Parse(Console.ReadLine()));
i++;
} while(numeros[i-1]!=0 && i < numeros.Length);
}


// Se requiere la cantidad de elementos que son !=0
public int Largo() {
int largo = 0;

foreach (int n in numeros) {
if(n==0) break;
largo++;
}
return(largo);
}

// Verifica si el elemento a est en el conjunto
public bool Esta(int a) {
foreach(int n in numeros)
if(n == a) return (true);

return (false);
}


// Agrega el elemento si hay espacio y slo si no est
public void Agregar(int a) {
int posicion;
posicion = Largo();
if(!Esta(a) && posicion<numeros.Length) numeros[posicion] = a;
}

// Imprime en pantalla en formato ( ... )
public void Imprimir() {
Console.Write("{0} elementos: ( ", Largo());
foreach(int n in numeros)
if(n!=0) Console.Write("{0} ",n);
else break;
Console.WriteLine(")");
}

// Unin de conjuntos
// Se usan dos instancias de la clase como parmetros de este mtodo
// Este mtodo es de nivel superior a cada instancia, por lo que se
// declara "static" -> comn para todas las instancias de la clase Conjunto
public static Conjunto Union(Conjunto c1, Conjunto c2) {
Conjunto c = new Conjunto();
IIC 1102 Pgina: 10
Intro. Prog. Orientada a Objeto Arreglos y Enumeraciones Rodrigo Sandoval U.

// Primero se copian todos los elementos del conjunto 1
for(int i=0; i<c1.Largo(); i++)
c.Agregar(c1.Elemento(i+1));

// Segundo, se copian los del segundo conjunto que an no estn
for(int i=0; i<c2.Largo(); i++)
if (!c.Esta(c2.Elemento(i+1)))
c.Agregar(c2.Elemento(i+1));

return(c); // Se retorna el conjunto resultante
}

// Interseccin de Conjuntos
public static Conjunto Interseccion(Conjunto c1, Conjunto c2) {
Conjunto c = new Conjunto();

// Se copian todos los elementos del conjunto 1 que estn en c2
for(int i=0; i<c1.Largo(); i++)
if (c2.Esta(c1.Elemento(i+1)))
c.Agregar(c1.Elemento(i+1));

return(c); // Se retorna el conjunto resultante
}
}


class MainApp {

static void Main() {
Conjunto c1 = new Conjunto();
Conjunto c2 = new Conjunto();
Conjunto c3 = new Conjunto();
Conjunto c4 = new Conjunto();

// Se le agregan elementos al primer conjunto y se muestra
c1.Agregar(2); c1.Agregar(3); c1.Agregar(4);
c1.Imprimir();

Console.WriteLine("5 es elemento del conjunto 0? --> {0}", c1.Esta(5));
Console.WriteLine("Se ingresa 5 al conjunto c1");
c1.Agregar(5);
Console.WriteLine("5 es elemento del conjunto 0? --> {0}", c1.Esta(5));
c1.Imprimir();
Console.WriteLine("---------------------------");

Console.WriteLine("Ingrese elementos del conjunto 2");
c2.Cargar();
Console.WriteLine("---------------------------");

Console.WriteLine("Ingrese elementos del conjunto 3");
c3.Cargar();
Console.WriteLine("---------------------------");

Console.WriteLine("Conjunto 2: "); c2.Imprimir();
Console.WriteLine("Conjunto 3: "); c3.Imprimir();

Console.WriteLine("Conjunto2 U Conjunto3");
c4 = Conjunto.Union(c2,c3);
c4.Imprimir();

Console.WriteLine("Conjunto2 Intersec. Conjunto3");
c4 = Conjunto.Interseccion(c2,c3);
c4.Imprimir();

Console.ReadLine();
}
}

IIC 1102 Pgina: 11
Intro. Prog. Orientada a Objeto Arreglos y Enumeraciones Rodrigo Sandoval U.
Ejemplo de ejecucin:
3 elementos: ( 2 3 4 )
5 es elemento del conjunto 0? --> False
Se ingresa 5 al conjunto c1
5 es elemento del conjunto 0? --> True
4 elementos: ( 2 3 4 5 )
---------------------------
Ingrese elementos del conjunto 2
CARGA DE DATOS (0 para terminar)
Ingrese el elemento 1 del conjunto
1
Ingrese el elemento 2 del conjunto
2
Ingrese el elemento 3 del conjunto
3
Ingrese el elemento 4 del conjunto
4
Ingrese el elemento 5 del conjunto
0
---------------------------
Ingrese elementos del conjunto 3
CARGA DE DATOS (0 para terminar)
Ingrese el elemento 1 del conjunto
2
Ingrese el elemento 2 del conjunto
4
Ingrese el elemento 3 del conjunto
6
Ingrese el elemento 4 del conjunto
8
Ingrese el elemento 5 del conjunto
0
---------------------------
Conjunto 2:
4 elementos: ( 1 2 3 4 )
Conjunto 3:
4 elementos: ( 2 4 6 8 )
Conjunto2 U Conjunto3
6 elementos: ( 1 2 3 4 6 8 )
Conjunto2 Intersec. Conjunto3
2 elementos: ( 2 4 )

IIC 1102 Pgina: 12
Intro. Prog. Orientada a Objeto Arreglos y Enumeraciones Rodrigo Sandoval U.
2 Arreglos Multidimensionales
Los arreglos que se estudiaron anteriormente son estructuras de datos vectoriales de una sola dimensin.
En C#tambin es posible manejar arreglos de ms de una dimensin. Particularmente en este lenguaje,
existen dos maneras de declarar arreglos multidimensionales, por un lado aquellos en que todas las
dimensiones son fijas, tambin conocidos como matrices, y en segundo lugar, los que tienen filas (o
columnas) de largo distinto. En forma rigurosa, estos ltimos arreglos no son ms que arreglos en los que
cada elemento es a la vez otro arreglo, que puede ser de diferente dimensin que su vecino.
Los arreglos de dos dimensiones reciben el nombre de matrices. Gran parte del desarrollo de esta
seccin se limita a las matrices, es decir, a arreglos de dos dimensiones, de filas del mismo tamao. Sin
embargo, tanto la sintaxis para la declaracin como la forma de utilizar estos arreglos puede
generalizarse sin problema a dimensiones mayores (3D, 4D, etc).
Para referirse a cada uno de los elementos que constituyen el arreglo es necesario emplear una serie de
ndices. En el caso de las matrices, dos. Esto es posible pues los elementos de la matriz, al igual que en
el caso de los vectores unidimensionales, estn numerados en forma jerrquica consecutiva, empezando
en 0,0. Cada par de ndices referencia tanto una fila, como una columna de la matriz, identificando de
manera nica cada elemento de la estructura.
2.1 Declaracin de Matrices
Como se mencion anteriormente, las matrices no son ms que arreglos en los que cada elemento es a
su vez otro arreglo. La sintaxis de la declaracin de una matriz es la siguiente:
<tipo-base>[,] <identificador>;
Observaciones:
El <tipo-base> puede ser cualquiera de los tipos bsicos del lenguaje, o incluso algunos
complejos como estructuras. Cada elemento de la matriz ser del tipo definido aqu.
El <identificador> es el nombre que distinguir la matriz.
Los corchetes [] son obligatorios.
El separador de dimensiones es la coma ,.
El dimensionamiento de estas matrices se puede hacer en una declaracin separada, de la siguiente
manera:
<identificador> = <tipo-base>[NumElem1, NumElem2];
El trmino <NumElem1> determina el tamao de la primera dimensin de la matriz, es decir, la
cantidad de filas que tendr. Los elementos de la segunda dimensin (columnas) estn
numerados en forma consecutiva, empezando en 0. El trmino <NumElem2> determina el
tamao de la segunda dimensin de la matriz, es decir, la cantidad de elementos del tipo base
que contendr. Dichos elementos estarn numerados en forma consecutiva, empezando en 0.
Al igual que en el caso de arreglos unidimensionales, es posible declarar una matriz y al mismo tiempo
inicializar sus elementos con valores del tipo base. La sintaxis para hacer esto es la siguiente:
<tipo-base>[M,N] identif = { { valor1-1, valor1-2, ..., valor1-N },
{ valor2-1, valor2-2, ..., valor2-N },
...,
{ valorM-1, valorM-2, ..., valorM-N }
};
Con los valores indicados entre llaves {} se inicializarn los MxN elementos de la matriz.
Los valores deben ser del <tipo-base> de la matriz.
IIC 1102 Pgina: 13
Intro. Prog. Orientada a Objeto Arreglos y Enumeraciones Rodrigo Sandoval U.
2.2 Uso de Matrices
Los elementos de una matriz se pueden entender como un casillero o una celda, determinada por fila y
columna. Para asignar un valor a un elemento de una matriz basta con escribir:
matriz[indice1,indice2] = valor;
en donde matriz es el nombre de la variable y las expresiones indice1 e indice2 hacen referencia a la
posicin del elemento al que se le quiere asignar el valor.
El nombre de una matriz tambin puede emplearse sin ndice, bajo ciertas circunstancias, por ejemplo,
para pasar la matriz completa como argumento a una funcin.
2.2.1 Obteniendo Dimensiones de una Matriz
Al igual que en las matrices unidimensionales, el largo de la fila o columna de una matriz se puede
obtener, en este caso con el mtodo GetLength(dimension), donde dimension se refiere a filas, columnas,
etc. En el caso de una matriz bidimensional, el largo de las filas se ve con GetLength(0), y de las
columnas, con GetLength(1).
2.2.2 Ejemplos de uso de Matrices
En todos los casos, matriz es el nombre de la variable declarada:
1. Declaracin de una matriz de 50 filas de 20 enteros:
int[,] matriz = new int[50,20];

2. Declaracin e inicializacin de una matriz:
int[,] matriz = { { 2, 5, 8 }, { 9, 1, 2 } }; // 2 filas, 3 col.

3. Asignando un valor a la primera posicin de la segunda
fila de una matriz de enteros:
matriz[1,0] = 50;

4. Imprimiendo una matriz de 100x50 enteros mediante un ciclo for:
int i, j;
for (i=0; i<100; i++) {
for (j=0; j<50; j++)
Console.Write("{0} ", matriz[i,j]);
Console.WriteLine();
}

5. Imprimiendo una matriz de NxN enteros mediante un ciclo for:
int i, j;
for (i=0; i<matriz.GetLength(0); i++) {
for (j=0; j< matriz.GetLength(1); j++)
Console.Write("{0} ", matriz[i,j]);
Console.WriteLine();
}
2.2.3 Foreach en matrices
En forma similar al caso de los arreglos unidimensionales, es posible utilizar foreach() para recorrer los
elementos de las celdas de una matriz. Sin embargo, foreach() hace un recorrido exhaustivo sin explicitar
cuando se cambia de fila o de columna. Es decir, en este caso sirve para recorrer todo el contenido de
una matriz, sin tener conocimiento explcito de las respectivas posiciones de las celdas.
IIC 1102 Pgina: 14
Intro. Prog. Orientada a Objeto Arreglos y Enumeraciones Rodrigo Sandoval U.
2.2.4 Ejemplo: Clculo de las notas finales de un curso (mnimo, mximo, promedio)
Se desea calcular las notas finales de los alumnos de un curso, as como tambin el promedio, mnimo y
mximo de stas. Se recibir el nmero de alumnos y las notas parciales de cada uno de stos. Las
notas parciales corresponden a la I1, I2, T1, T2 y Exmen. La nota final se calcula empleando la frmula:
NF =0.7*NP +0.3*Ex
en donde NP es la nota de presentacin calculada como:
NP =(I1+I2+T1+T2)/4

1. Definicin del problema
Conceptualizacin: El problema consiste en calcular la nota final obtenida por cada uno de los
alumnos de un curso, y el promedio, mnimo y mximo de estas notas finales. El clculo de la nota
final es una funcin de las notas parciales que obtuvo durante el semestre. Se supone que cada
alumno tiene todas y cada una de las notas parciales definidas, que el usuario conoce a priori la
cantidad de alumnos del curso y que entregar los datos en forma correcta.
Objetivo: El objetivo es obtener la nota final de cada alumno, junto con el promedio, el mximo, y el
mnimo de stas.
Elementos involucrados: Los elementos involucrados son la cantidad de alumnos, las notas
parciales y la nota final de cada alumno, y por ltimo el promedio, el mnimo y el mximo de las notas
finales.
2. Conceptualizacin de la solucin
2.1 Entidades: El Curso es la nica entidad relevante, la cual se conceptualiza como la agrupacin
de notas correspondientes a los alumnos.
2.2 Clases: La clase Curso, ser la representacin de las notas de un curso cuyo promedio se quiere
calcular. Esta clase se compone de los siguientes:
Atributos de la Clase Curso
notas: una matriz que almacenar todas las notas parciales (en forma de nmero real, con
decimales).
promedio (PROM): el valor resultante del promedio de notas del curso
minimo (MIN): el valor de la mnima de todas las notas del curso
maximo (MAX): el valor de la mnima de todas las notas del curso
Mtodos de la Clase Curso
Curso: (constructor) obtiene los valores de todas las notas parciales ingresadas por el usuario. El
algoritmo de este mtodo es:
1. Obtener la cantidad de alumnos: N
2. Iterar para cada uno de los N alumnos
2.1 Iterar para cada nota parcial del alumno
2.1.1 Obtener la nota parcial del alumno
2.2 Calcular la Nota P del Alumno
2.3 Calcular la Nota Final del Alumno y agregarlo a la matriz
Calcular: recorre la lista de notas, calculando el mnimo, el mximo y el promedio de estos
valores. El algoritmo de este mtodo es:
IIC 1102 Pgina: 15
Intro. Prog. Orientada a Objeto Arreglos y Enumeraciones Rodrigo Sandoval U.
0. Se declara una variable local: SUMA
1. Inicialmente la suma de notas, SUMA, es 0, el mximo, MAX, es 1, y el mnimo, MIN, es 7
2. Iterar para cada para cada uno de los N alumnos
2.1 Agregar a SUMA la nota FINAL del alumno
2.2 Si la nota FINAL del alumno es mayor que MAX
2.2.1 MAX es ahora la nota FINAL del alumno
2.3 Si la nota FINAL del alumno es menor que MIN
2.3.1 MIN es ahora la nota FINAL del alumno
3. El promedio, PROM es SUMA dividido por N
Mostrar: muestra en pantalla las notas finales y los valores de promedio, mnimo y mximo

2. 3 Instancias:
La nica instancia requerida es notas1, de la clase Curso.

3. Especificacin del Algoritmo
Algoritmo:
1. Declarar instancia de curso
2. Obtener las notas para el curso
3. Calcular el promedio, mnimo y mximo
4. Mostrar los resultados

Cdigo de la Solucin
////////////////////////////////////////////////////////////////
// Programa que lee del usuario una lista de notas parciales correspondientes a los alumnos
// de un curso, y calcula la nota final de cada alumno, y el promedio, mnimo y mximo.
// Se ilustra el uso de arreglos 2D (matrices) para el almacenamiento de la info. de entrada.
////////////////////////////////////////////////////////////////using System;

class Curso {
const float MAX_NOTA = 7.0F; // Las expresiones tipo float requieren una F al final
const float MIN_NOTA = 1.0F;

float[,] notas;
float promedio;
float minimo;
float maximo;

public Curso() {
int n;
float notap;
Console.Write("Ingrese el nmero de alumnos en la seccin: ");
n = int.Parse(Console.ReadLine());
notas = new float[n,6]; // 6 notas (5 parciales y 1 final) de n alumnos

for(int i=1; i<=n; i++) {
Console.WriteLine("Alumno N {0}", i);
for(int j=1; j<=5; j++) { // Slo se asignan 5 notas parciales
Console.Write("Ingrese la nota {0}: ", j);
notas[i-1,j-1] = float.Parse(Console.ReadLine());
}
// Nota P, con las primeras 4 notas
notap = (notas[i-1,0]+notas[i-1,1]+notas[i-1,2]+notas[i-1,3]) / 4.0F;
// Nota final: 0.7*NotaP + 0.3*Examen (la 5a)
IIC 1102 Pgina: 16
Intro. Prog. Orientada a Objeto Arreglos y Enumeraciones Rodrigo Sandoval U.
notas[i-1,5] = 0.7F*notap + 0.3F*notas[i-1,4];
}
}

public void Calcular() {
float suma = 0;

minimo = MAX_NOTA;
maximo = MIN_NOTA;

for(int i=0; i<notas.GetLength(0); i++) {
if (minimo>notas[i,5]) minimo = notas[i,5];
if (maximo<notas[i,5]) maximo = notas[i,5];
suma += notas[i,5];
}
promedio = suma / notas.GetLength(0);
}

public void Mostrar() {
Console.WriteLine("Notas Finales:");
for(int i=0; i<notas.GetLength(0); i++)
Console.Write("{0:F1} ",notas[i,5]);
Console.WriteLine("Promedio de las {0} notas = {1}", notas.GetLength(0), promedio);

Console.WriteLine("Mnimo de las {0} notas = {1}", notas.GetLength(0), minimo);

Console.WriteLine("Mximo de las {0} notas = {1}", notas.GetLength(0), maximo);
}
}

class MainApp {

static void Main() {
Curso c = new Curso();
c.Calcular();
c.Mostrar();
Console.ReadLine();
}
}

Ejemplo de ejecucin:

Ingrese el nmero de alumnos en la seccin: 3
Alumno N 1
Ingrese la nota 1: 4,3
Ingrese la nota 2: 4,4
Ingrese la nota 3: 4,5
Ingrese la nota 4: 5,2
Ingrese la nota 5: 5,6
Alumno N 2
Ingrese la nota 1: 5,4
Ingrese la nota 2: 6,2
Ingrese la nota 3: 5,8
Ingrese la nota 4: 5,5
Ingrese la nota 5: 5,7
Alumno N 3
Ingrese la nota 1: 3,4
Ingrese la nota 2: 6,2
Ingrese la nota 3: 5,6
Ingrese la nota 4: 4,5
Ingrese la nota 5: 6,0
Notas Finales:
4,9 5,7 5,2 Promedio de las 3 notas = 5,288333
Mnimo de las 3 notas = 4,9
Mximo de las 3 notas = 5,7175
IIC 1102 Pgina: 17
Intro. Prog. Orientada a Objeto Arreglos y Enumeraciones Rodrigo Sandoval U.
2.2 ces Cuadradas
Se desea realizar la multiplicacin AxB de dos matrices cuadradas A y B, utilizando el algoritmo que se
uiente forma:
.5 Ejemplo: Multiplicacin de Matri
presenta en el siguiente diagrama.
Dadas dos matrices A, de dimensin MxP, y B, de dimensin PxN, la matriz multiplicacin C, de
dimensin MxN, se calcula de la sig

IIC 1102 Pgina: 18
Intro. Prog. Orientada a Objeto Arreglos y Enumeraciones Rodrigo Sandoval U.
1. Definicin del problema
Conceptualizacin: El problema consiste en calcular la multiplicacin de 2 matrices cuadrada
igual dimensin. El usuario debe entregar la dimensin y los valores de cada uno de los elem
las matrices a multiplicar (nmeros enteros).
Objetivo: El objetivo es obtener una matriz resultante de multiplicar las dos matrices entregadas.
Elementos involucrados: Los elementos involucrados son la dimensin de las matrice
matrices a multiplicar y la matriz con el resultado.
2. Conceptualizacin de la solucin
Entidades: la nica entidad relevante es Matriz, que representa precisamente una matriz de NxN
Clases: para representar esta nica entidad, la clase Matriz ser la encargada de expone
informacin y funcionalidad para distinguir una matriz de otra, as como los mtodos para opera
ellas, en particular el mtodo de multiplicacin entre matrices.
Atributos: la estructura para manejar los datos de la matriz: datos.
Mtodos:
- Matriz(n): Constructor. Inicializa la dimensin de la matriz (n).
- Cargar():se le preguntan los datos al usuario
Obtener la dimensin de la matriz
Inicializacin de la estructura datos.
Obtener los valores de los elementos de las matrices
1. Iterar la fila i de la matriz por todos sus posibles valores
1.1. Iterar la columna j de la matriz por todos sus posibles valores
1.1.1. Obtener el elemento ( i , j ) de la matriz
- Multiplicar(Matriz A, Matriz B): se calcula la multiplicacin de dos matrices A y B
1. Iterar sobre cada fila i de la matriz resultado C
1.1. Iterar sobre cada columna j de la fila i
1.1.1. Obtener el valor del elemento C ( i , j ) del resultado
1.1.1.1. Inicialmente C ( i , j ) es 0 (acumulador)
1.1.1.2. Iterar k desde 1 hasta la dimensin de las matrices
Agregar a C ( i , j ) el valor A ( i , k ) * B ( k , j )
- Mostrar(): muestra la matriz en pantalla
Instancias:
A: Primera de las matrices a multiplicar
B: Segunda de las matrices a multiplicar
C: Matriz resultado (AxB)
s de
entos de
s, las
r la
r con
3. Especificacin del Algoritmo
Declarar instancia Matriz A y B
Cargar A y Cargar B
Declarar instancia Matriz C
C = A x B
Mostrar C en pantalla
IIC 1102 Pgina: 19
Intro. Prog. Orientada a Objeto Arreglos y Enumeraciones Rodrigo Sandoval U.
4. V
es extremas para la dimensin de las matrices, tal
o para comprometer la implementacin en C#(segn la
defi
Por
elem
las
cas ra presentar problemas.

5. Limitaciones
No se incluy uario como elementos de las
matrices e es correctos. De no ser as, el comportamiento
del program n pasar cualquier cosa). Tambin se supone que la
dimensin d mportamiento del programa no est definido.

Cdigo de a
/////////////////////////////////////////////////////////////////////////
alidacin
cion En primera instancia se debe considerar las situa
es el caso en que se defina como cero com
nicin de la matriz).
otra parte, otros dominios deben incluir distintos valores para la dimensin de las matrices y para los
entos dentro de las matrices. Algunos casos interesante de estudiar son aquellos en que alguna de
matrices (o ambas) son cero (todos sus elementos) o uno (la diagonal). Tambin debe estudiarse el
o en que la dimensin de las matrices es uno, lo cual es correcto pero pod
en controles de validez de los nmeros que ingresa el us
, d modo que se supone que se ingresarn valor
a o est definido (es decir, puede
e las matrices es mayor que cero, o el co
l Solucin
// Programa que hace la multiplicacin AxB de dos matrices cuadradas A y B.
// El programa pide al usuario que ingrese la dimensin de las matrices, es
// decir, la longitud de los lados, as como los valores para las entradas de
// ambas at m rices (A y B), calcula la multiplicacin empleando un ciclo for
// con a da ni miento de tres niveles, y finalmente despliega el resultado de
// la multiplicacin A*B, el cual se almaceno en una tercera matriz: C.
/////////////////////////////////////////////////////////////////////////

using System;

class Matriz {
int[,] datos;

public Matriz(int n) {
datos = new int[n,n]; // Se crea la matriz del tamao indicado
}

l pub ic void Cargar() {
int i,j;
Console.WriteLine("\nIngrese los Valores para la matriz:");
for (i=0; i<datos.GetLength(0); i++) {
Console.WriteLine("Fila :", i); {0}
1); j++) { for (j=0; j<datos.GetLength(
Console.Write("\tCelda {0}: ", j);
datos[i,j] = int.Parse(Console.ReadLine());
}
}
}

int Tamano() { return(datos.GetLength(0)); }

car(Matriz A, Matriz B) { public static Matriz Multipli
A.Tamano()); Matriz m = new Matriz(

ciclo con anidamiento de 3 nivel realiza la multiplicacin // El siguiente
for (int i=0; i<m.Tamano(); i++) {
for (int j=0; j<m.Tamano(); j++) {
m.datos[i,j] = 0;
for (int k=0; k<m.Tamano(); k++)
m.datos[i,j] += (A.datos[i,k] * B.datos[k,j]);
}
}
return(m);
}
IIC 1102 Pgina: 20
Intro. Prog. Orientada a Objeto Arreglos y Enumeraciones Rodrigo Sandoval U.

// Mostrar(): muestra en pantalla (consola) la matriz.
public void Mostrar() {

Console.WriteLine("\n");
// Se imprime por filas completas hacia el lado
for (int i=0; i<datos.GetLength(0); i++) {
Console.Write("| "); // Se imprime un separador
for (int j=0; j<datos.GetLength(1); j++)
Console.Write("{0} ",datos[i,j]);
Console.WriteLine("|"); // Se imprime un separador
}
// Al final de recorrer la fila, se cambia de lnea
Console.WriteLine();
}
}

class MainApp {
static void Main() {
int N; // Dimension real de las matrices, dada por el usuario
Console.WriteLine("Multiplicacin de A(NxN) X B(NxN)");
Console.Write("Ingrese el valor de N (de 1 a 10): ");
N = int.Parse(Console.ReadLine());

Matriz A = new Matriz(N); // Se declaran e inicializan las dos matrices A y B
Matriz B = new Matriz(N);
A.Cargar(); B.Cargar();

Matriz C = Matriz.Multiplicar(A,B);
C.Mostrar();

Console.Write("Presione ENTER para terminar..."); Console.ReadLine();
}
}

Ejemplo de ejecucin:
Multiplicacin de A(NxN) X B(NxN)
Ingrese el valor de N (de 1 a 10): 3

Ingrese los Valores para la matriz:
Fila 0:
Celda 0: 1
a Celd 1: 2
Celda 2: 3
Fila 1:
Celda 0: 4
Celda 1: 5
Celda 2: 6
F : ila 2
Celda 0: 7
Celda 1: 8
Celda 2: 9

Ingrese los Valores para la matriz:
Fila 0:
Celda 0: 9
Celda 1: 8
Celda 2: 7
Fila 1:
Celda 0: 6
Celda 1: 5
Celda 2: 4
IIC 1102 Pgina: 21
Intro. Prog. Orientada a Objeto Arreglos y Enumeraciones Rodrigo Sandoval U.
Fila 2:
Celda 0: 3
Celda 1: 2
Celda 2: 1

| 30 24 18 |
| 84 69 54 |
| 138 114 90 |

IIC 1102 Pgina: 22
Intro. Prog. Orientada a Objeto Arreglos y Enumeraciones Rodrigo Sandoval U.
3 Enumeraciones
simplificada de arreglos, que se declaran con datos incluidos. Estos se utilizan
encialmente para listar opciones fijas para un programa. Por definicin, todos los elementos de las
raciones son de tipo entero.
En otras palabras, al declarar una enumeracin, se est definiendo un conjunto de valores aceptados,
dndole nombres ms entendibles, y como consecuencia, el compilador dar aviso cuando se intente
usar un valor no definido.
La sintaxis para la declaracin de una enumeracin es la siguiente:
enum <identificador> {
<nombre1> = <valorEntero1>,
<nombre2> = <valorEntero2>,
...
<nombreN> = <valorEnteroN>
}

Por ejemplo, una til enumeracin se puede definir al utilizar una clase con un atributo que slo puede
tomar los valores Femenino o Masculino.
Ejemplo:
public enum Sexo {
Existe una versin
es
enume
Femenino = 1,
Masculino = 2
}

class Persona {
string nombre;
int edad;
Sexo sexo;

Public void Mostrar() {
Console.WriteLine(Nombre: {0}, nombre);
Console.WriteLine(Edad: {0}, edad);
if ( sexo == Sexo.Masculino )
Console.WriteLine(Sexo: Masculino);
else
Console.WriteLine(Sexo: Femenino);
}
}

Entre los beneficios de utilizar enumeraciones se cuentan:
- Se hace ms fcil de mantener el cdigo, al permitir asegurar que las variables slo reciben
valores dentro de un rango definido, sin posibilidad de valores invlidos.
- Las enumeraciones hacen al cdigo ms legible y entendible, permitiendo referenciar
valores enteros con nombres ms descriptivos, en lugar de nmeros oscuros y mgicos.
IIC 1102 Pgina: 23
Material preparado por Rodrigo Sandoval U en Abril 2004

PONTIFICIA UNIVERSIDAD CATLICA DE CHILE
ESCUELA DE INGENIERA
DEPARTAMENTO DE CIENCIA DE LA COMPUTACIN
IIC 1102 INTRODUCCIN A LA PROGRAMACIN
Profesor: Rodrigo Sandoval U.

Captulo VIII Strings en C#


1 CADENAS DE TEXTO..............................................................................................................................................1
1.1 LA CLASE SYSTEM.STRING....................................................................................................................................1
1.1.1 Declaracin de un string...............................................................................................................................1
1.1.2 Operadores bsicos sobre un string..............................................................................................................1
1.1.3 Revisando los caracteres individuales de un string ......................................................................................2
1.1.4 Mtodos de la clase String ............................................................................................................................2
1.1.5 Ejemplo: Validacin de formato de un e-mail ..............................................................................................3
1.1.6 Ejemplo: Manejo de un Diccionario, incluyendo la bsqueda de palabras..................................................4
1.1.7 Ejemplo: Bsqueda y Reemplazo de Texto....................................................................................................7
1.2 TRANSFORMACIN DE OTROS TIPOS A STRING ......................................................................................................9
1.2.1 Transformacin con Formato .......................................................................................................................9


Intro. Prog. Orientada a Objeto Strings en C# Rodrigo Sandoval U.
IIC 1102 Pgina: 1
1 Cadenas de Texto
Los strings esencialmente son cadenas de texto, compuestas por uno o ms caracteres. Si bien no se
incluyen dentro de los tipos bsicos de C#, como son el int, el double, el char, efectivamente se reconoci su
enorme importancia al haberse incluido una clase String y su alias string en la base del lenguaje C#.
Internamente, un string, al ser una lista de caracteres, se puede equiparar con un arreglo de char, sin
embargo, dada su propia necesidad funcional, se han agregado diversos atributos y mtodos a la clase
String, para simplificar y potenciar su utilizacin, hasta cierto punto ocultando su real implementacin de
arreglo interna.
1.1 La clase System.String
La clase System.String, o simplemente String (cuando se incluy using System; en la primera lnea del
programa) es una clase especialmente diseada para almacenar cadenas de texto, en forma de una
secuencia de caracteres. Dada su importancia, una palabra reservada de C#corresponde a un alias para
esta clase, al igual que en el caso de in (Int), y otros. Esta palabra clave es simplemente string.
1.1.1 Declaracin de un string
string <identificador>;

string <identificador> = valor inicial;

Algunos ejemplos:
string nombre;
nombre = Juan Prez;

string nombre = Juan Prez;
1.1.2 Operadores bsicos sobre un string
Adicionalmente, algunos de los operadores ms recurridos dentro de las expresiones del lenguaje C#
tambin son vlidos para trabajar con strings, tal es el caso de la asignacin (=), la igualdad (==), y la suma
(+).
Ejemplos:
string nombre;
nombre = Juan;

nombre = nombre + Prez;

Console.WriteLine(nombre);

if( nombre == Juan Prez) Console.WriteLine(Es igual);


Intro. Prog. Orientada a Objeto Strings en C# Rodrigo Sandoval U.
IIC 1102 Pgina: 2
1.1.3 Revisando los caracteres individuales de un string
Considerando que los strings siguen siendo arreglos, es an factible utilizar la misma sintaxis para revisar los
caracteres (elementos) segn su indexacin. Esto se hace mediante la declaracin:
<identificador>[indice]
Ejemplo:
string nombre;
nombre = Juan;

nombre = nombre + Prez;

Console.WriteLine(Iniciales: {0}{1}, nombre[0],nombre[6]);

1.1.4 Mtodos de la clase String
Siendo String una clase derivada de Array, los mismos atributos y mtodos de sta (descritos en el captulo
anterior), son totalmente vlidos. Tal es el caso de Length (atributo), por ejemplo.
Especficamente, los mtodos principales de la clase String son los siguientes:
EndsWith Determina si el final de la instancia de String coincide con un substring dado.
Equals Determina si dos strings dados tienen el mismo valor.
Format Formatea un string conteniendo varios valores y especificadores acerca de cmo cada
valor debe ser formateado.
IndexOf Ubica la primera ocurrencia de un substring dado, en el string.
IndexOfAny Ubica la primera ocurrencia de cualquier carcter de un substring dado, en el string.
Insert Inserta un substring en una posicin especfico dentro del string.
LastIndexOf Igual que IndexOf, pero comenzando desde el final del string.
LastIndexOfAny Igual que IndexOfAny, pero comenzando desde el final del string.
Replace Reemplaza todos los caracter4es de un substring indicado, por otro tambin indicado.
Split Identifica los substrings en la instancia y los ordena por separado en un arreglo de
strings.
StartsWith Como EndsWith, pero revisando el comienzo del string.
Substring Entrega un substring de la instancia, comenzando en un ndice dado.
ToLower Convierte el string as minsculas.
ToUpper Convierte el string a maysculas.
Intro. Prog. Orientada a Objeto Strings en C# Rodrigo Sandoval U.
IIC 1102 Pgina: 3
Trim Elimina todos los espacios al comienzo y al final del string.
TrimEnd Elimina todos los espacios al final del string.
TrimStart Elimina todos los espacios al comienzo del string.
1.1.5 Ejemplo: Validacin de formato de un e-mail
/////////////////////////////////////////////////////////////////////////////////
// Validacin de direcciones e-mail. Las reglas de validacin son:
// - Que todos los caracteres sean vlidos.
// Slo letras, dgitos y los smbolos: _ - @ y el punto
// - Que tengan un nico smbolo @, ni ms ni menos
// - Que tengan al menos un punto a la derecha del @, pero pueden ser ms de uno
// - Que el lado izquierdo sea ms largo que 0.
// - Por ende, el largo mnimo de un e-mail es 6: x@x.xx
//
// En este ejemplo se ilustra el uso de los siguientes mtodos de la clase String:
// IndexOf(), LastIndexOf(), Substring(), ToLower(), Trim()
/////////////////////////////////////////////////////////////////////////////////

using System;


class Email {

public static bool Validar(string email) {
// string que contiene caracteres vlidos dentro de un e-mail
string caracteresvalidos = "abcdefghijklmnopqrstuvwxyz1234567890_-.@";

if(email.Length<6) return (false);

// Se valida sobre e-mail en minsculas y sin espacios antes y despus
email = email.ToLower().Trim();

// Verifica todos los caracteres
for (int i=0; i<email.Length; i++)
// Es un caracter no-vlido?
if( caracteresvalidos.IndexOf(email[i]) < 0 ) return(false);

// Cantidad de @
if( email.IndexOf('@') < 0 ) return (false); // No haba @
if( email.IndexOf('@') != email.LastIndexOf('@') )
return (false); // Hay ms de 1 @

// Cantidad de . a la derecha de @.
// Se busca un . slo en el substring a la derecha del @
if( email.Substring(email.IndexOf('@'),
email.Length-email.IndexOf('@')-1).IndexOf('.') < 0)
return(false);

// Que el @ no sea el primer smbolo
if( email.IndexOf('@') == 0 ) return (false);

return (true);
}
}



Intro. Prog. Orientada a Objeto Strings en C# Rodrigo Sandoval U.
IIC 1102 Pgina: 4
class MainApp {
static void Main() {
string email;

do {
Console.Write("Ingrese su e-mail: ");
email = Console.ReadLine();
} while( !Email.Validar(email) );

Console.Write("Gracias. Presione ENTER para terminar ...");
Console.ReadLine();
}
}

1.1.6 Ejemplo: Manejo de un Diccionario, incluyendo la bsqueda de palabras

/////////////////////////////////////////////////////////////////////////////////
// Ejemplo de manejo de un diccionario de palabras
// ===============================================
// Este ejemplo declara una clase Diccionario que maneja una lista de palabras
// (en este caso, nombres de animales). Luego, permitindole al usuario ingresar
// nombres o subpalabras a buscar, se filtran y se revisan las palabras del
// diccionario que comienzan con la palabra indicada, o terminan, o la contienen.
//
// En este ejemplo se ilustra el uso de los siguientes mtodos de la clase String:
// IndexOf(), StartsWith(), EndsWith(), Trim(), ToUpper(),
/////////////////////////////////////////////////////////////////////////////////

using System;

class Diccionario {

// Lista (arreglo): nombres de animales, ordenados alfabticamente.
string[] diccionario = {
"AGUILA", "ALBATROS", "ALCE", "ANACONDA", "ANGUILA", "ANTILOPE", "ARAA",
"BALLENA", "BISONTE", "BUFALO", "BUITRE",
"CABRA", "CABALLO", "CANGREJO", "CEBRA", "CIERVO", "CISNE", "COBRA",
"CONDOR", "CORMORAN",
"DELFIN", "DINGO",
"ELEFANTE", "EMU", "EQUIDNA", "ESCORPION", "ESTRELLA DE MAR", "ERIZO",
"FAISAN", "FLAMENCO", "FOCA",
"GACELA", "GARZA", "GATO", "GAVILAN", "GAVIOTA", "GORRION", "GOLONDRINA",
"GUEPARDO",
"HALCON", "HIENA", "HIPOPOTAMO", "HORMIGA", "HURON",
"IBIS", "IGUANA",
"JABALI", "JAGUAR", "JAIBA", "JIRAFA", "JOTE",
"LANGOSTA", "LEOPARDO", "LEON", "LEON MARINO", "LOBO", "LOCO",
"LUCIERNAGA",
"MANATI", "MERLUZA", "MONO", "MORSA", "MURCIELAGO",
"NARVAL", "NUTRIA",
"OSO", "OSO HORMIGUERO",
"PANTERA", "PATO", "PAVO", "PERRO", "PERDIZ", "PEREZOSO", "PINGUINO",
"PULPO",
"RATON", "RENO", "RINOCERONTE",
"SALTAMONTES", "SERPIENTE", "SIMIO",
"TAPIR", "TIBURON", "TIGRE", "TUCAN",
"VACA", "VENADO",
Intro. Prog. Orientada a Objeto Strings en C# Rodrigo Sandoval U.
IIC 1102 Pgina: 5
"ZORRO", "ZORRILLO" };


// BuscarInicio(palabra): Busca la palabra dada en todos los strings del diccionario
// viendo en cules de ellos se encuentra al comienzo
// Retorna: un arreglo de strings con las palabras del diccionario que coincidieron
public string[] BuscarInicio(string palabra) {
string[] resultado;
int cantidad = 0;
int[] posiciones = new int[diccionario.Length];
// Registrar posiciones que empiezan con el string indicado (palabra)
for(int i=0; i<diccionario.Length; i++)
if( diccionario[i].StartsWith(palabra) ) {
posiciones[cantidad] = i;
cantidad++;
}

// Se copian los strings correspondientes
resultado = new string[cantidad];
for(int i=0; i<cantidad; i++)
resultado[i] = diccionario[posiciones[i]];

return(resultado);
}

// BuscarFinal(palabra): Busca la palabra dada en todos los strings del diccionario
// viendo en cules de ellos se encuentra al final
// Retorna: un arreglo de strings con las palabras del diccionario que coincidieron
public string[] BuscarFinal(string palabra) {
string[] resultado;
int cantidad = 0;
int[] posiciones = new int[diccionario.Length];
// Registrar posiciones que terminan con el string indicado (palabra)
for(int i=0; i<diccionario.Length; i++)
if( diccionario[i].EndsWith(palabra) ) {
posiciones[cantidad] = i;
cantidad++;
}

// Se copian los strings correspondientes
resultado = new string[cantidad];
for(int i=0; i<cantidad; i++)
resultado[i] = diccionario[posiciones[i]];

return(resultado);
}

// BuscarInicio(palabra): Busca la palabra dada en todos los strings del diccionario
// viendo en cules de ellos se encuentra en cualquier parte
// Retorna: un arreglo de strings con las palabras del diccionario que coincidieron
public string[] Buscar(string palabra) {
string[] resultado;
int cantidad = 0;
int[] posiciones = new int[diccionario.Length];
// Registrar las posiciones que contienen el string indicado (palabra)
for(int i=0; i<diccionario.Length; i++)
if( diccionario[i].IndexOf(palabra)>=0 ) {
posiciones[cantidad] = i;
cantidad++;
}

// Se copian los strings correspondientes
resultado = new string[cantidad];
for(int i=0; i<cantidad; i++)
Intro. Prog. Orientada a Objeto Strings en C# Rodrigo Sandoval U.
IIC 1102 Pgina: 6
resultado[i] = diccionario[posiciones[i]];

return(resultado);
}
}


class MainApp {
static void Main() {
Diccionario d = new Diccionario();
string palabra;
string[] resultado;

Console.Write("Indique la palabra a buscar: ");
palabra = Console.ReadLine();
// El string ingresado por el usuario debe ser filtrado:
// Primero, eliminar todos los espacios blancos, al comienzo y al final
palabra = palabra.Trim();
Console.WriteLine("Buscando: \"{0}\"", palabra);
// Segundo, la palabra debe venir en maysculas
palabra = palabra.ToUpper();
Console.WriteLine("Buscando: \"{0}\"", palabra);

// Primero, los strings que comienzan con la palabra
Console.WriteLine("Los sig. strings comienzan con \"{0}\":",palabra);
resultado = d.BuscarInicio(palabra);
foreach(string s in resultado)
Console.WriteLine(s);

// Segundo, los strings que terminan con la palabra
Console.WriteLine("Los sig. strings terminan con \"{0}\":",palabra);
resultado = d.BuscarFinal(palabra);
foreach(string s in resultado)
Console.WriteLine(s);

// Tercero, los strings que contienen la palabra
Console.WriteLine("Los siguientes strings contienen \"{0}\":",palabra);
resultado = d.Buscar(palabra);
foreach(string s in resultado)
Console.WriteLine(s);

Console.ReadLine();
}
}

Ejemplos de Ejecucin
Indique la palabra a buscar: oso
Buscando: "oso"
Buscando: "OSO"
Los siguientes strings comienzan con "OSO":
OSO
OSO HORMIGUERO
Los siguientes strings terminan con "OSO":
OSO
PEREZOSO
Los siguientes strings contienen "OSO":
OSO
OSO HORMIGUERO
PEREZOSO
Intro. Prog. Orientada a Objeto Strings en C# Rodrigo Sandoval U.
IIC 1102 Pgina: 7

Indique la palabra a buscar: mo
Buscando: "mo"
Buscando: "MO"
Los siguientes strings comienzan con "MO":
MONO
MORSA
Los siguientes strings terminan con "MO":
HIPOPOTAMO
Los siguientes strings contienen "MO":
CORMORAN
HIPOPOTAMO
MONO
MORSA
SALTAMONTES

1.1.7 Ejemplo: Bsqueda y Reemplazo de Texto

/////////////////////////////////////////////////////////////////////////////////
// Implementacin de Find-Replace de los Editores de Texto
// =======================================================
// Entre las funcionalidades que ofrecen los editores de texto hoy en da se encuentra
// la bsqueda y reemplazo de una palabra por otra, todas las veces que sta aparezca
// en el texto.
// El siguiente programa implementa la bsqueda y reemplazo utilizando las funciones
// y conceptos de string, con las siguientes condiciones:
// * El contenido del texto se almacena en la clase Texto
// * Se incluye el mtodo BuscarReemplazar(str1,str2)
// donde el primer parmetro (str1) es el string a buscar y el segundo (str2)
// es el string por el cual reemplazar el string encontrado.
// * En la bsqueda se consideran idnticas las maysculas de las minsculas, es decir,
// "CASA" es totalmente equivalente a "Casa".
// * La bsqueda no considera palabras acotadas, es decir, al buscar "el",
// se considera que se encontr en "el", "ellos", "aquel".
// * Al encontrar la palabra buscada, se reemplaza el texto de ella por el texto indicado.
// Si el texto encontrado es parte de otra palabra, slo se reemplaza la porcin corresp.
// al texto encontrado. Es decir, si se busca "casa" y se reemplaza por "hogar",
// entonces la frase
// "El casamiento fue en la tarde", quedar como "El hogarmiento fue en la tarde".
// * Se considera ajustar el texto restante: si la palabra buscada tiene distinto
// largo que su reemplazo.
//
// En este ejemplo se ilustra el uso de los siguientes mtodos de la clase String:
// IndexOf(), Substring(), ToLower(), Insert(), Remove()
/////////////////////////////////////////////////////////////////////////////////

using System;

class Reemplazo {
public string texto = "En la casa del explorador, se encuentra todo tipo de cosas, " +
"incluyendo fotografas de recuerdo. " +
"Estos objetos son parte de la historia de este explorador, " +
"a travs de los aos y kilmetros que ha recorrido";


public void BuscarReemplazar(string str1, string str2) {
int posicion = 0; // Se comienza desde el primer caracter (-1+1 = 0)
int indice = 0;
string copiatexto;

Intro. Prog. Orientada a Objeto Strings en C# Rodrigo Sandoval U.
IIC 1102 Pgina: 8
do {
// Se busca la sig. posicin en que str1 est en el texto
indice = texto.Substring(posicion,texto.Length-posicion).IndexOf(str1);

// Si la posicin es vlida, se procesa el reemplazo
if ( indice >= 0 ) {
// Se eliminan los caracteres del str1
// de la posicin encontrada (pero en la original)
texto = texto.Remove(posicion+indice,str1.Length);
// Se inserta el nuevo string (str2) en la misma posicin
texto = texto.Insert(posicion+indice,str2);
posicion += indice;
}
} while(indice>=0);
}

public void BuscarReemplazarDirecto(string str1, string str2) {
str1 = str1.ToLower(); // El texto a buscar tambin se deja en minsculas.

texto = texto.Replace(str1,str2);
}

}


class MainApp {
static void Main() {
Reemplazo r = new Reemplazo();
string str1;
string str2;

Console.WriteLine("** Bsqueda-Reemplazo de texto **");
Console.WriteLine("\nTexto: \"{0}\"\n", r.texto);
Console.Write("Texto a buscar: "); str1 = Console.ReadLine().Trim();
Console.Write("Texto de reemplazo: "); str2 = Console.ReadLine().Trim();

// Se efecta el reemplazo y se muestra el resultado
r.BuscarReemplazar(str1,str2);
Console.WriteLine("\nTexto modificado: \"{0}\"\n", r.texto);

Console.ReadLine();
}
}

Ejemplos de Ejecucin
** Bsqueda-Reemplazo de texto **

Texto: "En la casa del explorador, se encuentra todo tipo de cosas, incluyendo
fotografas de recuerdo. Estos objetos son parte de la historia de este
explorador, a travs de los aos y kilmetros que ha recorrido"

Texto a buscar: la
Texto de reemplazo: lo

Texto modificado: "En lo casa del explorador, se encuentra todo tipo de cosas,
incluyendo fotografas de recuerdo. Estos objetos son parte de lo historia de
este explorador, a travs de los aos y kilmetros que ha recorrido"


Intro. Prog. Orientada a Objeto Strings en C# Rodrigo Sandoval U.
IIC 1102 Pgina: 9
1.2 Transformacin de otros Tipos a String
Es comn requerir que datos, que se almacenan en otro tipo de dato de origen, como podra ser un int, char,
float, double, quieran ser transformados a string. Las clases en C#, proveen naturalmente el mtodo
ToString(), que efectivamente transforma el dato correspondiente a un string, incluyendo funcionalidad de
formato.
Ejemplo:
// Transformacin bsica
int numero = 10;
string num = El nmero es + numero.ToString();

1.2.1 Transformacin con Formato
Al igual que al imprimir texto en pantalla (por medio de Console.Write() y WriteLine()), es posible transformar
tipos bsicos a strings, con un formato numrico predefinido. Para ello, el mtodo ToString() en los tipos
numricos bsicos (int, float, double, etc.), permite agregar como parmetro la cadena que indica el formato.
El parmetro es de la forma:
{formato}
Formato puede ser uno de los siguientes:
C o c, para formato monetario (tomado de la configuracin de Windows)
D o d, para nmeros enteros (decimales).
E o e, para nmeros en formato de exponente (ej: 1.234E+005)
F o f, para nmeros reales, con parte decimal
G o g, para formato general.
N o n, similar a F, pero con la separacin de miles.
P o p, porcentaje.
R o r, round-trip o viaje redondo, que se usa en nmeros reales. Garantiza que un valor numrico
convertido a string ser re-transformado de vuelta sin perder informacin.
X o x, nmero en formato hexadecimal (ej: 1A24C)

Ejemplo:
////////////////////////////////////////////////////////////////////////////////
// Transformacin de tipos bsicos a strings con formato. Uso de ToString()
/////////////////////////////////////////////////////////////////////////////////

using System;

class ValoresNumericos {

static void Main() {
int[] valores = new int[4];

Console.WriteLine("Proceso de cantidades monetarias");

for(int i=0; i<valores.Length; i++) {
Intro. Prog. Orientada a Objeto Strings en C# Rodrigo Sandoval U.
IIC 1102 Pgina: 10
Console.Write("Ingrese el monto {0}: ",i+1);
valores[i] = int.Parse(Console.ReadLine());
}

// Ntese que el formato moneda viene de la configuracin de Windows
Console.WriteLine("Los montos son: ");
foreach(int n in valores)
Console.Write("{0}, ", n.ToString("C")); // C: currency (moneda)


int contador=0;
foreach(int n in valores) // Cuenta montos sobre $100
if(n>100) contador++;

Console.WriteLine("De ellos, el {0} es mayor que {1:C}",
((float)contador/ valores.Length).ToString("P"),100);


Console.Write("Presione ENTER para terminar ..."); Console.ReadLine();
}
}

Ejemplos de Ejecucin
Proceso de cantidades monetarias
Ingrese el monto 1: 150
Ingrese el monto 2: 1200
Ingrese el monto 3: 23
Ingrese el monto 4: 33
Los montos son:
$ 150, $ 1.200, $ 23, $ 33, De ellos, el 50,00 % es mayor que $ 100
Presione ENTER para terminar ...


Material preparado por Rodrigo Sandoval U en Mayo 2004

PONTIFICIA UNIVERSIDAD CATLICA DE CHILE
ESCUELA DE INGENIERA
DEPARTAMENTO DE CIENCIA DE LA COMPUTACIN
IIC 1102 INTRODUCCIN A LA PROGRAMACIN
Profesor: Rodrigo Sandoval U.

Captulo IX Archivos en C# y Bases de Datos


1 LECTURA Y ESCRITURA DE ARCHIVOS DE TEXTO.....................................................................................1
1.1 STREAMS ...............................................................................................................................................................1
1.1.1 Lectura de Archivos ......................................................................................................................................1
1.2 USING SYSTEM.IO.................................................................................................................................................2
1.3 CONTROL DE ERRORES ..........................................................................................................................................2
1.4 LECTURA: STREAMREADER...................................................................................................................................2
1.4.1 Constructores de StreamReader....................................................................................................................2
1.4.2 Lectura con StreamReader............................................................................................................................3
1.4.3 Ejemplo: Lectura de un Archivo de Texto, mostrando contenido en pantalla ..............................................3
1.4.4 Ejemplo: Procesamiento de Operaciones Matemticas en Archivo .............................................................4
1.5 ESCRITURA: STREAMWRITER................................................................................................................................6
1.5.1 Constructores de StreamWriter.....................................................................................................................6
1.5.2 Escritura con StreamWriter ..........................................................................................................................6
1.5.3 Ejemplo: Lectura y Escritura de un Archivo.................................................................................................7
2 BASES DE DATOS...................................................................................................................................................10
2.1 CONCEPTOS BSICOS DE BASES DE DATOS .........................................................................................................10
2.1.1 Base de Datos..............................................................................................................................................10
2.1.2 Sistema de Administracin de Base de Datos .............................................................................................10
2.1.3 Elementos relacionados a una Base de Datos.............................................................................................10
2.1.4 EJEMPLO.....................................................................................................................................................0
2.2 MODELOS DE BASES DE DATOS...........................................................................................................................12
2.2.1 Esquema de Archivos ..................................................................................................................................12
2.2.2 Modelo Jerrquico......................................................................................................................................12
2.2.3 Modelo Relacional ......................................................................................................................................13
2.2.4 Modelo Distribuido .....................................................................................................................................15
2.2.5 Modelo de BD Orientado a Objeto .............................................................................................................15
2.2.6 BD Multidimensional ..................................................................................................................................15
2.3 PROGRAMACIN DE BASES DE DATOS CON C#....................................................................................................16
2.3.1 Ejemplo: Programa de Registro de Alumnos..............................................................................................16


intro. Prog. Orientada a Objeto Archivos y B. de Datos Rodrigo Sandoval U.
IIC 1102 Pgina: 1
1 Lectura y Escritura de Archivos de Texto
En todos los programas, la manera de almacenar y recuperar informacin que perdure en el tiempo se basa
en el uso de memoria secundaria, compuesta esencialmente por discos (diskettes, discos duros, CD, DVD,
etc.) y ocasionalmente cintas. En cualquiera de estos medios, la unidad de almacenamiento de informacin
se denomina archivo.
Al igual que prcticamente todos los lenguajes de programacin, C#ofrece el acceso a leer y escribir
archivos en disco, por medio de estructuras especialmente definidas. En el caso de este lenguaje Orientado a
Objeto, las estructuras consisten en clases de caractersticas y mtodos particulares, que resuelven la
problemtica general de acceso a los archivos, permitiendo desarrollar programas que los utilicen como
fuente de informacin y medio de almacenamiento de informacin de largo plazo.
1.1 Streams
Un stream es como se denomina a un objeto utilizado para transferir datos. Estos datos pueden ser
transferidos en dos posibles direcciones:
- Si los datos son transferidos desde una fuente externa al programa, entonces se habla de leer
desde el stream.
- Si los datos son transferidos desde el programa a alguna fuente externa, entonces se habla de
escribir al stream.
Frecuentemente, la fuente externa ser un archivo, pero eso no necesariamente es el caso, por lo que el
concepto es utilizado ampliamente con fuentes de informacin externas de diversos tipos. Algunas otras
posibilidades fuera de los archivos incluyen:
- Leer o escribir datos a una red utilizando algn protocolo de red, donde la intencin es que estos
datos sean recibidos o enviados por otro computador.
- Lectura o escritura a un rea de memoria.
- La Consola
- La Impresora
- Otros ...
Algunas clases que C#provee para resolver este acceso a fuentes diversas incluyen las clases de tipo
Reader y Writer.
1.1.1 Lectura de Archivos
Las clases ms relacionadas con la escritura y lectura de archivos (File Input/Output o File I/O) son:
- FileStream, cuyo propsito es lectura y escritura de datos binarios (no de texto legible), a cualquier
archivo de tipo binario, aunque se puede utilizar para acceder a cualquier tipo de archivo, inclusive
los de texto.
- StreamReader y StreamWriter, las cuales estn diseadas para lectura y escritura de archivos de
texto. Estas clases se asumen como de un nivel ms alto que FileStream.

Una observacin acerca de la declaracin de nombres/rutas de archivos en C#. Usualmente, la ruta de un
archivo contiene el carcter \, que en C#se utiliza como caracter de control para smbolos especiales (como
el cambio de lnea: \n). Sin embargo, entendiendo que no es el mismo sentido el que se le quiere dar en la
interpretacin de rutas de archivos (por ej: C:\Mis documentos\Programas\ejemplo.cs), se utiliza una
sintaxis particular, anteponiendo el smbolo @ antes del string con la ruta del archivo. Es decir:
string rutaarchivo = @C:\Temp\archivo.txt;
intro. Prog. Orientada a Objeto Archivos y B. de Datos Rodrigo Sandoval U.
IIC 1102 Pgina: 2
Esta declaracin evita la interpretacin de los dos caracteres \ como smbolos especiales y el string queda
correctamente inicializado.
1.2 Using System.IO
Para el uso de estas clases, es necesario referenciar el uso del namespace System.IO, ya que System no
contiene los elementos para el manejo de archivos. Por ello, los programas con acceso a archivos deben
incluir la lnea:
using System.IO;
1.3 Control de Errores
Si bien en una serie de instrucciones de ejecucin en lenguaje C#se pueden producir errores importantes,
particularmente cuando hay input del usuario que debera tener cierta forma o valores, o en clculos
matemticos (especficamente evitando divisiones por cero), es factible en C#tener cierto control sobre el
comportamiento del programa ante dichas situaciones.
Esencialmente, el bloque try-catch persigue precisamente tener cierto control sobre lo que el programa har
en caso de producirse un error.
public int division(int n1, int n2) {
int resultado = 0;
try {
resultado = n1/n2;
}
catch(Exception e) {
Console.WriteLine("Error en la divisin de {0}/{1}\n\n{2}",n1, n2,
e.ToString());
}
}

1.4 Lectura: StreamReader
La ventaja de esta clase es que hace una operacin sobre archivos que resulta muy natural al momento de
utilizarla.
1.4.1 Constructores de StreamReader
El ms simple de los constructores toma slo el nombre/ruta del archivo a abrir para lectura:
StreamReader sr = new StreamReader(@C:\Temp\archivo.txt);
Sin embargo, reconociendo que hoy existen diferentes formatos (codificaciones) de archivos de texto y no
solamente el tradicional formato ASCII, es factible establecer cul es la codificacin especial que este archivo
de texto plano puede tener. Los formatos posibles son: ASCII, Unicode, UTF7, UTF8, BigEndianUnicode.
El constructor ad-hoc es:
StreamReader sr = new StreamReader(@C:\Temp\file.txt, Encoding.UTF8Encoding);
En trminos prcticos, nos ser necesario recurrir a este tipo de codificaciones, ya que usualmente se
trabajar con codificacin ASCII.
El constructor deja abierto el stream para poder recuperar la informacin del archivo desde la instancia de
StreamReader declarada. Para cerrar un stream o archivo, se invoca el mtodo Close():
sr.Close();

intro. Prog. Orientada a Objeto Archivos y B. de Datos Rodrigo Sandoval U.
IIC 1102 Pgina: 3
1.4.2 Lectura con StreamReader
Son bsicamente tres los mtodos propios de StreamReader que permiten efectuar lectura desde el stream
(archivo) declarado.
1.4.2.1 ReadLine()
Al igual que el conocido Console.ReadLine(), este mtodo lee una lnea completa de un archivo de texto
hasta el cambio de lnea ms prximo. Al igual que su equivalente de consola, StreamReader.ReadLine() no
incluye en el string el carcter de cambio de lnea.
string linea = sr.ReadLine()
1.4.2.2 ReadToEnd()
Este mtodo, por su parte, se encarga de acumular la informacin que hay desde la lectura anterior (que
pudo haberse hecho con ReadLine(), por ejemplo) hasta el final del archivo, todo en el mismo string.
string linea = sr.ReadToEnd()
1.4.2.3 Read ()
Finalmente, el mtodo simple Read() se encarga de leer un caracter a la vez, lo que permite procesar
smbolo por smbolo el contenido del archivo. Convenientemente, este mtodo reconoce el cambio de lnea y
se lo salta como si no existiese. Cuando se encuentra con el fin de archivo, retorna un valor 1, considerando
que su retorno es siempre un int (y no un char).
int SigCaracter = sr.Read();
Este mismo mtodo ofrece una declaracin alternativa (sobrecarga), donde es posible leer una cantidad
especfica de caracteres y almacenarlos en un arreglo de enteros.
char[] CharArray = new char[100];
int[] nChars = sr.Read(CharArray, 0, 100);
nChars es un arreglo con los enteros retornados por el mtodo, y ser menor si es que la cantidad de
caracteres que quedan en el archivo es menor de 100.
1.4.3 Ejemplo: Lectura de un Archivo de Texto, mostrando contenido en pantalla
/////////////////////////////////////////////////////////////////////////////////
// Ejemplo de Lectura de Archivos
/////////////////////////////////////////////////////////////////////////////////

using System;
using System.IO;


class Archivo {
StreamReader sr;
bool abierto = false;

// Constructor: Recibe el nombre del archivo y lo abre (con control errores)
public Archivo(string filename) {
try {
sr = new StreamReader(filename);
abierto = true;
}
catch(Exception e) {
Console.WriteLine("Error en la apertura de \"{0}\": {1}",
filename, e.ToString());
}
intro. Prog. Orientada a Objeto Archivos y B. de Datos Rodrigo Sandoval U.
IIC 1102 Pgina: 4
}

public void Mostrar() {
string linea;

if(!abierto) return; // Si no se pudo abrir, no hay nada que leer

linea = sr.ReadLine();
while(linea != null) { // Lee lneas mientras haya (mientras sean !=null)
Console.WriteLine(linea);
linea = sr.ReadLine();
}
sr.Close(); abierto = false;
}

}

class MainApp {

static void Main() {
string nombre;

Console.Write("Nombre del archivo: ");
nombre = Console.ReadLine();

Archivo archivo = new Archivo(nombre);
archivo.Mostrar();

Console.ReadLine();
}
}
1.4.4 Ejemplo: Procesamiento de Operaciones Matemticas en Archivo
/////////////////////////////////////////////////////////////////////////////////
// Ejemplo de Lectura de Archivos: Calculadora de Archivo
// ======================================================
// Este ejemplo muestra cmo se procesa el contenido de un archivo, que indica
// operaciones matemticas bsicas: * / + -
/////////////////////////////////////////////////////////////////////////////////

using System;
using System.IO;


class Calculadora {
StreamReader sr;
bool abierto = false;

// Constructor: Recibe el nombre del archivo y lo intenta abrir.
// Si no puede abrirse para lectura, "abierto" queda como false
public Calculadora(string filename) {
try {
sr = new StreamReader(filename);
abierto = true;
}
catch(Exception e) {
Console.WriteLine("Error en la apertura de \"{0}\": {1}",
filename,e.ToString());
}
}

intro. Prog. Orientada a Objeto Archivos y B. de Datos Rodrigo Sandoval U.
IIC 1102 Pgina: 5
// Operacion: Recibe la operacin y dos nmeros en forma de string.
// Retorna el resultado (int) de la operacin entre ambos nmeros.
int Operacion(string op, string n1, string n2) {
switch(op) {
case "+": return( int.Parse(n1) + int.Parse(n2));
case "-": return( int.Parse(n1) - int.Parse(n2));
case "*": return( int.Parse(n1) * int.Parse(n2));
case "/": return( int.Parse(n1) / int.Parse(n2));
}
return(0);
}

// Procesar: lee lneas del archivo abierto, procesando el contenido en forma de operaciones.
// Observaciones: al finalizar se cierra el stream. No se valida el formato de c/lnea.
public void Procesar() {
string linea;
string[] elementos;

if(!abierto) return; // Si no se pudo abrir, no hay nada que leer

linea = sr.ReadLine();
while(linea != null) {
// Para poder usar Split(), las operaciones y los operandos deben
// venir separados por espacios.
elementos = linea.Split();
Console.WriteLine("{0} = {1}", linea,
Operacion(elementos[1], elementos[0], elementos[2]));
linea = sr.ReadLine();
}
sr.Close(); abierto = false;
}
}

class MainApp {

static void Main() {
string nombre;

Console.Write("Nombre del archivo: ");
nombre = Console.ReadLine();
Calculadora c = new Calculadora(nombre);
c.Procesar();
Console.ReadLine();
}
}
Ejemplo de Ejecucin:
Tomando el siguiente archivo de operaciones calculos.txt:
4 + 4
5 * 6
8 - 2
6 / 3
Resulta el siguiente output:
Nombre del archivo: calculos.txt
4 + 4 = 8
5 * 6 = 30
8 - 2 = 6
6 / 3 = 2


intro. Prog. Orientada a Objeto Archivos y B. de Datos Rodrigo Sandoval U.
IIC 1102 Pgina: 6
1.5 Escritura: StreamWriter
Esta clase funciona prcticamente de la misma manera que StreamReader, excepto que su propsito es
nicamente para escribir dentro de un archivo (u otro stream). Es relevante distinguir que en este caso, el
proceso de apertura para escritura considera que:
- Si el archivo no existe lo crea vaco para comenzar a escribir.
- Si el archivo ya existe, lo deja vaco para comenzar a escribir.
- Si el archivo ya existe, es posible abrirlo en forma Append (agregar) para escribir al final.
1.5.1 Constructores de StreamWriter
El ms simple de los constructores toma slo el nombre/ruta del archivo a abrir para escritura.
StreamWriter sw = new StreamWriter (@C:\Temp\archivo.txt);
Este constructor asume por defecto el formato UTF8 de archivos planos, ya que es el manejado por .NET.
Sin embargo, existe el constructor equivalente que permite abrir un archivo especificando otra codificacin de
archivo plano, por ejemplo ASCII.
StreamWriter sw = new StreamWriter (@C:\doc\file.txt, Encoding.ASCII);
Un tercer constructor utiliza como segundo parmetro un boolean que indica si el archivo debe ser abierto
para Agregar, es decir, en un modo Append.
StreamWriter sw = new StreamWriter (@C:\Temp\archivo.txt, true);
De la misma manera que en el caso de la lectura, para cerrar un stream o archivo, se invoca el mtodo
Close:
sw.Close();

1.5.2 Escritura con StreamWriter
Son bsicamente dos los mtodos propios de StreamWriter que permiten escribir hacia el stream (archivo)
declarado y son los mismos que se usan para escribir en la consola: Write() y WriteLine().
1.5.2.1 WriteLine()
Totalmente equivalente a Console.WriteLine(), se utiliza la misma idea, y el mismo formato, sabiendo que se
estar escribiendo el texto no a la consola, sino que al stream abierto con el constructor.
string linea = Texto de prueba;
sw.WriteLine(linea);
sw.WriteLine(Los valores posibles son: {0} y {1}, 3, 5);

1.5.2.2 Write ()
Tambin presente, el mtodo simple Write(), permite escribir texto en el stream, de la misma forma que su
equivalente mtodo de la clase Console. En este caso se reconocen las siguientes alternativas de uso:
Imprimir un string
string linea = Texto de prueba;
sw.Write(linea);

intro. Prog. Orientada a Objeto Archivos y B. de Datos Rodrigo Sandoval U.
IIC 1102 Pgina: 7
Imprimir un caracter
char caracter = T;
sw.Write(caracter);
Imprimir un arreglo de caracteres
char[] caracteres = new char[100];
for(int i=0; i<100; i++) caracteres[i] = +;
sw.Write(caracteres);
Imprimir una porcin de un arreglo de caracteres
char[] caracteres = new char[100];
for(int i=0; i<100; i++) caracteres[i] = +;
sw.Write(caracteres, 25, 50); // Desde posicin 25 se escriben 50 caracteres

1.5.3 Ejemplo: Lectura y Escritura de un Archivo
/////////////////////////////////////////////////////////////////////////////////
// Ejemplo de Lectura de Archivos: Calculadora de Archivo
// ======================================================
// Este ejemplo muestra cmo se procesa el contenido de un archivo, que indica
// operaciones matemticas bsicas: * / + -
// Este ejemplo en particular, escribe el resultado en un archivo destino
/////////////////////////////////////////////////////////////////////////////////

using System;
using System.IO;

class Calculadora {
StreamReader sr;
StreamWriter sw;
bool abierto1 = false;
bool abierto2 = false;

// Constructor: Recibe el nombre del archivo y lo intenta abrir.
// Si no puede abrirse para lectura, "abierto" queda como false
// Si lo puede abrir, crea un segundo archivo con un nombre similar.
public Calculadora(string filename) {
try {
sr = new StreamReader(filename);
abierto1 = true;
}
catch(Exception e) {
Console.WriteLine("Error en la apertura de \"{0}\": {1}",
filename,e.ToString());
}

if(abierto1) {
string nombrearchivo2;
// Transforma "nombre.txt" en "nombre.out.txt"
nombrearchivo2 = filename.Insert(filename.IndexOf('.'),".out");
try {
sw = new StreamWriter(nombrearchivo2);
abierto2 = true;
}
catch(Exception e) {
Console.WriteLine("Error en la apertura de \"{0}\": {1}",
intro. Prog. Orientada a Objeto Archivos y B. de Datos Rodrigo Sandoval U.
IIC 1102 Pgina: 8
nombrearchivo2,e.ToString());
}
}

}

// Operacion: Recibe la operacin y dos nmeros en forma de string.
// Retorna el resultado (int) de la operacin entre ambos nmeros.
int Operacion(string op, string n1, string n2) {
switch(op) {
case "+": return( int.Parse(n1) + int.Parse(n2));
case "-": return( int.Parse(n1) - int.Parse(n2));
case "*": return( int.Parse(n1) * int.Parse(n2));
case "/": return( int.Parse(n1) / int.Parse(n2));
}
return(0);
}

// Procesar: lee el archivo abierto, lnea por lnea,
// procesando el contenido en forma de operaciones y escribiendo
// el resultado en un segundo archivo.
// Observaciones: Al finalizar se cierran los dos streams.
// No se valida el formato de c/lnea.
public void Procesar() {
string linea, linea2;
string[] elementos;

// Si no se pudo abrir, no se podr leer ni escribir
if(!abierto1 || !abierto2) return;

Console.WriteLine("Procesando ...");
linea = sr.ReadLine();
while(linea != null) {
elementos = linea.Split();
// ahora graba los resultados en el segundo archivo
linea2 = linea + " = " +
Operacion(elementos[1], elementos[0], elementos[2]).ToString();
sw.WriteLine(linea2);
linea = sr.ReadLine();
}
sr.Close(); abierto1 = false;
sw.Close(); abierto2 = false;
Console.WriteLine("Listo");
}
}


class MainApp {

static void Main() {
string nombre;

Console.Write("Nombre del archivo: ");
nombre = Console.ReadLine();

Calculadora c = new Calculadora(nombre);
c.Procesar();

Console.ReadLine();
}
}
Al abrir el archivo calculos.txt, se crea el archivo calculos.out.txt con el siguiente contenido:
intro. Prog. Orientada a Objeto Archivos y B. de Datos Rodrigo Sandoval U.
IIC 1102 Pgina: 9
4 + 4 = 8
5 * 6 = 30
8 - 2 = 6
6 / 3 = 2


intro. Prog. Orientada a Objeto Archivos y B. de Datos Rodrigo Sandoval U.
IIC 1102 Pgina: 10
2 Bases de Datos
Uno de los grandes objetivos de la computacin es la capacidad de procesar datos: muchos datos, en forma
rpida, eficiente, y segura (confiable). Esto no era posible con mtodos manuales tradicionales. Hoy en da
existen muchas aplicaciones computacionales, pero para este contexto se vuelven muy importantes aquellas
que trabajan directamente con la administracin de datos.
2.1 Conceptos Bsicos de Bases de Datos
Para la realidad computacional de nuestros das, es necesario definir dos elementos puntuales que existen
en todo gran o pequeo sistema que maneje cantidades de datos: la Base de Datos (BD) y el Sistema
Administrador de Base de Datos (DBMS).
2.1.1 Base de Datos
Se puede definir como Una coleccin estructurada y organizada de datos y de otros objetos que
permiten trabajar con esos datos. Si se habla de bolsn de datos, no se incluye un concepto de orden
o estructuracin. Una base de datos tiene una estructura claramente definida, sin importar el nivel de
complejidad de esta estructura. Tradicionalmente, los datos se manejan en estructuras uniformes, que se
pueden comparar con planillas de datos. Es decir, una base de datos contiene varias planillas de datos
diversos, que pueden a su vez estar relacionados o no.
2.1.2 Sistema de Administracin de Base de Datos
Se puede definir como Un elemento capaz de manejar los datos contenidos en una Base de Datos a
travs de operaciones claramente establecidas. Si la Base de Datos contiene los objetos que
corresponden a los datos y otras estructuras adicionales, el DBMS (Data Base Manager System) se encarga
de accesar esos datos, utilizando operaciones bsicas como: agregar, eliminar, modificar, buscar.
Un DBMS es un grupo de programas que se encargan de administrar estas operaciones y todos los
elementos que facilitan su ejecucin.
2.1.3 Elementos relacionados a una Base de Datos
Al trabajar con los datos de una BD, se deben mantener elementos que apoyan el acceso adecuado a las
estructuras de datos. Se distinguen:
Planillas de datos: tablas que contienen filas, cada una representa un objeto de un tipo comn
para las filas de la tabla, que a su vez se compone de varios atributos o propiedades que se
ordenan en las columnas de la planilla.
Registro: una fila de una tabla. Representa un objeto de un tipo definido y se compone de
atributos.
Campos: son precisamente la definicin de estos atributos de la tabla o planilla.
Llave Primaria: es una parte de los campos de un registro que permite distinguirlo en forma nica
del resto de registros adicionales.
Indices: al igual que el ndice de un libro, un ndice de una BD, que se asocia a una sola tabla,
referencia la posicin de un registro dentro de una tabla, de acuerdo a un orden predefinido.
Vistas: son ngulos de la BD. Al igual que una persona puede ver un auto desde el exterior, lo
cual constituye la vista externa del vehculo, existe otra vista interior, y por su parte el objeto
vehculo posee muchas propiedades o atributos que no son visibles en algunas vistas.

intro. Prog. Orientada a Objeto Archivos y B. de Datos Rodrigo Sandoval U.
IIC 1102 Pgina: 0
2.1.4 EJ EMPLO
En una Compra-Venta de autos usados se manejan los datos de los vehculos existentes en el momento.
Para poder utilizar informacin adecuada, se entiende que un auto es un objeto de tipo vehculo, y como tal
posee ciertas caractersticas determinables: Marca y Modelo, Patente, Nmero de Puertas, Cilindraje, Color.
Aplicando los conceptos mencionados de Bases de Datos:

Planilla de Datos o Tabla
Marca y Modelo Patente N Puertas Cilindraje Color
Suzuki Samurai HK-2367 3 1200 Azul
Subaru Impreza J G-2304 4 1800 Blanco
Chevrolet Cavalier LM-3948 4 1600 Rojo
Toyota Corolla TF-3404 4 1800 Gris
Toyota Corolla HK-2376 4 1600 Verde
Chevrolet Cavalier BC-2340 4 1600 Rojo



Llave Primaria
La llave primaria se obtiene al seleccionar una combinacin de campos cuyos valores combinados no se
repitan para ms de un registro. En este caso, podemos ver que el N de puertas es repetido, al igual que el
color y el cilindraje. La marca y el modelo tambin se repiten, pero claramente ningn auto posee la misma
patente de otro. Entonces la Patente es la candidata ideal para ser una llave Primaria.

Indice
Puede ser relevante ordenar la lista de autos por orden alfabtico de la Marca+Modelo. Es decir, el ndice
sera el que se ve a continuacin:
Chevrolet Cavalier BC-2340
Chevrolet Cavalier LM-3948
Subaru Impreza J G-2304
Suzuki Samurai HK-2367
Toyota Corolla HK-2376
Toyota Corolla TF-3404

Campos
Registro
intro. Prog. Orientada a Objeto Archivos y B. de Datos Rodrigo Sandoval U.
IIC 1102 Pgina: 12
Vista
Como visin parcial de los datos se puede definir verbalmente algo como Todos aquellos autos,
identificados por modelo, patente, y cilindraje, cuyo cilindraje sea mayor o igual a 1.700.
Marca y Modelo Patente Cilindraje
Subaru Impreza J G-2304 1800
Toyota Corolla TF-3404 1600

2.2 Modelos de Bases de Datos
Dados los conceptos bsicos de una BD, a travs del tiempo, ya para diversas necesidades se han diseado
algunos esquemas o modelos que difieren en su estructura, lo cual muchas veces trae ventajas y
desventajas. Muchos de los modelos diseados han quedado obsoletos frente a otros que cumplen de mejor
manera con las exigencias funcionales. Algunas de las caractersticas que deben tener:
Consistencia en los datos (todos los datos dicen lo mismo, no hay contradicciones)
Orden (permite saber qu existe y qu no existe, y dnde)
Rapidez en la bsqueda (necesidad de la realidad informtica de hoy)
Integridad de los datos (que su solidez se garantice evitando perder datos valiosos con operaciones
indirectas).
Acceso compartido a los datos (de modo que distintas entidades (usuarios, aplicaciones, etc.) puedan
acceder simultneamente a los datos.
2.2.1 Esquema de Archivos
Originalmente, los datos eran almacenados en archivos planos, que no contenan ms que una nica
estructura bsica de tabla, donde cada registro ocupa un largo fijo de bytes y sus campos son estticos. Se
habla de Archivos Secuenciales, ya que los registros son almacenados en orden de llegada y se mantienen
en ese orden (muy rgido). Para apoyar las exigencias a este esquema, se utilizan archivos adicionales para
manejar los ndices (utilizando el trmino archivos indexados), aunque las operaciones bsicas de insercin
y eliminacin funcionan bastante bien.
La indexacin (aplicacin de ndices) se realizaba de diversas maneras: ndices absolutos, relativos.
Esquemas posteriores permitieron cambiar el esquema secuencial a un de tipo rbol, donde la manera de
guardar los datos obedece a un esquema estructurado y jerrquico, de acuerdo a un orden preestablecido.
Tradicionalmente se utilizaron productos comerciales, tanto lenguajes de programacin, como DBMS (por as
nombrarlos) que manejan este esquema: lenguaje COBOL, archivos DBF (dBase, Clipper).
En este captulo es un esquema de este tipo el que se aprovecha al manejar archivos con C#, en un ejemplo
ms adelante.
2.2.2 Modelo J errquico
Este modelo ms complejo, a travs de la identificacin de relaciones entre los tipos de objetos que se
quieren almacenar, es capaz de construir una especia de red o ms bien, rbol de datos, donde existen
precedencias en cuanto a la estructura de orden. Esto se puede ver en el siguiente ejemplo.

intro. Prog. Orientada a Objeto Archivos y B. de Datos Rodrigo Sandoval U.
IIC 1102 Pgina: 13
N Curso Ttulo Descripcin
CURSO
REQUISITO
N Curso Ttulo
DICTAR
Da Hora Sala
Nombre N Profesor
PROFESOR ALUMNO
N Alumno Nombre Nota


Este modelo muestra una realidad de una universidad, donde se dictan cursos de distinto tipo que tienen
prerrequisitos, profesor (o profesores) que dicta(n) el curso, y alumnos que lo toman. Se distinguen algunos
elementos como N Alumno como identificador de alumno. Un ejemplo puntual de este modelo podra darse
con los siguientes datos:

AN-21 Computacin II Computacin orientada a....
AN-11 Computacin I
Mircoles 19:00 N7
23 Prez
1023 Alvarez 5,8
1293 Barrios 5,4
987 Cabrera 6,2


El primer sistema que existi con esta esquema fue el IMS (Information Managment System) desarrollado en
1960. Este fue el precursor que fue aprovechado en la NASA en la dcada de los 60, en particular en el
proyecto Apollo. Luego apareci System 2000 desarrollado por Intel.
Una de las grandes ventajas de este sistema fue la posibilidad de estructurar datos en una forma ms
completa que el esquema de archivos simples. An as, se vi en aprietos al momento de representar
situaciones donde la naturaleza de los datos implicaba una doble jerarqua, o al momento de consultar sobre
datos particulares.
2.2.3 Modelo Relacional
Fruto del trabajo de E.F. Codd, y sus publicaciones de la dcada de los 70, naci el System R que
implementaba un modelo bautizado como Relacional. La gran caracterstica de este modelo es que las tablas
que manejaba representaban entidades, que en la realidad tenan ciertos vnculos entre ellas. Estos vnculos
son conocidos como relaciones.
2.2.3.1 Tipos de Relaciones
Al identificar dos o ms entidades que estn vinculadas, se distingue una relacin. Esta puede tener distinta
cardinalidad, lo que se refiere a las repeticiones que se encuentran del vnculo. Supongamos las
entidades del ejemplo de cursos en una universidad: curso, profesor, alumno. Cada curso puede ser dictado
por uno o ms profesores, asisten varios alumnos a ese curso, los cules, a su vez asisten a otros cursos.
intro. Prog. Orientada a Objeto Archivos y B. de Datos Rodrigo Sandoval U.
IIC 1102 Pgina: 14
2.2.3.2 Relacin 1 a 1
Cuando dos entidades se relacionan en forma nica. Por ejemplo, si se diera como restriccin que cada
curso es dictado por un solo profesor, entonces Profesor es 1 a 1 a Curso.
2.2.3.3 Relacin 1 a N
Cuando dos entidades se relacionan de modo que una se relaciona varias veces con la otra. Por ejemplo,
cada curso debe dictarse en una nica sala (1), pero en una sala se dictan varios cursos (a distintas horas
obviamente), entonces Curso es 1 a N a Sala.
2.2.3.4 Relacin N a N
Cuando dos entidades se relacionan en forma abierta, es decir muchos de un tipo se relacionan con
muchos del otro. Por ejemplo, los alumnos toman varios cursos y a su vez cada curso integra a varios
alumnos, entonces Alumno es N a N a Curso.
Este modelo de BD se desarroll fuertemente en los 80 y sigue siendo hasta hoy muy utilizado en forma
comercial y universal.
Otro de los grandes aportes desde el punto de vista de la ciencia que se hizo con este modelo es el lgebra
relacional, donde en una manera formal se pueden establecer las relaciones entre las distintas entidades y
cules son las caractersticas de estas relaciones.
2.2.3.5 Formas Normales
Para asegurar consistencia de los datos, integridad, y evitar redundancia y otras anomalas que algunos
esquemas de datos proveen, en el modelo relacional es posible disear un esquema de tablas y relaciones
que para un caso puntual pueda asegurar de mejor manera esa integridad y consistencia.

Esta definicin se hace a travs de Formas Normales, las cules definen ciertas reglas que deben cumplir los
registros de cada tabla para asegurar estas caractersticas.
Existen las formas Normales: 1NF, 2NF, 3NF y BCNF. Cada una de estas establece ciertas caractersticas
que permiten mejorar la consistencia de datos, y la integridad.
Por ejemplo, en el ejemplo de los Cursos de la Universidad, es posible definir un esquema de datos que
maneje todos los datos de una manera muy rudimentaria. De esa manera se tendra una tabla como la
siguiente:

N Curso Ttulo Descripcin Nombre Prof. Sala Da Hora Alumno Nota
AN-21 C. II Compu.... Prez N7 Mie 19:00 Alvarez 5,6
AN-21 C. II Compu.... Prez N7 Mie 19:00 Barrios 5,8
AN-21 C. II Compu.... Prez N7 Mie 19:00 Cabrera 6,2


Despus de aplicar ciertas reglas los datos podran guardarse en varias tablas. En el esquema rudimentario
recin mostrado, se pueden producir los siguientes problemas:
- Redundancia: el curso, su profesor y la sala se repiten para cada alumno del curso.
intro. Prog. Orientada a Objeto Archivos y B. de Datos Rodrigo Sandoval U.
IIC 1102 Pgina: 15
- Inconsistencia: es posible que en el primer registro diga AN-21 con Prez como profesor, pero en el 2.
Registro puede decir AN-21, con Snchez como profesor. No hay cmo saber cul es el correcto.
- Problemas de insercin. Si agrego un nuevo alumno debo repetir todos los datos.
- Problemas de eliminacin. Si elimino todos los registros de los alumnos (es decir, este curso no tuvo
alumnos), entonces se pierde la informacin del profesor que haba sido designado.

En el esquema relacional adecuado, aplicando algn nivel de formas normales se pueden evitar todos estos
problemas definiendo tablas separadas, usualmente distinguiendo entidades distintas, y relaciones ms
complejas (N a N).
2.2.4 Modelo Distribuido
A veces aplicable a varias de las estructuras existentes, la idea del modelo distribuido es repartir los datos en
distintas tablas que estn ubicadas en distintas posiciones en una red de computadores. Este esquema se
hace necesario cuando la administracin compartida y global de la informacin consume demasiados
recursos: canal de comunicacin de red, espacio en discos de los computadores, etc. Lo que se busca con
este esquema es repartir los datos de manera que el trfico de datos por la red se vea disminuido, a la vez
que se permite que cada unidad que solicita datos a esta BD distribuida, pueda obtenerlos adecuadamente.
2.2.5 Modelo de BD Orientado a Objeto
Buscando mejorar el rendimiento de un DBMS ante eventuales bsquedas complejas de informacin de la
BD, se diseo la BD OO (Orientada a Objetos). En ella, cada entidad se distingue como un obejto que tiene
Propiedades, Atributos (Campos) y Operaciones definidas que accesan esta informacin.
2.2.6 BD Multidimensional
Con el creciente desarrollo de las aplicaciones computacionales orientadas a dar informacin de alto nivel, es
decir, informacin que ha pasado por varias etapas de proceso desde el detalle de los datos, se han
desarrollados esquemas que son capaces de contestar complejas preguntas que requieren de valores a un
alto nivel de agregacin de los datos originales. Cuando se habla de la gestin de una empresa, hoy en da
se habla de obtener informacin desde los datos originales que permitan tomar decisiones de acuerdo al
comportamiento del negocio reflejado por los datos analizados en diversas dimensiones.

En palabras ms simples, cuando se requieren analizar los datos de ventas de productos de una fbrica,
tanto por lnea de producto, o distribucin geogrfica, o travs del tiempo, es necesario tener parte de los
datos ya digeridos. Si se intenta hacer sumas de detalles de facturas emitidas para obtener la informacin,
segn un esquema relacional, la respuesta demorar largo tiempo en llegar, dependiendo de la cantidad de
datos existentes.
Una BD multidimensional utiliza un esquema en que los datos han sido procesados (sumados, recalculados
totales, etc.) hasta cierto nivel y se organizan de acuerdo a las dimensiones relevantes del negocio. Esto
permite contestare con buena eficiencia complejas preguntas, como tendencias, etc., pero imposibilita poder
analizar una factura en particular (datos a gran nivel de detalle).

intro. Prog. Orientada a Objeto Archivos y B. de Datos Rodrigo Sandoval U.
IIC 1102 Pgina: 16
2.3 Programacin de Bases de Datos con C#
Si bien hoy existen numerosas tecnolgicas maduramente desarrolladas para administrar datos en Bases de
Datos, incluyendo lenguajes de manejo especializados, como es el SQL, es factible hacer programas que
incluyan el manejo simple de informacin en archivos de datos de formato definido y acotado.
En la gran mayora de estos programas, se define lo que se conoce como una capa lgica, que se conforma
de clases que representan los datos almacenados en las diferentes tablas (o archivos), de modo que el resto
del programa slo conoce la forma lgica de estas clases, y desconoce el formato de las tablas o archivos.
2.3.1 Ejemplo: Programa de Registro de Alumnos

Definicin del Problema
En este ejemplo, se considera un almacenamiento de datos en archivos para poder hacer el registro de
alumnos en cursos para semestres especficos. Pensando en un modelo estilo Relacional, se determinan las
siguientes entidades de informacin relevantes:
- El alumno, detallado con nombre, apellido, N alumno (nico), fecha nacimiento (forma ddmmaaaa), y
edad.
- El curso dictado, identificado por su sigla (nica), su descripcin, y la cantidad de crditos.
- La inscripcin, que relaciona un alumno (identificado por su N) con un curso (identificado por su sigla),
asociado a un semestre en particular (de la forma aaaan, donde aaaa es el ao y n el semestre).
En este caso particular, se requiere permitir las siguientes operaciones:
- Ingresar un nuevo alumno
- Ingresar un nuevo curso
- Inscribir un alumno en un curso, en un semestre particular
- Mostrar todos los cursos
- Mostrar todos los alumnos
- Mostrar todas las inscripciones realizadas
- Leer los datos de los archivos correspondientes
- Guardar los datos de los archivos correspondientes.
Elementos Involucrados: la lista de alumnos, la lista de cursos, y la lista de inscripciones.

Conceptualizacin de la Solucin
Para este programa se requiere implementar las entidades: Lista de Alumnos, Lista de Cursos, Inscripciones.
Las clases necesarias para implementar estas entidades son las siguientes:
- Alumno y ListaAlumnos
- Curso y ListaCursos
- Inscripcin y ListaInscripciones
Clase Alumno: contiene los datos bsicos de cada alumno y propiedades que permiten acceder a ellos
Clase ListaAlumnos: maneja un conjunto de alumnos, permitiendo cargar y guardar datos de y hacia un
archivo de texto con un formato especfico y adecuado. Adicionalmente permite operaciones como: Agregar
Alumnos, Mostrar los Alumnos registrados, Buscar un Alumno en particular.
intro. Prog. Orientada a Objeto Archivos y B. de Datos Rodrigo Sandoval U.
IIC 1102 Pgina: 17
Las clases Curso, ListaCurso, Inscripcion, y ListaInscripciones ofrecen elementos equivalentes, cada una en
su propio contexto de informacin a manejar.
Adicionalmente, en la clase principal ofrece mtodos para la manipulacin general de los datos, como son:
- Men de opciones
- Creacin de un nuevo Alumno, preguntando sus datos
- Creacin de un nuevo Curso, preguntando sus datos
- Registro de una nueva inscripcin, preguntando y validando el curso y el alumno correspondiente.

Algoritmo Principal
1. Crear las instancias de las listas de datos Leer los archivos con datos
2. Repetir mientras la opcin seleccionada no sea Salir
a. Mostrar Men de Opciones
b. Preguntar opcin
c. Si la opcin no es Salir
i. Ejecutar Opcin
3. Grabar datos en archivos desde las listas

Limitaciones
El programa no hace todas las validaciones de datos ingresados por el usuario, pero particularmente requiere
lo siguiente:
- Las descripciones de cursos deben ser un nico string sin espacios entre medio.
- Los nombres y apellidos no pueden ser compuestos (o al menos, no separados por espacios)
- Slo se maneja un nmero limitado de alumnos, un nmero limitado de cursos, y un nmero limitado de
inscripciones
- Si bien se valida la existencia de los archivos antes de leerlos, se muestra un mensaje en pantalla
derivado del registro de error de la plataforma .NET.


Cdigo Fuente de la Solucin
/////////////////////////////////////////////////////////////////////////////////
// Ejemplo de Manejo de Datos en Archivos - Inscripcin de Alumnos en Cursos
// =========================================================================
/////////////////////////////////////////////////////////////////////////////////

using System;
using System.IO; // Namespace de clases StreamReader y StreamWriter, para archivos

//------------------------------------------------------------------------
//------------------------------------------------------------------------
// Clase Curso: representa un curso con sus atributos bsicos
//------------------------------------------------------------------------
class Curso {
string sigla, descripcion;
int creditos;

intro. Prog. Orientada a Objeto Archivos y B. de Datos Rodrigo Sandoval U.
IIC 1102 Pgina: 18
public Curso(string s, string d, int c) {
sigla = s.ToUpper(); descripcion = d.ToUpper(); creditos = c;
}

public string Sigla { get { return(sigla); } }
public string Descripcion { get { return(descripcion); } }
public int Creditos { get { return(creditos); } }
}


//------------------------------------------------------------------------
//------------------------------------------------------------------------
// Clase ListaCursos: representa un conjunto de cursos
//------------------------------------------------------------------------
class ListaCursos {
Curso[] cursos; // Almacena la lista de cursos
int cantidad = 0;
const int MAX = 20; // Limitacin: 20 cursos mx
string archivo = "cursos.dat";

// ------------------------------------------------------------------
// Constructor: dimensiona la lista de alumnos en MAX
public ListaCursos() { cursos = new Curso[MAX]; } // Limitacin: 20 cursos mx

// ------------------------------------------------------------------
// Constructor: dimensiona la lista de cursos en MAX
// y carga los datos de archivo identificado por su nombre
public ListaCursos(string filename) {
StreamReader fr;
cursos = new Curso[MAX];
archivo = filename;
try {
fr = new StreamReader(archivo);
} catch(Exception e) { //OJO: esta lnea indicar warning: no se usa e
// No se pudo abrir: se crea
StreamWriter sw = new StreamWriter(archivo);
sw.Close();
return;
}
string linea;
linea = fr.ReadLine();
while(linea != null) {
string[] datos = linea.Split();
// Formato del archivo tiene: creditos sigla descripcin
Agregar(datos[1].ToUpper(), datos[2].ToUpper(), int.Parse(datos[0]));
linea = fr.ReadLine();
}
fr.Close();
}

// ----------------------------------------------------------------------------
// Guardar(): guarda datos en estructura al archivo identificado por su nombre
public bool Guardar() {
StreamWriter fw;
try {
fw = new StreamWriter(archivo);
} catch(Exception e) {
Console.WriteLine("Error en la apertura de \"{0}\": {1}",
archivo,e.ToString());
return (false);
}
for(int i=0; i<cantidad; i++)
fw.WriteLine("{0} {1} {2}",
intro. Prog. Orientada a Objeto Archivos y B. de Datos Rodrigo Sandoval U.
IIC 1102 Pgina: 19
cursos[i].Creditos, cursos[i].Sigla, cursos[i].Descripcion);

fw.Close();
return (true);
}

// ------------------------------------------------------------------
// Agregar(): agrega un curso dado a la lista
// Parmetros: Curso c, el curso a agregar
public void Agregar(Curso c) { if(cantidad<MAX) cursos[cantidad++] = c; }

// ------------------------------------------------------------------
// Agregar(): agrega un curso dados sus datos, a la lista
// Parmetros: la sigla, la descripcin, y los crditos
public void Agregar(string s, string d, int c) {
if(cantidad<MAX) {
cursos[cantidad++] = new Curso(s,d,c);
}
}

// -------------------------------------------------------------------
// Atributo Cantidad - slo lectura, no se puede modificar "por fuera"
public int Cantidad { get { return(cantidad); } }

// -------------------------------------------------------------------------------
// Mostrar(): muestra los datos registrados al momento
public void Mostrar() {
Console.WriteLine("\nCURSOS:");
for(int i=0; i<cantidad; i++)
Console.WriteLine("{0} {1} {2}",
cursos[i].Creditos, cursos[i].Sigla, cursos[i].Descripcion);
Console.WriteLine("----------------------------------------------------\n");
}

// -------------------------------------------------------------------------------
// Buscar(): Busca curso definido por sigla. Retorna la posicin, -1 si no est.
public int Buscar(string sigla) {
for(int i=0; i<cantidad; i++)
if( cursos[i].Sigla == sigla.ToUpper() )
return(i);
return(-1); // Si lleg aqu: no lo encontr
}

// ------------------------------------------------------------------------------
// GetCurso(): Entrega curso ubicado en la posicin n del arreglo, con n de 0..N-1
public Curso GetCurso(int n) { return(cursos[n]); }
}


//------------------------------------------------------------------------
//------------------------------------------------------------------------
// Clase Alumno: representa un alumno con sus atributos bsicos
//------------------------------------------------------------------------
class Alumno {
string nombre, apellido;
string fechanac;
int numero;

public Alumno(int num, string n, string a, string f) {
numero = num; nombre = n.ToUpper(); apellido = a.ToUpper(); fechanac = f;
}
public string Nombre { get { return(nombre); } }
public string Apellido { get { return(apellido); } }
intro. Prog. Orientada a Objeto Archivos y B. de Datos Rodrigo Sandoval U.
IIC 1102 Pgina: 20
public string FechaNac { get { return(fechanac); } }
public int Numero { get { return(numero); } }
}


//------------------------------------------------------------------------
//------------------------------------------------------------------------
// Clase ListaAlumnos: representa un conjunto de alumnos
//------------------------------------------------------------------------
class ListaAlumnos {
Alumno[] alumnos; // Almacena la lista de alumnos
int cantidad = 0;
const int MAX = 20; // Limitacin: 20 alumnos mx
string archivo = "alumnos.dat";

// ------------------------------------------------------------------
// Constructor: dimensiona la lista de alumnos en MAX
public ListaAlumnos(){ alumnos = new Alumno[MAX]; } // Limitacin: 20 alumnos mx

// ------------------------------------------------------------------
// Constructor: dimensiona la lista de alumnos en MAX
// y carga los datos de archivo identificado por su nombre
public ListaAlumnos(string filename) {
StreamReader fr;
alumnos = new Alumno[MAX];
archivo = filename;
try {
fr = new StreamReader(archivo);
} catch(Exception e) { //OJO: esta lnea indicar warning: no se usa e
// No se pudo abrir: se crea
StreamWriter sw = new StreamWriter(archivo);
sw.Close();
return;
}
string linea;
linea = fr.ReadLine();
while(linea != null) {
string[] datos = linea.Split();
// Formato del archivo tiene: num fecha nombre apellido
Agregar(int.Parse(datos[0]), datos[2], datos[3], datos[1]);
linea = fr.ReadLine();
}
fr.Close();
}

// --------------------------------------------------------------------------------
// Guardar(): guarda datos en la estructura al archivo identificado por su nombre
public bool Guardar() {
StreamWriter fw;
try {
fw = new StreamWriter(archivo);
} catch(Exception e) {
Console.WriteLine("Error en la apertura de \"{0}\": {1}",
archivo,e.ToString());
return (false);
}
for(int i=0; i<cantidad; i++)
fw.WriteLine("{0} {1} {2} {3}",
alumnos[i].Numero, alumnos[i].FechaNac,
alumnos[i].Nombre, alumnos[i].Apellido);

fw.Close();
return (true);
intro. Prog. Orientada a Objeto Archivos y B. de Datos Rodrigo Sandoval U.
IIC 1102 Pgina: 21
}

// ------------------------------------------------------------------
// Agregar(): agrega un alumno dado a la lista
// Parmetros: Alumno a, el alumno a agregar
public void Agregar(Alumno a) { if(cantidad<MAX) alumnos[cantidad++] = a; }

// ------------------------------------------------------------------
// Agregar(): agrega un alumno dados sus datos, a la lista
// Parmetros: el nmero, nombre, apellido, y fecha nacimiento
public void Agregar(int num, string n, string a, string f) {
if(cantidad<MAX) {
alumnos[cantidad++] = new Alumno(num,n,a,f);
}
}

// -------------------------------------------------------------------
// Atributo Cantidad - slo lectura, no se puede modificar "por fuera"
public int Cantidad { get { return(cantidad); } }

// -------------------------------------------------------------------------------
// Mostrar(): muestra los datos registrados al momento
public void Mostrar() {
Console.WriteLine("\nALUMNOS:");
for(int i=0; i<cantidad; i++)
Console.WriteLine("{0} {1} {2} {3}",
alumnos[i].Numero, alumnos[i].FechaNac,
alumnos[i].Nombre, alumnos[i].Apellido);
Console.WriteLine("-----------------------------------------------------");
}

// ------------------------------------------------------------------------
// Buscar(): Busca alumno definido por su numero. Retorna posicin, -1 si no est.
public int Buscar(int numero) {
for(int i=0; i<cantidad; i++)
if( alumnos[i].Numero == numero )
return(i);
return(-1); // Si lleg aqu: no lo encontr
}

// -------------------------------------------------------------------------------
// GetAlumno(): Entrega alumno ubicado en posicin n del arreglo, con n de 0..N-1
public Alumno GetAlumno(int n) { return(alumnos[n]); }
}


//------------------------------------------------------------------------
//------------------------------------------------------------------------
// Clase Inscripcion: representa la relacin entre un alumno y un curso
//------------------------------------------------------------------------
class Inscripcion {
string sigla;
int numero, semestre;

public Inscripcion(string s, int n, int m) {
sigla = s.ToUpper(); numero = n; semestre = m;
}
public string Sigla { get { return(sigla); } }
public int Numero { get { return(numero); } }
public int Semestre { get { return(semestre); } }
}


intro. Prog. Orientada a Objeto Archivos y B. de Datos Rodrigo Sandoval U.
IIC 1102 Pgina: 22
//------------------------------------------------------------------------
//------------------------------------------------------------------------
// Clase ListaInscripciones: representa un conjunto de inscripciones
//------------------------------------------------------------------------
class ListaInscripciones {
Inscripcion[] inscripciones; // Almacena la lista de inscripciones
int cantidad = 0;
const int MAX = 60; // Limitacin: 60 inscripciones mx
string archivo = "inscripciones.dat";

// ------------------------------------------------------------------
// Constructor: dimensiona la lista de inscripciones en MAX
public ListaInscripciones() { inscripciones = new Inscripcion[MAX]; }

// ------------------------------------------------------------------
// Constructor: dimensiona la lista de inscripciones en MAX
// y carga los datos de archivo identificado por su nombre
public ListaInscripciones(string filename) {
StreamReader fr;
inscripciones = new Inscripcion[MAX];
archivo = filename;
try {
fr = new StreamReader(archivo);
} catch(Exception e) { //OJO: esta lnea indicar warning: no se usa e
// No se pudo abrir: se crea
StreamWriter sw = new StreamWriter(archivo);
sw.Close();
return;
}
string linea;
linea = fr.ReadLine();
while(linea != null) {
string[] datos = linea.Split();
// Formato del archivo tiene: sigla numero semestre
Agregar(datos[0].ToUpper(), int.Parse(datos[1]), int.Parse(datos[2]));
linea = fr.ReadLine();
}
fr.Close();
}

// -------------------------------------------------------------------------------
// Guardar(): guarda datos en la estructura al archivo identificado por su nombre
public bool Guardar() {
StreamWriter fw;
try {
fw = new StreamWriter(archivo);
} catch(Exception e) {
Console.WriteLine("Error en la apertura de \"{0}\": {1}",
archivo,e.ToString());
return (false);
}
for(int i=0; i<cantidad; i++)
fw.WriteLine("{0} {1} {2}",
inscripciones[i].Sigla, inscripciones[i].Numero,
inscripciones[i].Semestre);

fw.Close();
return (true);
}

// ------------------------------------------------------------------
// Agregar(): agrega una inscripcin dada a la lista
// Parmetros: Inscripcion i, el curso a agregar
intro. Prog. Orientada a Objeto Archivos y B. de Datos Rodrigo Sandoval U.
IIC 1102 Pgina: 23
public void Agregar(Inscripcion i) {
if(cantidad<MAX) inscripciones[cantidad++] = i;
}

// ------------------------------------------------------------------
// Agregar(): agrega un curso dados sus datos, a la lista
// Parmetros: la sigla, la descripcin, y los crditos
public void Agregar(string s, int n, int m) {
if(cantidad<MAX) {
inscripciones[cantidad++] = new Inscripcion(s,n,m);
}
}

// -------------------------------------------------------------------
// Atributo Cantidad - slo lectura, no se puede modificar "por fuera"
public int Cantidad { get { return(cantidad); } }

// ------------------------------------------------------------------------------
// Mostrar(): muestra los datos registrados al momento
public void Mostrar(ListaAlumnos la, ListaCursos lc) {
Console.WriteLine("\nINSCRIPCIONES:");
for(int i=0; i<cantidad; i++) {
Alumno a; Curso c;
a = la.GetAlumno(la.Buscar(inscripciones[i].Numero));
c = lc.GetCurso(lc.Buscar(inscripciones[i].Sigla));

Console.WriteLine("{0} ({1}) - {2} ({3} {4}) en {5}",
c.Sigla, c.Descripcion, a.Numero, a.Nombre, a.Apellido,
inscripciones[i].Semestre);
}
Console.WriteLine("----------------------------------------------------\n");
}
}



//------------------------------------------------------------------------
//------------------------------------------------------------------------
// Clase MainApp: Bloque del Algoritmo Principal y mtodos auxiliares
//------------------------------------------------------------------------
class MainApp {

// ----------------------------------------------------
// ValidarFecha(): valida una fecha en formato ddmmaaaa
static bool ValidarFecha(string fecha) {
string digitos = "0123456789";
if(fecha.Length!=8) return (false);
for(int i=0; i<fecha.Length; i++)
if(digitos.IndexOf(fecha[i])<0) return (false);
if(int.Parse(fecha.Substring(0,2))>31) return (false);
if(int.Parse(fecha.Substring(0,2))==0) return (false);
if(int.Parse(fecha.Substring(2,2))>12) return (false);
if(int.Parse(fecha.Substring(2,2))==0) return (false);
return (true);
}

static Alumno NuevoAlumno() {
string nombre, apellido, fechanac;
int numero;

Console.WriteLine("Datos del nuevo alumno");
Console.Write("Nombre: "); nombre = Console.ReadLine();
Console.Write("Apellido: "); apellido = Console.ReadLine();
intro. Prog. Orientada a Objeto Archivos y B. de Datos Rodrigo Sandoval U.
IIC 1102 Pgina: 24
do {
Console.Write("Fecha Nac (ddmmaaaa): ");
fechanac = Console.ReadLine();
} while (!ValidarFecha(fechanac));
Console.Write("Numero: "); numero = int.Parse(Console.ReadLine());

return(new Alumno(numero, nombre, apellido, fechanac));
}

static Curso NuevoCurso() {
string sigla, descripcion;
int creditos;

Console.WriteLine("Datos del nuevo curso");
Console.Write("Sigla: "); sigla = Console.ReadLine();
Console.Write("Descripcin: "); descripcion = Console.ReadLine();
Console.Write("Crditos: "); creditos = int.Parse(Console.ReadLine());

return(new Curso(sigla, descripcion, creditos));
}

// --------------------------------------------------------------------------
// NuevaInscripcion(): Crea una nueva inscripcin relacionando un alumno existente
// con un curso que tambin debe ser existente.
// Observaciones: Se le pide al usuario slo el N del alumno y la sigla del curso,
// validando que ambos existan.
static Inscripcion NuevaInscripcion(ListaAlumnos la, ListaCursos lc) {
string sigla;
int numero, semestre;
Alumno a; Curso c;

// Muestra listas en pantalla para ayudar al usuario a indicar datos.
la.Mostrar(); lc.Mostrar();
Console.WriteLine("Inscripcin de Curso:");
do {
Console.Write("N Alumno: ");
numero = int.Parse(Console.ReadLine());
} while( la.Buscar(numero)<0 );
do {
Console.Write("Sigla Curso: ");
sigla = Console.ReadLine();
} while( lc.Buscar(sigla)<0 );
Console.Write("Semestre: "); semestre = int.Parse(Console.ReadLine());

a = la.GetAlumno(la.Buscar(numero)); c = lc.GetCurso(lc.Buscar(sigla));
Console.WriteLine("El alumno {0} {1} se inscribi en el curso {2} ({3})",
a.Nombre, a.Apellido, c.Sigla, c.Descripcion);

return(new Inscripcion(sigla, numero, semestre));
}


static int Menu(string[] opciones) {
int contador = 1, op = 0;
foreach(string opcion in opciones)
Console.WriteLine("{0}) {1}",contador++,opcion);
Console.Write("Ingrese su opcin: ");
do op = int.Parse(Console.ReadLine()); while (op<=0 && op>=contador);
return(op);
}

static void Main() {
string[] opciones = { "Agregar Alumno", "Agregar Curso",
intro. Prog. Orientada a Objeto Archivos y B. de Datos Rodrigo Sandoval U.
IIC 1102 Pgina: 25
"Inscribir en Curso", "Mostrar Alumnos",
"Mostrar Cursos", "Mostrar Inscripciones",
"Salir" };
int opcion = 0;

const string archivocursos = "cursos.dat";
const string archivoalumnos = "alumnos.dat";
const string archivoinscripciones = "inscripciones.dat";

ListaCursos lc = new ListaCursos(archivocursos);
ListaAlumnos la = new ListaAlumnos(archivoalumnos);
ListaInscripciones li = new ListaInscripciones(archivoinscripciones);


do {
opcion = Menu(opciones);
switch(opcion) {
case 1: la.Agregar(NuevoAlumno()); break;
case 2: lc.Agregar(NuevoCurso()); break;
case 3: li.Agregar(NuevaInscripcion(la,lc));break;
case 4: la.Mostrar(); break;
case 5: lc.Mostrar(); break;
case 6: li.Mostrar(la,lc); break;
}
} while(opcion!=7);

lc.Guardar();
la.Guardar();
li.Guardar();
}
}
Instrucciones de compilacin.
Para compilar este ejemplo, se debe copiar el cdigo en un archivo .cs y compilarlo individualmente. En este
proceso aparecern 3 warnings relacionados los bloques try-catch de los constructores de las listas definidas,
en especfico, indicando que la variable e no es utilizada. Se puede modificar ese bloque para utilizarla
como parte de un mensaje adecuado, pero no es necesario en estricto rigor.
Instrucciones de ejecucin.
Para ejecutar correctamente este ejemplo, los archivos alumnos.dat, cursos.dat, e inscripciones.dat deeben
estar ubicados en la misma carpeta del ejecutable, o bien no existir, y sern creados en dicha ubicacin.
PONTIFICIA UNIVERSIDAD CATLICA DE CHILE
ESCUELA DE INGENIERA
DEPARTAMENTO DE CIENCIA DE LA COMPUTACIN
Curso: IIC 1102 INTRODUCCIN A LA PROG. ORIENTADA A OBJETO
Profesor: Rodrigo Sandoval U.

Simulacin Computacional con C#


1 INTRODUCCIN ............................................................................................................................................... 1
2 MODELO DE SIMULACIN............................................................................................................................ 2
2.1 PARMETROS DE LA SIMULACIN ..................................................................................................................2
2.2 DATOS O INPUT DE LA SIMULACIN................................................................................................................2
2.2.1 Generacin de Nmeros Aleatorios ....................................................................................................... 2
2.2.2 Carga de Datos Reales desde Archivos.................................................................................................. 4
2.3 EJ ECUCIN DE LA SIMULACIN.......................................................................................................................5
2.3.1 El Manejo del Tiempo ............................................................................................................................ 5
2.3.2 Colas en C#............................................................................................................................................ 7
3 EJEMPLOS.......................................................................................................................................................... 9
3.1 SIMULACIN DE CADENA DE CORREO............................................................................................................9
3.2 LLEGADA DE CLIENTES A CAJ A EN EL BANCO..............................................................................................10
3.2.1 Solucin 1.0.......................................................................................................................................... 11
3.2.2 Solucin 2.0.......................................................................................................................................... 13
3.2.3 Solucin 3.0.......................................................................................................................................... 15
3.3 SIMULACIN DE LAS COLAS EN UN SUPERMERCADO....................................................................................17
3.3.1 Definicin del Problema ...................................................................................................................... 17
3.3.2 Caractersticas del Modelo.................................................................................................................. 17
3.3.3 Mediciones Requeridas ........................................................................................................................ 17
3.3.4 Solucin................................................................................................................................................ 18
3.4 SIMULACIN DE UNA PLAZA DE PEAJ E..........................................................................................................24
3.4.1 Definicin del Problema ...................................................................................................................... 24
3.4.2 Solucin................................................................................................................................................ 26


Material preparado por Rodrigo Sandoval U en Agosto 2005, (rsandova@ing.puc.cl)
basado en los apuntes de clase del curso IIC1102, ao 2003, de M. Nussbaum, Marcos Seplveda, et.al.

Simulacin Computacional con C# Rodrigo Sandoval U.
1 Introduccin
La simulacin mediante programas de computador permite el estudio detallado de sistemas complejos,
sobre los que resulta costoso, difcil o peligroso llevar a cabo estudios reales. La simulacin se basa en
analizar el comportamiento de un modelo derivado de una situacin real, de la forma ms equivalente
posible, para obtener resultados de la medicin del comportamiento de este modelo y as sacar
conclusiones.
En otras palabras, un modelo de simulacin intenta recrear de la mejor manera posible las
caractersticas del sistema representado y se comporta de manera similar a como lo hara en la realidad.
La idea es que la ejecucin de la simulacin produzca resultados en la forma de valores estadsticos, o
simplemente permita monitorear el desempeo del sistema durante su funcionamiento.


Modelo de Simulacin
Los modelos de simulacin distinguen en general cuatro elementos esenciales:
A. Parmetros de Funcionamiento. Estos datos, muchas veces valores numricos fijos para una
simulacin, determinan ciertas condiciones de la ejecucin, que tambin se define como el
escenario a analizar. Siempre ser posible cambiar los valores de estos parmetros y como
consecuencia, observar el comportamiento del modelo con esas nuevas condiciones y
eventualmente sacar conclusiones al comparar los resultados de un escenario con los de otro.
B. Datos o Input de la Simulacin. Para representar situaciones del modelo real, se cuenta con
datos de diverso tipo que alimentarn la simulacin completando el escenario a implementar con
este modelo. Estos datos generalmente son de tres tipos: datos fijos, conceptualizados como
promedios constantes; datos aleatorios que le dan un factor de variabilidad y ofrecen un
escenario con elementos impredecibles al modelo; y datos reales, que fueron medidos en una
situacin equivalente en la vida real, y que le aportarn el factor realista directo al modelo.
C. Ejecucin de la Simulacin. Consiste en realizar la simulacin propiamente tal, por medio de la
ejecucin iterativa de pasos que emulan el comportamiento de la situacin modelada. Entre los
elementos que se consideran en esta ejecucin, posiblemente el ms importante es el manejo del
tiempo, en el cual el modelo es capaz de identificar los eventos que ocurren en un instante
relevante de tiempo, y ejecutarlos como parte de la simulacin.
D. Resultados de la Simulacin. Datos medidos durante la ejecucin que permiten obtener una
visin del desempeo del modelo y por ende, sacar conclusiones de la situacin simulada.
Tomando un ejemplo clsico, la simulacin de autos en una interseccin de calles, un parmetro de
entrada sera la duracin de la luz roja y de la verde; datos o input sera la llegada de vehculos en
momentos de la simulacin; la ejecucin considerara el tiempo que toma que los autos se vayan
acumulando en roja y luego salgan en verde; y resultados posibles se consideran el tiempo de espera, o
la probabilidad de que un auto no alcance a cruzar en verde.
IIC 1102 Pgina: 1
Simulacin Computacional con C# Rodrigo Sandoval U.
2 Modelo de Simulacin
2.1 Parmetros de la Simulacin
En estos modelos es de mucha utilidad el uso de parmetros, que permitan de manera simple cambiar
las caractersticas del ambiente o del sistema mismo, de modo que sea posible observar los cambios que
se producen en su operacin. Definen un escenario especfico en el cual se realizar la simulacin.
Normalmente son valores numricos, que se mantienen constantes durante la simulacin completa.
El hecho de mantener estos valores paramtricos, permite a quien analiza la simulacin variarlos y poder
probar distintos escenarios de simulacin. Por ejemplo, parmetros de una simulacin podran ser la
duracin de un semforo en una interseccin, la capacidad de carga de un camin o de otro medio de
transporte, la capacidad de atencin de una caja de banco o de tienda, valores monetarios o tarifas.
2.2 Datos o Input de la Simulacin
Los datos que alimentan el modelo de simulacin pueden ser fijos que usualmente son ms bien
considerados como parmetros de la simulacin o bien generarse en forma aleatoria de acuerdo a
ciertas condiciones de distribucin de estos valores casi siempre numricos, y finalmente es posible
contar con mediciones reales tomadas en terreno, las cuales al quedar almacenadas en archivos, por
ejemplo, permiten su recuperacin durante el proceso de la simulacin, para constituir una fuente realista
de la situacin modelada.
2.2.1 Generacin de Nmeros Aleatorios
La generacin de valores aleatorios le da un grado de incerteza al comportamiento del modelo. Si bien es
posible determinar que ciertos valores que alimentan el modelo se comportan de acuerdo a diferentes
tipos de distribuciones estadsticas, en el gran porcentaje de los casos, el uso de la distribucin uniforme
en la cual todos los nmeros de un rango tienen la misma posibilidad de salir es suficiente para
soportar diferentes modelos.
Para producir estos datos es necesario contar con herramientas que generen nmeros aleatorios en
ciertos intervalos y con cierta distribucin especificada en el modelo.
En C#la generacin de nmeros aleatorios est resuelta por una clase llamada Random, cuyo principal
propsito es generar nmeros aleatorios dentro de un rango especificado. Un programa que utilice
Random para la generacin de nmeros, depende de dos principales declaraciones: el constructor y el
mtodo Next().
2.2.1.1 Constructor de Random
Existen diferentes versiones del constructor, las cuales por sobrecarga reciben distintos parmetros.
El constructor simple no recibe parmetros:
Random num = new Random();
El constructor con semilla permite su inicializacin estableciendo una semilla de aleatoriedad, de manera
que no se repitan las secuencias de nmeros entregados. Para darle un grado de variabilidad a esta
generacin de nmeros, se recomienda el uso de una semilla que en cada llamado al programa tenga un
valor diferente. El usar un nmero fijo o constante, es equivalente funcionalmente al constructor sin
parmetros: la secuencia de nmeros aleatorios ser idntica en cada ejecucin desde cero del
programa. Para la semilla, hay dos alternativas: utilizar un nmero entregado por el usuario, que se
espere vaya variando en cada ejecucin, o utilizar un valor del reloj del computador, el cual se obtiene del
uso de DateTime.Now objeto que se detalla ms adelante en este documento. Este objeto tiene un
campo llamado Millisecond, el cual indica la parte de milisegundos (de 0 a 999) de la hora actual.
Random num = new Random(DateTime.Now.Millisecond);

IIC 1102 Pgina: 2
Simulacin Computacional con C# Rodrigo Sandoval U.
2.2.1.2 Generacin de nmeros con Next
El mtodo Next() tiene varias versiones, las cuales por sobrecarga de mtodos ofrecen
comportamientos levemente diferentes y tiles en situaciones distintas. Las dos versiones principales son
las siguientes, y ambas incluyen un valor que representa el lmite superior no incluido del rango de
valores posibles:
int numero1 = num.Next(11); // numero1 tendr un valor entre 0 y 10
int numero2 = num.Next(5,11); // numero2 tendr un valor entre 5 y 10
2.2.1.3 Ejemplo Bsico de Random
A continuacin, un ejemplo de un programa que genera 10 nmeros aleatorios entre 1 y 10.
using System;

class MainApp {
static void Main() {
Random rn = new Random(DateTime.Now.Millisecond);
for(int n=0; n<10 ; n++)
Console.WriteLine(Nmero: {0}, rn.Next(1,11)); // Nmeros entre 1 y 10
Console.ReadLine();
}
}
En el ejemplo anterior resulta relevante analizar las siguientes lneas:
- La instanciacin de un nuevo generador de nmeros aleatorios: Random rn = new Random(...)
- Le generacin de un nuevo nmero: rn.Next(1,11);
La primera lnea se refiere a la creacin de un nuevo generador de nmeros aleatorios, instanciado como
rn. Como argumento al constructor, se entrega la semilla de generacin, que en este caso es un nmero
de 0 a 999 (correspondiente a los milisegundos de la hora actual). Este nmero, que segn el instante en
que se ejecute la lnea, tendr uno de 1.000 valores posibles, inicializar el punto de partida de la serie
de generacin de nmeros aleatorios, asegurando que la posibilidad de que se repita una secuencia de
nmeros generados, sea una en mil.
La segunda lnea relevante de conocer es la que entrega un nuevo nmero: rn.Next(1,11),
indicando que los valores posibles van entre el 1 y el 10 (11-1).
2.2.1.4 Generacin de Valores Aleatorios en Otras Escalas
En muchos casos, el uso de valores enteros directamente no es parte del contexto del problema
modelado. Por tal razn, existen estrategias de aprovechamiento del comportamiento de Random
descrito anteriormente, que permiten generar estos nmeros en otras escalas.
Generacin de Verdadero o Falso Aleatoriamente.
La conversin es simple, si se toma la generacin de nmeros enteros aleatorios entre 0 y 1 se puede
tener una conversin en que 0 corresponde a False (o false en C#) y 1 corresponde a Verdadero (true en
C#).
using System;

class MainApp {
static void Main() {
Random rn = new Random(DateTime.Now.Millisecond);
for(int n=0; n<10 ; n++)
if( rn.Next(2) == 1 ) // Valores entre 0 y 1
Console.WriteLine(VERDADERO);
else Console.WriteLine(FALSO);
Console.ReadLine();
}
}
IIC 1102 Pgina: 3
Simulacin Computacional con C# Rodrigo Sandoval U.
Generacin de Valores Reales Aleatoriamente.
La primera decisin que hay que tomar es cuntos decimales son relevantes para el modelo
representado. Si la cantidad de decimales relevantes son 2, entonces, se generan nmeros enteros que
se dividen por 100 (10 elevado a 2).
using System;

class MainApp {
static void Main() {
Random rn = new Random(DateTime.Now.Millisecond);
for(int n=0; n<10 ; n++) // 10 nmeros reales aleatorios entre 0.00 y 99.99
Console.WriteLine(Nmero: {0}, rn.Next(1,10001)/100);
Console.ReadLine();
}
}

Generacin con Diferente Probabilidad
Un modelo particular puede plantear algo como la cantidad de personas que entran en cada instante de
tiempo es de 1 con 20% de probabilidad, 2 con 30% y 3 con 50%. Esta situacin una vez ms puede
modelarse con la generacin de nmeros enteros aleatorios, con la adaptacin en funcin de los
porcentajes de probabilidades.
Es decir, si un caso tiene 20% de probabilidades de salir, implica que de 10 nmeros (1 al 10) la
probabilidad de que salga un 1 un 2 es exactamente de 10%+10% =20%. As, el siguiente 30% se da
cuando salen el 3, 4 5, y el 50% restante con cualquier nmero entre 6 y 10. En ese caso, el ejemplo
podra plantearse en C#.
using System;

class MainApp {
static void Main() {
Random rn = new Random(DateTime.Now.Millisecond);
int numero = rn.Next(1,11);
if(numero <= 2) Console.WriteLine(20%);
if(numero>2 && numero<=5) Console.WriteLine(30%);
if(numero>5) Console.WriteLine(50%);
Console.ReadLine();
}
}

2.2.2 Carga de Datos Reales desde Archivos
En muchos casos, ms que asumir comportamientos de acuerdo a una distribucin estadstica, es factible
contar con datos reales, en muchos casos medidos en su generacin real. Por ejemplo, la cantidad de
autos llegados a una interseccin por unidad de tiempo, la cantidad de clientes que llegan a la caja en un
banco, etc.
En estos casos, conociendo el comportamiento de cierto parmetro en forma real, estos datos alimentan
el sistema de simulacin, el cual procesa la informacin entrante segn la lgica.
La informacin se almacena en archivos de datos, cuyo caso ms comn es simplemente el formato de
texto plano, cada lnea del archivo representando un dato puntual. El archivo es ledo antes de comenzar
la simulacin y sus datos son almacenados en una representacin de cola, o alguna estructura que emule
la misma generacin de los datos, secuencialmente en el tiempo.

IIC 1102 Pgina: 4
Simulacin Computacional con C# Rodrigo Sandoval U.
2.3 Ejecucin de la Simulacin
Uno de los aspectos ms importantes en una simulacin es el manejo del tiempo, pues los sistemas
normalmente se desenvuelven de acuerdo a una componente temporal. En este punto, la alternativa ms
simple es emplear una componente de tiempo discreto. Segn este enfoque, el funcionamiento del
sistema se puede predecir dentro de unidades discretas de tiempo (por ejemplo, segundos o minutos, e
incluso das). La eleccin de esta unidad resulta fundamental, pues introducir cierto margen de error en
la simulacin.
Otro aspecto fundamental es la alimentacin de la simulacin con datos de entrada reales. Las
simulaciones usualmente llevan consigo una gran cantidad de trabajo de campo recogiendo valores de
entrada. Por ejemplo, para simular los tacos que se forman en una interseccin ser necesario tomar
datos sobre la afluencia de vehculos por cada calle que concurre a la interseccin.
Existen bases tericas que pueden aplicarse a distintos modelos de simulacin, tal es el caso de la
Teora de Colas para la simulacin de filas en las que usuarios esperan ser atendidos, o Dinmica para
la simulacin de cuerpos en movimiento. En general, una simulacin requerir de algn sustento terico
que guiar el funcionamiento del sistema, y por consiguiente depender de cada caso en particular.
En esta seccin se presenta un modelo de simulacin, junto con su implementacin, que pretende ilustrar
esta importante aplicacin de los computadores. El modelo planteado no hace uso de resultados tericos
importantes, con el objetivo de hacerlo ms fcil de entender. Sin embargo, presenta conceptos de
mucha importancia, como el manejo del tiempo discreto, la representacin de las entidades que forman el
modelo como estructuras de datos del lenguaje de programacin empleado, y el manejo de algunos
parmetros de configuracin.
2.3.1 El Manejo del Tiempo
Tal como se indic, uno de los elementos relevantes de controlar es el tiempo. Ya sea que el contexto de
la simulacin requiere una unidad discreta basada en segundos, minutos, horas, das, semanas, o incluso
meses, siempre es necesario ir registrando el paso del tiempo con un contador. Este registro puede ser
tan simple como utilizar un contador entero que se incrementa de uno en uno, hasta determinar el fin de
la simulacin. En este caso, se usa por convencin el concepto de Tics, refirindose a que cada Tic es un
incremento en el contador de tiempo.
Para esto, dos objetos existentes en el framework de .NET resuelven el manejo del tiempo y lapsos.
2.3.1.1 DateTime
En algunos casos, se requiere un registro del tiempo ms preciso que un simple contador, por lo que se
usa una estructura que almacena los datos referentes al tiempo. En C#se cuenta con tal tipo de
estructura, en la forma de una clase de nombre DateTime.
En particular, existe una propiedad de DateTime, que ofrece todos los datos de la hora actual (al
momento de ser consultada), incluyendo hasta los milisegundos: ao-mes-da-hora-min-seg-miliseg. Esta
es DateTime.Now y se usa como referencia temporal para inicializaciones, o incluso, comparaciones
referenciales.
La instanciacin de un objeto de tipo DateTime aprovecha las facultades del Constructor. Por ejemplo:
using System;
// Nueva instancia DateTime con el 28 del 7 de 1979 a las 10:35:05 PM.
DateTime dateTime = new DateTime(1979, // Ao
07, // Mes
28, // Da
22, // Hora
35, // Minutos
5, // Segundos
15); // Milisegundo
Console.WriteLine("{0:F}", dateTime); // Escribe la fecha
IIC 1102 Pgina: 5
Simulacin Computacional con C# Rodrigo Sandoval U.
2.3.1.2 Propiedades, Mtodos y Operadores principales de DateTime
Propiedades
Date Obtiene el componente correspondiente a la fecha de esta instancia.
Day Obtiene el da del mes representado por esta instancia.
DayOfWeek Obtiene el da de la semana representado por esta instancia.
DayOfYear Obtiene el da del ao representado por esta instancia.
Hour
Obtiene el componente correspondiente a la hora de la fecha representada por esta
instancia.
Millisecond
Obtiene el componente correspondiente a los milisegundos de la fecha representada por
esta instancia.
Minute
Obtiene el componente correspondiente a los minutos de la fecha representada por esta
instancia.
Month
Obtiene el componente correspondiente al mes de la fecha representada por esta
instancia.
Now Obtiene un DateTime que constituye la fecha y hora locales actuales de este equipo.
Second
Obtiene el componente correspondiente a los segundos de la fecha representada por esta
instancia.
Ticks Obtiene el nmero de pasos que representan la fecha y hora de esta instancia.
TimeOfDay Obtiene la hora del da para esta instancia.
Today Obtiene la fecha actual.
UtcNow
Obtiene un DateTime que representa la fecha y hora locales actuales de este equipo y que
se expresa en forma de hora universal coordinada (UTC).
Year Obtiene el componente correspondiente al ao de la fecha representada por esta instancia.
Mtodos
AddDays Agrega el nmero de das especificado al valor de esta instancia.
AddHours Agrega el nmero de horas especificado al valor de esta instancia.
AddMilliseconds Agrega el nmero de milisegundos especificado al valor de esta instancia.
AddMinutes Agrega el nmero de minutos especificado al valor de esta instancia.
AddMonths Agrega el nmero de meses especificado al valor de esta instancia.
AddSeconds Agrega el nmero de segundos especificado al valor de esta instancia.
AddTicks Agrega el nmero de pasos especificado al valor de esta instancia.
AddYears Agrega el nmero de aos especificado al valor de esta instancia.
Compare
Compara dos instancias de DateTime y devuelve una indicacin de sus valores
relativos.
CompareTo
Compara esta instancia con un objeto especificado y devuelve una indicacin de los
valores relativos.
Operadores
Suma (+)
Agrega un intervalo de tiempo especificado a una fecha y hora especificadas,
generando una fecha y hora nuevas.
Igualdad (==) Determina si dos instancias especificadas de DateTime son iguales.
Mayor que (>y >=)
Determina si un DateTime especificado es mayor que otro DateTime
especificado.
Desigualdad (!=) Determina si dos instancias especificadas de DateTime no son iguales.
Menor que (<y <=)
Determina si un DateTime especificado es menor que otro DateTime
especificado.
Resta (-) Sobrecargado. Resta un DateTime especificado de un DateTime especificado.
IIC 1102 Pgina: 6
Simulacin Computacional con C# Rodrigo Sandoval U.
Ejemplos prcticos del uso de DateTime como parte de los datos de una clase utilizada en una
simulacin se ven en la siguiente seccin de ejemplos.
2.3.1.3 TimeSpan
Por su parte, el manejo de lapsos o intervalos de tiempo se resuelve con TimeSpan. Esencialmente ste
representa el objeto resultante de la diferencia entre dos objetos de tipo DateTime, y es el que se usa
para representar los Tics o unidades de tiempo relevante.
Existen varias versiones del constructor de TimeSpan, las que varan principalmente en la cantidad de
enteros que reciben como parmetro, lo cual determina la cantidad de tiempo que incluye el intervalo de
tiempo. Algunas de estas diferentes versiones se demuestran en los siguientes ejemplos.
using System;

TimeSpan t1 = new TimeSpan(0, 1, 0); // 0 horas, 1 minuto, 0 segundos
TimeSpan t2 = new TimeSpan(1, 0, 0, 0); // 1 da, 0 horas, 0 min, 0 seg
TimeSpan t3 = new TimeSpan(0, 0, 0, 0, 1); // 1 dd, 0 hh, 0 mm, 0 s, 1 mseg.

A continuacin se muestra un ejemplo prctico del uso de TimeSpan y DateTIme juntos en una
simulacin. En este caso, el reloj de control de la simulacin deber comenzar a las 13:30. Como
referencia de fecha, se utiliza la fecha actual por medio de DateTime.Now que corresponde a un objeto
de tipo DateTime asignado a la fecha del computador en el momento en que se invoca.
using System;

. . .

// Declaracin del reloj que llevar la cuenta de tiempo de simulacin
DateTime reloj = DateTime.Now; // Reloj puesto a la fecha y hora actual
// Se ajusta el reloj a la hora de inicio de la simulacin
reloj.Hour = 13; reloj.Minute = 30; reloj.Second = 0; reloj.Millisecond = 0;

// Declaracin de la hora de fin -> 30 minutos despus del inicio.
DateTime fin = reloj + new TimeSpan(0,30,0);

// Declaracin de la unidad significativa de tiempo -> 1 minuto
TimeSpan tick = new TimeSpan(0, 1, 0); // 0 horas, 1 minuto, 0 segundos

. . .
while(reloj <= fin) { // Mientras el reloj no sea igual a la hora de fin
. . .
Reloj += tick; // Se incrementa el contador de tiempo en un tick
}
. . .
2.3.2 Colas en C#
El uso de colas en simulacin permite representar la llegada de objetos (personas, autos, rdenes de
compra, etc.) en el tiempo y que sern atendidos como parte del proceso de simulacin. El uso de colas
es un concepto tradicionalmente referido en simulacin computacional.
En el caso del lenguaje C#y del framework de .NET, reconociendo las colas como una estructura
frecuentemente requerida, se ha incluido su definicin completa en un objeto denominado Queue, que
ofrece el comportamiento tradicional de una cola, en la cual los elementos nuevos ingresan slo al final y
se sacan elementos slo por adelante. Esta clase est disponible dentro del Namespace
System.Collections.
IIC 1102 Pgina: 7
Simulacin Computacional con C# Rodrigo Sandoval U.
Esta clase Queue puede almacenar objetos de cualquier tipo, ya que su elemento base es Object, que es
el objeto base del cual derivan absolutamente todos los objetos definidos por los desarrolladores. De esa
manera, se pueden crear fcilmente colas para almacenar elementos bsicos como nmeros (int, double,
etc.) o cualquier otro elemento definido en una clase del programa.
Las operaciones estndar de una cola son: Agregar un Elemento (que lo ubica al final de la cola de
elementos ya agregados); Sacar el Primero (slo se sacan elementos por el inicio de la cola); Ver el
Primero (slo se puede ver el elemento que est en primer lugar sin sacarlo de la cola); y ver el Largo de
la lista (para determinar la cantidad de elementos que estn en la cola).
Formalmente, los elementos de la clase Queue son los siguientes:
Mtodos
void Enqueue(Object) Este mtodo encola un elemento derivado de la clase Object.
Object Dequeue()
Saca el primer elemento de la cola, retornndolo para ser utilizado. Este
mtodo no verifica si la cola cuenta con elementos, por lo que es
conveniente agregar una clusula condicional verificando que existan
elementos antes de retirar el primero, o bien aprovechar un bloque de control
de excepciones try-catch.
Object Peek()
Funciona equivalentemente a Dequeue(), con la diferencia de que el objeto
en primer lugar de la cola no es retirado, sino que permanece.
Propiedades
int Count
Propiedad que retorna un nmero mayor o igual a cero, indicando la cantidad de
elementos de la cola.
Count
Enqueue() Dequeue()
Peek()

La siguiente seccin incluye diferentes ejemplos que hacen uso exhaustivo de la definicin de Queue, de
modo de ilustrar el comportamiento de cada uno de estos mtodos y propiedad, as como dar una nocin
de la manera de utilizar esta clase para apoyar el proceso de simulacin.
IIC 1102 Pgina: 8
Simulacin Computacional con C# Rodrigo Sandoval U.
3 Ejemplos
Entre los ejemplos que ilustran la simulacin conceptual, se distinguen diversos tipos de complejidad. A
medida que los ejemplos van involucrando ms elementos de simulacin y de resultados, se van
programando y utilizando objetos ms complejos.
3.1 Simulacin de Cadena de Correo
Las cadenas enviadas por correo (originalmente en cartas de papel, hoy por e-mail), son seguidas por
muchos y odiadas por otros tantos. En este ejemplo se pretende ver el comportamiento de una nueva
cadena por correo, la cual cuenta con ciertas caractersticas que definen su funcionamiento. Esta cadena
en particular indica que para ser continuada, cada receptor deber re-enviar a 4 nuevas personas. Para
efectos del ejemplo se han tomado ciertas simplificaciones a un caso realista, de modo de concentrar el
modelamiento en los conceptos vistos en este documento.
La forma de funcionamiento es la siguiente:
De las 4 personas a quienes se reenva, existe un 66% de probabilidad de que la persona
receptora no lo tome en cuenta y corte su parte de la cadena.
El periodo que se toma en leer y reenviar es de 24 horas.
Este programa de simulacin analiza el comportamiento de una cadena, en la medida en que se van
agregando nuevas personas, por un periodo de 30 das.
Al final de la simulacin, se indicarn en pantalla cuntas personas en total recibieron la cadena y
cuntas efectivamente la reenviaron.
Solucin
Esta solucin se implementa en forma directa, sin mayores estructuras especiales. En particular, el
manejo del tiempo, al no requerirse en fechas absolutas, se maneja en forma relativa con un simple
contador de tipo entero, avanzando por un loop o ciclo de 30 iteraciones (representando los 30 das de
simulacin).
Cdigo Fuente Solucin
using System;

class MainApp {
static void Main() {
Random rn = new Random(DateTime.Now.Millisecond);
int enviaron = 1, recibieron = 0, recibieronant = 1; // Se parte con 1 sola persona

for(int i=0; i<30 ; i++) { // loop para 30 das
int rec = 0, env = 0;
Console.Write("Da {0}: ", i+1);
for(int j=0; j<recibieronant; j++) { // p/todos los receptores da anterior
for(int k=0; k<4; k++) { // c/u de los anteriores, envi a 4
rec++;
if( rn.Next(0,3) > 1 ) // Posibilidad de que lo reenve
env++;
}
}
Console.WriteLine(" de:{0} rec:{1} y env:{2}", recibieronant, rec, env);
recibieronant = env;
recibieron += rec;
enviaron += env;
}

Console.WriteLine("En un periodo de simulacin de 30 das:");
Console.WriteLine("Recibieron: {0} personas", recibieron);
Console.WriteLine("Enviaron: {0} personas", enviaron);
Console.ReadLine();
}
}
IIC 1102 Pgina: 9
Simulacin Computacional con C# Rodrigo Sandoval U.
Ejemplo de ejecucin y resultados:
Da 1: de:1 rec:4 y env:3
Da 2: de:3 rec:12 y env:3
Da 3: de:3 rec:12 y env:9
Da 4: de:9 rec:36 y env:14
Da 5: de:14 rec:56 y env:22
Da 6: de:22 rec:88 y env:28
Da 7: de:28 rec:112 y env:32
Da 8: de:32 rec:128 y env:41
Da 9: de:41 rec:164 y env:56
Da 10: de:56 rec:224 y env:70
Da 11: de:70 rec:280 y env:85
Da 12: de:85 rec:340 y env:100
Da 13: de:100 rec:400 y env:140
Da 14: de:140 rec:560 y env:192
Da 15: de:192 rec:768 y env:251
Da 16: de:251 rec:1004 y env:332
Da 17: de:332 rec:1328 y env:450
Da 18: de:450 rec:1800 y env:596
Da 19: de:596 rec:2384 y env:805
Da 20: de:805 rec:3220 y env:1027
Da 21: de:1027 rec:4108 y env:1389
Da 22: de:1389 rec:5556 y env:1803
Da 23: de:1803 rec:7212 y env:2430
Da 24: de:2430 rec:9720 y env:3337
Da 25: de:3337 rec:13348 y env:4488
Da 26: de:4488 rec:17952 y env:5960
Da 27: de:5960 rec:23840 y env:7777
Da 28: de:7777 rec:31108 y env:10201
Da 29: de:10201 rec:40804 y env:13572
Da 30: de:13572 rec:54288 y env:18036
En un periodo de simulacin de 30 das:
Recibieron: 220856 personas
Enviaron: 73250 personas

3.2 Llegada de Clientes a Caja en el Banco
Este ejemplo muestra el simple proceso de la llegada de clientes a una caja de banco y cmo son
atendidos.
En particular se busca mostrar distintas versiones de un mismo ejemplo, agregando ciertos elementos o
simplificando algunas condiciones para ilustrar el uso de los diferentes elementos que tanto la teora,
como la librera de clases del Microsoft .NET framework ofrecen para facilitar estas implementaciones.
Se toman las siguientes condiciones:
El periodo de simulacin es de 30 minutos.
Se conoce el momento de llegada de los clientes a la cola, datos que vienen almacenados en un
archivo de datos. Puede llegar ms de un cliente por minuto.
En un archivo de entrada, clientes.dat, vendr como nico dato por cada lnea, el instante en
que lleg el cliente N (con N: lnea del archivo). Es posible que ms de una lnea contenga el
mismo nmero, representando que ms de un cliente lleg en el mismo instante de tiempo.
Se asume que todos los clientes tienen en promedio la misma cantidad de trmites que realizar,
por lo que se demorarn lo mismo.
IIC 1102 Pgina: 10
Simulacin Computacional con C# Rodrigo Sandoval U.
Se sabe que el nico cajero atendiendo, procesa 1 cliente por minuto. Por esta razn se utilizar
1 minuto como unidad de tiempo significativa.
Instante 1 Instante 2 Instante 3 Instante 4
Orden de Llegada
Atiende 1
cliente por
minuto
1 4

Al finalizar la simulacin interesa conocer:
El total de clientes atendidos por el cajero.
La espera mxima en la cola en minutos.

3.2.1 Solucin 1.0
Esta primera versin del ejemplo se modela y soluciona de la forma ms simple, tomando algunas
suposiciones de la operacin real y utilizando los elementos bsicos del lenguaje C#.
Solucin
Se implementar una cola de clientes, registrando el instante de llegada de cada uno de ellos, de modo
de procesar los momentos de llegada en sincronizacin con el manejo del tiempo de la simulacin,
mientras que se utilizan los instantes de llegada para medir el tiempo de espera de cada cliente, al
compararlo con el momento en que son atendidos.
El proceso general tomar un reloj de tipo nmero entero, funcionando como contador (cronmetro de
minutos), que ir aumentando en 1, cuando haya clientes en cola, o se adelantar hasta el instante en
que llega el siguiente cliente. Es decir, no es necesario una contabilizacin exhaustiva de cada unidad de
tiempo de simulacin, sino que se puede simplificar el proceso computacional involucrado al procesar
slo los instantes en que ocurren eventos relevantes dentro del proceso, como es la atencin de clientes,
mientras que se saltan los instantes en que no hay clientes en la cola.
Cdigo Fuente Solucin
using System;
using System.IO;

// ----------------------------------------------------------------
// Clase Cliente
// Representa un cliente, con su instante de llegada
// ----------------------------------------------------------------
class Cliente {
int llegada;

public Cliente(int l) { llegada = l; }
public int Llegada { get { return(llegada); } }
}

IIC 1102 Pgina: 11
Simulacin Computacional con C# Rodrigo Sandoval U.
// ----------------------------------------------------------------
// Clase Cola
// Representa la cola que se forma frente a la caja. Almacena todos
// los clientes ingresados con su respectivo instante de llegada
// ----------------------------------------------------------------
class Cola {
const int MAX = 30;
Cliente[] clientes;
int cantidad = 0;
string archivo = "clientes.dat";

public Cola() {
clientes = new Cliente[MAX]; // Dimensionamiento

StreamReader sr;
try { sr = new StreamReader(archivo); }
catch (Exception e) {
Console.WriteLine("Error al abrir \"{0}\"\n{1}", archivo, e.ToString());
return;
}

string linea = sr.ReadLine();
while(linea != null) {
Agregar(int.Parse(linea));
linea = sr.ReadLine();
}
sr.Close();
}

// Agregar(): dado un instante de llegada 'l', lo agrega a la cola
public void Agregar(int l) { if(cantidad<MAX) clientes[cantidad++] = new Cliente(l); }

// Primero(): devuelve el primer cliente en la cola
public Cliente Primero() {
if(cantidad>0) return(clientes[0]);
else {
Cliente vacio = new Cliente(0);
return(vacio);
}
}

// Atender(): atiende al primer cliente de la cola, sacndolo de ella
public void Atender() {
if(cantidad>0) {
for(int i=1; i<cantidad ; i++)
clientes[i-1] = clientes[i];
cantidad--;
}
}

public int Cantidad { get { return(cantidad); } }
}


// ----------------------------------------------------------------
// Clase Principal
// ----------------------------------------------------------------
class Principal {
static void Main() {
int reloj = 0; // reloj contador de minutos
Cola cola = new Cola(); // Instancia la cola de clientes
int esperamax = 0;
int cantclientes = cola.Cantidad; // Se registra la cantidad total de clientes

Console.WriteLine("Procesando...");

// Proceso simulacin involucra 30 min o hasta que se acaben los clientes
while(reloj<=30 && cola.Cantidad>0) {
Cliente c = cola.Primero();

if(reloj<c.Llegada) reloj = c.Llegada; // Se avanza reloj al primero
IIC 1102 Pgina: 12
Simulacin Computacional con C# Rodrigo Sandoval U.
else reloj++;
Console.Write(" {0}", reloj);

if( reloj-c.Llegada > esperamax ) esperamax = reloj-c.Llegada;
cola.Atender();
}

// Al final, indica los valores registrados
Console.WriteLine("\nPersonas atendidas: {0}", cantclientes);
Console.WriteLine("Espera mxima: {0}", esperamax);

Console.Write("Presione ENTER..."); Console.ReadLine();
}
}
Ejemplo de Ejecucin
Archivo clientes.dat :
1
1
1
3
6
7
9
11
11
15
16
17
19
19
19
21
22
23
24
26
28
Salida en Pantalla:
Procesando...
1 2 3 4 6 7 9 11 12 15 16 17 19 20 21 22 23 24 25 26 28
Personas atendidas: 21
Espera mxima: 2
Presione ENTER...


3.2.2 Solucin 2.0
Evolucionando un poco el ejemplo anterior, esta segunda versin profundiza un poco en el uso de la
clase Queue como apoyo al modelamiento de la cola de clientes que llegan al banco, de manera que la
implementacin de la cola de clientes se muestra ms simple en cdigo.
Particularmente, el enfoque de esta solucin, implementa la clase Cola, heredando de Queue,
complementando algunos mtodos especiales para el contexto de este problema, en particular el
constructor.
IIC 1102 Pgina: 13
Simulacin Computacional con C# Rodrigo Sandoval U.
Cdigo Fuente
using System;
using System.IO;
using System.Collections;


// ----------------------------------------------------------------
// Clase Cliente
// Representa un cliente, con su instante de llegada
// ----------------------------------------------------------------
class Cliente {
int llegada;

public Cliente(int l) { llegada = l; }
public int Llegada { get { return(llegada); } }
}


// ----------------------------------------------------------------
// Clase Cola (Hereda de Queue)
// Representa la cola que se forma frente a la caja. Almacena todos
// los clientes ingresados con su respectivo instante de llegada
// ----------------------------------------------------------------
class Cola : Queue {
string archivo = "clientes.dat";

public Cola() {
StreamReader sr;
try { sr = new StreamReader(archivo); }
catch (Exception e) {
Console.WriteLine("Error al abrir \"{0}\"\n{1}", archivo, e.ToString());
return;
}

string linea = sr.ReadLine();
while(linea != null) {
Enqueue(new Cliente(int.Parse(linea)));
linea = sr.ReadLine();
}
sr.Close();
}

// Primero(): devuelve el primer cliente en la cola
public Cliente Primero() {
if(Count>0) return( (Cliente) Peek() );
else return(new Cliente(0));
}

// Atender(): atiende al primer cliente de la cola, sacndolo de ella
public void Atender() { if(Count>0) Dequeue(); }

public int Cantidad { get { return(Count); } }
}


// ----------------------------------------------------------------
// Clase Simulacion
// ----------------------------------------------------------------
class Simulacion {
int atendidos = 0;
int esperamax = 0;
int encola = 0;

public void Simular(int tiempo) {
int reloj = 1; // reloj contador de minutos
Cola cola = new Cola(); // Instancia la cola de clientes

Console.WriteLine("Procesando...");
encola = cola.Cantidad;

IIC 1102 Pgina: 14
Simulacin Computacional con C# Rodrigo Sandoval U.
// Proceso dura 30 minutos o hasta que se acaben los clientes
while(reloj<=tiempo && cola.Cantidad>0) {
Cliente c = cola.Primero();

if(reloj<c.Llegada) reloj = c.Llegada; // Se avanza reloj al primero
else reloj++;
Console.Write(" {0}", reloj);

if( reloj-c.Llegada > esperamax ) esperamax = reloj-c.Llegada;
cola.Atender(); atendidos++;
encola = cola.Cantidad;
}
}

public int Atendidos { get { return(atendidos); } }
public int EsperaMax { get { return(esperamax); } }
public int EnCola { get { return(encola); } }
}

// ----------------------------------------------------------------
// Clase Principal
// ----------------------------------------------------------------
class Principal {
static void Main() {
Simulacion s = new Simulacion();
s.Simular(30); // Efecta el proceso completo de simulacin

// Al final, indica los valores registrados
Console.WriteLine("\nPersonas atendidas: {0}", s.Atendidos);
Console.WriteLine("Espera mxima: {0}", s.EsperaMax);
Console.WriteLine("Personas en Cola: {0}", s.EnCola);

Console.Write("Presione ENTER..."); Console.ReadLine();
}
}
3.2.3 Solucin 3.0
En esta tercera versin del mismo caso de simulacin ofrece algunas diferencias al problema original. En
primer lugar, la llegada de los clientes se mide en horas absolutas (hh:mm) y no en una referencia relativa
de minutos. Por otro lado, la llegada de los clientes no se conoce y se determina en forma aleatoria. En
cada instante de simulacin podrn llegar entre 0 y 2 clientes. La tercera diferencia, relacionada con la
implementacin, es que se simplifica la definicin de la cola de clientes (utilizando directamente la clase
Queue).
Dado el uso de minutos en la forma hh:mm, se aprovechar la clase DateTime, identificando para cada
cliente el instante de llegada. A la vez, el control de la evolucin del tiempo de la simulacin, tambin
tomar el mismo tipo de objeto para ir contabilizando los minutos en la forma hh:mm. Para representar la
unidad relevante de tiempo se utilizar un objeto de tipo TimeSpan, como un tick.
Cdigo Fuente
using System;
using System.IO;
using System.Collections;

// ----------------------------------------------------------------
// Clase Cliente
// Representa un cliente, con su instante de llegada
// ----------------------------------------------------------------
class Cliente {
DateTime horallegada;

public Cliente(DateTime hl) { horallegada = hl; }

public DateTime HoraLlegada { get { return(horallegada); } }
}

IIC 1102 Pgina: 15
Simulacin Computacional con C# Rodrigo Sandoval U.
// ----------------------------------------------------------------
// Clase Simulacion
// ----------------------------------------------------------------
class Simulacion {
int atendidos = 0;
int maxespera = 0;

public void Procesar() {
DateTime reloj = new DateTime(2000,1,1,13,30,0,0);
DateTime horafin = new DateTime(2000,1,1,14,00,0,0);
TimeSpan tick = new TimeSpan(0,1,0);
Random rn = new Random(DateTime.Now.Millisecond);
Queue cola = new Queue();

while( reloj <= horafin ) {
int clientes = rn.Next(0,3);
for(int i=0; i<clientes; i++)
cola.Enqueue(new Cliente(reloj));
Console.WriteLine("{0}:{1}, llegaron {2} clientes a una cola con {3}",
reloj.Hour, reloj.Minute, clientes, cola.Count);

if(cola.Count>0) { // Siempre verificar largo de la cola antes de procesar.
Cliente sale = (Cliente) cola.Dequeue();
atendidos++;
if(maxespera < (reloj.Minute - sale.HoraLlegada.Minute))
maxespera = (reloj.Minute - sale.HoraLlegada.Minute);
}

reloj += tick;
}
}

public int Atendidos { get { return(atendidos); } }
public int MaxEspera { get { return(maxespera); } }
}

// ----------------------------------------------------------------
// Clase Principal
// ----------------------------------------------------------------
class Principal {
static void Main() {
Simulacion sim = new Simulacion();

sim.Procesar();

Console.WriteLine("Cliente atendidos: {0}", sim.Atendidos);
Console.WriteLine("Mxima espera: {0}", sim.MaxEspera);

Console.Write("Presione ENTER..."); Console.ReadLine();
}
}

IIC 1102 Pgina: 16
Simulacin Computacional con C# Rodrigo Sandoval U.
3.3 Simulacin de las Colas en un Supermercado
En este ejemplo se muestra una simulacin que modela las colas que se forman en las cajas de un
supermercado. El desarrollo de este ejemplo es informal, en el sentido de que no se basa en formalismos
tericos para desarrollar el modelo.
3.3.1 Definicin del Problema
Un supermercado recibe una cantidad regular de clientes diariamente, los cuales traen consigo una lista
de los productos que van a comprar. Los clientes buscan sus productos en los estantes y pasan de
inmediato a la caja que ms les convenga (en la que deban esperar menos en la fila). Una vez que han
pagado se retiran del local.
Para determinar cul es la caja ms conveniente, los clientes miran las compras que llevan los clientes en
la cola, y eligen aquella caja con menos productos delante de ellos (como es natural).
3.3.2 Caractersticas del Modelo
El modelo de simulacin que se emplear hace ciertas suposiciones sobre el comportamiento del
sistema:
Los clientes llegan al supermercado segn una tasa regular todos los das, y siguiendo un
comportamiento de compras tambin regular.
Un cliente se demora un tiempo constante en ubicar cada uno de los productos que comprar.
Las cajeras pasan por el lector de barras los productos a un ritmo constante, es decir, una
determinada cantidad de productos por minuto.
Una vez que un cliente elige una caja en la que har fila, no se mover a otra.
Se considera despreciable el tiempo que le toma al cliente pagar por sus compras y recibir su
vuelto.
La unidad de tiempo discreto que se emplear en la simulacin es equivalente a un minuto,
descartando las tareas que puedan llevarse a cabo en fracciones restantes. Por ejemplo, si a un
cajero le toma 10 segundos pasar los artculos de un cliente, el resto de ese minuto lo
desperdiciar y no lo emplear atendiendo a otro cliente.
El modelo se centrar en la simulacin del tiempo, ejecutando en cada unidad discreta de tiempo las
actividades propias del supermercado y los clientes:
Se verificar cules clientes han terminado de buscar sus productos y se les colocar en la fila de
la caja.
Cada cajera atender al primer cliente en la fila, y le pasar tantos productos como pueda en una
unidad de tiempo.
3.3.3 Mediciones Requeridas
Con fines estadsticos, es necesario guardar la visin que tuvo cada cliente al llegar a la caja, es decir,
cuntos productos tienen los clientes que estn delante de l, y cuntos son estos clientes. Esto se
llevar a cabo en forma acumulativa con ayuda de la clase, de manera que sea posible obtener
promedios al final de la simulacin. Adems, resulta valioso almacenar los valores mximos, tanto para el
tiempo de espera como para el largo de cola en cada caja.
IIC 1102 Pgina: 17
Simulacin Computacional con C# Rodrigo Sandoval U.
3.3.4 Solucin
Los clientes del supermercado se representarn mediante una clase Cola, en donde cada
elemento corresponder con un cliente. Para cada cliente se almacenar:
o Hora de llegada al supermercado.
o Cantidad de productos que pretende comprar (generado aleatoriamente).
hh:mm 1
compras1
Orden de Llegada
1 4
hh:mm 2
compras2
hh:mm 3
compras3
hh:mm 4
compras4

Las cajas se representarn tambin como una clase, el cual ofrece en su interfaz funciones de mucha
utilidad, como determinar la caja con menos productos para que un cliente se pueda ubicar en ella. El
nico dato que es necesario almacenar es la cantidad de productos que lleva cada uno de los clientes
que hacen fila en las cajas.
compras1
compras2
comprasN
. . .
Caja1
Caja2
compras1
compras2
comprasN
. . .
CajaN
compras1
compras2
comprasN
. . .

IIC 1102 Pgina: 18
Simulacin Computacional con C# Rodrigo Sandoval U.
Por otra parte, ser necesario llevar constancia del tiempo actual (hora), para saber en qu momento los
clientes pasarn a las cajas y cmo irn evolucionando las colas al cumplirse cada unidad de tiempo.
De los resultados arrojados por estas estadsticas dependern los posibles cambios de configuracin que
deban llevar a cabo los administradores del negocio. Por ejemplo, el aumento o disminucin de cajas
disponibles, la reubicacin de los productos para que los clientes pasen menos tiempo ubicndolos, la
capacitacin de las cajeras para que pasen ms productos por minuto por el lector de barras, etc.
Entradas del Programa
Los datos de los clientes se leen desde un archivo de entrada, llamado clientes.txt.
El archivo tiene un formato riguroso. En la primera lnea se indica el nmero de clientes que concurrir al
supermercado en el da, seguido de una lnea por cada uno de estos clientes.
Cada una de las lneas de clientes est compuesta por dos enteros que indican la hora de llegada al
supermercado (hora y minutos).
A modo de ejemplo se incluye aqu un archivo de entrada, que considera 25 clientes.
25
10 01
10 05
10 05
10 05
10 05
10 05
10 05
10 07
10 08
10 08
10 10
10 12
10 15
10 20
10 22
10 22
10 22
10 22
10 22
10 22
10 35
10 45
10 50
10 50
10 55
El nmero de cajas que se desea emplear se pregunta como primer paso dentro del programa.
Desarrollo de la solucin
Para esta solucin, los objetos relevantes son:
- Cliente. Representado por una clase cuyos atributos son: la hora de llegada (de tipo DateTime)
y la cantidad de compras (int). Estos valores son pasados como parmetros al constructor y
adicionalmente se definen las propiedades que dan acceso a los dos atributos privados del
objeto Cliente.
- Cajas. Un objeto ms complejo, que maneja un arreglo de colas de caja y ofrece una serie de
mtodos que resuelven las preguntas ms requeridas, como cul es la caja con la cola ms
corta? cuntos productos hay en la caja N? adems de procesar cada cola en una unidad de
tiempo de simulacin.
IIC 1102 Pgina: 19
Simulacin Computacional con C# Rodrigo Sandoval U.
- Estadstica. Un objeto que guarda los valores numricos que se van obteniendo por el proceso
de atencin de las cajas y que finalmente sirve para mostrar en pantalla los resultados
estadsticos medidos durante la simulacin.
- La cola de llegada de los clientes al supermercado se maneja como un objeto de tipo Queue y
se incluye la lgica de inicializacin de esta cola al leer los datos que vienen en el archivo de
llegadas. El procesamiento de este archivo va creando objetos de tipo cliente, tomando la hora y
minutos que indica la lnea respectiva del archivo y tambin generando un nmero aleatorio de
productos a comprar, por medio de la clase Random.

Cdigo Fuente Solucin
using System;
using System.IO;
using System.Collections;

class Cliente {
private DateTime dt;
private int compras;

public Cliente(int hora, int minuto) {
dt = new DateTime(DateTime.Now.Year,DateTime.Now.Month,DateTime.Now.Day,
hora,minuto,0,0);
compras = 0;
}

public void Imprimir() { Console.WriteLine("Hora: {0} - compras: {1}",dt,compras); }

public DateTime HoraRegistro { get { return dt; } }

public bool registro_vacio {
get{
if(compras == 0) return true;
else return false;
}
}

public int registro_compra {
get { return compras; }
set { compras = value; }
}
}

class Cajas {
private int [,] cajas;
private int num, max_caja;

public Cajas(int num_cajas, int max_clientes_caja) {
num = num_cajas;
max_caja = max_clientes_caja;
cajas = new int[num_cajas,max_clientes_caja];
}

public void Insertar(int prod) {
int i;
for(i = 0; i < num && cajas[MejorCaja(),i] != 0; i++);
cajas[MejorCaja(),i] = prod;
}

public int MejorCaja() {
int cant_aux = 0, cant = Int32.MaxValue, mejor = 0;
for(int i = 0; i < num; i++) {
for(int j = 0; j < max_caja; j++)
cant_aux += cajas[i,j];

if(cant_aux < cant) {
mejor = i;
cant = cant_aux;
IIC 1102 Pgina: 20
Simulacin Computacional con C# Rodrigo Sandoval U.
}
cant_aux = 0;
}
return mejor;
}

public int ProductosEnCaja(int caja) {
int num_prod = 0;
for(int i = 0; i < max_caja; i++) num_prod += cajas[caja,i];
return num_prod;
}

public int ColaCaja(int caja) {
int num_clientes = 0;
for(int i = 0; i < max_caja; i++)
if(cajas[caja,i] != 0)
num_clientes++;

return num_clientes;
}

public int ProdsPrimerCliente(int caja) { return cajas[caja,0]; }

public void Cobrar(int caja, int prod) { cajas[caja,0] -= prod; }

public void SacarCaja(int caja) {
for(int i = 1; i < max_caja; i++)
cajas[caja,i-1] = cajas[caja,i];
}

public bool QuedanClientes() {
for(int i = 0; i < num; i++)
for(int j = 0; j < max_caja; j++)
if(cajas[i,j] > 0) return true;

return false;
}

public void Imprimir() {
for(int i = 0; i < num; i++) {
Console.Write("\n\t Caja n {0}: ",i);
for(int j = 0; j < max_caja; j++)
if(cajas[i,j] != 0)
Console.WriteLine(" {0}",cajas[i,j]);
}
Console.WriteLine("");
}

public void Atender() {
int caja, cobrados;

for( caja = 0; caja < num; caja++) {
if(ProductosEnCaja(caja) > 0) {
if(ProdsPrimerCliente(caja) < 3)
cobrados = ProdsPrimerCliente(caja);
else cobrados = 3;

Cobrar(caja,cobrados);

if(ProdsPrimerCliente(caja) == 0)
SacarCaja(caja);
}
}
}
}

class Estadistica {
private int LargoTotal;
private int LargoMax;

public Estadistica() { LargoTotal = 0; LargoMax = 0; }
IIC 1102 Pgina: 21
Simulacin Computacional con C# Rodrigo Sandoval U.

public int LargoT {
get { return LargoTotal; }
set { LargoTotal = value; }
}

public int LargoM {
get { return LargoMax; }
set { LargoMax = value; }
}
}


class CMain {
public static void Main() {
DateTime dt = new DateTime(DateTime.Now.Year,DateTime.Now.Month,DateTime.Now.Day,
9,0,0,0);
int NumClientes = 0, EsperaTotal = 0, EsperaMax = 0;
int cajas = 0;

Console.WriteLine("SIMULACION DE SUPERMERCADO");
Console.Write("Indique la cantidad de cajas atendiendo: ");
cajas = int.Parse(Console.ReadLine());

Queue Clientes = new Queue();
Cajas Cajas = new Cajas(cajas,10);
Estadistica [] estadistica = new Estadistica[cajas];

for(int i = 0; i < Estadistica.Length; i++)
estadistica[i] = new Estadistica();

try {
StreamReader sr = new StreamReader("clientes.txt");
Console.WriteLine("Leyendo datos de entrada");

NumClientes = int.Parse(sr.ReadLine());
string str;
System.Random rn = new System.Random(System.DateTime.Now.Millisecond);
for(int i = 0; (str = sr.ReadLine()) != null; i++) {
string[] hh_mm = str.Split(' ');
Cliente cr = new Cliente (int.Parse(hh_mm[0]),
int.Parse(hh_mm[1]));
cr.registro_compra = rn.Next(0,99);
Clientes.Enqueue(cr);
}

sr.Close();
} catch(Exception e) {
Console.WriteLine("No se abre archivo clientes.txt: {0}",e.Message);
return;
}

while(Clientes.Count > 0 || Cajas.QuedanClientes()) {
if(Clientes.Count == 0) break;
CRegistro cli = (CRegistro)Clientes.Peek();
while(cli.HoraRegistro == dt) {
int prodsCajas = Cajas.ProductosEnCaja(Cajas.MejorCaja());
int colaCaja = Cajas.ColaCaja(Cajas.MejorCaja());

EsperaTotal += prodsCajas;

if(prodsCajas > EsperaMax) EsperaMax = prodsCajas;
Estadistica[Cajas.MejorCaja()].LargoT += colaCaja;
if(colaCaja > Estadistica[Cajas.MejorCaja()].LargoM)
Estadistica[Cajas.MejorCaja()].LargoM = colaCaja;

if(Clientes.Count == 0) break;
cli = (CRegistro)Clientes.Dequeue();
Cajas.Insertar(cli.registro_compra);
}
Cajas.Atender();
IIC 1102 Pgina: 22
Simulacin Computacional con C# Rodrigo Sandoval U.
DateTime d = dt.AddMinutes(1);
dt = d;
}

Console.WriteLine("\n\n\t\t-=Estadistica=-\n\n");
int valor = (EsperaTotal / 3) / NumClientes;
int min = valor;
int seg = ((valor-min)*60);
Console.WriteLine("\tTiempo de espera Promedio (mm:ss) -> {0}:{1}",min,seg);

valor = (EsperaMax / 3);
min = (int)valor;
seg = (int) ((valor-min)*60);
Console.WriteLine("\tTiempo de Espera Maximo (mm:ss) -> {0}:{1}",min,seg);

Console.WriteLine("\tLargo de la Cola en las Cajas (Promedio/Maximo):");
for(int i=0 ; i<cajas ; i++)
Console.WriteLine("\t\tCaja n{0}: {1} / {2}",i,
Estadistica[i].LargoT,Estadistica[i].LargoM);

Console.Write("Presione ENTER ..."); Console.ReadLine();
}
}

Ejemplos de ejecucin (varias configuraciones)
Con 1 caja:
-=Estadistica=-

Tiempo de espera Promedio (mm:ss) -> 29:0
Tiempo de Espera Maximo (mm:ss) -> 52:0
Largo de la Cola en las Cajas (Promedio/Maximo):
Caja n0: 44 / 2
Con 2 cajas:
-=Estadistica=-


Tiempo de espera Promedio (mm:ss) -> 29:0
Tiempo de Espera Maximo (mm:ss) -> 57:0
Largo de la Cola en las Cajas (Promedio/Maximo):
Caja n0: 6 / 2


Caja n1: 50 / 3
Con 4 cajas:
-=Estadistica=-


Tiempo de espera Promedio (mm:ss) -> 26:0
Tiempo de Espera Maximo (mm:ss) -> 46:0
Largo de la Cola en las Cajas (Promedio/Maximo):
Caja n0: 12 / 4
Caja n1: 12 / 3
Caja n2: 12 / 4
Caja n3: 15 / 4

Modificaciones propuestas
IIC 1102 Pgina: 23
Simulacin Computacional con C# Rodrigo Sandoval U.
Como se puede ver en los ejemplos de ejecucin, la simulacin arroja algunos valores estadsticos que
pueden ser de utilidad para el administrador del supermercado: tiempos de espera de los clientes y largos
de cola en las cajas. Sin embargo, la experimentacin es an algo engorrosa, pues cada vez que se
quieren ver los resultados para una determinada configuracin, es necesario ejecutar de nuevo el
programa y registrar los resultados.
Una posible modificacin al programa planteado es hacer que por s mismo busque la mejor
configuracin, de acuerdo a parmetros dados por el usuario. Por ejemplo, Cuntas cajas son
necesarias para que los clientes no deban esperar ms de 1 minuto?. Para lograr esto, el cuerpo de la
simulacin se debe convertir en un mtodo o funcin que reciba como argumento el nmero de cajas y
retorne el tiempo de espera promedio (actualmente se enva por la consola). El algoritmo principal (Main)
har llamados sucesivos a esta nueva funcin (mediante un ciclo), pasndole como argumento distintos
valores para el nmero de cajas en forma incremental (primero 2, luego 3, etc.), hasta que se llegue al
tiempo de espera propuesto por el usuario (1 minuto).
Otra caracterstica que podra resultar muy til es permitir la simulacin por perodos distintos al da
completo. Por ejemplo, es bien sabido que las horas de mayor saturacin en el supermercado se dan al
final de la tarde. Sera til que el administrador del supermercado pudiera determinar cuntas cajas
requiere para cada perodo del da en forma independiente. Actualmente los datos de las horas de muy
alta y muy baja afluencia estn alterando los promedios arrojados. Para lograr esto el programa debera
pedir un rango de horas y ejecutar la simulacin nicamente con los datos de entrada que correspondan
con el rango especificado. Adems, dependiendo de la hora del da el nmero de productos que llevan
los clientes podra variar. Para lograr esto bastara con cambiar la generacin aleatoria de la cantidad de
productos para que dependiera de la hora en la que se est comprando.
Finalmente, podra ser interesante lograr que la hora de llegada de los clientes se genere en forma
aleatoria, de modo que podamos suprimir el archivo de entrada y lo nico que deba dar el usuario es el
nmero de clientes y la cantidad de cajas que debern emplearse para la simulacin.
La planificacin y la implementacin de estas modificaciones se dejan como ejercicio al estudiante.

3.4 Simulacin de una Plaza de Peaje
Este ejemplo en particular se present como trabajo personal dentro de un curso. Cada alumno, contando
slo con ejemplos como los anteriores y la explicacin que se indica a continuacin.
Este ejemplo se centra en implementar una plaza de peaje de la carretera, donde se tienen distintas
casetas abiertas para atencin y en el tiempo van llegando autos a ser atendidos.
Una plaza de peaje est compuesta de distintas casetas que atienden a los autos que llegan por cada
lado de la carretera. Los autos deben pagar una tarifa que depende de la hora, y segn esa tarifa, la tasa
de atencin de la caseta puede aumentar o disminuir.
El propsito del programa es determinar la cantidad ptima de casetas abiertas y atendiendo para dar
un servicio adecuado a los vehculos al menor costo.
Esta particularidad le impone un factor especial al ejemplo, ya que ms que slo ejecutar una simulacin
del funcionamiento de la plaza de peaje, se toman los datos obtenidos de una simulacin completa y se
usan para cambiar los parmetros que determinan el escenario de la siguiente simulacin (en particular la
cantidad de casetas abiertas). De tal manera, se evalan diferentes escenarios y se determina cul de
ellos ofrece la mejor relacin costo/ingreso. Este proceso informal de optimizacin se refleja en el
algoritmo principal (Main).
3.4.1 Definicin del Problema
En detalle el funcionamiento de la simulacin considera lo siguiente:
IIC 1102 Pgina: 24
Simulacin Computacional con C# Rodrigo Sandoval U.
3.4.1.1 El Tiempo de Simulacin
El periodo a simular consta de dos horas, desde las 17:00 a las 19:00 de un da viernes.
Cada unidad de tiempo de simulacin es de 1 minuto.
A las 18:00 - la mitad del tiempo de simulacin - se cambia la tarifa de peaje, con lo cual tambin
cambia la tasa de atencin. Estos dos valores se explican ms adelante.
3.4.1.2 Las Casetas
Hay un total de 20 casetas construidas, de las cuales en una simulacin dada, el total de ellas o
slo una parte estarn atendiendo (al menos dos casetas siempre, una para cada direccin).
De las abiertas, la mitad est atendiendo a los autos que llegan por el sur y las otras a los que
llegan por el norte. La cantidad de casetas que atienden a cada lado tambin es fijo para cada
simulacin, pero es el parmetro a ir ajustando para determinar la cantidad ptima.
El costo fijo de atencin por caseta es de $50.000 por cada periodo de simulacin, lo que permite
calcular los costos.
En cada caseta siempre habr una cola que tiene 0 ms autos.
Cada auto que llegue a la plaza de peaje, por cualquier direccin, seleccionar la caseta cuya
cola sea la ms corta, o bien la primera si todas son iguales.
Tarifa de peaje: en la primera hora la tarifa es de $1.200 por vehculo, y en la segunda hora es de
$2.000.
La tasa de atencin en la caseta es de:
o 2 autos por minuto cuando la tarifa es baja (ya que se cuenta el tiempo para dar vuelto en
monedas).
o 4 autos por minuto cuando la tarifa es alta (ya que no se requiere dar vuelto en
monedas).
o En cualquiera de los dos casos se atender a la cantidad de autos correspondiente a la
tasa del horario actual, y si quedan menos autos, slo se atender a los que haya.
3.4.1.3 Los Vehculos
Existe un registro de los autos que llegan por el sur y por el norte respectivamente, identificando
la hora (en hh y mm) y la cantidad de autos que llegan en ese minuto.
Los del norte vienen en el archivo norte.txt y los del sur en sur.txt. Estos archivos asumen
conocidos y para este ejemplo se pueden inventar datos.
En cada archivo se registra una lnea por minuto de datos, la cual tiene en orden:
hh mm cantidadautos.
Si en un minuto dado no se registraron autos (cantidadautos=0), esa lnea no viene en el archivo.
En la correccin de la tarea se pueden utilizar otros archivos, por lo que no asuma que esos
sern siempre los archivos.
3.4.1.4 El Proceso de Optimizacin
El proceso de optimizacin no se enfoca en las tcnicas formales de optimizacin matemtica, ya que
ese enfoque no forma parte de este documento. Sin embargo, se busca lograr un punto denominad
ptimo por medio de la evaluacin de los resultados tomando distintos escenarios de simulacin. Al
comparar progresivamente los escenarios en torno a los costos e ingresos, se puede llegar a una
combinacin ideal de casetas abiertas que logren un nivel aceptable de tasa de atencin por vehculo.
Para ello, el procedimiento (algoritmo) es el siguiente:
Se comienza con el mnimo: 1 caseta abierta para los vehculos del norte y 1 para los del sur.
Se efecta la simulacin completa y se miden los siguientes datos que deben mostrarse en
pantalla.
IIC 1102 Pgina: 25
Simulacin Computacional con C# Rodrigo Sandoval U.
o Cantidad de cajas abiertas por cada lado.
o Cantidad de autos atendidos por cada lado.
o $ ingreso (cobro de peaje).
o $ costos (casetas x costo fijo).
o Mxima espera en minutos.
Se aumenta en uno la cantidad de casetas abiertas por cada lado y se vuelve a simular.
Las condiciones de trmino del proceso de optimizacin (que a su vez ejecuta varias
simulaciones) son:
o El Tiempo Mximo de espera por atencin debe ser menor que un valor en minutos dado
por el usuario al comienzo de todo el proceso.
o Se analiza si la utilidad (ingresos-costos) disminuye o aumenta. Dentro de la restriccin
de Tiempo de Espera Mxima, se busca el menor costo posible (el mnimo de casetas
abiertas).
o El mximo de casetas es el de la cantidad construida: 20 en total (10 para cada lado).
3.4.2 Solucin
Cdigo Fuente
using System;
using System.IO;
using System.Collections;


//------------------------------------------------------------------------------------
// Clase: Auto
// Representa un auto cuyos datos relevantes son nicamente los de la hora de llegada
//------------------------------------------------------------------------------------
class Auto {
DateTime horallegada; // Atributo relevante: la hora de llegada.

public Auto(int hh, int mm) {
// Transforma la hora y minutos de llegada en un tipo DateTime
horallegada = new DateTime(DateTime.Now.Year, DateTime.Now.Month,

DateTime.Now.Day, hh, mm, 0, 0);
}

public DateTime HoraLlegada { get { return(horallegada); } }
public int Hora { get { return(horallegada.Hour); } }
public int Minutos { get { return(horallegada.Minute); } }

// Al imprimir una instancia de Auto, se imprime la hora de llegada
public override string ToString() {
return(horallegada.ToString());
}
}


//------------------------------------------------------------------------------------
// Clase: Caseta
// Hereda de Queue, por lo cual la misma caseta representa una cola de vehculos que
// se atienden en dicha caseta. Adems, registra el tiempo mximo de espera durante
// toda la operacin de la caseta, contabiliza los autos atendidos, y va sumando
// el cobro de peajes segn tarifa por auto atendido.
//------------------------------------------------------------------------------------
class Caseta : Queue {
int maxespera = 0;
int procesados = 0;
int ingresos = 0;

// AtenderPrimero(): toma al primero de la cola, y si est en la hora adecuada
// lo atiende, registrando su tiempo de espera y contabilizndolo
public int AtenderPrimero(DateTime lahora, int valorpeaje) {
if(Count<=0) return(-1); // Si no hay autos en cola, no se atiende a nadie.
Auto a = (Auto) Peek(); // Se mira el primero de la cola
IIC 1102 Pgina: 26
Simulacin Computacional con C# Rodrigo Sandoval U.
if( a.HoraLlegada<=lahora ) {// Si lleg antes de la hora actual
TimeSpan ts = lahora - a.HoraLlegada; // Tiempo de espera
Dequeue(); // Se saca de la cola
procesados++; // Se contabiliza
ingresos += valorpeaje; // Suma el pago por el peaje al total acum.
return(ts.Hours*60 + ts.Minutes); // Retorna el valor total de minutos
}
return(-1); // Si no se atendi ninguno, retorna <0 para no contabilizar.
}

// Dos versiones para Agregar Auto a la cola (Queue) de la caseta.
public void AgregarAuto(int hh, int mm) { Enqueue((Object) new Auto(hh,mm)); }
public void AgregarAuto(Auto a) { Enqueue((Object) a); }

// Propiedades de Caseta
public int CantidadAutos { get { return(Count); } }
public int AutosProcesados { get { return(procesados); } }
public int Ingresos { get { return(ingresos); } }
public int MaxEspera {
get { return(maxespera); }
set { if(value>maxespera) maxespera = value; }
}
// PrimerAuto: revisa el primer auto sin sacarlo de la cola
public Auto PrimerAuto { get { return( (Auto) Peek()); } }
}


//------------------------------------------------------------------------------------
// Clase: Plaza
// Representa una coleccin de casetas o plaza de peaje, atendiendo DIR colas de
// autos que llegan. Si bien el ejemplo habla de dos extremos por los que llegan
// autos, se maneja un tributo DIR que representa la cantidad de extremos en forma
// genrica, permitiendo al ejemplo el potencial de ser extendido.
// El valor de casetasenuso se maneja referenciando una nica direccin. Si se abren
// dos casetas por cada direccin, entonces ese valor es 2, totalizando 4 casetas abiertas.
//------------------------------------------------------------------------------------
class Plaza {
const int DIR = 2; // Dos direcciones: Norte y Sur
Caseta[,] casetas; // Matriz de casetas. N casetas por M direcciones (2 dir: N y S).
int casetasenuso;

// Constructor, prepara la plaza indicando cuntas casetas se utilizarn.
// No requiere validar un mximo de casetas en uso, ya que es indiferente a este nivel
public Plaza(int enuso) {
casetas = new Caseta[enuso,DIR]; // Dimensiona la matriz de casetas

for(int dir=0; dir<DIR; dir++)
for(int i=0; i<casetas.GetLength(0); i++)
casetas[i,dir] = new Caseta(); // Instancia c/celda de la matriz.
casetasenuso = enuso;
}

// MejorCaseta(): segn la direccin dada (0: norte; 1: sur)
// : indica cul es la caseta con la fila ms corta
public Caseta MejorCaseta(int direccion) {
int mincola = casetas[0,direccion].CantidadAutos;
int mincaseta = 0;
for(int i=0; i<casetasenuso; i++)
if( mincola > casetas[i,direccion].CantidadAutos ) {
mincola = casetas[i,direccion].CantidadAutos;
mincaseta = i;
}
return( casetas[mincaseta,direccion] ); // Retorna la caseta elegida.
}

public int CasetasEnuso {
get { return(casetasenuso); }
set { if( value >= 1 ) casetasenuso = value; } // Mnimo de 1 caseta
}

// ProcesarMinuto(): atiende autos en las casetas que alcanzan en el minuto actual,
IIC 1102 Pgina: 27
Simulacin Computacional con C# Rodrigo Sandoval U.
// : de acuerdo a tasa dada, tomando valor del peaje en ese minuto.
public void ProcesarMinuto(DateTime lahora, int tasa, int valorpeaje) {
for(int dir=0; dir<DIR; dir++) // Para ambas direcciones (norte y sur).
for(int i=0; i<casetasenuso; i++) // Para todas las casetas abiertas.
for(int j=0; j<tasa; j++) // Los autos que alcanzan en un min.
if(casetas[i,dir].CantidadAutos>0) {
// Calcula espera del atendido. Si no hay nadie en la cola
// no se atiende a nadie, la espera es -1,
// que no es asignada a MaxEspera.
// Validaciones estn en AtenderPrimero() y de MaxEspera.
int espera = casetas[i,dir].AtenderPrimero(lahora, valorpeaje);
casetas[i,dir].MaxEspera = espera;
}
}

// EsperaMax: Calcula la Mxima espera registrada en las cajas.
public int EsperaMax {
get {
int max=0;
for(int dir=0; dir<DIR; dir++)
for(int i=0; i<casetasenuso; i++)
if(max<casetas[i,dir].MaxEspera) max = casetas[i,dir].MaxEspera;
return(max);
}
}

public int TotalIngresos {
get {
int total = 0;
for(int dir=0; dir<DIR; dir++)
for(int i=0; i<casetasenuso; i++)
total += casetas[i,dir].Ingresos;
return(total);
}
}

public int TotalAutos {
get {
int total = 0;
for(int dir=0; dir<DIR; dir++)
for(int i=0; i<casetasenuso; i++)
total += casetas[i,dir].AutosProcesados;
return(total);
}
}

public int AutosEnCola {
get {
int total = 0;
for(int dir=0; dir<DIR; dir++)
for(int i=0; i<casetasenuso; i++)
total += casetas[i,dir].CantidadAutos;
return(total);
}
}

public void Encabezado() {
for(int dir=0; dir<DIR; dir++)
for(int i=0; i<casetasenuso; i++)
Console.Write("{0}.{1} ", dir+1, i+1);
Console.WriteLine();
}

public void MostrarResumen() {
for(int dir=0; dir<DIR; dir++)
for(int i=0; i<casetasenuso; i++)
Console.Write("{0,3} ", casetas[i,dir].CantidadAutos);
Console.WriteLine();
}
}

IIC 1102 Pgina: 28
Simulacin Computacional con C# Rodrigo Sandoval U.

//------------------------------------------------------------------------------------
// Clase: ColaLlegada
// Representa la cola de autos de llegada por una direccin especfica.
//------------------------------------------------------------------------------------
class ColaLlegada : Queue {
StreamReader sr;

// Constructor: Abre archivo. Lee todos registrndolos en una cola de autos de llegada
public ColaLlegada(string filename) {
try { sr = new StreamReader(filename);
} catch(Exception e) {
Console.WriteLine("Error al abrir {0}\n{1}",
filename, e.ToString()); return;
}

string linea = sr.ReadLine();
int contador = 0;
while(linea!=null) { // Procesa el archivo completo
contador++;
string[] datos = linea.Split();
if(datos.Length != 3) { // Si no vienen 3 datos, avisa y termina el proceso
Console.WriteLine("Error en formato del archivo de entrada:
+ lnea N {0} no tiene 3 datos", contador);
sr.Close();
return;
}
int cant = int.Parse(datos[2]); // Lee cantidad de autos en min. en proceso
for(int i=0; i<cant; i++) // Registra 1 elem. x c/auto en el min. en proc.
Enqueue( (Object) new Auto(int.Parse(datos[0]),
int.Parse(datos[1])));
linea = sr.ReadLine();
}
sr.Close(); // Se cierra el archivo con datos.
}

// Propiedades bsicas de la Cola de Llegada --> Se basan en los mtodos de Queue
public Auto PrimerAuto { get { return( (Auto) Peek()); } }
public int CantidadAutos { get { return(Count); } }

// Mtodos pblicos de la Cola de Llegada
public void SacarPrimerAuto() { if(Count>0) Dequeue(); }
}



//------------------------------------------------------------------------------------
// Clase: SimuladorPlaza
// Se encarga de hacer una simulacin completa en un escenario dado por
// las colas de los autos en llegada y de una cantidad determinada de casetas abiertas
//------------------------------------------------------------------------------------
class SimuladorPlaza {
Plaza p;
ColaLlegada c1;
ColaLlegada c2;
const int TARIFA1 = 1200;
const int TARIFA2 = 2000;
const int TASA1 = 2;
const int TASA2 = 4;
const int COSTO = 50000;

public SimuladorPlaza(string file1, string file2, int casetas) {
p = new Plaza(casetas);
c1 = new ColaLlegada(file1);
c2 = new ColaLlegada(file2);
}

// Procesar(): Mtodo principal de la clase, que realiza (ejecuta) la simulacin
public void Procesar() {
// Se procesa el loop de simulacin principal
DateTime HoraActual = new DateTime(DateTime.Now.Year, DateTime.Now.Month,
IIC 1102 Pgina: 29
Simulacin Computacional con C# Rodrigo Sandoval U.
DateTime.Now.Day, 17, 0, 0, 0);
DateTime HoraCambio = new DateTime(DateTime.Now.Year, DateTime.Now.Month,
DateTime.Now.Day, 18, 0, 0, 0);
DateTime HoraFinal = new DateTime(DateTime.Now.Year, DateTime.Now.Month,
DateTime.Now.Day, 19, 0, 0, 0);
TimeSpan UnTick = new TimeSpan(0,1,0);

// Para ver en pantalla avance del proceso: Console.Write("Llegan "); p.Encabezado();

while( HoraActual<=HoraFinal ) {
// Console.WriteLine(HoraActual);
// Procesa los autos de la hora de llegada actual -> Norte
int llegaron1 = 0;
int llegaron2 = 0;
while( (c1.CantidadAutos>0) && (c1.PrimerAuto.HoraLlegada<=HoraActual) ) {
Caseta cas = p.MejorCaseta(0);
cas.AgregarAuto(c1.PrimerAuto);
c1.SacarPrimerAuto(); llegaron1++;
}
// Procesa los autos de la hora de llegada actual -> Sur
while( (c2.CantidadAutos>0) && (c2.PrimerAuto.HoraLlegada<=HoraActual) ) {
Caseta cas = p.MejorCaseta(1);
cas.AgregarAuto(c2.PrimerAuto);
c2.SacarPrimerAuto(); llegaron2++;
}
// Ahora procesa las colas
int tasa = TASA2;
int tarifa = TARIFA2;
if( HoraActual < HoraCambio ) { tasa = TASA1; tarifa = TARIFA1; }
// Console.Write("{0,2} {1,2} ", llegaron1, llegaron2);
// p.MostrarResumen(); // OJO: En simulacin larga esto muestra demasiada info
p.ProcesarMinuto(HoraActual, tasa, tarifa);

// Console.Write(" ", llegaron1, llegaron2);
// p.MostrarResumen(); // OJO: En simulacin larga esto muestra demasiada info

HoraActual += UnTick; // Aumenta en un instante de simulacin
}
}

public int Costos { get { return(COSTO*p.CasetasEnuso*2); } }
public int Ingresos { get { return(p.TotalIngresos); } }
public int Resultado { get { return(Ingresos - Costos); } }

public int MaxEspera { get { return(p.EsperaMax); } }
public int AutosAtendidos { get { return(p.TotalAutos); } }
}


class CMain {
public static void Main() {
int casetasenuso = 0;
int resultado = 0;

Console.Write("Ingrese tiempo de espera mximo razonable en minutos: ");
int esperamax = int.Parse(Console.ReadLine());
int espera = 0;
int minespera = 100;
int optimocasetas = 2;
int maxresultado = 0;

// Loop principal: realiza simulaciones y tiene la lgica de optimizacin.
// En cada iteracin aumenta la cantidad de casetas en uso.
// Ojo que se maneja un nmero de casetas por lado.
// Los datos resultantes de cada simulacin de los pregunta al SimuladorPlaza.
do {
casetasenuso++; // Cantidad de casetas abiertas por lado
SimuladorPlaza sp =
new SimuladorPlaza("norte.txt","sur.txt", casetasenuso);

Console.WriteLine("\n==============================);
IIC 1102 Pgina: 30
Simulacin Computacional con C# Rodrigo Sandoval U.
Console.WriteLine("Nueva Simulacin\n==============================");
sp.Procesar();
resultado = sp.Resultado;
espera = sp.MaxEspera;
// Se imprimen en pantalla los datos pedidos:
Console.WriteLine("\nResultados de la Simulacin);
Console.WriteLine("==============================");
Console.WriteLine("Casetas : {0}\nAutos Atendidos: {1}\nMx. Espera: {2}",
casetasenuso*2, sp.AutosAtendidos, espera);
Console.WriteLine("Ingresos: {0:C}\nCostos: -{1:C}\nResultado: {2:C}",
sp.Ingresos, sp.Costos, resultado);

// Registra el punto con espera menor que el mnimo dado.
// Dado que siempre ser el de menor cantidad de casetas abiertas
// este punto tambin es el de mayores ingresos.
if( espera<=esperamax ) {
minespera = espera;
optimocasetas = casetasenuso;
maxresultado = resultado;
break;
}
} while(casetasenuso<10);

Console.WriteLine("\nEl punto Optimo);
Console.WriteLine(==========================\n);
Console.WriteLine(Casetas: {0} - Resultado: {1:C}", optimocasetas*2, resultado);

Console.Write("Presione ENTER ..."); Console.ReadLine();
}
}


IIC 1102 Pgina: 31
Material preparado por Rodrigo Sandoval U en Mayo 2004,
basado en los apuntes de clase del curso IIC1102, ao 2003, de M. Nussbaum, Marcos Seplveda, et.a
Los ejemplos fueron adaptados y preparados por el MSR Lab, del DCC de la Escuela de Ingeniera de la PUC

PONTIFICIA UNIVERSIDAD CATLICA DE CHILE
ESCUELA DE INGENIERA
DEPARTAMENTO DE CIENCIA DE LA COMPUTACIN
IIC 1102 INTRODUCCIN A LA PROGRAMACIN
Profesor: Rodrigo Sandoval U.

Captulo XI Recursividad


1 RECURSIVIDAD................................................................................................................................................. 1
1.1 EJ EMPLO: NMEROS DE FIBONACCI................................................................................................................2
1.2 EJ EMPLO: OBTENCIN DEL MXIMO EN UN VECTOR DE ENTEROS...................................................................4
1.3 EJ EMPLO: FUNCIN PARA CALCULAR MDULO...............................................................................................5
1.4 EJ EMPLO: SOLUCIN DE UN LABERINTO.........................................................................................................7
1.4.1 Descripcin ............................................................................................................................................ 7
1.4.2 Diseo .................................................................................................................................................... 7


Intro. Prog Orientada a Objeto - Recursividad Rodrigo Sandoval U.
IIC 1102 Pgina: 1
1 Recursividad
Existen muchas funciones matemticas cuyos argumentos son nmeros naturales, que pueden definirse
de manera recursiva. Esto quiere decir que el valor de la funcin para el argumento n puede definirse en
trminos del argumento n-1 (o alguno anterior). En este tipo de definiciones siempre existir un caso base
a partir del cual parte la definicin, el cual normalmente es el valor de la funcin en cero o en uno, aunque
no necesariamente debe ser as.
Por ejemplo, el factorial puede definirse de manera recursiva de la siguiente manera:

Para definir una funcin en forma recursiva es necesario especificar:
Caso(s) base: Donde la recursividad se detiene.
Paso de recursin: Cmo se define un elemento distinto del caso base, en trminos de elementos
anteriores.
Usualmente los lenguajes de programacin permiten definir funciones de manera recursiva. La definicin
recursiva para el factorial sera:
int factorial(int n) {
if ((n == 0) || (n == 1))
return(1);
else
return(n*factorial(n-1));
}
Normalmente las definiciones recursivas pueden expresarse en forma no recursiva. Sin embargo,
dependiendo del caso, el resultado puede ser ms confuso. Por ejemplo, un mtodo que calcula el
factorial en forma iterativa sera:
int factorial(int n) {
int i, fact = 1;

for (i=2; i<=n; i++)
fact = fact * i;
return(fact);
}
Sin embargo, los algoritmos iterativos tienen una ventaja en cuanto al uso de memoria, si se comparan
con los recursivos. La recursividad requiere que se guarde el estado de la ejecucin antes de cada
llamado recursivo, implicando un gasto considerable de memoria. Es probable que, por esta razn, las
versiones recursivas tengan mayores limitaciones al ejecutarse en un computador.
La aplicacin de las definiciones recursivas puede ampliarse a una amplia gama de problemas, en los
que la solucin ms natural puede ser la que se expresa de esta forma. Por ejemplo, para buscar un
nmero en un vector (arreglo unidimensional de enteros) podemos tener una funcin que reciba como
argumento el vector, el rango de bsqueda y el nmero buscado. El prototipo de esta funcin sera como:
int busqueda(int[] vec, int inicio, int fin, int num)
La funcin que quiere hacer la bsqueda hara el llamado indicando los rangos apropiados para el vector:
Intro. Prog Orientada a Objeto - Recursividad Rodrigo Sandoval U.
IIC 1102 Pgina: 2
resultado = busqueda(vector, 0, N, x);
La funcin busqueda() puede hacer su trabajo partiendo el vector en dos partes y llamndose a s
misma en forma recursiva, de la siguiente manera:


res1 = busqueda(vec, inicio, fin-inicio/2, num);
res2 = busqueda(vec, (fin-inicio/2)+1, fin, num);

El caso base sera cuando el vector que recibe la funcin busqueda() contiene un nico elemento. En
este caso simplemente compara el elemento con el nmero buscado y retorna el valor apropiado.
Ms adelante, en el captulo sobre Ordenamiento y Bsqueda, se tratar en detalle este algoritmo que
recibe el nombre de Bsqueda Binaria.
1.1 Ejemplo: Nmeros de Fibonacci
La Sucesin de Fibonacci es una secuencia de nmeros naturales, que empieza con 0 y 1, y cuyos
siguientes trminos estn definidos como la suma de los dos anteriores:

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, ...

Algoritmo Recursivo
Es bastante sencillo y natural definir la Sucesin de Fibonacci en forma recursiva:

Intro. Prog Orientada a Objeto - Recursividad Rodrigo Sandoval U.
IIC 1102 Pgina: 3
A partir de esta definicin, se puede escribir un mtodo que genere el trmino n-simo de la sucesin. En
el siguiente ejemplo se presenta esta funcin, junto con un programa de prueba que pide un nmero
entero al usuario y determina el correspondiente trmino de la sucesin.
/***************************************************************************
* Programa que calcula, de forma recursiva, el trmino n-simo de la
* sucesin de fibonacci, para un valor n dado por el usuario.
***************************************************************************/
using System;

public class Ccopy {
/***************************************************************************
* Ejemplo: Clculo recursivo del n-esimo termino de fibonacci
* Por definicin:
* Fibonacci(0) = 0
* Fibonacci(1) = 1
* Fibonacci(n) = Fibonacci(n - 1) + Fibonacci(n - 2)
***************************************************************************/
public static double Fibonacci(int n) {
switch (n) {
case 0 : { return 0; }
case 1 : { return 1; }
default: { return Fibonacci(n - 1) + Fibonacci(n - 2); }
}
}

public static void Main() {
Console.Write("Ingrese el numero a calcular: ");
int a = int.Parse(Console.ReadLine());
Console.WriteLine("El nmero fibonacci solicitado es: {0}", Fibonacci(a));
}
}

Ejemplo de Ejecucin
Ingrese el valor de n: 10
El termino 10 de Fibonacci es: 55

Ingrese el valor de n: 20
El termino 20 de Fibonacci es: 6765

Algoritmo Iterativo
En contraposicin a la implementacin recursiva que se present anteriormente, se ofrece aqu una
versin iterativa de la funcin para calcular el n-simo trmino de la Sucesin de Fibonacci.
Para implementar el algoritmo en forma iterativa, es necesario guardar en variables los valores para los
dos trminos anteriores de la sucesin, para poder llevar a cabo el clculo del siguiente. Una vez hecho
esto se actualizan los valores anteriores para preparar el siguiente clculo (siguiente iteracin).
Compare ambas funciones. Aparentemente la versin recursiva es ms limpia y clara (fcil de entender)
que su contraparte iterativa. Cul es su opinin?.
Se mantiene el mismo programa de prueba empleado anteriormente.
using System;

public class Ccopy {
public static double Fibonacci(int n) {
int i;
double Fibi = 0, Fibn1, Fibn2;
switch(n) {
case 0 : { return 0; }
case 1 : { return 1; }
default :
{
Fibn2 = 0; /* Fibonacci(n - 2) */
Intro. Prog Orientada a Objeto - Recursividad Rodrigo Sandoval U.
IIC 1102 Pgina: 4
Fibn1 = 1; /* Fibonacci(n - 1) */
for (i = 2; i <= n; i++)
{
Fibi = Fibn1 + Fibn2;
Fibn2 = Fibn1;
Fibn1 = Fibi;
}
break;
}
}
return Fibi;
}

static void Main() {
Console.Write("Ingrese el numero a calcular: ");
int a = int.Parse(Console.ReadLine());
Console.WriteLine("El numero fibonacci solicitado es: {0}", Fibonacci(a));
}
}

Experimento Sugerido
Como se mencion al introducir la recursividad, la implementacin recursiva de un algoritmo normalmente
consume ms memoria que su contraparte iterativa. Esto se debe a que es necesario guardar el estado
actual de la ejecucin antes de cada llamado recursivo. Esto puede provocar limitaciones importantes en
los programas que emplean funciones recursivas.
Se sugiere probar los dos programas ofrecidos en esta seccin para valores altos (a partir de 20) y
comparar los resultados obtenidos.
Variantes Propuestas
A manera de ejercicio pueden escribirse variantes de este programa, que empleen la funcin Fibonacci,
ya sea iterativa o recursiva:
Programa que lee un nmero y dice si pertenece a la Sucesin de Fibonacci.
Programa lee un nmero entero n y despliega en pantalla los primeros n trminos de la Sucesin
de Fibonacci. En este caso, existe alguna ventaja en usar una versin sobre la otra?, por qu?.

1.2 Ejemplo: Obtencin del mximo en un vector de enteros
En este ejemplo mostraremos una funcin recursiva para encontrar el valor mximo en un vector de
nmeros enteros. Se incluye un programa de prueba que recibe los valores del vector del usuario y
despliega el valor mximo calculado mediante la funcin mencionada.
Algoritmo
La definicin recursiva de la funcin para obtener el mximo puede hacerse como:
Si el vector tiene un nico elemento, ese elemento es el mximo (caso
base).
Si el valor en la posicin inicial del vector es mayor que el mximo del
resto del vector, entonces el valor de la primera posicin es el mximo
global.
Si el valor en la posicin inicial del vector es menor que el mximo del
resto del vector, entonces el mximo global ser el mximo en el resto del
vector.
Escrito en palabras simples: Para encontrar el mximo en un vector, basta comparar el primer elemento
con el mximo del resto del vector.
Intro. Prog Orientada a Objeto - Recursividad Rodrigo Sandoval U.
IIC 1102 Pgina: 5
/***************************************************************************
* Funcin recursiva que obtiene el mximo en un vector de nmeros enteros.
* Retorna el valor del mximo elemento dentro del vector.
***************************************************************************/
using System;

class CMax {
public static int Maximo(int [] vector, int n) {
int max, maxResto;
if (n == 1) max = vector[0]; /* Caso base */
else
{
int [] vec = new int[vector.Length-1];
for(int i = 0; i < vec.Length; i++)
vec[i] = vector[i+1];

maxResto = Maximo(vec, n-1); /* Maximo del resto del vector */
if (vector[0] > maxResto)
max = vector[0];
else
max = maxResto;
}
return(max);
}

public static void Main() {
Console.Write("Ingrese el numero de elementos: ");
int [] vec = new int[Int32.Parse(Console.ReadLine())];

for(int i = 0; i < vec.Length; i++) {
Console.Write("Ingrese el elemento n {0}: ",i);
vec[i] = int.Parse(Console.ReadLine());
}

Console.WriteLine("Mximo: {0}", Maximo(vec,vec.Length));
}
}

Ejemplo de ejecucin:
Ingrese el nmero de elementos: 5
Elemento[0]: 6
Elemento[1]: 10
Elemento[2]: 8
Elemento[3]: 15
Elemento[4]: 12

Mximo: 15

1.3 Ejemplo: Funcin para calcular mdulo
El operador binario mdulo obtiene el resto o residuo de la divisin de dos nmeros enteros. Es bastante
sencillo definir en forma recursiva la operacin m md n. La idea es ir restando el divisor del dividendo y
calculando de nuevo el mdulo, pues el resultado es el mismo. La recursividad se detiene cuando el
divisor es mayor que el dividendo. En ese caso el resultado es el dividendo. La definicin sera:
Intro. Prog Orientada a Objeto - Recursividad Rodrigo Sandoval U.
IIC 1102 Pgina: 6


A partir de esta definicin, se puede escribir una funcin en C que calcule m md n, con m y n como los
parmetros de la funcin. En el siguiente ejemplo se presenta esta funcin, junto con un programa de
prueba que pide dos nmeros enteros al usuario, calcula la operacin y muestra en pantalla el resultado.

using System;

public class CModulo {
public static int modulo(int m, int n) {
if (m < n) return(m);
else return( modulo( (m-n) , n) );
}

public static void Main() {
Console.Write("Ingrese el valor de m: ");
int m = int.Parse(Console.ReadLine());
Console.Write("Ingrese el valor de n: ");
int n = int.Parse(Console.ReadLine());
Console.WriteLine("{0} mod {1} es: {2}", m, n, modulo(m,n));
}
}

Ejemplo de ejecucin:
Ingrese el valor de m: 10
Ingrese el valor de n: 3
10 mod 3 es: 1

Ingrese el valor de m: 3
Ingrese el valor de n: 5
3 mod 5 es: 3

Ingrese el valor de m: 3
Ingrese el valor de n: 3
3 mod 3 es: 0

Ejercicio Propuesto
De manera similar a como se defini recursivamente el operador mdulo es posible definir el operador
para divisin entera, es decir, divisin sobre operandos enteros y cuyo resultado es entero (se ignoran los
decimales). Se deja como ejercicio la definicin recursiva de este operador y la implementacin del
mtodo correspondiente. Como programa de prueba puede emplearse el mismo que se emple para el
mdulo con unos pocos cambios.

Intro. Prog Orientada a Objeto - Recursividad Rodrigo Sandoval U.
IIC 1102 Pgina: 7
1.4 Ejemplo: Solucin de un laberinto
Se presenta un programa que resuelve laberintos en forma recursiva. El laberinto a resolver se
representa mediante una matriz de caracteres.
1.4.1 Descripcin
Se presenta un programa que resuelve laberintos en forma recursiva. El laberinto a resolver se
representa mediante una matriz de caracteres, y su configuracin est dada por la inicializacin que se
haga a dicha matriz. Por esto, para cambiar el laberinto ser necesario cambiar el cdigo del programa.
Una vez que se haya introducido el concepto de archivo ser posible ampliar este programa para que sea
ms til, almacenando distintas configuraciones de laberinto en distintos archivos.
1.4.2 Diseo
1. Definicin del problema
Conceptualizacin: El problema se ubica en un contexto en el que se debe buscar una solucin a un
laberinto con una entrada y una salida, y con movimientos vlidos en cuatro direcciones (no diagonales).
En el caso de este ejemplo, el contexto est limitado a una aplicacin de computador, en la que el
laberinto est representado mediante una matriz de nmeros enteros.
Objetivo: Partiendo de la entrada del laberinto, sealar una ruta que nos gue hasta la salida. Por
ejemplo, dado el siguiente laberinto (figura de la izquierda). Una solucin que permitira alcanzar el
objetivo sera la ruta mostrada con asteriscos en la figura de la derecha.


Descripcin general de la solucin: El problema se resolver haciendo uso de la recursividad. La
solucin se basa en una tarea o funcin que se llamar recursivamente para intentar solucionar el
laberinto a partir de una posicin particular. Desde cualquier lugar dentro del laberinto se intentar
resolverlo primero intentando hacia izquierda, luego a la derecha, luego arriba y finalmente abajo. Para
hacer estos intentos se emplear la funcin recursiva. El procedimiento parte de la posicin de entrada.
Se utilizarn marcas que sern dejadas en el camino para no intentar por caminos por los que ya se pas
y, en particular, no volver atrs salvo si se determina que no hay solucin por el camino que se sigue
hasta ahora.
Elementos involucrados: No existen elementos externos involucrados en la bsqueda de la solucin. El
nico elemento activo es el computador en s llevando a cabo su trabajo. En el problema participan
tambin los siguientes elementos pasivos:
la matriz que representa el laberinto
la ubicacin de la entrada
Intro. Prog Orientada a Objeto - Recursividad Rodrigo Sandoval U.
IIC 1102 Pgina: 8
la ubicacin de la salida

2. Conceptualizacin de la solucin
Clases: Como se mencion, el laberinto estar representado mediante una clase que contiene una matriz
de nmeros enteros: Lab. Adems, la posicin de la entrada en el laberinto estar dada por las
coordenadas dentro de la matriz, representadas por las variables x0, y0, para la fila y la columna,
respectivamente. De manera similar, la posicin de la salida del laberinto se guardar en xf, yf las cuales
sern atributos de la clase.
Cada posicin de la matriz puede estar en uno de tres estados:
parte del muro (ladrillo)
camino libre no visitado
camino libre visitado
La inicializacin de la matriz que se requiere, se establece con una configuracin de caracteres en cdigo
ASCII, y corresponde al laberinto presentado en la figura del inicio. Los caminos estn formados de
espacios libres (E's). Observe el contorno del laberinto, formado por L's, y los puntos de entrada y salida.

Mtodos de la Clase Lab
Validate(f,c)
Parmetros: fila y columna de la posicin.
Valor de retorno: valor booleano que indica si la posicin es vlida.
Descripcin: Esta funcin analiza una posicin dentro del laberinto, especificada por la fila y
columna recibidas como parmetro, y deduce si es una posicin vlida para recorrer. Bsicamente
debe verificar que no est fuera de los lmites del laberinto, que no se trate de una posicin en la que
hay pared, y que no se trate de una posicin previamente visitada.
Algoritmo:

1. Si la posicin dada est fuera del laberinto o si es pared o ya fue
visitada
1.1. retornar FALSO
2. En caso contrario
2.1. retornar VERDADERO

Recorrer(f,c)
Parmetros: fila y columna (fil y col) desde donde se empieza el recorrido.
Valor de retorno: TRUE o FALSE que indica si se logr resolver el laberinto o no.
Descripcin: Mtodo recursivo que recorre el laberinto a partir de una posicin dada por la fila y
columna pasadas como parmetro y devuelve un valor bool que indica si se logr llegar a la salida. El
caso base de la recursividad (condicin de trmino) es que las coordenadas correspondan con la
salida del laberinto. En caso contrario, se procede a marcar la casilla y a intentar en las distintas
direcciones (izquierda, derecha, arriba y abajo), asegurndose primero que en esa direccin haya
una casilla valida (no ladrillo, no fuera del laberinto y no visitada). En caso en que ninguna direccin
nos lleva a la salida, se desmarca la casilla actual (pues se va a retroceder) y se devuelve falso como
valor de retorno. Las marcas sirven tambin para sealar la ruta que conforma la solucin, una vez
alcanzada.
Intro. Prog Orientada a Objeto - Recursividad Rodrigo Sandoval U.
IIC 1102 Pgina: 9
Algoritmo:

1. Inicialmente l i st o vale FALSO.
2. Se marca la casilla.
3. Si la posicin es el fin del laberinto.
3.1. Retornar VERDADERO.
4. Si no se ha solucionado (l i st o vale FALSO) y la posicin de la
izquierda es vlida.
4.1. Llamar a r ecor r er recursivamente con la casilla de la izquierda
como parmetro y guardar valor de retorno en l i st o, para ver si se
resolvi el laberinto a partir de ah.
5. Si no se ha solucionado (l i st o vale FALSO) y la posicin de la
derecha es vlida.
5.1. Llamar a r ecor r er recursivamente con la casilla de la derecha
como parmetro y guardar valor de retorno en l i st o, para ver si se
resolvi el laberinto a partir de ah.
6. Si no se ha solucionado (l i st o vale FALSO) y la posicin de arriba es
vlida.
6.1. Llamar a r ecor r er recursivamente con la casilla de arriba como
parmetro y guardar valor de retorno en l i st o, para ver si se
resolvi el laberinto a partir de ah.
7. Si no se ha solucionado (l i st o vale FALSO) y la posicin de abajo es
vlida.
7.1. Llamar a r ecor r er recursivamente con la casilla de abajo como
parmetro y guardar valor de retorno en l i st o, para ver si se
resolvi el laberinto a partir de ah.
8. Si no se logr resolver el laberinto en ninguna direccin (l i st o
todava vale FALSO).
8.1. Quitar marca de la casilla (pues no formar parte del camino).
9. Retornar l i st o indicando si se pudo resolver o no el laberinto.


Display()
Parmetros: no tiene
Valor de retorno: no tiene
Descripcin: Despliega en la pantalla el laberinto
Algoritmo:

1. Iterar i por todas las filas
1.1. Iterar j por todas las columnas
1.1.1. Desplegar posicin i,j
1.2. Cambiar de lnea pues termin una fila


Intro. Prog Orientada a Objeto - Recursividad Rodrigo Sandoval U.
IIC 1102 Pgina: 10
3. Especificacin del Algoritmo Principal
El algoritmo principal debe llamar a la tarea que recorre el laberinto, especificando como posicin la
entrada: ( x0 , y0 ). Antes y despus de la resolucin se despliega el laberinto. La segunda vez incluir el
camino que forma la solucin (las posiciones que fueron marcadas y no desmarcadas posteriormente).
Algoritmo:
1. Desplegar el laberinto sin resolver
2. Recorrer desde la entrada del laberinto: ( x0 , y0 )
3. Si se pudo resolver
3.1. Desplegar el laberinto una vez resuelto (con el camino)
4. Si no, desplegar un mensaje indicando que no hay solucin

4. Validacin del algoritmo
La validacin de un algoritmo recursivo requiere verificar que la condicin de trmino se cumplir en
algn momento. En caso contrario, el algoritmo se llamar a s mismo recursivamente hasta que el stack
se agote y el programa colapse (error de ejecucin).
En este caso, la condicin de trmino se alcanza cuando se logra llegar a la salida del laberinto o cuando
se han probado todas las posibles direcciones (izquierda, derecha, arriba y abajo) y an as no se ha
encontrado solucin. En este caso, el algoritmo recursivo se ha planteado de una forma bastante segura.
El procedimiento siempre termina, ya sea positiva o negativamente, encontrando la solucin o desistiendo
de encontrarla, respectivamente.
Por otra parte, es necesario definir dominios que caractericen situaciones distintas bajo las cuales se
puede ejecutar el algoritmo.
Dominios: Deben definirse dominios en los que, tanto la entrada como la salida del laberinto, se
encuentren en distintas posiciones, incluso del mismo lado o hasta contiguas.
Validacin: Ejecutando en algoritmo para los dominios definidos debe verificarse que la solucin
cumple con la especificacin planteada y por lo tanto alcanza el objetivo propuesto.

5. Limitaciones del algoritmo
A simple vista el algoritmo no tiene limitaciones importantes. Sin embargo, no existe una prueba
formal de esto, por lo que se deja como ejercicio analizar la solucin propuesta a fin de determinar
potenciales limitaciones.

Posibles modificaciones (Ejercicios)
Existen diversas variantes de este programa que pueden implementarse como ejercicio. Algunas
requieren leves modificaciones, principalmente en la funcin recursiva, pero otras involucran mayores
cambios.
Ser posible eliminar los pasos innecesarios que puede provocar la funcin recursiva
suministrada?. Si es as, modifique la funcin para que no haga esos pasos.
El problema puede replantearse, indicando que el laberinto tiene una entrada y el objetivo es
buscar algn tesoro que se encuentra en el interior, tomarlo y regresar a la entrada. Implemente
la solucin de este nuevo problema.
La solucin presentada no toma en cuenta la direccin en la que se viene buscando la solucin.
Puede implementarse una solucin en la cual se mantenga la direccin actual, y la bsqueda se
Intro. Prog Orientada a Objeto - Recursividad Rodrigo Sandoval U.
IIC 1102 Pgina: 11
haga haciendo giros a partir de esa direccin. Tendra esto alguna ventaja?. Trate de
implementar la solucin.
Ser posible implementar una funcin recursiva que disee el laberinto?. Si lo logra concebir,
implemntela. Esto sustituira la tediosa inicializacin de la matriz y le dara mayor flexibilidad al
programa. Ahora el programa plantea laberintos y luego los resuelve.
Cuando se hayan estudiado bibliotecas para manejo de grficos, ser posible implementar una
versin animada de la solucin del laberinto, en la que se vayan mostrando los distintos caminos
que va probando el algoritmo.

/**********************************************************************
* Ejemplo: Solucin de un laberinto en forma recursiva.
* Para mejor comprensin ver la descripcin adjunta.
**********************************************************************/

using System;

class Clab {
private char [,] lab;
public int xf = 11, yf = 20;

public CLab() {
lab = new char[13,21]
{
{ '\x4F', '\x4F', '\x4F', '\x4F', '\x4F', '\x4F', '\x4F', '\x4F', '\x4F', '\x4F',
'\x4F', '\x4F', '\x4F', '\x4F', '\x4F', '\x4F', '\x4F', '\x4F', '\x4F', '\x4F', '\x4F' },
{ '\x20', '\x20', '\x20', '\x4F', '\x20', '\x4F', '\x20', '\x4F', '\x20', '\x4F', '\x20',
'\x20', '\x20', '\x4F', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x4F' },
{ '\x4F', '\x4F', '\x20', '\x4F', '\x20', '\x20', '\x20', '\x4F', '\x20', '\x20', '\x20',
'\x4F', '\x20', '\x4F', '\x20', '\x4F', '\x20', '\x20', '\x4F', '\x20', '\x4F' },
{ '\x4F', '\x20', '\x20', '\x20', '\x20', '\x4F', '\x20', '\x4F', '\x4F', '\x4F', '\x20',
'\x4F', '\x20', '\x4F', '\x20', '\x4F', '\x4F', '\x20', '\x4F', '\x20', '\x4F' },
{ '\x4F', '\x20', '\x4F', '\x4F', '\x4F', '\x4F', '\x20', '\x4F', '\x20', '\x4F', '\x20',
'\x4F', '\x20', '\x4F', '\x4F', '\x4F', '\x20', '\x20', '\x4F', '\x20', '\x4F' },
{ '\x4F', '\x20', '\x20', '\x20', '\x4F', '\x20', '\x20', '\x4F', '\x20', '\x4F', '\x20',
'\x4F', '\x20', '\x20', '\x20', '\x20', '\x20', '\x4F', '\x4F', '\x20', '\x4F' },
{ '\x4F', '\x20', '\x4F', '\x4F', '\x4F', '\x4F', '\x4F', '\x4F', '\x20', '\x4F', '\x20',
'\x4F', '\x4F', '\x20', '\x4F', '\x20', '\x20', '\x20', '\x20', '\x20', '\x4F' },
{ '\x4F', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20',
'\x20', '\x4F', '\x20', '\x4F', '\x20', '\x4F', '\x4F', '\x20', '\x4F', '\x4F' },
{ '\x4F', '\x4F', '\x4F', '\x4F', '\x4F', '\x4F', '\x4F', '\x4F', '\x4F', '\x4F', '\x4F',
'\x20', '\x4F', '\x20', '\x4F', '\x20', '\x20', '\x4F', '\x20', '\x4F', '\x4F' },
{ '\x4F', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x4F', '\x20', '\x20',
'\x20', '\x4F', '\x4F', '\x4F', '\x4F', '\x4F', '\x4F', '\x20', '\x4F', '\x4F' },
{ '\x4F', '\x20', '\x4F', '\x4F', '\x4F', '\x4F', '\x4F', '\x20', '\x20', '\x20', '\x4F',
'\x4F', '\x4F', '\x20', '\x4F', '\x20', '\x20', '\x20', '\x20', '\x20', '\x4F' },
{ '\x4F', '\x20', '\x20', '\x4F', '\x20', '\x20', '\x20', '\x20', '\x4F', '\x20', '\x20',
'\x4F', '\x20', '\x20', '\x20', '\x20', '\x4F', '\x4F', '\x4F', '\x20', '\x20' },
{ '\x4F', '\x4F', '\x4F', '\x4F', '\x4F', '\x4F', '\x4F', '\x4F', '\x4F', '\x4F', '\x4F',
'\x4F', '\x4F', '\x4F', '\x4F', '\x4F', '\x4F', '\x4F', '\x4F', '\x4F', '\x4F' } };
}

public void mDisplay() {
Console.Write("\n\t");
for(int i = 0; i < 13; i++) {
for(int j = 0; j < 21; j++)
Console.Write("{0}",lab[i,j]);
Console.Write("\n\t");
}
}

private bool mValidate(int f, int c) {
// Controla si la posicin esta fuera del laberinto
if (((f<0) || (f>=13) || (c<0) || (c>=21)) ||
(lab[f,c] == '*' || lab[f,c] == '\x4F'))
return false;
else return true;
Intro. Prog Orientada a Objeto - Recursividad Rodrigo Sandoval U.
IIC 1102 Pgina: 12
}

public bool mRecorrer(int fil, int col) {
bool listo = false; // Indica si se ha encontrado la salida

// Se marca la casilla como visitada
lab[fil,col] = '*';

// Se controla la condicin de termino de recursividad:
// " Llegamos a la salida? "
if (fil == xf && col == yf)
return(true);

if (!listo && mValidate(fil,col-1)) // Intento a la izquierda
listo = mRecorrer(fil,col-1);
if (!listo && mValidate(fil,col+1)) // Intento a la derecha
listo = mRecorrer(fil,col+1);
if (!listo && mValidate(fil-1,col)) // Intento hacia arriba
listo = mRecorrer(fil-1,col);
if (!listo && mValidate(fil+1,col)) // Intento hacia abajo
listo = mRecorrer(fil+1,col);

// Si no se logr resolver el laberinto desde esta posicin, se
// desmarca la casilla pues no ser parte de la solucin. En este
// caso se retornara falso lo que provocara que se retroceda.
if (!listo)
lab[fil,col] = ' ';
// Se retorna TRUE/FALSE dependiendo de si se encontr solucin
return(listo);
}
}

class Cmain {
public static void Main() {
CLab l = new CLab();
l.mDisplay();
if(l.mRecorrer(1,0)) l.mDisplay();
else Console.WriteLine("Laberinto no tiene solucin!");
}
}


Obsrvense los pasos innecesarios que se dan (por qu ocurre?)

Material preparado por Rodrigo Sandoval U en Mayo 2004,
basado en los apuntes de clase del curso IIC1102, ao 2003, de M. Nussbaum, Marcos Seplveda, et.a
Los ejemplos fueron adaptados y preparados por el MSR Lab, del DCC de la Escuela de Ingeniera de la PUC

PONTIFICIA UNIVERSIDAD CATLICA DE CHILE
ESCUELA DE INGENIERA
DEPARTAMENTO DE CIENCIA DE LA COMPUTACIN
IIC 1102 INTRODUCCIN A LA PROGRAMACIN
Profesor: Rodrigo Sandoval U.

Captulo XII Bsqueda y Ordenamiento


1 INTRODUCCIN ............................................................................................................................................... 1
2 ALGORITMOS DE BSQUEDA SIMPLE...................................................................................................... 2
2.1 BSQUEDA LINEAL .........................................................................................................................................2
2.1.1 Ejemplo: Bsqueda lineal en vector de enteros ..................................................................................... 2
3 ALGORITMOS DE ORDENAMIENTO .......................................................................................................... 5
3.1 ORDENAMIENTO POR SELECCIN....................................................................................................................5
3.2 ORDENAMIENTO POR SELECCIN (VERSIN ITERATIVA).................................................................................7
4 COMPLEJIDAD DE ALGORITMOS............................................................................................................... 9
4.1 ORDENAMIENTO Y BSQUEDA EFICIENTES.....................................................................................................9
4.2 COMPARACIN DE ALGUNAS FUNCIONES DE TIEMPO......................................................................................9
5 ALGORITMOS EFICIENTES DE BSQUEDA........................................................................................... 11
5.1 BSQUEDA BINARIA .....................................................................................................................................11
5.1.1 Algoritmo ............................................................................................................................................. 11
5.1.2 Ejemplo: Bsqueda Binaria ................................................................................................................. 11
5.1.3 Versin Iterativa................................................................................................................................... 13
5.2 ALGORITMO DE ORDENAMIENTO: QUICKSORT.............................................................................................14
5.2.1 Ejemplo: Ordenamiento con Quicksort de forma recursiva................................................................. 15
5.2.2 Ejemplo: Ordenando las lneas de un archivo..................................................................................... 17


Intro. Prog. Orientada a Objeto Bsqueda y Ord. Rodrigo Sandoval U.
IIC 1102 Pgina: 1
1 Introduccin
Los computadores se emplean frecuentemente para almacenar y recuperar grandes volmenes de datos.
Con su velocidad y facilidad de acceso, los computadores aventajan a otros medios de almacenamiento
como el papel y las microfichas.
Es importante estudiar la forma en que los computadores pueden almacenar los datos, de modo que su
recuperacin (bsqueda) sea rpida. Para lograr esto, y puesto que usualmente los usuarios requieren
que los datos recuperados cuenten con algn orden particular, tambin es importante estudiar algoritmos
para ordenar los datos almacenados.
En todos los ejemplos se supondr que existe un vector que contiene N datos. Para el caso de la
bsqueda, el problema consiste en averiguar si un determinado dato est o no en el vector, y si es as,
queremos saber su posicin.
Para el caso del ordenamiento, el problema consiste en ordenar el vector en forma ascendente (de menor
a mayor). Si se quisiera trabajar con ordenamiento descendente los cambios seran mnimos.
En este captulo se presentan varios algoritmos de bsqueda y ordenamiento que difieren entre s en
cuanto a su complejidad y eficiencia.

Intro. Prog. Orientada a Objeto Bsqueda y Ord. Rodrigo Sandoval U.
IIC 1102 Pgina: 2
2 Algoritmos de Bsqueda Simple
2.1 Bsqueda Lineal
Algoritmo:
Recorrer el vector de inicio a fin, comparando el dato buscado con cada elemento del arreglo.
Implementacin:
Mediante una funcin que implemente el algoritmo descrito. La funcin retornar la posicin en que se
encontr el dato, o bien la cantidad de elementos en el vector en el caso en que no se encuentre (esto
sera un subndice invlido).
/*************************************************************************
* Funcion que realiza una busqueda lineal de un valor entero en un vector
* de enteros. La funcion recibe como parametros el vector, la cantidad de
* elementos que hay en el vector (N) y el valor entero que se busca.
* Si se encuentra el valor entonces se devuelve la posicion de este, sino
* se devuelve la cantidad de elementos del vector.
*************************************************************************/
int BuscarLinealmente(int Numeros[], int N, int NumeroBuscado) {
/* Inicializar el indice para recorrer el vector de numeros */
int i = 0;

/* Recorrer el vector mientras no se llegue a su fin y no
se encuentre el numero buscado */
while ((i < N) && (NumeroBuscado != Numeros[i]))
i++;

/* Retornar la posicion del numero o la cantidad de elementos */
return(i);
}

2.1.1 Ejemplo: Bsqueda lineal en vector de enteros
/*************************************************************************
* Ejemplo: Busqueda lineal en un vector de enteros.
*************************************************************************/
using System;
using System.IO;

public class CSort {
public int[] mLeerVector(string archivo) {
StreamReader sr;
int [] numeros;

Console.WriteLine("Leyendo datos de entrada");

// Abrir el archivo
try {
sr = new StreamReader(archivo);
numeros = new int[Int32.Parse(sr.ReadLine())];

string str;
for(int i = 0; (str = sr.ReadLine()) != null; i++)
numeros[i] = Int32.Parse(str);

sr.Close();

Intro. Prog. Orientada a Objeto Bsqueda y Ord. Rodrigo Sandoval U.
IIC 1102 Pgina: 3
return(numeros);
} catch (Exception e) {
Console.WriteLine("Problema con apertura de I/O: ");
Console.WriteLine(e.Message);
Environment.Exit(1);
}

return null;
}

public void mMostrarVector(int[] vector) {
Console.WriteLine("Los contenidos del vector son...");
foreach(int i in vector)
Console.WriteLine("{0}",i);
}

public int mBusquedaLineal(int[] Numeros, int NumeroBuscado) {
for(int i = 0; i < Numeros.Length; i++)
if(Numeros[i] == NumeroBuscado) return i;

return -1;
}
}

public class CMain {
public static void Main(string [] args) {
CSort cs = new CSort();

Console.Write("Ingrese Nombre archivo: ");
string archivo = Console.ReadLine();

int[] vector = cs.mLeerVector(archivo);
cs.mMostrarVector(vector);
Console.Write("Ingrese el nmero que desea buscar: ");
int search = Int32.Parse(Console.ReadLine());
int pos = cs.mBusquedaLineal(vector,search);
if(pos == -1)
Console.WriteLine("No se encontr el nmero {0}",search);
else
Console.WriteLine("El numero {0} se encuentra en la posicin {1}",
search,pos);
}
}

Archivo de entrada
10
3
-5
20
0
11
4
2
9
-1
90

Ejemplo de ejecucin
Intro. Prog. Orientada a Objeto Bsqueda y Ord. Rodrigo Sandoval U.
IIC 1102 Pgina: 4
El vector de 10 enteros es:
3 -5 20 0 11 4 2 9 -1 90
Ingrese un nmero entero: 5
El 5 no esta en el vector.

Leyendo datos de entrada
El vector de 10 enteros es:
3 -5 20 0 11 4 2 9 -1 90
Ingrese un nmero entero: 11
El 11 esta en la posicin 4.
Intro. Prog. Orientada a Objeto Bsqueda y Ord. Rodrigo Sandoval U.
IIC 1102 Pgina: 5
3 Algoritmos de Ordenamiento
3.1 Ordenamiento por Seleccin
Algoritmo recursivo escogiendo el mayor:
Si el vector tiene un nico elemento no se hace nada. En caso contrario, se elige el mayor de los
elementos y se intercambia por el ltimo (posicin N-1). De esta forma, el ltimo elemento estar en su
posicin correcta. Luego se ordena el subvector que tiene N-1 datos.

/*************************************************************************
* Programa con funcin recursiva que ordena vector de enteros por seleccin.
* Si el vector tiene un solo elemento no se hace nada. De lo contrario,
* se elige el mayor de los elementos y se intercambia por el ultimo del
* vector (posicion N - 1). Luego se ordena el vector con N - 1 datos.
*************************************************************************/
using System;
using System.IO;

public class CSelSort {
public int [] mLeerVector(string archivo) {
StreamReader sr;
int [] numeros;

Console.WriteLine("Leyendo datos de entrada");

try {
sr = new StreamReader(archivo);
numeros = new int[Int32.Parse(sr.ReadLine())];

string str;
for(int i = 0; (str = sr.ReadLine()) != null; i++)
numeros[i] = Int32.Parse(str);

sr.Close();

return(numeros);
} catch (Exception e) {
Console.WriteLine("Problema con apertura de I/O: ");
Console.WriteLine(e.Message);
Environment.Exit(1);
}

return null;
}

public void mMostrarVector(int [] vector) {
Console.WriteLine("Los contenidos del vector son...");
foreach(int i in vector)
Console.WriteLine("{0}",i);
}

public void mOrdenarPorSeleccionRecursivo(int [] Numeros, int N) {
int i, PosMayor, aux;

if (N > 1) {
/* Busca el mayor elemento */
PosMayor = 0; /* Supone que el mayor es el primero */
for (i=1; i<N; i++)
if (Numeros[i] > Numeros[PosMayor])
Intro. Prog. Orientada a Objeto Bsqueda y Ord. Rodrigo Sandoval U.
IIC 1102 Pgina: 6
PosMayor = i;

/* Se lleva a cabo el intercambio */
aux = Numeros[N - 1];
Numeros[N - 1] = Numeros[PosMayor];
Numeros[PosMayor] = aux;

/* Llamado recursivo con el subvector de N-1 elementos */
mOrdenarPorSeleccionRecursivo(Numeros, N - 1);
}
}
}

public class CMain {
public static void Main(string [] args) {
CSelSort ss = new CSelSort();

Console.Write("Ingrese Nombre archivo: ");
string archivo = Console.ReadLine();

int [] vector = ss.mLeerVector(archivo);
Console.WriteLine("Antes de ordenar...");
ss.mMostrarVector(vector);
ss.mOrdenarPorSeleccionRecursivo(vector,vector.Length-1);
Console.WriteLine("Despues de ordenar...");
ss.mMostrarVector(vector);
}
}

Archivo de entrada
10
3
-5
20
0
11
4
2
9
-1
90

Ejemplo de ejecucin

C:\>ordsel entrada.txt
Leyendo datos de entrada

Antes de Ordenar
El vector de 10 enteros es:
3 -5 20 0 11 4 2 9 -1 90

Despues de Ordenar
El vector de 10 enteros es:
-5 -1 0 2 3 4 9 11 20 90
Intro. Prog. Orientada a Objeto Bsqueda y Ord. Rodrigo Sandoval U.
IIC 1102 Pgina: 7
3.2 Ordenamiento por Seleccin (versin iterativa)
Algoritmo iterativo escogiendo el mayor:
Se itera tantas veces como elementos hay en el vector. En cada iteracin se elige el mayor de los
elementos y se intercambia por el ltimo. Se decrementa N para que en la siguiente iteracin se trate el
siguiente. El orden en que se van ubicando los elementos es el mismo que en el caso recursivo.

using System;
using System.IO;

public class CSelSort {
public int [] mLeerVector(string archivo) {
StreamReader sr;
int [] numeros;

Console.WriteLine("Leyendo datos de entrada");

try {
sr = new StreamReader(archivo);
numeros = new int[Int32.Parse(sr.ReadLine())];

string str;
for(int i = 0; (str = sr.ReadLine()) != null; i++)
numeros[i] = Int32.Parse(str);

sr.Close();

return(numeros);
} catch (Exception e) {
Console.WriteLine("Problema con apertura de I/O: ");
Console.WriteLine(e.Message);
Environment.Exit(1);
}

return null;
}

public void mMostrarVector(int [] vector) {
Console.WriteLine("Los contenidos del vector son...");
foreach(int i in vector)
Console.WriteLine("{0}",i);
}

public void mOrdenarPorSeleccionIterativo(int [] Numeros, int N) {
int i, PosMayor, aux;
/* Itera tantas veces como elementos hay en el vector. */
/* En cada iteracion ubica el elemento en la posicion N */
while (N > 1) {
/* Busca el mayor */
PosMayor = 0; /* Supone que el mayor es el primero */
for (i = 1; i < N; i++)
if (Numeros[i] > Numeros[PosMayor])
PosMayor = i;

/* Lleva a cabo el intercambio */
aux = Numeros[N - 1];
Numeros[N - 1] = Numeros[PosMayor];
Numeros[PosMayor] = aux;
N--; /* Decrementar cantidad de elementos a ordenar */
}
}
Intro. Prog. Orientada a Objeto Bsqueda y Ord. Rodrigo Sandoval U.
IIC 1102 Pgina: 8
}

public class CMain {
public static void Main(string [] args) {
CSelSort ss = new CSelSort();

Console.Write("Ingrese Nombre archivo: ");
string archivo = Console.ReadLine();

int [] vector = ss.mLeerVector(archivo);
Console.WriteLine("Antes de ordenar...");
ss.mMostrarVector(vector);
ss.mOrdenarPorSeleccionIterativo(vector,vector.Length-1);
Console.WriteLine("Despues de ordenar...");
ss.mMostrarVector(vector);
}
}
Archivo de entrada
10
3
-5
20
0
11
4
2
9
-1
90

Ejemplo de ejecucin

Leyendo datos de entrada
Antes de Ordenar
El vector de 10 enteros es:
3 -5 20 0 11 4 2 9 -1 90
Despus de Ordenar
El vector de 10 enteros es:
-5 -1 0 2 3 4 9 11 20 90

Intro. Prog. Orientada a Objeto Bsqueda y Ord. Rodrigo Sandoval U.
IIC 1102 Pgina: 9
4 Complejidad de Algoritmos
El estudio de la complejidad de los algoritmos intenta obtener medidas que indiquen cmo ser el
comportamiento de los algoritmos ante variaciones en las caractersticas de los datos de entrada (por
ejemplo, la cantidad de datos).
El orden de ejecucin de un algoritmo, denotado por O(expresin) indica cmo ser el comportamiento
del tiempo de ejecucin del algoritmo ante variaciones en los parmetros de la expresin.
Por ejemplo, cuando se dice que un algoritmo tiene orden lineal respecto al nmero de elementos de
entrada, n, y denotado por O(n), se quiere expresar que el tiempo de ejecucin del algoritmo se
incrementar linealmente conforme se incremente el nmero de elementos de entrada.
Puede deducirse entonces que los algoritmos ms deseables son aquellos que cuenten con rdenes de
ejecucin logartmicos, y los menos deseables son aquellos con rdenes de ejecucin exponenciales.
4.1 Ordenamiento y Bsqueda Eficientes
Cuando la cantidad de datos que se estn manipulando es extremadamente grande, incluso un
computador puede tener problemas para llevar a cabo bsquedas u ordenamientos en un tiempo
razonable.
El algoritmo de bsqueda lineal, como es de esperar, es de orden O(n), donde n es el nmero de
elementos. El algoritmo de ordenamiento por seleccin es de orden O(n
2
), donde n es el nmero de
elementos.
A continuacin se estudiarn algoritmos que tienen complejidad O(log n).
4.2 Comparacin de algunas funciones de tiempo
n log n n log n n2 n2 log n
1 0,00 0,0 1 0,0
2 0,69 1,4 4 2,8
5 1,61 8,0 25 40,2
10 2,30 23,0 100 230,3
20 3,00 59,9 400 1198,3
50 3,91 195,6 2500 9780,1
100 4,61 460,5 10000 46051,7
200 5,30 1059,7 40000 211932,7
500 6,21 3107,3 250000 1553652,0
1000 6,91 6907,8 1000000 6907755,3
2000 7,60 15201,8 4000000 30403609,8
5000 8,52 42586,0 25000000 212929829,8
Intro. Prog. Orientada a Objeto Bsqueda y Ord. Rodrigo Sandoval U.
IIC 1102 Pgina: 10
10000 9,21 92103,4 100000000 921034037,2
20000 9,90 198069,8 400000000 3961395021,0
50000 10,82 540988,9 2500000000 27049445711,0
100000 11,51 1151292,5 10000000000 115129254649,7
200000 12,21 2441214,5 40000000000 488242905821,2
500000 13,12 6561181,7 250000000000 3280590844351,1
1000000 13,82 13815510,6 1000000000000 13815510557964,3
2000000 14,51 29017315,5 4000000000000 58034630954096,9
5000000 15,42 77124742,4 25000000000000 385623711759959,0


Intro. Prog. Orientada a Objeto Bsqueda y Ord. Rodrigo Sandoval U.
IIC 1102 Pgina: 11
5 Algoritmos Eficientes de Bsqueda
5.1 Bsqueda Binaria
La bsqueda binaria puede aplicarse nicamente a un conjunto ordenado de datos. Por esto,
supondremos que el vector que contiene los datos se encuentra ordenado ascendentemente (es decir, de
menor a mayor).
5.1.1 Algoritmo
Se analiza la posicin del medio. Si ah se encuentra el dato buscado, terminamos. Si el dato buscado es
menor, se busca en el subvector menor, y si es mayor, se busca en el subvector mayor (aprovechando el
hecho de que el vector est ordenado).
Cada vez que se hace uno de estos anlisis, se divide el vector en dos (de ah su nombre, bsqueda
binaria), y se descarta una de las mitades. Intuitivamente puede verse que la cantidad de trabajo
necesaria para encontrar un elemento (o saber que no est), es mucho menor que para el caso de la
bsqueda lineal.

/***********************************************************************
* Mtodo que realiza una bsqueda binaria de un elemento en un vector
* de enteros. La funcin recibe como parmetros el vector, el ndice de
* inicio y de fin del vector, y el valor entero que se desea buscar.
* Si el ndice de inicio es mayor que el de fin se retorna que no se
* encontr. En otro caso se divide el vector a la mitad, si el numero
* buscado es menor que el que esta en la mitad se busca entonces en la
* mitad inferior, si el numero buscado es mayor que el que esta en la
* mitad se busca entonces en la mitad superior y en otro caso, el numero
* en la mitad es el numero buscado.
***********************************************************************/
public int BusquedaBinaria(int[] Numeros, int Inicio, int Fin,
int NumeroBuscado) {
if (Inicio > Fin)
return(-1); // -1 representa: NO ENCONTRADO
else {
int pos = (Inicio + Fin) / 2;
if (NumeroBuscado < Numeros[pos])
return(BusquedaBinaria(Numeros, Inicio, pos-1, NumeroBuscado));
else if (NumeroBuscado > Numeros[pos])
return(BusquedaBinaria(Numeros, pos + 1, Fin, NumeroBuscado));
else
return(pos);
}
}

5.1.2 Ejemplo: Bsqueda Binaria

using System;
using System.IO;

public class CSort {
Intro. Prog. Orientada a Objeto Bsqueda y Ord. Rodrigo Sandoval U.
IIC 1102 Pgina: 12
public void mOrdenarPorSeleccionRecursivo(int [] Numeros, int N) {
int i, PosMayor, aux;

if (N > 1) {
// Busca el mayor elemento
PosMayor = 0; // Supone que el mayor es el primero
for (i=1; i<N; i++)
if (Numeros[i] > Numeros[PosMayor])
PosMayor = i;
// Se lleva a cabo el intercambio
aux = Numeros[N - 1];
Numeros[N - 1] = Numeros[PosMayor];
Numeros[PosMayor] = aux;

// Llamado recursivo al mtodo con el subvector de N-1 elementos
mOrdenarPorSeleccionRecursivo(Numeros, N - 1);
}
}

public int [] mLeerVector(string archivo) {
StreamReader sr;
int [] numeros;

Console.WriteLine("Leyendo datos de entrada");

// Abrir el archivo indicado
try {
sr = new StreamReader(archivo);
numeros = new int[Int32.Parse(sr.ReadLine())];

string str;
for(int i = 0; (str = sr.ReadLine()) != null; i++)
numeros[i] = Int32.Parse(str);

sr.Close();

return(numeros);
}
catch (Exception e) {
Console.WriteLine("Problema con apertura de I/O: ");
Console.WriteLine(e.Message);
Environment.Exit(1);
}

return null;
}

public void mMostrarVector(int [] vector) {
Console.WriteLine("Los contenidos del vector son...");
foreach(int i in vector)
Console.WriteLine("{0}",i);
}

public int mBusquedaBinaria(int[] Numeros, int Inicio, int Fin,
int NumeroBuscado) {
if (Inicio > Fin) return(-1);
else {
Intro. Prog. Orientada a Objeto Bsqueda y Ord. Rodrigo Sandoval U.
IIC 1102 Pgina: 13
int pos = (Inicio + Fin) / 2;
if (NumeroBuscado < Numeros[pos])
return(mBusquedaBinaria(Numeros, Inicio, pos-1, NumeroBuscado));
else if (NumeroBuscado > Numeros[pos])
return(mBusquedaBinaria(Numeros, pos+1, Fin, NumeroBuscado));
else
return(pos);
}
}
}

public class CMain {
public static void Main(){
CSort cs = new CSort();

Console.Write(Ingrese nombre archivo: );
string archivo = Console.ReadLine();

int [] vector = cs.mLeerVector(archivo);
cs.mOrdenarPorSeleccionRecursivo(vector,vector.Length);
cs.mMostrarVector(vector);
Console.Write("Ingrese el numero que desea buscar: ");
int search = Int32.Parse(Console.ReadLine());
int pos = cs.mBusquedaBinaria(vector,0,vector.Length-1,search);
if(pos==-1) Console.WriteLine("No se encontr el No {0}",search);
else Console.WriteLine("El No {0} se encuentra en la pos. {1}",
search, pos);
}
}
}

5.1.3 Versin Iterativa
Tambin es posible implementar el algoritmo de bsqueda binaria iterativamente, reemplazando la
recursividad por un ciclo:
/************************************************************************
* Mtodo que realiza una bsqueda binaria de un valor entero en vector
* de enteros. Se reciben como parmetros el vector, el ndice de
* inicio y de fin del vector, y el valor entero que se desea buscar.
* Mientras el ndice de inicio sea menor o igual que el de fin se divide
* vector a la mitad, si el numero buscado es menor que el que esta en la
* mitad se cambia el ndice de fin para la posicin anterior a la mitad y
* se vuelve a iterar, si el numero buscado es mayor que el que esta en la
* mitad se cambia ndice de inicio para la posicin posterior a la mitad
* y se vuelve a iterar, y sino, el numero en la mitad es el buscado.
* Si el ndice de inicio se hace mayor que el de fin entonces se retorna
* como No Encontrado.
*************************************************************************/
int BusquedaBinariaIterativa(int[] Numeros, int Inicio,
int Fin, int NumeroBuscado) {
while (Inicio <= Fin) {
int pos = (Inicio + Fin) / 2;
if (NumeroBuscado < Numeros[pos])
Fin = pos - 1;
Intro. Prog. Orientada a Objeto Bsqueda y Ord. Rodrigo Sandoval U.
IIC 1102 Pgina: 14
else if (NumeroBuscado > Numeros[pos])
Inicio = pos + 1;
else
return pos;
}
return -1; // -1 indica no encontrado
}


5.2 Algoritmo de Ordenamiento: Quicksort
El algoritmo Quicksort fue desarrollado en 1962 por C.A.R. Hoare, antes de que se implementaran los
primeros lenguajes con capacidad para ejecutar funciones recursivas.
El algoritmo, aplicado a un subvector vec[a ... b] es:
1. Elegir un elemento x cualquiera del vector, entre a y b. El elemento x se llama pivote. Usualmente
se elige el elemento que est en el medio.
2. Particionar el vector en dos subvectores: vec[a ... p] y vec[p+1 ... b], intercambiando elementos
de modo que todos los elementos que son menores que x estn a la izquierda y todos los
mayores que x estn a la derecha.
3. Aplicar Quicksort al subvector vec[a ... p]
4. Aplicar Quicksort al subvector vec[p+1 ... b]

La funcin que implementa el algoritmo Quicksort podra implementarse de la siguiente manera:
/*************************************************************************
* Mtodo recursivo que ordena un vector de enteros mediante Quicksort.
* Si el vector no tiene ms de dos elementos no se hace nada. De lo
* contrario, se particiona el vector y se aplica el mtodo a los dos
* subvectores que resultan de la particin.
* Se reciben como parmetros el vector y el ndice inicial y final.
*************************************************************************/
void QuickSort(int[] Numeros, int Inicio, int Fin) {
int p;

if (Inicio < Fin) {
p = ParticionarVector(Numeros, Inicio, Fin);
QuickSort(Numeros, Inicio, p);
QuickSort(Numeros, p + 1, Fin);
}
}

La funcin que lleva a cabo la seleccin del pivote y el particionamiento del vector sera:
/*************************************************************************
* Funcin para particionar un vector en dos subvectores, intercambiando
* elementos de modo que todos los menores que el pivote estn a la
* izquierda y los mayores a la derecha.
* Se reciben como parmetros el vector y el ndice inicial y final.
* Se retorna el ndice para particionar el vector (posicin del pivote).
*************************************************************************/
Intro. Prog. Orientada a Objeto Bsqueda y Ord. Rodrigo Sandoval U.
IIC 1102 Pgina: 15
int ParticionarVector(int[] Numeros, int Inicio, int Fin) {
int pivote = Numeros[(Inicio + Fin) / 2];
int izq = Inicio - 1;
int der = Fin + 1;
int aux;

while (izq < der) {
// Busca el 1er. elemento de la derecha que haya que intercambiar
do {
izq++;
} while (Numeros[izq] < pivote);

// Busca el 1er. elemento de la izq. que haya que intercambiar
do {
der--;
} while (Numeros[der] > pivote);

if (izq < der) {
// Lleva a cabo el intercambio
aux = Numeros[izq];
Numeros[izq] = Numeros[der];
Numeros[der] = aux;
}
}
return(der);
}


5.2.1 Ejemplo: Ordenamiento con Quicksort de forma recursiva

using System;
using System.IO;

public class CQSort {
public int [] mLeerVector(string archivo) {
StreamReader sr;
int [] numeros;

Console.WriteLine("Leyendo datos de entrada");

// Abrir el archivo
try {
sr = new StreamReader(archivo);
numeros = new int[Int32.Parse(sr.ReadLine())];

string str;
for(int i = 0; (str = sr.ReadLine()) != null; i++)
numeros[i] = Int32.Parse(str);

sr.Close();

return(numeros);
}
Intro. Prog. Orientada a Objeto Bsqueda y Ord. Rodrigo Sandoval U.
IIC 1102 Pgina: 16
catch (Exception e) {
Console.WriteLine("Problema con apertura de I/O: ");
Console.WriteLine(e.Message);
Environment.Exit(1);
}
return null;
}

public void mMostrarVector(int [] vector) {
Console.WriteLine("Los contenidos del vector son...");
foreach(int i in vector)
Console.WriteLine("{0}",i);
}

private int mParticionarVector(int[] Numeros, int Inicio, int Fin) {
int pivote = Numeros[(Inicio + Fin) / 2];
int izq = Inicio - 1;
int der = Fin + 1;
int aux;

while (izq < der) {
// Busca el 1er elemento de la der. que haya que intercambiar
do {
izq++;
} while (Numeros[izq] < pivote);

// Busca el 1er elemento de la izq. que haya que intercambiar
do {
der--;
} while (Numeros[der] > pivote);

if (izq < der) {
// Lleva a cabo el intercambio: swap
aux = Numeros[izq];
Numeros[izq] = Numeros[der];
Numeros[der] = aux;
}
}
return(der);
}

public void mQuickSort(int [] Numeros, int Inicio, int Fin) {
int p;

if (Inicio < Fin) {
p = mParticionarVector(Numeros, Inicio, Fin);
mQuickSort(Numeros, Inicio, p);
mQuickSort(Numeros, p + 1, Fin);
}
}
}

public class CMain {
public static void Main() {
CQSort qs = new CQSort();

Console.Write(Ingrese nombre archivo: );
Intro. Prog. Orientada a Objeto Bsqueda y Ord. Rodrigo Sandoval U.
IIC 1102 Pgina: 17
string rchivo = Console.ReadLine();

int [] vector = qs.mLeerVector(archivo);
Console.WriteLine("Antes de ordenar...");
qs.mMostrarVector(vector);
qs.mQuickSort(vector,0,vector.Length-1);
Console.WriteLine("Despus de ordenar...");
qs.mMostrarVector(vector);
}
}

5.2.2 Ejemplo: Ordenando las lneas de un archivo
Programa que ordena las lneas de un archivo y las guarda en otro.
Ilustra el uso de operaciones sobre archivos, y aplica uno de los algoritmos de ordenamiento estudiados.
Las lneas del archivo origen se leen una a una mediante fgets, y se almacenan en un vector de strings (o
matriz de chars). Una vez ah, se aplica un algoritmo de ordenamiento por seleccin y se procede a
escribirlas al archivo de salida mediante fputs. Los nombres de los archivos, se pasan como argumentos
a travs de la lnea de comandos.

using System;
using System.IO;

public class CLineSort {
public string [] mReadFile(string fileName) {
StreamReader sr;
string [] lines;

Console.WriteLine("Leyendo datos de entrada");

// Abrir el archivo
try {
sr = new StreamReader(fileName);

lines = new string[Int32.Parse(sr.ReadLine())];
for(int i = 0; i < lines.Length; i++) lines[i] = sr.ReadLine();

sr.Close();

return(lines);
}
catch (Exception e) {
Console.WriteLine("Problema con apertura de I/O: ");
Console.WriteLine(e.Message);
Environment.Exit(1);
}

return null;
}

public void mWriteFile(string fileName, string [] vector) {
StreamWriter sw;

try {
sw = new StreamWriter(fileName);
foreach(string str in vector)
Intro. Prog. Orientada a Objeto Bsqueda y Ord. Rodrigo Sandoval U.
IIC 1102 Pgina: 18
sw.WriteLine(str);

sw.Close();
}
catch (Exception e) {
Console.WriteLine("Problema con apertura de I/O: ");
Console.WriteLine(e.Message);
Environment.Exit(1);
}
}


public void mOrdenar(string [] VecString, int N) {
int i, PosMayor;
string StrAux;

if (N > 1) {
// Busca el mayor elemento
PosMayor = 0; // Al inicio se supone que el mayor es el primero
for (i=1; i<N; i++)
if (String.Compare(VecString[i], VecString[PosMayor])>0)
PosMayor = i;

/* Se lleva a cabo el intercambio */
StrAux = VecString[N-1];
VecString[N-1] = VecString[PosMayor];
VecString[PosMayor] = StrAux;

// Llamado recursivo a la funcin con el subvector de N-1 elementos
mOrdenar(VecString, N - 1);
}
}
}

public class CMain {
public static void Main(string [] args) {
Console.Write(Ingrese nombre archivo: );
string archivo = Console.ReadLine();

CLineSort ls = new CLineSort();
string [] vector = ls.mReadFile(archivo);
ls.mOrdenar(vector, vector.Length);
ls.mWriteFile(args[1],vector);
}
}

Archivo de prueba original
Volvo
Renault
Honda
Daihatsu
Chrysler
Opel
Alfa-Romeo
Mitsubishi
Suzuki
Rover
BMW
Jaguar
Ford
Intro. Prog. Orientada a Objeto Bsqueda y Ord. Rodrigo Sandoval U.
IIC 1102 Pgina: 19
Fiat
Mercedes-Benz
Volkswagen
Dodge
Nissan
Chevrolet
Kia
Daewoo
Toyota
Audi
Seat
Subaru
Citroen
Porsche
Peugeot
Hyundai
Mazda

Archivo de salida (resultado)
Alfa-Romeo
Audi
BMW
Chevrolet
Chrysler
Citroen
Daewoo
Daihatsu
Dodge
Fiat
Ford
Honda
Hyundai
Jaguar
Kia
Mazda
Mercedes-Benz
Mitsubishi
Nissan
Opel
Peugeot
Porsche
Renault
Rover
Seat
Subaru
Suzuki
Toyota
Volkswagen
Volvo