Está en la página 1de 25

Asignatura: Introducción a la programación Carrera: Ing.

Informática
Curso: 2016-17 Año: 1ro Semestre: 1ro Semana 1 Tipo de Curso: CRD

Tema 1: Conceptos básicos de programación


Conferencia # 1: Conceptos básicos de programación

Contenidos:
1 Esquema funcional de una computadora (MCE)
2 Conceptos básicos de computación
2.1 Algoritmo
2.2 Lenguaje de programación
2.3 Programa
2.4 Código fuente
2.5 Código objeto
2.6 Compiladores e intérpretes
3 Conceptos elementales de la programación
3.1 Identificadores
3.2 Palabras Reservadas
3.3 Tipos de datos
3.4 Constantes
3.5 Variables
3.6 Expresiones
3.7 Asignación
3.8 Comentarios
3.9 Separadores
3.10 Estructuras básicas de la programación. Estructura Secuencial

Bibliografía:
3.11 Cómo Programar en C/C++. Tomo I. Segunda edición.
Harvey M. Deitel, Pail Dietel
3.12 Notas de clases

Introducción

3.13 Organización de la asignatura

La asignatura se imparte en:

Tipo de actividad Cantidad Horas


Conferencias 5 10
Clases Prácticas 21 42
Talleres 4 12
Total 64

Se divide en los temas:

1
Tema Horas
Conceptos básicos de programación 28
Estructuras de programación 18
Arreglos 18

Sistema de evaluación

 TCC
 Tarea
 Evaluaciones sistemáticas en talleres:
- Preguntas escritas para la comprobación de lectura/estudio

Introducción

Las computadoras electrónicas constituyen potentes herramientas que ayudan al hombre a resolver
problemas de diversa naturaleza. En aras de lograr este objetivo, las computadoras deben ser
programadas para que puedan desarrollar la solución a dichos problemas. Los informáticos se
encargan de analizar, diseñar e implementar estos programas o aplicaciones también conocidos como
software.

En la asignatura se estudiará cómo programar las computadoras para resolver problemas sencillos y de
mediana complejidad, para lo cual se abordarán las estructuras básicas de programación, algunos tipos
de datos y algoritmos básicos, así como, otros conceptos muy importantes para un principiante en la
materia.

El tema que comienza en esta conferencia, se ocupa del estudio de elementos básicos de
programación que permitirán en lo adelante escribir programas para ser ejecutados en una
computadora.

Para ello se estudiarán sentencias básicas de los lenguajes de programación y la sintaxis de


cada una se analizará en el marco del lenguaje C++ que ha sido el lenguaje escogido para la
introducción de los conceptos de programación. En las clases prácticas en máquinas se
utilizará el ambiente de desarrollo CBuilder que utiliza como lenguaje base, precisamente, al
C++.

Desarrollo

1.- Esquema funcional de una MCE

Una MCE o simplemente computadora, vista desde el punto de vista funcional, no es más que un
equipo que permite almacenar información para su procesamiento. Se podría esquematizar como
sigue:

2
Unidad de Entrada y Unidad de Salida: Ambas unidades permiten la comunicación
Hombre – Máquina. A través de la unidad de Entrada el hombre introduce los datos a procesar
y a través de la unidad de Salida obtiene los resultados. Entre los diferentes dispositivos que
cumplen las funciones de entrada se encuentran, por ejemplo: el teclado, el mouse, etc. y entre
los de salida el monitor o display, impresoras, plateadores, etc. A todos estos dispositivos se
les conoce también como periféricos.

Unidad Central de Procesamiento: Esta unidad es lo que llamamos computadora como tal,
ya que aquí es donde se realiza todo el procesamiento en sí. Como puede apreciarse en el
esquema en la CPU se encuentran y comunican entre sí la:

 Unidad de Memoria: Donde se almacena toda la información que entra y la que se


produce durante el procesamiento. Los datos que se almacenan en la memoria se
almacenan codificados en cadenas de ceros y unos. La menor unidad de medida de la
memoria es el bit. En 1 bit se puede almacenar sólo un cero o un uno.

La magnitud de la memoria de una computadora se suele expresar como un múltiplo de


210=1024 bytes. Esta cantidad se suele denominar 1 KB (KiloByte). La siguiente tabla
muestra algunas cantidades comunes al momento de hablar de capacidad de
almacenamiento.

Nombre Equivalencia Abreviaciones Equivalencia en bytes


Byte 8 bit
Kilobyte 1024 bytes KB, kB, K, Kbyte 210 = 1024 bytes
MegaByte 1024 KB MB 220 = 1 048 576 bytes
GigaByte 1024 MB GB 230 = 1 073 741 824 bytes
Terabyte 1024 GB TB 240 = 1 099 511 627 776 bytes

La memoria puede ser interna o externa. Se le dice memoria interna o RAM (Memoria
de Acceso Rápido, en inglés Rapid Acces Memory) a la memoria donde se carga toda
la información a procesar en un momento dado. Toda la información contenida en la
memoria interna se pierde cuando se apaga o reinicia la computadora. Físicamente son
unas tarjetas conectadas a la tarjeta madre. Según la capacidad de las tarjetas

3
conectadas la computadora tendrá más o menos memoria y se comportará más o menos
rápida. En contraposición, la memoria externa es aquella que conserva la información
aún cuando la computadora se apaga, físicamente se corresponde con las discos duros,
flopys o disquetes, CD y cualquier otro dispositivo de almacenamiento permanente, por
lo que también se le denomina almacenamiento secundario

 Unidad Lógico - Aritmética: Donde se llevan a cabo todas las operaciones aritméticas
y lógicas necesarias para el procesamiento adecuado de los datos. Esta unidad procesa
datos que están almacenados en la memoria y coloca en ésta los resultados de dicho
procesamiento.

2.- Conceptos básicos

2.1- Algoritmo

Un algoritmo es una secuencia lógica, finita y bien definida de pasos para dar solución a un tipo
determinado de problemas. Los pasos deben responder a un orden lógico, que guíe hacia la solución.
Un algoritmo debe siempre terminar luego de un número finito de pasos pues de lo contrario no se
puede garantizar alcanzar una solución. Es necesario precisar que aun cuando no es posible arribar a
una solución los algoritmos deben tener un paso final o punto de salida. Por último, se ha dicho que
cada paso del algoritmo debe ser bien definido lo que significa que debe ser especificado de manera
precisa, rigurosa y sin ambigüedades para que se entienda exactamente el significado de ellos y los
resultados intermedios queden definidos de manera única y sólo dependan de los datos de entrada y de
los resultados de los pasos anteriores. Es decir, que la misma secuencia de pasos con los mismos datos
de entrada no puede dar lugar a más de un resultado.

Nótese que la definición anterior se corresponde, lo mismo con una secuencia de pasos para resolver
un problema con la ayuda de la computadora, que con una receta de cocina o a las instrucciones de uso
de un equipo electrodoméstico. Esta observación, en modo alguno, significa que la definición anterior
sea incorrecta, sino todo lo contrario: las recetas de cocina, las instrucciones de uso de equipos y otros,
son ejemplos de algoritmos.

En esta asignatura, desde luego, nos ocuparemos sólo del estudio de aquellos algoritmos que nos
permitan la solución de problemas con la ayuda de la computadora, es decir, nos interesan sólo los
algoritmos que, de alguna manera, puedan ser representados en la computadora.

Otras características de los algoritmos:

- Entrada:
Normalmente los algoritmos reciben datos de entrada, o sea, se le proporciona información que será
procesada por él. Cada elemento de la entrada se corresponde con un objeto del dominio del problema.
- Salida:
El algoritmo produce una o más salidas, o sea, genera los resultados del procesamiento, los cuales
guardan una relación específica con la entrada.
- Efectividad:
Cuando el algoritmo es efectivo, todas las operaciones que en él se realizan son suficientemente
básicas como para que, en principio, puedan ser desarrolladas exactamente y en un tiempo finito por
una persona, usando papel y lápiz.

4
En el mundo de la programación de computadoras se utilizan diferentes formalismos para la
representación de los algoritmos. Cualquiera de ellos establece las estructuras de control para la
ejecución correcta de dichos algoritmos. Estas estructuras indican, en cada momento, la operación que
se debe realizar para alcanzar la solución del problema planteado. Algunos de los formalismos más
usados son: el seudo código y los diagramas de bloques.

 Seudo código

El seudo código, como su nombre lo indica, es una forma de representación que se asemeja al código
que se usa para la representación del algoritmo en un lenguaje de programación. Esta forma de
representación se basa en el lenguaje natural, o sea, el lenguaje que utilizan los seres humanos para
comunicarse entre sí. Esto significa que el seudo código es una representación literal de la solución
del problema. Tiene pocas reglas sintácticas, por lo que el algoritmo resulta fácil y rápido de
desarrollar, y no tiene en cuenta la sintaxis de los lenguajes de programación, por lo que, mediante él,
se puede representar casi cualquier operación.

Como el seudo código se expresa en forma literal, cada programador o equipo de programadores
pueden inventar el suyo propio. Generalmente se usan palabras que denotan las acciones a realizar
como: Entrar, Hacer, Repetir, Mientras, Calcular, Si, Entonces, Sino, Mostrar, etc. También se usan
palabras para enmarcar conjuntos de pasos, por ejemplo: Inicio, Fin, etc., y para las operaciones
matemáticas y comparaciones se usan símbolos como los del álgebra y la lógica matemática, ejemplo:
+,-, y, o, <, =, etc.

 Diagrama de bloques

El diagrama de bloques es una representación gráfica de los algoritmos. Se basa en el uso de figuras
geométricas, cada una de las cuales representa una estructura que controla la ejecución del algoritmo.

Las figuras geométricas son enlazadas entre sí por flechas que establecen el flujo de la ejecución del
algoritmo, o sea, el orden en que debe ejecutarse sus operaciones o instrucciones. Por lo general, las
instrucciones se representan a través de rectángulos.

Este es un formalismo que en la actualidad apenas se usa por los programadores, por varias razones,
ente ellas:
- requieren mucho espacio para poder representar algoritmos aun cuando estos no son de muchos
pasos ni tan complejos,
- constituyen una representación intermedia bastante distante de la representación final
- en algunos casos los símbolos gráficos no son capaces de expresar toda la semántica asociada a un
paso concreto.

 Pasos para resolver un problema con una computadora

1. Comprensión y análisis del problema planteado


2. Desarrollo de un modelo matemático que dé solución al problema
3. Desarrollo de la solución del problema mediante un algoritmo
4. Programación de la solución para la computadora

Es evidente que esta metodología constituye un algoritmo, que establece los pasos necesarios para dar
solución a un problema.

5
En el primer paso de este algoritmo se estipula que el problema ha de entenderse correctamente antes
de acometer su solución. Es obvio que no podremos dar solución a un problema sin entenderlo
previamente, es decir, sin saber qué es lo que hay que resolver. Luego de entender el problema
planteado, se analiza cuáles son sus características, en aras de enfocar correctamente su solución, o
sea, cómo acometerla.

El segundo paso plantea que una vez que se ha comprendido y analizado el problema, se procede al
desarrollo de un modelo matemático que presente la solución teórica del problema. Este modelo
matemático, por supuesto, debe corresponderse con las características analizadas en el paso anterior,
puede apoyarse con gráficos y fórmulas, según sea el caso. Es aquí donde debe quedar claro cuáles son
los datos que son necesarios para el cálculo, o sea, los datos de entrada, cómo ellos son procesados, y
cuáles son los resultados esperados de dicha solución, o sea la salida.

En el tercer paso se establece que con el modelo matemático están dadas las condiciones para
desarrollar la secuencia de pasos –o sea, el algoritmo– necesaria para dar solución al problema.

El último de los pasos plantea el desarrollo, a partir del algoritmo, de un programa escrito en un
lenguaje para la computadora, con el cual se le “instruye” de cuáles pasos seguir para resolver el
problema.

2.2- Lenguaje de programación

Un lenguaje de programación es aquel que se utiliza para escribir algoritmos que serán
ejecutados en computadoras, por lo que puede considerarse un lenguaje intermediario que
permite determinada comunicación entre el hombre y la computadora. De una manera
informal se puede definir como un conjunto de reglas sintácticas que permiten formar
sentencias con un valor semántico asociado según la gramática definida para el lenguaje. Todo
lenguaje de programación define su propio alfabeto, cuyos símbolos son caracteres
alfanuméricos o cadenas de éstos.

Los lenguajes de programación han evolucionado desde los lenguajes de máquinas hasta los
supe lenguajes o lenguajes de alto nivel. Los primeros son lenguajes de muy bajo nivel, más
cercanos a las máquinas, en los que se escriben instrucciones muy simples y que resultan
muy incómodos para el hombre, por ejemplo Ensamblador. Los últimos son lenguajes que
resultan más comprensibles y fáciles de usar por los hombres pues utilizan algunos términos y
reglas sintácticas de los lenguajes naturales para la construcción de instrucciones.

2.3- Programa

En el mundo de la computación se conoce como programa a todo conjunto de órdenes,


escrito en un lenguaje de programación, que pueden ser ejecutadas por una computadora
produciendo determinado comportamiento de ésta. Un programa no es más que un algoritmo
trascrito en cierto lenguaje de programación y dirigido a una computadora [Zam86].

“Así, de manera intuitiva, se puede definir un programa como una serie de instrucciones
expresadas de una manera más o menos elemental, (según el lenguaje utilizado), que se da a
una computadora para que la misma pueda seguir los caminos lógicos del algoritmo que él
representa.” [Zam86]

6
Toda la comunicación de los usuarios con las computadoras se produce gracias a la ejecución
de algún programa y a través de éste.

Como consecuencia del aumento lógico de la complejidad de los programas y del cambio de
paradigma de interacción hombre-máquina, el arte de la programación, o sea de la escritura de
programas para computadoras ha transitado por diferentes etapas caracterizadas por el estilo
asumido al abordar el diseño de éstos. La etapa de programación monolítica, se caracterizó
por un diseño de programas considerados como un todo, los cuales eran mejores mientras más
sofisticados eran, más tareas realizaran y más memoria ahorraban. Optimizar era una señal de
eficiencia. Se utilizaban los diagramas de bloques como herramientas para representar los
algoritmos. La programación monolítica era incapaz de dar respuesta al crecimiento de los
programas tanto en tamaño como en complejidad. A esta le siguió, por tanto, una nueva etapa
conocida como de programación modular o estructurada y que puede resumirse en un estilo
de diseño de programas basado en la técnica de divide y vencerás, a partir del cual un
programa puede concebirse como un conjunto de módulos cada uno de los cuales implementa
una función determinada, tiene una sola entrada y una sola salida y puede ser probado
independientemente. Para representar los algoritmos a implementar por los diferentes
módulos se utilizaban todavía los diagramas de bloques. Este nuevo estilo de programación,
aunque no era la respuesta final, permitió aumentar el personal en los equipos de
programación y contribuyó al ahorro de tiempo y recursos. Para el diseño modular la piedra
angular son las tareas a desarrollar para solucionar el problema, cada una de las cuales puede
desempeñarse en un módulo de relativa independencia. Entre estos módulos viajan los
distintos datos necesarios para resolver cada tarea concreta de manera que a cada uno llegan
solamente aquellos que son necesarios. Otra forma de abordar la programación es con un
enfoque más centrado en la modelación de los objetos del problema a resolver, o lo que es lo
mismo los datos y las operaciones sobre éstos, la cual ha dado lugar a una etapa marcada por
un diseño de programas orientados a los objetos. Este estilo de abordar la programación no
echa por tierra los principios de la programación modular sino que los complementa elevando
ésta a un nivel cualitativamente superior. Por último, el diseño orientado a objetos ha dado
lugar al surgimiento de las interfaces gráficas de usuarios y esto a su vez ha dado lugar a un
nuevo estilo de programación denominado programación guiada por eventos que centra la
atención del diseño de los programas en la atención a los distintos eventos que pueden ser
generados durante la ejecución de una aplicación y que pueden ser originados por los
usuarios, otras aplicaciones y los propios objetos.

Se dice que un lenguaje de programación soporta un determinado enfoque o estilo de


programación, si cuenta con herramientas que garantizan y velan por la implementación
adecuada de las estructuras básicas de dicho estilo. Así por ejemplo, se dice que Fortran (en
sus últimas versiones), Basic, Quick Basic y Pascal y C (estos últimos en algunas de sus
versiones iniciales) son lenguajes estructurados, Smalltak, Java son lenguajes orientado a
objetos puro, otros como Turbo Pascal 5.5 y superiores, Borland Pascal, Object Pascal y C++
son lenguajes híbridos pues soportan más de un enfoque o la combinación de ellos
(estructurado + orientado a objetos).

Existen otros estilos de programación aunque no se reconocen etapas caracterizadas por el uso
de dichos estilos, pues nunca se han usado de manera masiva por los programadores, ni para

7
abordar cualquier tipo de problemas, sino un grupo reducido y específico de éstos. Es el caso
de la programación descriptiva (soportada por Prolog) y la programación funcional
(soportada por Lisp)

 Aplicación

Gracias a la evolución del hardware y el software, se construyen hoy en día programas o


sistemas de computadoras que resuelven problemas cada vez más complejos y donde se
procesan generalmente grandes volúmenes de información. Dichos sistemas pueden verse por
su nivel de complejidad y estructuración como un conjunto de programas más simples
relacionados entre sí, por lo que se prefiere utilizar el término aplicación para acuñarlos. No
obstante, es muy común el uso de los términos programas y aplicación indistintamente.

2.4- Código fuente

A los programas escritos en lenguajes de programación se les llama código fuente. O sea, los
programadores escriben código fuente.

2.5- Código objeto

Los programas en código fuente son comprensibles por el hombre pero no son directamente
comprensibles por la máquina. Para que esto suceda, o sea, para que el código fuente pueda
ser entendido y ejecutado por la computadora, es necesario traducirlo a código objeto, que es
el código de máquina.

2.6- Compiladores e intérpretes

El proceso de traducción del código fuente al código objeto se puede realizar de diferentes
maneras.

Traductor
Código Fuente Código Objeto
(Compilador o
Intérprete)

Los intérpretes realizan la traducción sentencia por sentencia y garantizan que cada sentencia
traducida a código objeto sea ejecutada al momento. Una vez que una sentencia ha sido
ejecutada se traduce y ejecuta la siguiente sentencia que aparezca en el código fuente. Los
compiladores traducen todo el código fuente generando el código objeto del programa
completo, el cual podrá ser ejecutado de una vez.

8
Sentencia X
Programa Intérprete Sentencia X
Fuente ejecutada
por la MCE

La compilación permite, a diferencia de la interpretación, guardar los documentos en código


objeto para que puedan ser ejecutados nuevamente sin necesidad de realizar la traducción otra
vez. Por otra parte, durante la traducción se encuentran los errores de sintaxis en el código
fuente o sea, las sentencias mal escritas, si éste proceso se realiza a través de un compilador el
mismo se convierte además en un proceso de depuración de errores que culmina cuando el
programador ha eliminado todos y cada uno de los errores de este tipo, por lo que se puede
asegurar que el código fuente es sintácticamente correcto.

Compilador Programa
Programa
Fuente Objeto

Los ambientes de desarrollo incluyen compiladores o intérpretes, por ejemplo, para todas las
versiones de Pascal y de C se han construido compiladores. La mayoría de las versiones
iniciales de Basic estaban montadas sobre intérpretes. Por las ventajas que ellos reportan, en
la actualidad se construyen más compiladores que intérpretes, de ahí que la mayoría de los
ambientes modernos incluyen un compilador.

Por lo general estos sistemas de programación permiten guardar tanto los códigos fuentes
(archivos con extensión: PAS en Pascal, C, H, etc. en C, por sólo citar algunos ejemplos)
como los códigos objetos (archivos con extensión DCU, OBJ, etc.). Los archivos con
extensión EXE contienen código objeto previamente preparados (enlazados con las
bibliotecas necesarias) para una total autonomía. Esa es la razón por la que al hacer doble
click sobre ellos, se ejecuta directamente la aplicación en cuestión, sin necesidad de ejecutar
la herramienta utilizada para su elaboración. Sin embargo, si se hace doble click sobre un
archivo, por ejemplo, PAS se cargará automáticamente la versión de Pascal o Delphi
instalada en la máquina y éste podrá ser ejecutado sólo desde allí. O sea, se puede concluir
que un código sólo puede ser ejecutado en una máquina si es un código objeto o si se
encuentra instalado en dicha máquina el ambiente de desarrollo que contiene al compilador o
intérprete que lo reconoce.

9
Programa Compilador Programa Enlazador Programa
Fuente Objeto Ejecutable

COMPUTADORA Bibliotec
a
COMPUTADORA
Es muy importante aclarar que las herramientas de desarrollo no disponen de facilidades para
realizar el proceso inverso a la compilación, por lo que los programadores son responsables de
guardar los códigos fuentes de sus programas para futuras modificaciones.

Código Fuente Traductor Código Objeto

3.- Conceptos elementales de la programación.

3.1- Identificadores

Los identificadores son cadenas alfanuméricas, o sea, cadenas de letras y dígitos, que sirven
para identificar, o sea nombrar, algún elemento de un programa. En la mayoría de los
lenguajes de programación estas cadenas deben comenzar con letra y pueden contener el
símbolo subrayado, “_”. Se usan para denotar variables, constantes, módulos, etc.

La cantidad de caracteres que se admite para formar dichas cadenas puede variar de un
lenguaje a otro e incluso de una versión a otra de un mismo lenguaje. Por lo general no se
permiten letras acentuadas como parte de los identificadores.

Algunos compiladores de Pascal o cualquiera de sus versiones no diferencian las minúsculas


de las mayúsculas dentro de cadenas usadas como identificadores, otros como los de C sí
hacen distinción entre mayúsculas y minúsculas.

Ejemplos válidos en C++


1. A
2. Alfa
3. Radio1
4. CentroDeMasa
5. Perimetro_del_cuadrado

10
Note que como C distingue entre mayúsculas y minúsculas, el primer identificador no sería el
mismo que “a”, ni el segundo sería el mismo que “alfa” o “alFa”, etc.

Los estándares de codificación más difundidos actualmente entre los programadores usan el
estilo mostrado en el ejemplo válido no. 4, o sea, cada palabra que compone el identificador
comenzando con mayúscula y el resto de las letras minúsculas.

Ejemplos no válidos en C++


1. 1Beta  no puede comenzar con número
2. A3   no es un carácter no permisible
3. BaseDeTriángulo  no se permiten caracteres acentuados (á)
4. Longitud-Cilindro  no se permite el carácter –

Recomendaciones para el uso de identificadores.


1. Elegir identificadores que al leerse refieran el contenido del elemento en cuestión.
2. Elegir identificadores que sean pronunciables y entendibles.
3. No usar abreviaturas a menos que sean muy claras.
4. Evitar usar caracteres numéricos que puedan confundirse con letras como son los casos de
1(uno) y l (ele minúscula), 2 y Z, 0 y o, etc.

3.2- Palabras reservadas

Las palabras reservadas son cadenas de caracteres alfanuméricos cuyo uso, como su nombre
lo indica, está reservado para el compilador. Esto significa que no se pueden utilizar como
identificadores de elementos en los programas.

Ejemplos

int, if, else, for, do, while, char, struct, void, return

Existen otras muchas palabras reservadas en el lenguaje. Para poder diferenciarlas de los
demás identificadores en los documentos se usarán en negritas. Así se diferencian,
generalmente en los editores de código.

3.3- Tipos de datos

Un tipo de dato define:


 un tipo de valor (numérico, de caracteres, lógico, etc.)
 un rango de posibles valores de ese tipo, y
 la cantidad de memoria que se necesita para almacenarlo.
Los tipos de datos se utilizan para construir otros identificadores contenedores de datos.

Algunos ejemplos de tipos de datos son:

11
 el tipo definido por todos los caracteres alfanuméricos incluyendo letras mayúsculas,
minúsculas, dígitos y el resto de los caracteres posibles y que necesitan sólo un byte de
memoria para almacenarse,
 el tipo definido por los valores lógicos verdadero y falso y que necesitan sólo un byte de
memoria para almacenarse,
 el tipo definido por los valores numéricos enteros, con o sin signo, entre –2147483648 y
2147483647 y que necesitan 4 bytes de memoria para almacenarse,
 el tipo definido por los valores numéricos reales entre 5.0 x 10^–324 y 1.7 x 10^308 de
15 a 16 dígitos significativos y que necesitan 8 bytes de memoria para almacenarse,
 etc.

A cada tipo de dato se le asocia un identificador a través del cual se hace referencia al mismo.

Los lenguajes de programación definen algunos tipos de datos que los programadores pueden
utilizar en sus programas, los cuales se conocen como tipos estándar. Estos pueden variar de
un lenguaje a otro e incluso entre las distintas versiones de un mismo lenguaje, por lo que es
responsabilidad del programador conocer exactamente cuáles tipos de datos estándar existen y
las características de aquellos que requiera utilizar.

