Documentos de Académico
Documentos de Profesional
Documentos de Cultura
1. INTRODUCCIÓN A LA PROGRAMACIÓN .
Programa, conjunto de instrucciones dadas al ordenador en un lenguaje que solo es entendible por él.
Algoritmo, secuencia finita de operaciones que resuelven un problema expuesto. Es una forma de resolver un problema.
El PROCESO DE PROGRAMACIÓN COMUNICA a un USUARIO CON UNA MÁQUINA, y aparecen varios tipos de lenguajes:
- Alto nivel, están más cerca del lenguaje que habla el usuario.
- Bajo nivel, están más cerca de las estructuras de lenguaje de la máquina.
- Medio nivel, toman características de los dos anteriores.
* Nosotros usaremos lenguaje de Alto nivel, necesitamos un proceso de traducción para convertir el programa
escrito en lenguaje máquina.
CARACTERÍSTICAS DEL LENGUAJE DE ALTO NIVEL:
Independiente de la máquina y portable.
Muy utilizado en el mundo laboral.
Modificaciones y actualizaciones fáciles de realizar.
Para la traducción de código necesitamos un compilador y un enlazador con librerías del lenguaje elegido.
PROGRAMACIÓN ESTRUCTURADA
En una programación estructurada, las instrucciones deben ejecutarse una detrás de otra, dependiendo de una serie de condiciones que pueden cumplir
o no. En C# podemos tener una aplicación formada por uno o varios ficheros con su código fuente correspondiente, pero solo uno de ellos va a ser el
principal cuya extensión es .cs
CLASE → estructura de datos que está compuesta por atributos o variables y métodos o funciones.
* La clase Program es la estructura que Visual Studio nos crea por defecto y el método Main es el método principal. En C# el método Main se puede
declarar con o sin un parámetro string, que contiene los argumentos de línea de comandos.
* Para comentar: una línea → ponemos // al comienzo de la línea | varias líneas → ponemos /* al inicio y */ al final.
TIPOS DE DATOS:
- Simples
Tipos simples predefinidos o primitivos → son indivisibles, tienen existencia propia y permiten operadores relacionales.
NATURAL: NÚMEROS NATURALES (N) sin signo → byte, uint, ushot, ulong.
ENTERO: NÚMEROS ENTEROS (Z) con signo. → sbyte, int, long, short.
REAL, NÚMEROS REALES (R) → decimal, float, double.
LÓGICO, BOOLEANOS (B) → bool (TRUE/FALSE)
CARÁCTER,CARACTERES (C) → char (UTF-16)
Tipos simples definidos por el usuario
TIPOS ENUMERADOS(enum) → Tipo de valor definido por el usuario y
un conjunto de constantes. ofrecen la posibilidad de definir nuevos tipos
simples. Un tipo enumerado se declara utilizando la palabra clave enum.
Las enumeraciones de C # son tipos de datos de valor, es decir, contiene
sus propios valores y no puede heredar o no puede heredar. Ej →
Declarando enum:
La sintaxis general es: enum <enum_name> {enumeration list};
* enum_name especifica el nombre del tipo de enumeración.
* enumeration list es una lista de identificadores separados por comas.
- CONVERSIÓN EXPLÍCITA → se realizan explícitamente por los usuarios que utilizan las funciones predefinidas. Se debe colocar entre paréntesis
el tipo de dato al que queremos convertirlo, y así indicamos al compilador que queremos convertir un tipo de dato a otro diferente. Las conversiones
explícitas requieren un operador de conversión. Se utilizan cuando es posible la perdida de información.
TRUNCANDO DECIMALES Ej: double a = 10,5; | int b; | b=(int)a;
SIN TRUNCAR DECIMALES Ej: int a = 11; | double suma= (double) a/10
PARSE permite convertir caracteres numéricos de tipo string a datos numéricos de tipo int, double,... Ej: int b; | b= int.Parse
CONVERT también puede realizar la conversión de un tipo de dato a otro. Ej: int b; | b=convert.int32
* DIFERENCIA PARSE Y CONVERT - Al recibir un valor null o entrada nula Convert no genera errores de conversión, devuelve un 0 y Parse sí genera un error.
- Si la entrada es una cadena vacía en ambos se genera un error de conversión.
La única diferencia de significado entre las conversiones explícitas e implícitas, tiene que ver con el hecho de si existe riesgo o no de perder en información.
3. PROGRAMACIÓN ESTRUCTURADA .
Es la manera que tenemos de escribir o diseñar un programa de una forma clara y sencilla. Edsger Dykstra comprobó que todo
programa se puede escribir utilizando únicamente tres tipos de instrucciones de control (años setenta).
SECUENCIA DE INSTRUCCIONES | SELECCIÓN DE INSTRUCCIONES O INSTRUCCIÓN CONDICIONAL | ITERACIÓN O BUCLE DE INSTRUCCIONES
FUNDAMENTOS DE PROGRAMACIÓN
Programar → decirle a una máquina qué debe realizar en el menor tiempo posible. El programa se
encarga de transformar la entrada en salida. Es conveniente: especificar la estructura y el
comportamiento de un determinado programa, probar que realiza la tarea que le ha sido asignada de
forma correcta y que ofrece un buen rendimiento.
Algoritmo → la secuencia de los pasos y las distintas operaciones que debe realizar el programa para conseguir resolver un problema.
Algoritmia → conjunto ordenado y finito de operaciones que permite encontrar la solución a un problema cualquiera.
La programación → es una etapa en todo el proceso de desarrollo que existe a la hora de resolver un problema.
CONDICIONAL IF-ELSE
Una instrucción if puede ser seguida por una instrucción else opcional, que se ejecuta
cuando la expresión booleana es falsa. Sintaxis:
if(expresión_booleana){
bloque de código
} else{
bloque de código
}
Si la expresión booleana se evalúa como verdadera, el bloque if ejecuta el código, de lo
contrario el bloque else ejecuta el código.
CONDICIONAL IF ANIDADO
Siempre se puede anidar declaraciones if-else, lo que significa que se puede usar una declaración if o else if dentro de otra declaración if o
else if.
- SENTENCIA SWITCH
Es una instrucción de selección múltiple que elige una sola acción de una lista de opciones en función de una coincidencia de distintos
patrones con la expresión de coincidencia. Sintaxis:
switch (expresión de control){
case expresión constante:
código a realizar
break;
case expresión constante:
código a realizar
break;
. . .
default:
código a realizar
break;
- Solo se usa switch para evaluar: int, char, string, float y double (estos han de usar la
condición if)
- Los case solo pueden contener expresiones contantes (que han de ser únicas) y todo
case debe llevar su break;
- DO…WHILE (Hacer…Mientras), mientras que se cumpla una condición, el código incluido dentro del
bucle se repite. La condición se evalúa al final, por lo que, como mínimo se va a ejecutar una vez. Sintaxis:
do {
código
} while (condición){
código
}
- FOR (para), estructura de control de repetición que permite escribir un bucle que necesita ejecutarse un número específico de veces.
Sintaxis: for ( int i=0; i<=8 ; i++ ){
código de repetición
}
En el ej. mientras i (que es igual a 0) sea menor o igual a 8 se repetirá la ejecución del código, y por cada ejecución i aumentará su valor en 1.
- FOREACH (por cada uno..), utilizamos un bucle for para acceder a cada elemento de
la matriz. También se puede usar una instrucción foreach para recorrer en iteración una matriz.
Se utiliza para arrays implícitos, arrays de objetos y arrays de tipos o anónimos. Sintaxis:
foreach (int j in nombre_array){
código de repetición
}
En el ej. j es el iterador o variable para recorrer el bucle foreach, in palabra clave del bucle foreach y nombre_array es el nombre del array.
ESTRUCTURAS DE SALTO
Son todas aquellas que detienen (de diferentes formas en bucles, ciclos y condicional) la ejecución de alguna de las
sentencias del programa.
BREAK:
o Cuando el break se encuentra dentro de un bucle, el bucle finaliza inmediatamente y el control
del programa se reanuda en la siguiente instrucción que sigue al bucle.
o Se usa para terminar un case en la instrucción switch.
o En bucles anidados, la instrucción break detendrá la ejecución del bucle más interno y
comenzará a ejecutar la siguiente línea de código después del bloque.
CONTINUE:
En lugar de forzar la terminación, continue obliga a que tenga lugar la siguiente iteración del bucle,
omitiendo cualquier código intermedio.
RETURN:
Con return termina la ejecución del método en el que aparece y devuelve el
control al método de llamada.
TRATAMIENTO DE CADENAS
Una cadena es un objeto de tipo string y para la representación de cadenas de caracteres se utiliza el tipo de datos string.
El operador new → la palabra new crea un objeto tipo string al que pasamos el parámetro “letras” como una tabla de caracteres.
PRINCIPALES MÉTODOS DE STRING:
Length => Obtiene el número de carácter del string → devuelve el tamaño del string contando los espacios en blanco.
Ej: string variable=”Hola”; | Console.Writeline(variable.Length); | Salida=4
ToCharArray() => Convierte un string en array de caracteres.
SubString() => Recupera una subcadena de la instancia, es decir, extrae parte de una cadena. Este método puede ser sobrecargado
indicando su inicio o su inicio y su fin; .SubString (posInicio) o .SubString(posInicio, tamañoSubcadena)
Ej: string variable=”Hola, como estáis”; | Console.WriteLine(variable.SubString(0,4)); | Salida= Hola
CopyTo() => Copia un número de caracteres especificados a una determinada posición del string.
CompareTo() => Compara la cadena con otra pasada por parámetro, Devuelve un entero.
Valor Condición
Menor que cero Si el objeto que se esta comparando es menor devolverá -1
Cero Si los dos objetos son iguales devuelve 0.
Mayor que cero Si el objeto que se esta comparando es mayor devolverá 1.
Contains() => Comprueba si la cadena que se le pasa por parámetro forma parte del string . Devuelve un booleano TRUE o FALSE.
Ej: string variable=“Hola que tal estáis”; | Console.WriteLine(variable.Contains(“tal”) | Salida= TRUE
IndexOf() => Si aparece un carácter especificado en el string, devuelve el índice de la posición de la primera vez que aparece o -1 si
no está en la cadena. Ej: string names=”Robert, Marks, Mary”; | Console.Write(names.IndexOf(M)); | Salida=8
Insert() => Inserta una cadena de caracteres en una posición concreta del string.
Ej: string a= “David”; | Console.WriteLine(a.Insert(5,”s”)); | Salida=Davids
Trim() => Quita todos los espacios en blanco del principio y el final del string.
Ej: string variable=”Hola David”; | Console.WriteLine (variable.Trim()); | Salida=HolaDavid
Replace()=> Sustituye un string o carácter por otro. Ej: string a=“Paco”; | Console.WriteLine(a.Replace(“P”,”T”); | Salida= Taco
Remove() => Elimina un número de caracteres especificado. Ej: string a= “Hola!!” | Console.Write(a.Remove(5)); | Salida = Hola!
Split() => Separa en varias partes una cadena de caracteres.
Este método devuelve un array de string.
ToLower() => Devuelve la copia del string que hace la llamada en minúsculas.
ToUpper() => Devuelve la copia del string que hace la llamada en mayúsculas.
Ej: string a = “david”; | Console.WriteLine(a.ToUpper()); | Salida = DAVID
string b = “DAVID”; | Console.WriteLine(b.ToLower()); | Salida = David
DEPURACIÓN DE ERRORES
Llegados a la etapa de depuración de nuestro programa, nuestro objetivo será descubrir todos los errores que existan e intentar
solucionarlos de la mejor forma posible. Podemos encontrar tres tipos de errores diferentes:
• De compilación o sintaxis → errores en el código.
• De tiempo de ejecución: → los que producen un fallo a la hora de ejecutar el programa. Se trata de fragmentos de código que
parecen estar correctos, que no tienen ningún error de sintaxis, pero que no se ejecutan.
• Lógicos → aquellos que aparecen cuando la aplicación está en uso. Se dan resultados erróneos, diferentes a los esperados, a menudo en
respuesta a las acciones del usuario. Son los más difíciles de corregir, ya que no siempre está claro dónde se originan.
TECLAS PARA DEPURAR ERRORES EN Visual Studio:
- F5 → inicia la depuración recorriendo el código completo si no encuentra ningún error.
- F9 → pone un punto de interrupción y ejecuta hasta ahí.
- F10 → paso a paso por procedimientos
- F11 → paso a paso por instrucciones
- Podemos poner un punto de interrupción en una determinada línea de código y pulsar F5→ se ejecutará el código en el
depurador de Visual Studio y se detendrá en el punto de interrupción.
DOCUMENTACIÓN DE PROGRAMAS
- Una vez que finaliza nuestro proceso de compilación y ejecución, debemos elaborar una memoria para que quede registrado todo el desarrollo que
hemos llevado a cabo, los fallos que ha presentado y cómo hemos conseguido solventarlos.
- La etiqueta <summary> se usa para describir un tipo y agregar información adicional .
Programación modular → consiste en dividir el problema original en diversos subproblemas, que se pueden resolver por separado,
para después, recomponer los resultados y obtener la solución al problema.
Subproblema o módulo,→ una parte del problema que se puede resolver de manera independiente.
Ventajas: Inconvenientes:
- Facilita el mantenimiento, la modificación y la documentación. - Separación de módulos → ¿cuánto hay que dividir el problema?
- Facilita la escritura y el testing. - Aumenta el uso de memoria y el tiempo de ejecución.
- Reutilización de módulos. - No se dispone de algoritmos formales de modularidad
- Independencia de fallos. (a veces los programadores no tienen claras las ideas de los módulos →experiencia)
Procedimientos y funciones → son unidades de programas diseñados para ejecutar una tarea específica.
• Los procedimientos (subrutinas = métodos no tipados) no retornan valor,sólo realizan tareas específicas. Usan la palabra reservada void.
- Suelen utilizarse para reducir la duplicación de códigos en un programa. Pueden recibir parámetros.
- Su visibilidad viene determinada por la declaración private, public o internal, (por defecto un procedimiento en C# es public???)
• Las funciones (métodos tipados) devuelven un sólo valor al programa que invoca a la función. Usa la palabra reservada return.
* La FUNCIÓN o MÉTODO MAIN→ Un caso especial es la función Main (que es función pero usa la palabra void y no return). Todos los programas desarrollados en C# tienen una función principal
denominada main() es el punto de entrada, donde se crean objetos y se invocan a otros métodos. Ej: class NombreClase { static void Main(string[] args){...} }
- Se referencia o invoca utilizando su nombre en una expresión.
- Función→ conjunto de instrucciones (delimitadas por llaves) que tienen un nombre y son de un tipo específico.
- Puede recibir o no parámetros (si no necesita recibir parámetros se deja sin poner nada entre los paréntesis)
- Partes de la función:
● Modificadores de acceso: conjunto de palabras reservadas que modifican o aplican propiedades a la función.
o Public: el acceso no está restringido. ¡¡¡ Si no se indica, por defecto una función en C# es internal !!!
o Private: el acceso está limitado a la misma clase.
o Protected: el acceso está limitado a la clase contenedora o a los tipos derivados de la clase contenedora.
o Internal: el acceso no está restringido (dentro del mismo ensamblado o entorno actual).
● Tipo: las funciones también poseen un tipo → el tipo del dato que devuelven.
● Nombre de la función: el identificador de la función, se usa para referenciarla.
● Parámetros de entrada: las variables que recibe la función en el momento de su llamada.
o Parámetro real o actual → aquel que pasamos a la función.
o Parámetro formal → el que usamos dentro de la función (las variables que usamos dentro de la función).
● Return: es obligatorio que devuelva un parámetro del tipo adecuado usando la palabra return.
PASO DE PARÁMETROS .
Mediante el uso de parámetros, se permite la comunicación de las diferentes funciones con el código.
Paso de parámetros por valor o copia
Al ejecutar la función se crea una copia del parámetro pasado. Las
modificaciones se realizan sobre la copia y el original no se modifica, ni se altera su
valor en la función. (En el ej. la salida de numero sigue siendo 1)
(*Si queremos ver lo de dentro tenemos que hacer un Write desde dentro de la función)
Cuando hablamos del ámbito nos referimos a la visibilidad que tendrán las variables con respecto al programa que estamos creando.
- Variables globales: las creadas fuera del Main y de cualquier método. Podemos acceder a ellas desde cualquier parte del programa.
- Variables locales: las declaradas dentro de un método o función y que sólo son visibles en ese fragmento de código.
* En términos generales, NO USAR VARIABLES GLOBALES , USAR VARIABLES LOCALES para que cada parte del programa trabaje con sus propios datos, evitando que un error en un trozo de
programa pueda afectar al resto. PASAR LOS DATOS A TRAVÉS DE PARÁMETROS.
PROBAR: Una vez terminado el programa, debemos probarlo para comprobar que no tiene fallos y que su funcionamiento es el correcto.
COMENTAR: Es conveniente comentar lo importante que realiza el programa.
DEPURAR: (ver apartado Depuración de errores)
Cuando ejecutamos un programa, podemos dividir el proceso en:
• Compilación: Al escribir código, el entorno de desarrollo va haciendo comprobaciones y expone los errores de compilación subrayados.
Una vez corregidos esos errores, el programa se va a compilar y va a pasar a ejecutarse.
• Vinculación: Todos los programas usan bibliotecas y algunos usan clases diseñadas por el programador. Las clases se vinculan cuando el programa comienza a ejecutarse.
• Ejecución: Llegar a la fase de ejecución significa que nuestro programa ya no tiene errores, pero puede que el resultado no sea el esperado.
Los errores lógicos son los más complicados de detectar. Debemos depurar comprobando, paso a paso, cómo va funcionando hasta dar con el error.
LIBRERÍAS .
Librerías: conjunto de métodos relacionados con el mismo objetivo para poder ser reutilizados. Son archivos que nos permiten realizar tareas sin
necesidad de saber cómo están desarrolladas, sólo entender cómo utilizarlas. Además, nos permiten hacer programas más modulares y reutilizables, con
funcionalidades bastante complejas. Una biblioteca de clases define los tipos y los métodos que se llaman desde una aplicación.
El lenguaje C# permite la interoperación con otros lenguajes, siempre que estos tengan:
• Acceso a las diferentes librerías a través de COM+ y servicios .NET.
• Soporte XML (a nivel de documentación).
• Simplificación en administración y componentes gracias a un mecanismo muy cuidado de versiones.
Podemos CREAR NUESTRAS PROPIAS LIBRERÍAS en C# con VS 2019:
1. Creamos un proyecto nuevo como aplicación de consola. * DLL (Dynamic Link Library): librerías de enlace dinámico.
2. Agregamos a nuestra solución una biblioteca de clases (ir a la ventana del explorador de soluciones, botón derecho y agregar).
3. Creamos nuestra dll, realizando un módulo (ej: ‘Multiplicar’). Allí crearemos una función que realizará una tarea (ej: la multiplicación de dos números).
4. A mi proyecto, agregaremos como referencia (botón derecho -> referencia) mi dll con el nombre que habíamos puesto con anterioridad (‘Operaciones’).
5. Ahora ya podemos llamar desde nuestro programa a nuestra referencia.
USO DE LIBRERÍAS: ej: podemos usar la librería Random para generar números aleatorios y las librerías Math para operaciones matemáticas.
Random → generar números aleatorios con la clase Random: Math → operaciones matemáticas:
RECURSIVIDAD .
Recursividad: la llamada de una función a sí misma hasta que cumpla una determinada condición de salida. Reemplaza estructuras repetitivas.
Estructura:
• caso base = condición de salida → que permite la finalización del programa.
Si no hay el método recursivo terminará llamándose a sí mismo interminablemente
y provocará un desbordamiento en la memoria (“Stack Overflow”)
• Casos recursivos → que son los que se encargan de que la función vuelva a ejecutarse, pero acercándose cada vez más al caso base.
Tipos de recursividad:
• Directa: cuando la función hace la llamada a sí misma desde un punto específico de su código.
• Indirecta: cuando la función hace la llamada a otra función y es esta la que llama a la primera.
Para que los datos persistan después de la ejecución de un programa podemos almacenarlos en un fichero. Cada vez que se ejecute la aplicación que
trabaja con esos datos, podrá leer del fichero los que necesite y manipularlos.
* La BCL (Base Class Library) reserva un espacio de nombres denominados System.IO, destinado a trabajar con ficheros.
FICHEROS .
FICHERO →parte de un dispositivo no volátil (los que no pierden la info al apagar el pc) a la que se le asigna un nombre y que puede
contener una cantidad de datos limitada (o por la cantidad de espacio del dispositivo o por las características del sistema operativo).
- Se almacenan en directorios o carpetas y cada directorio puede contener otros directorios diferentes (estructura jerárquica). Debe
existir un directorio raíz que contenga a todos los demás.
- Son una secuencia de bits, bytes, líneas o registros que se almacenan en un dispositivo de almacenamiento secundario,
por lo que la información va a permanecer a pesar de que se cierre la aplicación que los utilice.
- Son conjuntos de bytes con una misma estructura.
- Pueden almacenar gran cantidad de información.
- Independencia de la información: la información que contiene existe aunque el programa no se esté ejecutando.
- Al trabajar con ficheros hay que tener en cuenta:
•Para manipular un fichero realizamos tres operaciones: Abrir el fichero | Escribir o leer registros del fichero | Cerrar el fichero.
•La información es binaria.
•Al agrupar los bits, se forman bytes o palabras. Y los tipos de datos van a estar formados por un conjunto de bytes o palabras.
•Al agrupar los campos, se crean los registros de información.
•Una función de los directorios es agrupar distintos ficheros siguiendo las condiciones determinadas por el SO o el programador.
- RUTAS DE FICHEROS Y DIRECTORIOS: * Ruta →camino que nos lleva hasta localizar o identificar la ubicación del fichero:
• Ruta absoluta o completa: se le indica el camino del directorio desde el comienzo (en Windows →empieza por la unidad, ej: c:\... | en Linux →por / )
• Ruta relativa: se le indica el camino del directorio desde la posición actual. La ruta no empezaría con la letra de la unidad.
- TIPOS DE FICHEROS:
• Según su acceso y la forma de organizar la información:
- Secuencial: los registros se almacenan consecutivamente y cada vez que queremos acceder a ellos tenemos que
recorrerlos de uno en uno desde el principio. Solo se puede realizar una operación de lectura o escritura a la vez.
- Aleatorio o directo: podemos acceder a un registro concreto indicando su posición. Los registros están organizados pero
pueden ser leídos o escritos en cualquier orden, basta con colocar el puntero justo antes de éste.
- Secuencial indexado: Permiten el acceso secuencial y aleatorio a un fichero porque los ficheros indexados poseen un
campo clave para ser identificados: 1º) busca de forma secuencial el campo clave
2º) accede al fichero directamente con la posición indicada por el campo clave.
• Según su estructura:
- Ficheros de texto: textos planos. (.txt)
- Ficheros binarios: los datos se encriptan y almacenan en binario, su almacenamiento es más eficiente (.bin, .jpg, .mp3,...)
DISEÑO Y MODULACIÓN DE LAS OPERACIONES SOBRE FICHEROS .
* Algunas de las clases que nos proporciona el espacio de nombres System.IO y que se utilizan para realizar operaciones con archivos (ej: crear, eliminar,
leer, escribir, cerrar …) son:
Se pueden distinguir:
• Flujos base: los que operan más a nivel máquina (ej: porción de memoria, espacio de disco o conexión de red)
• Flujos intermedios: los que trabajan por encima de los anteriores. Se pueden combinar
con el flujo base y verse beneficiados por las funcionalidades que ofrezca el flujo base.
* El flujo base envía bytes de un lugar a otro mientras que el flujo intermedio procesa la info.
➢ LECTURA/ESCRITURA:
Tenemos que leer o escribir la información del fichero prestando atención: > en ficheros secuenciales → al fin de fichero
> en ficheros aleatorios → a la posición del puntero
➢ CIERRE:
Cuando cerramos el fichero, este queda liberado y termina el proceso de almacenamiento de información.
LA CLASE FILESTREAM
Lectura de un fichero de texto
CONTROL DE EXCEPCIONES .
Para saber si el fichero está donde esperamos podemos usar el método Exists. Si se prevé otra excepción podemos usar Try/catch para localizar y solventar el problema :