Apuntes Programación A
Apuntes Programación A
DIAGRAMA DE FLUJO: Representación gráfica de un algoritmo (proceso). Se escriben de arriba abajo o de izquierda a
derecha, evitando cruces de líneas. Las líneas de flujo deben estar conectadas a algún objeto. El texto en las formas debe
ser escueto y legible. Los símbolos de decisión deben tener más de una línea de salida.
Compilador: Traduce un programa escrito en lenguaje de alto nivel, a un programa en lenguaje máquina, generando un
archivo ejecutable para una determinada plataforma. El programa compilado no contiene el código fuente.
CLR (Common Language Rutime): Ejecuta el código y proporciona servicios facilitando el proceso de desarrollo
(integración entre lenguajes, control de excepciones, seguridad mejorada y compatibilidad de versiones).
PROGRAMACIÓN ESTRUCTURADA: Las instrucciones deben ejecutarse una detrás de otra. Tres estructuras básicas:
secuencial, selectiva (condicional) e iterativa (Alfred Dijkstra).
C#
Lenguaje orientado a objetos, que utiliza recolector de basura y permite unificación de tipos.
Las aplicaciones están formadas por uno o varios ficheros con su código fuente correspondiente, siendo sólo uno de ellos
el principal. Extensión ficheros en C#: “cs”.
Toda clase que vaya a ser ejecutada debe contener una función main.
COMENTARIOS:
//Esto es un comentario
Console.WriteLine ("Hola Mundo") ;
/*Esto es otro comentario separado
en varias líneas*/
FUNCIÓN: Trozo de código al que se le denomina con un nombre, por el que se la llamará cada vez que se quiera
ejecutar.
VARIABLE: Espacio de memoria identificado por un nombre, que puede ir variando a lo largo del programa, que almacena
un dato determinado. Tienen como ámbito de trabajo el bloque {} donde han sido definidas. Al salir de él se destruyen.
Debe comenzar por letra o “_”. Pueden ir acentuadas (aunque no es buena práctica). Puede incluir dígitos (pero no
comenzar por ellos). Distingue mayúsculas de minúsculas. No puede llevar espacios en blanco y es recomendable utilizar
notación lowerCamelCase (si es privada) o UpperCamelCase (si es pública). No se pueden utilizar palabras clave
(palabras reservadas).
VARIABLE GENÉRICA “VAR”: Es el propio compilador el que asigna el tipo y debe inicializarse en la misma línea de su
definición:
CONSTANTE: Espacio de memoria identificado por un nombre, que puede ir variando a lo largo del programa, que
almacena un dato determinado. Se recomienda escribir las constantes en MAYÚSCULAS.
CONVERSIONES: Conforme vamos avanzando en el programa, es posible que debamos adaptar variables a nuevos
tipos de datos. Los tipos en C# son estáticos en tiempo de compilación, por lo que, tras la declaración de la variable, no
se puede volver a declarar, ni se le puede asignar un valor de otro tipo salvo que se trate de una conversión implícita o se
realice un casting.
(tipoAlQueConvertir) valor
Conversión de texto a número (método PARSE): Con Parse() convertimos un string en “int”, “double”, etc.. El
problema de Parse es que, si no se puede hacer la conversión, genera una excepción. Es mejor utilizar
TryParse(cadena, out valor), que devuelve un booleano true, si se ha podido hacer la conversión, en cuyo caso, además,
devuelve el valor convertido
TIPOS DE DATO
Simples predefinidos:
Tipos enumerados: Ofrecen la posibilidad de definir nuevos tipos simples de cardinalidad reducida.
enum <nombreVariable> {elemento1, elemento2,..., elementoN};
enum Días {lunes, martes, miércoles, jueves, viernes, sábado};
int x = (int) dias.martes;
Console.WriteLine(“martes= {0}”);
martes=1
Tipos de estructura:
struct <nombreVariable> { };
ARRAY: Almacena varias variables del mismo tipo en una estructura de datos. Base 0, es decir, el primer elemento
se sitúa en el índice 0.
Definición: <tipo> [] <nombreVariable>= new* <tipo> [n]; * New reserva un espacio en la memoria.
<tipo> [] <nombreVariable>= new <tipo> []{1, 2, 3, ... , n};
<tipo> [] <nombreVariable>= {1, 2, 3, ... , n};
MATRICES: Son la unión de varios arrays. Si se trata de una matriz bidimensional, necesitaremos dos indicadores de
posición.
Definición: <tipo> [ , ] <nombreVariable>= new <tipo> [filas, columnas];
STRING: Texto. Se almacena como una colección secuencial de sólo lectura de objetos Char. Su funcionamiento es
similar al del array, teniendo características comunes, como el índice en base 0, de los elementos.
NO es un tipo de dato primitivo, sino que es un TIPO DE DATO DE REFERENCIA.
Recorriendo un Array:
nombreArray.Length();
El array puede ser usado como parámetro en cualquier función, teniendo en cuenta que siempre será pasado por
referencia.
OPERADORES
NÚMEROS ALEATORIOS: Tope inferior: Valor mínimo del rango. Incluido entre los posibles.
// Concatenación
Console.WriteLine(“Mi cantante favorito es ” +favorito+ ” y nació en “ +nacimiento+ ”.”);
if: Bloque mínimo. if / elseif / else: Sólo puede haber un “si no” (o ninguno).
switch II:
switch I:
for: Mientras el contador cumpla la condición, se repiten las instrucciones del bloque. El contador cambia en cada
iteración, de acuerdo con la modificación prevista. La condición se evalúa al principio, por lo que puede no llegar a
ejecutarse nunca.
ESTRUCTURAS DE SALTO: Son aquellas que paran la ejecución de las sentencias de control del programa.
break: Interrumpe la ejecución del bucle contenedor donde se encuentra, para continuar a partir de la siguiente sentencia
después del bloque del ciclo.. en una sentencia switch con varios casos, garantiza que sólo se ejecute el caso relacionado.
continue: Se utiliza en for, while y do...while, para saltar directamente a la siguiente iteración de la instrucción
envolvente.
return: Obliga a que se finalice la ejecución de una función, devolviendo el control a la función de llamada.
goto: Transfiere el control a una instrucción con etiqueta. Un uso común es transferir el control a una etiqueta de switch
case específica goto case 3; También es útil para salir de bucles demasiado anidados.
DEPURACIÓN DE ERRORES
Utilizar excepciones y validaciones para asegurar que el usuario introduce datos válidos, teniendo en cuenta todos los
escenarios posibles.
Utilizar la técnica de “divide y vencerás”... una buena forma de contrarrestar los errores lógicos es dividir algoritmos
grandes y complejos en tareas pequeñas, de forma que el código sea más legible y se puedan depurar más fácilmente
los errores lógicos.
DOCUMENTACIÓN DE PROGRAMAS
- Memoria: Se registra el desarrollo, los fallos que se han presentado y cómo se han solventado.
- Un proyecto puede ser utilizado para entregar más de una aplicación.
- Visual Studio permite configurar los archivos que se deben entregar y, además, ejecuta y genera un wizard de
instalación. Ofrece la posibilidad de configurar directorios de destino, el registro de Windows y el escritorio de usuario.
IDE: Entorno de programación que se ha utilizado para realizar un programa: Editor de código, compilador, depurador e
interfaz gráfica (GUI).
Son utilizados por distintos lenguajes de programación. Algunos funcionan como sistemas en tiempo de ejecución.
Algunos Entornos de Desarrollo Integrado son: Eclipse, Netbeans, JDeveloper de Oracle, Visual C++, Monodevelop,
Visual Studio...
Para un correcto funcionamiento, deben ser multiplataforma, ser válidos para diferentes lenguajes de programación,
reconocer sintaxis, estar integrados con sistemas de control de diferentes versiones, incluir depurador, permitir importar-
exportar proyectos, varios idiomas y manual de usuario.
Ventajas: Baja curva de aprendizaje, uso óptimo para usuarios no expertos, formateo de código, .funciones para
renombrar funciones y variables, creación de proyectos, herramientas para extraer partes de código, errores y warnings...
TRATAMIENTO DE CADENAS
En este caso, al crear el objeto string, le pasamos el parámetro letras como tabla de caracteres.
Principales métodos STRING (muchos de ellos tienen sobrecarga, que no se muestra en la tabla):
Arrays, Strings.. y algo de código para ilustrar..
Hay diversas formas de concatenar.. si puede utilizarse, StringBuilder tiene como positivo que es más rápida y eficiente
que string. Esta última, tiene una longitud fija, mientras que la primera varía.
Aparentemente, podemos concatenar con string, pero realmente, estamos ocupando un lugar nuevo de memoria (cada
vez que Viene a decir, que un string es inmutable y cuando aparentemente lo cambiamos, realmente, estamos haciendo
una instancia nueva, utilizando otro lugar de memoria... El programa irá siempre a la última instancia, a la última dirección
de memoria donde se haya guardado el string.. En el caso del StringBuilder, en cambio, es mutable.. y no se instancia
más que la primera vez..
Principales métodos de CHAR (muchos de ellos tienen sobrecarga, que no se muestra en la tabla
UF2: PROGRAMACIÓN MODULAR
La programación modular permite diseñar la solución del problema dividiendo la solución en módulos que se estructuran
e integran jerárquicamente. Aplica la técnica de “divide y vencerás”. Divide el problema original en subproblemas que
resuelve por separado y luego se integra para obtener la solución del problema
CARACTERÍSTICAS:
Diseño descendente o Top-Down: Pone en práctica la frase “divide y vencerás” de forma que se aborda un
problema dividiendo este en partes más pequeñas.
Abstracción: Mecanismo por el que se consigue que un bloque de código pueda ser usado sin conocer los
detalles de su programación. La persona que lo utiliza sólo necesitará conocer qué función desempeña, qué
elementos necesita para comenzar a funcionar y cuáles serán las salidas obtenidas.
Modulación: C# implementa la modulación mediante las funciones (métodos) y las clases. La modulación
permite la división de un programa en partes más pequeñas llamadas módulos, siendo cada uno de ellos tan
independiente como sea posible del bloque principal y resto de partes.
SUBPROGRAMAS/MÓDULOS (funciones y procedimientos)
Grupo de sentencias (instrucciones) a las que se les da un nombre identificativo, que realiza una tarea en concreto.
En C# los métodos las funciones y los procedimientos son lo mismo, salvo que las funciones devuelven un valor
y los procedimientos no.
Deberá ir dentro de una clase.
No realiza su tarea hasta que no es llamado.
Tiene que incluir “return”, salvo que sea del tipo “void”.
Puede no tener parámetros, o tener “n” parámetros.
Suelen comenzar con mayúscula si sólo tienen una palabra.
Para llamar a un método (las veces que queramos), deberemos hacerlo desde el método Main, o desde otro
procedimiento.
MODIFICADORES:
Public:
Cualquier otro código del mismo
ensamblado o de otro que haga
referencia a este, tiene acceso al tipo o
miembro.
Private:
Solamente el código de la misma clase
o estructura puede acceder al tipo o
miembro.
Protected:
Solamente el código de la misma clase,
o de una clase derivada, puede acceder
al tipo o miembro.
El método Main es estático para que pueda ser siempre llamado por el sistema operativo, sin tener que crear un objeto
de la clase que lo contiene. Se encarga de gestionar el flujo de ejecución, llamando a los diferentes módulos.
TIPO: Tipo devuelto por la función, salvo que sea VOID.
RETURN: Si la función no es VOID, es obligatoria la devolución de un parámetro del tipo adecuado, utilizando la palabra
clave return.
Cuando las funciones que devuelven un valor y, por lo tanto, tienen un “return”, constan de una sola línea de código,
no hace falta utilizar la palabra “return”, ni utilizar {llaves}, si se utiliza el operador “lambda” (==>):
static int sumaNumeros(int num1, int num2) ==> num1+num2; // Equivale a return num1+num2;
- POR VALOR (copia): Todas las modificaciones y/o cambios que se realicen, se están haciendo sobre la copia. El original
no altera su valor en la función.
- POR REFERENCIA (Original): Todas las modificaciones que se realicen en la función van a afectar a sus parámetros,
ya que se trabaja con los originales. Recordar, que los arrays son de tipo de referencia, es decir, siempre que se pasan
a un método, pasan por referencia, indiquemos o no ref, out..
Las palabras reservadas ref y out deberán incluirse junto al parámetro tanto en la declaración como en la
invocación a la función.
COMPILACIÓN: Según vamos escribiendo el código, el IDE de C# nos marca los errores de compilación que tenemos,
de forma que una vez subsanados, se puede proceder a una compilación limpia.
VINCULACIÓN: El IDE comprueba, además, que los métodos que se invocan existen (bibliotecas) y que coinciden con
su tipo y parámetros.
EJECUCIÓN: Una vez se consigue la ejecución del programa, hay que hacer pruebas, tratando de detectar cualquier
error que produzca resultados inesperados.
LIBRERÍAS: Conjunto de métodos relacionados con un mismo objetivo, preparados para ejecutarse. Al compilar, se
comprueba que se ha llamado a las de manera correcta a las funciones que pertenecen a las librerías que nos ofrece el
compilador, aunque en este momento, el código de estas funciones todavía no se ha insertado en el programa. Esta
inserción la hará posteriormente el enlazador o linkador, a la hora de generar el programa ejecutable.
C# permite la interoperación con otros lenguajes, si éstos tienen acceso a las diferentes librerías a través COM+ y
servicios .NET, soporte XML y simplificación en administración y componentes, gracias a un mecanismo muy cuidado de
versiones.
Recursividad directa: La función realiza una llamada a sí misma desde un punto concreto entre sus llaves de
inicio y fin.
Recursividad indirecta: La función realiza una invocación a otra función que es quien llama a la primera.
En caso de sobrecarga, al llamar al método desde el Main, el programa elegirá el método adecuado en función de
los atributos que introduzcamos.
if (input >= 0)
{
classify = "positivo";
}
else
{
classify = "negativo";
}
UF3: MANEJO DE FICHEROS
Los FICHEROS son una parte de un dispositivo no volátil a la que se le asigna un nombre y que contiene una cantidad
de datos limitada por el espacio disponible en el dispositivo o por las características del sistema operativo.
La BCL (Base Class Library) reserva un namespace denominado System.IO para su manejo. La plataforma .NET nombra
los ficheros utilizando un máximo de 259 caracteres, con este formato: <nombre_fichero>.<extensión>
Se almacenan en directorios o carpetas que, a su vez, pueden contener otros directorios creándose una estructura
jerárquica, donde cada fichero o directorio tiene como “padre” al directorio que lo contiene. Dado que la estructura es
finita, debe existir un directorio raíz.
La información es un conjunto de 0 y 1. Al agruparse los bits, se forman bytes o palabras. Al agruparse los campos, se
forman los registros de información. Un archivo estará constituido por un conjunto de registros, de forma que todos ellos
poseen la misma estructura. Finalmente, los directorios tienen la función de agrupar distintos ficheros
RUTA: Camino que lleva hasta un fichero, identificándolo de manera inequívoca (“dirección”).
Absoluta o completa: En Linux o Mac empezará por la raíz: ‘/’. En el caso de Windows, debe empezar por el nombre de
la unidad en cuestión: ‘C:\’
TIPOS DE FICHEROS
SECUENCIAL: Los registros se van almacenando en posiciones consecutivas. Cada vez que queremos
acceder a uno, debemos empezar desde el primero e ir recorriéndolos de uno en uno.
Sólo se puede realizar una operación de lectura o escritura a la vez.
ALEATORIO O DIRECTO: Se puede acceder a un registro concreto indicando una posición perteneciente a
un conjunto de posiciones posibles.
Pueden ser leídos o escritos en cualquier orden. Para realizar una operación, basta con situar el puntero justo
en la posición anterior.
SECUENCIAL INDEXADO: Poseen un campo clave, de forma que se permite el acceso secuencial y
aleatorio de la siguiente manera:
APERTURA: Al abrir un fichero relacionamos un objeto de nuestro programa con un archivo, de forma que
debemos especificar el nombre del fichero y el modo en el que vamos a operar sobre él.
LECTURA/ESCRITURA: Se leerá la información teniendo en cuenta especialmente la posición en la que se
encuentra el manejador de archivos. Éste indica el punto desde el que empezar a leer y si está situado al final
del fichero, la operación de lectura no sería posible.
CIERRE: El fichero queda liberado y finaliza el proceso de almacenamiento de la información, es decir, se termina
de escribir en el dispositivo físico la información guardada aún en el buffer.
TIPOS DE FLUJO:
FLUJOS DE BASE: Trabajan directamente con el dispositivo físico, disco, memoria, conexión de red, etc...
FLUJOS INTERMEDIOS: No trabajan con los dispositivos de forma directa, sino que envuelven a otros flujos que sí
lo hacen.
De alguna forma, el flujo intermedio procesa la información, mientras que el base realiza la función de envío de bytes
de un lugar a otro.
Los flujos son las pasarelas que tenemos para acceder a los datos. Representa una secuencia de bytes entre una
fuente y un destino de información.
El tipo de stream lo definimos al principio de trabajar con el fichero y no se puede cambiar una vez abierto
FileMode
FileAccess
Al escribir la ruta utilizamos: @ para no tener que poner \\ en lugar de \.
https://docs.microsoft.com/es-es/dotnet/csharp/language-reference/tokens/verbatim
OJO: Siempre hay que cerrar primero, lo último que se abre.. para evitar fallo del
código. “Hay que cerrar de dentro para fuera”.
FICHEROS DE TEXTO
Las siguientes son clases que implementan flujos intermedios para trabajar con ficheros de texto.
Ejemplo Lectura:
String linea;
// Apertura Fichero.
FileStream ejemploLectura = new FileStream(“fichero.txt”, FileMode.Open, FileAccess.Read);
// Apertura Flujo Lectura.
StreamReader flujoLectura = new StreamReader(ejemploLectura);
while ((linea=flujoLectura.ReadLine()) != null)
{
flujoLectura.WriteLine(linea);
}
flujoLectura.Close(); // Cierre Flujo Lectura.
ejemploLectura.Close(); // Cierre Fichero.
Ejemplo Escritura:
// Apertura Fichero.
FileStream ejemploEscritura = new FileStream(“fichero.txt”, FileMode.Open, FileAccess.Write);
// Apertura Flujo Escritura.
StreamWriter flujoEscritura = new StreamWriter(ejemploEscritura);
flujoEscritura.WriteLine(“Esta línea la estamos escribiendo en el fichero \”fichero.txt\””);
flujoEscritura.Close(); // Cierre Flujo Escritura.
ejemploEscritura.Close(); // Cierre Fichero.
Ejemplo Lectura y Escritura:
// Apertura Fichero.
FileStream ejemploLecturaEscritura = new FileStream(“fichero.txt”, FileMode.OpenOrCreate, FileAccess.ReadWrite);
// Apertura Flujo Lectura.
StreamReader flujoLectura = new StreamReader(ejemploLecturaEscritura);
Console.WriteLine(flujoLectura.ReadLine());
// Apertura Flujo Escritura.
StreamWriter flujoEscritura = new StreamWriter(ejemploLecturaEscritura);
flujoEscritura.Write(“HOLA”);
flujoEscritura.Close(); // Cierre Flujo Escritura.
flujoLectura.Close(); // Cierre Flujo Lectura.
ejemploLecturaEscritura.Close(); // Cierre Fichero.
Otro ejemplo...
flujoSalida.WriteLine(“líneas de texto.”);
FICHEROS BINARIOS
Las siguientes operaciones: BinaryReader y BinaryWriter (encapsuladas en FileStream), proporcionan métodos para
facilitar las operaciones de lectura y escritura de archivos binarios.
Ejemplo Escritura:
// Apertura Fichero.
FileStream ejemploEscritura = new FileStream(“datos.dat”, FileMode. Create, FileAccess.Write);
// Apertura Flujo Escritura.
BinaryWriter flujoEscritura = new BinaryWriter (ejemploEscritura);
string linea=”Hola mundo.”;
flujoEscritura.Write(linea);
// Cierre Flujo Escritura.
flujoEscritura.Close();
// Cierre Fichero.
ejemploEscritura.Close();
// Apertura Fichero.
FileStream ejemploLectura = new FileStream(“datos.dat”, FileMode.Open, FileAccess.Read);
// Apertura Flujo Lectura.
BinaryReader flujoLectura = new BinaryReader (ejemploLectura);
string linea = flujoLectura.ReadString();
Console.WriteLine(linea); // Escritura en pantalla de la línea leída en el fichero.
flujoLectura.Close(); // Cierre Flujo Lectura.
ejemploLectura.Close(); // Cierre Fichero.