También se utilizan en programación los términos tipo de dato simple y tipo de dato
estructurado. Los tipos simples son aquellos que hacen referencia, en cada instante, a un solo
valor de los posibles. Para él se reserva una sola localización de memoria en la se puede
almacenar un valor o leer el valor que allí esté almacenado. Los estructurados, como su
nombre lo indica, son estructuras de datos que agrupan varios valores. Por esta razón los
tipos simples constituyen la base de cualquier otro tipo de dato estructurado. En la primera
parte de la asignatura se trabajará solamente con tipos de datos simples.

Se dice que un tipo es ordinal, si sus valores responden a un orden dado, por lo que es
posible hablar del predecesor y sucesor de cualquiera de ellos. Nótese que el concepto de
ordinal no es inherente a los números reales.

Algunos de los tipos de datos simples estándar definidos en C++ (Cbuilder 6.00) son:
 int para enteros
 float para Reales
 char para Caracteres
 bool para Lógicos (valores posibles: false, true. Es ordinal, false precede a true)

Se propone que investiguen los rangos de valores posibles en cada caso y el espacio que
ocupan en memoria así como otros tipos de datos estándar en C++.

Por otra parte, algunos lenguajes dan libertad a los programadores para que definan sus
propios tipos de datos. Esto constituye una gran ventaja pues permite trabajar con tipos de
datos más cercanos al problema concreto que se pretende resolver y por tanto aumenta la
claridad de los programas. En la primera parte del curso se trabajará solamente con los tipos
estándar.

12
3.4 Constantes

En muchas situaciones se utilizan valores constantes para realizar diferentes cálculos. Tal es el
caso, por ejemplo, de la constante Pi tan utilizada en las matemáticas para cálculos
trigonométricos. Como su nombre lo indica, las constantes son valores que no varían en
ningún cálculo.

Declarar o definir una constante en un programa significa declarar un identificador a través


del cual se hará referencia a un valor constante en el programa, o sea un identificador que se
asocia a un valor que no cambia durante la ejecución.

Los lenguajes de programación incluyen muchas constantes ya definidas, que el programador


puede utilizar y generalmente brindan a éstos la posibilidad de declarar sus propias
constantes.

La declaración de las constantes, en C++, se puede realizar de dos maneras, una a través de la
directiva al compilador “define” y la otra, través del calificar const con la sintaxis siguiente:

<#define> <identificador de constante> <valor >


<const> [identificador de tipo de la constante] <identificador de constante> = <valor>;

donde:
identificador de constante: es el identificador, escogido por el programador para referirse a la
constante en el cuerpo del código.
valor: valor al cual hará referencia la constante en el cuerpo del código.
identificador de tipo de la constante: identificador de algún tipo de dato estándar o algún tipo
de dato previamente definido por el programador

Nota: Al definir la sintaxis se usarán los corchetes angulares, <> para indicar algo que es
obligatorio que aparezca en la sentencia y los corchetes rectangulares, [], para indicar algo
que es opcional, o sea que no es obligatorio que aparezca dentro de la sentencia.

Ejemplos

const max =100;


#define ConstanteCalibracion 2.956834544;

En el código donde aparezcan las declaraciones anteriores se puede hacer referencia a los
valores 100 y 2.956834544 a través de los identificadores max y ConstanteCalibracion
respectivamente. Esto reporta las siguientes ventajas, en primer lugar donde quiera que sea
necesario utilizar esos valores se pueden colocar sus identificadores, en segundo lugar y como
consecuencia de lo anterior, si fuese necesario en un momento posterior modificar algunos de
estos valores, bastará con modificar la declaración de la constante en lugar de tener que
modificar todos aquellos lugares del código donde aparezcan.

13
En C++ las constantes se deben declarar siempre antes de usarlas por primera vez.

3.5- Variables

En los lenguajes de programación se le llama variable a todos los identificadores a través de


los cuales se pueden almacenar datos en la memoria durante la ejecución de los programas y
acceder a ellos. Toda variable tiene un identificador, un tipo y un valor. Las variables pueden
referenciar datos simples o datos estructurados lo cual depende de la forma en que haya sido
declarada la variable. El siguiente esquema ilustra de manera gráfica el almacenamiento de
algunas variables en memoria:

Nótese que a cada variable se asocia una zona de memoria de un tamaño suficiente, según el
tipo de dato, para almacenar sus valores.

Para declarar las variables se usa el identificador de tipo de la variable seguido del
identificador de variable. La sintaxis (regla de escritura) es:

<identificador de tipo> <identificador de variable>

donde:
identificador de tipo: identificador de tipo estándar o algún otro tipo previamente definido
por el programador, que permite al compilador conocer la memoria que debe reservar
para el uso de dicha variable y además hacer chequeos de compatibilidad durante la
ejecución del código.
identificador de variable: es el nombre, escogido por el programador para hacer referencia,
durante el cuerpo del código, al valor almacenado en la zona de memoria
correspondiente a la variable.

La declaración de variable, en C++, se realiza donde se usa por primera vez la variable o en
cualquier parte del cuerpo previo a que sea usada por primera vez. Una misma variable debe
ser declarada una sola vez. El alcance de una variable empieza en su declaración y se extiende
hasta la llave derecha de cierre (}) del bloque donde se declaró. Por lo tanto, enunciados
anteriores a la declaración de la variable no pueden hacer referencia a ella, aun si están dentro

14
del mismo bloque. De la misma manera no pueden ser referenciadas por enunciados
posteriores al cierre del bloque.

Cuando se hace la declaración de una variable se está indicando al compilador en tiempo de


compilación que reserve en la memoria interna el espacio necesario para guardar el valor de
dicha variable. El espacio reservado sólo será usado para este fin durante la ejecución de la
aplicación y a través del identificador de la variable se podrá acceder a él ya sea para guardar
o recuperar la información. A este tipo de reservación se le llama reservación estática.

A diferencia de las constantes, las variables pueden tomar diferentes valores durante la
ejecución del código. Cada vez que una variable cambia su valor se actualiza la zona de la
memoria donde ella se almacena, por lo que el valor almacenado allí anteriormente se pierde.

Ejemplos
float DaimetroInterior;
int CantidadTrabajadores;
char Consonante;
bool EsVisible;

En la variable DiametroInterior, se pueden almacenar valores reales, mientras que en


