0% encontró este documento útil (0 votos)
34 vistas57 páginas

Métodos de Programación Básica

El documento aborda diversos aspectos fundamentales de la programación, incluyendo definiciones, historia, tipos de lenguajes, y paradigmas. Se exploran conceptos como algoritmos, diagramas de flujo, programación modular, estructuras de control, y programación orientada a objetos. Además, se discuten lenguajes de bajo y alto nivel, así como la evolución histórica de la programación desde sus inicios hasta la actualidad.

Cargado por

damian bertamoni
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
34 vistas57 páginas

Métodos de Programación Básica

El documento aborda diversos aspectos fundamentales de la programación, incluyendo definiciones, historia, tipos de lenguajes, y paradigmas. Se exploran conceptos como algoritmos, diagramas de flujo, programación modular, estructuras de control, y programación orientada a objetos. Además, se discuten lenguajes de bajo y alto nivel, así como la evolución histórica de la programación desde sus inicios hasta la actualidad.

Cargado por

damian bertamoni
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd

METODOS DE PROGRAMACION

MODULO II

Contenido

TEMA 1. INTRODUCCIÓN A LA PROGRAMACIÓN ................................................................................


4
1.1 Algunas definiciones y conceptos importantes: ................................................................. 4
1.2 Historia de la Programación ................................................................................................ 5
1.3 Tipos de lenguajes de programación .................................................................................. 8
1.4 Paradigmas de la programación .......................................................................................... 9
1.4.1 Programación Imperativa ...................................................................................................
9
1.4.2 Programación Orientada por Objeto................................................................................ 10
1.5 Programación Estructurada .............................................................................................. 11
1.5.1 Definición de las estructuras básicas de control lógico ................................................... 11
1.6 Lenguajes de Programacion Pascal y C++ ......................................................................... 13
1.7 Diagramas de Flujo ............................................................................................................ 13
1.7.1 Símbolos y operadores de los diagramas de flujo ..................................................... 14
1.7.2 Reglas para la construcción de un diagrama de flujo ...................................................... 16
1.8 Uso de pseudocódigo ........................................................................................................ 16
1.9 Compilador Dev C++ .......................................................................................................... 18
1.10 El p ヴ i マ e ヴ p ヴ og ヴ a マ a さ Hola Mu ミ do ざ e ミ C++ ....................................................................... 20
1.11 Ejercicios ............................................................................................................................ 22
TEMA 2. ESTRUCTURAS DE CONTROL. ..............................................................................................
25
2.1 Secuencia, Condición y Ciclos de Repetición .................................................................... 25
2.1.1 Secuencia ................................................................................................................... 25
2.1.2 Bifurcación Condicional ............................................................................................. 25
2.1.3 Ciclos De Repetición .................................................................................................. 27
2.2 Tipos de Datos y Variables ................................................................................................ 30
2.2.1 Tipos de datos ........................................................................................................... 30
2.2.2 Variables .................................................................................................................... 31
2.3 Uso de comentarios en programación .............................................................................. 32
TEMA 3. PROGRAMACIÓN MODULAR (FUNCIONES Y PROCEDIMIENTOS) ...................................... 33
3.1 Introducción ...................................................................................................................... 33
3.2 Funciones .......................................................................................................................... 33
3.3 Procedimientos ................................................................................................................. 35
3.4 Paso de parámetros por referencia .................................................................................. 36
TEMA 4. VECTORES Y MATRICES .......................................................................................................
38
4.1 Vectores ............................................................................................................................ 38
4.2 Matrices ............................................................................................................................. 40
4.3 Estructuras ........................................................................................................................ 43
TEMA 5. PUNTEROS Y MEMORIAS DINAMICAS ................................................................................
45
5.1 Introducción ...................................................................................................................... 45
5.2 Aritmética de punteros ..................................................................................................... 46
5.3 Comparación de punteros ................................................................................................. 47
5.4 Vectores Dinámicos ........................................................................................................... 48
TEMA 6. PROGRAMACION ORIENTADA A OBJETOS. .........................................................................
49
6.1 Que es la programación orientada a objetos? .................................................................. 49
6.2 Definición de clase ............................................................................................................ 50
6.3 Definición de objeto .......................................................................................................... 52
6.4 Herencia ............................................................................................................................ 54
6.5 Polimorfismo ..................................................................................................................... 56
6.6 Sobrecarga ......................................................................................................................... 57
6.7 Declaración de clases en C++ ............................................................................................ 57
6.7.1. Especificadores de acceso ......................................................................................... 58
6.7.2 Operador de resolución de ambito ........................................................................... 60
6.7.3 El apuntador this ....................................................................................................... 61
TEMA 1. INTRODUCCIÓN A LA PROGRAMACIÓN

1.1 Algunas definiciones y conceptos importantes:

¿Qué es un Algoritmo?

En matemáticas, ciencias de la computación y disciplinas relacionadas, un algoritmo es un conjunto


preescrito de instrucciones o reglas bien definidas, ordenadas y finitas que permite realizar una
actividad mediante pasos sucesivos que no generen dudas a quien deba realizar dicha actividad.

Dados un estado inicial y una entrada, siguiendo los pasos sucesivos se llega a un estado final y se
obtiene una solución.

En la vida cotidiana, se emplean algoritmos frecuentemente para resolver problemas. Algunos


ejemplos son los manuales de usuario, que muestran algoritmos para usar un aparato, o las
instrucciones que recibe un trabajador por parte de su patrón. Algunos ejemplos en matemática
son el algoritmo de la división para calcular el cociente de dos números, el algoritmo de Euclides
para obtener el máximo común divisor de dos enteros positivos, o el método de Gauss para
resolver un sistema lineal de ecuaciones.

Muchos autores definen a los algoritmos como listas de instrucciones para resolver un problema
abstracto, es decir, que un número finito de pasos convierten los datos de un problema (entrada)
en una solución (salida).

¿Qué es un Diagrama de Flujo?

Los diagramas de flujo son descripciones gráficas de algoritmos; usan símbolos conectados con
flechas para indicar la secuencia de instrucciones y están regidos por ISO.

Los diagramas de flujo son usados para representar algoritmos pequeños, ya que abarcan mucho
espacio y su construcción es laboriosa. Por su facilidad de lectura son usados como introducción a
los algoritmos, descripción de un lenguaje y descripción de procesos a personas ajenas a la
computación.

¿Qué es Programar?
Es la acción de escribir instrucciones correctas para que sean interpretadas por una máquina.
¿Qué es el Software?
Son programas que para que tengan sentido de software deben ser ejecutados sobre una máquina.

¿En qué medida nos compete programar?


Depende del interés. De todas formas hoy en día es un さマ ust ざ pa ヴ a Iual ケ uie ヴ i ミ ge ミ ie ヴ o o téI
ミ iIo debe de conocer.

¿En qué medida dependemos de software?


Depende de su estilo de vida, pero para el ciudadano común la dependencia es bastante: celulares,
controles remotos (TV, DVD, radios, mp3 players, etc.), cajeros automáticos, etc.

¿Qué es un programa o código fuente?


Es un programa escrito en algún lenguaje y que no ha sido traducido a lenguaje de máquina.

¿Qué es un programa o código objeto?

Es un programa que ya se encuentra en lenguaje de máquina y que ya es ejecutable.

¿Qué es un compilador?
Es aquel programa de software que traduce todo el código fuente escrito y genera un código objeto
que es entendible por la máquina y se encuentra listo para funcionar

¿Qué es un Lenguaje de Programación?


Son conjuntos de instrucciones con que se pueden escribir los algoritmos para que un sistema lo
ejecute. Existen múltiples tipos de lenguajes de programación:

1.2 Historia de la Programación

Los ordenadores son uno más de los inventos del hombre, aunque debemos decir que las
tecnologías para su fabricación y explotación han tenido un desarrollo sorprendente a partir de la
segunda mitad del siglo XX. Esta herramienta por sí sola no es capaz de efectuar ninguna tarea, es
tan sólo un conjunto de cables y circuitos que necesitan recibir instrucción por parte de los
humanos para desempeñar alguna tarea. El problema entonces, se puede fijar en ¿cómo vamos a
poder hacer que un conjunto de circuitos desempeñen una determinada tarea y nos entreguen los
resultados que nosotros esperamos?, es decir, ¿de qué manera se puede lograr la comunicación
entre el hombre y el ordenador?

Así pues, tratando de dar una solución al problema planteado, surgieron los lenguajes de
programación, que son como un lenguaje cualquiera, pero simplificado y con ciertas normas, para
poder trasmitir nuestros deseos al ordenador.

Por otro lado, como se sabe, un conjunto de circuitos no entendería ningún lenguaje que nosotros
conozcamos, por más sencillo que éste parezca. Los circuitos en todo caso, sólo reconocen
presencia o ausencia de energía, es decir que debemos hablarle a la máquina en su propio
lenguaje (presencia y ausencia de energía, 0 y 1), o nuestro lenguaje deberá de ser traducido a un
lenguaje binario cuyo alfabeto es el 0 y el 1, mediante las herramientas desarrolladas para llevar a
cabo esta tarea, las cuales reciben el nombre de traductores, y como veremos más adelante, los
hay de muchos tipos, dependiendo de características más específicas del lenguaje a traducir y de la
manera de llevar a cabo su traducción.

1946: Konrad Zuse , un ingeniero Alemán mientras trabajaba en los Alpes de Bavaria,
desarrolló el lenguaje Plankalkul, el cual, fue aplicado entre otras cosas para jugar al ajedrez.

1949: Aparece Short Code, que viene a ser el primer lenguaje que fue usado en un dispositivo
de cómputo electrónico, aunque se debe decir que se trata de un lenguaje traducido a mano.

1951: Grace Hopper , trabajando para Remington Rand, comenzó el trabajo de diseño del
primer compilador conocido ampliamente, el A-0, el cual, al ser liberado por la compañía en
1957, lo hizo con el nombre de MATH-MATIC.

1952: Alick E. Glennie, durante su tiempo libre en la Universidad de Manchester, concibe un


sistema de programación llamado AUTOCODE, que viene a ser un compilador muy
rudimentario.

1957: aparece FORTRAN (FORmula TRANslating) sistema traductor de fórmulas matemáticas.


Fue desarrollado por un equipo, al frente del cual se encontraba John Backus quien después
vendría a contribuir en el desarrollo del compilador para el lenguaje ALGOL y de la notación
usada para la especificación sintáctica de los lenguajes, conocida como BNF (Backus Naur
Form).

A partir de los años sesenta, empiezan a surgir diferentes lenguajes de programación, atendiendo a
diversos enfoques, características y propósitos, que más adelante describiremos. Por lo pronto,
puede decirse, que actualmente existen alrededor de más 2000 lenguajes de programación y
continuamente, están apareciendo otros más nuevos, que prometen hacer mejor uso de los
recursos computacionales y facilitar el trabajo de los programadores.

Tratando de resumir un poco, se presenta a continuación un cuadro donde aparecen los lenguajes
que por su uso y comercialización, han resultado ser los más populares a lo largo de este medio
siglo.
1.3 Tipos de lenguajes de programación
Los lenguajes más próximos a la arquitectura hardware se denominan lenguajes de bajo nivel y los
que se encuentran más cercanos a los programadores y usuarios se denominan lenguajes de alto
nivel. A continuación hacemos una breve descripción de ambos tipos.

 Lenguajes de Bajo Nivel


Son lenguajes totalmente dependientes de la máquina, es decir que el programa que se
realiza con este tipo de lenguajes no se pueden migrar o utilizar en otras maquinas.

Al estar prácticamente diseñados a medida del hardware, aprovechan al máximo las


características del mismo.

Dentro de este grupo se encuentran:

El lenguaje maquina: este lenguaje ordena a la máquina las operaciones fundamentales


para su funcionamiento. Consiste en la combinación de 0's y 1's para formar las ordenes
entendibles por el hardware de la máquina. Este lenguaje es mucho más rápido que los
lenguajes de alto nivel.

