Apunte Algoritmos V 5.31
Apunte Algoritmos V 5.31
Apunte Algoritmos V 5.31
SIA200
Algoritmos y Programación
Por Matías Sánchez / Francisco Requena
Contenidos
1. Introducción ........................................................................................... 2
2. Comentarios........................................................................................... 3
3. Tipos de Variable y declaraciones .......................................................... 4
3.1. Expresiones Booleanas ........................................................................... 5
3.2. Strings .................................................................................................... 6
4. Entrada y salida ...................................................................................... 7
4.1. Impresión en pantalla ............................................................................ 7
4.2. Lectura en pantalla y conversión de tipos (parse): ................................. 9
5. Funciones (Métodos) ........................................................................... 10
6. Recursividad ......................................................................................... 12
7. Estructuras de control .......................................................................... 13
7.1. Estructuras condicionales selectivas .................................................... 13
7.2. Estructuras de repetición ..................................................................... 15
8. Arreglos................................................................................................ 17
8.1. Arreglos de una dimensión .................................................................. 17
8.2. Arreglos Multidimensionales: .............................................................. 20
9. Windows Forms ................................................................................... 23
9.1. Atributos de un objeto Forms: ............................................................. 24
9.2. Eventos: ............................................................................................... 25
9.3. Cuadros de diálogo: ............................................................................. 29
1. Introducción
Una de las principales razones por las cuales una persona aprende un lenguaje de
programación es para poder utilizar un computador como una herramienta que nos ayude
con la resolución de problemas (desde operaciones sencillas hasta una vasta gama de
problemas y procedimientos complejos).
Se podría decir que el proceso de crear un programa tiene dos fases: Primero, el
análisis y planteamiento de un problema que nos conduce a la especificación de un
algoritmo que lo resuelve y finalmente, la segunda fase que consiste en realizar la
transformación de dicho algoritmo a un programa.
La primera fase es la más difícil, dado que tendremos que definir tareas, variables,
flujos y cuáles serán las restricciones y validaciones que habremos de considerar. Además,
de entre varias soluciones posibles tendremos que escoger la que nos parezca más
adecuada para luego definir bien que pasos tendremos que seguir.
La segunda fase, en cambio, consiste básicamente en realizar una especie de
“traducción” de nuestro algoritmo previamente especificado al lenguaje de programación,
que en este curso será el C# (C Sharp).
Espero este apunte les sea de mucha utilidad y les deseo mucho éxito en este
curso.
Francisco Requena
Agradecimientos:
-Sebastián Cisterna
-Gustavo Moreno
-Nicolás Charmín
-Iván Abarca
-Jonathan Vásquez
-Matías Sánchez (el autor de esta iniciativa)
2. Comentarios
Los comentarios serán parte importante de nuestro código. No sólo sirven para
externos que ven nuestro código (como sus queridos ayudantes), sino que también los
pueden ayudar a ustedes a llevar un orden en caso de que su código se haga muy largo o
si utilizan muchas variables.
La forma de poner los comentarios en el código es la siguiente:
/* Comentarios
en bloque */
Los comentarios de linea se escriben poniendo //. Todo lo que este hacia la
derecha de los slash en esa linea se convierte en comentario.
Los comentarios en bloque se comienzan con /* y se cierran con */. Todo lo que se
encuentre entre estos dos signos se considerara comentario.
Al momento de compilar, el computador no tomara los comentarios como código,
y nos van a ayudar para explicar que es lo que estamos haciendo. En Visual C veremos los
comentarios en color verde.
Como sugerencia, utilizen comentarios cuando esten usando muchas variables con
nombres que no representen lo que son (como por ejemplo a, x, y, etc). De esta manera
pueden tener registrado que haran con cada variable.
Tambien es muy util para ustedes (y para corregir) que especifiquen que hace
alguna parte de su código, como por ejemplo:
Ejemplos de declaración:
int x = 0;
char letra = 'a';
double real = 5.2;
string palabra, frase = "Hola Mundo";
bool condicion = true;
Observaciones:
- Se puede declarar la variable primero y luego asignarle valor en otra línea de
código. Ejemplo:
- Se pueden declarar múltiples variables del mismo tipo en una sola linea.
Ejemplo:
int x, y, z;
3.1. Expresiones Booleanas
int x = 1, y = 2;
Entonces:
x == y; //Falso
x != y; //Verdadero
x < y; //Verdadero
x > y; //Falso
x == 1; //Verdadero
x != 1; //Falso
Entonces:
q && p; //Falso
q || p; //Verdadero
3.2. Strings
Los string poseen una serie de propiedades que pueden ser de mucha utilidad
para la resolución de ciertos problemas. Tengamos presente que este tipo de variable es
en esencia una cadena de caracteres (char). Pueden ser comparados usando los
operadores ‘==’ y ‘!=’. Además, podemos utilizar el operador ‘+’ para concatenar dos o
más string. Ejemplo:
Console.WriteLine("");
Console.Write("");
Console.WriteLine("Hola Mundo");
Si se fijan, el cursor quedo una línea más abajo de lo que escribimos debido al salto
de línea después de haber impreso. Ahora si hubiésemos hecho Console.Write("Hola
Mundo"); el cursor habría quedado justo después de la ‘o’.
Para poder imprimir variables, tendremos que colocar signos ‘+’ entre las comillas
y el nombre de la variable. De esta manera, si tenemos que:
int x = 1;
Console.WriteLine(x + "Hola Mundo");
Console.WriteLine("Hola " + x + " Mundo");
Console.WriteLine("Hola Mundo " + x);
Obtendríamos lo siguiente en pantalla:
Otros comandos útiles que tenemos para las impresiones en pantalla son \t y \n.
donde \t es una tabulación y \n un salto de línea. Ellos deben ir dentro de las comillas y se
verían así:
Console.WriteLine("Hola \tMundo");
Console.WriteLine("Hola \nMundo");
En pantalla:
Donde se ve que la primera línea tiene la tabulación (es una especie de espacio) y
en la segunda vemos el salto de línea.
4.2. Lectura en pantalla y conversión de tipos (parse):
int x;
x = int.Parse(Console.Readline()); //Transformamos la lectura a int
char letra;
letra = char.Parse(Console.ReadLine());
int x;
string y;
y = Console.ReadLine();
x = int.Parse(y);
Otra función que nos será de utilidad será Console.ReadKey();, la cual consiste en
esperar a que el usuario presione una tecla antes de continuar. Lo utilizaremos
principalmente al final de nuestro código para que el programa no finalize su ejecución
hasta que nosotros se lo indiquemos.
5. Funciones (Métodos)
Cuando le pedimos al compilador que ejecute nuestro código lo que hará es leer
todas las instrucciones dentro del Main para luego crear un ejecutable el cual es el que
vemos (en la consola). Las funciones son declaradas afuera del Main, pero su
funcionalidad está en que puedan ser llamadas por el Main para ser ejecutadas. A
continuación, un program.cs de ejemplo:
namespace ConsoleAplication
{
class Program
{
static void Main(string[] args)
{
Nombre(); // Llamado de la funcion en el Main
}
Observaciones:
- Una función puede ser llamada por otra función. Incluso, una función puede ser
llamada por si misma. A esto último se le conoce en programación como
recursividad, lo cual profundizaremos a continuación.
6. Recursividad
Así, si la función es llamada con un número cualquiera mayor a cero, esta será
llamada nuevamente desde si misma con el mismo número menos uno hasta que n – 1
sea igual a cero, tras lo cual la función no se seguirá llamando a sí misma y retornará 1 al
llamado anterior, y este al anterior y así hasta la primera llamada, con lo cual se calculará
el resultado.
Ciertamente, esta forma de resolver problemas tiene sus ventajas y desventajas
respecto a la forma tradicional (iterativa) de plantear algoritmos. De manera recursiva los
problemas se pueden plantear de una forma mucho más elegante y comprensible. Los
ejemplos más comunes son el factorial y la sucesión de Fibonacci. Como desventaja, para
el computador será mucho más pesado resolver problemas a través de un planteamiento
recursivo que de modo iterativo.
Observación:
-Una función recursiva siempre tendrá su equivalente iterativa y viceversa
7. Estructuras de control
Ahora ingresaremos al tema de estructuras de ciclos y selección. En general, estas
herramientas son la base de la programacion básica. Las distintas estructuras serán
nuestra base para resolver problemas, a través de la resolución de preguntas como “¿Qué
pasa si son iguales? y ¿Qué pasa si son distintos? “, “¿Cuántas veces necesito repetir una
acción y cuando deseo detenerme?”.
En un principio puede ser confuso qué usar y bajo qué condición, pero con la
práctica verán que uno se acomoda a su uso.
Recordemos que la ‘Condicion’ es una expresión Booleana. En el caso que ella nos
devuelva verdadero, entonces entraremos al if. Si nos devuelve Falso, simplemente no
entraremos.
if (Condicion1)
{
Acciones;
}
else if (Condicion2)
{
Acciones;
}
else if (condicion3)
{
Acciones;
}
else
{
Acciones;
}
En resumen, si la condicion1 es falsa, analizaremos la condicion2, si esa tambien es
falsa, analizaremos la condicion3 y asi. Si todas las condiciones resultaron falsa, podríamos
terminar con un else.
7.1.2 Switch
La otra estructura de selección que usaremos es el switch. La estructura es la
siguiente:
switch (variable)
{
case (valor1): //“Si variable es igual a valor1”
Acciones;
break;
case (valor2): //“Si variable es igual a valor2”
Acciones;
break;
case (valor3): //“Si variable es igual a valor3”
Acciones;
break;
default: //“Si variable no es igual a ninguno”
Acciones;
break;
}
Llamaremos al switch con una variable (la cual obviamente tiene que estar
declarada y cuyo valor debe haber sido asignado previamente). Esa variable será
comparada con el valor que se le de a los distintos casos. Los valores que están
representados por valor1, valor2 y valor3 tienen que ser acorde con el tipo de variable
que le ingresamos al switch. Por ejemplo si ingresamos la variable int x los valores de los
casos no pueden ser caracteres. El default será el caso en que la variable que le
ingresemos sea distinta de todos los casos existentes. Este es opcional, pero el switch
claramente necesitara al menos un case para funcionar.
A diferencia del if, el switch no pedirá condiciones booleanas, pero en el fondo
estará haciendo una comparación también (algo asi como variable == valor1).
Entre los que usaremos comunmente estan el while y el do while. Sus respectivas
traducciones “mientras” y “hacer mientras” nos dan a entender que repetirán un
procedimiento “mientras” alguna condicion se cumpla. La única diferencia entre estos dos
ciclos es que en el do while necesariamente entraremos al menos una vez (fijense que la
condición esta despues del procedimiento), mientras que en el while puede que no
entremos nunca (si la primera vez que llegamos a él la condición es falsa). Se escriben de
la siguiente manera:
while (condicion)
{
Acciones;
}
do
{
Acciones;
}while(condicion);
Estos ciclos son bastante faciles de usar y cómodos, ya que bajo la condición que
tengamos tendremos la posibilidad de manipularla dentro del código. Por ejemplo, si en
algun punto logramos nuestro objetivo dentro del ciclo, podemos alterar el valor variable
de nuestra condición de manera que salgamos inmediatamente.
7.2.2. For
El ciclo for requiere un poco más de sintáxis para usarlo. Nos pedirá la
inicialización de una variable, una condición y alguna alteración (incremento) a una
variable despues de terminar un ciclo. Se escribe así:
Un ejemplo:
for (int i = 0; i < 10; i++)
{
Acciones;
}
Observación:
- Un ciclo while puede ser escrito de tal manera que cumpla la misma
funcionalidad que un for ya que este último es un caso particular del primero.
8. Arreglos
8.1. Arreglos de una dimensión
Los arreglos son una estructura de datos que nos ayudará a almacenar variables de
un mismo tipo de manera agrupada. La declaración de un arreglo se hará de la siguiente
manera:
O bien:
TipoDeDato[] NombreArreglo = {valores}; //Los valores separados por comas
En donde creamos un arreglo del mismo tipo y del mismo tamaño, pero con los
valores ya asignados. Si declaramos un arreglo como int[] numeros = new int[5];
Inicialmente este no tendrá valores en sus índices, por lo cual deberemos llenarlo para
poder trabajar.
int[] numeros = { 4, 5, 3, 1, 2 }
Fijense que el ultimo indice del arreglo es el tamaño menos 1 ya que los índices
comienzan desde 0. Para poder mostrar en pantalla algun valor del arreglo escribimos:
Console.Write("el indice 3 del arreglo es: " + numeros[3]);
En pantalla:
El ciclo en particular que nos va a ayudar mucho a trabajar con arreglos es el ciclo
for. Con él, seremos capaces de mover el índice y hacer distintas tareas sobre el arreglo.
Por ejemplo, si quisieramos imprimir todos los valores del arreglo, haríamos lo siguiente:
int[] numeros = { 4, 5, 3, 1, 2 };
for (int i = 0; i < numeros.Length; i++)
{
Console.Write(numeros[i]);
}
/* Nota: NombreDelArrglo.Length devuelve un entero que representa
el número de casillas del arreglo */
Con esto, la variable i se movera desde 0 hasta 4 (ultimo indice de este arreglo) y
cada ciclo imprimirá el valor de ‘numeros[i]’ en donde i sera el índice. Por lo tanto, cuando
i valga 0, imprimirá numeros[0] el cual es el primer indice de este arreglo. En pantalla
tendremos:
int[] numeros = { 4, 5, 3, 1, 2 };
Console.Write(numeros[5]); // Llamando un indice que no existe
Y al ejecutar:
int[] numeros = { 4, 5, 3, 1, 2 };
char[] letras = new char[10];
string[] saludo = new string[3];
double[] reales = new double[100];
bool[] bombas = { false, true, false };
Y tener en pantalla:
Hasta el momento hemos visto el caso de arreglos de una dimensión, los cuales
podríamos decir que se comportan como un vector. Ahora veremos que tambien
podemos declarar arreglos de mas de una dimensión; una matriz de datos, incluso un
cubo de datos o mucho mas. Respecto al curso, sólo veremos hasta arreglos
bidimensionales, es decir, como una matriz. Primero veamos una declaración de un
arreglo bidimensional vacío:
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
N° de Filas/ N° de Columnas: 0 1 2 3 4
1
2
Antes que nada, consideramos importante para una mejor comprensión de esta
sección hacer una breve introducción del concepto de “objeto” en programación, dado
que para este caso no utilizarán la consola para probar sus códigos sino que ahora
trabajarán programas que mostrarán directamente una interfaz gráfica de ventanas con
sus respectivos controles (tales como botones) y donde cada uno de estos elementos,
incluida la misma ventana, es un objeto.
Básicamente, un objeto está caracterizado por los atributos que lo definen y los
métodos que dispone. Como ejemplo, podríamos decir que hay una clase “persona” cuyos
atributos serían su edad, estatura, peso, color de pelo, etc. Sus métodos (funciones) serían
las acciones que la persona podría realizar, como por ejemplo hablar o caminar.
En el entorno que nos ofrece el C# podremos encontrar múltiples objetos que nos
serán de utilidad para elaborar una interfaz que permita al usuario hacer uso de las
funcionalidades que programaremos. A continuación mencionaremos algunos objetos de
uso recurrente:
Un ejemplo:
9.1. Atributos de un objeto Forms:
BackColor: corresponde al color del fondo del objeto. Existen no sólo los colores
típicos, sino combinaciones similares a las de las páginas Web.
BackgroundImage: lo que conseguimos con esta propiedad es la de asignarle al
fondo de la ventana una imagen ya definida por nosotros mismos (en estos casos
es recomendable salvar esta imagen en el directorio “…Bin\Debug” a modo de
orden).
Font: esta propiedad nos permite modificar lo referente a la fuente que utilizamos
en la ventana, desde la tipografía, tamaño, tal como lo hacemos en el procesador
de texto.
ForeColor: esta propiedad nos permite modificar el color de la fuente utilizada en
la ventana.
Size: par ordenado que nos permite modificar el ancho y el alto de la ventana, éste
está expresado en pixeles.
Text: esta propiedad modifica el texto que despliega el objeto en pantalla, así
como en el caso de los textbox podemos acceder al texto que ingresa el usuario a
través de esta propiedad. Es del tipo string.
Icon: Modifica el icono que aparece en la barra antes mencionada.
Enabled: Esta propiedad, al estar en estado False, impide al usuario a manipular el
objeto. Es del tipo bool.
ReadOnly: en este caso, estamos dando la cualidad de que el objeto sólo podrá ser
leído por el usuario, el cual no podrá modificar ni ingresar texto en él
(independiente de que sí podrá colocar el cursor en él). Es tipo bool.
Visible: Propiedad que permite ocultar el objeto al momento de ejecutar el
programa. Es tipo bool.
Ítems: Colección de elementos que puede contener el objeto. Puede ser una lista
de strings.
SelectionMode: Nos permite definir si el objeto permite seleccionar, uno, más de
uno o ninguno de los campos (si los tiene).
Podemos acceder a modificar las variables de un objeto seleccionándolo con el mouse y
modificando los campos en la ventana “Propiedades”:
El campo (Name) es uno de los más importantes ya que este determina cual será el
nombre de referencia con el cual nos vamos a referir a el objeto en particular. Mediante
esta referencia podremos acceder a las propiedades (atributos) del objeto cuando veamos
el código de nuestra aplicación de ventanas.
9.2. Eventos:
Ahora que nos encontramos frente a una interfaz gráfica que contiene botones,
campos, cuadros de texto y etiquetas, nuestra tarea será determinar el cómo responderán
nuestros objetos al interactuar el usuario con ellos. Debemos programar nuestros objetos
de tal manera que ante un determinado evento el programa ejecute cierta acción. Por
ejemplo, al crear un botón podríamos ubicarlo en nuestra ventana, cambiar su texto y su
color (entre otros atributos). Pero al compilar, si es que aún no hemos establecido que
sucede al hacer click al botón esté pasará a ser un simple adorno en nuestra pantalla. Los
eventos se modifican en la ventana propiedades haciendo click en el ícono del relámpago:
Cuando hacemos doble click en un objeto, el programa crea de manera automática
una función que responderá a un evento al hacer click en él o cambiar de selección en el
caso de que fuera una lista. Generalmente, la función lleva por nombre
nombreObjeto_Evento. Nótese que en el form1.cs (vista código) podemos ver las
funciones existentes e incluso podemos programar algunas nuevas con los nombres y
funcionalidades que nosotros queramos (generalmente del tipo void) y asignar la función
que hayamos creado a determinado evento. Por ejemplo crearemos la función
“cambiarTexto” en nuestro programa:
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
Y luego podremos seleccionar esa función para cualquier evento que queramos:
En el espacio de las funciones podemos cambiar la apariencia y contenido de los
elementos de nuestra ventana. Como mencionábamos anteriormente, para acceder a una
“variable atributo” de nuestros objetos podemos hacer lo siguiente:
Donde lo que va después del punto puede ser una de las variables que
encontramos en la ventana propiedades. Al igual que cualquier variable, podemos
asignarle un nuevo valor y también podemos realizar condicionantes al valor que esta
variable tome. Tener presente que podemos declarar variables tanto dentro de estos
eventos como fuera de ellos.
A continuación veremos un ejemplo del uso de eventos para cambiar las propiedades de
algún objeto:
En este ejemplo, se diseñó una ventana con un label que tiene el texto “Hola!” a la
cual llamaremos “saludo” (propiedad “(Name)”) y un button con el texto “Despedirme” al
cual llamaremos “boton1”. Para este ejemplo, programaremos que ante el evento que
boton1 sea presionado el texto (propiedad “Text”) del label saludo cambie a “Chao”.
Para hacer esto debemos seleccionar el objeto boton1 y establecer el código para
realizar la acción que queremos dado el evento que en este caso será “hacer click” en el
botón:
Hacemos doble click en el campo del evento “Click” y el programa nos generará
automáticamente una función vacía en la cual podremos establecer que sucederá al
ocurrir este evento:
Ahora indicaremos al programa que debe cambiar el texto del objeto llamado
saludo a “Chao”:
También podemos establecer que una vez el texto sea “Chao” al presionar el botón
este cambie a “Hola” y que el botón diga “Saludar” en vez de “Despedirme” y viceversa:
MessageBox.Show("Mensaje","Titulo", MessageBoxButtons.<TipoDeBotones>);
Donde en el campo <TipoDeBotones> debemos escoger cuales serán los botones (de
entre un set de predeterminados) que tendrá nuestro cuadro de dialogo:
Al igual que sucede con los botones de nuestra ventana, si no programamos una
respuesta a las acciones del usuario, nuestro cuadro de diálogo será un simple decorativo
en el programa.
Para almacenar la respuesta del usuario debemos declarar una variable del tipo
DialogResult, la cual podremos utilizar para responder ante determinado botón que
presione el usuario: