You are on page 1of 109

LENGUAJES DE PROGRAMACIÓN I

CONFERENCIA # 1
 Introducción
 Resolución de problemas computacionales por medio de la tecnología top -
down o de lo complejo a lo simple
 Definición de: Secuenciación, repetición, Refinamiento sucesivo,
procedimientos
 Ejemplo: Copiar el contenido de un rollo antiguo a rollo nuevo utilizando

INTRODUCCIÓN
A menudo nos hacemos la pregunta del por qué los programadores escriben un
programa. Esto es para resolver un problema por lo que el propósito de nuestro
estudio será el enseñar y aprender un método de solución de problemas con
programas de computadora mediante el estudio de la programación
estructurada.

Para llegar a nuestros objetivos, es necesario también presentar al C++ en un


estilo diseñado para fomentar buenos hábitos de programación.

Lenguajes de programación
Permite expresar un algoritmo comprensible para un ordenador

¿Qué es un algoritmo?
 Fórmula para resolver un problema
 Consta de una serie de pasos
 Se aplica de forma mecánica
 Se aplica en un tiempo finito

Formas de programar:
 Programación modular
 Programación estructurada
 Programación dinámica

Distintas tecnologías
Lenguaje de programación: refleja un paradigma

Programación imperativa
 Programa en un lenguaje imperativo:
o Lista de instrucciones, órdenes elementales
o Ejecución: una tras otra, en el orden del programa

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 1


LENGUAJES DE PROGRAMACIÓN I

 Las instrucciones de un programa imperativo utilizan variables


o Variable: dato almacenado en la memoria del ordenador
 Ejemplos de lenguajes imperativos: BASIC, Pascal, C.

Programación imperativa
Elementos principales
 Variable
o Nombre de celdas en memoria donde se almacenan los datos
o Estado del programa en un momento dado: Conjunto de valores de
las variables del programa
 Operaciones de asignación
o Se calcula un nuevo valor y se asigna a la variable
o Así se modifica el estado del programa
 Repetición
o Ejecución repetida de una secuencia de pasos elementales

Programación funcional
 Basada en el concepto matemático de función
 Función = regla de correspondencia que asocia a cada elemento de un
conjunto origen un elemento de un conjunto destino
o Conjunto origen = dominio de la función
o Conjunto destino = rango de la función
 Composición funcional: el resultado de un cálculo es el argumento del
siguiente
 Ejemplos de lenguajes de programación funcional: LISP, Haskell, Gofer.

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 2


LENGUAJES DE PROGRAMACIÓN I

Elementos principales de la programación funcional


 Tipos de datos
 Expresiones condicionales
 Recursión (método de programación en el cual una rutina se llama a si
misma varias veces)

Abstracción en programación funcional


 Abstracción del problema a solucionar, modelándolo como una
composición de funciones
 Más cercanos al “espacio del problema” que al “espacio de la solución”

Programación orientada a objetos


 Permite representar en el programa los elementos del dominio del
problema
 Estos elementos se denominan objetos
 El código del programa contiene la solución del problema
 Cada objeto tiene un estado, representado por:
o Atributos (parecido a las variables) y
o Operaciones que puede realizar
 Ejemplos de lenguajes orientados a objeto: Smalltalk, C++ y Java
 Programa: objetos que se comunican mediante "mensajes".
 Un objeto puede estar formado por otros objetos.
 Cada objeto en una "instancia" de una "clase" o categoría.
 Clase: definición de las características comunes de un conjunto de objetos.
o Interfaz: conjunto de métodos.
o Estructura: conjunto de variables.
 Cada objeto de la misma "clase" puede recibir los mismos mensajes.
 Un objeto tiene: identidad única, "state" (estado interno, datos propios),
"methods" (para generar un comportamiento).

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 3


LENGUAJES DE PROGRAMACIÓN I

¿Cómo se ejecuta un programa?


 Código fuente: programas escritos en un lenguaje de alto nivel
 Traducción a un lenguaje ejecutable por procesador del ordenador
o Compilador: traduce código fuente a instrucciones básicas del
ordenador (código máquina), que luego se ejecutan
o Intérprete: traduce instrucción a instrucción del código fuente, a
código máquina, y la ejecuta

HISTORIA DEL LENGUAJE C


 C fue creado por Dennis Ritchie en 1972 en un computador DEC PDP-11,
con sistema operativo UNIX
 C es sucesor del antiguo lenguaje B, desarrollado por Ken Thompson

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 4


LENGUAJES DE PROGRAMACIÓN I

 La primera versión de C fue el estándar utilizado para la construcción del


verdadero UNIX actual “UNIX System V”
 Su rápida aparición ocasiona la aparición de muchas variantes y
problemas de compatibilidad

Existe un estándar ISO de 1986 denominado ANSI C. En teoría, un lenguaje


100% ANSI C sería portable entre plataformas y/o arquitecturas pero en la
práctica esto no es siempre cierto.

ANSI: American National Standars Institute

En 1989 se adopta el primer estándar con lo cual aparecen los primeros


compiladores para C.

En 1999 se adoptó el último estándar conocido como C99 con algunas mejoras e
ideas de C++.

Actualmente coexisten ambos estándares (C89 y C99) pero se está migrando a


este último.

CARACTERISTICAS
 C es un lenguaje estructurado que permite trabajar a alto y bajo nivel,
esto permite mayor potencia y flexibilidad a cambio de menos abstracción
 No es un lenguaje fuertemente tipado, lo que significa que se permite casi
cualquier conversión de tipos
 Tiene un reducido número de palabras clave: 32 en C89 y 37 en C99
 Los compiladores de C, en general, producen programas ejecutables muy
eficientes y portables
 C dispone de una biblioteca estándar de funciones
 Se distingue entre mayúsculas y minúsculas
 Palabras clave: siempre en minúsculas
 Todas las sentencias y declaración de variables terminan en punto y coma
 La ejecución siempre comienza con la función main()

En resumen:
C es un lenguaje muy flexible, muy potente, muy popular pero que NO
PROTEGE AL PROGRAMADOR DE SUS ERRORES.

PORTABILIDAD DE C
El compilador de C genera código ejecutable multiplataforma

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 5


LENGUAJES DE PROGRAMACIÓN I

RESOLUCIÓN DE PROBLEMAS COMPUTACIONALES POR MEDIO DE LA


TECNOLOGÍA TOP-DOWN O DE LO COMPLEJO A LO SIMPLE
Se cree que uno de los aspectos más importantes en la solución de problemas
utilizando métodos estructurados es el desarrollo de la solución de problemas
desde una perspectiva descendente (Top-Down). Esto significa que primero
debemos concentrarnos en qué hacer en vez de cómo hacerlo. El proceso
de refinamiento, completado por etapas o pasos es frecuentemente llamado
refinamiento sucesivo o progresivo.

Ejemplo:
Supongamos que ha sido localizado un antiguo rollo (contribución arqueológica
sugiere que fue escrito a mediados de los años cincuenta). La escritura en este
rollo está en inglés y se cree que contiene alguna nueva historia muy importante
acerca de los orígenes de la música de rock. Sin embargo, el rollo es muy frágil,
y sólo puede ser manipulado una sola vez. Por lo tanto, todos los interesados
acuerdan que al manipular deberá ser copiado, para que su contenido pueda
estudiarse con profundidad.

Recursos
 Un robot.
 Una caja de papel de formas continúas (de la clase utilizada por las
impresoras de computadora).
 Máquina de escribir.

El robot es lo bastante complejo como para ser programado para ejecutar cierto
número de tareas simples: puede leer textos un carácter a la vez, y escribir cada
carácter presionando la tecla apropiada en una máquina de escribir. El robot
puede hacer esto rápidamente sin cometer errores nunca. Puede también
reconocer el final de una línea escrita y el final del propio texto.

El que hacer:

Copiar RolloAntiguo a RolloNuevo

Refinamiento:

Preparar RolloAntiguo para lectura


Preparar RolloNuevo para escritura
Copiar una línea de RolloAntiguo a RolloNuevo
Mientras haya más líneas por copiar.

SECUENCIACIÓN
Una Secuenciación es una serie de operaciones que son llevadas a cabo
(ejecutadas) una después de la otra. Además las operaciones en una serie se
agrupan y se consideran como una sola operación. Las series de operaciones
que escribimos primero como solución a un problema se convierten en la primera
parte de un programa. Por último, una secuenciación puede tener una o más
operaciones; la secuenciación más corta tiene una sola operación.

REPETICIÓN
Recuerde que la tercera operación de nuestra solución presenta la repetición:

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 6


LENGUAJES DE PROGRAMACIÓN I

Copiar una línea de RolloAntiguo a RolloNuevo


Mientras haya más líneas por copiar.

Entonces se realiza la pregunta ¿Hay más líneas por copiar?


Si la respuesta es sí copiamos una línea de RolloAntiguo a RolloNuevo. Si la
respuesta es no la operación está completa.

REFINAMIENTO SUCESIVO
Si el robot comprende el cómo preparar el RolloAntiguo y el RolloNuevo entonces
estas dos operaciones no necesitan ningún refinamiento y se convierten en parte
del cómo ejecutar la operación copiar.

Si el robot no entiende lo que se requiere, entonces sería necesario un


refinamiento adicional.

Sabemos que el robot no comprende cómo copiar una línea entonces debemos
refinar nuestra solución para poder describir cómo llevarla a cabo:

Copiar un carácter de RolloAntiguo a RolloNuevo


Mientras haya más caracteres en la línea.

Después:

Copiar un carácter de RolloAntiguo a RolloNuevo


Mientras haya más caracteres en la línea.

Colocarse al principio de la siguiente línea de RolloAntiguo


Colocarse al principio de la siguiente línea de RolloNuevo

El robot no sabe como copiar un carácter:

Mientras haya más caracteres en la línea de RolloAntiguo


Leer un carácter de RolloAntiguo
Escribir ese carácter en RolloNuevo presionando
La tecla correspondiente en la máquina de escribir
Colocarse al principio de la siguiente línea de RolloAntiguo
Colocarse al principio de la siguiente línea de RolloNuevo

Esto sugiere que el robot repita la lectura y la escritura de un carácter mientras


haya más caracteres en una línea.

Conclusiones
 Plantearnos la solución de un problema en términos generales Qué hacer y
omitiendo los detalles de cómo hacerlo.
 La solución de un problema se puede plantear como una secuencia de
procedimientos donde cada procedimiento en sí se convierte en un problema
de menor escala por resolver.
 En las primeras etapas no queremos ocuparnos de los detalles de bajo nivel
de la solución, es decir del cómo hacerlo. Primero organizamos nuestras
ideas de tal manera que podamos esbozar la solución como una serie de
procedimientos.

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 7


LENGUAJES DE PROGRAMACIÓN I

 Cuando estamos trabajando los detalles más minuciosos de una operación


nos preocupamos únicamente por esa operación. Lo que simplifica nuestro
trabajo.
 De este enfoque se dice que es de arriba-debajo de lo general a lo específico.
También se le ha llamado refinamiento paso a paso o sucesivo programas
que requieren subprogramas (procedimientos), los cuales en su momento
pueden requerir subprocedimientos.

PROGRAMAS Y PROCESOS
Refinemos nuestra solución convirtiéndola en un programa.

El programa se llama Copiar que comprende tres operaciones:


 Las dos primeras (preparar para leer y preparar para escribir)
 Tercera operación copiar una línea

El robot entiende la tarea de preparar y el copiar una línea no es un


procedimiento comprendido por el robot.

Procesos.- Es una secuencia de operaciones; el nombre del proceso se refiere a


una secuencia de operaciones específica. Entonces un proceso es muy parecido
a un programa, pero está subordinado o es controlado por un programa. A los
procedimientos o procesos también se los llama como subprogramas.

Deber:
1. Algoritmo para llegar a la ESPOCH
2. Algoritmo para cambiar un neumático bajo en el automóvil
3. Algoritmo para cambiar un foco quemado
4. Algoritmo para aprobar la materia de lenguajes de programación I
5. Algoritmo para realizar un pastel

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 8


LENGUAJES DE PROGRAMACIÓN I

CONFERENCIA # 2
 Herramientas para la solución de problemas
 Diagramas estructurales del programa
 Estructuras de control lógico
 Estructuras de datos
 Lenguaje de definición del programa (PDL)
 Ejemplo: Tratamiento en PDL del problema de copiar el contenido del Rollo
antiguo a un Rollo Nuevo

HERRAMIENTAS PARA LA SOLUCIÓN DE PROBLEMAS


Las herramientas para la solución de problemas son 4 y son las siguientes:
1. Diagramas estructurales del programa
2. Estructuras de control lógico
3. Estructuras de datos
4. Lenguaje de definición del programa

DIAGRAMAS ESTRUCTURALES DEL PROGRAMA


Una forma alterna de enfocar la solución a un problema es dibujar un diagrama
estructural del programa, en el cual se muestran las relaciones entre un
programa y sus procesos. Ejemplo COPIAR

COPIAR

Preparar RolloAntiguo Preparar RolloNuevo CopiarUnaLinea

Un diagrama estructural es una representación gráfica de la relación entre un


programa y sus procesos. Proporciona una documentación visual de la
estructura en conjunto de la solución de un problema.

ESTRUCTURAS DE CONTROL
Las estructuras de control se usan para mostrar la lógica de una solución. Una
estructura de control muestra las condiciones que controlan, o determinan, si
una operación debe terminarse. Podemos decir que las estructuras de control
son los medios por los cuales organizamos y decidimos si se ejecutan o no
diversas partes de la solución y bajo qué condiciones. Es este modo las
estructuras de control son las herramientas que utilizamos para organizar y
controlar la solución lógica de un problema.

Existen tres estructuras de control:


 Secuenciación (agrupamiento de uno o más pasos que son manejados como
uno solo).
 Repetición de una secuenciación.
 Selección de una secuenciación.

Secuenciación.- es un agrupamiento de una o más operaciones que describe


qué o cómo hacer alguna tarea.

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 9


LENGUAJES DE PROGRAMACIÓN I

Repetición.- La estructura de repetición está diseñada para controlar la


repetición de una secuenciación. Prueba si una repetición deberá realizarse. La
prueba consiste en formular una pregunta; si la respuesta es sí, entonces se
ejecuta la secuenciación indicada. El proceso se repite hasta que la respuesta a
la pregunta sea no. Después se ejecuta la operación que sigue a la repetición.

Selección.- La estructura de selección nos permite determinar cuál de los


diversos cursos posibles de acción se escoge. La forma más simple de la
estructura de selección es el enunciado if / else.

ESTRUCTURAS DE DATOS
Una estructura de datos es algo parecido a un modelo. Nos proporciona una
manera precisa de ver cómo diferentes datos se almacenan en la memoria de la
computadora. Y más que eso, el tipo de estructura de datos define cuáles
operaciones están permitidas y cuáles no para los diferentes datos. Por ejemplo
para los tipos de datos numéricos están permitidas las operaciones aritméticas y
de comparación. Para los datos tipo carácter no está permitidas las operaciones
aritméticas, pero sí están permitidas las operaciones de comparación.

Operaciones aritméticas:
 Sumar
 Restar
 Multiplicar
 Dividir
 Raíces cuadradas
 Tablas
 Vectores

Operaciones con caracteres:


 Comparar
 Leer
 Escribir
 Construir palabras
 Líneas
 Páginas
 Volúmenes

LENGUAJE DE DEFINICIÓN DEL PROGRAMA


Un Lenguaje de Definición de Programa, o PDL (Program Definition Language),
es una manera razonablemente precisa de describir cómo las estructuras de
control controlan las operaciones sobre los datos. Algunos llaman a este
lenguaje pseudolenguaje (lenguaje falso), ya que se parece un poco al lenguaje
de programación y un poco al lenguaje natural, sin ser ninguno realmente. En la
ingeniería de software el PDL se usa extensamente para describir las soluciones a
un problema antes de escribir dichas soluciones en un lenguaje de computadora.

Nótese el uso de la palabra Programa (main) para mostrar que estamos


describiendo la lógica para un programa, usaremos { (Comienza) y } (termina o
fin.) La cabecera del programa se escribe cargada a la izquierda como la
cabecera principal de un bosquejo. Todos los elementos definidos dentro del
programa aparecen indentados para resaltar que son elementos subordinados.

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 10


LENGUAJES DE PROGRAMACIÓN I

Además se utilizarán las palabras clave While do (Mientras Ejecutar) { }


formando un conjunto de llaves alrededor de las operaciones que se repiten. Por
lo tanto While y }se usan para delimitar las operaciones que se repetirán.

Ejemplo:

Programa Copiar de RolloAntiguo a RolloNuevo


CUERPO DE ROGRAMA
{ Operaciones de Copiar
Preparar RolloAntiguo para lectura
Preparar RolloNuevo para escritura
While existan más líneas en RolloAntiguo Do
{
CopiarUnaLinea de RolloAntiguo a RolloNuevo
}
} operaciones de Copiar

Ahora construiremos la lógica de nuestro procedimiento CopiarUnaLínea. El PDL


para un procedimiento es bastante similar al de un programa. La diferencia más
grande es que se usa la palabra Proceso en lugar de Program.

Ejemplo:

Proceso CopiarUnaLínea
{operaciones de CopiarUnaLínea
While existan más caracteres en esta línea de RolloAntiguo Do
{ Leer un carácter de RolloAntiguo
Escribir un carácter en RolloNuevo presionando
La tecla correcta en la máquina de escribir
}
Colocarse al principio de la siguiente línea de RolloAntiguo
Colocarse al principio de la siguiente línea de RolloNuevo
} operaciones de CopiarUnaLínea

Ahora debemos ensamblar todas las partes dentro del programa completo. Los
procesos se definen antes de utilizarse en el programa.

Ejemplo:

Programa Copiar de RolloAntiguo a RolloNuevo


Proceso CopiarUnaLínea
{ operaciones de CopiarUnaLínea
While existan más caracteres en esta línea de RolloAntiguo Do
{ Leer un carácter de RolloAntiguo
Escribir un carácter en RolloNuevo presionando
La tecla correcta en la máquina de escribir
}
Colocarse al principio de la siguiente línea de RolloAntiguo
Colocarse al principio de la siguiente línea de RolloNuevo
} operaciones de CopiarUnaLínea
CUERPO DEL PROGRAMA
{ Operaciones de Copiar

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 11


LENGUAJES DE PROGRAMACIÓN I

Preparar RolloAntiguo para lectura


Preparar RolloNuevo para escritura
While existan más líneas en RolloAntiguo Do
{
CopiarUnaLinea de RolloAntiguo a RolloNuevo
}
} operaciones de Copiar
 Deber:
1. Contar el número de líneas que contiene Rollo Nuevo
2. Reemplazar @ por la palabra "en" en el Rollo Nuevo
3. Proceso para facturar un pedido
4. Proceso para matricularse en la materia de Lenguajes de programación I
5. Añadir uno propio

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 12


LENGUAJES DE PROGRAMACIÓN I

CONFERENCIA # 3
 Proyecto informático
 Pasos para la solución de problemas
 Ejemplo: Ingresar por teclado 5 pares de números y comparar si son
iguales, si el primer número es mayor que el segundo o, si el primer número
es menor que el segundo

PROYECTO INFORMÁTICO
Ordenadores e informática son términos que van unidos y se complementan. La
informática estudia el tratamiento automático de la información a través de
medios electrónicos. Y estos son los ordenadores.

El ordenador es la máquina electrónica que trata la información mediante el


programa almacenado en su memoria.

El proceso de datos con ordenador mecaniza y automatiza la realización de


tareas rutinarias.

PASOS PARA LA SOLUCIÓN DE PROBLEMAS


Cada paso deberá seguirse cuidadosamente. Intentar abreviar el proceso
pasando demasiado aprisa por los primeros pasos aumenta la posibilidad de
errores en la solución.

1. Comprender el problema
Primero debemos analizar cuidadosamente los requerimientos del problema.
Debemos insistir en que los requerimientos del problema sean claramente
especificados en términos de los resultados esperados. Se debe de determinar:
 La fuente y el tipo de datos para la entrada
 La interacción de los datos y su transformación
 El destino y el formato de la salida

2. Diseñar una solución


Los pasos preliminares de una solución pueden escribirse como una
secuenciación sin tomar mucho en cuenta la necesidad de comunicar nuestra
solución a otros. Además necesitamos organizar la información para que sea
comprensible para nosotros y los demás. Utilizaremos un PDL.

3. Probar el diseño
Debemos estar convencidos de que la lógica escrita resuelve de hecho el
problema planteado. ¿Sí realizamos la secuenciación obtendremos la salida que
esperamos a partir de la entrada suministrada?. Si no, debemos regresar al
paso 2, corregir el diseño y luego probar otra vez.

4. Traducir el diseño a un lenguaje de programación


Este paso también se lo llama codificación, o sea traducir un diseño a un
lenguaje de programación. Ahora debemos considerar todas las reglas de
organización y puntuación del lenguaje de programación.

5. Preparar el problema en el lenguaje seleccionado (Pascal, C. etc.)


Capturar en la computadora con la ayuda de un editor el programa traducido.
Este paso requiere la edición (creación o modificación) del texto. Aquí es donde

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 13


LENGUAJES DE PROGRAMACIÓN I

comenzamos a utilizar el Ambiente Integrado de Desarrollo del sistema en


nuestro caso C++.

6. Compilación del programa


El traductor del lenguaje seleccionado, o también llamado compilador, nos
indicará si hemos empleado correctamente la organización y la puntuación. Si
existen errores hay que regresar al paso 5.

7. Correr el programa y comprobar los resultados


Debemos probar nuestra lógica para determinar si es correcta, probar el
programa con datos que estén al límite, números grandes o pequeños.

Si existen problemas es necesario descubrir qué pudo haber causado los


resultados erróneos podemos usar diversas técnicas para eliminar el error.

8. Depurar si es necesario (debug)


La eliminación de errores se conoce como depuración (debugging). Aquí se
determina si el error es causado por:
 Mal entendido del lenguaje de programación (regresar al paso 4).
 Por el diseño defectuoso (regresar al paso 2)
 O por falta de comprensión del problema (regresar al paso 1).

CASO DE ESTUDIO: DISEÑO DESCENDENTE Y PRUEBA


Ejercicio:
Debemos diseñar un programa que procese cinco pares de números. Los
números están arreglados por pares en cada una de las cinco líneas. El
programa debe examinar cada par y devolver uno de tres mensajes,
dependiendo de sí:
 Los números son iguales
 El primero es mayor que el segundo, o
 El segundo es mayor que el primero

Comprender el programa
Se determinarán las entradas y salidas requeridas.
Un posible conjunto de datos de entrada para el programa es:

35 46
52 38
49 23
67 67
35 -63

 Los datos serán captados por el teclado de una terminal o de una


microcomputadora.
 El mensaje de petición aparecerá en la pantalla.
 Los resultados de la comparación deberán aparecer en la pantalla.
 Debemos saber lo que significa pares de números.
 En la muestra se ven únicamente números enteros.
 En nuestro caso hay 5 entradas.

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 14


LENGUAJES DE PROGRAMACIÓN I

Pantalla:
Comparación de parejas de números enteros
Ingrese dos números enteros
35 46
El primer número 35 es menos que el segundo número 46
Ingrese dos números enteros
52 38
El primer número 52 es mayor que el segundo número 38
Ingrese dos números enteros
49 23
El primer número 49 es mayor que el segundo número 23
Ingrese dos números enteros
67 67
El primer número 67 es igual que el segundo número 67
Ingrese dos números enteros
35 -63
El primer número 35 es mayor que el segundo número -63

Diseño de la solución

CompararParDeNumeros

ImprimirEncabezado ProcesarNumeros

 Determinaremos una secuencia o procesos a seguir.


 Los procesos no necesitan ser explicados al detalle.
 Los procesos tomados en conjunto deberán resolver completamente el
problema.

ImprimirEncabezado.- Es una tarea relativamente fácil.

ProcesarNumeros.- Esta es la tarea a refinar.

 Llevar la cuenta del número de veces que se hayan completado los tres
pasos.
 Utilización de variables para el almacenamiento.

For (inicialización desde I=1; condición(I<= 5);incremento I++)


{ Proceso 2a: PedirParNumeros
Proceso 2b: LeerParDeNumeros
Proceso 2c: CompararNumerosEImprimirMensaje.
}

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 15


LENGUAJES DE PROGRAMACIÓN I

CompararParDeNumeros

ImprimirEncabezado ProcesarNumeros

PedirParDeNumeros LeerParDeNumeros CompararNumerosEImpri


mirMensaje

Prueba del diseño


 Debemos estar convencidos de que nuestra solución, expresa en términos
generales, resolverá el problema, antes de que podamos comenzar con los
detalles.
 Revisar los datos y la secuencia de los procedimientos.
 Revisar en el papel si los procesos que están fuera del for se ejecutan una
sola vez.
Refinamiento sucesivo y procesos
 El refinamiento proseguirá hasta que cada paso haya sido traducido a las
instrucciones necesarias en un lenguaje de programación.

1. ImprimirEncabezado
2. ProcesarNumeros.- se ha dividido en tres pasos:
2.1 PedirParDeNumeros
2.2 LeerParDeNumeros
2.3 CompararNumerosEImprimirMensaje
Las tres operaciones se realizan completamente por cada par de números
introducidos desde el teclado

2.1 PedirParDeNumeros.- es un proceso bastante fácil


2.2 LeerParDeNumeros.- Este proceso requiere que tengamos dos nombres de
variables uno por cada número. Primero y Segundo para nombrar las
localidades de memoria.
2.3 CompararNumerosEImprimirMensaje.- es más complicado y se muestra de
la siguiente manera:
If el número en Primero es menor que el número en Segundo
Imprimir Mensaje1
Else
Hacer más comparaciones
If el número en Primero es menor que el número en Segundo
ImprimeMensaje1
Else
If el número en Primero es Mayor que el número en Segundo
ImprimeMensaje2
Else
{
Los dos números deben ser iguales así que
ImprimeMensaje3
}

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 16


LENGUAJES DE PROGRAMACIÓN I

Este diseño detallado muestra tres procesos más.

CompararNumerosEImprimirMensaje

ImprimeMensaje1 ImprimeMensaje2 ImprimeMensaje3

Lo que sigue es el diseño de ImprimeMensaje1 (Mensaje1 se imprime cuando el


primer número es el menor). Deberán escribirse diseños similares para imprimir
los otros dos mensajes.

Imprimir una copia del número almacenado en Primero


Imprimir el mensaje: ' es menor que el segundo número'
Imprimir una copia del número almacenado en Segundo
Terminar la línea de salida (retorno de carro)

El programa PDL completo representado en una versión de alto nivel de


ComparaParDeNumeros:

Programa ComparaParDeNumeros
CUERPO DEL PROGRAMA
{operaciones de ComparaParDeNumeros
ImprimirEncabezado
ProcesarNumeros
} operaciones de CompararParDeNumeros.

 Deber:
1. Completar el PDL del ejercicio.
2. Tomar una cápsula cuatro veces al día (a intervalos regulares). Asegúrese de
tomar todas las cápsulas del frasco. No suspenda el medicamento aún si los
síntomas desaparece.
3. Suponga que el RolloAntiguo contiene un carácter, digamos @, que significa
en. También suponga que esta abreviatura ya no se usará en adelante.
Rediseñe el programa Copiar para que cada @ que aparezca en el
RolloAntiguo sea traducida como "en" en el RolloNuevo.
4. Suponga que a uno de los arqueólogos involucrados en el estudio del
RolloAntiguo le gustaría que nuestro programa Copiar reportara el número de
líneas que fueron copiadas. Rediseñe el programa Copiar para que cuente el
número de líneas copiadas, así estén vacías. Use la variable Líneas para
llevar la cuenta. Recuerde asignar el valor cero a Línea antes de comenzar la
cuenta.
5. Rediseñe el programa CompararParDeNumeros para que procese más de
cinco pares de números.

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 17


LENGUAJES DE PROGRAMACIÓN I

APLICACIÓN PRÁCTICA # 4
 Aplicación de las herramientas y de los pasos para la solución de problemas
computacionales
 Ejemplo: Dados los 3 lados de un triángulo: L1, L2 y L3 verificar si el
triángulo es Isósceles (dos lados iguales), Equilátero (tres lados iguales) o
Escaleno (tres lados distintos).

 Deber:
1. Probar si los tres lados L1, L2, L3 pertenecen o no a un triángulo: es un
triángulo si la suma de sus dos lados menores es mayor al lado mayor. Si es
triángulo identificar qué tipo de triángulo
2. Verificar si un número ingresado por teclado es o no un número primo
3. Verificar si un número ingresado por teclado es o no un número perfecto
4. Cómo se realiza un cobro de una planilla eléctrica?
5. Cómo se realiza la compra de distintos productos en un almacén

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 18


LENGUAJES DE PROGRAMACIÓN I

APLICACIÓN PRÁCTICA # 5
 Tarea de investigación: Los sistemas operativos más difundidos en el
mercado
¿QUÉ ES UN SISTEMA OPERATIVO?
Un sistema operativo es un conjunto de instrucciones que ejecuta el procesador
del sistema que tiene por misión el controlar todos los dispositivos instalados en el
sistema y permitir que los otros programas de ordenador puedan usarlos.

ESTRUCTURA DE UN SISTEMA OPERATIVO


El sistema operativo está formado por dos componentes principales:
 Núcleo
 Sistemas utilitarios.
N
U Ad. Trabajo Ad. Tareas

C
L
E Ad. Datos
Ad.
Dispositivos
O

S.O.
Editores Gráficos Programas
Utilit arios

Impresoras Format

E. Texto B. Datos Programas


Exterrnos
al
Sistema Operativo
H. Electrónicas Juegos

Administración de trabajos
En computadoras pequeñas, el sistema operativo responde a los comandos del
usuario y carga en memoria el programa de aplicación requerido para su
ejecución. En grandes computadoras, el sistema operativo lleva a cabo las
instrucciones de control de trabajos, las que pueden describir la mezcla de
programas que deben ser ejecutadas para un conjunto completo de tareas.

Administración de tareas
En computadoras monotarea, el sistema operativo no tiene virtualmente ninguna
administración de tareas que realizar, pero en computadoras multitarea es
responsable de la operación simultánea de uno o más programas. En los
sistemas operativos modernos poseen la habilidad de asignar prioridades a los
programas de modo tal que se ejecute un trabajo antes de otro (Gestionar una
cola de tareas a imprimir). Primero en entrar primero en salir.

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 19


LENGUAJES DE PROGRAMACIÓN I

Los sistemas operativos avanzados disponen de mayores capacidades para


acelerar o retardar un trabajo por medio de comandos del operador de la
computadora.

Administración de datos
Una de las funciones principales de un sistema operativo es la de llevar la cuenta
de los datos en el disco; de aquí la denominación DOS (Disk operating system
sistema operativo en disco). Los programas de aplicación no saben dónde se
encuentran almacenados los datos o cómo obtenerlos. Estos conocimientos
están contenidos en las rutinas de métodos de acceso del sistema o
controladores de dispositivos. Cuando un programa está listo para aceptar
datos, le pasa una señal al sistema operativo mediante un mensaje codificado.
El sistema operativo busca el dato y lo entrega al programa. A la inversa,
cuando el programa está listo para emitir datos, el sistema operativo transfiere
estos datos del programa al espacio disponible en el disco.

Administración de dispositivos
En teoría, el sistema operativo debe ser capaz de administrar todos los
dispositivos, no solamente los controladores de disco. Se supone que puede
manejar las entradas y las salidas a la pantalla de presentación, así como la
impresora. Manteniendo los detalles del dispositivo periférico dentro del sistema
operativo, el dispositivo puede ser reemplazado por un modelo más moderno, y
sólo debe cambiarse en el sistema operativo la rutina que se encarga de este
dispositivo.

Seguridad
Los sistemas operativos multiusuario mantienen una lista de los usuarios
autorizados y proveen protección de claves de acceso (passwords) contra los
usuarios no autorizados que pueden intentar introducirse en el sistema. Los
sistemas operativos más potentes mantienen asimismo registro de actividad del
sistema y contabilidad del tiempo del usuario con fines de facturación. También
proveen rutinas de respaldo y recuperación para comenzar nuevamente en el
caso de un fallo del sistema.

FUNCIONES DEL SISTEMA OPERATIVO


 Ordenamiento en el tiempo.
 Administración de recursos.
 Inicia y controla las operaciones de entrada/salida, manipula errores
(interrupciones).
 Coordina la comunicación entre el operador y la máquina.
 Controla el modo de programación que puede ser
 Serial.
 Tiempo compartido
 Tiempo real.
 Optimizar el rendimiento del sistema.
 Controlar el acceso de usuarios
 Permite cambiar la configuración del equipo (en DOS es el archivo
CONFIG.SYS9).

CONSIDERACIONES TÉCNICAS PARA LA SELECCIÓN DE UN SISTEMA


OPERATIVO
 El número de usuarios.

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 20


LENGUAJES DE PROGRAMACIÓN I

 El tipo de aplicaciones que se van a utilizar.


 Qué lenguajes soporta el sistema operativo.
 Que protección se va a dar a los usuarios contra accidentes, e interrupciones.
 Proporciones seguridades en cuanto al control del usuario.
 Que posee las utilidades básicas como son programas de formato, editores,
etc.

RELACIÓN DEL SISTEMA OPERATIVO, HARDWARE Y USUARIO.

2 3

4 5 6

7 8 9

10

11 12 13 14

15
1. Usuario
2. Programas utilitarios: Base de Datos
3. Hojas electrónicas.
4. Editores de texto.
5. Programas de aplicación.
6. Programas de utilidad: Lenguajes de programación.
7. Programas compiladores
8. Ensambladores
9. Cargadores
10. Sistema operativo
11. Administrador de Trabajos
12. Administrador de Tareas.
13. Administrador de Datos
14. Administrador de Dispositivos.
15. Hardware.

CONFERENCIA # 6
 Lenguaje de programación C++
 Generalidades
 Historia y desarrollo de C++
 Tarea de investigación: Componentes del IDE de C++ (composición del
menú principal)

HISTORIA Y DESARROLLO DEL C++


La historia del lenguaje de programación C++ comienza a principios de los años
70, con un programador de nombre Dennis Ritchie que trabajaba en los
laboratorios de AT&T Bell.

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 21


LENGUAJES DE PROGRAMACIÓN I

Trabajando con un lenguaje llamado BCPL inventado por Martin Richards (que
luego influyó para crear el B de Ken Thompson), Dennis deseaba un lenguaje
que le permitiese manejar el hardware de la misma manera que el ensamblador
pero con algo de programación estructurada como los lenguajes de alto nivel.
Fue entonces que creó el C que primeramente corría en computadoras PDP-7 y
PDP-11 con el sistema operativo UNIX. Pero los verdaderos alcances de lo que
sería éste, se verían poco tiempo después cuando Dennis volvió a escribir el
compilador C de UNIX en el mismo C, y luego Ken Thompson (diseñador del
sistema) escribió UNIX completamente en C y ya no en ensamblador.

Al momento de que AT&T cedió (a un precio bastante bajo) el sistema operativo


a varias universidades, el auge de C comenzaba. Cuando fueron comerciales las
computadoras personales, empezaron a diseñarse varias versiones de
compiladores C, éste se convirtió en el lenguaje favorito para crear aplicaciones.

En 1983, el Instituto Americano de Normalización (ANSI) se dio a la tarea de


estandarizar el lenguaje C, aunque esta tarea tardó 6 años en completarse, y
además con la ayuda de la Organización Internacional de Normalización (ISO),
en el año de 1989 definió el C Estándar.

A partir de éste, se dio pie para evolucionar el lenguaje de programación C. Fue


en los mismos laboratorios de AT&T Bell, que Bjarnes Stroutstrup diseñó y
desarrolló C++ buscando un lenguaje con las opciones de programación
orientada a objetos.

Ahora el desarrollo del estándar de C++ acaparaba la atención de los


diseñadores.

En el año 1995, se incluyeron algunas bibliotecas de funciones al lenguaje C. Y


con base en ellas, se pudo en 1998 definir el estándar de C++.

Algunas personas podrían pensar que entonces C++ desplazó a C, y en algunos


aspectos podría ser cierto, pero también es cierto que algunas soluciones a
problemas requieren de la estructura simple de C más que la de C++, C
generalmente es usado por comodidad para escribir controladores de
dispositivos y para programas de computadoras con recursos limitados.

La base del lenguaje fue creada por programadores y para programadores, a


diferencia de otros lenguajes como Basic o Cobol que fueron creados para que
los usuarios resolvieran pequeños problemas de sus ordenadores y el segundo
para que los no programadores pudiesen entender partes del programa.

C++ es un lenguaje de nivel medio pero no porque sea menos potente que otro,
sino porque combina la programación estructurada de los lenguajes de alto nivel
con la flexibilidad del ensamblador. La siguiente tabla muestra el lugar del
lenguaje respecto a otros.

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 22


LENGUAJES DE PROGRAMACIÓN I

Ejemplos de lenguajes estructurados:

C++ es un superconjunto de C, cualquier compilador de C++ debe ser capaz de


compilar un programa en C. De hecho la mayoría admite tanto código en C como
en C++ en un archivo. Por esto, la mayoría de desarrolladores compilan con C+
+ su código escrito en C, incluso hay quienes, siendo código en C ponen la
extensión CPP (extensión de los archivos de código C++) y lo compilan con C++.

APLICACIÓN PRÁCTICA # 7
 Familiarización y utilización del IDE de C++
 Creación de programas
 Conservación, compilación, y ejecución de un programa en el entorno de C++

CONFERENCIA # 8
 Palabras reservadas del lenguaje C++
 Tipos de datos
 Estructura de un programa en C++
 Declaración y uso de constantes en un programa

Palabras reservadas
Tienen un significado predeterminado para el compilador y sólo pueden ser usadas con
dicho sentido.
auto double int struct
break else long switch
case enum register Typedef
char extern return Union
const float short Unsigned
continue For signed void
default goto sizeof Volatile
do if static While
Además cada compilador puede añadir al conjunto de palabras estándar las
suyas de propia creación.

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 23


LENGUAJES DE PROGRAMACIÓN I

IDENTIFICADORES
Los identificadores son nombres creados para designar constantes, variables,
tipos, funciones, etc., que forman parte de un programa.

Un identificador consta de uno o más caracteres (letras, dígitos y caracteres de


subrayado); el primero debe ser una letra o el carácter _. El número de
caracteres no debe superar 31.

En C/C++ hay diferencia entre mayúsculas y minúsculas. Entre todos los


identificadores distinguimos un conjunto de ellos, predefinidos, con un
significado especial para el compilador (palabras clave).

DIAGRAMA DE SINTAXIS DE UN IDENTIFICADOR VALIDO


Letra
Identificador
Letra

Dígito

Subrayado

Tipos de datos simples


El tipo de dato determina la naturaleza del valor que puede tomar una variable.
Un tipo de dato define un dominio de valores y las operaciones que se pueden
realizar con éstos valores.

C++ dispone de unos cuantos tipos de datos predefinidos (simples) y permite al


programador crear otros tipos de datos

Tipo int
Tamaño en bytes: 2 bytes (16 bits)
Dominio: son todos los números enteros entre los valores -32.768 y 32.767
Operaciones:

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 24


LENGUAJES DE PROGRAMACIÓN I

Tipo float
Tamaño en bytes: 4 bytes
Dominio: son todos los números reales que contienen una coma decimal
comprendidos entre los valores:

Tipo double
Tamaño en bytes: 8 bytes
Dominio: son todos los números reales que contienen una coma decimal
comprendidos entre los valores:

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 25


LENGUAJES DE PROGRAMACIÓN I

Además de estas operaciones, C++ dispone de un gran conjunto de funciones


matemáticas.

Tipo bool
Tamaño en bytes: 1 byte
Dominio: dos únicos valores: { true, false }
No todos los compiladores de C++ tienen éste tipo de dato. En su lugar se
utiliza el tipo int para representar el tipo de datos bool, de forma que el valor
entero 0 representa false y cualquier otro valor representa true.

Tabla de verdad:

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 26


LENGUAJES DE PROGRAMACIÓN I

Escritura de valores bool


Raramente se tiene la necesidad de escribir o leer valores de tipo bool ya que
éste tipo de datos se utiliza sobre todo para evaluar expresiones lógicas.
En caso necesario, si escribimos un dato de tipo bool cuyo valor es true, en
consola se visualiza el valor 1.
La lectura es análoga.

Tipo char
Tamaño en bytes: 1 byte
Dominio: dígitos, letras mayúsculas, letras minúsculas y signos de puntuación.

Internamente, los caracteres se almacenan como números. El tipo char


representa valores en el rango -128 y 127 y se asocian con el código ASCII. Así,
el carácter ‘A’ se almacena como el número 65, etc. ...

0 < 1 < 2 …. < 9 < A < B < … < Z < a < b < …< z

Operaciones:
Dado que los caracteres se almacenan internamente como números enteros, se
pueden realizar operaciones aritméticas con los datos de tipo char. Se puede
sumar un entero a un carácter para obtener otro código ASCII diferente.
Ejemplos:
 Para convertir una letra minúscula en mayúscula basta con restar 32.
‘a’ - 32 = ‘A’
 Para convertir una letra mayúscula en minúscula basta con sumar 32.
‘B’ + 32 = ‘b’
 Para convertir el carácter ‘4’ en el número 4 basta con restar 48.
‘4’ - 48 = 4
Funciones:

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 27


LENGUAJES DE PROGRAMACIÓN I

Modificadores de tipos de datos


Los tipos de datos int, double y char tienen variaciones o modificadores de
tipos de datos.

Las computadoras realizan numerosas operaciones para la resolución de


problemas,
- Operaciones aritméticas y lógicas.
- Operaciones condicionales.

Además, puede ocurrir que en una misma expresión concurran varios tipos de
datos. Ante ésta situación, debemos saber cómo se comporta el compilador.

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 28


LENGUAJES DE PROGRAMACIÓN I

ESTRUCTURA DE LOS PROGRAMAS


Estructura de un programa
Un programa en C++ puede verse como un grupo de bloques construidos
llamados funciones. Una función es una o más instrucciones en C++ designadas
para una tarea específica.

#include <iostream.h>
La parte del #include se refiere a la biblioteca de funciones que vamos a utilizar.
Es decir para llamar a una biblioteca en particular debemos hacer lo siguiente:

#include <librería_solicitada>

El estándar de C++ incluye varias bibliotecas de funciones, y dependiendo del


compilador que se esté usando, puede aumentar el número.

int main(void){
Todo programa en C++ comienza con una función main(), y sólo puede haber
una.

En C++ el main() siempre regresa un entero, es por eso se antepone “int” a la


palabra “main”. Los paréntesis que le siguen contienen lo que se le va a mandar
a la función. En este caso se puso la palabra “void” que significa vacío, es decir
que a la función main no se le está mandando nada, podría omitirse el void
dentro de los paréntesis, el compilador asume que no se enviará nada. La llave
que se abre significa que se iniciará un bloque de instrucciones.

cout<<”hola mundo”<<endl;
Esta es una instrucción. La instrucción cout está definida dentro de la biblioteca
iostream.h, que previamente declaramos que íbamos a utilizar. Una función, en
este caso main() siempre comienza su ejecución con una instrucción (la que se
encuentra en la parte superior), y continúa así hasta que se llegue a la última
instrucción (de la parte inferior). Para terminar una instrucción siempre se coloca
“;”. Pero además de instrucciones se pueden invocar funciones definidas por el
usuario (por supuesto diferentes de main) como se verá más adelante.

return 0;
Esta es otra instrucción, en este caso la instrucción return determina que es lo
que se devolverá de la función main(). Habíamos declarado que main devolvería
un entero, así que la instrucción return devuelve 0. Lo cual a su vez significa que
no han ocurrido errores durante su ejecución.

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 29


LENGUAJES DE PROGRAMACIÓN I

}
La llave de cierre de la función main() indica el termino del bloque de
instrucciones.

En algunos programas de ejemplo, notará el uso de dobles diagonales (“//”).


Estas diagonales se usan para escribir comentarios de una línea dentro del
código del programa. Además podrá encontrar el uso de “/*” “*/” estos
caracteres encierran un comentario de varias líneas y cualquier cosa que se
escriba dentro de ella no influenciará en el desempeño del programa.

Directivas del preprocesador


Existen archivos de cabecera estándar muy utilizados

El uso más frecuente en C++ de las directivas del preprocesador es la inclusión


de archivos de cabecera, pero también se usan para definir macros, nombres de
constantes, etc.

Comienzan con el símbolo # y son órdenes dadas al preprocesador para efectuar


determinadas acciones sobre el fichero fuente C/C++.

El preprocesador de C es un procesador de texto que manipula el archivo que


contiene el texto del programa fuente, como una primera fase de la compilación.

Cuando se ejecuta la orden para compilar un fichero, el preprocesador procesa el


texto fuente antes de que lo haga el compilador, realizando las siguientes
acciones:
1. Se elimina caracteres dependientes del sistema.
2. El texto fuente se descompone en elementos reconocibles por el C.
3. Se ejecuta las directivas, se expanden las macros, etc..
4. Se compila el código fuente resultante.
Fuente.c

Preprocesador

Fuente_resultante.c

Compilador

Fichero.obj

Librerías
Link

fichero_ejecutable.exe

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 30


LENGUAJES DE PROGRAMACIÓN I

La función main()
Una función C++ es un subprograma que devuelve un valor, un conjunto de
valores o realiza una tarea específica.
Todo programa C++ tiene una única función main() que es el punto inicial de
entrada al programa.

DECLARACIÓN DE CONSTANTES Y VARIABLES


Constantes y variables C++
 Son porciones de memoria que almacenan un valor.
 Las variables son palabras que manipulan datos. Dicho valor puede ser
modificado en cualquier momento durante la ejecución del programa.
 Una constante es una variable cuyo valor no puede ser modificado.
 Las variables pueden almacenar todo tipo de datos: caracteres, números,
estructuras, etc … Dependiendo del valor de la variable, decimos que dicha
variable es de un tipo de dato.
 Tanto las variables como las constantes están constituidas por un nombre
y un valor. El nombre lo llamaremos identificador.

Declaración de variables
La declaración de una variable consiste en escribir una sentencia que
proporciona información al compilador de C++.
 El compilador reserva un espacio de almacenamiento en memoria.
 Los nombres de las variables se suelen escribir en minúsculas.

El procedimiento para declarar una variable:

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 31


LENGUAJES DE PROGRAMACIÓN I

Una forma de expresar el procedimiento para declarar una variable es mediante


los diagramas sintácticos:

Declaraciones locales
Son variables locales aquellas que están declaradas dentro de las funciones o de
los bloques.

Declaraciones globales ( variables globales, funciones, …) La zona de


declaraciones globales de un programa puede incluir declaraciones de variables
y declaraciones de funciones (prototipos).

Declaración de Constantes

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 32


LENGUAJES DE PROGRAMACIÓN I

Una constante es una variable cuyo valor no puede ser modificado.


Los nombres de las constantes se suelen escribir en mayúsculas.

1. Constantes declaradas const


La palabra reservada const es un calificador de tipo variable e indica que el valor
de variable no se puede modificar.

2. Constantes definidas
Se declaran mediante la directiva #define

3. Constantes enumeradas
Las constantes enumeradas permiten crear listas de elementos afines.

Ejemplo del funcionamiento de enumeraciones

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 33


LENGUAJES DE PROGRAMACIÓN I

CONFERENCIA # 9
 Uso de las variables
 Sentencia de asignación
 Operaciones básicas
 Operadores en C++
 Funciones predefinidas
 Operaciones de entrada/salida
 Ejemplo: Uso de un programa que contenga constantes y variables

Constantes de carácter no imprimibles

Declaración de variables
Todas las variables deben de ser declaradas antes de utilizarlas, aunque ciertas
declaraciones se realizan implícitamente por el contexto. Una declaración
especifica un tipo, y le sigue una lista de una o más variables de ese tipo.

Ejemplo:
int a, b;
char c;

Las variables también se pueden inicializar en su declaración.


Ejemplo:
int i = 0;
float x = 3.4;

EJEMPLO: texto completo de condolar.cpp


// Programa: CONDOLAR.CPP
// Desc. : Convierte pesos a dólares
#include <iostream.h>
void main(void){

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 34


LENGUAJES DE PROGRAMACIÓN I

int pesos;
float dolares;
cout << endl << "Cuantos pesos desea convertir a dolares? ";
cin >> pesos;
dolares = pesos / 11;
cout << "Dolares = " << dolares;
}

Una variable es una posición de memoria con nombre, empleada para guardar
un dato, que puede ser modificado durante la ejecución del programa.

Sintaxis: tipo_de_almacenamiento tipo nombre_de_variable;

Asignación:
DIAGRAMA DE SINTAXIS DE LA OPERACIÓN DE ASIGNACIÓN

Se evaluará la expresión y el resultado es asignado a la variable. El tipo


resultante de la expresión debe coincidir con el tipo de la variable.
Ejemplo: a8 a = 8;
b5+3*2 -a b = 5 + 3*2 – a;
OPERACIONES BÁSICAS
Operadores aritméticos
Operado Acción
r
- resta y menos unario
+ suma
* multiplicación
/ división
% modulo de división
-- decremento
++ incremento
Operadores relaciónales
Operador Acción
> mayor que
> = mayor que o igual que
< menor que
<= menor o igual que
== igual

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 35


LENGUAJES DE PROGRAMACIÓN I

!= no igual
Nota: El doble signo igual == es la notación de C++ para "es igual a". Este
símbolo se distingue de la condición de igualdad del simple = empleado en las
asignaciones.

Operadores lógicos
Operado Acción
r
&& and
|| or
! not
Incremento
++ Incrementa en uno
Decremento
-- Decrementa en uno

Ejemplos:

Al usar la forma de prefijo la variable se incrementa o decrementa antes de ser


usada; en la forma pos fijo la variable primero se usa y después se incrementa o
decrementa según sea el caso.

EJEMPLO: texto completo de mas_mas.cpp


//Programa : mas_mas.cpp
// Descripción: Demostración del operador unario ++
#include <iostream.h>
void main(void) {
int i;
i = 10;

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 36


LENGUAJES DE PROGRAMACIÓN I

i++;
cout << "i = " << i;
cout << "\nSalida en posfija de i++ = " << i++;
cout << "\n\Salida de i = " << i;
cout << "\nSalida prefija de ++i = " << ++i;
}

1.6 Precedencia y orden de evaluación de operadores

EJEMPLOS DE ASIGNACIONES
Operadores se asignación.

Operador Descripción Ejemplo C Pseudocódigo


++ Incremento. a ++ a  a+1
-- Decremento. a-- a  a-1
= Asignación simple. a =1 a1
*= Multiplicación más asignación. a *=5 a  a*5
/= División más asignación. a /=2 a  a/2
%= Módulo más asignación a %2 a  a%2
+= Suma más asignación. a +=2 a  a+2
-= Resta más asignación a -=3 a  a-3
&= Operación AND sobre bits más a&b aa&b
asig.
|= Operación OR sobre bits más a |= b aa|b
asig.

OPERACIONES DE ENTRADA/SALIDA.
Instrucciones de Entrada / Salida
En C++ la entrada y salida se lee y escribe en flujos. Cuando se incluye la
biblioteca iostream.h en el programa, se definen automáticamente dos flujos:

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 37


LENGUAJES DE PROGRAMACIÓN I

Esta biblioteca también nos proporciona dos operadores, uno de inserción (<<),
que inserta datos en el flujo cout y otro operador de extracción ( >> ) para
extraer valores del flujo cin y almacenarlos en variables.

C++ utiliza secuencias de escape para visualizar caracteres que no están


representados por los símbolos tradicionales.

Las más utilizadas las mostramos en la siguiente tabla:

 Deber:
1. Declaración de constantes y variables de tipo entero, float, char y string
2. Realizar un programa que lea dos número y realice el cálculo de suma, resta
multiplicación y división entre dichos números
3. Diseñar un programa que permita obtener el promedio de 4 notas

APLICACIÓN PRÁCTICA # 10
 Uso de la estructura de un programa en C++
 Declaración de constantes y variables
 Evaluación de expresiones

CONFERENCIA # 11
 Programación estructurada
 Estructura secuencial
 Estructura de selección simple (IF /ELSE)
 Omisión de la cláusula ELSE
 Sentencias compuestas

Programación estructurada
Introducción. Teorema de la programación estructurada
El principio fundamental de la programación estructurada es que en todo
momento el programador pueda mantener el programa “dentro” de la cabeza.
Esto se consigue con:
a) Un diseño descendente del programa,
b) Unas estructuras de control limitadas y
c) Un ámbito limitado de las estructuras de datos del programa.

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 38


LENGUAJES DE PROGRAMACIÓN I

Hace más fácil la escritura y verificación de programas. Se adapta perfectamente


al diseño descendente.
Para realizar un programa estructurado existen tres tipos básicos de estructuras
de control:
 Secuencial: Ejecuta una sentencia detrás de otra.
 Condicional: Se evalúa una expresión y, dependiendo del resultado, se
decide la siguiente sentencia a ejecutar.
 Iterativa: Repetimos un bloque de sentencias hasta que sea verdadera
una determinada condición.

Existe un teorema debido a que establece lo siguiente:

“Todo programa propio se puede escribir utilizando únicamente las estructuras


de control secuencial, condicional e iterativa”

Un programa propio es aquel que:


 Tiene un único punto de entrada y un único punto de salida.
 Existen caminos desde la entrada hasta la salida que pasan por todas las
partes del programa.
 Todas las instrucciones son ejecutables y no existen bucles sin fin.
 Este teorema implica que la utilización de la sentencia GOTO es totalmente
innecesaria, lo que permite eliminar esta sentencia. Un programa escrito
con GOTO es más difícil de entender que un programa escrito con las
estructuras mencionadas.

Estructura secuencial
Ejecución de sentencias una detrás de la otra. En C++, toda una estructura
secuencial se agrupa mediante los símbolos { y }.
Ejemplo:

Todo el bloque se considera una sola sentencia. Después de las llaves no se pone
punto y coma.

Estructura condicional
Alternativa simple:

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 39


LENGUAJES DE PROGRAMACIÓN I

Alternativa doble:

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 40


LENGUAJES DE PROGRAMACIÓN I

Sentencias if anidadas:
Cuando la sentencia dentro del if es otra sentencia if.

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 41


LENGUAJES DE PROGRAMACIÓN I

 Deber:
1. Diseñar un programa que permita determinar si un año es bisiesto. Un año
es bisiesto si es múltiplo de 4. Los años múltiplos de 100 no son bisiestos
salvo si ellos son también múltiplos de 400 (Ejemplo: 2000 es bisiesto, 1800
no lo es).
2. Diseñar un programa que permita ingresar una letra y decir si es no vocal
3. Encontrar el mayor de 3 números
4. Encontrar el mayor, menor y el número intermedio entre 3 números
considere también los casos en los que exista más de un número igual
5. Dada la siguiente ecuación:
AX 2  BX  C  0
Encontrar:
B 2  4 AC
X 1, X 2  B 
2A
Considere los casos:
 Si el discriminante es mayor a 0 la respuesta será dos números reales
distintos
 Si el discriminante es igual a 0 la respuesta será dos números reales
iguales
 Si el discriminante es menor a 0 la respuesta será dos números
imaginarios

CONFERENCIA # 12
 Sentencia de selección múltiple (switch)

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 42


LENGUAJES DE PROGRAMACIÓN I

Alternativa múltiple:

Pseudocódigo:

La expresión ya no es lógica, sino de tipo ordinal.

Una forma de implementar esta estructura es mediante sentencias if anidadas.

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 43


LENGUAJES DE PROGRAMACIÓN I

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 44


LENGUAJES DE PROGRAMACIÓN I

Importante resaltar la utilización de la palabra reservada ‘break’ como señal de


final de las sentencias que van con cada opción o conjunto de opciones.

 Deber:
1. Diseñar un programa que permita ingresar 3 notas valoradas cada una de
ellas sobre una nota de 20 puntos. Obtener su promedio e imprimir uno de
los siguientes mensajes:
20-19 Sobresaliente
18-16 Muy buena
15-13 Buena
12-10 Regular
09-0 Insuficiente
2. Diseñar un programa que permita ingresar un caracter e imprimir un mensaje
que diga si es vocal, consonante, cifra o carácter especial
3. Ingresar un número que se encuentre entre 1 y 31 y decir si es un número
primo o no primo
4. Simular el trabajo de una calculadora en la que se sume, reste, multiplique y
divida siempre con un número fijo cualesquiera.
5. Diseñar un programa que permita calcular las funciones trigonométricas

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 45


LENGUAJES DE PROGRAMACIÓN I

APLICACIÓN PRÁCTICA # 13
 Uso de las estructuras de selección
 IF/ELSE
 Switch
 Ejemplo: Control de los números que sean pares
 Deber
1. Pago de la factura de alquiler de un automóvil
2. La fecha de Pascua se corresponde al primer domingo después de la
primera luna llena que sigue al equinoccio de primavera y se calcula con
las siguientes expresiones
A = año mod 19
B = año mod 4
C = año mod 7
D = (19*A+24) mod 30
E = (2*B+4*C+6*D+5) mod 7
N = 22 +D+ E
En el que N indica el número del día del mes de marzo (o abril sí N es mayor
a 31) correspondiente al domingo de pascua.
3. Diseñar un programa que permita resolver un sistema de 2 ecuaciones,
verificando que no se produzca división para cero
aX + bY = C
dX + eY = F

X= ce- df/ae-bd
Y= af - cd/ae-bd

CONFERENCIA # 14
 Estructuras de repetición
 Sentencia While Do
 Reglas de funcionamiento del While do
 Sentencia do While
 Reglas de funcionamiento del do While
 Comparación de los bucles while do/ do While
 Ejemplo: Diseñar un programa que permita sumar n número enteros
positivos ingresados por el usuario y obtener su promedio utilizando While do
y do While

ESTRUCTURAS REPETITIVAS
Son aquellas que crean un bucle (repetición continua de un conjunto de
instrucciones) en la ejecución de un programa respecto de un grupo de
sentencias en función de una condición.
Las tres sentencias repetitivas de C++ son:
 SENTENCIA WHILE
 SENTENCIA DO WHILE
 SENTENCIA FOR

Cabe destacar que todos funcionan hasta que se cumple con una condición que
es la encargada de hacer parar el ciclo y continuar con el resto de instrucciones
del programa.

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 46


LENGUAJES DE PROGRAMACIÓN I

La sentencia puede no ejecutarse nunca si la condición no se cumple.


Si la condición está mal hecha, el bucle puede no acabar nunca. Es lo que se
denomina un bucle infinito

En C++ la sintaxis sería:


while (expresión lógica)
sentencia

Ejemplo:

cin >> n;
num = 1;
while (num <= n)
{
cout << num << endl;
num++;
}

Con el bucle mientras se puede construir cualquier estructura iterativa. De todas


maneras, por comodidad existen otras estructuras iterativas.

REGLAS DE FUNCIONAMIENTO DEL WHILE DO


1. Permite repetir un bloque de sentencias cero o más veces dependiendo del
valor que se evalúa para una expresión booleana.

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 47


LENGUAJES DE PROGRAMACIÓN I

2. Primero se evalúa la condición; si la expresión booleana es “verdadera” se


ejecuta el cuerpo del bucle y se vuelve a evaluar la condición.
3. El proceso se repite mientras la condición resulte cierta en cada evaluación
y termina cuando la condición evaluada es “falsa”.

Repetir (o hacer)

Repite la sentencia mientras la expresión sea cierta.

La sentencia siempre se ejecuta como mínimo una vez.

La sintaxis en C++:
do
sentencia
while (expresión lógica);

Se utiliza sobre todo en preguntas o menús, puesto que siempre se han de


ejecutar al menos una vez.

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 48


LENGUAJES DE PROGRAMACIÓN I

do
{
cout << "Introduce un entero";
cin >> i;
cout << "¿Es correcto (s/n)?";
cin >> c;
}
while (c != 's');

REGLAS DE FUNCIONAMIENTO DEL DO WHILE


1. Permite repetir un bloque de sentencias una o más veces dependiendo del
valor que se evalúa para una expresión booleana.
2. Primero se ejecuta el cuerpo del bucle y luego se evalúa la condición; si la
expresión booleana es “verdadera” se ejecuta el cuerpo del bucle.
3. El proceso se repite mientras la condición resulte verdadera en cada
evaluación y termina cuando la condición evaluada es “falsa”.

 Deber:
1. Diseñar un programa que permita encontrar la sumatoria de los n primeros
números primos
2. Diseñar un programa que permita encontrar la sumatoria de los n primeros
números perfectos. Un número es perfecto cuando es igual a la suma de
todos los números para los cuales es divisible excepto el mismo número. (6 =
1+2+3).
3. Diseñar un programa que permita realizar la operación de multiplicación de
dos números utilizando sumas sucesivas
4. Diseñar un programa que permita realizar la operación de potenciación
utilizando sumas sucesivas
5. Diseñar un programa que permita encontrar el factorial de un número

CONFERENCIA # 15
 Sentencia FOR
 Reglas de funcionamiento del FOR
 Bucles anidados
 Ejemplo: Diseñar un programa que permita generar la sumatoria de la serie:
1  2! 2  3! 3  ....  n! n
2 2 2 2
Para (o desde)
Es como una estructura mientras, pero especialmente preparada para incorporar
un contador.

Pseudocódigo
para <variable> <- <valor inicial> hasta <valor final> hacer
<sentencia>
fin_para

La variable del bucle se denomina variable de control.

Ejemplo:

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 49


LENGUAJES DE PROGRAMACIÓN I

leer n
para num 1 hasta n hacer
escribir n
fin_para

Se utiliza cuando se conocen el número de veces que se van a repetir las


sentencias.

La variable de control NO se puede modificar dentro del bucle.

Cuando el bucle acaba, el valor de la variable de control es indeterminado.

La sintaxis en C++ es:


for(inicialización; condición; incremento)
sentencia

En C++, la instrucción for es como una instrucción while, con la salvedad de


que tiene espacios especiales para poner la inicialización de la variable de
control, la condición de repetición y el incremento de la variable de control.

El incremento se realiza siempre después de ejecutar la sentencia.

Al igual que en la instrucción while, la sentencia puede no ejecutarse nunca si la


condición no se cumple.

Ejemplo:
cin >> n;
for(num = 1; num <= n; num ++)
cout << num << endl;

Se utiliza también para realizar sumatorias o productos con la ayuda de una


variable acumuladora:

Tipos de control de bucles


Existen tres formas típicas de controlar cuando se ejecuta un bucle:
a) Bucles con contador (ya vistos).
b) Bucles controlados por indicadores (banderas o flags).

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 50


LENGUAJES DE PROGRAMACIÓN I

Decir si un número introducido por teclado contiene sólo cifras menores que
cinco;

bool menor;
int num;
cin >> num;
menor = true;
while (menor && (num > 0) )
{
if (num % 10 >= 5)
menor = false;
num = num / 10;
}
if (menor)
cout << “Todas las cifras son menores que 5”;
else
cout << “Hay alguna cifra mayor o igual que 5”;

c) Bucles controlados por centinela.

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 51


LENGUAJES DE PROGRAMACIÓN I

Bucles anidados
Los bucles, al igual que las sentencias condicionales, también se pueden anidar.
Esto es especialmente útil para el manejo de matrices, como veremos en los
temas posteriores

CUÁNDO UTILIZAR WHILE DO/DO WHILE/FOR?


 Utilizar la sentencia o estructura FOR cuando se conozca el número de
iteraciones, y siempre que la variable de control de bucle sea de tipo
ordinal.
 Utilizar la estructura DO WHILE cuando el bucle se realice por lo menos
una vez.
 En todos los demás casos utilizar la sentencia WHILE.

 Deber:
1. Diseñar un programa que permita generar la sumatoria de la serie:
a ( a 1)!  a ( a  2 )!  a ( a 3)!  .......
2. Diseñar un programa que permita generar la sumatoria de la serie:
2 4 4 6 6
 2      ......
3 3 5 5 7
3. Diseñar un programa que permita generar las tablas de multiplicación
4. Imprimir todos los caracteres en minúsculas que existen entre un intervalo de
mayúsculas ejemplo: A b c d e f g H

APLICACIÓN PRÁCTICA # 16
 Uso del While do/ Do While / For
 Tarea de investigación: Consultar sobre todos los procedimientos y
funciones que se utilizan en el manejo de cadenas.
 Ejemplo:
 Diseñar un programa que permita calcular cuántas palabras existen en una
frase
 Probar si una palabra ingresada por el usuario es o no palíndromo. Una
palabra es palíndromo cuando se lee igual de derecha a izquierda que de
izquierda a derecha ejemplo Ana, Radar, Oso
Deber:

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 52


LENGUAJES DE PROGRAMACIÓN I

1. Diseñar un programa que permita calcular cuántas vocales existen en una


frase
2. Contar la incidencia de las letras en una palabra. Es decir cuantas veces se
repiten
3. En una frase contar palabras de longitud par y las de longitud impar que
existan en ella
4. Reemplazar las palabras de longitud par en una frase por asteriscos
5. Visualizar las palabras de longitud impar en una frase al revés

CONFERENCIA # 17
 Programación modular
 Diseño descendente
 Procedimientos
 Declaración de los procedimientos
 Llamada al procedimiento
 Ventajas de utilizar procedimientos
 Los parámetros: transferencia de información a/desde procedimientos
 Variables locales y globales
 Funciones definidas por el usuario
 Definición
 Llamada de funciones

Subprogramas. Funciones y procedimientos


Los subprogramas (procedimientos y funciones) constituyen una unidad de
ejecución mayor que el bloque. Proporcionan abstracción operacional al
programador y constituyen una unidad fundamental en la construcción de
programas.

Los subprogramas pueden ser vistos como un “mini” programa encargado de


resolver algorítmicamente un subproblema que se encuentra englobado dentro
de otro mayor. En ocasiones también pueden ser vistos como una
ampliación/elevación del conjunto de operaciones básicas (acciones primitivas)
del lenguaje de programación, proporcionándole un método para resolver nuevas
operaciones.

Funciones y procedimientos
Dependiendo de su utilización (llamada) podemos distinguir dos casos:

Procedimientos: encargados de resolver un problema computacional. Se les


envía los datos necesarios y produce unos resultados que devuelve al lugar
donde ha sido requerido:
int main()
{
int x = 8;
int y = 4;
ordenar(x, y);
...
}
Funciones: encargados de realizar un cálculo computacional y generar un
resultado (normalmente calculado en función de los datos recibidos) utilizable
directamente:

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 53


LENGUAJES DE PROGRAMACIÓN I

int main()
{
int x = 8;
int y = 4;
int z;
z = calcular_menor(x, y);

Definición de subprogramas
Su definición podría ser como se indica a continuación:

void ordenar(int &a, int &b)


{
if (a > b)
{
int aux = a;
a = b;
b = aux;
}
}
int calcular_menor(int a, int b)
{
int menor;
if (a < b)
{
menor = a;
}
else
{
menor = b;
}
return menor;
}

La definición de un subprograma comienza con una cabecera en la que se


especifica en primer lugar el tipo del valor devuelto por este si es una función, o
void en caso de ser un procedimiento.

A continuación vendrá el nombre del subprograma y la declaración de sus


parámetros.

El cuerpo del subprograma determina la secuencia de acciones necesarias para


resolver el problema especificado. En el caso de una función, el valor que toma
tras la llamada vendrá dado por el resultado de evaluar la expresión de la
construcción return. Aunque C++ es más flexible, y nosotros sólo permitiremos
una única utilización del return y deberá ser al final del cuerpo de la función.

Nota: la función calcular_menor anterior también podría haber sido definida de la


siguiente
forma:

int calcular_menor(int a, int b)


{

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 54


LENGUAJES DE PROGRAMACIÓN I

return ( (a < b) ? a : b ) ;
}

Normalmente la solución de un subproblema o la ejecución de una operación


dependerá del valor de algunos datos, modificará el valor de otros datos, y
posiblemente generará nuevos valores.

Todo este flujo de información se realiza a través de los parámetros o


argumentos del subprograma.

Parámetros por valor y por referencia


Llamaremos argumentos o parámetros de entrada a aquellos que se utilizan para
recibir la información necesaria para realizar la computación. Por ejemplo los
argumentos a y b de la función calcular_menor anterior.

Los argumentos de entrada se reciben por valor, que significa que son valores
que se copian desde el sitio de la llamada a los argumentos en el momento de la
ejecución del subprograma.

Se declaran especificando el tipo y el identificador asociado.

Llamaremos argumentos o parámetros de salida a aquellos que se utilizan para


transferir información producida como parte de la solución realizada por el
subprograma.

Ejemplo:
int main()
{
int cociente;
int resto;
dividir(7, 3, cociente, resto);
// ahora ’cociente’ valdrá 2 y ’resto’ valdrá 1
}

Su definición podría ser la siguiente:

void dividir(int dividendo, int divisor, int &cociente, int &resto)


{
cociente = dividendo / divisor;
resto = dividendo % divisor;
}

Así, dividendo y divisor son argumentos de entrada y son pasados “por valor”
como se vio anteriormente. Sin embargo, tanto cociente como resto son
argumentos de salida (se utilizan para devolver valores al lugar de llamada), por
lo que es necesario que se pasen por referencia que significa que ambos
argumentos serán referencias a las variables que se hayan especificado en la
llamada. Es decir, cualquier acción que se haga sobre ellas es equivalente a que
se realice sobre las variables referenciadas.

Se declaran especificando el tipo, el símbolo “ampersand” (&) y el identificador


asociado.

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 55


LENGUAJES DE PROGRAMACIÓN I

Llamaremos argumentos o parámetros de entrada/salida a aquellos que se


utilizan para recibir información necesaria para realizar la computación, y que
tras ser modificada se transfiere al lugar de llamada como parte de la
información producida resultado de la computación del subprograma. Por
ejemplo los argumentos a y b del procedimiento ordenar anterior.

Los argumentos de entrada/salida se reciben por referencia y se declaran como


se especificó anteriormente.

También es posible recibir los parámetros de entrada por referencia constante de


tal forma que el parámetro será una referencia al argumento especificado en la
llamada, tomando así su valor, pero no podrá modificarlo al ser una referencia
constante, evitando así la semántica de salida asociada al paso por referencia.
Para ello, se declaran como se especificó anteriormente para el paso por
referencia, pero anteponiendo la palabra reservada const.

int calcular_menor(const int &a, const int &b)


{
return ( (a < b) ? a : b ) ;
}

En la llamada a un subprograma, una expresión de un tipo compatible es


adecuada para un parámetro que se pase por valor, sin embargo, si el
parámetro se pasa por referencia es obligatorio que sea pasada como parámetro
actual una variable que concuerde en tipo. Si el paso es por referencia constante
((const int &x)) es posible que el parámetro actual sea una expresión de tipo
compatible.

Declaración de subprogramas
Los subprogramas, al igual que los tipos, constantes y variables, deben ser
declarados antes de ser utilizados. Dicha declaración se puede realizar de dos
formas: una de ellas consiste simplemente en definir el subprograma antes de
utilizarlo. La otra posibilidad consiste en declarar el subprograma antes de su
utilización, y definirlo posteriormente. El ámbito de visibilidad del subprograma
será global al fichero, es decir, desde el lugar donde ha sido declarado hasta el
final del fichero.

Para declarar un subprograma habrá que especificar el tipo del valor devuelto (o
void si es un procedimiento) seguido por el nombre y la declaración de los
argumentos igual que en la definición del subprograma, pero sin definir el cuerpo
del mismo. En lugar de ello se terminará la declaración con el carácter “punto y
coma” (;).

int calcular_menor(int a, int b); // declaracion de ’calcular_menor’


int main()
{
int x = 8;
int y = 4;
int z;
z = calcular_menor(x, y);
// ahora ’z’ contine el calcular_menor numero de ’x’ e ’y’

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 56


LENGUAJES DE PROGRAMACIÓN I

..............}

Ejemplo de un programa que imprime los números primos menores que


100.
//- fichero: primos1.cpp --------------------------------------------
#include <iostream>
const int MAXIMO = 100;
bool es_divisible(int x, int y)
{
return ( x % y == 0 );
}
bool es_primo(int x)
{
int i;
for (i = 2; ((i < x) && ( ! es_divisible(x, i))); ++i) {
// vacio
}
return (i >= x);
}
void escribir(int x)
{
cout << x << " ";
}
void primos(int n)
{
for (int i = 1; i < n; ++i) {
if (es_primo(i)) {
escribir(i);
}
}
cout << endl;
}
int main()
{
primos(MAXIMO);
// return 0;
}
//- fin: primos1.cpp ---------------------------------

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 57


LENGUAJES DE PROGRAMACIÓN I

FUNCIONES SIN ARGUMENTOS


Son funciones que no recogen ni devuelven ningún valor.

FUNCIONES CON ARGUMENTOS


Son funciones que recogen uno o más parámetros del mismo o distinto tipo.

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 58


LENGUAJES DE PROGRAMACIÓN I

FUNCION QUE DEVUELVE UN VALOR


#include < stdio.h >
double suma(double x, double y);
int maximo(int x, int y);
void main (void)
{ int a,b, mayor;
double x, y ,total;
x=22.2; y= 443.0;
a=1; b=2;
total = suma (x,y);
mayor= maximo (a,b);
}
double suma(double x, double y)
{
return (x+y);
}
int maximo(int x, int y)
{
// si (x>y) entonces devuelve x, sino devuelve y
return (x >y) ? x:y;
}

EJEMPLO:
#include < stdio.h >
void uno(void);

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 59


LENGUAJES DE PROGRAMACIÓN I

void dos(void);
void main (void)
{
uno( );
}
void uno( )
{
printf(“\n UNO 1”);
dos( ); // desde una función llamamos a otra función
}
void dos( )
{
printf(“\n DOS 2”);
}

Variables locales y globales


Locales
#include < stdio.h>
void fun(void);
void main (void )
{ int a,b; /* Variables locales */
a=b= 1;
printf("\n Antes de llamar a fun: a = %d, b= %d", a,b);
fun( );
printf("\n Después de llamar a fun: a = %d, b= %d",a,b);
}
void fun()
{ int a,b; // son locales a esta función
a=b=11;
printf {"\n En la función: a = %d b= %d", a,b);
}
_________________________________________________________
#include < stdio.h >
int suma(int,int);
void main(void)
{ int a,b,total; /* Variables locales */
a=b=1;
total = suma(a,b);
printf ("\n a = %d, b= %d, suma = %d",a,b,total);
}
int suma(int a, int b)
{ //a y b son locales en suma
int total;
total = a+b;
a++;
b++;
return ( total) ;
}

Globales
#include < stdio.h >
void suma(int a, int b);

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 60


LENGUAJES DE PROGRAMACIÓN I

int total; /* Variable global , declarada fuera del main */


void main (void)
{ int a,b; /* Variables locales */
a=b=1;
suma(a,b);
printf("\n a = %d, b= %d, suma = %d1”,a,b,total);
}
void suma(int a, int b )
{ /* a y b son locales en suma */
total = a+b; /* Total es variable global */
a++; b++;
}

Funciones definidas por el usuario


Una función es un bloque de código con un nombre asignado, este código es
privado a la función y no puede ser accesazo por ninguna declaración en ninguna
otra función excepto a través de argumentos y variables globales.

Las variables definidas dentro de una función son variables locales dinámicas.
(Empiezan a existir cuando la función es llamada y se destruyen al terminar).

Forma general:
especificador_tipo nombre_funcion(declaración de argumentos )
{
cuerpo de la función
}

El especificador_de_tipo especifica el tipo de valor que la función devolver


mediante el return.

La lista_de_argumentos es una lista de nombres de variables separados por


comas que recibe los valores de los argumentos cuando se llama la función.

Las funciones terminan y devuelven automáticamente al lugar que la llamo


cuando se encuentra la ultima llave o mediante la sentencia return.

EJEMPLO:texto completo de mayusculas.cpp


// Programa : mayusculas.cpp
// Convierte una cadena de caracteres a mayusculas
#include <iostream.h>
char mensaje[80] =”Esta es un prueba”;
void mayusculas(void) {
int i;
for (i = 0; mensaje[i] != '\0'; i++)
mensaje[i] = toupper(mensaje[i]);
}
int main() {
system("cls");
cout << "Programa para cambiar a mayúsculas un mensaje ";
mayusculas();

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 61


LENGUAJES DE PROGRAMACIÓN I

cout << "\nEl mensaje en mayúsculas es " << mensaje;


}

Argumentos de funciones
Hay tres tipos de argumentos para las funciones
1. Por valor
2. Por puntero
3. Por referencia

Llamada por valor


Este método copia el valor del argumento dentro de los parámetros formales de
la función y todos los cambios que sufran los parámetros no afectan el valor del
argumento usado para llamar la función. Los parámetros formales de la función
son las declaraciones de las variables que aceptan los valores de los argumentos.

EJEMPLO: texto completo de sqr.cpp


// Programa : SQR.CPP
// Descripcion: Usa una funcion que recibe y regresa un valor entero
#include <iostream.h>
int sqr(int num) {
num = num * num;
return num;
}
main() {
int n, x;
cout << "Ingresa un numero ";
cin >> n;
x = sqr(n);
cout << endl << "El cuadrado de " << n << " es " << x;
}

EJEMPLO: texto completo de cambiarf.cpp


// Prog: CambiaRf.Cpp
// Desc: Usa una funcion que intercambia los valores de sus argumentos
// utilizando paso por Referencia
#include <iostream.h>
void cambia(int &a, int &b) {
int paso;
paso = a;
a = b;
b = paso;
}
main() {
int x, y;
x = 10; y = 20;
cambia(x, y);
cout << endl << "X = " << x;
cout << endl << "Y = " << y;
}
 Deber de procedimientos:
1. Transformar un número de cualquier base a base 10

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 62


LENGUAJES DE PROGRAMACIÓN I

2. Diseñar un programa que permita encontrar cuantas palabras existen en una


frase que no contengan vocales
3. Diseñar un programa que calcule la siguiente serie:

(a! X ) a (( a  1)! X ) ( a 1) (( a  2)! X ) ( a  2)


  ....
ea e ( a 1) e ( a  2)
X Toma valores de 1 .. 5 y a indica el número de términos que deberá ser entre
3y6

4. Encontrar cuantas palabras de longitud 3 existen en una frase ingresada por


el usuario
5. Transformar la frase: La _ _ EIE _ _ _ esta _ en _ la _ _ _ _ ESPOCH.
Retirando los espacios en blanco que están de más
La _ EIE _ esta _ en _ la _ ESPOCH

 Deber de funciónes:
1. Hallar el número relativo de un número
2. Convertir un número dado en su respectivo número pero en Romanos
3. Halar el máximo común divisor entre dos números
4. Hallar la siguiente sumatoria
3 5 7
XX X X ....
3! 5! 7!
5. Cuántas palabras que tienen al menos 2 letras "a" existen en una frase
ingresada por el usuario

APLICACIÓN PRÁCTICA # 18
 Uso de procedimientos y funciones
 Ejemplo:
 Cuántas palabras palíndromo existen en una frase ingresada por el usuario:
ejemplo: El oso de Ana se llama Radar. Respuesta = Existen 3 palabras
palíndromos en al frase oso, Ana, Radar
 Deber:
1. Hallar las siguientes sumatorias:
a a  n!  a a  ( n 1)!  a a ( n  2 )! .....

2 3 5 7 11 13
1      ...
2. 2! 3! 4! 5! 6! 7!

((n * X )  1) n! (((n  1) * X )  2) ( n 1)! (((n  2) * X )  3) ( n  2 )!


   ....
3. n ( n  1) ( n  2)
Con todos los valores para X de 1 a 5

( X  1) ( X  2) ( X  3)
  2!2  3!3  ....
4. 11!1 2 3
Con todos los valores para X entre 1 y 10 y el número de términos
solamente entre 1 y 9
5. Cuántas palabras de longitud 5 existen en la frase y visualizarlas en una
línea diferente cada una

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 63


LENGUAJES DE PROGRAMACIÓN I

CONFERENCIA # 19
 Concepto de los arreglos
 Arreglos unidimensionales: Los vectores
 Operaciones con vectores
 Arreglos como parámetros en procedimientos y funciones
 Ejemplo:
 Ingresar n números en un vector, sumar y visualizar cada elemento
 Cuántos números entre a y b se encuentran almacenados en un vector
 Tarea de investigación: Consultar sobre los distintos métodos de
ordenación y búsqueda de los elementos de un vector.

Arreglos

 Un arreglo se compone de elementos de igual tamaño almacenados


linealmente en posiciones de memoria consecutiva.

 Un arreglo es un conjunto finito de posiciones de memoria consecutivas


que tienen el mismo nombre y el mismo tipo de dato. Los arreglos de una
dimensión (Unidimensionales) se llaman vectores. Los arreglos de dos
dimensiones (bidimensionales) se llaman matrices.

int A [ 7 ];
“A” es un vector de 7 elementos que C++ reconoce de la posición 0 a la 6.
Se puede “ignorar” la posición 0 y trabajar de la 1 a la 6.

int A [ 7 ] = {0,72,53,43,23,46,35};
En este caso se inicializa el valor de los elementos al momento de declarar el
vector. También puede hacerse desde el programa:
A[1] = 72;
A[2] = 53;
….etc.

 Un vector o array -arreglos en algunas traducciones- es una secuencia de


objetos del mismo tipo almacenados consecutivamente en memoria. El
tipo de objeto almacenado en el array puede ser cualquier tipo definido en
C/C++. Los vectores y matrices son pasados siempre por referencia como
argumentos de una función. La única diferencia con los tipos simples es

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 64


LENGUAJES DE PROGRAMACIÓN I

que no se usa el ‘&’ ya que basta simplemente el nombre del vector o


matriz.

Forma general de un arreglo unidimiensional:

tipo nombre_variable[tamaño]

En C++ todos los arreglos usan el cero como índice del primer elemento.

Los siguientes son dos ejemplos de declaraciones de arreglos válidas en C/C++

int CoordenadasDePantalla[5]; /*Un arreglo de 5 enteros */


char IDCompania[20]; /*Un arreglo de 20 caracteres */

En la figura 1 se muestra el primer arreglo que fue declarado con el tipo de


números enteros, llamado CoordenadasDePantalla, ocupa en memoria 5
localidades de memoria contiguas, cada una de ellas capaz de almacenar un
número entero. Actualmente es común que los números enteros sean de 32 bits,
esto hace que el arreglo CoordenadasDePantalla ocupe 32 × 5 = 160 bits

No se permite utilizar nombres de variables dentro de los corchetes. Por esto no


es posible evitar la especificación del tamaño del arreglo hasta la ejecución del
programa. La expresión debe ser un valor constante, para que el compilador
sepa exactamente cuánto espacio de memoria tiene que reservar para el arreglo.

Una buena práctica de programación es usar constantes predefinidas.

#define Coordenadas_Max 20
#define Tamano_MaX_Compania_Id 15

int CoordenadasDePantalla[Coordenadas_Max];
char IDCompania[Tamano_MaX_Compania_Id];

El uso de constantes predefinidas garantiza que futuras referencias al arreglo no


excedan el tamaño del arreglo definido.

Iniciación del arreglo


C/C++ proporciona 3 maneras de iniciar elementos del arreglo:

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 65


LENGUAJES DE PROGRAMACIÓN I

Por defecto: Cuando son creados, se aplica solamente a arreglos globales y


estáticos.
Explícita: Cuando son creados, suministrando datos de iniciación
Tiempo de ejecución: Durante la ejecución del programa cuando se asignan o
copias datos en el arreglo.

Acceso a los elementos de un arreglo


Si se tiene un error cuando se utilizan arreglos en C/C++, de seguro el error
involucra el acceso a los elementos del arreglo, por la simple razón de que el
primer elemento está en una posición 0, no 1. De manera que el último elemento
del arreglo lo encontramos en n-1, donde n es el número de elementos.

Supongamos la siguiente declaración:


int Estado[Rango_Maximo_Estado]={-1,0,1};

La siguiente sentencia tiene acceso a -1:


Estado[0];

Si escribimos Estado[3] causará un error porque no hay 4 elementos.

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 66


LENGUAJES DE PROGRAMACIÓN I

Ejemplo:
int lista[10]

El ejemplo declara un arreglo llamado lista con diez elementos desde lista[0]
hasta lista[9].

EJEMPLO: texto completo de fecha.cpp


// fecha.cpp
#include <iostream>
using namespace std;
void main() {
int fecha[3];
fecha[0] = 8; // mes
fecha[1] = 21; // dia
fecha[2] = 2003;// año
cout << "Fecha ";
cout << fecha[0] << '/' << fecha[1] << '/' << fecha[2];
}

Arreglos como argumentos de funciones

Se pueden pasar vectores como argumentos de una función

Prototipo:

tipo_devuelto NombreFun(tipo_vec nom_vec[ ]);

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 67


LENGUAJES DE PROGRAMACIÓN I

Llamada: var = NombreFun(nom_vec);

 Deber:
1. Sumar dos vectores de igual longitud
2. Sumar dos vectores de distinta longitud
3. Buscar el mayor y menor número que se encuentran almacenados en un
vector
4. Ordenar un vector
5. Reemplazar en un vector todos los números repetidos por un -5

CONFERENCIA # 20
 Arreglos multidimensionales
 Arreglos bidimensionales (Tablas)
 Declaración de arreglos bidimensionales
 Variables del tipo matriz
 Operaciones con matrices
 Matrices como parámetros en procedimientos y funciones
 Ejemplo: En una fábrica de componentes electrónicos se desea conocer la
cantidad de componentes fabricados en dos semanas consecutivas. Para
resolver este problema hay que realizar las siguientes tares:
a) Conocer cuántos tipos diferentes de componentes se fabrican y cuántos
días a la semana se trabaja
b) Leer la cantidad fabricada por cada componente en cada día laborable en
al primera semana
c) Leer la cantidad fabricada por cada componente en cada día laborable en
al segunda semana
d) Hallar la suma total en la primera semana
e) Hallar la suma total en la segunda semana

Arreglos multidimensionales
El término dimensión representa el número de índices utilizados para referirse a
un elemento particular en el arreglo. Los arreglos de más de una dimensión se
llaman arreglos multidimensionales.

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 68


LENGUAJES DE PROGRAMACIÓN I

Matrices en C++
int M [ 4 ] [ 4 ];
“M” es una matriz de 4 renglones y 4 columnas que C++ reconoce de la posición
0 a la 3.

Se puede “ignorar” la posición 0 y trabajar de la 1 a la 3.


int M [ 4 ] [ 4 ] = { 0,0,0,0,
0,5,1,9,
0,8,6,4,
0,3,7,2 };

En este caso se inicializa el valor de los elementos al momento de declarar la


matriz. También puede hacerse desde el programa:
A[1][1] = 5;
A[1][2] = 1;
….etc.

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 69


LENGUAJES DE PROGRAMACIÓN I

EJEMPLO:Matrices
#include<stdio.h>
#define M 3
#define N 2
int main(void)
{
int a[M][N]; /* matriz bidimensional */
int i, j;
for (i=0;i<M;i++) { /* lectura de cada elemento */
for (j=0;j<N;j++) {
printf(“Elemento %d,%d : “, i,j);
scanf(“%d”,&a[i][j]);
}
}
printf(“\nLa matriz introducida es:\n\n”); /* muestra cada elem */
for (i =0;i <M;i++) {
for (j =0;j <N;j++) {
printf(“%d ”,a[i][j]);
}
printf(“\n”); /* para cambiar de línea al final de cada fila */
}
}

Paso de matrices a funciones

Vector multidimensional:

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 70


LENGUAJES DE PROGRAMACIÓN I

En el prototipo hay que indicar el tamaño de todas las dimensiones, excepto la


primera

Dado que un vector no tiene tamaño predefinido, pasar su contenido como un


parámetro por valor es un costo innecesario que C/C++ no asume.

Un vector completo (a través de su referencia) se puede pasar a una función


como parámetro.

Recordemos que la referencia a un vector o la dirección inicial, se especifica


mediante su nombre, sin corchetes ni subíndices.
char caracteres[80] = “esta cadena es constante”;

foo(caracteres, longitud);

El parámetro formal debe ser definido dentro de la función, se escribirá un par
de corchetes vacíos, es decir, el tamaño del vector no se especifica.

void foo(char cadena_entrada[], int lng)

En C/C++ los arreglos en general son pasados como parámetros por referencia.
Esto es, el nombre del arreglo es la dirección del primer elemento del arreglo.

En C/C++ un elemento cualquiera de un arreglo puede ser pasado a una función


por valor o por referencia, tal y como se hace con una variable simple.

Ejemplo
float media(int a, float x[]) // Definición de la función
{ // Note que se incluyen los corchetes
// calculo de la media
// Fijese que el tamaño del vector ´x´ es pasado en ´a´
}
void main ()
{
int n;
float med;
float lista[100];

med = media(n, lista); // Esta llamada pasa como parámetros

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 71


LENGUAJES DE PROGRAMACIÓN I

// actuales la longitud del vector y


// el vector. Note que no se incluyen los
// corchetes

}

Ejemplo
#include <ctype.h>
#include <string.h>
void F1(char cadena[], int lng) {
int i;
for (i=0; i!=lng; i++)
cadena[i] = toupper(cadena[i]);
}
int main () {
char caracteres[80] = “Ejemplo”;
int longitud = strlen(caracteres);
puts(caracteres);
F1(caracteres, longitud);
puts(caracteres);
return 0;
}

Ejemplo
Diseñar un programa que calcule y escriba el área y la circunferencia de n
círculos, tal que todos n radios se deben almacenar en el vector R.

#include <stdio.h>
#define n 100
void leerRadios(float radios[], int &numEltos) {
// Parametros de salida: vector radios su numero de
elementos numEltos
int j;
printf(“¿Cuantos radios seran introducidos ?\n”);
scanf(“%i”,&numEltos);
for (j = 0; j < numEltos; j++) {
printf(“radio %i = ”);
scanf(“%i”,&radios[j]);
}
}
void AreaCirc (float radio, float &area, float &cir)
// Parametros de entrada: radio
// Parametros de salida: area y cir
{
float pi = 3.14159;
area = pi * pow(radio, 2);
cir = 2 * pi * radio;
}
void AreasCircs(float radios[], int numEltos, float
areas[], float cirs[]) {
// Parametros de entrada: vector radios
// Parametros de salida: vectores areas y cirs

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 72


LENGUAJES DE PROGRAMACIÓN I

int I;
for (I = 0; I < numEltos; I++)
AreaCirc(radios[I], areas[I], cirs[I]);
}
void escribirAreasCircs (float radios[], int numEltos, float
areas[], float cirs[]) {
int j;
for (j = 0; j < numEltos; j++) {
printf(“Para la circunferencia de radio %i”,radios[j]);
printf(“su area es: %i\n”, areas[j]);
printf(“su circunferencia es: %i\n”,cirs[j]);
}
}
int main() {
float R[n], A[n], C[n];
int nRadios;
leerRadios(R, nRadios);
AreasCircs(R, nRadios, A, C);
escribirAreasCircs (R, nRadios, A, C);
return 0;
}

 Deber:
1. Sumar dos matrices de igual dimensión
2. Sumar dos matrices de distinta longitud
3. Ingresar en una matriz las n notas de m estudiantes y encontrar el promedio
de notas por estudiante y el promedio de cada nota
4. Cuántas palabras de longitud 4 existen en una matriz
5. Diseñar un programa que simule el juego de la sopa de letras

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 73


LENGUAJES DE PROGRAMACIÓN I

CONFERENCIA # 21
 Recursividad
 Definición
 Ejemplo:
 Diseñar un programa utilizando recursividad que permita encontrar el
factorial de un número
 Diseñar un programa utilizando recursividad que permita multiplicar dos
números
 Hallar el enésimo término de la serie de fibonacci

RECURSIVIDAD
 Decimos que un objeto es recursivo si en su definición se nombra a sí mismo.

 En programación, una función es recursiva si en el ámbito de esa función hay


una llamada a sí misma, C/C++ permite esta clase de acciones. Los
algoritmos recursivos dan elegancia a las soluciones de los problemas.

 La recursividad se presenta cuando una función se invoca a si misma.

 Una función recursiva se programa simplemente para resolver los casos más
sencillos, cuando se llama a una función con un caso más complicado, se
divide el problema en dos partes, la parte que se resuelve inmediatamente y
la que necesita de más pasos, ésta última se manda de nuevo a la función,
que a su ves la divide de nuevo, y así sucesivamente hasta que se llegue al
caso base. Cuando se llega al final de la serie de llamadas, va recorriendo el
camino de regreso, hasta que por fin, presenta el resultado.

Un ejemplo clásico para este problema es calcular el factorial de un número,


(n!).

Conocemos los casos base, 0!=1, 1!=1. Sabemos que la función factorial puede
definirse como n!=n*(n−1)! . Entonces:

5! = 5*4! = 5*4*3! = 5*4*3*2! = 5*4*3*2*1! = 120.

Nuestro programa quedaría como sigue:

#include <iostream.h>
long factorial(long numero)
{
if(numero<=1)
return 1;
else
return numero*factorial(numero-1);
}
int main()
{
long numero;

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 74


LENGUAJES DE PROGRAMACIÓN I

cout<<"número para calcular el factorial:"<<endl;


cin>>numero;
cout<<"el factorial es: "<<factorial(numero)<<endl;
return 0;
}

Nuestro programa llama a la función factorial con un número inicial,


posteriormente, esta función se llama a sí misma cada vez con número más
pequeño hasta que llega al caso base (numero<=1).

1. factorial(4) := 4 * factorial(3) Se invoca a si misma y crea una segunda


variable cuyo nombre es numero y su valor es igual a 3.
2. factorial(3) := 3 * factorial(2) Se invoca a si misma y crea una tercera
variable cuyo nombre es numero y su valor es igual a 2.
3. factorial(2) := 2 * factorial(1) Se invoca a si misma y crea una cuarta
variable cuyo nombre es numero y su valor es igual a 1.
4. factorial(1) := 1 * factorial(0) Se invoca a si misma y crea una quinta
variable cuyo nombre es numero y su valor es igual a 0.
5. Como factorial(0) := 1, con éste valor se regresa a completar la
invocación: factorial(1) := 1 * 1 , por lo que factorial(1) := 1
6. Con factorial(1) := 1, se regresa a completar: factorial(2) := 2 * 1, por lo
que factorial(2) := 2
7. Con factorial(2) := 2, se regresa a completar : factorial(3) := 3 * 2, por lo
que factorial(3) := 6

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 75


LENGUAJES DE PROGRAMACIÓN I

8. Con factorial(3) := 6, se regresa a completar : factorial(4) := 4 * 6, por lo


que factorial(4) := 24 y éste será el valor que la función factorial
devolverá al módulo que la haya invocado con un valor de parámetro local
igual a 4 .

¿Cuándo utilizar la recursión?


Para empezar, algunos lenguajes de programación no admiten el uso de
recursividad, como por ejemplo el ensamblador o el FORTRAN. Es obvio que en
ese caso se requerirá una solución no recursiva (iterativa).

Tampoco se debe utilizar cuando la solución iterativa sea clara a simple vista. Sin
embargo, en otros casos, obtener una solución iterativa es mucho más
complicado que una solución recursiva, y es entonces cuando se puede plantear
la duda de si merece la pena transformar la solución recursiva en otra iterativa.

La recursión, y se basa en almacenar en una pila los valores de las variables


locales que haya para un procedimiento en cada llamada recursiva. Esto reduce
la claridad del programa. Aún así, hay que considerar que el compilador
transformará la solución recursiva en una iterativa, utilizando una pila, para
cuando compile al código del computador.

Por otra parte, casi todos los algoritmos basados en los esquemas de vuelta
atrás y divide y vencerás son recursivos, pues de alguna manera parece mucho
más natural una solución recursiva.

Aunque parezca mentira, es en general mucho más sencillo escribir un programa


recursivo que su equivalente iterativo.

La recursividad es un tema importante en el mundo de la programación, la


utilidad de este tipo de funciones se aprovecha en el diseño de algoritmos de
criptografía, de búsqueda, entre otros. La implementación de la recursividad en
nuestros programas debe de evaluarse con mucho cuidado, debemos de tratar
de evitar que se usen funciones de complejidad exponencial, que se llamen a sí
mismas una y otra vez sin que se tenga un control claro.

 Deber:
1. Cambiar un número de base 10 a base 2
2. Hallar el máximo común divisor de dos números
3. Hallar la potencia de un número
4. Sumar los n primeros números pares
5. Sumar los n primeros números impares

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 76


LENGUAJES DE PROGRAMACIÓN I

APLICACIÓN PRACTICA # 22
 Utilización de procedimientos y funciones
1. Hallar las siguientes sumatorias:
(n n )! ((n  1) ( n 1) )! ((n  2) ( n  2 ) )!
  ....
( X  n)! ( X  (n  1))! ( X  (n  2))!
Con todos los valores de X entre 1 y 5, b es un valor constantes ingresada
el usuario y n el número de términos entre 1 y 10

2. Con todos los valores de X entre 10 y 20, n el número de términos entre 1 y


5
n n 1 n2
 5( X  n)   10( X  (n  1))   15( X  ( n  2)) 
      ....
 n!   ( n  1)!   ( n  2)! 
     

3. Con todos los valores de X entre 6 y 20, n el número de términos entre 1 y 5


 X  1   X  2 2   X  3 2 ...
1! 2  2! 2  3! 2
4. Con todos los valores de X entre 2 y 7, n el número de términos entre 1 y 5

3( a  n) 6( a  ( n  1)) 9(a  (n  2))


 
 n 3
 ( n  1)  6
 ( n  2)  9

NOTA: Consultar sobre el problema de las TORRES DE HANOI. Problema que se


resuelve con recursividad.

APLICACIÓN PRÁCTICA # 23
 Uso de la recursividad
 Deber:
1. Buscar el dígito mayor en una cifra entera: ejemplo 12354 Respuesta = 5
2. Buscar el dígito menor en una cifra entera: ejemplo 12354 Respuesta = 1
3. Sumar 1234 = 10 de forma recursiva
4. Longitud de una cifra 123564 Respuesta=6 dígitos

CONFERENCIA # 24
 Tipos de datos definidos por el usuario
 Enumerados

TIPOS DE DATOS

Tipos enumerados
La declaración de un tipo enumerado es simplemente una lista de valores que
pueden ser asumidos por una variable del tipo definido. Los valores del tipo
enumerado se representan mediante identificadores que serán las constantes del
nuevo tipo.

Ejemplo:
enum dia_semana { lunes, martes, miércoles, ··· sábado, domingo};

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 77


LENGUAJES DE PROGRAMACIÓN I

Con esta declaración el tipo dia_semana es ya conocido, podremos por lo tanto,


definir variables del tipo anterior.
enum dia_semana ayer, hoy;

Estas variables pueden tomar cualquiera de los valores incluidos en la


declaración de tipo.

Sintaxis:
enum nombre_de_tipo_enumerado
{
lista de nombre de constantes enteras,
···
};
enum nombre _de_tipo_enumerado lista de variables...

Los valores asociados a los identificadores de constantes son 0 para la primera


constante, 1 para la segunda, etc., aunque con una simple asignación, cuando se
declara la constante, sirve para modificar estos enteros asociados. En el ejemplo
lunes vale 0, marte1, miércoles 2, etc.

typedef
La palabra clave typedef permite declarar nuevos nombres de tipos de datos
para tipos fundamentales o previamente definidos. Estos nuevos nombres
pueden ser utilizados para sucesivas declaraciones.

Sintaxis: typedef nombre_de_tipo nuevo_nombre_de_tipo


Ejemplo:
typedef int ENTERO;
···
ENTERO n;

Declaración simplificada de variables tipo enumeración


Las enumeraciones (variables enum) permiten definir variables de tipo entero
con un número pequeño de valores que están representados por identificadores
alfanuméricos. Estos identificadores permiten que el programa se entienda más
fácilmente, dando un significado a cada valor de la variable entera. Las variables
tipo enum son adecuadas para representar de distintas formas valores binarios
(SI o NO; VERDADERO o FALSO; EXITO o FRACASO, etc.), los días de la semana
(LUNES, MARTES, MIERCOLES, ...), los meses del año (ENERO, FEBRERO,
MARZO, ...), y cualquier conjunto análogo de posibles valores. En C las variables
de tipo enum se hacían corresponder con enteros, y por tanto no hacían nada
que no se pudiera hacer también con enteros.

La principal razón de ser de las variables enum es mejorar la claridad y facilidad


de comprensión de los programas fuente.

Por ejemplo, si se desean representar los colores rojo, verde, azul y amarillo se
podría definir un tipo de variable enum llamada color cuyos cuatro valores
estarían representados por las constantes ROJO, VERDE, AZUL Y AMARILLO,
respectivamente. Esto se puede hacer de la siguiente forma:

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 78


LENGUAJES DE PROGRAMACIÓN I

enum color {ROJO, VERDE, AZUL, AMARILLO};

Utilizar mayúsculas para los identificadores que representan constantes es una


convención estilística ampliamente adoptada. En el ejemplo anterior se ha
definido el tipo color, pero no se ha creado todavía ninguna variable con ese
tipo.

Por defecto los valores enteros asociados empiezan en 0 y van aumentando de


uno en uno. Así, por defecto, los valores asociados serán:

ROJO = 0 VERDE = 1 AZUL = 2 AMARILLO = 3

Sin embargo, el programador puede asignar el valor que desee a cada uno de
esos identificadores, asignando incluso el mismo entero a varios identificadores
diferentes. Por ejemplo, siguiendo con el tipo color:

enum color {ROJO = 3, VERDE = 5, AZUL = 7, AMARILLO};

Lógicamente en este caso los valores enteros asociados serán:


ROJO = 3 VERDE = 5 AZUL = 7 AMARILLO = 8

Cuando no se establece un entero determinado para un identificador dado, se


toma el entero siguiente al anteriormente asignado. Por ejemplo, en el caso
anterior al AMARILLO se le asigna un 8, que es el número siguiente al asignado
al AZUL.

Una vez que se ha definido un tipo enum, se pueden definir cuantas variables de
ese tipo se desee. Esta definición es distinta en C y en C++. Por ejemplo, para
definir las variables pintura y fondo, de tipo color, en C hay que utilizar la
sentencia:
enum color pintura, fondo; /* esto es C */

Mientras que en C++ bastaría hacer:

color pintura, fondo; // esto es C++

Así pues en C++ no es necesario volver a utilizar la palabra enum. Los valores
que pueden tomar las variables pintura y fondo son los que puede tomar una
variable del tipo color, es decir: ROJO, VERDE, AZUL Y AMARILLO. Se puede
utilizar, por ejemplo, la siguiente sentencia de asignación:
pintura = ROJO;

Hay que recordar que al imprimir una variable enum se imprime su valor entero
y no su valor asociado 3.

CONFERENCIA # 25
 Registros
 Declaración simplificada de variables correspondientes a estructuras
 Implantación de Registros
 Inicialización de un registro
 Asignación entre registros y paso como parámetro a un subprograma
 Uso de registros en estructuras de datos complejas

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 79


LENGUAJES DE PROGRAMACIÓN I

 Registros y Arreglos con Componentes Estructurados


 Uniones
 Arreglos de registros
 Registros con vectores

REGISTROS
• Es una estructura de datos compuesta de un número fijo de de
componentes de distintos tipos.
• También se conocen como estructuras.
• Son estructuras lineales y de longitud fija.
• Los registros, también llamados a veces por vicio del lenguaje
“estructuras”, son tipos compuestos de datos heterogéneos, es decir, que
agrupan datos que pueden ser de diferentes tipos.
• Los componentes de registros:
– Se llaman Campos.
– Pueden ser heterogéneos.
– Se designan con nombres simbólicos (nombre del campo).

Un registro es una estructura de datos compuesta de un número fijo de


componentes de distintos tipos, sus componentes se llaman campos. También se
conocen simplemente como estructuras. Son estructuras lineales y de longitud
fija, al igual que los vectores, pero difieren de estos últimos en que sus
componentes pueden ser heterogéneos y se designan con nombres simbólicos.

Declaración simplificada de variables correspondientes a estructuras


De modo análogo a lo que pasa con la palabra clave enum, en C++ no es
necesario colocar la palabra clave struct para declarar una variable del tipo de
una estructura definida por el usuario. Por ejemplo, si se define la estructura
alumno del modo siguiente:

struct alumno {
long nmat;
char nombre[41];
};

En C++ se puede declarar después una variable delegado del tipo alumno
simplemente con:

alumno delegado; // esto es C++

Mientras que en C es necesario utilizar también la palabra struct en la forma:


struct alumno delegado; /* esto es C */

Implantación de Registros
• La declaración del registro determina:
– El tamaño de los componentes.
– La posición de los componentes en el bloque de almacenamiento
durante la traducción.

La representación de almacenamiento para un registro consiste de un solo


bloque secuencial de memoria en el cual se guardan los componentes en serie.

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 80


LENGUAJES DE PROGRAMACIÓN I

Los componentes individuales pueden requerir descriptores para indicar su tipo


de dato y otros atributos, pero ordinariamente en tiempo de ejecución no se
requiere del descriptor del registro.

La selección de componentes se implanta con facilidad porque los subíndices


(nombres de campos) se conocen durante la traducción en vez de calcularse en
tiempo de ejecución.

struct persona{
char nombre[40];
int edad;
char domicilio[100];
} x;
strcpy(x.nombre,“Ana Laura”);
x.edad=22;
printf (“%s tiene %d años”, x.nombre, x.edad);
Salida: Ana Laura tiene 22 años

Consideremos por ejemplo una ficha de venta de un libro para una librería. En
ella se guarda la siguiente información:
 Titulo del libro
 Autor
 Editorial
 Número de páginas
 Precio

Toda esta información puede guardarse en una estructura de datos de tipo


registro. Para definirla se utiliza la palabra reservada struct y tiene la siguiente
sintaxis:

struct ficha{
char titulo[ ];
char autor[ ];
char editorial[ ];
int num_pag;
float precio;
};

Esta declaración debe entenderse como una declaración de tipo (de ahí el punto
y coma final) y no como un subprograma.

Para declarar una variable de tipo ficha deberemos hacerlo dentro de un


subprograma de la manera habitual:

int main(){
ficha venta;
....
return 0;
}

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 81


LENGUAJES DE PROGRAMACIÓN I

Ahora la variable venta es de tipo ficha.

A cada uno de los componentes de un registro se denomina campo. Así, los


datos titulo, autor, editorial, num_pag, precio, son los campos del registro.

Para acceder a cada uno de los campos de un registro se utiliza el operador


punto ‘.’

venta.titulo = “El conde de Montecristo”;

Inicialización de un registro
Un registro puede inicializarse en el momento de su declaración como variable:

struct dimensiones_libro{
float alto;
float ancho;
};
int main(){
dimensiones_libro dim={12.4, 20.8};
....
return 0;
}

La alternativa es la inicialización campo a campo que podemos hacer en


cualquier punto del programa:

int main(){
ficha libro;
...
libro.titulo = “El conde de Montecristo”;
libro.autor = “Alejandro Dumas”;
libro.editorial = “Aguilar”;
libro.num_pag = 324;
libro.precio = 12.35;
...
return 0;
}

Entrada y salida de registros


Tanto la entrada como la salida de un registro debe hacerse campo a campo,
siempre que el campo sea de un tipo de dato que tenga salida directa con cout o
entrada directa con cin (tipo de dato simple o tipo string).

Asignación entre registros y paso como parámetro a un subprograma


En C++ está permitida la asignación entre registros:

dimensiones_libro libroA, libroB;


libroA.alto = 13.56;
libroA.ancho = 12.56;
libroB = libroA; //ahora libroB tiene el mismo contenido que libroA

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 82


LENGUAJES DE PROGRAMACIÓN I

Como consecuencia de esta propiedad, un registro puede pasarse por valor


o por referencia como parámero a una función. Igualmente una función
puede devolver un registro.

dimensiones_libro carga_informacion(ficha &mi_libro){


dimensiones_libro dim;
cout << “Escribe titulo \n”;
cin >> mi_libro.titulo;
cout << “Escribe autor \n”;
cin >> mi_libro.autor;
cin >> mi_libro.editorial;
cout << “Escribe numero de paginas \n”;
cin >> mi_libro.num_pag;
cout << “Escribeprecio \n”;
cin >> mi_libro.precio;
cout << “Escribe centimetros de alto\n”;
cin >> dim.alto;
cout << “Escribe centimetros de ancho \n”;
cin >> dim.ancho;
return(dim);
}
int main(){
ficha libroA;
dimensiones_libro dimA;
dimA = carga_informacion(libroA);
...
return 0;
}

Uso de registros en estructuras de datos complejas


Registros con campos de registros
Un registro puede tener como campo otro registro. Para ello el registro que hace
de campo debe declararse antes que en el momento de su uso como tipo de dato
de un campo de otro registro.

struct dimensiones_libro{
float alto;
float ancho;
};

struct ficha_modif{
char titulo[ ];
char autor[ ];
char editorial[ ];
int num_pag;
float precio;
dimensiones_libro tamanyo;
};

El acceso a los campos del registro “tamanyo” se hace usando dos veces el
operador punto ‘.’
ficha_modif libro;

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 83


LENGUAJES DE PROGRAMACIÓN I

cout << “El libro mide “ << libro.tamanyo.alto << “cm de alto \n“;

El campo registro tiene todas las propiedades de los registros (asignación,...).

Registros y Arreglos con Componentes Estructurados


• Su implantación es una extensión de la representación de almacenamiento
de las estructuras simples.

En lenguajes que suministran arreglos y registros como tipos básicos de datos,


común mente se proveen de recursos para que los componentes de los dos tipos
se entremezclen con componentes de tipos elementales.
Cuando se tiene un arreglo de registros, sus componentes se seleccionan usando
una serie de operaciones de selección para elegir primero un componente del
vector y luego un componente del registro.

También se pueden tener registros cuyos componentes sean otros registros, lo


cual conduce a registros con una estructura jerárquica consistente en un nivel
superior de componentes, algunos de los cuales pueden ser registros. Los
componentes de estos componentes de segundo nivel también pueden ser
registros.

Un vector de registros tiene una representación semejante a la de un vector de


vectores, pero por cada fila sustituida por la representación de almacenamiento
de un registro.

Uniones
Otra construcción útil, aunque no muy utilizada, son las uniones, y sirven para
compactar varias entidades de diferentes tipos en la misma zona de memoria. Es
decir, todas las entidades definidas dentro de una unión compartirán la misma
zona de memoria, y por lo tanto su utilización será excluyente. Se utilizan dentro
de las estructuras:

enum Tipo { COCHE, MOTOCICLETA, BICICLETA };


struct Vehiculo {
Tipo vh;
union {
float capacidad;// para el caso de tipo COCHE
int cilindrada; // para el caso de tipo MOTOCICLETA
int talla; // para el caso de tipo BICICLETA

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 84


LENGUAJES DE PROGRAMACIÓN I

};
};

Y su utilización:

Vehiculo xx;
Vehiculo yy;
xx.vh = COCHE;
xx.capacidad = 1340.25;
yy.vh = MOTOCICLETA;
yy.cilindrada = 600;

Obviamente, los tipos de los campos de la unión pueden ser tanto simples como
compuestos.

Es responsabilidad del programador utilizar los campos adecuados en función del


tipo que se esté almacenando.

Vectores o Arreglos de registros


Esta estructura de datos es muy útil para hacer colecciones de datos. Por
ejemplo para tener los datos de todos los libros en venta de una librería,
podemos guardar las fichas de los libros en un vector.

const int MAX_TAM= 500;


ficha inventario[MAX_TAM];

La variable inventario guardaría hasta un máximo de 500 fichas de libros en


venta.

Registros con vectores


Igualmente un campo de un registro puede ser un vector o una matriz.

En nuestro ejemplo sería interesante llevar la cuenta de la ocupación útil de


nuestro vector de fichas.

Para ello se creo un registro más complejo que será:


struct titulos_en_venta{
ficha stock[MAX_TAM];
int cuantos;
};

El campo cuantos de este registro, indica el número de fichas rellenas del vector
stock.

Para listar todos los títulos disponibles podemos hacer un bucle:


titulos_en_venta oferta;

//Inicializamos oferta
for(i=0;i<oferta.cuantos;i++)
cout << oferta.stock[i].titulo;

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 85


LENGUAJES DE PROGRAMACIÓN I

CONFERENCIA # 26
 Archivos o ficheros
 Conceptos básicos de archivos
 Definiciones de datos, registros y archivos
 Apertura de archivos
 Clasificación de archivos por tipo de contenido
 Clasificación de archivos por tipo de acceso
 Direcciones lógicas y direcciones físicas
 Funciones de manejo de archivos en lenguaje c++
 Declaración del alias del archivo
 Funciones de manejo de archivos
 Aplicaciones de archivos en c++

FICHEROS

CONCEPTOS BÁSICOS DE ARCHIVOS


Esta sección presenta las generalidades relacionadas con archivos antes de
empezar a utilizarlos y programarlos. Es necesario involucrarse con la
terminología relacionada como archivo, registro, campo, etc. También es
recomendable conocer las clasificaciones generales y las operaciones
fundamentales con archivos.

¿Cómo surge la necesidad de utilizar archivos?


Hasta antes del tema de archivos, muchas de las aplicaciones que hemos
programado han sido usando la memoria principal o memoria RAM como único
medio de almacenamiento (usando variables, arreglos o estructuras de datos
mas complejas), con el inconveniente que esto representa: la volatilidad de la
memoria RAM; es decir, si se apaga la computadora se pierden los datos.
Además, algunas aplicaciones exigen transportar los datos de una computadora
a otra. De ahí surge la necesidad de almacenar dichos datos de forma
permanente que permita retenerlos en ciertos dispositivos de almacenamiento
secundario por un período de tiempo largo sin necesidad de suministrarles
energía, de tal forma que permitan transportarlos y utilizarlos en otro equipo
computacional.

Definiciones de datos, registros y archivos

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 86


LENGUAJES DE PROGRAMACIÓN I

 Datos: Básicamente se refieren a los testimonios individuales relacionados


con hechos, ya sean características de ciertos objetos de estudio o
condiciones particulares de situaciones dadas. Los elementos individuales de
los archivos se llaman datos o campos. Por ejemplo un cheque de un banco
tiene los siguientes campos: Cuenta habiente, Número de cheque, Fecha,
Persona a la que se le paga, Monto numérico, Monto con letra, Nota,
Identificación del banco, Número de cuenta y Firma. Cada campo es definido
por un tipo de dato.
 Registro: Es el conjunto completo de datos relacionados pertenecientes a
una entrada. P. ejem. Un almacén puede retener los datos de sus productos
en registros de acuerdo al formato mostrado en la figura a continuación.

El registro de la figura anterior puede ser declarado globalmente (por encima de


la función main) en el Lenguaje C++ utilizando struct:

 Archivo: En términos computacionales es una colección de datos que tiene


un nombre y se guardan en dispositivos de almacenamiento secundario, los
cuales pueden ser magnéticos, ópticos, electrónicos, etc. P. ejem. Diskettes,
discos duros, CD´s, ZIP drives, flash drives, memory sticks, etc. P. ejem. La
figura de acontinuación muestra la estructura de un archivo con registros
homogéneos de Productos (con la misma estructura) declarados
previamente.

Apertura de archivos

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 87


LENGUAJES DE PROGRAMACIÓN I

Antes de escribir o leer datos de un archivo es necesario abrirlo. Al abrir el


archivo se establece comunicación entre el programa y el sistema operativo a
cerca de cómo accesarlo. Es necesario que el programa le proporcione al sistema
operativo el nombre completo del archivo y la intención de uso (leer o escribir
datos), entonces se definen áreas de comunicación entre ellos. Una de estas
áreas es una estructura que controla el archivo (alias del archivo), de esta forma
cuando se solicita una operación del archivo, se recibe una respuesta que
informa el resultado mediante un apuntador. Cada archivo abierto requiere un
alias para poder realizar operaciones en él.

La estructura del archivo contiene información del archivo que se está usando,
así como el tamaño actual y la localización de los buffers de datos.

Clasificación de archivos por tipo de contenido


Existen muchas clasificaciones de archivos de acuerdo a diferentes criterios o
aplicaciones. Aquí se presenta una muy importante: de acuerdo al contenido.

Archivos de texto
Son aquellos que pueden contener cualquier clase de datos y de tal manera que
son “entendibles” por la gente. Los datos en un archivo de texto se almacenan
usando el código ASCII, en el cual cada carácter es representado por un simple
byte. Debido a que los archivos de texto utilizan el código ASCII, se pueden
desplegar o imprimir. En este tipo de archivos, todos sus datos se almacenan
como cadenas de caracteres, es decir, los números se almacenan con su
representación ASCII y no su representación numérica, por lo tanto no se
pueden realizar operaciones matemáticas directamente con ellos. P. ejem. Si se
guarda el dato 3.141592 en un archivo de texto, se almacena como “3.141592”
y nótese que ... 3.141592 ≠ “3.141592”