La desventaja es que son bastantes difíciles de manejar y usar, además de tener códigos
fuente enormes donde encontrar un fallo es casi imposible.

El lenguaje ensamblador es un derivado del lenguaje máquina y está formado por


abreviaturas de letras y números llamadas mnemotécnicos. Con la aparición de este
lenguaje se crearon los programas traductores para poder pasar los programas escritos en
lenguaje ensamblador a lenguaje máquina. Como ventaja con respecto al código máquina
es que los códigos fuentes eran más cortos y los programas creados ocupaban menos
memoria. Las desventajas de este lenguaje siguen siendo prácticamente las mismas que las
del lenguaje de maquina añadiendo la dificultad de tener que aprender un nuevo lenguaje
difícil de probar y mantener.

 Lenguajes de Alto Nivel


Son aquellos que se encuentran más cercanos al lenguaje natural que al lenguaje máquina.
Están dirigidos a solucionar problemas mediante el uso de Estructura Dinámicas de Datos,
algo muy utilizado en todos los lenguajes de programación. Son estructuras que pueden
cambiar de tamaño durante la ejecución del programa. Nos permiten crear estructuras de
datos que se adapten a las necesidades reales de un programa.

Se tratan de lenguajes independientes de la arquitectura del ordenador. Por lo que, en


principio, un programa escrito en un lenguaje de alto nivel, lo puedes migrar de una
máquina a otra sin ningún tipo de problema.

Estos lenguajes permiten al programador olvidarse por completo del funcionamiento


interno de la maquina/s para la que están diseñando el programa. Tan solo necesitan un
traductor que entiendan el código fuente como las características de la máquina. Algunos
de ellos son: Basic, C, C++, Pascal, Cobol, Fortran, etc.
1.4 Paradigmas de la programación

Un paradigma de programación es una propuesta tecnológica que es adoptada por una comunidad
de programadores cuyo núcleo central es incuestionable en cuanto a que unívocamente trata de
resolver uno o varios problemas claramente delimitados. La resolución de estos problemas debe
suponer consecuentemente un avance significativo en al menos un parámetro que afecte a la
ingeniería de software. Tiene una estrecha relación con la formalización de determinados lenguajes
en su momento de definición. Un paradigma de programación está delimitado en el tiempo en
cuanto a aceptación y uso ya que nuevos paradigmas aportan nuevas o mejores soluciones que la
sustituyen parcial o totalmente.

Si bien existen varios paradigmas de programación haremos una descripción de aquellos que
consideramos más importantes como son la programación imperativa y la orientada a objetos.

1.4.1 Programación Imperativa

El paradigma imperativo debe su nombre al papel dominante que desempeñan las sentencias
imperativas, es decir aquellas que indican realizar una determinada operación que modifica los
datos guardados en memoria. Su esencia es resolver un problema complejo mediante la ejecución
repetitiva y paso a paso de operaciones y cálculos sencillos con la asignación de los valores
calculados a posiciones de memoria.

La programación en este paradigma consiste en determinar qué datos son requeridos para el
cálculo, asociar a esos datos una dirección de memoria, y efectuar, paso a paso, una secuencia de
transformaciones en los datos almacenados, de forma que el estado final represente el resultado
correcto.

Los conceptos básicos del paradigma son representados por la arquitectura Von Neumann, ya que
utiliza este modelo de máquina para conceptualizar las soluciones.

Principales características

• Celdas de memoria

El principal componente de la arquitectura es la memoria, compuesta por un gran número de


celdas que contienen los datos. Las celdas, llamadas variables, tienen nombres que las
referencian y se organizan en diferentes estructuras de datos.

• Asignación

Estrechamente ligado a la arquitectura de memoria se encuentra la idea de que cada valor


calculado debe ser almacenado, o sea, asignado, en una variable. Estas asignaciones se
realizan repetitivamente sobre la misma celda de memoria, remplazando los valores
anteriores. La asignación determina el estado de una variable, que consiste en el valor que
contiene en un momento en particular. Por lo tanto los resultados corresponden al estado final
que asumen las variables.
• Algoritmos

Un programa imperativo, normalmente realiza su tarea ejecutando repetidamente una


secuencia de pasos elementales, ya que en este modelo computacional la única forma de
ejecutar algo complejo es repitiendo una secuencia de instrucciones. La programación ヴ e ケ uie
ヴ e la Io ミ st ヴ uIIió ミ de さ algo ヴ it マ os ざ, a マ odo de ヴ eIeta, マ étodo, téI ミ iIa, p ヴ oIedi マ ie ミ to
o rutina, que se definen como conjuntos finito de sentencias, ordenadas de acuerdo a sus
correspondientes estructuras de control, que marcan el flujo de ejecución de operaciones para
resolver un problema específico.

• Programación estructurada y estructuras de control

La programación estructurada surge como un conjunto de técnicas para facilitar el desarrollo


de sistemas en lenguajes del paradigma imperativo, pero presenta ideas que también fueron
tenidas en cuenta en lenguajes de otros paradigmas.

La base teórica de la programación estructurada plantea que cualquier programa, por más
grande y complejo que fuera, puede representarse mediante tres tipos de estructuras de
control: secuencia, selección e iteración.

• Modularización

También propone desarrollar el programa en forma TOP-DOWN, de arriba hacia abajo. Es decir,
modularizar el programa creando porciones más pequeñas de programas con tareas
espeIífiIas, ケ ue se suHdivide ミ a su vez e ミ ot ヴ os さ suHp ヴ og ヴ a マ as ざ, Iada vez マ ás pe ケ
ueños ┞ operativos. Estos subprogramas, denominados rutinas, funciones, procedimientos,
módulos y de otras maneras en los diferentes lenguajes, deben tener sólo un punto de entrada
y uno de salida, y realizar conceptualmente una sola tarea.

Existen numerosos lenguajes del paradigma imperativo, como son PASCAL, C, C++, FORTRAN,
ALGOL, COBOL, ADA, CLIPPER, FOX, PL/1, etc. Muchos de ellos incluyen extensiones que permiten
soportar otros paradigmas, en mayor o menor grado; no obstante, sigue predominando en ellos el
modelo de máquina imperativa.

1.4.2 Programación Orientada por Objeto

La programación Orientada a objetos (POO) es una forma especial de programar, más cercana a
como expresaríamos las cosas en la vida real que otros tipos de programación.

La POO no es difícil, pero es una manera especial de pensar, a veces subjetiva de quien la
programa, de manera que la forma de hacer las cosas puede ser diferente según el programador.
Aunque podamos hacer los programas de formas distintas, no todas ellas son correctas, lo difícil no
es programar orientado a objetos sino programar bien. Programar bien es importante porque así
nos podemos aprovechar de todas las ventajas de la POO.
Actualmente el paradigma de programación más usado es el de la programación orientada a
objetos, donde podemos mencionar los siguientes lenguajes: C++, Objective C, Java, Smalltalk,
Eiffel, Ruby, Python, Object Pascal, Visual .net, Actionscript, Perl, C#, PHP, Delphi, etc.

Otros paradigmas.
Programación Funcional (Tarea)
Programación por Eventos (Tarea)
Programación Concurrente (Tarea)
Programación en la Nube (Tarea)

1.5 Programación Estructurada

La programación estructurada es un estilo de programación con el cual el programador elabora


programas, cuya estructura es la más clara posible, mediante el uso de tres estructuras básicas de
control lógico, a saber: SECUENCIA, SELECCIÓN, ITERACIÓN

Un programa estructurado se compone de funciones, segmentos, módulos y/o subrutinas, cada


una con una sola entrada y una sola salida. Cada uno de estos módulos, se denomina programa
apropiado cuando, además de estar compuesto sólamente por las tres estructuras básicas, tiene
sólo una entrada y una salida y en ejecución no tiene partes por las cuales nunca pasa ni tiene
ciclos infinitos.

La programación estructurada tiene un teorema estructural o teorema fundamental, el cual afirma


que cualquier programa, no importa el tipo de trabajo que ejecute, puede ser elaborado utilizando
únicamente las tres estructuras básicas (secuencia, selección, iteración).

1.5.1 Definición de las estructuras básicas de control lógico

• Secuencia
Indica que las instrucciones de un programa se ejecutan una después de la otra, en el
mismo orden en el cual aparecen en el programa. Se representa gráficamente como una
caja después de otra, ambas con una sola entrada y una única salida.

B
Las cajas A y B pueden ser definidas para ejecutar desde una simple instrucción hasta un
módulo o programa completo, siempre y cuando que estos también sean programas
apropiados.

• Selección
También conocida como la estructura SI-CIERTO-FALSO, plantea la selección entre dos
alternativas con base en el resultado de la evaluación de una condición o predicado;
equivale a la instrucción IF de todos los lenguajes de programación y se representa
gráficamente de la siguiente manera:

V F
C

A B

En el diagrama de flujo anterior, C es una condición que se evalúa; A es la acción que se


ejecuta cuando la evaluación de este predicado resulta verdadera y B es la acción
ejecutada cuando indica falso. La estructura también tiene una sola entrada y una sola
salida; y las funciones A y B también pueden ser cualquier estructura básica o conjunto de
estructuras.

• Iteración
También llamada la estructura HACER-MIENTRAS-QUE, corresponde a la ejecución repetida
de una instrucción mientras que se cumple una determinada condición. El diagrama de
flujo para esta estructura es el siguiente:

V
C
F
Aquí el bloque A se ejecuta repetidamente mientras que la condición C se cumpla o sea
cierta. También tiene una sola entrada y una sola salida; igualmente A puede ser cualquier
estructura básica o conjunto de estructuras.

1.6 Lenguajes de Programacion Pascal y C++

¿Qué es Pascal?

Pascal es un lenguaje de programación de ordenadores, de propósito general. Es muy estructurado,


y bastante adecuado para introducirse en la programación de ordenadores.

Turbo Pascal ha sido durante mucho tiempo la versión más extendida del lenguaje Pascal. Fue
desarrollada por la compañía Borland, para el sistema operativo Dos. Este puesto actualmente lo
ocupa una versión de libre distribución (y código fuente abierto) llamada Free Pascal, disponible
para varios sistemas operativos.

¿Qué es Pascal C/C++?

C es un lenguaje de programación de ordenadores, de propósito general. Su uso está muy


extendido, y existen compiladores para muchos sistemas operativos.

C++ (C plus plus o C más más) es una evolución del lenguaje C, que soporta la Programación
Orientada a Objetos.

1.7 Diagramas de Flujo

Un Diagrama de Flujo representa la esquematización gráfica de un algoritmo, el cual muestra


gráficamente los pasos o procesos a seguir para alcanzar la solución de un problema. Su correcta
construcción es sumamente importante porque, a partir del mismo se escribe un programa en
algún Lenguaje de Programación. Si el Diagrama de Flujo está completo y correcto, el paso del
mismo a un Lenguaje de Programación es relativamente simple y directo.

La creación del diagrama de flujo es una actividad que agrega valor, pues el proceso que representa
está ahora disponible para ser analizado, no sólo por quienes lo llevan a cabo, sino también por
todas las partes interesadas que aportarán nuevas ideas para cambiarlo y mejorarlo.

Ventajas de los Diagramas de Flujo:

• Favorecen la comprensión del proceso a través de mostrarlo como un dibujo. El cerebro


humano reconoce fácilmente los dibujos. Un buen diagrama de flujo reemplaza varias
páginas de texto.
• Permiten identificar los problemas y las oportunidades de mejora del proceso. Se
identifican los pasos redundantes, los flujos de los reprocesos , los conflictos de autoridad,
las responsabilidades, los cuellos de botella, y los puntos de decisión.
• Muestran las interfases cliente-proveedor y las transacciones que en ellas se realizan,
facilitando a los empleados el análisis de las mismas.
• Son una excelente herramienta para capacitar a los nuevos empleados y también a los que
desarrollan la tarea, cuando se realizan mejoras en el proceso

Determinar las necesidades de una aplicación. División de la aplicación en tareas. Utilización de


organigramas para representar algoritmos. Utilización de pseudocódigo para la representación de
algoritmos. Utilización de pseudocódigo para especificar algoritmos.

1.7.1 Símbolos y operadores de los diagramas de flujo

Los Diagramas de flujo se dibujan generalmente usando algunos símbolos estándares; sin embargo,
algunos símbolos especiales pueden también ser desarrollados cuando séan requeridos. Los
símbolos tienen significados específicos y se conectan por medio de flechas que indican el flujo
entre los distintos pasos o etapas.

Algunos símbolos estándares, que se requieren con frecuencia para diagramar programas de
computadora se muestran a continuación:

Inicio o Fin del Programa

Pasos, procesos o líneas de instrucción de


programa de computo

Operaciones de entra y salida

Toma de decisiones

Conector para unir flujo a otra parte del


diagrama.

Líneas de flujo

Disco magnético o base de datos

Envía datos a la impresora.


Los operadores son utilizados específicamente para para operaciones aritméticas y relaciones
condicionales. La siguiente es una lista de los símbolos más comúnmente utilizados:
+ Sumar

- Menos

* Multiplicación

/ División

± Más o menos

= Equivalente a

> Mayor que

< Menor que

>= Mayor o igual que

<= Menor o igual que

<> Diferente de

Si

No

True

False

1.7.2 Reglas para la construcción de un diagrama de flujo

Las reglas para la creación de diagramas de flujo son:

1. Los Diagramas de flujo deben escribirse de arriba hacia abajo, y/o de izquierda a derecha.
2. Los símbolos se unen con líneas, las cuales tienen en la punta una flecha que indica la
dirección que fluye la información procesos, se deben de utilizar solamente líneas de flujo
horizontal o verticales (nunca diagonales).
3. Se debe evitar el cruce de líneas, para lo cual se quisiera separar el flujo del diagrama a un
sitio distinto, se pudiera realizar utilizando los conectores. Se debe tener en cuenta que
solo se van a utilizar conectores cuando sea estrictamente necesario.
4. No deben quedar líneas de flujo sin conectar
5. Todo texto escrito dentro de un símbolo debe ser legible, preciso, evitando el uso de
muchas palabras.
6. Todos los símbolos pueden tener más de una línea de entrada, a excepción del símbolo
final.
7. Solo los símbolos de decisión pueden y deben tener más de una línea de flujo de salida.

Ejemplo: Sumar dos números:

1.8 Uso de pseudocódigo


El principal objetivo del pseudocódigo es el de representar la solución a un algoritmo de la forma
más detallada posible, y a su vez lo más parecida posible al lenguaje que posteriormente se
utilizara para la codificación del mismo.

Las principales características de este lenguaje son:

• Se puede ejecutar en un ordenador


• Es una forma de representación sencilla de utilizar y de manipular.
• Facilita el paso del programa al lenguaje de programación.
• Es independiente del lenguaje de programación que se vaya a utilizar.
• Es un método que facilita la programación y solución al algoritmo del programa.

Todo documento en pseudocódigo debe permitir la descripción de:


• Instrucciones primitivas
• Instrucciones de proceso
• Instrucciones de control
• Instrucciones compuestas
• Instrucciones de descripción

La Estructura a seguir en su realización:

Cabecera:
• Programa:
• Modulo:
• Tipos de datos:
• Constantes:
• Variables:
Cuerpo
Inicio
Instrucciones
Fin

Para comentar en pseudocódigo se le antepone al comentario dos asteriscos (*)

Ejemplos

* Programa que calcula el área de un cuadrado a partir de un lado dado por teclado.
Programa: area_cuadrado
Modulo: main **( también se puede llamar principal)
Variables:
lado: natural
area: natural
Inicio
Visualizar "Introduce el lado del cuadrado"
Leer lado
Area<- lado * lado
Visualizar "El área del cuadrado es", area
Fin

* Programa que visualice la tabla de multiplicar del numero introducido por teclado

Programa: Tabla
multiplicar Modulo: main
Variables: t: entero num :
entero
Inicio
Visualizar "Introduce un número"
Leer num
Desde t=1 hasta t=10 repetir
Visualizar num, " X", t, "=", num*t
Fin desde
Fin

Una vez que tenemos preparado un diagrama de flujos (ordinograma u organigrama) y un


pseudocódigo ya podemos comenzar con la codificación del programa en nuestro ordenador. A
partir de aquí todo varía dependiendo del lenguaje de programación que utilicemos, pero en todos
los programas tendremos que definir los tipos de datos que utilizaremos. De todo esto hablaré en
el siguiente artículo.
1.9 Compilador Dev C++

El compilador del cual se va a hacer uso durante el desarrollo del curso será el Dev C++ v. 4.9.9.2.
Dev C++ es totalmente gratuito que genera código objeto para DOS (modo consola) y para
Windows (95/98/2000/NT) con un entorno de programación visual integrado (IDE). Está basado en
el compilador Mingw (Minimalist GNU* for Windows) version MSCVRT 2.95.2-1 que está incluido
en el propio entorno, el cual a su vez es una particularización del compilador GCC (el compilador g+
+ del GNU).

También permite integrar el depurador gratuito para C++ Cygnus Insight Debugger.

Alguna de las principales características del entorno Dev C++ son:

• Depurador integrado (GDB o Insight)


• Editor de programas fuente sensible a la sintaxis C-C++ configurable.
• Editor multiventana con múltiples opciones de edición.
• Se puede trabajar con ficheros independientes o con proyectos multi-ficheros.
• Generador de paquetes de instalación de programas para entorno Windows.
• Puede generar programas DOS (modo consola), aplicaciones Windows y DLLs.
• Edición de ficheros de recursos windows con generador de menús integrado
• Ventanas independientes para el gestor de proyectos, editor y resultados de compilación.
• Resultados de compilación, enlace (linker) y generación de recursos.
• Genera automáticamente esqueletos de programas en C y C++.
• Generación automática de "Makefile"
• Dos juegos de iconos para los menús y las barras de herramientas  Pe ヴマ ite i ミ teg ヴ a
ヴ he ヴヴ a マ ie ミ tas e┝te ヴミ as マ edia ミ te el "tool マ a ミ age ヴざ  Plantillas para la
creación de nuevos tipos de proyectos.

En el siguiente gráfico se muestra la interfaz del compilador. Las configuraciones y distribución de


opciones y herramientas generalmente son muy parecidas entre estos tipos de programas. Es así
por ejemplo que la barra de herramientas contiene las opciones de creación y guardado de
proyectos, búsquedas y ediciones de texto. También se encuentran las opciones de compilación y
ejecución del código.

Son también frecuentes las ventas de navegación que facilitan la manipulación de diferentes
archivos.

El editor de texto, el cual es sensible a la sintaxis del lenguaje.

Y finalmente la barra de estado que facilita la identificación de errores.


Barra de
herramientas Editor de
Texto

Barra de
Navegación Barra de
Estado

1.10 El primer programa さ Hola Mundo ざ en C++

Como en la mayoría de los cursos de lenguajes de programación uno de los primeros programas ケ
ue ge ミ e ヴ al マ e ミ te se esI ヴ iHe ミ es el fa マ oso さ Hola Mu ミ do ざ, a t ヴ avés del Iual se ミ os pe ヴマ
ite da ヴ u ミ vistazo a la sintaxis y estructura del programa.

Pasos a seguir:

1. En primer lugar creamos u ミ ミ uevo p ヴ o┞eIto, haIie ミ do IliIk e ミ el マ e ミ ú さ A ヴ Ihivo-


>Nuevo ざ, seleIIio ミ es la opIió ミ さ Nuevo P ヴ o┞eIto ざ.
2. A continuación se muestra la siguiente pantalla, donde se deberá seleccionar el tipo de
proyecto que vamos a construir. “eleIIio ミ a マ os la opIió ミ さ Co ミ sole AppliIatio ミざ, p ヴ opo
ヴ Iio ミ a マ os el ミ o マ H ヴ e del p ヴ o┞eIto, ケ ue ミ uest ヴ o Iaso se ヴ á さ Hola Mu ミ do ざ y
finalizamos haciendo click en el botón aceptar.

3. Terminamos estableciendo la ubicación donde se guardarán todos los archivos del


proyecto.

Una vez construido el proyecto, el editor de texto contiene las siguientes líneas de código.

#include <cstdlib>
#include <iostream>
using namespace std
int main(int argc, char *argv[])
{
system("PAUSE");
return EXIT_SUCCESS;
}

Tal Io マ o vi マ os e ミ la seIIió ミ de さ pseudoIódigo ざ, este p ヴ og ヴ a マ a Io ミ tie ミ e u ミ a IaHeIe ヴ a


donde se definen el uso de librerías, variables, módulos y un cuerpo que contiene las instrucciones.

El significado de cada palabra se verá más adelante, simplemente nos concentramos en el cuerpo
del programa donde se establece todo lo necesario para construir nuestros programas.

/* Primer Programa Hola Mundo */


#include <cstdlib>
#include <iostream>

using namespace std;

int main(int argc, char *argv[])


{
cout<<"Hola Mundo\n";
system("PAUSE");
return EXIT_SUCCESS;
}
Para compilar nuestro código ingresamos la menú->ejecutar y seleccionamos la opción Compilar y
para ejecutarlo realizamos los mismos pasos solo que en este caso seleccionamos la opción
Ejecutar. Es importante hacer notar que siempre es necesario compilar primero nuestro código
antes de ejecutarlo puesto que esto nos permite actualizar los cambios que hayamos hecho en
nuestro código.

Un acceso rápido a estas opciones es mediante la combinación de teclas CTRL + F9 para compilar y
F9 para ejecutar el programa.

La salida en pantalla se muestra a continuación:

1.11 Ejercicios

a) Hacer el diagrama de flujo para sumar dos números leídos por teclado y escribir el
resultado.

b) Modificar el anterior pero para sumar 100 números leídos por teclado.
c) Hacer un diagrama de flujo que permita escribir los 100 primeros pares

P: Variable para contener el siguiente par que se debe escribir.


I: Contador de pares que quedan por escribir.
El proceso es similar al anterior. Necesitamos un bucle para contar 100 veces y dentro de él
escribimos el par e incrementamos para obtener el siguiente.
d) La sucesión de Fibonacci se define de la siguiente forma: a1=1, a2=1 y an=an-1+an-2 para
n>2, es decir los dos primeros son 1 y el resto cada uno es la suma de los dos anteriores,
los primeros son: 1, 1, 2, 3, 5, 8, 13, 21, ... Hacer un diagrama de flujo para calcular el
Nésimo término de la sucesión.

Dado N, el proceso es el siguiente:


- si N£2 se escribe directamente 1 y se acaba.
- en otro caso se guardan en A y B los 2 últimos (al principio 1) y se suman, pasando después a
llamar A al antiguo B, y B a la suma. Se decrementa N y cuando valga 2, en B tenemos lo que
queremos.

Vamos a ver como funciona paso a paso. Para ello vamos a numerar cada uno de los pasos
y ver como se van realizando. (1) Leemos N, supongamos N=4.
(2) ¿N£2? ® NO
(3) A=1
(4) B=1
(5) C=A+B=1+1=2
(6) A=B=1
(7) B=C=2
(8) N=N-1=4-1=3
(9) ¿N=2? ® NO
(5) C=A+B=1+2=3
TEMA 2. ESTRUCTURAS DE CONTROL.

Las estructuras de control determinan la secuencia en que deben ejecutarse las instrucciones de un
algoritmo.

Existen tres Estructuras de control básicas ó primitivas y combinándolas se puede escribir cualquier
algoritmo. Estas estructuras primitivas son: la secuencia, la bifurcación condicional y el ciclo.