CantidadTrabajadores se pueden almacenar números enteros. La variable no numérica
Consonante permitirá manipular caracteres (uno en cada instante de tiempo). EsVisible podrá
guardar, uno de los valores true o false.

Si en algún momento de la ejecución del código se trata de almacenar en una de estas


variables un valor no permitido el compilador generará un mensaje de error y se detendrá la
ejecución. A este chequeo realizado por el compilador se le denomina chequeo de
compatibilidad de tipos.

Las variables en C++ pueden ser inicializadas con un valor en la declaración como se muestra
a continuación:

int CantidadTrabajadores= 100;

En una declaración pueden declararse más de una variable, en ese caso se usa la coma “,” para
separar las variables entre sí. Todas las variables serán del tipo especificado al inicio de la
declaración. Ejemplo:

float r, s= 1.5;

En este ejemplo se reserva espacio para una variable flotante r y para otra variable flotante s.
Esta última se inicializa con el valor 1.5.

15
Ejemplo del uso de variables Memoria

int a = 20, b = 10; 20 10

… Localización Localización
… reservada para a reservada para b es
… es inicializada en 20 inicializada en 10

int suma;

… Localización
… reservada para suma

Nótese del ejemplo que la declaración es la que indica que se haga la reservación de espacio
en la memoria. Por tanto:
 No se puede usar una variable que no se haya declarado previamente.
 Se reservarán tantos bytes como requiera el tipo especificado en la declaración.

Es necesario explicar que aunque el programador no asigne ningún valor a una variable, una
vez que ésta se ha declarado, el espacio de memoria quedará reservado y no se puede asumir
que está vacío. Por el contrario, allí siempre habrá algún valor. Una forma de comprobar esto
es declarando una variable e inmediatamente mostrar su contenido. Hay algunos compiladores
que inicializan las variables en valores por defecto, por ejemplo las numéricas en 0, las
lógicas en false, etc., pero muchos no lo hacen, por lo que una buena práctica es asumir como
responsabilidad del programador inicializar las variables siempre que sea necesario. En el
ejemplo anterior se ha representado que el programador no ha asignado ningún valor a la
variable suma, no que su localización esté vacía.

3.6- Expresiones.

Expresión: conjunto de operandos combinados entre sí, a través de operadores. Los


operadores indican la operación a realizar. A toda expresión se asocia un valor que depende
del valor de cada operando en el momento de su evaluación y de las operaciones indicadas
entre ellos por los operadores.

Las expresiones según el resultado de su evaluación pueden ser:


3.13.1 Numéricas, al evaluarlas se obtiene un valor numérico producto de la combinación
de operandos numéricos a través de operadores aritméticos.
3.13.2 Lógicas, al evaluarlas se obtiene un valor lógico, producto de la combinación de
operandos del mismo tipo a través de operadores de relación, o de otras expresiones
combinadas a través de operadores lógicos. Se estudiarán en la Clase Práctica # 2.

También se puede hablar de expresiones de cadenas alfanuméricas y otros tipos de


expresiones, pero en este momento del curso no es de interés profundizar en ellas.

Los operadores, según la cantidad de operandos que combinan, pueden ser:

16
 Unarios, operan sobre un solo operando. Tal es el caso del cambio de signo en los
números y de la potenciación.
 Binarios, operan sobre dos operandos. Ejemplo el operador de suma, el de multiplicación,
etc.
 Ternarios, operan sobre tres operandos.

Y según el resultado de la operación en:


 Aritméticos: operan sobre operandos numéricos.
Suma: +
Diferencia: –
Multiplicación: *
Binarios División: / (entre enteros el resultado siempre será un entero, la parte
entera del resultado. Si al menos uno de los operandos es
algún tipo de número real, el resultado de la expresión es
real)
Módulo (Resto de la división): %

Unario Cambio de signo: – (unario)

 Lógicos: Estudiar en el punto 3 del Estudio Independiente.

Los operandos de una expresión pueden ser cualquier identificador contenedor de datos como
constantes, variables y otros que se verán más adelante, así como otras expresiones. Los
identificadores de tipos no pueden formar parte de una expresión, pues no son contenedores
de datos.

En el caso particular de C existe un único operador ternario (que opera sobre tres operandos)
que es el Operador Condicional que se estudiará en próximas conferencias.

Precedencia de los operadores:

Operadores aritméticos Prioridad Sentido en que


- Cambio de signo 0 aumenta la
*, / , % 1 prioridad
+, - 2

Al evaluar una expresión se realizan las operaciones de izquierda a derecha, y según la


precedencia de los operadores que aparecen en ella. Para violar la precedencia de los
operadores, se pueden utilizar paréntesis () dentro de las expresiones, con las mismas reglas
conocidas del álgebra. No se pueden usar para esto los corchetes, pues están reservados para
otro uso en el lenguaje.

17
Ejemplos de expresiones

1. x+y*z
2. Alfa * 22 – h
3. Pi * Radio * Radio
4. (h + s) / (n * q)

3.7- Asignación.

La sentencia de asignación es aquella a través de la cual se asigna un valor a una variable. Se


utiliza para ella el operador de asignación = y responde a la siguiente sintaxis:

<identificador de variable>= <expresión>;

Esta instrucción asigna a la variable, especificada en la parte izquierda, el valor resultante de


la evaluación de la expresión dada. O sea, primero se evalúa la expresión y luego el resultado
se deposita en la localización de memoria asociada a la variable en cuestión. El sentido de la
asignación siempre es de derecha a izquierda, por lo que la variable que debe recibir el valor
debe encontrarse siempre a la izquierda de la asignación, que se representa por “=”. Es
importante resaltar que una asignación no es una igualdad, aunque a veces por comodidad se
lea de esa forma.

El tipo de la variable de la izquierda tiene que ser compatible al del resultado de la evaluación
de la expresión de la derecha, de lo contrario el compilador generará un error de
incompatibilidad de tipos.

Ejemplos

1. x= x + 1;
2. float AreaCirculo = Pi * Radio* Radio;
3. float AreaTriangulo = Base * Altura;
4. int Resto:= k % n;
5. float AreaSemiCirculo:= AreaCirculo / 2;

Todos los ejemplos anteriores requieren, por supuesto, que los identificadores que no
aparecen declarados hayan sido previamente declarados, tal es el caso de x, Radio, Base,
Altura, EsVisible, k, n. Obsérvese que dichos operadores no pueden ser declarados en estas
expresiones, pues se supone que tienen un valor que es usado en la expresión, por tanto ya
debieron haber sido declarados en algún momento previo en el programa donde aparezcan
dichas sentencias de asignación.