Archivos binarios
Este tipo de archivos almacenan los datos numéricos con su representación
binaria. Pueden ser archivos que contienen instrucciones en lenguaje máquina
listas para ser ejecutadas. Por ejemplo, cuando escribimos un programa en un
lenguaje en particular (como C++, Pascal, Fortran, etc), tenemos las

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 88


LENGUAJES DE PROGRAMACIÓN I

instrucciones almacenadas en un archivo de texto llamado programa fuente,


pero una vez que lo sometemos a un proceso de compilación y ejecución nuestro
programa lo trasladamos a un programa ejecutable (en lenguaje máquina), que
es directamente entendido por la computadora y se crea un archivo binario. En
este tipo de archivos también se pueden almacenar diferentes tipos de datos
incluyendo datos numéricos; sin embargo, cabe destacar que los datos
numéricos se graban con su representación binaria (no con su representación
ASCII), por tal razón, cuando se despliegan con un editor de textos o por medio
de comandos del sistema operativo, aparecen caracteres raros que no se
interpretan. P. ejem. Si se guarda el dato 27 en un archivo binario, se almacena
como 00001111 y no como “27”.

Clasificación de archivos por tipo de acceso


De acuerdo a la forma de acceder los datos de los archivos, éstos se clasifican en
secuenciales o directos (también conocidos como de acceso directo, relativos o
aleatorios). En esta sección no se pretende analizar las diferentes estructuras de
datos involucradas en estas clasificaciones de archivos ni desarrollar aplicaciones
complejas debidamente diseñadas usándolos, sino conocer esencialmente sus
conceptos teóricos y la forma de manejarlos.

Archivos secuenciales
Como su nombre lo indica, en este tipo de archivos los registros se graban en
secuencia o consecutivamente y deben accesarse de ese mismo modo, es decir,
conforme se van insertando nuevos registros, éstos se almacenan al final del
último registro almacenado; por lo tanto, cuando se desea consultar un registro
almacenado es necesario recorrer completamente el archivo leyendo cada
registro y comparándolo con el que se busca. En este tipo de archivo se utiliza
una marca invisible que el sistema operativo coloca al final de los archivos: EOF
(End of File), la cual sirve para identificar dónde termina el archivo

Consulta o recorrido secuencial


A continuación se muestra un diagrama de flujo de una rutina de consulta de un
registro en particular mediante un recorrido secuencial. En esta rutina se maneja
un archivo que almacena datos de productos (PRODUCTO.SEC) según el registro
declarado anteriormente y lo recorre completamente en forma secuencial
(registro por registro) hasta encontrar el producto solicitado.

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 89


LENGUAJES DE PROGRAMACIÓN I

Archivos directos (relativos, de acceso directo o aleatorios)


A diferencia de los archivos secuenciales, en los archivos directos no es necesario
recorrerlo completamente para acceder un registro en particular, sino se puede
colocar el apuntador interno del archivo directamente en el registro deseado,
permitiendo con esto mayor rapidez de acceso. Cabe destacar que para
reposicionar este apuntador se utiliza el comando SEEK indicándole la dirección
del registro que se desea.

Direcciones lógicas y direcciones físicas


El lenguaje C++ utiliza direcciones físicas para los archivos (a diferencia de
direcciones lógicas de otros lenguajes como PASCAL), esto es, que el
direccionamiento consiste en el espacio ocupado por los datos en el archivo
(calculado en bytes) no en el renglón al que se asignó dicho registro. P. ejem.
Suponga que tiene un archivo llamado “PRODUCTO.SEC” que almacena
registros con el formato mostrado en las figuras anteriores. Dicho registro tiene
cinco campos, cada uno con un tipo de dato determinado, un tamaño específico
y que al sumarlos se obtiene el espacio ocupado por cada registro con este
formato.

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 90


LENGUAJES DE PROGRAMACIÓN I

Cálculo de direcciones físicas


Para poder reposicionar el apuntador de un archivo en un registro específico es
necesario calcular su dirección física correspondiente de acuerdo al espacio
ocupado por sus registros predecesores.

De esta forma, para convertir direcciones lógicas en direcciones físicas se utiliza


la fórmula mostrada a continuación.

FUNCIONES DE MANEJO DE ARCHIVOS EN LENGUAJE C++


Esta sección presenta los aspectos generales de la implementación de programas
de archivos en Lenguaje C++. Aunque se puede almacenar cualquier tipo de
datos en archivos, aquí se muestran las operaciones del manejo de registros
(struct) en archivos, por lo que las funciones que se mencionan a continuación
son las mas importantes para este tipo de datos.

Declaración del alias del archivo


Para realizar programas de manejo de archivos en Lenguaje C++ se requiere el
encabezado “Standard I/O” y se necesita incluirlo de la siguiente forma:
#include <stdio.h>

Además es necesario declarar una variable de tipo FILE que opere como el
apuntador a la estructura del archivo (alias), esto se logra con la siguiente línea:
FILE *alias;
Funciones de manejo de archivos
En esta sección se presentan las funciones más importantes para el manejo y
control de registros en archivos.

La función fopen() y modos de apertura de archivos

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 91


LENGUAJES DE PROGRAMACIÓN I

Se usa la función fopen para abrir un archivo, determinar el modo de apertura y


establecer la vía de comunicación mediante su alias correspondiente.

Además determinar el tipo de contenido del archivo (texto o binario). Esta


función tiene dos argumentos: el nombre del archivo y su modo que se muestra
más adelante. La figura muestra los modos de apertura de archivos de texto y
binarios.

Validar la apertura de un archivo


Algunas funciones requieren la existencia del archivo para realizar operaciones,
por ello es necesario verificar que cuando se intenta abrir un archivo haya tenido
éxito la operación. Si un archivo no se puede abrir, la función fopen devuelve el
valor de 0 (cero), definido como NULL en stdio.h. A continuación se muestra un
ejemplo de la manera de detectar la apertura de un archivo.

#include <stdio.h>
FILE *alias;
alias = fopen(“EJEMPLO.DAT”, “rb”);

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 92


LENGUAJES DE PROGRAMACIÓN I

if (alias==NULL)
{
cout << “\n\r No se puede abrir el archivo !!!”;
getch();
return();
}

Cierre de archivos usando fclose() y fcloseall()


Antes de dejar de utilizar un archivo es necesario cerrarlo. Esto se logra
mediante las funciones fclose o fcloseall. Si se usa fclose es necesario indicarle el
alias del archivo que se desea cerrar. La función fcloseall cierra todos los
archivos abiertos.

Escritura de registros usando fwrite()


La función fwrite proporciona el mecanismo para almacenar todos los campos
de un registro en un archivo. Cabe destacar que al utilizar esta función, se
almacena una variable (de tipo struct) que representa un bloque de datos o
campos; es decir, no se almacena campo por campo. Esta función tiene cuatro
argumentos: la variable que se desea grabar, su tamaño en bytes, la cantidad
de variables y el alias del archivo donde se desea almacenar.

#include <stdio.h>

Vaciando los buffers con fflush()


Un buffer es un área de almacenamiento temporal en memoria para el conjunto
de datos leídos o escritos en el archivo. Estos buffers retienen datos en tránsito
desde y hacia al archivo y tienen la finalidad de hacer más eficiente las
operaciones de entrada/salida en los archivos de disco, provocando menor

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 93


LENGUAJES DE PROGRAMACIÓN I

cantidad de accesos, los cuales son más lentos que la memoria. P. ejem. Si se
requiere consultar constantemente un dato del archivo, no es necesario calcular
su dirección física, reposicionar el apuntador del archivo, “cargar” el dato en
memoria mediante una operación de lectura cada vez que se necesita, sino que
el sistema operativo controla y mantiene este dato en los buffers de memoria y
de ahí lo toma cuando lo requiera. Sólo hay una consideración importante al
utilizar los buffers, los datos escritos en ellos no se reflejan exactamente en los
archivos de disco en forma inmediata, sino hasta que se “vacía” el buffer. Para
ello se utiliza la función fflush y basta enviarle el alias del archivo como
argumento. Los buffers también se vacían cuando se cierra el archivo.

Lectura de registros usando fread()


La función fread permite “cargar” todos los campos de un registro en un
archivo, es decir, lee un registro y lo copia en la memoria RAM. Esta función
tiene los mismos argumentos que la función fwrite.

Reposicionando el apuntador mediante fseek()


Para comprender la operación de esta función es necesario estar relacionado con
el apuntador del archivo, el cual indica la posición dentro del archivo. Cuando se
abre un archivo en modo de sólo lectura, sólo escritura o lectura/escritura, el
apuntador del archivo se posiciona al inicio del mismo y cuando un archivo se
abre en modo agregar se posiciona al final, sin embargo, se puede reposicionar
este apuntador del archivo mediante la función fseek. También es importante
mencionar que cada vez que se realiza una operación de lectura o de escritura
de cualquier tipo de datos (caracter, cadena, estructura, etc.), el apuntador del
archivo se mueve al final de dicho dato, de tal forma que está posicionado en el
siguiente, por lo que es muy importante asegurarse que se encuentre en la
posición deseada antes de realizar cualquier operación.

Como se mencionó en las secciones anteriores los archivos en lenguaje C++ son
controlados por direcciones físicas (no lógicas) indicadas en bytes y la función
fseek permite reposicionar el apuntador del archivo en la dirección física deseada
mediante tres argumentos: el alias del archivo, la dirección física (en bytes) y el
punto de referencia. Para poder reposicionar el apuntador del archivo es
necesario que éste se encuentre abierto y se le haya asignado el alias
correspondiente, también es necesario calcular la dirección física donde se desea
colocar e indicarle el punto de referencia de donde se partirá en el conteo de la
cantidad de bytes indicado por la dirección física, los cuales pueden ser desde el
principio, desde donde se encuentre el apuntador del archivo y desde el final.

Puntos de referencia de la función fseek()


El último argumento de la función fseek es conocido como el punto de referencia
o el modo y se refiere desde dónde se iniciará el conteo de bytes determinado
por la dirección física.

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 94


LENGUAJES DE PROGRAMACIÓN I

Conociendo la posición del apuntador del archivo con la función ftell()


Se usa la función ftell para conocer la posición actual del apuntador de un
archivo abierto. La posición se expresa en bytes (dirección física) contados desde
el principio del archivo.

Detectando el final del archivo con feof()


Se usa el macro feof() (definido en stdio.h) para determinar si se ha encontrado
el final de un archivo. Si se encuentra el final de un archivo, devuelve un valor
diferente de cero y cero en caso contrario. Para invocarlo es necesario colocar el
alias del archivo abierto como argumento. Se utiliza mucho esta función en
recorridos de tipo secuencial.

Cambiando nombres de archivos mediante rename()


Esta función tiene como objetivo cambiar el nombre de un archivo o
subdirectorio especificado por su ruta de acceso. Sólo necesita dos argumentos:
el nombre anterior del archivo y el nuevo nombre. Es importante destacar
que esta función sólo puede aplicarse a archivos cerrados.

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 95


LENGUAJES DE PROGRAMACIÓN I

Eliminando archivos con la función remove()


La función remove elimina definitivamente un archivo especificando su nombre.
Es importante destacar que esta función sólo puede aplicarse a archivos
cerrados.

APLICACIONES DE ARCHIVOS EN C++


Aquí se analizarán los procedimientos de inserción, consulta y eliminación de
registros tanto en archivos secuenciales como directos, así como el listado
secuencial. En ambos tipos de archivos se tratarán como archivos binarios.

Para apoyar el análisis, diseño e implementación de estas rutinas, se tomará el


ejemplo del control de PRODUCTOS que se mencionó anteriormente así como la
definición del registro.

Declaraciones globales
Antes de analizar, diseñar e implementar las rutinas es necesario establecer las
consideraciones iniciales tales como el uso de los encabezados (*.h), las
declaraciones globales del registro de productos y el alias correspondiente. La
figura siguiente muestra las declaraciones globales necesarias para estas
aplicaciones. Para efectos de identificación, se usará el nombre
“PRODUCTO.SEC” para el archivo secuencial y el nombre “PRODUCTO.DIR”
para el archivo directo.

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 96


LENGUAJES DE PROGRAMACIÓN I

Archivos Secuenciales en Lenguaje C++


En esta sección se analizará la manera de diseñar rutinas que manipulen
registros de productos o artículos en un archivo secuencial. Como su nombre lo
indica, en este tipo de archivo se hace un recorrido secuencial para localizar la
dirección del registro solicitado, es decir, se lee registro por registro hasta llegar
al deseado.

Altas Secuenciales
Aquí se presenta una rutina que inserta registros de productos en un archivo
secuencial. Se considera un número de producto (campo no_prod) que servirá
como referencia para identificarlo y diferenciarlo de otros productos y no se
permite que se graben dos productos diferentes con el mismo número, por lo
que es necesario realizar un recorrido secuencial completo del archivo para
asegurarse que no haya duplicados.

La primera ocasión que se intente insertar registros en un archivo, éste debe


crearse; sin embargo debe cuidarse no crear el archivo cada vez que se
invoque esta rutina porque debe tenerse presente que si se crea un archivo
existente, se pierde su contenido anterior.

Codificación de la rutina de ALTAS secuenciales


A continuación se muestra el código de la rutina de ALTAS secuenciales:

void ALTA_SECUENCIAL(void)
{
int no_prod; // Variable local para el numero de producto
clrscr();
cout << "\n\rALTAS DE REGISTROS DE PRODUCTOS";
alias=fopen("PRODUCTO.SEC","rb+"); // Intenta abrir el archivo
// en modo de lectura/escritura

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 97


LENGUAJES DE PROGRAMACIÓN I

if(alias==NULL)
alias=fopen("PRODUCTO.SEC","wb"); // Crea el archivo en caso de no
// existir
cout << "\n\n\n\rNumero de producto: "; cin >> no_prod;
fread(&Registro,sizeof(Registro),1,alias);
// Lee el "Registro", de tamano=sizeof(Registro) del archivo "alias"
while(!feof(alias)) // Ciclo mientras no se encuentre el final del
// archivo
{
if(Registro.no_prod==no_prod)
{
cout << "\n\n\n\rRegistro duplicado !!!";
fclose(alias);
getch();
return;
}
fread(&Registro,sizeof(Registro),1,alias);
}
cout << "\n\rDescripcion: "; gets(Registro.descrip);
cout << "\n\rCantidad : "; cin >> Registro.cantidad;
cout << "\n\rPrecio : "; cin >> Registro.precio;
do
{
cout << "\n\rGarantia : "; Registro.garantia=toupper(getche());
}while(Registro.garantia!='S' && Registro.garantia!='N');
Registro.no_prod=no_prod;
fwrite(&Registro,sizeof(Registro),1,alias); // Grabar el Registro
fclose(alias); // Cierra el archivo
cout << "\n\n\n\rProducto registrado !!!";
cout << "\n\r<<< Oprima cualquier tecla para continuar >>>";
getch();
return;
}

CONSULTAS secuenciales
En esta sección se analiza una rutina que busca un registro particular de un
producto en un archivo secuencial. En este tipo de archivo se inicia el recorrido
desde el primer registro almacenado y se detiene cuando se localiza el registro
solicitado o cuando se encuentre el final del archivo.

Codificación de la rutina de CONSULTAS secuenciales


A continuación el código de la rutina de CONSULTAS secuenciales:

void CONSULTA_SECUENCIAL(void)
{
int no_prod;
clrscr();
cout << "\n\rCONSULTA DE REGISTROS DE PRODUCTOS";
alias=fopen("PRODUCTO.SEC","rb"); // Intenta abrir el archivo PRODUCTO.SEC
// en modo de solo lectura
if(alias==NULL)
{

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 98


LENGUAJES DE PROGRAMACIÓN I

cout << "\n\n\n\rNo existe el archivo !!!";


cout << "\n\r<<< Oprima cualquier tecla para continuar >>>";
getch();
return;
}
cout << "\n\n\n\rNumero de producto: "; cin >> no_prod;
fread(&Registro,sizeof(Registro),1,alias);

// Lee el "Registro", de tamano=sizeof(Registro) del archivo "alias"


while(!feof(alias))
{
if(Registro.no_prod==no_prod)
{
cout << "\n\rNo Prod Descripcion Cantidad Precio Garantia";
cout << "\n\r-----------------------------------------------------------------------";
printf("\n\r%3d\t%30s\t%3d\t\t$%4.2f\t%c",Registro.no_prod,Registro.descrip,
Registro.cantidad,Registro.precio,Registro.garantia);
fclose(alias);
cout << "\n\r<<< Oprima cualquier tecla para continuar >>>";
getch();
return;
}
fread(&Registro,sizeof(Registro),1,alias);
}
cout << "\n\rNo se encuentra ese registro !!!";
fclose(alias); // Cierra el archivo
cout << "\n\r<<< Oprima cualquier tecla para continuar >>>";
getch();
return;
}

LISTADO secuencial
Esta rutina es muy semejante a la de CONSULTAS secuenciales, solo que en el
LISTADO se despliegan todos los registros lógicos que contiene el archivo.

En este tipo de archivo se inicia el recorrido desde el primer registro almacenado


y se detiene cuando se encuentre el final del archivo.

Codificación de la rutina de LISTADO secuencial


A continuación el código de la rutina de LISTADO secuencial.

void LISTADO_SECUENCIAL(void)
{
clrscr();
cout << "\n\rLISTADO DE REGISTROS DE PRODUCTOS";
alias=fopen("PRODUCTO.SEC","rb"); // Intenta abrir el archivo PRODUCTO.SEC
// en modo de solo lectura
if(alias==NULL)
{
cout << "\n\n\n\rNo existe el archivo !!!";
cout << "\n\r<<< Oprima cualquier tecla para continuar >>>";

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 99


LENGUAJES DE PROGRAMACIÓN I

getch();
return;
}
cout << "\n\rNo Prod Descripcion Cantidad
Precio Garantia";
cout << "\n\r---------------------------------------------------------------------";
fread(&Registro,sizeof(Registro),1,alias);
// Lee el "Registro", de tamano=sizeof(Registro) del archivo "alias"
while(!feof(alias)) // Ciclo mientras no se encuentre el final del archivo
{
printf("\n\r%3d\t%30s\t%3d\t\t$%4.2f\t%c",Registro.no_prod,Registro.descrip,
Registro.cantidad,Registro.precio,Registro.garantia);
fread(&Registro,sizeof(Registro),1,alias);
}
fclose(alias); // Cierra el archivo
cout << "\n\r-----------------------------------------------------------------------";
cout << "\n\rFin del listado !!!";
cout << "\n\r<<< Oprima cualquier tecla para continuar >>>";
getch();
return;
}

MODIFICACIONES de datos en un archivo secuencial


La forma de modificar el contenido de los campos de registros de un archivo,
depende mucho de la rutina de consulta, ya que es necesario localizar
previamente el registro que se desea modificar, capturar los nuevos valores y
posteriormente grabar el registro completo en la misma posición que se
encontraba. Esto último es muy importante porque recuerde que cuando se
termina de leer un registro del archivo, el apuntador se posiciona al inicio del
siguiente registro, por lo que, antes de grabar el registro modificado, es
necesario reposicionar el apuntador del archivo en la dirección correcta.

Codificación de la rutina de MODIFICACIÓN secuencial


Se muestra la codificación de la rutina de modificaciones de campos de un
registro particular en un archivo secuencial.