2.1 Secuencia, Condición y Ciclos de Repetición

2.1.1 Secuencia

La estructura de control más simple es la secuencia. Esta estructura permite que las instrucciones
que la constituyen se ejecuten una tras otra en el orden en que se listan. Por ejemplo, considérese
el siguiente fragmento de un algoritmo:

En este fragmento se indica que se ejecute la operación 1 y a continuación la operación 2.

2.1.2 Bifurcación Condicional

a) Condición Simple (if else)

La estructura de bifurcación condicional permite elegir una de dos opciones en una alternativa,
dependiente del resultado obtenido al evaluar la condición. Véase el siguiente fragmento de
algoritmo:
La palabra clave si indica que estamos en una sentencia de bifurcación condicional. Si la condición
es verdadera se ejecuta la operación 1, de otra manera se ejecutará la operación 2.

Cuando la condición se hace falsa el ciclo termina.

En lenguaje C++ la estructura condicional seria de la siguiente manera:

if (condicion) {
// instrucciones que hay que ejecutar si la condición es verdadera
} else {
// Instrucciones que hay que ejecutar si la condición es falsa
}

b) La sentencia switch

Mediante la sentencia switch se puede seleccionar entre varias sentencias según el valor de cierta
expresión.

La sentencia switch evalúa la expresiónMultivalor y ejecuta el conjuntoDeSentencias que aparece


junto a la cláusula case cuyo valor corresponda con el de la expresiónMultivalor.

Cada sentencia case debe ser única y el valor que evalúa debe ser del mismo tipo que el devuelto
por la expresiónMultivalor de la sentencia switch.

Las sentencias break que aparecen tras cada conjunto de sSentencias provocan que el control salga
del switch y continúe con la siguiente instrucción al switch. Las sentencias break son necesarias
porque sin ellas se ejecutarían secuencialmente las sentencias case siguientes. Existen ciertas
situaciones en las que se desea ejecutar secuencialmente algunas o todas las sentencias case, para
lo que habrá que eliminar algunos break.

Finalmente, se puede usar la sentencia default para manejar los valores que no son explícitamente
contemplados por alguna de las sentencias case. Su uso es altamente recomendado.
En lenguaje C++ la estructura condicional switch seria de la siguiente manera:

switch ( expresionMultivalor ) { case valor1 :


conjuntoDeSentencias; break; case valor2 :
conjuntoDeSentencias; break; case valor3:
conjuntoDeSentencias; break;
default: conjuntoDeSentencias; break;
}

Por ejemplo, supongamos un programa con una variable entera meses cuyo valor indica el mes
actual, y se desea imprimir el nombre del mes en que estemos. Se puede utilizar la sentencia
switch para realizar esta operación:
switch (meses){
case 1: cout<<"Enero"<<endl; break;
case 2: cout<<"Febrero"<<endl; break;
case 3: cout<<"Marzo"<<endl; break;
case 4: cout<<"Abril"<<endl; break;
case 5: cout<<"Mayo"<<endl; break;
case 6: cout<<"Junio"<<endl; break;
case 7: cout<<"Julio"<<endl; break;
case 8: cout<<"Agosto"<<endl; break;
case 9: cout<<"Septiembre"<<endl; break;
case 10: cout<<"Octubre"<<endl; break;
case 11: cout<<"Noviembre"<<endl; break;
case 12: cout<<"Diciembre"<<endl; break;
default: cout<<"No existe el mes"<<endl; break; }

2.1.3 Ciclos De Repetición

Los ciclos son estructuras de control que permiten ejecutar varias veces una operación. Existen
varios tipos de ciclos:

a) Ciclo Mientras (WHILE)

Este ciclo repite una operación, mientras se cumpla una cierta condición. Por ejemplo:

E ミ le ミ guaje C++ la est ヴ uItu ヴ a さマ ie ミ t ヴ as ざ seria de la siguiente manera:


While (condicion) {

// Instrucciones a ejecutar una y otra


//vez mientras la condición sea cierta
}

La palabra clave mientras, señala que se trata de un ciclo mientras. La condición se verifica antes de
ejecutar la operación.

b) Ciclo Hacer-mientras (DO-WHILE)

En este ciclo la operación se ejecuta y después se evalúa la condición. Si es verdadera, la operación


se evalúa de nuevo, y así sucesivamente.

En lenguaje C++ la estructura さ haIe ヴ マ ie ミ t ヴ as ざ seria de la siguiente manera:

do {

// Instrucciones a ejecutar una y otra


//vez mientras la condición sea
cierta }while(condicion)

c) Ciclo Desde (FOR)

En este ciclo se ejecuta una operación un cierto número de veces, especificando en un contador el
incremento unitario, desde un Valor Inicial hasta un Valor Final que marcará la condición de salida
del ciclo. Por ejemplo:
En lenguaje C++ la estructura さヴ epeti ヴざ seria de la siguiente manera:

for (valor inicial; condición; ejecutar en cada bucle) {

// Instrucciones a ejecutar mientras la condición sea cierta


}

2.2 Tipos de Datos y Variables

2.2.1 Tipos de datos

Es uno de los conceptos fundamentales de cualquier lenguaje de programación. Estos definen los
métodos de almacenamiento disponibles para representar información, junto con la manera en
que dicha información ha de ser interpretada.

Todos los programas gestionan algunos tipos de información que normalmente se pueden
representar utilizando uno de los ocho (8) tipos de datos básicos de C y C++: texto o char, valores
enteros o int, valores de coma flotante o float, valores en como flotante de doble precisión o
doublé (long double), enumerados o enum, sin valor o void, punteros y booleanos.