18
Ejemplo Memoria

int a = 20, b = 10; 20 10

… Localización Localización
… reservada para a reservada para b e
… e inicializada en 20 inicializada en 10

int suma;

… Localización
… reservada para suma

suma= a + b; Mantienen su
30 valor

… Localización
… reservada para suma
actualizada con el nuevo valor

Veamos la secuencia de pasos (algoritmo) que realiza el compilador para realizar las
operaciones del ejemplo anterior:

int a= 20, b= 10; Esta secuencia es equivalente a:


int suma; int a= 20, b= 10;
suma= a + b; int suma= a + b;

Pasos:
1) Reserva espacio para un número entero que identificará como a y escribe en ese espacio el
número 20
2) Reserva espacio para un número entero que identificará como b y escribe en ese espacio el
número 10
3) Reserva espacio para un número entero que identificará como suma
4) Va al espacio identificado como a y toma su valor
5) Va al espacio identificado como b y toma su valor
6) Suma ambos valores y el resultado lo almacena en el espacio identificado como suma.

3.8- Comentarios

Para aumentar la claridad del código es una buena práctica documentarlo con comentarios. Un
comentario no es más que algún texto que se coloca dentro del código, para hacer éste más
explícito, y que es ignorado por el compilador durante la ejecución o sea, no hacen que la
computadora realice ninguna acción. Los comentarios no generan código objeto en lenguaje
de máquina.

En C++ los comentarios se pueden escribir como sigue:


/* aquí va el comentario..
que puede abarcar tantas líneas como se desee */

19
Otra forma:

// esto también es un comentario pero que termina con el fin de línea

Ejemplos de comentarios
 /* Este programa calcula potencia entera*/
 /*Ultimo cambio realizado el 23-10-2005*/

3.9- Separadores

Todo lenguaje de programación establece una forma de indicar o reconocer el fin de una
sentencia. En muchos se utiliza el Enter o fin de línea como separador, lo cual tiene el
inconveniente de obligar a una sentencia por línea.
En C++ se utiliza como separador el punto y coma “;” y esto da la posibilidad de escribir más
de una sentencia en una misma línea de código.

3.10- Estructuras básicas de la programación

Al inicio de la década del 60 comenzaron a aparecer trabajos sobre la programación


estructurada. De manera general, todos de una forma u otra coincidían en afirmar que para
escribir códigos claros y correctos sólo se necesitaban tres estructuras de programación:
a) secuencial
b) alternativa
c) repetitiva
La estructura secuencial, es simplemente la idea de que las sentencias de un código son
ejecutadas en el orden en que aparecen en él. A través de estructuras secuenciales se
implementan fragmentos lineales de los algoritmos.

Ejemplo de estructura secuencial


Problema: Veamos como programar una secuencia que calcule el volumen de un cilindro
hueco conocidos su radio interior, radio exterior y su longitud.

Primero analicemos el modelo matemático:

Área del círculo:


a = ∏. r^2
Volumen del cilindro
V = Área de la base . Longitud = ∏ . r^2 .l
Área de la base:
AB= Área Círc. Ext. - Área Círc. Int
Volumen del cilindro hueco:
VCH= AB . l

20
/*el siguiente fragmento corresponde a una secuencia que calcula el volumen de un cilindro
hueco conocidos su radio interior, radio exterior y su longitud*/

const float pi = 3.1416;


…..
float RadioExterior, RadioInterior, Longitud;
float AreaBaseExterior= pi * RadioExterior * RadioExterior;
float AreaBaseInterior= pi * RadioInterior * RadioInterior;
float AreaBase= AreaBaseExterior – AreaBaseInterior;
float Volumen= AreaBase * Longitud;
….

Por supuesto, para que este conjunto de sentencias de asignación se pueda ejecutar es
necesario que las variables RadioExterior, RadioInterior y Longitud tomen valor previamente.
Más adelante en el curso se verán distintas formas en que esto puede hacerse, por el momento
lo simularemos con la palabra ENTRAR de la siguiente manera:

const float pi = 3.1416;


…..
float RadioExterior, RadioInterior, Longitud;
ENTRAR RadioExterior; //aquí se está simulando una entrada de datos
ENTRAR RadioInterior; //hasta que en próximas conferencias se estudien
ENTRAR Longitud; //las sentencias del lenguaje para ello
float AreaBaseExterior= pi * RadioExterior * RadioExterior;
float AreaBaseInterior= pi * RadioInterior * RadioInterior;
float AreaBase= AreaBaseExterior – AreaBaseInterior;
float Volumen= AreaBase * Longitud;
MOSTRAR Volumen; //aquí se está simulando una salida de datos
….
De la misma manera se ha simulado la visualización del resultado con la palabra MOSTRAR.

Conclusiones

En esta conferencia se han estudiado conceptos y elementos básicos de la programación que


son independientes del lenguaje y para ejemplificarlos se ha utilizado la sintaxis del C/C++.
La comprensión de los conceptos expuestos en esta conferencia es de vital importancia para la
compresión del resto del contenido del tema.
Una vez culminada la exposición los estudiantes deben ser capaces de responder:
¿Qué es un lenguaje de programación?
¿Qué es un programa?
¿Qué son los compiladores e intérpretes?
¿Qué es un programa fuente y un programa objeto?
¿Qué son y cómo se implementan en C++, los identificadores, las variables y las constantes?
¿Cuál es la regla de la precedencia de la declaración?
Los operadores y las expresiones aritméticas
La sintaxis y significado de la sentencia de asignación

21
Escribir alguna estructura secuencial sencilla en C++ con expresiones aritméticas y
asignación

Estudio independiente
1. Estudiar para la comprobación de lectura del Taller # 1
a) Capítulo 1 del libro de texto
b) Notas de clases
c) Los operadores lógicos
Como se vio en la conferencia los operadores pueden ser numéricos y lógicos. A
continuación se explican los operadores lógicos y los resultados de las expresiones
lógicas según los operadores involucrados.
 Relacionales: operan sobre cualquier par de operandos que sean del mismo tipo.
Igual que: ==
Menor que: <
Menor o igual que: <=
Mayor que: >
Mayor o igual que: >=
Diferente de: !=
 Lógicos: operan sobre operandos lógicos.
Negación lógica: !
Conjunción lógica: &&
Disyunción lógica: ||

