1 INTRODUCCIÓN A LA PROGRAMACIÓN
Programación - A
Un programa es un conjunto de instrucciones dadas al or-
denador en un lenguaje que solo es entendible por él para
comunicarle lo que queremos que haga. Un algoritmo es
una secuencia finita de operaciones que resuelven un de-
terminado problema.
Un algoritmo es más parecido a una idea, una forma de
resolver un problema, mientras que un programa está más
relacionado con la realización de una o más tareas por
parte de un ordenador.
Un programa debe cumplir una serie de características:
• Deber ser finito: formado por un conjunto limitado de
sentencias.
• Debe ser legible: es importante crear códigos limpios y
fáciles de leer con tabulaciones y espacios que diferen-
cien las partes del programa.
• Debe ser modificable: debe ser sencillo el proceso de ac-
tualización o modificación ante nuevas necesidades.
• Debe ser eficiente: debemos crear programas que ocu-
pen poco espacio en memoria y se ejecuten rápidamente.
• Debe ser modulable: debemos realizar algoritmos que se
dividan a su vez en subalgoritmos de forma que se dis-
ponga de un grupo principal desde el que llamaremos al
resto. Así, incitamos a la reutilización de código.
• Debe ser estructurado: engloba a las características an-
teriores, ya que un programa estructurado será fácil de
leer y modificar, y estará compuesto de subprogramas
que permitirán la reutilización de código.
7
Tema 1: Introducción a la programación
Representaciones gráficas
Para representar un algoritmo, podemos utilizar dos
herramientas gráficas: los diagramas de flujo y el pseu-
docódigo.
Un diagrama de flujo es una representación gráfica de un
proceso. Cada paso del proceso se representa con un sím-
bolo diferente que contiene una breve descripción.
Debemos usar una serie de símbolos estándar:
Indican inicio o fin de programa.
Representan una instrucción, un paso a dar o un proceso. Por
ejemplo: cont= cont+1.
Operaciones de entrada/salida de datos. Por ejemplo: visuali-
za en pantalla suma.
Usaremos este símbolo si nos encontramos en un punto en el
que se realizará una u otra acción en función de una decisión.
Por ejemplo, si miVariable= 0, hacemos la instrucción 1. Si no,
hacemos la instrucción 2.
Conector. Permite unir diferentes zonas del diagrama de
forma que se redefine el flujo de ejecución hacia otra parte
del diagrama.
Representa un método o subprograma.
Flechas para indicar la dirección de flujo.
8
Programación - A
Características de los diagramas de flujo:
• Deben escribirse de arriba abajo o de izquierda a derecha.
• Debemos evitar el cruce de líneas, para eso se define la
forma de conector. El uso de conectores debe producirse
cuando no exista otra opción.
• Todas las líneas de flujo deben estar conectadas a algún
objeto.
• El texto que se escribe en las formas debe ser escueto y
legible.
• Todos los símbolos de decisión deben tener más de una
línea de salida, es decir, deben indicar qué camino seguir
en función de la decisión tomada.
EJEMPLO
Se representa el siguiente diagrama de flujo, que
muestra todos los números pares del 0 al 98:
INICIO
i=0
F
i <100
i = i+2
FIN
9
Tema 1: Introducción a la programación
La otra herramienta para representar los algoritmos es el
pseudocódigo.
Es la manera de representar las distintas sentencias que
va a realizar nuestro algoritmo con un lenguaje cercano al
natural. Por tanto, es un lenguaje que no se puede ejecutar
en una máquina.
Características del pseudocódigo
• Comienza con la palabra algoritmo seguido de su nombre.
• A continuación, tenemos la secuencia de instrucciones
de este algoritmo.
• Finaliza con la estructura FinAlgoritmo.
• No es necesaria la indentación (sangrado), aunque es re-
comendable.
• No se diferencia entre mayúsculas ni minúsculas.
Algoritmo triángulo
Definir área, altura, base de tipo números reales;
Escribir “Introduce la altura del triángulo:”;
Leer altura;
Escribir “Introduce la base del triángulo:”;
Leer base;
Área = (altura*base)/2;
Escribir “El área del triángulo es:”, área;
FinAlgoritmo
Comunicación de un sistema informático
En el proceso de programación se comunica a un usuario
con una máquina. Para que se pueda realizar dicha comu-
nicación, debemos tener:
• Los dos agentes principales, usuario y máquina.
• El canal. Para continuar con el ejemplo con el que esta-
mos explicando el proceso de programación, podemos
decir que el canal por el que se comunica nuestro usuario
será el teclado.
• El lenguaje. Tanto el receptor como el emisor hablan un
lenguaje completamente diferente. Para que la comunica-
ción sea fluida, debemos acercar los lenguajes, tanto de la
máquina como del usuario, y así lograr el entendimiento.
10
Programación - A
Ahora bien, para solventar el problema de la comunicación,
tenemos lenguajes de programación de tres tipos: alto
nivel, nivel medio y bajo nivel. Los lenguajes de alto nivel
están más cerca del lenguaje que habla el usuario, mien-
tras que los lenguajes de bajo nivel se acercan más a las
estructuras del lenguaje de la máquina. Por su parte, los
lenguajes de nivel medio toman características de ambos,
como por ejemplo el lenguaje C.
11
Tema 1: Introducción a la programación
Para facilitar el trabajo, implementaremos nuestro código
con lenguajes de alto nivel, de modo que necesitaremos
un proceso de traducción para convertir el programa escri-
to en lenguaje máquina.
Características del lenguaje de alto nivel
• Es totalmente independiente de la máquina y, por tanto,
muy portable.
• Muy utilizado en el mercado laboral informático.
• Tanto las modificaciones como las actualizaciones son
muy fáciles de realizar.
• Para la tarea de traducción de código necesitamos un
compilador y un enlazador con librerías del propio len-
guaje de programación elegido.
Algunos ejemplos de lenguajes de alto nivel son java, php,
c#, [Link], Python…
Características del lenguaje de bajo nivel
• Está relacionado con las características del hardware.
• Es fácilmente traducible al lenguaje máquina.
• Es totalmente dependiente de la máquina.
Un ejemplo de lenguaje de bajo nivel es Ensamblador. Este
lenguaje trabaja con registros a más bajo nivel.
12
Programación - A
A lo largo de esta unidad formativa hablaremos de la es-
tructura de un programa informático y de sus elementos
principales, como son las variables, las constantes y los
distintos operadores que podemos usar a la hora de imple-
mentar un código fuente.
Lenguajes compilados e interpretados
Aquellos lenguajes de alto nivel que utilizan un compilador
para poder traducirlo al lenguaje máquina se denominan
lenguajes compilados.
En nuestro caso, un programa escrito en C# necesita un
compilador de C#. En este supuesto, el lenguaje máquina
no corresponde al del ordenador, sino al de una máquina
ficticia llamada máquina virtual. En C#, la máquina virtual
se denomina CLR (Common Language Runtime).
Esta máquina no existe físicamente, sino que es simulada
por un ordenador. Podemos instalarla en nuestro ordena-
dor copiando ese programa en nuestro disco duro.
Gracias a esa máquina, podemos ejecutar nuestro progra-
ma en cualquier ordenador del mundo.
Un lenguaje interpretado no genera un programa escrito
en una máquina virtual. Efectúa directamente la traduc-
ción y ejecución simultáneamente para cada una de las
sentencias.
13
Tema 1: Introducción a la programación
Un intérprete verifica cada línea del programa cuando se
escribe. La ejecución es más lenta debido a esta traducción
simultánea.
En esta asignatura vamos a centrarnos en el lenguaje de
programación C#. Otro lenguaje muy utilizado actualmen-
te es el lenguaje Java. En la siguiente tabla mostramos las
características de ambos:
C# Java
Es un lenguaje orientado a objetos. Es un lenguaje orientado a objetos.
Contiene dos categorías generales de Los argumentos son siempre pasados
tipos de datos integrados: tipos de por valor independientemente del tipo
valor y tipos de referencia. de variable.
La migración de C# a Java es sencilla La migración de Java a C# es sencilla
porque mantiene una sintaxis muy porque mantiene una sintaxis muy
similar. similar.
C# está incluido en la plataforma .NET Gracias al recolector de basura, se
que tiene a su disposición el recolector elimina la necesidad de la liberación
de basura del CLR (Common Language explícita de memoria.
Runtime o entorno en tiempo de
ejecución).
En C# todos los tipos derivan de una Java soporta sincronización de múlti-
superclase común llamada System. ples hilos de ejecución (multithreading)
Object. A diferencia de Java, esta a nivel de lenguaje.
característica también se aplica para los
tipos básicos.
C# es un lenguaje compilado. Java es compilado, en la medida en
que su código fuente se transforma en
un código máquina muy parecido al
lenguaje ensamblador.
Se genera un código intermedio Java es interpretado, ya que ese
llamado MSIL (Microsoft Intermediate código máquina se puede ejecutar
Language) y luego ese código se vuelve directamente sobre cualquier máquina
a compilar para obtener el formato la cual tenga el intérprete y el sistema
nativo en la máquina en la que se va a de ejecución en tiempo real.
ejecutar.
14
Programación - A
ponte a prueba
¿Cómo debe ser un programa informático?
a) Legible.
b) Modificable.
c) Eficiente.
d) Todas las opciones anteriores son correctas.
¿Cuál de las siguientes opciones sobre el
siguiente diagrama de flujo es correcta?
INICIO
“Escribe el valor de N”
i=1
Result = 0
no
i<=N
si
Result = 2*i-1
FIN
i = i+1
“Escribe el valor de result”
a) Muestra los n primeros números impares.
b) Realiza un producto de dos números.
c) Muestra los n primeros múltiplos.
d) Realiza la suma de dos números.
C# tiene dos categorías tipos de datos inte-
grados: por valor y por referencia.
a) Verdadero.
b) Falso.
15
2 ESTRUCTURA DE UN PROGRAMA INFORMÁTICO
Programación - A
El lenguaje de programación C# es un lenguaje de alto nivel
que pertenece al conjunto de lenguajes de .NET. C# es una
evolución de C++ y mucha de la sintaxis está heredada de
este lenguaje.
Con C#, podemos crear aplicaciones con una interfaz de
texto, que denominamos aplicaciones de consola.
Una de las ventajas de aprender este lenguaje es que es
independiente de la plataforma donde lo ejecutemos (sea
Intel o AMD).
Para desarrollar nuestros programas ne C#, utilizaremos
un IDE. Un entorno de desarrollo integrado (IDE) es un
software diseñado para el desarrollo de aplicaciones con
un conjunto de herramientas integradas en una interfaz
gráfica de usuario (GUI).
Sus características son:
• Editor de código fuente: ayuda al programador a es-
cribir el código, resaltando la sintaxis de forma visual y
rellenando de forma automática las distintas opciones
que nos proporciona el lenguaje.
• Depurador: ayuda al programador a localizar sus errores
de código.
• Compilación del código fuente: un código binario en-
tendible por la máquina.
Para plataformas Windows y Mac OSX, podemos desa-
rrollar con IDE Visual Studio. El proyecto que implementa
el desarrollo de .NET en GNU/Linux es el proyecto Mono,
concretamente el entorno de desarrollo MonoDevelop.
Con estos programas, vamos a ir generando los diferentes
proyectos. Cada vez que creemos un proyecto nuevo, el
programa va a generar solo un fichero de código fuente,
que es el que va a dar lugar al ejecutable que necesita la
aplicación.
Este fichero que se genera debe tener la extensión cs, ya
que es la extensión utilizada por los ficheros en C#.
17
Tema 2: Estructura de un programa informático
Instalación de Visual Studio
Para instalar nuestro Visual Studio, vamos a la página oficial
de Microsoft, donde, en la parte de downloads, tendremos
varias opciones.
Así, descargamos Visual Studio Community, que es la
versión gratuita:
BUSCA EN LA WEB
[Link]
Una vez descargado, procedemos a la instalación.
Durante la instalación, nos dará a elegir entre una serie de
paquetes instalables.
Nosotros, para realizar nuestras aplicaciones de consola,
añadiremos el siguiente paquete:
18
Programación - A
Instalación de MonoDevelop
Para la instalación de este IDE en plataformas como Ubun-
tu o Debian, podemos seguir las indicaciones de la página
oficial:
BUSCA EN LA WEB
[Link]
2.1. Bloques de un programa
informático
Estructura de un programa
[Link]/MTJoNPqXT1E
Podemos definir un programa como una secuencia de ins-
trucciones separadas por un punto y coma que se van a ir
agrupando en diferentes bloques mediante llaves.
Para crear un proyecto, abrimos nuestro Visual Studio y
seleccionamos la opción de Crear un proyecto.
19
Tema 2: Estructura de un programa informático
Posteriormente, elegiremos la opción de Crear un aplicati-
vo de consola.
Nombramos nuestra aplicación con el nombre que quera-
mos y seleccionamos la ruta donde lo guardaremos.
Cuando hayamos configurado estos parámetros, se nos
abrirá la interfaz de nuestro IDE, que estará formado por
tres partes principales:
20
Programación - A
• La primera parte será nuestro editor de código. El desa-
rrollador implementará todas las instrucciones necesarias
para completar su programa.
• La segunda es el explorador de soluciones. En esta parte
de nuestro IDE, veremos los archivos generados de nues-
tro aplicativo.
• La tercera parte es la salida. Nos proporcionará el resulta-
do de si la compilación ha sido correcta o, por el contrario,
si ha habido un error, así como también el porqué de ese
error.
Cuando creamos el proyecto, se crea la siguiente estructura:
using System;
namespace MiAplicación
{
class Program
{
static void Main(string[] args)
{
}
}
}
La estructura que Visual Studio nos crea por defecto es la
clase program. Una clase es una estructura de datos que
está compuesta por atributos o variables (de las que ha-
blaremos más adelante) y métodos o funciones. El método
principal se denomina Main.
21
Tema 2: Estructura de un programa informático
De hecho, siempre que ejecutemos un programa, el primer
método que se ejecutará será el Main. Este método tiene
una serie de argumentos. Estos argumentos son cade-
nas de caracteres que podemos pasar línea de comandos
(CMD):
Nosotros trabajaremos con la Consola de nuestro entorno
de desarrollo.
Entrada y salida por pantalla
Para establecer la comunicación entre el usuario y el pro-
grama, emplearemos la clase Console.
• Para la salida por pantalla, podemos utilizar los métodos
de esta clase, Write y Writeline:
– El método Write() escribe un valor o valores especifica-
do(s) en el flujo de salida estándar, que generalmente
será nuestra pantalla.
– El método WriteLine() escribe un valor o valores
especificado(s) en el flujo de salida estándar, que gene-
ralmente será nuestra pantalla, y se realiza un salto de
línea en nuestra consola.
22
Programación - A
using System;
namespace MiAplicación
{
class Program
{
static void Main(string[] args)
{
[Link](“Hello World!”);
[Link](“Programming...”);
}
}
}
La salida será:
Para la entrada de datos de usuario, utilizaremos el méto-
do ReadLine(). Este método leerá el dato introducido por
el usuario y devolverá un dato de tipo cadena (string).
using System;
namespace MiAplicación
{
class Program
{
static void Main(string[] args)
{
[Link](“Introduce un
dato”);
string dato = [Link]();
}
}
}
Otra forma para recoger los datos de entrada de usuario es
el método Read(). Este método leerá el dato introducido
por el usuario y devolverá un dato de tipo entero (int).
Asimismo, otro método utilizado por la clase Console es
el método ReadKey(). En este caso, se obtiene el carácter
presionado por el usuario y se muestra esta tecla por la
pantalla.
23
Tema 2: Estructura de un programa informático
Se pueden consultar más métodos de esta clase en el sigui-
ente enlace:
BUSCA EN LA WEB
[Link]
console?view=netframework-4.8
ponte a prueba
¿Qué es un IDE?
a) El lenguaje C# es considerado como un IDE.
b) El lenguaje java es considerado como un IDE.
c) Es un software diseñado para el desarrollo de
aplicaciones.
d) Ninguna de las respuestas es correcta.
Siempre que ejecutemos un programa, el
primer método que se ejecutará será el Main.
a) Verdadero.
b) Falso.
¿Qué realiza el siguiente código?
static void Main(string[] args)
{
[Link](“Hello World!”);
}
a) Muestra por pantalla args.
b) Muestra por pantalla “Hello World!”.
c) Muestra por pantalla Hello World!
d) Realiza una lectura de datos de args.
24
Programación - A
2.2. Variables. Usos y tipos
Una variable es una estructura de datos que ocupan un es-
pacio en memoria y pueden variar a lo largo de un programa.
Cuando declaramos una variable, establecemos el tipo de
dato (entero, cadena, carácter, etc.) y su identificador.
class Program
{
static void Main(string[] args)
{
int numero;
numero = 10;
char letra = ‘a’;
string cadena = “Esta es una cadena”;
}
}
Tipos de datos en C#:
Tipo simple Descripción
Sbyte, short, int, long Enteros con signo
Byte, unshort, uint, Enteros sin signo
ulong
Float, double Punto flotante
Char Uno o varios caracteres
Decimal Decimal de alta precisión
Bool Booleano
• Tipo String: son cadenas de caracteres. Por ejemplo:
string cadena = “Hola mundo”;
• Tipo de dato enumerado: enum días_semana {lunes,
martes, miercoles};
• Tipos matriz:
– Unidimensionales:
int[] array = new int[5];
int[] array2 = new int[] { 1, 3, 5, 7, 9 };
int[] array3 = { 1, 2, 3, 4, 5, 6 };
– Multidimensionales:
int[,] multiDimensionalArray1 = new int[2, 3];
int[,] multiDimensionalArray2 = { { ‘a’, ‘b’, ‘c’ }, { ‘d’, ‘e’, ‘f’ } };
25
Tema 2: Estructura de un programa informático
Para definir una variable, necesitamos conocer primero el
tipo de datos que va a almacenar y, a continuación, el nombre
que le vamos a asignar. Es recomendable que este nombre
tenga relación con el ejercicio que estemos desarrollando.
Para identificar a una variable, y que tenga un identifica-
dor válido por el compilador, debemos seguir una serie de
normas:
• Debe comenzar por un carácter (letra o “_”).
• Debe estar formada por caracteres del alfabeto (no pode-
mos usar “ñ”) o por dígitos (del 0 al 9). Se puede utilizar
el subrayado (“_”).
• No debe comenzar con un dígito.
• Distingue entre mayúsculas y minúsculas.
• No puede llevar espacios en blanco.
• No se pueden utilizar palabras reservadas. Por ejemplo,
string es una palabra reservada como tipo de dato cadena.
A continuación, encontraréis una lista de las palabras claves
(o identificadores) predefinidos por el compilador:
BUSCA EN LA WEB
[Link]
language-reference/keywords/
Para declarar una variable:
<tipo> <nombre_variable>;
Y en C# lo pondríamos de la siguiente forma:
int num;
En este caso, estamos definiendo una variable de tipo en-
tero denominada num.
A las variables también se les puede asignar un valor:
int num=5;
Definimos una variable de tipo entero, denominada num y
le asignamos el valor de 5.
Debemos utilizar un tipo u otro de variable, dependiendo
del tipo de dato que queremos tratar.
26
Programación - A
A grandes rasgos, podemos dividir las variables en dos
grandes bloques, dependiendo del ámbito en el que se
encuentren:
• Variables locales: aquellas declaradas dentro de un mé-
todo o función.
• Variables globales: aquellas declaradas fuera de un mé-
todo o función. Podemos acceder a ellas desde cualquier
punto del programa.
Más adelante definiremos el concepto de ámbito de va-
riables, cuando hablemos del concepto de programación
modular.
No es buena práctica utilizar variables globales.
AVISO
El problema de las variables globales es que crean depen-
dencias ocultas. Cuando se trata de una aplicación grande,
el programador no conoce los objetos que tiene ni sus
relaciones.
27
Tema 2: Estructura de un programa informático
ponte a prueba
¿Cuál de las siguientes opciones es una
característica de una variable?
a) Ocupa espacio en memoria.
b) P
uede variar su contenido a lo largo del
programa.
c) Es de un tipo de dato.
d) Todas las respuestas son correctas.
¿Qué tipo de dato es un char?
a) Carácter.
b) Entero.
c) String.
d) Decimal.
Las variables globales son aquellas que están
declaradas dentro de un método o función.
a) Verdadero.
b) Falso.
2.3. Constantes y literales.
Tipos y utilidades
Constantes
En el apartado anterior hemos hablado de las variables
como espacio de memoria donde se almacenan datos que
pueden variar a lo largo del programa. Ahora trabajaremos
con los espacios de memoria cuyo contenido no se puede
alterar a lo largo del programa: las constantes.
El valor se establece en tiempo de compilación y no se
puede cambiar su contenido.
const <tipo> <nombre_variable>;
Por ejemplo:
const int num;
28
Programación - A
Después, declaramos una constante de tipo entero que
denominamos num.
A continuación, exponemos una constante llamada días
semana, con el valor 7, ya que todas las semanas tienen 7
días:
class Calendar1
{
public const int dias_semanas = 7;
}
Las constantes se definen fuera del cuerpo de cualquier
función, normalmente al principio del programa.
• Literales
Mediante un literal podemos representar de forma explí-
cita todos los valores que pueden tomar los tipos básicos
del lenguaje.
Seguidamente, vamos a explicar los diferentes tipos de
literales que podemos encontrarnos en C#.
• Literales enteros:
– Decimales: sin ningún prefijo. Por ejemplo: int dLiteral
= 10;
– Hexadecimales: con el prefijo de 0x o 0X. Por ejemplo:
int hLiteral= 0x3F;
• Literales reales:
– El literal sin sufijo o con el sufijo d o D es del tipo double.
– Por ejemplo: double num = 3.4d;
– Double num2= 3.4;
– El literal con el sufijo f o F es del tipo float.
– Por ejemplo: float variable = 4.5F;
– El literal con el sufijo m o M es del tipo decimal.
– Por ejemplo: decimal numero = 3.2m;
• Literales de lógicos: representados por los valores lógi-
cos true (verdadero) y false (falso).
• Literales de carácter: cualquier carácter en C# podemos
representarlo con comillas simples. Por ejemplo, ‘a’ co-
rrespondería al carácter a.
29
Tema 2: Estructura de un programa informático
Existen caracteres especiales que pueden representarse de
la siguiente forma:
Carácter Representación
ponte a prueba
Comilla simple \’
¿Con qué palabra reservada se Comilla doble \”
define una constante?
a) Const Carácter nulo \0
b) Enum
Retroceso \b
c) Array
d) N
inguna de las opciones es Salto de página \f
correcta
Nueva línea \n
¿Qué representa el literal \n?
a) U
na nueva línea Retorno de carro \r
b) Un carácter nulo Tabulación horizontal \t
c) Un salto de página
d) Una tabulación vertical Tabulación vertical \v
2.4. Operadores del lenguaje de
programación
Operadores aritméticos
Operadores aritméticos
+ Suma aritmética de dos valores.
++ Incremento en 1 del operando.
- Resta aritmética de dos valores.
-- Decremento en 1 del operando.
* Multiplicación aritmética de dos valores.
/ División aritmética de dos valores.
% Obtiene el resto de la división entera.
El operador de incremento ++ puede ser aplicado como
prefijo o sufijo de una variable.
30
Programación - A
El resultado de num++ es el valor de num antes de la ope-
ración:
int num = 100;
[Link](num); // salida por pantalla: 100
[Link](num++); // salida por pantalla: 100
[Link](num); // salida por pantalla: 101
El resultado de ++num es el valor de num después de la
operación:
double num = 10.4;
[Link](num); // salida por pantalla: 10.4
[Link](++num); // salida por pantalla: 11.4
[Link](num); // salida por pantalla: 11.4
Asimismo, sucede lo mismo con el operador decremento - -.
La prioridad de los operadores (de mayor a menor prio-
ridad) es:
1. Operadores de incremento x++ y decremento x-- sufijos.
2. Operadores de incremento ++x y decremento --x prefijos.
3. Operadores de multiplicación, división y resta *, / y %.
4. Operadores de suma y resta + y -.
Operadores booleanos
Operadores booleanos
& AND lógico. Evalúa ambos operandos.
&& AND lógico. Evalúa el operando derecho solo
si es necesario.
| OR lógico. Evalúa ambos operandos.
|| OR lógico. Evalúa el operando derecho solo si
es necesario.
^ XOR lógico.
! Negación lógica.
El operador AND lógico & calcula el AND lógico de sus
operandos. El resultado de a & b es true si a y b se evalúan
como true. Si no, el resultado es false.
31
Tema 2: Estructura de un programa informático
El operador AND lógico condicional && también evalúa
el operador AND lógico de sus operandos, pero no evalúa
el operando derecho si el izquierdo se evalúa como false.
El operador | calcula el operador OR lógico de sus
operandos. El resultado de a | b es true si a o b se evalúan
como true. Si no, el resultado es false.
El operador OR lógico condicional || también evalúa el
operador OR lógico de sus operandos, pero no evalúa el
operando derecho si el izquierdo se evalúa como true.
El operador ^ es el operador OR exclusivo o XOR. La tabla
de la verdad (tabla que muestra el resultado de una combi-
nación de valores) es la siguiente:
a b a^b a||b a&&b
T T F T T
T F T T F
F T T T F
F F F F F
El operador ! calcula la negación lógica de su operando, es
decir, si el operando es true, devolverá el valor false. Si el
operando es false, devolverá el valor true.
Operadores de comparación e igualdad
Operadores de comparación
> Mayor
< Menor
>= Mayor o igual
<= Menor o igual
== Igual
!= Desigualdad
= Asignación
El operador < devuelve true si el operando izquierdo es
menor que el derecho.
El operador > devuelve true si el operando izquierdo es
mayor que el derecho.
32
Programación - A
El operador <= devuelve true si el operando izquierdo es
menor o igual que el derecho.
El operador >= devuelve true si el operando izquierdo es
mayor o igual que el derecho.
El operador de igualdad == devuelve true si sus operandos
son iguales.
El operador de desigualdad != devuelve true si sus
operandos son distintos.
ponte a prueba
¿Cuál es el resultado del siguiente código?
int x = 1;
num++;
[Link](num);
a) 1.
b) 2.
c) 0.
d) Ninguna de las repuestas es correcta.
¿Cuál de las siguientes opciones sobre el
operador ! es correcta?
a) Calcula la negación lógica de nuestro
operando.
b) Incrementa en 1 nuestro operando.
c) Decrementa en 1 nuestro operando.
d) Compara dos operandos.
33
Tema 2: Estructura de un programa informático
2.5. Conversiones de tipos de
clase
Como hemos visto anteriormente, en C#, cuando declara-
mos una variable, no se puede volver a declarar, ni asignar
un valor de otro tipo.
Por tanto, si tenemos una variable de tipo entero, no pode-
mos asignar un valor de tipo string.
Este fragmento de código daría un error:
int numero=10;
numero = “a”; // No se puede convertir
implícitamente el tipo ‘string’ en ‘int’
Sin embargo, en ocasiones, podemos convertir el valor de
una variable de un tipo de dato a otro tipo. A estas conver-
siones se les denomina conversiones de tipos.
Podemos tener diferentes clases de conversiones:
• Conversiones implícitas: son aquellas que se producen
cuando el valor que se va a almacenar se puede almace-
nar en la variable sin truncarse ni redondearse.
Por ejemplo, una variable de tipo long puede almacenar
datos de hasta 64 bits. Por tanto, puede almacenar cual-
quier dato de tipo int (32 bits).
int a = 300;
long numero=a;
• Conversiones explícitas: cuando no hay posibilidad de
realizar una conversión implícita es cuando debemos
indicar al compilador que se pretende realizar una con-
versión que pueda producir una pérdida de datos. En este
caso, se antepone a la variable el nuevo tipo de datos en-
tre paréntesis.
double num = 100.85;
int b;
b = (int)num;
[Link](b);
// La salida por pantalla será 100
Parse y TryParse
Con los métodos Parse y TryParse, podemos convertir una
cadena en varios tipos numéricos: int, decimal, double…
El método Parse devuelve el número convertido. El método
TryParse devuelve un valor booleano indicando si la
34
Programación - A
conversión se realizó correctamente o no, y devuelve el
número convertido.
int numValido = [Link](“-100”);
[Link](numValido);
// La salida por pantalla será -100
while ([Link](“50”, out int miNumero))
// El argumento miNumero, se pasa por referencia. Lo veremos más
adelante en el apartado 4.5. Llamadas a funciones. Tipos y funcionamento.
[Link](miNumero);
// La salida por pantalla será 50
Convert
Es una clase que convierte un tipo de datos en otro. Algu-
nos métodos son:
Método Descripción
ToBoolean Convierte un valor especificado en un valor booleano.
ToChar Convierte un valor especificado en un carácter.
ToDecimal Convierte un valor especificado en un número decimal.
ToDouble Convierte un valor especificado en un número de punto flotante.
ToInt16 Convierte un valor especificado en un entero de 16 bits.
ToInt32 Convierte un valor especificado en un entero de 32 bits.
ToInt64 Convierte un valor especificado en un entero de 64 bits.
ToString Convierte un valor especificado en su representación de cadena.
double numero = 30.5;
string cadena = [Link](numero);
// Mostraría por pantalla la cadena “30.5”
35
Tema 2: Estructura de un programa informático
EJEMPLO
Ejemplo
Según el siguiente código:
int a=10, b=3, c=1, d, e;
Float x,y;
x=a/b;
c=a<b && c;
d= a + b++;
e= ++a - b;
y= (float)a / b;
// habría un error en la sentencia c=a<b && c; porque
estamos evaluando una condición booleana, mien-
tras que la variable c es una variable de tipo entero.
36
Programación - A
ponte a prueba
Las conversiones implícitas son ¿Qué convierte el método ToString?
aquellas que se producen cuando
a) Un valor especificado en un entero
el valor que se va a almacenar se
de 64 bits.
puede almacenar en la variable sin
pérdida de información. b) U
n valor especificado en un
carácter.
a) Verdadero.
c) Un valor especificado en un valor
b) Falso. booleano.
d) E
l valor especificado en su repre-
sentación de cadena.
2.6. Comentarios al código
Hasta ahora nos hemos introducido en la creación por
parte de un programador de código fuente con una fina-
lidad concreta. No debemos pasar por alto que, además
de realizar programas, lo debemos hacer de la forma más
optimizada y ordenada posible.
En el ámbito de la organización entra en escena el concepto
de los comentarios. Es una herramienta disponible en el
compilador para que el programador pueda hacer anota-
ciones en el código sin que sea procesado por el compilador.
Estas anotaciones deben de esclarecer el propio código y
ayudar a entender las sentencias del programa. Así, futuros
programadores podrán conocer su funcionamiento.
En el lenguaje de programación C# está permitido hacer
dos tipos de comentarios:
• Comentarios de una línea: son frases cortas y, por tan-
to, solo pueden ocupar una línea del código. Debemos de
escribir “//” antes de comenzar con dichas anotaciones.
• Comentarios multiline o multilíneas: son comentarios
de varias líneas, que se utilizan para hacer una explicación
mucho más detallada del código en cuestión. También
podemos hacer uso de este tipo de comentarios cuando
deseamos que una parte del código no sea procesada por
el compilador. En este caso, debemos de englobar el tex-
to entre los caracteres “/*” y “*/”.
37
Tema 2: Estructura de un programa informático
El uso de los comentarios es muy útil y, por tanto, se acon-
seja a los programadores que implementen programas con
tantos comentarios como sea posible para documentar el
código.
/*Programa que muestra por
pantalla la frase
Buenas tardes*/
// Está compuesto por la clase Hello1 y el método Main()
public class Hello1
{
public static void Main()
{
[Link]("Buenas tardes");
}
}
ponte a prueba
Según el siguiente código, ¿qué saldrá por
pantalla?
static void Main(string[] args)
{
/* [Link] (“HOLA MUNDO”);
Int i=10;
[Link] (i);
*/
}
a) HOLA MUNDO
b) HOLA MUNDO10
c) HOLA MUNDO
10
d) Nada, porque el código está comentado
Para hacer comentarios de una sola línea,
debemos utilizar el operado /.
a) Verdadero
b) Falso
38
Programación - A
39
5 GESTIÓN DE FICHEROS
Programación - A
Hasta aquí, hemos visto el uso de variables y las estructu-
ras de datos y hemos trabajado con información que, una
vez que finaliza la ejecución del programa, desaparece de
la memoria, ya que ha estado almacenada en la memoria
principal el tiempo que dura la ejecución del software.
La solución para que los datos persistan después de la eje-
cución es almacenarlos en un fichero. Entonces, cada vez
que ejecutemos una aplicación que trabaja con esos datos
podrá leer del fichero aquellos que sean necesarios.
5.1. Concepto y tipos de ficheros
Un fichero es una parte de un dispositivo no volátil a la que
se le asigna un nombre y que puede contener una cantidad
de datos que va a estar limitada, o por la cantidad de espa-
cio del que disponga el dispositivo, o por las características
del sistema operativo. Entendemos por dispositivos no vo-
látiles aquellos que no pierden la información que poseen
cuando apagamos nuestro ordenador.
Debido a la importancia que tienen los ficheros al actuar
de almacenes no volátiles de la información, la BCL (Base
Class Library) reserva un espacio de nombres denominados
[Link], destinado a trabajar con ellos.
El espacio de nombres [Link] contiene tipos que per-
miten leer y escribir en los archivos. Además, ese espacio
de nombres nos proporciona compatibilidad entre archivos
y directorios.
Algunas de las clases que nos proporciona son:
CLASE DESCRIPCIÓN
BinaryReader Lee tipos de datos primitivos como valores binarios.
BinaryWriter Escribe tipos primitivos en formato binario en una secuencia y admite
la escritura de cadenas.
File Proporciona métodos estáticos para crear, copiar, eliminar, mover y
abrir un solo archivo. Contribuye a la creación de objetos FileStream.
BufferedStream Almacena en un búfer los datos necesarios para las operaciones de
lectura y escritura en otra secuencia. No se puede heredar esta clase.
FileStream Proporciona un Stream para un archivo, lo que permite operaciones
de lectura y escritura sincrónica y asincrónica.
97
Tema 5: Gestión de ficheros
StreamReader Implementa un TextReader que lee los caracteres de una secuencia
de bytes.
StreamWriter Implementa TextWriter para escribir los caracteres de una secuencia.
TextReader Representa un lector que puede leer una serie secuencial de caracteres.
TextWriter Representa un escritor que puede escribir una serie secuencial de
caracteres.
Para obtener más información de las clases que del espacio
de nombres de [Link], podemos acceder a la documen-
tación de Microsoft:
BUSCA EN LA WEB
[Link]
[Link]?view=netcore-3.1
Los ficheros se almacenan en directorios o carpetas. Cada
directorio puede contener, a su vez, otros directorios dife-
rentes, y esto hace que el sistema de archivos vaya creando
una estructura jerárquica en la que cada fichero o directorio
tiene como padre el directorio que lo contiene.
Como es lógico, y para que esta estructura sea finita, debe
existir un directorio raíz, que va a ser el que contenga a
todos los demás y no tenga dependencia de ningún otro.
En resumen
Los ficheros o archivos 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.
Esto permite más independencia sobre la información, ya
que no necesitamos que el programa se esté ejecutando
para que la información que contiene exista. Cuando se di-
seña un programa y se quiere guardar información en algún
fichero, el programador es el encargado de indicar cómo
manejar esas estructuras (creación de ficheros, añadir in-
formación en un fichero ya existente…).
98
Programación - A
Por tanto, para manipular un fichero, que lo identificamos
por un nombre, realizaremos tres operaciones:
• Abrir el fichero.
• Escribir o leer registros del fichero.
• Cerrar el fichero.
A la hora de trabajar con ficheros, debemos tener en
cuenta:
• La información es binaria (conjunto de ceros y unos).
• Al agrupar los bits, se forman bytes o palabras.
• Los tipos de datos van a estar formados por un conjunto
de bytes o palabras.
• Al agrupar los campos, se crean los registros de infor-
mación.
• Un fichero es un conjunto de bytes con una misma es-
tructura.
• Los directorios tienen la función de agrupar distintos fi-
cheros siguiendo unas condiciones determinadas dadas
por el sistema operativo o por el programador.
Utilidades de los ficheros
• Permiten organizar más fácilmente el sistema de archivos.
• Evitan conflictos con sus nombres, ya que cada programa
instala sus ficheros en directorios diferentes. Por tanto,
en una misma máquina pueden existir dos ficheros iden-
tificados por el mismo nombre, ya que, como van a tener
distinta ruta, los vamos a poder diferenciar.
• La relación entre ficheros y directorio es muy cercana, en
C# se establece entre tipos y espacio de nombres.
99
Tema 5: Gestión de ficheros
Rutas de ficheros y directorios
En el apartado anterior hemos visto la relación entre fiche-
ro y directorio. Para la identificación inequívoca de este
fichero, habrá que nombrar el camino que nos lleva hasta
él. A este camino lo denominamos ruta.
Dependiendo de cómo empecemos la ruta de directorio
para nombrar el archivo, podemos tener dos tipos de rutas
bien diferenciados:
• Ruta absoluta o completa: se indica el camino del direc-
torio desde el comienzo. En el sistema operativo Linux,
empieza por “/”. En el sistema operativo Windows o MS-
DOS, cada partición posee un directorio raíz (por ejemplo,
C:\). No existe un directorio raíz común que los contenga
a todos ellos como en Linux.
• Ruta relativa: se le indica el camino del directorio desde
la posición actual. Por tanto, la ruta no empezaría desde
el directorio raíz.
Tipos de ficheros
• Según su acceso: según la forma de organizar la infor-
mación, podemos distinguir entre tres tipos diferentes de
ficheros:
– Secuencial: en los ficheros secuenciales, los registros
se van almacenando en posiciones consecutivas de
manera que cada vez que queramos acceder a ellos
tendremos que empezar desde el primero e ir reco-
rriéndolos de uno en uno.
100
Programación - A
• Aleatorio o directo: en los ficheros aleatorios, podemos
acceder a un registro concreto indicando una posición
perteneciente a un conjunto de posiciones posibles. De-
bido a que los registros están organizados, estos pueden
ser leídos o escritos en cualquier orden, ya que se acce-
de a cada uno a través de su posición. Cuando queremos
realizar una operación, basta con colocar el puntero que
maneja el fichero justo antes de este.
Registro 1 Registro 2 Registro 3 Registro 4 … Registro N
Posición lectura/escritura
Para leer el Registro 4, colocamos el puntero de lectura/
escritura justo antes de su posición.
– Secuencial indexado: los ficheros indexados poseen
un campo clave (índice) para ser identificados. Permi-
ten el acceso secuencial y aleatorio a un fichero de la
siguiente forma:
◦ Primero busca de forma secuencial el campo clave o
índice.
◦ Una vez que lo encuentra, el acceso al fichero es di-
recto, ya que solo tenemos que acceder a la posición
indicada por el campo clave.
Para que este proceso funcione de manera correcta, los
índices se encuentran ordenados, permitiendo de esta
forma un acceso más rápido.
Campo clave o índice Archivo de datos
1 1510
77
2 77
3 3680
1510
3680
101
Tema 5: Gestión de ficheros
• Según su estructura:
– Ficheros de texto: formados por texto plano con for-
mato legible por el usuario.
– Ficheros binarios: los datos se almacenan de forma bi-
naria (como su nombre indica) y, por tanto, de la misma
forma que se guarda en memoria. Los datos se encrip-
tan (codifican) en ceros y unos, de manera que se hace
mucho más eficiente su almacenamiento.
ponte a prueba
¿En qué tipo de dispositivo de almace-
namiento se guarda el contenido de los
ficheros?
a) Primario.
b) Secundario.
c) Terciario.
d) Ninguna de las opciones es correcta.
¿Cuál de las siguientes afirmaciones sobre un
fichero secuencial indexado es correcta?
a) Está compuesto por un índice secuencial.
b) E
stá formado por un puntero que nos indica
el campo que queremos acceder.
c) No podemos programar en C# este tipo de
ficheros.
d) A y B son correctas.
¿Qué tipo de ruta es esta: ./carpeta/fichero.
dat?
a) Es una ruta relativa.
b) Es una ruta absoluta.
c) Es una ruta secuencial.
d) Ninguna respuesta es correcta.
102
Programación - A
5.2. Diseño y modulación de las
operaciones sobre ficheros
5.2.1. Fundamentos de los flujos
Los flujos (también llamados stream) de datos son las es-
tructuras o pasarelas que tenemos para acceder a los datos
de un fichero, de una forma consistente y fiable, desde un
código fuente en cualquier lenguaje de programación.
La clase Stream nos permite abstraer de una secuencia
de bytes como, por ejemplo, un archivo, un dispositivo de
entrada/salida, una canalización de comunicación entre
procesos o un socket.
La clase FileStrem deriva de la clase Stream y nos propor-
ciona los siguientes métodos:
FileStream (string nombre, FileMode modo)
FileStream (string nombre, FileMode modo, FileAccess
acceso)
El primer método abre un flujo de entrada y salida que se
vincula al fichero especificado en el nombre, mientras que
el segundo método realiza lo mismo y añade el tipo de ac-
ceso: lectura, escritura o lectura/escritura.
El parámetro nombre es una cadena de caracteres que in-
dica la ruta donde está guardado o donde se guardará el
fichero.
103
Tema 5: Gestión de ficheros
Puede escribirse:
c:\\users\\AppData\\[Link]
@c:\users\AppData\[Link]
La ventaja de utilizar la @ es que las secuencias de escape
no se procesan. Una secuencia de escape son combina-
ciones de caracteres que consisten en una barra diagonal
inversa (\) seguida de una letra como, por ejemplo, \n que
representa una nueva línea.
FileMode nos indica cómo se debe abrir un archivo. Los
campos pueden tomar los siguientes valores:
CreateNew Crea un nuevo fichero. Si existe, lanzará un error.
Truncate Abre un fichero existente. El fichero será truncado a cero bytes de
longitud.
Create Crea un nuevo fichero. Si el fichero existe, será sobrescrito.
Open Abre un fichero existente. Si el fichero no existe, lanzará un error.
OpenOrCreate Abre un fichero si existe; si no, se crea un fichero nuevo.
Append Abre un fichero para añadir datos al final del mismo si existe, o
crea un fichero nuevo si no existe.
El parámetro acceso puede tomar los siguientes valores:
Read Permite acceder al fichero para realizar operaciones de lectura.
ReadWrite Permite acceder al fichero para realizar operaciones de lectura y
escritura.
Write Permite acceder al fichero para realizar operaciones de escritura.
En el flujo de entrada de datos (lectura), solo podemos rea-
lizar la operación de lectura de un fichero, es decir, existe
una comunicación unilateral desde el fichero al programa.
El flujo de salida (escritura) también es en sentido unidi-
reccional, ya que solo podemos realizar la operación de
escritura en el fichero.
104
Programación - A
En el flujo o stream de entrada/salida es cuando podemos
tanto leer como escribir en el fichero. El tipo de stream lo
vamos a definir al iniciar el trabajo con ficheros, y no se
podrá cambiar una vez abierto.
ponte a prueba
¿Qué es FileStream? ¿Qué hace la directiva Open?
a) Es un tipo de variable de ficheros. a) Abre un fichero si existe. Si no
b) Es un tipo de visibilidad de existe, se crea un fichero nuevo.
métodos en el manejo de ficheros. b) A
bre un fichero existente. Si el
c) Es una clase que permite opera- fichero no existe, lanzará un error.
ciones de lectura y escritura. c) Crea un nuevo fichero. Si existe,
d) Todas las opciones son correctas. lanzará un error.
d) Abre un fichero para añadir datos
al final de este.
5.2.2. Clases de flujos
System Object
MarshalByRefObject BinaryReader BinaryWriter
Stream TextReader TextWriter
BufferedStream
StringReader StringWriter
MemoryStream
StreamReader StreamWriter
FileStream
Flujos base Flujos intermedios
105
Tema 5: Gestión de ficheros
En este apartado utilizaremos las clases de C# pertenecien-
tes a los dos tipos de ficheros: binarios y de textos.
Se pueden distinguir dos tipos de flujos:
• Flujos base: son aquellos que operan más a nivel máqui-
na, como, por ejemplo, porción de memoria, espacio de
disco o conexión de red.
• Flujos intermedios: son aquellos flujos que trabajan por
encima de los anteriores. Se pueden combinar con el flu-
jo base de manera que este pueda verse beneficiado por
todas las funcionalidades que ofrezca el flujo base.
• Podríamos decir que el flujo intermedio procesa la in-
formación, mientras que el base realiza la función de
envío de bytes de un lugar a otro.
5.3. Operaciones sobre ficheros
secuenciales
Las tres operaciones básicas que tenemos cuando traba-
jamos con ficheros son:
1. Apertura
Lo primero que debemos hacer siempre es abrir el fichero
para la operación que vayamos a realizar sobre él. Cuan-
do abrimos el fichero, estamos relacionando un objeto de
nuestro programa con un archivo.
Los diferentes modos en los que se puede abrir un fichero
son los siguientes:
• Open: realizamos la apertura de un fichero. Recordemos
que se desencadena una excepción si el fichero no existe
(FileNotFoundException).
• Create: creamos un fichero nuevo. Si el archivo ya existe,
se sobrescribirá. Es equivalente a solicitar que se utilice
CreateNew si no existe el archivo, y que se utilice Truncate
en caso contrario.
• CreateNew: creamos un fichero nuevo. Si el fichero ya
existe, lanzará una excepción (IOException).
106
Programación - A
• Truncate: abrimos un archivo que ya existe. Cuando se
abra, se debe truncar su tamaño a cero bytes. Al intentar
leer un abierto en este modo, se producirá una excepción
(ArgumentException).
• OpenOrCreate: se abre un archivo si ya existe. En caso
contrario, se crea uno nuevo.
• Append: se abre el archivo si existe y realiza una búsque-
da hasta el final. Si el archivo no existe, crea uno nuevo.
2. Lectura/escritura
Tenemos que leer o escribir la información del fichero
prestando atención tanto al fin de fichero en ficheros
secuenciales como a la posición del puntero en ficheros
aleatorios.
Las operaciones de lectura/escritura se pueden hacer de
dos formas diferentes: para ficheros secuenciales o para
ficheros aleatorios. Vamos a verlo detenidamente con el
siguiente ejemplo:
Lectura secuencial
// PSEUDOCÓDIGO
// Declaración de la variable del fichero
fichero f1;
// Abrimos el fichero para leerlo
[Link](lectura);
Mientras no final de fichero Hacer
[Link](registro);
operaciones con registro leído;
FinMientras
// Cerramos el fichero
[Link]();
Escritura secuencial
// PSEUDOCÓDIGO
// Declaración de la variable del fichero
fichero f1;
// Abrimos el fichero para leerlo
[Link](escritura);
Mientras existan datos a escribir
[Link](registro);
FinMientras
// Cerramos el fichero
[Link]();
107
Tema 5: Gestión de ficheros
Lectura aleatoria
// PSEUDOCÓDIGO
// Declaración de la variable del fichero
fichero f1;
// Abrimos el fichero para leerlo
[Link](lectura);
Situar el puntero del fichero justo antes del
registro requerido
[Link](registro);
Otras operaciones con registro leído;
// Cerramos el fichero
[Link]();
Escritura aleatoria
// Declaración de la variable del fichero
fichero f1;
// Abrimos el fichero para leerlo
[Link](escritura);
Mientras se deseen escribir datos Hacer
Posicionar el puntero del fichero en la posición deseada
[Link](registro);
otras operaciones con registro leído;
finMientras
//Cerramos el fichero
[Link]();
108
Programación - A
3. Cierre
Cuando cerramos el fichero, este queda liberado y termina
el proceso de almacenamiento de información.
ponte a prueba
¿Qué realiza el siguiente código?
FileStream fichero = new FileStream(“C:/fichero/ejercicio1.
txt”, [Link], [Link]);
StreamReader fs = new StreamReader(fichero);
string linea = “”;
while ((linea = [Link]()) != null)
[Link](linea);
[Link]();
[Link]();
a) Muestra por pantalla una cadena vacía.
b) Muestra por pantalla el contenido del fichero “[Link]”.
c) Escribe línea en el fichero “[Link]”.
d) Ninguna de las opciones es correcta.
La programación en C# de los ficheros secuenciales y aleatorios se realiza
teniendo en cuenta la posición del puntero.
a) Verdadero.
b) Falso.
5.3.1. Clase FileStream
En el apartado 5.2.1 vimos los tipos de métodos que nos
proporciona esta clase y los diferentes valores que pueden
tomar el parámetro modo y acceso.
FileStream (string nombre, FileMode modo)
FileStream (string nombre, FileMode modo, FileAccess
acceso)
Vamos a trabajar con estos métodos para ficheros de texto
y ficheros binarios.
109
Tema 5: Gestión de ficheros
Ficheros de texto
Los datos pueden ser escritos o leídos de un fichero utilizan-
do los flujos de las clases StreamWriter y StreamReader:
• StreamReader implementa un TextReader que lee los ca-
racteres de una secuencia de bytes.
• StreamWriter implementa un TextWriter para escribir los
caracteres de una secuencia.
Lectura de un fichero de texto en C#:
using [Link]; // Importación de la clase [Link]
// Creamos la variable fichero con la clase FileStream pasando la ruta
del fichero, el modo de apertura (Open) y cómo vamos a acceder a él
(lectura)
FileStream fichero = new FileStream(“C:/fichero/[Link]”, File-
[Link], [Link]);
// Abrimos el flujo de lectura
// Proporciona una vista genérica de una secuencia de bytes
StreamReader fs = new StreamReader(fichero);
string linea = “”;
while ((linea = [Link]()) != null) // Mientras no lleguemos a fi-
nal de fichero
[Link](linea); //sacamos por pantalla lo
que contenga el fichero
[Link](); // cerramos el flujo
[Link](); // cerramos el fichero
}
}
110
Programación - A
Escritura de un fichero de texto en C#
using [Link]; // Importación de la clase [Link]
// Creamos la variable fichero con la clase FileStream pasando la ruta
del fichero, el modo de apertura (en este caso, vamos a añadir datos al
final del fichero -> Append) y cómo vamos a acceder a él (escritura)
FileStream fichero = new FileStream(“C:/fichero/[Link]”, File-
[Link], [Link]);
// abrimos el flujo de escritura
StreamWriter fs = new StreamWriter(fichero);
//pedimos al usuario una cadena de texto la escribiremos en el fichero
[Link](“Introduce una frase: “);
string frase = [Link]();
[Link](frase);
// cerramos el flujo y el fichero
[Link]();
[Link]();
Ficheros binarios
Generalmente, los usuarios trabajamos con ficheros de
texto, pero también es frecuente encontrarnos con infor-
mación que esté organizada como una secuencia de bytes.
Nos referimos a ficheros de imágenes, ficheros de sonido,
ficheros de video, etc.
Lo primero que vamos a analizar es cómo abrir un fichero
de forma que podamos leer los bytes que contiene.
Comenzaremos por utilizar la clase FileStream, diseñada
para acceder a un byte o a bloques de byte. Así, esta clase,
proporciona un método para el acceso:
• Read (Byte[], int offset, int count) lee un bloque de bytes
de la secuencia y escribe los datos en un búffer dado.
Los parámetros:
– array Byte []: contiene la matriz de bytes especificada
con los valores de offset y reemplazados por los bytes
leídos desde el origen actual.
– offset: se colocarán los bytes leídos.
– Count: el número máximo de bytes que se deben leer.
111
Tema 5: Gestión de ficheros
Por ejemplo:
byte[] buffer = new byte[[Link]];
// creamos un array unidimensional con la cantidad de bytes que se
compone el fichero
[Link](buffer, 0, [Link]);
// Vamos a leer el buffer donde todavía no hemos consumido ningún byte
y el número máximo que vamos a leer es lo que contiene el buffer
Ejemplo de lectura en ficheros binarios
using [Link];
// Vamos a trabajar con un fichero imagen, de tal forma que lo abrire-
mos de modo lectura
FileStream fichero = new FileStream(“C:/fichero/[Link]”, FileMode.
Open, [Link]);
// Creamos un buffer de tipo byte para poder trabajar con los datos del
fichero
Byte [] buffer = new byte[[Link]]; //un entero de 8 bits sin
signo.
// Abrimos el fichero para la lectura y vamos a ir consumiendo todos
los bytes del fichero y mostrándolos por pantalla
[Link](buffer, 0, [Link]);
for (int i = 0; i < [Link]; i++)
{
[Link](buffer[i]);
}
//[Link]();
112
Programación - A
Ejemplo de escritura en ficheros binarios
using [Link];
// Vamos a trabajar con un fichero imagen, modificando su contenido.
Primero lo abriremos de modo lectura y escritura
FileStream fichero = new FileStream(“C:/fichero/[Link]”, FileMode.
Open, [Link]);
// Creamos un buffer de tipo byte para poder trabajar con los datos del
fichero
Byte[] buffer = new byte[[Link]]; //un entero de 8 bits sin sig-
no.
// Abrimos el fichero para la lectura y vamos a ir consumiendo todos
los bytes del fichero
[Link](buffer, 0, [Link]);
// Ahora modificamos algunos bytes
for (int i = 1000; i < [Link]; i++)
{
buffer[i] = 0;
}
// Vamos a sustituir los caracteres en el fichero, volcamos el conteni-
do del buffer en el fichero y lo cerramos
[Link](buffer, 0, [Link]);
[Link]();
113
Tema 5: Gestión de ficheros
ponte a prueba
¿Qué realiza el siguiente código?
FileStream fichero = new FileS-
tream(“C:/fichero/[Link]”,
[Link], [Link]);
StreamWriter fs = new StreamWriter(-
fichero);
[Link](“Introduce una
frase: “);
string frase = [Link]();
[Link](frase);
[Link]();
[Link]();
a) Escribirá la frase introducida por el usuario en
un fichero binario.
b) E
scribirá la frase introducida por el usuario
en un fichero de texto.
c) Escribirá la frase introducida por el usuario en
un fichero de datos.
d) El código contiene errores porque falta cerrar
el flujo de datos.
La clase StreamReader es utilizada para leer
texto de un archivo.
a) Verdadero.
b) Falso.
¿Cuál es el objetivo de utilizar un buffer de
lectura para ficheros de datos?
a) Para almacenar el conjunto de bytes formado
por el fichero de datos.
b) Para guardar línea a línea el fichero de texto.
c) Para controlar el fin de fichero.
d) Ninguna opción es correcta.
114
Programación - A
5.4. Control de excepciones
Hasta ahora, hemos trabajado con ficheros para realizar su
lectura y escritura. El problema es que no hemos compro-
bado si ese fichero realmente existe o no, lo que puede
suponer que nuestro programa falle en caso de que el
fichero no se encuentre donde esperamos.
Una primera solución es usar el método exists para
comprobar si está, antes de intentar abrirlo.
• Exists (string path): le pasamos la ruta del fichero y de-
volverá un booleano. Si no existe, devolverá un false. Si la
ruta no existe o es incorrecta, también devolverá un false.
using [Link];
if ([Link](@”D:\[Link]”)) {
[Link](“El fichero existe...”);
} else {
[Link](“El fichero no existe en el directorio D…”);
}
• Try/catch: el bloque try contiene el código protegido que
puede producir la excepción.
Los mensajes de error y/o acciones para corregir el error
estarán en el bloque catch.
using [Link];
string linea;
try
{
FileStream fichero = new FileStream(“C:/fichero/ejercicio1.
txt”, [Link], [Link]);
StreamReader fs = new StreamReader(fichero);
if ((linea= [Link]())!= null)
[Link](linea);
[Link]()
[Link]();
}
catch (Exception exp)
{
[Link](“Ha habido un error: {0}”, [Link]);
}
115
BIBLIOGRAFÍA / WEBGRAFÍA
” Ceballos, F. J. (2011). Microsoft C#. Curso de programación. 2ªEdición. RA-MA Editorial.
” Serna, M. E. (2009). Edsger Wybe Dijkstra. Revista Digital Lámpsakos, no. 2, pp. 107-11.
” Nacho Cabanes. Introducción a C#. 2020. Sitio web: [Link]
csharp/curso2015/[Link]
” Pildorasinformaticas. Canal de Youtube. Sitio web: [Link]
pildorasinformaticas
” Corrado Böhm, Giuseppe Jacopini. (1966). Flow diagrams, turing machines and
languages with only two formation rules. 2020, de ACM Digital Library, Association for
Computing Machinery. Sitio web: [Link]
solucionario
1. Introducción a la programación 2.4. Operadores del lenguaje de
programación
¿Cómo debe ser un programa informático?
d) Todas las opciones anteriores son correctas. ¿Cuál es el resultado del siguiente código?
d) Ninguna de las repuestas es correcta.
¿Cuál de las siguientes opciones sobre el
La variable num no se ha declarado, por lo que
siguiente diagrama de flujo es correcta?
daría un error.
a) Muestra los n primeros números impares.
¿Cuál de las siguientes opciones sobre el
C# tiene dos categorías tipos de datos operador ! es correcta?
integrados: por valor y por referencia.
a) Calcula la negación lógica de nuestro
a) Verdadero. operando.
2.1. Bloques de un programa informático 2.5. Conversiones de tipos de clase
¿Qué es un IDE? Las conversiones implícitas son aquellas que se
c) Es un software diseñado para el desarrollo de producen cuando el valor que se va a almacenar
aplicaciones. se puede almacenar en la variable sin pérdida
de información.
Siempre que ejecutemos un programa, el
primer método que se ejecutará será el Main. a) Verdadero.
a) Verdadero. ¿Qué convierte el método ToString?
¿Qué realiza el siguiente código? d) E
l valor especificado en su representación de
cadena.
c) Muestra por pantalla Hello World!
2.6. Comentarios al código
2.2. Variables. Usos y tipos
Según el siguiente código, ¿qué saldrá por
¿Cuál de las siguientes opciones es una pantalla?
característica de una variable?
d) Nada, porque el código está comentado.
d) Todas las respuestas son correctas.
Para hacer comentarios de una sola línea,
¿Qué tipo de dato es un char?
debemos utilizar el operado /.
a) Carácter.
b) Falso.
Las variables globales son aquellas que están Hay que utilizar la doble barra //.
declaradas dentro de un método o función
b) Falso. 3.1. Fundamentos de la programación
Las variables globales son aquellas declaradas
Dijkstra concluyó que la combinación de varios
fuera de un método o función.
tipos de instrucciones, podemos crear un
programa estructurado. ¿Cuáles son?
2.3. Constantes y literales. Tipos y utilidades d)Todas las opciones son correctas.
¿Con qué palabra reservada se define una Según Böhm y Jacopini, ¿cuál de las siguientes
constante?
opciones sobre un programa es cierta?
a) Const. d) Todas las respuestas son correctas.
¿Qué representa el literal \n?
a) Una nueva línea. 3.3. Diseño de algortimos
En la etapa de diseño, tomamos los requisitos
de los clientes.
b) Falso.
Es en la etapa de análisis donde tomamos los
requisitos.
solucionario
Después de la fase de pruebas, ¿qué etapa se La función Trim() elimina cualquier carácter del
lleva a cabo? principio y el final de la cadena.
c) Mantenimiento. b) Falso.
Si no se pasa argumentos a la función Trim, eli-
3.5. Tipos de datos: simples y compuestos mina todos los caracteres de espacio en blanco
del principio y el final de la cadena.
¿Qué tipo de datos es el tipo enumerado?
b) Simple.
3.10. Depuración de errores
¿Cómo puedo acceder al dato 2 si tenemos el ¿Qué errores podemos encontrar en la etapa de
siguiente array? int[] a = new int[] {1, 2, 3}; la depuración de un programa?
a) a[1] d) Todas las respuestas son correctas.
¿Cuántas columnas contendrá la siguiente El programador está realizando un programa en
matriz? int [,] matriz = new int[2,3]; el cual quiere introducir dos datos enteros. Uno,
b) 3 que sea la base y otro que sea el exponente
para realizar la operación potencia. Introduce
como base el número 5 y como exponente 2.
3.6. Estructuras de selección
El resultado es 10. ¿Qué tipo de error le está
Según el siguiente código, ¿cuándo imprimimos dando a nuestro programador?
la cadena “Hola a todos”? b) Lógico.
c) Cuando se cumpla la condición a y b.
Según el siguiente código: 3.12. Entornos de desarrollo de programas
a) Escribimos por pantalla “Estamos en el if”. ¿Qué ventajas nos ofrecen los IDE?
d) Todas las opciones son correctas.
3.7. Estructuras de repetición
Según el siguiente código, ¿ejecutaríamos el 4.2. Ventajas e inconvenientes
código de la salida por pantalla? ¿Qué ventajas nos proporciona la programación
a) Sí, con que se cumpla una condición es modular?
suficiente.
d) Todas las opciones son correctas.
¿Cuántas veces ejecutaríamos un bucle do-
while? 4.3. Análisis descendente (top down)
b) Mínimo, una vez.
¿En qué consiste el diseño top down?
¿Es correcto el siguiente código? b) Dividir un gran problema en subproblemas.
b) No. La variable i no está declarada.
4.5. Llamadas a funciones. Tipos y
3.8. Estructuras de salto funcionamiento
Según el siguiente código, ¿qué saldrá por Las funciones deben tener un tipo asociado.
pantalla? a) Verdadero.
a) Case 1
¿Cuál es la salida del siguiente código?
a) 15.
3.9. Tratamiento de cadenas
¿Qué mostrará por pantalla el siguiente código? Cuando realizamos un paso por valor de una
variable, creamos dos posiciones de memoria
a) 3. distintas.
a) Verdadero.
solucionario
4.6. Ámbito de las llamadas a funciones ¿Qué tipo de ruta es esta: ./carpeta/[Link]?
a) Es una ruta relativa.
Una variable local puede ser accedida desde
cualquier función o método.
b) Falso. 5.2.1. Fundamentos de los flujos
Solo se pueden acceder a variables locales des- ¿Qué es FileStream?
de el método donde están creadas. c) Es una clase que permite operaciones de
lectura y escritura.
¿Qué muestra por pantalla el siguiente código?
c) 15 ¿Qué hace la directiva Open?
HOLA ILERNA. b) Abre un fichero existente. Si el fichero no
existe, lanzará un error.
Según el siguiente código, ¿qué ocurrirá con la
función?
c) La función nos devolverá num1 si es mayor 5.3. Operaciones sobre ficheros secuenciales
que num2 o num2 si es mayor que num1. ¿Qué realiza el siguiente código?
b) Muestra por pantalla el contenido del fichero
4.7. Prueba, depuración y comentarios de “[Link]”.
programas
La programación en C# de los ficheros
Podemos poner un punto de interrupción en secuenciales y aleatorios se realiza teniendo en
nuestros programas y depurar línea a línea. cuenta la posición del puntero.
a) Verdadero. b) Falso.
Solo hay que controlar el puntero en los ficheros
4.9. Uso de librerías aleatorios.
Gracias a la librería de matemáticas, el IDE nos
proporciona métodos ya implementados. 5.3.1. Clase FileStream
Según lo comentado, ¿qué realiza el siguiente ¿Qué realiza el siguiente código?
código? b) Escribirá la frase introducida por el usuario en
a) Saca por pantalla el coseno de un ángulo. un fichero de texto.
La clase StreamReader es utilizada para leer
4.10. Recursividad texto de un archivo.
a) Verdadero.
¿A qué se refiere el concepto de recursividad?
c) Llamada de una función a sí misma. ¿Cuál es el objetivo de utilizar un buffer de
lectura para ficheros de datos?
La recursividad necesita un caso base que a) Para almacenar el conjunto de bytes formado
permita la finalización del programa. por el fichero de datos.
a) Verdadero.
¿Qué realiza el siguiente código?
b) Muestra por pantalla los números de n a 1.
5.1. Concepto y tipos de ficheros
¿En qué tipo de dispositivo de almacenamiento
se guarda el contenido de los ficheros?
b) Secundario.
¿Cuál de las siguientes afirmaciones sobre un
fichero secuencial indexado es correcta?
d) A y B son correctas.