1. Texto (tipo de dato char) está constituido por caracteres simples, como a, Z, ¿, 3 y Iade ミ as,
Io マ o さ Esto es u ミ a p ヴ ueHa ざ (ミ o ヴマ al マ e ミ te, de 8 Hits o u ミ H┞te po ヴ Ia ヴ áIte ヴ, Ion
un rango de 0 a 255).
2. Los valores enteros (tipo de dato int) son aquellos números que se aprendieron a contar (1,
4, -2, 1354); normalmente, tienen un tamaño de 16 bits, 2 bytes o una palabra, con rango
de -32768 a 32767. En Windows 98 y Windows NT, los valores enteros tienen un tamaño
de 32 bits con un rango de -2147483648 a 2147483647.
3. Los valores en coma flotante (tipo de datofloat) son números que tienen una parte
fraccional, como por ejemplo pi (3,14159), y exponentes (7,5631021). También se conocen
como números reales (normalmente, son de 32 bits, 4 bytes o 2 palabras, con un rango de
+/-3,4E-38 a 3,4E+38).
4. Los valores en coma flotante de doble precisión (tipo de datodouble) tienen un rango
superior (normalmente de 64 bits, 8 bytes ó 4 palabras, con un rango de 1, 7E-308 a 1,
7E+308). Los valores en coma flotante long double (doble precisión largos) son incluso más
precisos (normalmente, tamaño de 80 bits ó 5 palabras, con un rango de +/-1,18E-4932 a
1,18E-4932).
5. Los tipos de datos enumerados (tipo de dato enum) permiten al usuario definir tipos de
datos.
6. El tipo void se utiliza para especificar valores que ocupan cero bits y no tienen valor (este
tipo también se puede utilizar para la creación de punteros genéricos.
7. El tipo de dato puntero no contiene información en el mismo sentido que el resto de los
tipos de datos; en su lugar, cada puntero contiene la dirección de la posición de memoria
que almacena el dato actual.
8. El tipo de dato bool, al que se le puede asignar las constantes true (verdadero) y false
(falso)

Rango de los tipos de datos


2.2.2 Variables

Es un nombre que representa el valor de un dato. Es una zona o posición de memoria en la


computadora donde se almacena información. Un objeto de datos que el programador define y
nombra explícitamente en un programa. Una variable simple es un objeto elemental de datos con
nombre. El valor o valores de una variable es modificable por operaciones de asignación; es decir,
el enlace de objeto de datos a valor puede cambiar durante su tiempo de vida. Las operaciones
que se pueden realizar con dos o más valores exigen que éstas sean del mismo tipo de datos. No se
puede sumar una variable carácter a otra numérica y/o viceversa.

Para crear una variable (de un tipo simple) en memoria debe declararse indicando su tipo de
variable y su identificador que la identificará de forma única. La sintaxis de declaración de variables
es la siguiente:

TipodeDato Identificador1, Identificador2;

Esta sentencia indica al compilador que reserve memoria para dos variables del tipo de dato
TipodeDato con nombres Identificador1 e Identificador2.

Reglas para definición de variables

• Pueden tener hasta 40 caracteres.


• Debe empezar obligatoriamente con una letra (a-z / A-Z), el resto de los dígitos pueden ser
números.
• No pueden contener espacios en blanco, se pueden incluir caracteres especiales como el
guión o el punto.
2.3 Uso de comentarios en programación

Los comentarios son anotaciones, observaciones, recordatorios, etc. en el programa. Son para uso
exclusivo del programador, y eliminados del código fuente en la fase de preprocesado.

Aunque los comentarios son voluntarios (no es obligatorio escribirlos), representan una ayuda
inestimable durante la construcción del programa. Siendo imprescindibles para el programador
original, o los que le sucedan en las tareas de mantenimiento, cuando es necesario habérselas con
el código un tiempo después de que fue escrito. Además de clarificar ideas, los comentarios son
también un valioso instrumento de depuración, pues permiten eliminar provisionalmente
secciones enteras de código.

Un comentario C/C++ es cualquier secuencia de caracteres contenida entre los delimitadores /*


... */. La totalidad de la secuencia, incluyendo los delimitadores /* y */ son sustituidos por un
simple espacio después de la expansión de macros.

C++ también admite comentarios de una sola línea utilizando dos barras inclinadas (//) como señal
de comienzo. El comentario empieza en este punto (incluyendo las señales de comienzo) y
continúa hasta el próximo carácter de nueva línea.

Ejemplos de comentarios:

/* Esto es un comentario */
A = B + C;

//Esto es un comentario de una línea C = C + D;

TEMA 3. PROGRAMACIÓN MODULAR (FUNCIONES Y PROCEDIMIENTOS)

3.1 Introducción

Uno de los métodos más conocidos para resolver un problema es dividirlo en problemas más
pequeños, llamados subproblemas. De esta manera, en lugar de resolver una tarea compleja y
tediosa, resolvemos otras más sencillas y a partir de ellas llegamos a la solución. Esta técnica se usa
mucho en programación ya que programar no es más que resolver problemas, y se le suele llamar
diseño descendente, metodología del divide y vencerás o programación top-down.

La programación modular consiste en dividir un algoritmo (programa) en unidades de menor


tamaño, donde cada fragmento realiza una tarea explícita y única. Cada uno de esos fragmentos
recibe el nombre de subalgoritmo o módulo. Por tanto, los subalgoritmos (sean funciones o
procedimientos) nos permiten hacer pequeñas porciones de código reutilizable, que pueden ser
llamados desde el resto del programa sin necesidad de repetir esas partes de código cada vez que
se necesiten.

En el siguiente grafico se muestra con un ejemplo sencillo la programación modular, donde para
oHte ミ e ヴ la ミ ota fi ミ al ヴ eIu ヴヴ i マ os a utiliza ヴ u ミ a fu ミ Iió ミ o p ヴ oIedi マ ie ミ to さ p ヴ o マ edio ざ ケ
ue ヴ ealiza el cálculo.
3.2 Funciones

La función desde el punto de vista de programación, se define como un proceso que recibe valores
de entrada (llamados argumentos) y el cual retorna un valor resultado. Adicionalmente las
funciones son subprogramas que se pueden invocar (ejecutar) , desde cualquier parte del
programa, es decir desde otra función, desde la misma función o desde el programa principal,
cuantas veces sea necesario.

Las funciones se utilizan cuando dos o más porciones de un algoritmo que son iguales o similares,
para lo cual se extrae es parte de código similar y se crea una funciona que tiene como cuerpo
dicho codigo. Luego se reemplaza el código extraído en el algoritmo principal con el nombre de la
nueva función creada.

Una función en C++, se declara de la siguiente manera

tipo ミ o マ bre ふ arg ヱ:tipo ヱ, arg ヲ:tipo ヲ,…, arg ミ:tipo ミぶ{
<instrucciones>
retornar <valor>
}

Donde:

• tipo: es tipo de dato que retorna o devuelve la función


• nombre: es el nombre de la función, Dicho nombre no puede contener espacios,
símbolos o letras acentuadas. El nombre debe comenzar siempre con una letra y
puede contener cualquier letra o número
• arg1, arg2, argn: son los argumentos o datos de entrada de la función
• tipo1, tipo2, tipon: son los tipos de datos de los argumentos  instrucciones son
el conjunto de instrucciones que realiza la función  valor es el dato que
devuelve o retorna la función.
En el siguiente ejemplo podemos definir la función sumar que recibe como datos de entrada dos
valores de tipo numérico y retorna como resultado un valor de tipo también numérico, que en esta
caso será como resultado de la suma.

En el programa principal invocamos a la función sumar con las variables け a ┞┞ け H げ Io マ o datos de


entrada, el programa devuelve el resultado que es asignado a la variable que es posteriormente
impreso en pantalla.
#include <cstdlib>
#include <iostream>

using namespace std;


/*Funcion sumar recibe:
dos parametros devuelve:
la suma de ambos
*/
int sumar(int a, int b)
{ int c; c = a + b;
return c;
}

int main(int argc, char *argv[])


{
int a = 2;
int b = 3;
int c;
c = sumar(a,b); cout<<"La suma de "<<a<<" + "<<b<<"
es de: "<<c<<endl; system("PAUSE");
return EXIT_SUCCESS;
}

NOTA: Toda función debe tener una instrucción return en su interior para devolver el resultado
calculado.

3.3 Procedimientos

La declaración de procedimientos en C++ es muy similar a la declaración de las funciones. Los más
puristas dirían que en C++ no existen los procedimientos como tales, ya que se declaran como
funciones pero que no devuelven nada (void). Entonces, en el cuerpo de un procedimiento no
devolveremos nada (no se escribe la instrucción return).

Veamos un ejemplo:
#include <cstdlib>
#include <iostream>

using namespace std;

/* Procedimiento que muestra la tabla de multiplicar


* Recibe: el numero de la tabla a imprimir
* No duevelve ningun valor
*/
void tabla_mult(int num)
{ int x;

for (x=1;x<=10;x++){
cout<<x<<" X "<<num<<" = "<<x*num<<endl;
}
}

int main(int argc, char *argv[])


{ in
t n;
cout<<"Introduzca el numero para la tabla multiplicar:";
cin>>n; tabla_mult(n); system("PAUSE");
return EXIT_SUCCESS;
}

Como puedes comprobar la declaración del procedimiento es exactamente igual que la declaración
de una función. La única diferencia está en que el procedimiento devuelve un valor de tipo void, es
decir, vacío/nada.

3.4 Paso de parámetros por referencia

Como los procedimientos no devuelven ningún tipo de valor en la llamada, la única forma de
devolver valores es incluir la posibilidad de modificar el valor de sus parámetros. Vamos a ver un
ejemplo de cómo hacer eso. El siguiente programa muestra cómo pasar 2 parámetros por
referencia, llamando a una función que intercambia los valores de los 2 parámetros dados.
#include <cstdlib>
#include <iostream>

using namespace std;


/*Procedimientoq que intercambia valores de a y b
* recibe: los dos valor para intercambiar
* no devuelve ningun valor
*/
void intercambiar(int &a, int &b)
{ int aux; aux = a; a = b;
b = aux;
}

int main(int argc, char *argv[])


{
int a = 2, b = 3; cout<<"Estos son los valores iniciales: a =
"<<a<<", b = "<<b<<endl; intercambiar(a,b);
cout<<"Estos son los valores intercambiados: a = "<<a<<", b = "<<b<<endl;
system("PAUSE");
return EXIT_SUCCESS;
}

Para indicar que los dos parámetros se pasan por referencia se coloca el símbolo & delante del
nombre de cada parámetro.
void intercambiar(int &a, int &b)

La utilización de dichos parámetros dentro del procedimiento es exactamente igual que el uso de
cualquier otra variable.

NOTA: La utilización del símbolo & para indicar el paso de parámetros por variable es propio de C+
+, pero por su facilidad es el método que usaremos para pasar parámetros por referencia. En C el
paso de parámetros por referencia es totalmente distinto.
TEMA 4. VECTORES Y MATRICES

Hasta ahora hemos trabajado con datos elementales (enteros, reales, caracteres; int, float, char)
donde podíamos almacenar 1 sólo dato del tipo especificado. En muchas ocasiones es necesario
trabajar con gran cantidad de datos de un mismo tipo.

Por ejemplo imagina que tienes que hacer un programa donde el usuario es un profesor que quiere
almacenar las notas de sus alumnos para posteriormente hacer estadísticas y cálculos como nota
máxima, mínima, la media, etc.

Podríamos hacerlo declarando una variable de tipo float para cada nota pero eso puede llegar a ser
intratable si la cantidad de notas a almacenar fuera muy grande. Además el programa sería muy
engorroso y difícil de entender.

Con los vectores y las matrices conseguimos, bajo un único nombre, es decir, con una única
variable, almacenar tantos valores de un mismo tipo como queramos (según el tamaño que
definamos en su declaración). En el ejemplo anterior, tendríamos un vector de float con longitud,
por ejemplo 100, donde podríamos almacenar hasta 100 valores reales.

4.1 Vectores

Los vectores, también llamados tablas unidimensionales, son tipos de datos compuestos o
estructurados caracterizados por:

- Todos los elementos del vector son del mismo tipo

- Todos los elementos del vector son referenciados con el mismo nombre y la diferencia
entre ellos es el índice de la posición que ocupan dentro del vector
- Todos sus elementos son almacenados en posiciones de memoria contiguas.
El formato general para la declaración de una variable de tipo vector es la siguiente:

Tipo_de_datos nombre_del_vector [tamaño_del_vector]

Donde:

• Tipo_de_datos indica el tipo de datos almacenados en la variable vector que se está


declarando (int, float, char o cualquier otro tipo definido).
• Nombre_del_vector indica el nombre de la variable vector que se está declarando. Con
este nombre refenciaremos a cada elemento del vector.
• Tamaño es un entero, o una constante de tipo entero, que indica cuántas posiciones tiene
ese vector, es decir, cuál es el número máximo de elementos del tipo Tipo_de_datos que se
pueden guardar en la variable Nombre_del_vector que estamos declarando. El tamaño no
puede ser una variable.

Por ejemplo:
float notas[100];

Sería la declaración de la variable notas donde podríamos almacenar hasta 100 números reales.

Gráficamente podríamos representarlo así:

notas

Para acceder a cada casilla del vector utilizamos un número entero llamado subíndice, que indica la
posición del elemento dentro del vector. En C, los elementos empiezan a numerarse en el 0. Así el
primer elemento del vector notas será notas sub 0, el segundo notas sub 1, etc., y el último notas
sub 99. Fíjate que el último elemento es el que ocupa la posición tamaño_del_vector menos
1.

notas

0 1 2 3 99

La sitaxis para acceder a estos elementos en C es la siguiente:

notas[0] (primer elemento)

notas[1] (segundo elemento)

…. notas[99] (último

elemento)
Operaciones que podemos hacer con un vector

a) Consultar o leer el valor de un elemento del vector

Si queremos poner en la variable nota_alu5, la nota del alumno que tenemos en la


posición 5 del vector anterior, haríamos la siguiente asignación:

float notas[100], nota_alu5; /*Declaración de variables */

...

nota_alu5 = notas[5];

b) Asignar o escribir un valor en un elemento del vector

Si queremos poner un 8 al alumno que está en la posición 5 haríamos la siguiente


asignación:
notas[5] = 8;

En estos dos casos, el acceso al elemento del vector que queremos leer o en el que
queremos escribir es directo, porque solamente leemos o modificamos un elemento, el 5
en ambos ejemplos. Si queremos recorrer todo el vector, ya sea para leer como para
escribir, tendremos que utilizar un bucle.

c) Recorrido de un vector

El bucle más utilizado para recorrer un vector es el for, porque a priori sabemos cuántas
vueltas dará el bucle (tantas como elementos del vector a visitar).

Mira el siguiente ejemplo:

#define MAX 20 int

main()

float notas[MAX];

int i;

for (i=0; i<MAX; i++)

{ cout<<さ Da マ e la ミ ota de la posición :ざ<<i;


cout>>notas[i];

return 1;

}
Este programa pide las notas de los alumnos y las almacena en el vector notas.

4.2 Matrices
Las matrices, también llamados tablas bidimensionales, son tipos de datos compuestos o
estructurados caracterizados por:

- Todos los elementos de la matriz son del mismo tipo

- Todos los elementos de la matriz son referenciados con el mismo nombre y la diferencia
entre ellos son los índices de la posición que ocupan dentro de la matriz
El formato general para la declaración de una variable de tipo matriz es la siguiente:

Tipo_de_datos nombre_de_la_matriz [número_filas] [número_columnas]

Donde:

• Tipo_de_datos indica el tipo de datos almacenados en la variable matriz que se está


declarando (int, float, char o cualquier otro tipo definido).
• Nombre_de_la_matriz indica el nombre de la variable matriz que se está declarando. Con
este nombre refenciaremos a cada elemento de la matriz.
• Número_filas es un entero, o una constante de tipo entero, que indica cuántas filas tiene
esa matriz
• Número_columnas es un entero, o una constante de tipo entero, que indica cuántas
columnas tiene esa matriz
• El número de filas y de columnas no puede ser una variable.

Por ejemplo:

#define MAX_ASIG 6 /*Definición de las constantes */

#define MAX_ALUM 40

...

float notas[MAX_ASIG][MAX_ALUM];

Sería la declaración de la variable notas donde almacenaríamos todas las notas de los alumnos de
cada asignatura. MAX_ASIG y MAX_ALUM serían dos constantes con valores enteros declaradas
anteriormente.
Gráficamente podríamos representarlo así:
notas columna

fila

En este ejemplo la fila indica la asignatura y la columna el alumno.

Para acceder a cada elemento de la matriz utilizamos dos números enteros llamados subíndices,
que indica la fila y la columna donde se encuentra el elemento dentro de la matriz. En C/C++, los
elementos empiezan a numerarse en el 0. Así el primer elemento de la matriz notas será notas[0]
[0] y el último notas [MAX_ASIG -1][MAX_ALUM – 1].

Si te fijas notarás que es exactamente igual que los vectores, pero con 2 dimensiones (la fila y la
columna) en lugar de 1.

Operaciones que podemos hacer con una matriz

a) Consultar o leer el valor de un elemento de la matriz

Si queremos poner en la variable nota_alu5, la nota del alumno que tenemos en la


posición 5 dentro de la asignatura 0, haríamos la siguiente asignación:

float nota_alu5, notas[MAX_ASIG][NAX_ALUM]; /*Declaración de variables*/

...

nota_alu5 = notas[0][5];

b) Asignar o escribir un valor en un elemento de la matriz

Si queremos poner un 8 en la asignatura 0 al alumno que está en la posición 5 haríamos la


siguiente asignación:

notas[0][5] = 8;

En estos dos casos, el acceso al elemento de la matriz que queremos leer o en el que
queremos escribir es directo, porque solamente leemos o modificamos un elemento, el fila
0, columna 5 en estos ejemplos. Si queremos recorrer toda la matriz, ya sea para leer como
para escribir, tendremos que utilizar un bucle.

c) Recorrido de una matriz