El resultado de las expresiones que involucran a operadores lógicos se obtiene siguiendo lo


especificado en las tablas de verdad de cada operador, las cuales se muestran a continuación:

&& (y lógico)
Operando 1 Operando 2 Resultado
true true true
true false false
false true false
false false false

Note que sólo es true si ambos operandos son true

|| (o lógico)
Operando 1 Operando 2 Resultado
true true true
true false true
false true true
false false false

Note que sólo es false si ambos operandos son false

! (negación lógica)

22
Operando Resultado
true false
false true

Note que el resultado siempre es lo contrario del operando.

Existen otros operadores que no aparecen en la relación anterior pues se utilizan entre
operandos de tipos que no serán vistos por el momento.

Precedencia de los operadores, estudiados hasta ahora, teniendo en cuenta los operadores
lógicos:

Operadores aritméticos y lógicos Prioridad


- cambio de signo 0
! 1
*, /, % 2
+, - 3
<,<=, >, >= 4
= =,!= 5
&& 6
|| 7
= 8

Recordemos que para violar la precedencia de los operadores, se pueden utilizar paréntesis
dentro de las expresiones, con las mismas reglas conocidas del álgebra.

Al evaluar una expresión se realizan las operaciones de izquierda a derecha, y según la


precedencia de los operadores que aparecen en ella.

Ejemplos de expresiones lógicas

1. EsVisible && a > b /*se supone que EsVisible es una variable bool que ya ha
tomado valor y a y b son otras dos variables de cualquier tipo
también previamente declaradas y con algún valor*/
2. !(x = = z) || (b < 10) //Es equivalente a !(x = = z) || b < 10
3. !x = = z || b < 10 //Es diferente a la anterior aquí en lugar de negar el resultado de la
igualdad se niega el valor de x.
4. !(x = = z) || b < 10 //Equivalente a 2

2. Ejercicios a resolver para el Taller #1

i. ¿Qué sucede con un virus si se aloja en RAM y usted apaga el equipo?


ii. Suponga que quiere ocupar toda la capacidad de un disco DVD de una capa para
guardar canciones MP3. ¿Cuántas canciones puede almacenar aproximadamente?. ¿Y
si en vez de un DVD posee un CD de 700 MB?
iii. ¿Cuál es la capacidad máxima de un disquete de 3.5 pulgadas?.

23
iv. Suponga que ha escrito 5 páginas del informe de programación o ha programado gran
parte del código de una aplicación, cuando de repente se corta el suministro de energía
eléctrica. ¿Qué sucede si usted no ha guardado la información en disco duro, o en
algún otro medio de almacenamiento secundario? ¿Qué medidas adoptaría usted para
evitar perder información?
v. En un bloque de un programa aparece el siguiente fragmento de código
{…..
int a = 10;
int b;
int c = a* b;
MOSTRAR c;
…}
a) ¿En cuál memoria se reserva espacio para las variables a, b y c?
b) La memoria para las variables a, b y c se reserva durante la:
_____Compilación o _____ la Ejecución. Marque la respuesta correcta.
c) La memoria reservada para las variables a, b y c se libera cuando se muestra c.
_____Verdadero _____ Falso. Marque la respuesta correcta.
d)¿Qué resultado mostrará?

vi. Declarar variables adecuadas para manipular los siguientes datos en una aplicación en
C++:
 El resultado de la división (/) entre dos enteros
 Cantidad de estudiantes de una brigada
 Memoria ocupada por un fichero
 Cantidad de habitantes del planeta
 El nombre de una sala de hospital (desde la A hasta la J)
 La edad de una persona
 Si un estudiante está becado o no
 Si una cama de un hospital está ocupada o no
 El resto de la división entre dos números reales
 El factorial de un número
vii. Escriba una secuencia lineal de código que conociendo la producción en unidades de
cada una de las 3 líneas de producción de una fábrica, calcule la producción promedio,
el por ciento que ésta representa de la norma conocida y la ganancia total de la fábrica
conociendo el costo y precio unitario. Asuma que las tres líneas producen el mismo
producto, y que la norma es igual para todas.
viii. Diga el orden en que se realizan las operaciones en las siguientes expresiones:

a) i <= Cantidad && !encuentra


b) (i <= Cantidad) && !encuentra
c) existe = i <= cant-1

ix. Evalúe las siguientes expresiones e indique el resultado

a) bool pertenece = x >= 10 && x <= 20; para x con valor 15


b) bool pertenece = x > 5 && x <= 10; para x con valor 5
c) bool pertenece = x < 5 || x > 10; para x con valor 15

24
d) bool equilatero = a == b && a == c para a igual a 2, b igual a 2 y c igual a 2
e) 7 + 3 * 5 / 2 -1 == 13.5
f) 7 + 3 * 5 / 2 -1 == 13
g) 2 % 2 + 2 * 2 – 2 / 2 >= 3 && (3 * 9* (3 + (9 * 3 / (3)))) != 30
h) a == b && a != b

x. Programe en C los siguientes enunciados

a) Una variable que recibe el resultado de una expresión que evalúa si tres variables
tienen valor diferente.
b) Una variable que recibe el resultado de una expresión que evalúa si sólo dos de tres
variables tienen el mismo valor.
c) Una variable que tome valor true si la variable c tiene almacenada una vocal ya sea
mayúscula o minúscula, acentuadas o no.
d) Una expresión que devuelva true si entre las variables x, y y z, x tiene el mayor valor.
e) Una expresión que devuelva true si una variable tiene almacenado un número impar
f) Una expresión que devuelva true si x es múltiplo de y

xi. Programe en C fragmentos de código que permitan resolver los siguientes problemas.
Simule la entrada de los datos con la orden ENTRAR dato1,dato2….y la visualización
de los resultados con la orden MOSTRAR dato1,dato2,….

a) Un vendedor recibe cada semana un salario fijo más una comisión del 9% del total del
promedio de las ventas realizadas en la semana. Conociendo el importe de cada una de
las 5 ventas realizadas en la semana calcular lo que debe ganar en la semana y si está
por encima de un valor dado almacenar true en una variable.
b) Almacenar true en una variable si el interés que se debe pagar por un préstamo en un
banco es mayor que un valor dado. Se conoce la magnitud del préstamo, la taza de
interés anual y la cantidad de días de vigencia del préstamo.
interés = préstamo * taza * días / 365

25

También podría gustarte