void MODIFICACION_SECUENCIAL(void)
{
int no_prod; // Variable local para el numero de producto que desea modificar
clrscr();
cout << "\n\rMODIFICACION DE REGISTROS DE PRODUCTOS";
alias=fopen("PRODUCTO.SEC","rb+"); // Intenta abrir el archivo PRODUCTO.SEC
// en modo de lectura/escritura
if(alias==NULL) // Valida la existencia del archivo
{
cout << "\n\n\n\rNo existe el archivo !!!";
cout << "\n\r<<< Oprima cualquier tecla para continuar >>>";
getch();
return;
}
cout << "\n\n\n\rNumero de producto: "; cin >> no_prod;
fread(&Registro,sizeof(Registro),1,alias);

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 100


LENGUAJES DE PROGRAMACIÓN I

// Lee el "Registro", de tamano=sizeof(Registro) del archivo "alias"


while(!feof(alias)) // Ciclo mientras no se encuentre el final del archivo
{
if(Registro.no_prod==no_prod)
{
cout << "\n\rNo Prod Descripcion Cantidad
Precio Garantia";
cout << "\n\r-----------------------------------------------------------------------";
printf("\n\r%3d\t%30s\t%3d\t\t$%4.2f\t%c",Registro.no_prod,Registro.descrip,
Registro.cantidad,Registro.precio,Registro.garantia);
cout << "\n\n\n\rAnote los nuevos datos ...";
cout << "\n\rDescripcion: "; gets(Registro.descrip);
cout << "\n\rCantidad : "; cin >> Registro.cantidad;
cout << "\n\rPrecio : "; cin >> Registro.precio;
do
{
cout << "\n\rGarantia : "; Registro.garantia=toupper(getche());
}while(Registro.garantia!='S' && Registro.garantia!='N');
// Es necesario reposicionar el apuntador del archivo al principio del
// registro que desea modificar, ya que al leer un registro, el
// apuntador se posiciona en el registro siguiente
// La funcion ftell(alias) devuelve la posicion donde se encuentra el
// apuntador
fseek(alias,ftell(alias)-sizeof(Registro),SEEK_SET);
fwrite(&Registro,sizeof(Registro),1,alias); // Graba el registro con
// los nuevos campos
fclose(alias); // Cierra el archivo
cout << "\n\n\n\rRegistro modificado !!!";
cout << "\n\r<<< Oprima cualquier tecla para continuar >>>";
getch();
return;
}
fread(&Registro,sizeof(Registro),1,alias);
}
cout << "\n\rNo se encuentra ese registro !!!";
fclose(alias); // Cierra el archivo
cout << "\n\r<<< Oprima cualquier tecla para continuar >>>";
getch();
return;
}

Bajas de registros en un archivo secuencial (bajas lógicas y bajas


físicas)
Básicamente existen dos formas de eliminar registros en un archivo: lógica y
físicamente. La diferencia radica en que cuando se elimina un registro en forma
lógica de un archivo, sólo se le coloca una marca especial en alguno de sus
campos que lo identifique como registro “borrado”, sin embargo, el registro sigue
existiendo en el archivo y por lo tanto ocupa espacio. En cambio en la baja física
de registros, se elabora una rutina que elimine físicamente el registro del
archivo, es decir, que el archivo solo conserve los registros válidos. Las bajas
físicas también son conocidas como rutinas de compactación o compresión del
archivo.

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 101


LENGUAJES DE PROGRAMACIÓN I

Codificación de la rutina de BAJAS lógicas en un archivo secuencial


Codificación íntegra de esta rutina.
V
oid BAJA_LOGICA_SECUENCIAL(void)
{
int no_prod; // Variable local para el numero de producto que desea eliminar
char op; //Variable local
clrscr();
cout << "\n\rBAJAS LOGICAS DE REGISTROS DE PRODUCTOS";
alias=fopen("PRODUCTO.SEC","rb+"); // Intenta abrir el archivo PRODUCTO.SEC
// en modo de lectura/escritura
if(alias==NULL) // Valida la existencia del archivo
{
cout << "\n\n\n\rNo existe el archivo !!!";
cout << "\n\r<<< Oprima cualquier tecla para continuar >>>";
getch();
return;
}
cout << "\n\n\n\rNumero de producto: "; cin >> no_prod;
fread(&Registro,sizeof(Registro),1,alias);
// Lee el "Registro", de tamano=sizeof(Registro) del archivo "alias"
while(!feof(alias)) // Ciclo mientras no se encuentre el final del archivo
{
if(Registro.no_prod==no_prod)
{
cout << "\n\rNo Prod Descripcion Cantidad Precio Garantia";
cout << "\n\r----------------------------------------------------------";
printf("\n\r%3d\t%30s\t%3d\t\t$%4.2f\t
%c",Registro.no_prod,Registro.descrip,Registro.cantidad,Registro.precio,Registr
o.garantia);
Registro.no_prod=0;
strcpy(Registro.descrip,"");
Registro.cantidad=0;
Registro.precio=0.0;
Registro.garantia=' ';
do {
cout << "\n\n\rEsta seguro que desea borrarlo? [S/N] ---> ";
op=toupper(getche());
}while(op!='S' && op!='N');
if(op=='S')
{
// Es necesario reposicionar el apuntador del archivo al principio del
// registro que desea modificar, ya que al leer un registro, el
// apuntador se posiciona en el registro siguiente
// La funcion ftell(alias) devuelve la posicion donde se encuentra el
// apuntador
fseek(alias,ftell(alias)-sizeof(Registro),SEEK_SET);
fwrite(&Registro,sizeof(Registro),1,alias); // Graba el registro con
// los nuevos campos
cout << "\n\n\n\rRegistro eliminado !!!";
}

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 102


LENGUAJES DE PROGRAMACIÓN I

fclose(alias); // Cierra el archivo


cout << "\n\r<<< Oprima cualquier tecla para continuar >>>";
getch();
return;
}
fread(&Registro,sizeof(Registro),1,alias);
}
cout << "\n\rNo se encuentra ese registro !!!";
fclose(alias); // Cierra el archivo
cout << "\n\r<<< Oprima cualquier tecla para continuar >>>";
getch();
return;
}

Codificación de la rutina de BAJAS físicas en un archivo secuencial


(compactar)
Codificación íntegra de esta rutina.

void BAJA_FISICA_SECUENCIAL(void)
{
FILE *temporal; //Declaracion local de una variable para controlar el
// archivo temporal
clrscr();
cout << "\n\rBAJAS FISICAS DE REGISTROS DE PRODUCTOS";
alias=fopen("PRODUCTO.SEC","rb"); // Intenta abrir el archivo PRODUCTO.SEC
// en modo de solo lectura
if(alias==NULL) // Valida la existencia del archivo
{
cout << "\n\n\n\rNo existe el archivo !!!";
cout << "\n\r<<< Oprima cualquier tecla para continuar >>>";
getch();
return;
}
temporal=fopen("TEMPORAL.TMP","wb"); // Crea el archivo TEMPORAL.TMP
fread(&Registro,sizeof(Registro),1,alias);
// Lee el "Registro", de tamano=sizeof(Registro) del archivo "alias"
while(!feof(alias)) // Ciclo mientras no se encuentre el final del archivo
{
if(Registro.no_prod!=0)
fwrite(&Registro,sizeof(Registro),1,temporal);
// Graba el registro valido en el archivo temporal
fread(&Registro,sizeof(Registro),1,alias);
}
fcloseall(); // Cierra todos los archivos abiertos
remove("PRODUCTO.SEC"); //Elimina el archivo original
rename("TEMPORAL.TMP","PRODUCTO.SEC");
//Renombra el archivo temporal con el nombre del archivo original
cout << "\n\n\n\rArchivo compactado !!!";
cout << "\n\r<<< Oprima cualquier tecla para continuar >>>";
getch();

Archivos directos en Lenguaje C++

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 103


LENGUAJES DE PROGRAMACIÓN I

En esta sección se analizará la manera de diseñar rutinas que manipulen


registros de productos o artículos en un archivo directo. A diferencia del archivo
secuencial en el que se hace un recorrido secuencial para localizar la dirección
del registro solicitado, en el archivo de acceso directo, se calcula la dirección
física y se posiciona el apuntador del archivo directamente en el registro
solicitado usando la función fseek.

Altas Directas
Aquí se presenta una rutina que inserta registros de productos en un archivo
directo. Se tomará el mismo ejemplo del registro de producto que se usó en el
archivo secuencial. En este caso se nombrará el archivo como
“PRODUCTO.DIR”

La primera ocasión que se intente insertar registros en un archivo, éste debe


crearse; sin embargo debe cuidarse no crear el archivo cada vez que se
invoque esta rutina porque debe tenerse presente que si se crea un archivo
existente, se pierde su contenido anterior.

Codificación de la rutina de Altas directas


Codificación de la rutina de altas en un archivo relativo o de acceso directo.
void ALTA_DIRECTA(void)
{
int no_prod; // Variable local para el numero de producto
clrscr();
cout << "\n\rALTAS DE REGISTROS DE PRODUCTOS";
alias=fopen("PRODUCTO.DIR","rb+"); // Intenta abrir el archivo PRODUCTO.DIR
// en modo de lectura/escritura
if(alias==NULL)
alias=fopen("PRODUCTO.DIR","wb"); // Crea el archivo en caso de no existir
cout << "\n\n\n\rNumero de producto: "; cin >> no_prod;
dir_fisica=no_prod*sizeof(Registro); // Calculo de la dir. fisica
fseek(alias,dir_fisica,SEEK_SET); //Posicionar el apuntador del archivo
fread(&Registro,sizeof(Registro),1,alias);
// Lee el "Registro", de tamano=sizeof(Registro) del archivo "alias"
if(Registro.no_prod==no_prod)
{
cout << "\n\n\n\rRegistro duplicado !!!";
fclose(alias);
getch();
return;
}
cout << "\n\rDescripcion: "; gets(Registro.descrip);
cout << "\n\rCantidad : "; cin >> Registro.cantidad;
cout << "\n\rPrecio : "; cin >> Registro.precio;
do
{
cout << "\n\rGarantia : "; Registro.garantia=toupper(getche());
}while(Registro.garantia!='S' && Registro.garantia!='N');
Registro.no_prod=no_prod;
fseek(alias,dir_fisica,SEEK_SET); //Posicionar el apuntador del archivo
fwrite(&Registro,sizeof(Registro),1,alias); // Grabar el Registro completo
fclose(alias); // Cierra el archivo

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 104


LENGUAJES DE PROGRAMACIÓN I

cout << "\n\n\n\rProducto registrado !!!";


cout << "\n\r<<< Oprima cualquier tecla para continuar >>>";
getch();
return;
}

CONSULTAS directas
En esta sección se analiza una rutina que busca un registro particular de un
producto en un archivo directo. En este tipo de archivo no es necesario hacer el
recorrido secuencial desde el primer registro almacenado, sino se calcula la
dirección física del registro que se desea consultar y se posiciona el apuntador
del archivo directamente.

Codificación de la rutina de CONSULTAS directas


Código de la rutina de CONSULTAS directas

void CONSULTA_DIRECTA(void)
{
int no_prod; // Variable local para el numero de producto que desea consultar
clrscr();
cout << "\n\rCONSULTA DE REGISTROS DE PRODUCTOS";
alias=fopen("PRODUCTO.DIR","rb"); // Intenta abrir el archivo PRODUCTO.DIR
// en modo de solo lectura
if(alias==NULL)
{
cout << "\n\n\n\rNo existe el archivo !!!";
cout << "\n\r<<< Oprima cualquier tecla para continuar >>>";
getch();
return;
}
cout << "\n\n\n\rNumero de producto: "; cin >> no_prod;
dir_fisica=no_prod*sizeof(Registro); // Calculo de la dir. fisica
fseek(alias,dir_fisica,SEEK_SET); //Posicionar el apuntador del archivo
fread(&Registro,sizeof(Registro),1,alias);
// Lee el "Registro", de tamano=sizeof(Registro) del archivo "alias"
if(Registro.no_prod==no_prod)
{
cout << "\n\rNo Prod Descripcion Cantidad Precio Garantia";
cout << "\n\r----------------------------------------------------------------------";
printf("\n\r%3d\t%30s\t%3d\t\t$%4.2f\t
%c",Registro.no_prod,Registro.descrip,Registro.cantidad,Registro.precio,Registr
o.garantia);
}
else
{
cout << "\n\n\n\rNo existe ese registro !!!";
}
fclose(alias);
cout << "\n\n\n\n\r<<< Oprima cualquier tecla para continuar >>>";
getch();
return;
}

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 105


LENGUAJES DE PROGRAMACIÓN I

MODIFICACIONES directas
Al igual que en el archivo secuencial, la forma de modificar el contenido de los
campos de registros de un archivo, depende mucho de la rutina de consulta, ya
que es necesario localizar previamente el registro que se desea modificar,
capturar los nuevos valores y posteriormente grabar el registro completo en
la misma posición que se encontraba. Esto último es muy importante porque
recuerde que cuando se termina de leer un registro del archivo, el apuntador se
posiciona al inicio del siguiente registro, por lo que, antes de grabar el registro
modificado, es necesario reposicionar el apuntador del archivo en la dirección
correcta.

Codificación de la rutina de MODIFICACIONES directas


Codificación de la rutina de modificaciones de campos de un registro particular
en un archivo directo.

void MODIFICACION_DIRECTA(void)
{
int no_prod; // Variable local para el numero de producto que desea modificar
clrscr();
cout << "\n\rMODIFICACION DE REGISTROS DE PRODUCTOS";
alias=fopen("PRODUCTO.DIR","rb+"); // Intenta abrir el archivo PRODUCTO.DIR
// en modo de lectura/escritura
if(alias==NULL) // Valida la existencia del archivo
{
cout << "\n\n\n\rNo existe el archivo !!!";
cout << "\n\r<<< Oprima cualquier tecla para continuar >>>";
getch();
return;
}
cout << "\n\n\n\rNumero de producto: "; cin >> no_prod;
dir_fisica=no_prod*sizeof(Registro); // Calculo de la dir. fisica
fseek(alias,dir_fisica,SEEK_SET); //Posicionar el apuntador del archivo
fread(&Registro,sizeof(Registro),1,alias);
// Lee el "Registro", de tamano=sizeof(Registro) del archivo "alias"
if(Registro.no_prod==no_prod)
{
cout << "\n\rNo Prod Descripcion Cantidad
Precio Garantia";
cout << "\n\r------------------------------------------------------------------------";
printf("\n\r%3d\t%30s\t%3d\t\t$%4.2f\t
%c",Registro.no_prod,Registro.descrip,Registro.cantidad,Registro.precio,Registr
o.garantia);
cout << "\n\n\n\rAnote los nuevos datos ...";
cout << "\n\rDescripcion: "; gets(Registro.descrip);
cout << "\n\rCantidad : "; cin >> Registro.cantidad;
cout << "\n\rPrecio : "; cin >> Registro.precio;
do
{
cout << "\n\rGarantia : "; Registro.garantia=toupper(getche());
}while(Registro.garantia!='S' && Registro.garantia!='N');
// Es necesario reposicionar el apuntador del archivo al principio del

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 106


LENGUAJES DE PROGRAMACIÓN I

// registro que desea modificar, ya que al leer un registro, el


// apuntador se posiciona en el registro siguiente
// La funcion ftell(alias) devuelve la posicion donde se encuentra el
// apuntador
fseek(alias,dir_fisica,SEEK_SET); //Posicionar el apuntador del archivo
fwrite(&Registro,sizeof(Registro),1,alias); // Graba el registro con
// los nuevos campos
fclose(alias); // Cierra el archivo
cout << "\n\n\n\rRegistro modificado !!!";
cout << "\n\r<<< Oprima cualquier tecla para continuar >>>";
getch();
return;
}
else
{
cout << "\n\n\n\rNo se encuentra ese registro !!!";
}
fclose(alias); // Cierra el archivo
cout << "\n\n\n\n\r<<< Oprima cualquier tecla para continuar >>>";
getch();
return;
}

Bajas de registros en un archivo de acceso directo (bajas lógicas)


Para el ejemplo que se ha estado manejando en este archivo directo, NO se
pueden realizar bajas físicas (únicamente bajas lógicas), ya que existe una
relación directa entre la dirección lógica y el número del producto: esto es, que el
producto 1 se almacena en el registro lógico 1, o sea que cada producto se
almacena en su respectivo registro de acuerdo al número de producto y si se
aplicase la rutina de bajas físicas (compactación), los registros se recorrerían a
otras direcciones que no corresponderían con su número de producto y dichos
registros no podrían ser localizados por las rutinas de consultas, modificaciones y
las mismas bajas lógicas.

Al igual que en las bajas lógicas de los archivos secuenciales, cuando se elimina
un registro en forma lógica de un archivo, sólo se le coloca una marca especial
en alguno de sus campos que lo identifique como registro “borrado”, sin
embargo, el registro sigue existiendo en el archivo y por lo tanto ocupa espacio.

Codificación de la rutina de BAJAS lógicas directas


Rutina de bajas lógicas en un archivo directo.

void BAJA_LOGICA_DIRECTA(void)
{
int no_prod; // Variable local para el numero de producto que desea eliminar
char op;
clrscr();
cout << "\n\rBAJA LOGICA DE REGISTROS DE PRODUCTOS";
alias=fopen("PRODUCTO.DIR","rb+"); // Intenta abrir el archivo PRODUCTO.DIR
// en modo de lectura/escritura
if(alias==NULL) // Valida la existencia del archivo
{

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 107


LENGUAJES DE PROGRAMACIÓN I

cout << "\n\n\n\rNo existe el archivo !!!";


cout << "\n\r<<< Oprima cualquier tecla para continuar >>>";
getch();
return;
}
cout << "\n\n\n\rNumero de producto: "; cin >> no_prod;
dir_fisica=no_prod*sizeof(Registro); // Calculo de la dir. fisica
fseek(alias,dir_fisica,SEEK_SET); //Posicionar el apuntador del archivo
fread(&Registro,sizeof(Registro),1,alias);
// Lee el "Registro", de tamano=sizeof(Registro) del archivo "alias"
if(Registro.no_prod==no_prod)
{
cout << "\n\rNo Prod Descripcion Cantidad
Precio Garantia";
cout << "\n\r------------------------------------------------------------------------";
printf("\n\r%3d\t%30s\t%3d\t\t$%4.2f\t
%c\n\n\n\n\r",Registro.no_prod,Registro.descrip,Registro.cantidad,Registro.prec
io,Registro.garantia);
Registro.no_prod=0;
strcpy(Registro.descrip,"");
Registro.cantidad=0;
Registro.precio=0.0;
Registro.garantia=' ';
// Es necesario reposicionar el apuntador del archivo al principio del
// registro que desea modificar, ya que al leer un registro, el
// apuntador se posiciona en el registro siguiente
// La funcion ftell(alias) devuelve la posicion donde se encuentra el
// apuntador
do
{
cout << "\n\rEsta seguro que desea eliminar este registro? [S/N] ---> ";
op=toupper(getche());
}while(op!='S' && op!='N');
if(op=='S')
{
fseek(alias,dir_fisica,SEEK_SET); //Posicionar el apuntador del archivo
fwrite(&Registro,sizeof(Registro),1,alias); // Graba el registro con
// los nuevos campos
cout << "\n\n\n\rRegistro eliminado logicamente !!!";
}
else
{
cout << "\n\n\n\rRegistro NO eliminado !!!";
}
fclose(alias); // Cierra el archivo
cout << "\n\r<<< Oprima cualquier tecla para continuar >>>";
getch();
return;
}
else
{
cout << "\n\n\n\rNo se encuentra ese registro !!!";

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 108


LENGUAJES DE PROGRAMACIÓN I

}
fclose(alias); // Cierra el archivo
cout << "\n\n\n\n\r<<< Oprima cualquier tecla para continuar >>>";
getch();
return;
}

Carrera Ingeniería En Electrónica Telecomunicaciones Y Redes Página: N° 109