Al igual que para recorrer un vector, para recorrer una matriz, el bucle más utilizado para
recorrer es el for, porque a priori sabemos cuántas vueltas dará el bucle (tantas como
elementos de la matriz a visitar).

Podemos recorrer la matriz por filas o por columnas. La manera de hacerlo dependerá del
ejercicio.
En el siguiente ejemplo se piden las notas por teclado haciendo un recorrido por filas,
pidiendo consecutivamente las notas de todos los alumnos de cada asignatura:

#define MAX_ASIG 6 #define

MAX_ALUM 40

int main()

float notas [MAX_ASIG][MAX_ALUM];

int i,j;

for (i=0; i<MAX_ASIG; i++) /*Para cada asignatura (para cada fila)*/

{cout<<さ Da マ e las ミ otas de la asig ミ atu ヴ a ざ<<i;

for(j=0; j<MAX_ALUM; j++) /* Para cada alumno de cada asignatura (para


cada columna de cada fila) */

{ Iout<<さ Nota del alu マミ o:ざ<<j;

cout>>notas[i][j];

return 1;

4.3 Estructuras

Una estructura es un grupo de variables las cuales pueden ser de diferentes tipos sostenidas o
mantenidas juntas en una sola unidad. La unidad es la estructura.
En C/C++ se forma una estructura utilizando la palabra reservada struct, seguida por un campo
etiqueta opcional, y luego una lista de miembros dentro de la estructura. La etiqueta opcional se
utiliza para crear otras variables del tipo particular de la estructura:

struct
nombre_estructura
{ tipo1 campo1;
tipo2 campo2;
tipo3 campo3;
.
.
.
TipoN campoN;
};

Un punto y coma finaliza la definición de una estructura puesto que ésta es realmente una
sentencia C/C++.

En un programa, podemos asociar una variable con una estructura utilizando una sentencia similar
a la siguiente:

nombre_estructura nombre_variable;

Para acceder a los miembros de las estructuras se usa el punto u operador miembro (.). La sintaxis
es:

nombre_variable.miembroNombre

Veamos su funcionamiento con un ejemplo:

#include <cstdlib>
#include <iostream>

using namespace std;

struct
persona{ string
nombre; string
apellido; string
direccion; string
telefono; int
edad;
};
int main(int argc, char *argv[])
{
persona p1;
p1.nombre = "Roberto";
p1.apellido = "Ramos";
p1.direccion = "Calvo #44";
p1.telefono = "6433434";
p1.edad = 21;

cout<<"Nombre:"<<p1.nombre<<endl;
cout<<"Apellido:"<<p1.apellido<<endl;
cout<<"Direccion:"<<p1.direccion<<endl;
cout<<"Telefono:"<<p1.telefono<<endl; cout<<"Edad:"<<p1.edad<<endl;
system("PAUSE");
return EXIT_SUCCESS;
}

E ミ el eje マ plo deIla ヴ a マ os u ミ a est ヴ uItu ヴ a lla マ ada さ pe ヴ so ミ a ざ Io ミ los Ia マ pos さミ o マ H ヴ e,


apellido, di ヴ eIIió ミ, teléfo ミ o ┞ edad ざ. E ミ la fu ミ Iió ミ p ヴ i ミ Iipal, defi ミ i マ os la va ヴ iaHle de tipo est
ヴ uItu ヴ a ┞ asignamos los valores a sus campos correspondientes y finalizamos mostrando en
pantalla los valores de cada campo.

TEMA 5. PUNTEROS Y MEMORIAS DINAMICAS


5.1 Introducción
Por definición un puntero es una variable que puede almacenar la dirección en memoria de otra
variable. Según mi definición, un puntero es una entidad, que puede ser variable o constante, que
siempre contiene una dirección de memoria (valida, inválida o nula), en la cual puede estar alojada
una entidad de nuestro programa o no.

El valor de todas las variables que manejamos en nuestros programas se almacenan en memoria y
tienen una dirección. Un puntero es una variable especial que apunta a la dirección de memoria de
una variable. El puntero tiene a su vez su propia dirección. Todas estas direcciones tienen un
formato hexadecimal.

Los punteros son herramientas muy poderosas con muchas utilidades y enormes ventajas como
veremos más adelante. A grandes rasgos, un puntero me permite desplazarme en la memoria,
apuntar, redireccionar a ciertas variables, funciones, métodos, objetos sin necesidad de mover
grandes bloques de datos, lo cual nos ahorra muchísimo el consumo de memoria en los programas.

La declaración de una variable tipo puntero debe ser de la forma:


TipoVariableApuntada *NombreVariablePuntero;

Una variable de tipo puntero debe ser de igual tipo que la variable cuya dirección en memoria
contiene, o dicho de otra forma, la variable a la que apunta.

Un puntero no tiene asociación directa con el dato actual, pero si una asociación indirecta. Por ese
マ otivo se usa el té ヴマ i ミ o さ di ヴ eIIió ミざ Iua ミ do se haIe ヴ efe ヴ e ミ Iia a u ミ a asoIiaIió ミ i ミ di ヴ eIta.

Un puntero se debe declarar de acuerdo al tipo de dato al que apunta. Ejem:

1 int *var; //Un puntero llamado var que podra apuntar a cualquier variable de tipo entero.
2 char *u;//puntero de tipo char
3 Persona *per;//puntero de tipo persona

Para determinar, asignar la dirección de una variable en c++, se usa el operador & y para obtener el
contenido de un puntero utilizamos el operador * Ejem:

1 int a;//entero
2 int *b;//puntero a entero
3 a = 20;//a tiene 20
4 b=&a;//asigno la dirección de a al puntero b
5
6 cout << b << endl; // imprimirá la dirección de memoria de a;
7 cout << *b;// imprimirá 20, es decir el contenido de a

5.2 Aritmética de punteros


Utilizando los operadores de adición y sustracción podemos movernos a partir de la dirección
relativa a la que apunta un puntero.

p++; cout
<< *p; P--;
cout<<*p;

Pueden visualizar que estoy incrementando el puntero p en 1. Esto quiere decir que el puntero se
desplazara 4 bytes en memoria (en este caso por ser entero) y entonces apuntara a otra direccion.
Por eso es que el nuevo contenido de p es basura o bueno el contenido de lo que tiene esa nueva
direccion a la que apunta.
Supongamos que definir un entero y puntero de tipo char:
1 char c;
2 char *d;
3
4 d= &c;//asigno la direccion de c a d
5 c='u';//asigno el valor u a mi variable c
6 c--;//desplazo una posicion a c
7 cout << *d;//

No I マ p ヴ i マ i ヴ a け u げ po ヴケ ue fije ミ se ケ ue desplazé I e ミ se ミ tido ミ egativo 1 H┞te (los Iha ヴ


oIupa ミ a 1 byte). Es decir, que si d estaba apuntado a una direccion como por ejemplo 0x22ff99,
despues del c– estara apuntando a algo como 0x22ff98

Para tomar en cuenta cosas que no puedo hacer con punteros:

01 int a=15;
02 int *p;
03
04 double *q;
05 void *r;
06 p = a; //No puedo hacer esto porque estoy asignando una variable a un puntero y un puntero es
07 una direccion. p = &50; // 50 es un valor constante en este caso y no una variable,por lo tanto
no tiene
08 direccion
09 p = &(a+1); //una expresion no tiene direccion
10 p = 30;//igual que el primer error, 30 es un entero.
11 &a = p;//no puedo cambiar la direccion de una variable
12 p = q;//p es puntero de tipo entero y q de tipo double

Un puntero de tipo void, es un puntero al cual le podemos asignar cualquier tipo de puntero. Por lo
tanto si podriamos hacer esto:

r = p;

5.3 Comparación de punteros

Para la comparación de punteros se utilizan los operadores básicos de comparación que usábamos
con variables bases, tales como int. Por lo que para saber por ejemplo si un puntero apunta a la
misma dirección a la que apunta otro, utilizaríamos: p1 == p2, para saber si son distintos
utilizaríamos el operador !=, para saber si p1 apunta a una dirección de memoria mas baja que p2
colocaríamos p1 < p2, y así con los demás operadores de comparación.
VECTORES Y PUNTEROS
Cuando declaramos un vector int v[10]; el nombre del vector es un puntero al primer elemento del
vector, es decir a v[0]. Entonces como un vector es un puntero al primer elemento del mismo,
también podríamos hacer aritmética de punteros con el vector.

1 (v+1) ;//apuntara a v[1];


2 *(v+5);//me refiero al contenido de v[5]
3
4 //Y también a los punteros les puedo poner índices:
5
6 int *p; //puntero de tipo entero
7 p = &v[0];//p apunta a la direccion del vector v[0] o tambien a v. p = v
8 p[8] = 80; //le asigno el valor 80 al puntero en la posicion 8, es decir a v[8]

5.4 Vectores Dinámicos


Lo que vimos en el inicio de este post, son vectores estáticos, puesto que tienen una cantidad fija
de memoria asignada y tamaño definido que no podemos modificarlo. Sin embargo, un vector
podría tener una cantidad variable de datos, a este se le llama un vector dinámico.

Para usar vectores dinámicos necesitamos gestionar memoria dinámica. Si bien es cierto que esto
trae enormes ventajas, el hacer un mal uso de la memoria dinámica nos podría traer problemas
desastrozos. Por eso es importante que cuando creemos vectores dinámicos también liberemos la
memoria utilizada. Obviamente eliminaremos la memoria utilizada cuando ya no necesitamos más
usar, en este caso, un determinado vector.

El operador new sirve para reservar memoria dinámica. El operador delete se usa para liberar la
memoria dinámica reservada con new. Para liberar memoria de un array dinámico usamos
delete[] .

El espacio de memoria que hemos reservado con new tendrá vida hasta que finalize la ejecución
del programa o cuando liberemos ese espacio con delete. Siempre es recomendable liberar
memoria para posteriormente no tener problemas con excesivo consumo de memoria.

Un simple ejemplo:

01 #include <iostream>
02 using namespace std;
03
04 int main()
05 {
06 int *pv;
07 int dim;
08
09 cout << "Ingresa el tamanyo del vector" << endl;
10 cin >>dim;
11 pv = new int[dim];
12
13 for(int i=0;i<dim;i++){
14 pv[i] = i * i;
15 cout << pv[i] << " ";
16 }
17
18 delete[] pv;
19 return 0;
20 }

TEMA 6. PROGRAMACION ORIENTADA A OBJETOS.

6.1 Que es la programación orientada a objetos?

Hasta ahora estamos estado "cuadriculando" todo para obtener algoritmos: tratábamos de
convertir cualquier cosa en funciones y variables que pudieramos emplear en nuestros programas.

Pero no todo lo que nos rodea es tan fácil de cuadricular. Supongamos por ejemplo que tenemos
que describir una puerta desde nuestro programa. En la zona de declaración de variables
detallaríamos datos como su tamaño o su color. Pero no basta con eso. De hecho, eso no es lo más
importante: lo que hace que una puerta sea una puerta es el hecho de que se pueda abrir y se
pueda cerrar. Por tanto, si queremos simular o controlar una puerta desde nuestro programa,
deberíamos crear también las funciones AbrirPuerta y CerrarPuerta en alguna otra parte de
nuestro fuente.

No está mal, pero es antinatural: una puerta es un conjunto: no podemos separar su color de su
tamaño, o de la forma en que debemos abrirla o cerrarla. Sus características son tanto las físicas (lo
que hasta ahora llamábamos variables) como sus comportamientos en distintas circunstancias (lo
que para nosotros eran las funciones). Todo ello va siempre unido, formando un OBJETO.

Por otra parte, si tenemos que explicar a alguien lo que es el portón de un garaje, y ese alguien no
lo ha visto nunca, pero conoce cómo es la puerta de su casa, le podemos decir "se parece a una
puerta de una casa, pero es más grande para que quepan los coches, está hecha de metal en vez
de madera..." . Las dos cosas son puertas: se trata de dos objetos que pertenecen a la misma
CLASE.
Finalmente, conviene recordar que "abrir" no se refiere sólo a una puerta. También podemos
hablar de abrir una ventana o un libro, por ejemplo.

Pues con esta discusión hemos comentado casi sin saberlo las tres características más importantes
de la Programación Orientada a Objetos (POO):

• ENCAPSULACION: No podemos separar los comportamientos de las características de un


objeto. Los comportamientos del objeto serán funciones, que en OOP llamaremos
METODOS. Las características del objeto serán variables, como las que hemos usado
siempre, que en OOP llamaremos ATRIBUTOS. La apariencia de un objeto en C++, como
veremos un poco más adelante, recordará a un registro o "struct" , que contendrá
funciones además de datos.
• HERENCIA: Unos objetos pueden "heredar" métodos y atributos de otros. Esto hace más
fácil definir objetos nuevos a partir de otros que ya teníamos anteriormente (como
ocurría con el portón y la puerta) y facilitará la reutilización de los programas, pudiendo
aprovechar buena parte de los anteriores... si están bien diseñados.
• POLIMORFISMO: Un mismo nombre de un método puede hacer referencia a
comportamientos relativamente distintos (como abrir una puerta o abrir un libro). En C+
+ el polimorfismo llega incluso al nivel de los operadores: podremos "redefinir" el
operador + para que sume matrices, ficheros o cualquier tipo de objeto que nos
interese.

(Nota: en C++ es frecuente llamar también "variables de instancia" o "variables miembro" a los
atributos, y "funciones miembro" a los métodos).

Comentado esto, vamos a empezar a ver ejemplos en C++ para tratar de fijar estos primeros
conceptos y de ver la sintaxis de este lenguaje. A partir de unos primeros ejemplos sencillos,
iremos profundizando paulatinamente.

6.2 Definición de clase

Una clase, es simplemente una abstracción que hacemos de nuestra experiencia sensible. El ser
humano tiende a agrupar seres o cosas -objetos- con características similares en grupos -clases-.
Así, aun cuando existen por ejemplo multitud de vasos diferentes, podemos reconocer un vaso en
cuanto lo vemos, incluso aun cuando ese modelo concreto de vaso no lo hayamos visto nunca. El
concepto de vaso es una abstracción de nuestra experiencia sensible.

Quizás el ejemplo más claro para exponer esto lo tengamos en las taxonomías; los biólogos han
dividido a todo ser (vivo o inerte) sobre la tierra en distintas clases.

Tomemos como ejemplo una pequeña porción del inmenso árbol taxonómico:
Ellos, llaman a cada una de estas parcelas reino, tipo, clase, especie, orden, familia, género, etc.; sin
embargo, nosotros a todas las llamaremos del mismo modo: clase. Así, hablaremos de la clase
animal, clase vegetal y clase mineral, o de la clase félidos y de las clases leo (león) y tigris (tigre).

Cada clase posee unas cualidades que la diferencian de las otras. Así, por ejemplo, los vegetales se
diferencian de los minerales -entre otras muchas cosas- en que los primeros son seres vivos y los
minerales no. De los animales se diferencian en que las plantas son capaces de sintetizar clorofila a
partir de la luz solar y los animales no.

Situémonos en la clase felinos (felis), aquí tenemos varias subclases (géneros en palabras de los
biólogos): león, tigre, pantera, gato, etc. cada una de estas subclases, tienen características
comunes (por ello los identificamos a todos ellos como felinos) y características diferenciadoras
(por ello distinguimos a un león de una pantera), sin embargo, ni el león ni la pantera en abstracto
existen, existen leones y panteras particulares, pero hemos realizado una abstracción de esos
rasgos comunes a todos los elementos de una clase, para llegar al concepto de león, o de pantera,
o de felino.

La clase león se diferencia de la clase pantera en el color de la piel, y comparte ciertos atributos
con el resto de los felinos -uñas retráctiles por ejemplo- que lo diferencian del resto de los
animales. Pero la clase león, también hereda de las clases superiores ciertas cualidades: columna
vertebral (de la clase vertebrados) y es alimentado en su infancia por leche materna (de la clase
mamíferos).

Vemos cómo las clases superiores son más generales que las inferiores y cómo, al ir bajando por
este árbol, vamos definiendo cada vez más (dotando de más cualidades) a las nuevas clases. Hay
cualidades que ciertas clases comparten con otras, pero no son exactamente iguales en las dos
clases. Por ejemplo, la clase hombre, también deriva de la clase vertebrado, por lo que ambos
poseen columna vertebral, sin embrago, mientras que en la clase hombre se halla en posición
vertical, en la clase león la columna vertebral está en posición horizontal.

En OOP existe otro concepto muy importante asociado al de clase, el de "clase abstracta". Una
clase abstracta es aquella que construimos para derivar de ella otras clases, pero de la que no se
puede instanciar. Por ejemplo, la clase mamífero, no existe como tal en la naturaleza, no existe
ningún ser que sea tan solo mamífero (no hay ninguna instanciación directa de esa clase), existen
humanos, gatos, conejos, etc. Todos ellos son mamíferos, pero no existe un animal que sea solo
mamífero.

Del mismo modo, la clase que se halla al inicio de la jerarquía de clases, normalmente es creada
sólo para que contenga aquellos datos y métodos comunes a todas las clases que de ella derivan:
Son clases abstractas. En árboles complejos de jerarquías de clases, suele haber más de una clase
abstracta.

Este es un concepto muy importante: el de "clase abstracta". Como hemos dicho, una clase
abstracta es aquella que construimos para derivar de ella otras clases, pero de la que no se puede
instanciar. Por ejemplo, la clase mamífero, no existe como tal en la naturaleza, no existe ningún ser
que sea tan solo mamífero (no hay ninguna instanciación directa de esa clase), existen humanos,
gatos, conejos, etc.
Todos ellos son mamíferos, pero no existe un animal que sea solo mamífero. Por último,
adelantemos algo sobre el concepto de objeto. El león, como hemos apuntado antes, no existe,
igual que no existe el hombre; existen leones en los circos, en los zoológicos y, según tenemos
entendido, aún queda alguno en la sabana africana. También existen hombres, como usted, que
está leyendo este libro (hombre en un sentido neutro, ya sea de la subclase mujer o varón), o cada
uno de los que nos encontramos a diario en todas partes.

Todos estos hombres comparten las características de la clase hombre, pero son diferentes entre sí,
en estatura, pigmentación de la piel, color de ojos, complexión, etc. A cada uno de los hombres
particulares los llamamos "objetos de la clase hombre". Decimos que son objetos de tipo hombre o
que pertenecen a la clase hombre. Más técnicamente, José Luis Aranguren o Leonardo da Vinci son
instanciaciones de la clase hombre; instanciar un objeto de una clase es crear un nuevo elemento
de esa clase, cada niño que nace es una nueva instanciación a la clase hombre.

6.3 Definición de objeto

En POO, un objeto es un conjunto de datos y métodos, donde los datos son lo que antes hemos
llamado características o atributos, los métodos son los comportamientos que pueden realizar. Lo
importante de un sistema OOP es que ambos, datos y métodos están tan intrínsecamente ligados,
que forman una misma unidad conceptual y operacional. En POO, no se pueden desligar los datos
de los métodos de un objeto. Así es como ocurre en el mundo real.

Vamos ahora a dar una serie de ejemplos en los que nos iremos acercando paulatinamente a los
objetos informáticos. Los últimos ejemplos son para aquellos que ya conocen Java y/o C++; sin
embargo, estos ejemplos que exigen conocimientos informáticos, no son imprescindibles para
entender plenamente el concepto de clase y el de objeto.

Observe que aunque los datos y los métodos se han enumerado verticalmente, no existe ninguna
correspondencia entre un dato y el método que aparece a su derecha, es una simple enunciación.

Ejemplo 1
Tomemos la clase león de la que hablamos antes y veamos cuales serían algunos de sus datos y de
sus métodos.
Ejemplo 2

Nuestros objetos (los informáticos), como hemos comentado antes, se parecen mucho a los del
mundo real, al igual que estos, poseen propiedades (datos) y comportamientos (métodos).
Tomemos para nuestro ejemplo un cassette. Veamos cómo lo definiríamos al estilo de POO.

Ejemplo 3

Pongamos otro ejemplo algo más próximo a los objetos que se suelen tratar en informática: un
recuadro en la pantalla. El recuadro pertenecería a una clase a la llamaremos marco. Veamos sus
datos y sus métodos.

6.4 Herencia

Esta es la cualidad más importante de un sistema POO, la que nos dará mayor potencia y
productividad, permitiéndonos ahorrar horas y horas de codificación y de depuración de errores.
Es por ello que me niego a considerar que un lenguaje es OOP si no incluye herencia, como es el
caso de Visual Basic (al menos hasta la versión 5, que es la última que conozco).
Como todos entendemos lo que es la herencia biológica, continuaremos con nuestro ejemplo
taxonómico del que hablábamos en el epígrafe anterior.

La clase león, como comentábamos antes, hereda cualidades -métodos, en lenguaje POO- de todas
las clases predecesoras -padres, en POO- y posee métodos propios, diferentes a los del resto de las
clases.

Es decir, las clases van especializándose según se avanza en el árbol taxonómico. Cada vez que
creamos una clase heredada de otra (la padre) añadimos métodos a la clase padre o modificamos
alguno de los métodos de la clase padre. Veamos qué hereda la clase león de sus clases padre:

La clase león hereda todos los métodos de las clases padre y añade métodos nuevos que forman su
clase distinguiéndola del resto de las clases: por ejemplo el color de su piel. Observemos ahora
algo crucial que ya apuntábamos antes: dos subclases distintas, que derivan de una misma clase
padre común, pueden heredar los métodos de la clase padre tal y como estos han sido definidos
en ella, o pueden modificar todos o algunos de estos métodos para adaptarlos a sus necesidades.
En el ejemplo que exponíamos antes, en la clase león la alimentación es carnívora, mientras que en
la clase hombre, se ha modificado éste dato, siendo su alimentación omnívora.

Pongamos ahora un ejemplo algo más informático: supongamos que usted ha construido una clase
que le permite leer números enteros desde teclado con un formato determinado, calcular su IVA y
almacenarlos en un fichero. Si desea poder hacer lo mismo con números reales (para que admitan
decimales), solo deberá crear una nueva subclase para que herede de la clase padre todos sus
métodos y redefinirá solo el método de lectura de teclado. Esta nueva clase sabe almacenar y
mostrar los números con formato porque lo sabe su clase padre.

Las cualidades comunes que comparten distintas clases, pueden y deben agruparse para formar
una clase padre -también llamada superclase-. Por ejemplo, usted podría derivar las clases
presupuesto, albarán y factura de la superclase pedidos, ya que estas clases comparten
características comunes. De este modo, la clase padre poseería los métodos comunes a todas ellas
y sólo tendríamos que añadir aquellos métodos propios de cada una de las subclases, pudiendo
reutilizar el código escrito en la superclase desde cada una de las clases derivadas. Así, si
enseñamos a la clase padre a imprimirse, cada uno de los objetos de las clases inferiores sabrán
automáticamente y sin escribir ni una solo línea más de código imprimirse.

La herencia como puede intuir, es la cualidad más importante de la POO, ya que le permite
reutilizar todo el código escrito para las superclases re-escribiendo solo aquellas diferencias que
existan entre éstas y las subclases.

Veamos ahora algunos aspectos más técnicos de la herencia:


A la clase heredada se le llama, subclase o clase hija, y a la clase de la que se hereda superclase o
clase padre. Al heredar, la clase heredada toma directamente el comportamiento de su superclase,
pero puesto que ésta puede derivar de otra, y esta de otra, etc., una clase toma indirectamente el
comportamiento de todas las clases de la rama del árbol de la jerarquía de clases a la que
pertenece.

Se heredan los datos y los métodos, por lo tanto, ambos pueden ser redefinidos en las clases hijas,
aunque lo más común es redefinir métodos y no datos. Muchas veces las clases –especialmente
aquellas que se encuentran próximas a la raíz en el árbol de la jerarquía de clases– son abstractas,
es decir, sólo existen para proporcionar una base para la creación de clases más específicas, y por
lo tanto no puede instanciarse de ellas; son las clases virtuales.

Una subclase hereda de su superclase sólo aquellos miembros visibles desde la clase hija y por lo
tanto solo puede redefinir estos.

Una subclase tiene forzosamente que redefinir aquellos métodos que han sido definidos como
abstractos en la clase padre o padres. Normalmente, como hemos comentado, se redefinen los
métodos, aun cuando a veces se hace necesario redefinir datos de las clases superiores. Al
redefinir un método queremos o bien sustituir el funcionamiento del método de la clase padre o
bien ampliarlo.

En el primer caso (sustituirlo) no hay ningún problema, ya que a la clase hija la dotamos con un
método de igual nombre que el método que queremos redefinir en la clase padre y lo
implementamos según las necesidades de la clase hija. De este modo cada vez que se invoque este
método de la clase hija se ejecutará su código, y no el código escrito para el método homónimo de
la clase padre.

Pero si lo que queremos es ampliar el funcionamiento de un método existente en la clase padre (lo
que suele ser lo más habitual), entonces primero tiene que ejecutarse el método de la cla se padre,
y después el de la clase hija. Pero como los dos métodos tienen el mismo nombre, se hace
necesario habilitar alguna forma de distinguir cuando nos estamos refiriendo a un método de la
clase hija y cuando al del mismo nombre de la clase padre.

Esto se hace mediante el uso de dos palabras reservadas, las cuales pueden variar dependiendo del
lenguaje que se utilice, pero que normalmente son: this (en algunos lenguajes se utiliza la palabra
reservada Self) y super:

this

Con esta palabra, podemos referirnos a los miembros de la clase.

En esencia, una clase en C++ es una estructura en el estilo de C con algunas ventajas sencillas pero
muy potentes.

6.5 Polimorfismo
Por polimorfismo entendemos aquella cualidad que poseen los objetos para responder de distinto
modo ante el mismo mensaje. Pongamos por ejemplo las clases hombre, vaca y perro, si a todos
les damos la orden -enviamos el mensaje- Come, cada uno de ellos sabe cómo hacerlo y realizará
este comportamiento a su modo.

Veamos otro ejemplo algo más ilustrativo. Tomemos las clases barco, avión y coche, todas ellas
derivadas de la clase padre vehículo; si les enviamos el mensaje Desplázate, cada una de ellas sabe
cómo hacerlo. Realmente, y para ser exactos, los mensaje no se envían a las clases, sino a todos o
algunos de los objetos instanciados de las clases. Así, por ejemplo, podemos decirle a los objetos
Juan Sebastián el Cano y Kontiqui, de la clase barco que se desplacen, con los que el resto de los
objetos de esa clase permanecerán inmóviles.

Del mismo modo, si tenemos en pantalla cinco recuadros (marcos) y tres textos, podemos decirle a
tres de los recuadros y a dos de los textos que cambien de color y no decírselo a los demás objetos.
Todos estos sabrán cómo hacerlo porque hemos redefinido para cada uno de ellos su método
Pintarse que bien podría estar en la clase padre Visual (conjunto de objetos que pueden
visualizarse en pantalla).

En programación tradicional, debemos crear un nombre distinto para la acción de pintarse, si se


trata de un texto o de un marco; en OOP el mismo nombre nos sirve para todas las clases creadas
si así lo queremos, lo que suele ser habitual. El mismo nombre suele usarse para realizar acciones
similares en clases diferentes.

Si enviamos el mensaje Imprímete a objetos de distintas clases, cada uno se imprimirá como le
corresponda, ya que todos saben cómo hacerlo. El polimorfismo nos facilita el trabajo, ya que
gracias a él, el número de nombres de métodos que tenemos que recordar disminuye
extensiblemente.

La mayor ventaja la obtendremos en métodos con igual nombre aplicados a las clases que se
encuentran próximas a la raíz del árbol de clases, ya que estos métodos afectarán a todas las clases
que de ellas se deriven.

6.6 Sobrecarga

La sobrecarga puede ser considerada como un tipo especial de polimorfismo que casi todos los
lenguajes de POO incluyen. Varios métodos (incluidos los "constructores", de los que se hablará
más adelante) pueden tener el mismo nombre siempre y cuando el tipo de parámetros que recibe
o el número de ellos sea diferente.

De este modo, por ejemplo la clase File puede tener tantos método Write() como tipos de datos
queramos escribir (no se preocupe si no entiende la nomenclatura, céntrese en la idea):

File::Write( int i ); Escribe un integer


File::Write( long l ); Escribe un long
File::Write( float f ); Escribe un flota
File::Write( string s ); Escribe una cadena
File::Write( string s, boolean b ); Escribe una cadena pasándola a mayúsculas
6.7 Declaración de clases en C++

Para declarar una clase, todo lo que se necesita es escribir una definición de estructura y sustituir la
palabra reservada struct por class. Por ejemplo, una clase empleado con campos como el nombre,
el departamento, la posición, el una función que nos imprima la información de este quedaría así:

class Empleado { char* m_nombre;


char* m_departamento; char*
m_posicion; long m_salario; void
Imprimir( Empleado infoEmpleado);

Cuando usted declara una clase en C++, no se reserva memoria para la clase hasta que usted crea
un objeto de la clase. Crear un objeto de una clase se llama instanciar un objeto. Un objeto creado
de una clase de denomina instancia de una clase. Por ejemplo, yo puedo tener una instancia de
empleado con el valor en m_nombre=Jose, m_departamento=Sistemas, m_posicion=programador
y m_salario=3000000 por ejemplo.

6.7.1. Especificadores de acceso

C++ utiliza especificadores de acceso para permitir controlar a una clase el acceso a las variables de
datos de esa clase. Los especificadores de acceso permiten acceder a algunos miembros de la clase
y restringir el acceso a otros.

Hay tres especificadores de acceso en C++: public, private y protected. Cuando usted declara
público (public) un miembro de una clase, usted permite el acceso a tal miembro desde dentro y
fuera de la clase. Los miembros de datos que son declarados protegidos ( protected ) son
únicamente accesibles por funciones miembro de la clase, pero no se pueden acceder a ellos
desde otras clases. Cuando un miembro de una clase es declarado privado ( private ) es ináccesible
no sólo desde otras clases y otras partes del programa, sino también desde sus clases derivadas.
Las clases derivadas se explicaran posteriormente.

Miremos el siguiente programa de ejemplo. Se compone de tres partes: la primera una declaración
de una clase llamada Empleado:

class Empleado
{ private:
char* m_nombre;
char* m_departamento;
char* m_posicion;
long m_salario;
public: void
ImprimirInfo();
void SetNombre( char* nombre ) { m_nombre = nombre } void
SetDepartamento( char * departamento) { m_departamento = departamento }
void SetPosicion ( char* posicion ) { m_posicion = posicion }
void SetSalario ( long salario ) { m_salario = salario } const
char* GetNombre( ){ return m_nombre } const char*
GetDepartamento( ){ return m_departamento }
const char* GetPosicion( ){ return m_posicion }
const char* GetSalario( ){ return m_salario }
};

Las funciones SetNombre, SetDepartamento, setPosicion, setSalario,


GetNombre, GetDepartamento, GetPosicion y GetSalario se denominan funciones intercaladas,
que son funciones que se declaran en una sola línea.

Las variables de miembro son declaradas privadas para que funciones de miembro de otras
funciones no tengan acceso a ellas sino a travez de la correspondiente funcion Get o Set. Las
funciones de miembro si son declaradas públicas de tal modo que se pueda acceder a ellas desde
otras funciones.

La definición de la función PrintInfo puede quedar así:

void Empleado::ImprimirInfo( )
{
cout << "Nombre: " << m_nombre << '\n'; cout <<
"Departamento: " << m_departamento << '\n';
cout << "Puesto: " << m_posicion << '\n';
cout << "Salario: " << m_salario << '\n';
}

Los dos puntos ( :: ) se denomina operador de resolución de ambito. Nos indica que la función que
estamos definiendo que en este caso es ImprimirInfo, pertenece a la clase Empleado.

La tercera parte es la función main. Veamos como podría ser:

void main()
{
//creacion de un objeto de la clase Empleado
Empleado empleado12;

//asignacion de valores a las variables miembro


empleado12.SetNombre("Jose");
empleado12.SetDepartamento("Sistemas");
empleado12.SetPosicion("Programador");
empleado12.SetSalario(3000000);
//impresion de los datos
empleado12.ImprimirInfo();
}

Entonces, primero en:

Empleado empleado12;

Se instancia un objeto de la clase Empleado con nombre empleado12. Entonces empleado12 tiene
la estructura de la clase Empleado.

Luego, en las líneas siguientes a la instanciación del objeto, se le asignan los valores iniciales a sus
variables:

//asignacion de valores a las variables miembro


empleado12.SetNombre("Jose");
empleado12.SetDepartamento("Sistemas");
empleado12.SetPosicion("Programador");
empleado12.SetSalario(3000000);

Finalmente se llama ImprimirInfo para imprimir el contenido de las variables:

//impresion de los datos


empleado12.ImprimirInfo();

que lo que hará es imprimir el valor de las variables en la pantalla.

Permitir el acceso a las variables solo a través de funciones, que en la mayoría de los casos se
llaman SetXxx y GetXxx, se llama encapsulación de datos. Las funciones que necesitan valores de
otra clase, llaman a las funciones que les dan acceso y obtienen estos datos sin conocimiento de
detalles específicos de como se manipulan los datos.

6.7.2 Operador de resolución de ambito

El operador de ámbito permíte acceder de otra manera funciones de miembro y variables de


miembro de una clase. Cuando aparece el operador de resolución de ámbito entre el nombre de la
clase y el nombre de la función en un programa significa que la función especificada es un
miembro de la clase especificada:

Empleado::ImprimirInfo();
El operador de resolución de ambito se suele utilizar para llamar funciones que se encuentran
fuera del ambito de la función de llamada. Entonces, para llamar la función ImprimirInfo() de la
clase Empleado se fuera de su ambito se debe utilizar este operador.

La principal diferencia entre este operador y los operadores punto y flecha es que el operador de
resolución de ambito se utiliza para acceder a miembros de clases, y el operador punto y flecha
para acceder a miembros de objetos específicos.

Veamos el siguiente código:

::MessageBox("Prueba del operador de resolucion");

Si el operador de resolución de ambito aparece sin un nombre de clase delante, significa que la
función que esta llamando ( MessageBox ) no es miembro de ninguna clase.

6.7.3 El apuntador this

Este apuntador lo tiene todo objeto en C++, apuntando a sí mismo. Se puede utilizar este
apuntador en cualquier lado para acceder a todos los miembros del objeto al cual está apuntando
este apuntador this. Veamos el siguiente código:

#include <iostream.h>

class Miclase
{ public:
Miclase() {} //constructor por defecto
~Miclase() {} //destructor
void yoMismo() { return this }
};

int main()
{
void* pClase; Miclase
unObjeto; pClase =
unObjeto.yoMismo(); cout<<
"El puntero pClase es "
<< pClase <<'\n.';
return 0;
}

En este ejemplo la clase yoMismo() devuelve un apuntador al objeto que lo posee de la clase
Miclase. El main() crea un objeto de la clase Miclase y luego llama a yoMismo(). Lo almacena en
pClase y luego enseña el contenido, que en este caso es el valor de la referencia. Entonces este
apuntador nos permitira realizar muchas cosas sobre los propios objetos con esta referencia.

También podría gustarte