0% encontró este documento útil (0 votos)
67 vistas66 páginas

Programación C

El documento es una introducción a la programación en C++, que abarca desde conceptos básicos hasta temas más avanzados como funciones y estructuras de datos. Incluye ejemplos, ilustraciones y ejercicios para facilitar el aprendizaje. Está estructurado en secciones que cubren aspectos fundamentales del lenguaje y su uso en la programación.

Cargado por

José Jiménez
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 PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
67 vistas66 páginas

Programación C

El documento es una introducción a la programación en C++, que abarca desde conceptos básicos hasta temas más avanzados como funciones y estructuras de datos. Incluye ejemplos, ilustraciones y ejercicios para facilitar el aprendizaje. Está estructurado en secciones que cubren aspectos fundamentales del lenguaje y su uso en la programación.

Cargado por

José Jiménez
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 PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 66

Introducción a la

Programación en C++

Con ejemplos e ilustraciones

Primera Edición

Semestre 2020A - EPN


Índice general

1. Introducción a C++ 1
1.1. Qué es programar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.2. Lenguaje de programación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.3. Qué es un IDE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.3.1. CodeBlocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.3.2. Geany . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.3.3. Dev C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.3.4. OnlineGBD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.4. Instrucciones básicas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.5. Mi primer programa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.5.1. Estructura del código fuente . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.6. Comentarios en C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.7. Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.7.1. Tipos de variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.8. Entrada y salida de datos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.9. Operadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.9.1. Operadores aritméticos . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
1.9.2. Operadores de asignación . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.10. Constantes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.11. Conversión de tipos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
1.12. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

2. Sentencias condicionales y repetitivas 15


2.1. Expresiones lógicas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.1.1. Expresiones lógicas compuestas . . . . . . . . . . . . . . . . . . . . . . . . 15
2.2. Sentencias condicionales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.2.1. Sentencia if-else . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.2.2. Sentencia switch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
2.3. Sentencias repetitivas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
2.3.1. Sentencia while . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
2.3.2. Sentencia do - while . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
2.3.3. Sentencia for . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.4. Ámbito de las variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
2.5. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

3. Datos estructurados 28
3.1. Vectores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
3.1.1. Inicialización de vectores . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
3.2. Matrices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
3.2.1. Inicialización de matrices . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
3.3. Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33

2
3.4. Estructuras . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
3.4.1. Estructuras Anidadas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
3.5. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

4. Números aleatorios 38
4.1. Generación de números aleatorios enteros . . . . . . . . . . . . . . . . . . . . . . 38
4.2. Generación de números aleatorios decimales . . . . . . . . . . . . . . . . . . . . . 40
4.3. Evaluación de integrales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
4.4. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

5. Funciones 45
5.1. Definición de función . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
5.2. Parámetros por defecto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
5.3. Tipos de datos que devuelve una función . . . . . . . . . . . . . . . . . . . . . . . 47
5.4. Funciones void . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
5.5. Almacenamiento de variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
5.5.1. La Pila . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
5.5.2. Estado de la pila . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
5.6. Funciones recursivas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
5.7. Paso por variable o referencia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
5.7.1. Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
5.7.2. Paso por referencia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
5.8. Paso de parámetros tipo estructura . . . . . . . . . . . . . . . . . . . . . . . . . . 57
5.9. Sobrecarga de funciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
5.10. Paso de parámetros de tipo vector . . . . . . . . . . . . . . . . . . . . . . . . . . 59
5.11. Paso de parámetros de tipo array . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
5.12. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
1 | Introducción a C++

El lenguaje C++ (se lee C plus plus) fue creado a mediados de los años 80 y es uno de los
lenguajes de programación más utilizados. De hecho muchos de los programas que utilizamos
diariamente están hechos en lenguaje C++, por ejemplo: los sistemas operativos Windows, Linux
y macOS, los programas de Office, el sistema Android, entre muchos otros.

1.1. Qué es programar


Programar es decirle al ordenador lo que tiene que realizar. Como el ordenador no es una per-
sona, sino una máquina, éste no va entender lo que tiene que hacer si no le indicamos de una
manera que pueda entenderlo.

Como ejemplo nos vamos a ubicar sobre un auto de Fórmula 1, si deseamos que el auto acelere
esto se lo diremos presionando el acelerador, o si deseamos que disminuya la velocidad esto se
lo diremos presionando el freno.

Figura 1.1: Auto Fórmula 1

Si deseamos realizar un giro a la derecha o izquierda, esto se lo diremos girando el volante.


En resumen, el auto hará en todo momento lo que le digamos que haga, es decir, seguirá las
instrucciones que le demos mediante las acciones que le indiquemos para ello.

Con los ordenadores sucede lo mismo. Harán lo que les hayamos dicho que hagan. Las instruc-
ciones que damos al ordenador, se pueden dar directamente, en su propio lenguaje, o pueden
estar ya integradas en un paquete que instalemos.

Figura 1.2: Word & Winedt

1
CAPÍTULO 1. INTRODUCCIÓN A C++ 2

De modo general, programar consiste en dar una serie de instrucciones a la máquina para que
esta se comporte de una determinada manera. Estas instrucciones se guardan dentro de un pro-
grama informático o aplicación.

Como los programas pueden guardarse en la memoria del ordenador, el usuario, cada vez que
quiera realizar una tarea que ya está definida en un programa, sólo tiene que abrirlo y ejecutar.

1.2. Lenguaje de programación


Los lenguajes de programación indican al ordenador qué es lo que este tiene que hacer. Para ello
tenemos dos códigos:

El código fuente: El lenguaje (líneas de texto) en el que el programador escribe las


órdenes que debe ejecutar el ordenador.

El código máquina: El lenguaje (señales eléctricas almacenadas como unos y ceros) que
entiende el ordenador, y en el cual debe recibir las órdenes para ejecutarlas.

Figura 1.3: Diferencias en entre el código fuente y código máquina

Estos dos lenguajes no son iguales, por lo que necesitamos un instrumento que pueda traducir
el código fuente a código máquina, si queremos que el ordenador entienda lo que le decimos en
el código fuente. Este instrumento es el compilador.

Figura 1.4: Compilador

Por otra parte, el programador necesita una aplicación en donde poder escribir el código fuente.
CAPÍTULO 1. INTRODUCCIÓN A C++ 3

1.3. Qué es un IDE


Un IDE, llamado también Entorno de Desarrollo Integrado (IDE son sus siglas en inglés), es
un programa o aplicación que consiste en un entorno de trabajo para programar. La aplicación
tiene varias herramientas útiles para el programador, entre ellas:

1. Menú de opciones: Permite crear, guardar, modificar, ejecutar proyectos y archivos.

2. Editor: Permite ingresar el código fuente.

3. Visualización documentos: Ventana en la cual se muestran los archivos sobre los cuales se
están trabajando. Permite identificar la jerarquía de los archivos.

4. Compilador y depurador: A partir del archivo en código fuente, crea un archivo en código
máquina, además, se indican los errores que tiene el código.

Figura 1.5: Ejemplo de IDE

1.3.1. CodeBlocks
Es una de las principales aplicaciones de Entorno de Desarrollo Integrado para C++. Para su
descarga ingresamos a su sitio oficial: http://www.codeblocks.org/downloads/26.

Figura 1.6: Logo CodeBlocks

Allí tenemos varias opciones para descargar la aplicación. Dependiendo del sistema operativo
que disponga el ordenador, iremos a la sección de Windows, Linux 32, Linux 64, o Mac OS X.
CAPÍTULO 1. INTRODUCCIÓN A C++ 4

1.3.2. Geany
Es una aplicación de Entorno de Desarrollo Integrado que se adapta bastante bien a la pro-
gramación con C++. Para su descarga ingresamos a su sitio oficial: http://www.geany.org/
Download/Releases

Figura 1.7: Logo Geany

1.3.3. Dev C++


Es una aplicación de Entorno de Desarrollo Integrado que se puede usar para programar con
C++. Para su descarga iremos a su sitio oficial: http://www.bloodshed.net/dev/devcpp.html

Figura 1.8: Logo Dev C++

La instalación de los IDEs se realiza todo por defecto (a todo le damos siguiente).

1.3.4. OnlineGBD
Es una aplicación online muy utilizada en la actualidad que permite correr códigos en C++,
Java, Phyton, entre otros.

Se puede acceder a la aplicación desde el enlace: https://www.onlinegdb.com

Figura 1.9: Logo OnlineGBD

1.4. Instrucciones básicas


El funcionamiento básico para cualquiera de las IDEs antes comentadas es el siguiente:
1. Abrimos la aplicación y creamos un nuevo archivo (proyecto), o abrimos uno ya existente
para modificarlo. Este archivo será el archivo fuente, y su contenido el código fuente.
2. Escribimos las instrucciones en lenguaje C++ (es decir, el código fuente), en el espacio de
edición de la aplicación.
CAPÍTULO 1. INTRODUCCIÓN A C++ 5

3. Compilamos y ejecutamos. La compilación crea un nuevo archivo (o sustituye al ya exis-


tente). Este nuevo archivo es el archivo ejecutable, y su contenido está escrito en código
máquina. Al ejecutarlo, éste se abre y se realizan las instrucciones que contiene.
A partir de aquí daremos ya por hecho que sabemos hacer estos pasos, tanto de apertura de
archivos, como de compilar y ejecutar, y nos centraremos más en el propio lenguaje C++.

1.5. Mi primer programa


En la gran mayoría de los IDEs al momento de crear un nuevo archivo nos encontraremos con
el siguiente código:

1 # include < iostream >


2 using namespace std ;
3
4 int main () {
5 cout << " Hola Mundo " << endl ;
6 return 0;
7 }

En los siguientes enlaces se comenta a mayor detalle el primer programa en C++:


⋄ http://y2u.be/ld4nzao5XAc
⋄ http://y2u.be/ZJIP_cO6JwM

1.5.1. Estructura del código fuente


Ahora vamos a analizar con detalle las líneas del código anterior:
include <iostream>
Esta línea inicia con almohadilla # y encarga al preprocesador que se incluya una sección
de código C++ estándar (bibliotecas o librerías) que permite realizar operaciones de en-
trada y salida de datos.

Para entender de mejor manera la necesidad de emplear bibliotecas usaremos la siguiente


metáfora:

Imaginemos que tener instalado el programa en el computador es como haber adquirido


un auto nuevo el cual cumple con ciertas funciones principales y no trae contratiempos,
una vez que lo empezamos a rodar nos vamos dando cuenta de la necesidad de mejorar el
rendimiento de ciertos mecanismos ya existentes del auto debido que lo vamos exponien-
do a diferentes ambientes y condiciones. Lo anterior pasa exactamente con C++, cuando
descargamos e instalamos el software contamos con ciertas características y funcionalida-
des básicas pero existen varias bibliotecas adicionales que pueden ser agregadas para lograr
mejorar su funcionalidad y a la vez realizar cosas estupendas.

En el siguiente enlace se enlistan las principales bibliotecas o librerías:


⋄ http://www.cplusplus.com/reference/
CAPÍTULO 1. INTRODUCCIÓN A C++ 6

using namespace std;


Esta línea declara un namespace o espacio de nombres. En concreto el namespace std o
estándar. Dentro del namespace std están declarados todos los elementos de las bibliotecas
estándar.
Mediante esta línea podemos usar los elementos de la biblioteca estándar sin necesidad de
tener que declararlos cada vez que se usan.

Si no se utiliza la instrucción using namespace std, entonces los nombres cout y endl del
código anterior se deberían escribir como std::cout y std::endl.

int main( )
Esta estructura es la función principal que contiene el código. Lo que se escriba dentro de
las llaves de esta función es el código fuente en sí, es decir el programa que se ejecutará.

La primera palabra int, nos dice el tipo del valor de retorno de la función, en este caso
un número entero. La función main siempre devuelve un entero. La segunda palabra es el
nombre de la función, en general será el nombre que se usa para realizar el llamado a la
función.

cout << Hola Mundo << endl;


Esta sentencia tiene varias partes: En primer lugar cout, que identifica el dispositivo de
salida de caracteres estándar (por lo general, la pantalla del ordenador).

En segundo lugar, el operador de inserción (<<), que indica que lo que sigue debe inser-
tarse (mostrarse en pantalla).

Por último, una frase entre comillas (Hola Mundo), que es el contenido insertado.

Estas dos últimas partes se repiten para volver a insertar otro elemento, es decir repetimos
el operador de inserción (<<) y luego indicamos lo que debe insertarse, en este caso es un
salto de línea que se indica mediante la instrucción endl.

return 0;
La palabra return es reservada propia de C++. Indica al programa que debe abandonar la
ejecución de la función y continuar a partir del punto en que se la llamó. El 0 es el valor de
retorno de nuestra función. Cuando main retorna el valor 0 indica que todo ha marchado
bien.

Cada instrucción en el programa debe terminar con un ";".

1.6. Comentarios en C++


Un comentario es un texto que sirve para que el programador pueda documentar su código. Los
comentarios no son analizados por el compilador. Existen dos tipos de comentarios:

Comentario en bloque: Texto encerrado entre /* y */, puede ocupar más de una línea.
No se pueden anidar, es decir, no se puede colocar un comentario dentro de otro.
CAPÍTULO 1. INTRODUCCIÓN A C++ 7

Comentario de línea: Texto que inicia con //. Una vez escritos estos dos caracteres lo
que queda de línea se considera un comentario.

1 # include < iostream >


2 using namespace std ;
3
4 int main () {
5 // Este es un comentario en linea
6 cout << " Mi segundo programa en C ++ " << endl ;
7 /*
8 Este es un comentario en bloque
9 !!!
10 */
11
12 return 0;
13 }

1.7. Variables
Lo contrario de una salida de datos (mensajes en pantalla) es una entrada de datos. En la entrada
de datos el usuario escribe un dato por teclado, y éste dato es recogido por el ordenador.

Figura 1.10: Esquema variable

Sin embargo, para poder recoger los datos necesitamos antes tener un recipiente en donde guar-
darlo, y éste será la variable. A continuación, se muestra un programa que emplea variables para
almacenar un texto y un número.

1 # include < iostream >


2 using namespace std ;
3
4 int main (){
5 // Definimos las variables ...
6 string frase = " Codigo Internacional Telefonico para Ecuador " ;
7 int numero = 593;
8
9 // Salida en pantalla de las variables ...
10 cout << frase << " : " << numero << endl ;
11
12 return 0;
13 }

Una variable es una parte de la memoria del ordenador en donde se almacena un dato.
CAPÍTULO 1. INTRODUCCIÓN A C++ 8

Cada variable necesita un nombre que la identifique, y que la diferencie de las demás. Adicio-
nalmente, en C++ debemos indicar el tipo de dato que queremos almacenar (número, cadena
de letras, etc.).

Al dato que se almacena en la variable se le llama valor. Podemos cambiar el valor (el dato que
se almacena) de una variable, siempre que sea del tipo indicado.

1.7.1. Tipos de variables


Existen varios tipos de variables, y cada uno corresponde a un tamaño máximo de un número,
un carácter o cadena de caracteres. Cuanto mayor sea el número que pueda admitir, más espacio
en memoria ocupará. Los principales tipos de variables se enlistan a continuación:

1. bool: Las variables de este tipo sólo pueden tomar dos valores true o false. Sirven para
evaluar expresiones lógicas.
Por lo general utiliza 1 byte de memoria, valores: true o false.

2. char: Es el tipo básico alfanumérico, es decir que puede contener un carácter, un dígito
numérico o un signo de puntuación.
Utiliza generalmente 1 byte de memoria, permite almacenar un carácter, valores; 256
caracteres.

3. unsigned short int: Las variables enteras almacenan números enteros dentro de los límites
de su tamaño, a su vez, ese tamaño depende de la plataforma del compilador, y del número
de bits que use por palabra de memoria
Utiliza generalmente 2 bytes de memoria, valores: de 0 a 65535.

4. unsigned long int:


Utiliza generalmente 4 bytes de memoria, valores: de 0 a 4294967295.

5. int:
Utiliza generalmente 4 bytes de memoria, valores: de -2147483648 a 2147483647.

6. float: Las variables de este tipo almacenan números en formato de coma flotante y expo-
nente, para entendernos, son números con decimales.
Utiliza generalmente 4 bytes de memoria, valores: de 1,2 × 10−38 a 3,4 × 10+38 .

7. double: Las variables de este tipo almacenan números en formato de coma flotante y
exponente, al igual que float, pero usan mayor precisión.
Utiliza generalmente 8 bytes de memoria, valores: de 2,3 × 10−308 a 1,8 × 10+308 .

A continuación, un programa que muestra algunos límites numéricos:


1 # include < iostream >
2 # include < limits >
3 using namespace std ;
4
5 int main () {
6 cout << " Maximo entero : " << numeric_limits < int >:: max () << endl ;
7 cout << " Minimo entero : " << numeric_limits < int >:: min () << endl ;
8 cout << " Maximo float : " << numeric_limits < float >:: max () << endl ;
9 cout << " Minimo float : " << numeric_limits < float >:: min () << endl ;
10
CAPÍTULO 1. INTRODUCCIÓN A C++ 9

11 return 0;
12 }

En el siguiente enlace se muestran todos los tipos de variables que admite C++:
⋄ http://www.cplusplus.com/doc/tutorial/variables/

1.8. Entrada y salida de datos


En C++ se puede enviar información a la salida estándar, que como se explicó previamente está
conectada por defecto al monitor o pantalla, mediante la instrucción cout. La sintaxis básica es
la siguiente:
1 cout << expresion 1 << expresion 2 << ... << endl ;

La instrucción anterior se encarga de convertir el resultado de cada expresión en una cadena de


caracteres y de enviar dicha cadena a la salida estándar.

Para la lectura de datos se emplea la instrucción cin. La sintaxis básica es la siguiente:


1 cin >> variable 1 >> variable 2 >> ... >> variable n ;

donde: variable 1, variable 2 y variable n son variables. Esta instrucción provoca la lectura de
datos desde la entrada estándar, que por defecto está asociada al teclado, y su almacenamiento
en las variables especificadas en la instrucción.

Los nombres de las instrucciones anteriores provienen de Character OUTput y Character INput.

A continuación, un programa que muestra la entrada y salida de datos:


1 # include < iostream >
2 using namespace std ;
3
4 int main () {
5 // Definimos dos variables a y b del tipo double
6 double a ;
7 double b ;
8 // Se imprime un mensaje al usuario
9 cout << " Ingrese dos numeros " << endl ;
10 // Se leen dos numeros ingresados a traves del teclado
11 cin >> a ;
12 cin >> b ;
13 // Se imprime un mensaje y la suma de los dos numeros
14 cout << " La suma de los numeros ingresados es : " << a + b << endl ;
15
16 return 0;
17 }

1.9. Operadores
Los operadores son elementos que disparan ciertos cálculos cuando son aplicados a variables u
otros objetos en una expresión. Primero revisemos algunas definiciones importantes:
CAPÍTULO 1. INTRODUCCIÓN A C++ 10

Operando: cada una de las cantidades, constantes o variables o expresiones que intervie-
nen en una expresión.
Expresión: según el diccionario, “Conjunto de términos que representan una cantidad”,
entre nosotros es cualquier conjunto de operadores y operandos, que dan como resultado
una cantidad.
Existe una división en los operadores atendiendo al número de operandos que afectan (unitarios,
binarios o ternarios).

1.9.1. Operadores aritméticos


Son usados para crear expresiones matemáticas. Existen dos operadores aritméticos unitarios +
y - que tienen la siguiente sintaxis:
+ <expresión>
- <expresión>
Asignan valores positivos o negativos a la expresión a la que se aplican.
1 # include < iostream >
2 using namespace std ;
3
4 int main (){
5 int a =5;
6 cout << " Numero positivo : " << + a << endl ;
7 cout << " Numero negativo : " << -a << endl ;
8
9 return 0;
10 }

En cuanto a los operadores binarios existen varios: ’+’, ’-’, ’*’ y ’/’, tienen un comportamiento
análogo, ya que admiten variables enteras y de coma flotante.
<expresión> + <expresión>
<expresión> - <expresión>
<expresión> * <expresión>
<expresión> / <expresión>
Evidentemente se trata de las conocidísimas operaciones aritméticas de suma, resta, multiplica-
ción y división.
1 # include < iostream >
2 using namespace std ;
3
4 int main (){
5 int a , b ;
6 cout << " Ingrese dos numeros enteros positivos : " << endl ;
7 cin >> a >> b ;
8 // Empleamos operadores binarios
9 cout << " Suma : " << a + b << endl ;
10 cout << " Resta : " << a - b << endl ;
11 cout << " Multiplicacion : " << a * b << endl ;
12 cout << " Division : " << a / b << endl ;
13
14 return 0;
15 }
CAPÍTULO 1. INTRODUCCIÓN A C++ 11

El operador de módulo %, devuelve el resto de la división entera del primer operando entre el
segundo. Por esta razón, no puede ser aplicado a operandos en coma flotante.

<expresión> % <expresión>

Otras operaciones como la potencia y radicación se encuentran definidas dentro de la biblio-


teca cmath, por lo cual, para utilizar dichas operaciones se debe incluir la siguiente sentencia:
#include <cmath>

A continuación, un programa que realiza las operaciones de potencia y radicación:


1 # include < iostream >
2 # include < cmath >
3 using namespace std ;
4
5 int main (){
6 int a ;
7 cout << " Ingrese un numero positivo " << endl ;
8 cin >> a ;
9 cout << " La raiz cuadrada es : " << sqrt ( a ) << endl ;
10 cout << " El cubo del numero es : " << pow (a ,3) << endl ;
11 cout << " El resto de dividir para 2 es : " << a %2 << endl ;
12
13 return 0;
14 }

Por último, otros dos operadores unitarios un tanto especiales, ya que sólo pueden trabajar
sobre variables, pues realizan una asignación. Se trata de los operadores ’++’y ’- -’. El primero
incrementa el valor del operando y el segundo lo decrementa, ambos en una unidad.

<variable> ++ (post-incremento)
++ <variable> (pre-incremento)
<variable>-- (post-decremento)
-- <variable> (pre-decremento)

A continuación, un programa que facilita el entendimiento de los operadores de incremento y


decremento:
1 # include < iostream >
2 using namespace std ;
3
4 int main (){
5 int a =1 , b =2 , c =3;
6 cout << " a ++ : " << a ++ << endl ;
7 cout << " ++ b * 2 : " << ++ b * 2 << endl ;
8 cout << " a : " << a << " y b : " << b << endl ;
9 cout << "b - - : " << b - - << endl ;
10 cout << " ++ c * 3: " << ++ c * 3 << endl ;
11 cout << " c ++ : " << c ++ << endl ;
12 cout << " a ++ + --b + c - - : " << a ++ + --b + c - - << endl ;
13
14 return 0;
15 }
CAPÍTULO 1. INTRODUCCIÓN A C++ 12

1.9.2. Operadores de asignación


Existen varios operadores de asignación, el más evidente y el más usado es el =, pero no es el
único. El operador de asignación se utiliza para asignar un valor a una variable. Su sintaxis es
la siguiente:

<variable> <operador de asignación> <expresión>

Si se desea escribir una expresión como a = a+8, en la que se incrementa el valor de una va-
riable en una cantidad, entonces se puede utilizar el operador += de la siguiente forma: a += 8.
Esta última expresión incrementa la variable que aparece a la izquierda del operador += en una
cantidad dada.

A continuación, un programa que emplea varios operadores de asignación:


1 # include < iostream >
2 using namespace std ;
3
4 int main () {
5 int a , b , c ;
6 cout << " Ingrese tres numeros " << endl ;
7 cin >> a >> b >> c ;
8 a += 8;
9 cout << " El primer numero incrementado en 8 unidades : " <<
10 a << endl ;
11 b *= 3;
12 cout << " El triple del segundo numero es : " << b << endl ;
13 c *= c ;
14 cout << " El cuadrado del tercer numero es : " << c << endl ;
15
16 return 0;
17 }

Los operadores -=, *=, /= y %= tienen un comportamiento análogo a += pero aplicados a la resta,
multiplicación, división y módulo, respectivamente.

En los siguientes enlaces se muestran otros ejemplos sobre operadores:


⋄ http://y2u.be/dKNZKgsv9og
⋄ http://y2u.be/Y0n-P5qZ1d0
⋄ http://y2u.be/nrmfgM5t2go
⋄ http://y2u.be/D_QLgW0KnmI

1.10. Constantes
Una constante es una variable que almacena un valor que no varía a lo largo de la ejecución
de un programa. En C++ se puede definir una constante anteponiendo al tipo de variable la
palabra reservada const.

Por convención, los nombres de las constantes se escriben en mayúsculas y se ubican en las
primeras líneas del código.
CAPÍTULO 1. INTRODUCCIÓN A C++ 13

A continuación, un programa que emplea constantes:


1 # include < iostream >
2 using namespace std ;
3
4 int main () {
5 const double IVA = 0.12;
6 const double PROPINA = 0.05;
7 double precio ;
8 cout << " Ingrese el valor del consumo " << endl ;
9 cin >> precio ;
10 precio
11 cout << " Su factura con IVA es de : " << precio + precio * IVA
12 << " dolares " << endl ;
13 cout << " Su factura incluida la propina es de : "
14 << precio + precio * ( IVA + PROPINA ) << " dolares "
15 << endl ;
16 cout << " Gracias por su consumo " << endl ;
17
18 return 0;
19 }

1.11. Conversión de tipos


Cuando se realizan operaciones aritméticas con operandos de distinto tipo, C++ realiza una
conversión implícita del operando cuyo tipo tiene un rango de representación menor al tipo del
operando cuyo rango de representación es mayor; de esta forma se puede realizar la operación.

En el caso de una operación entre un número entero y un número real el entero se convierte
implícitamente a real, realizándose la operación entre reales.

A continuación, un programa que ejemplifica la conversión de tipos:


1 # include < iostream >
2 using namespace std ;
3
4 int main () {
5 int a = 32 ,
6 double b = 10.5;
7 // Suma de entero y real
8 cout << a + b << endl :
9 // Division de entero a entero
10 cout << a /5 << endl ;
11 // Division entero a real
12 cout << a /5.0 << endl :
13 // Conversion explicita
14 cout << ( float ) a /5 << endl ;
15
16 return 0;
17 }
CAPÍTULO 1. INTRODUCCIÓN A C++ 14

En la línea 14 se utiliza el operador de conversión explícita de tipos. Éste es un operador unitario


cuya sintaxis es:

(tipo) operando

El efecto del operador es convertir el operando al tipo tipo.

1.12. Ejercicios
1. Escriba un programa que reciba dos números enteros y muestre en pantalla el producto
de dichos números.

2. Suponiendo que los impuestos prediales se incrementan en un t = 2 % cada año, realice


un programa que solicite el valor de la factura de este año C0 y una cantidad de años n y
muestre en la salida estándar cuánto deberá pagar dentro del número de años introducidos
Cn .
Cn = C0 (1 + t)n

3. Realice un programa que calcule el valor que toma la siguiente función para valores dados
de x e y: √
x3
f (x, y) = 2
y +1
4. Escriba un programa que reciba la temperatura media de la ciudad de Quito medida
en grados Celcius y muestre en la salida estándar la temperatura expresada en grados
Fahrenheit, Kelvin y Rankine.

5. La calificación final de la materia de Programación se obtiene de la media ponderada de


tres notas: la nota de deberes que cuenta un 20 %, la nota de la evaluación parcial que
cuenta un 35 % y la nota de la evaluación final que cuenta un 45 %. Escriba un programa
que lea de la entrada estándar las tres notas de un alumno y escriba en la salida estándar
su nota final.

6. Escriba un programa que reciba el diámetro de un círculo y muestre en la salida estándar


el valor del perímetro y área del círculo. (NOTA: defina una constante para π).

7. Cuando se adquiere una bebida en una máquina dispensadora y no se introduce el importe


exacto, la máquina utiliza un algoritmo para devolver el mínimo número de monedas.
Escriba un programa considerando que únicamente se utilizan monedas de 5, 10. 20 y 50
centavos, el programa debe leer el importe de la bebida y la cantidad de dinero introducida
por el usuario en la máquina y escriba en la salida estándar las monedas devueltas por la
máquina.
2 | Sentencias condicionales y repe-
titivas

2.1. Expresiones lógicas


Una expresión lógica es aquella que produce un resultado de verdadero o falso. Se puede construir
una expresión lógica simple utilizando un literal de tipo lógico, es decir, true o false, o combi-
nado dos expresiones aritméticas mediante un operador relacional. Los principales operadores
relacionales de C++ son:

Operador Significado
< menor que
> mayor que
<= menor o igual que
>= mayor o igual que
== igual que
!= distinto de

A continuación, un programa que verifica si los dos números enteros ingresados por el usuario
son iguales:

1 # include < iostream >


2 using namespace std ;
3
4 int main (){
5 int a , b ;
6 bool res ;
7 cout << " Ingrese dos numeros enteros " << endl ;
8 cin >> a >> b ;
9
10 // Expresion logica simple
11 res = a == b ;
12 cout << " Resultado : " << res << endl ;
13
14 return 0;
15 }

2.1.1. Expresiones lógicas compuestas


Una expresión lógica compuesta es aquella formada por expresiones lógicas combinadas mediante
operadores lógicos. Los principales operadores lógicos de C++ son:

15
CAPÍTULO 2. SENTENCIAS CONDICIONALES Y REPETITIVAS 16

Operador Significado
&& conjunción
|| disyunción
! negación

Una expresión lógica compuesta puede contener operadores aritméticos, relacionales y lógicos.

Se recomienda emplear paréntesis en las expresiones lógicas compuestas, con el fin de separar e
identificar cada una de las expresiones lógicas simples.

A continuación, un programa que verifica si los dos números ingresados por el usuario son iguales
y pares a la vez:
1 # include < iostream >
2 using namespace std ;
3
4 int main (){
5 int a , b ;
6 bool res ;
7 cout << " Ingrese dos numeros enteros " << endl ;
8 cin >> a >> b ;
9
10 // Expresion logica compuesta
11 res = ( a == b ) && ( a %2 == 0);
12 cout << " Resultado : " << res << endl ;
13
14 return 0;
15 }

En los siguientes enlaces se presentan a mayor detalle los operadores lógicos y relacionales:
http://y2u.be/7rnxBgZsWQ0
http://y2u.be/MUznvpgtn9g

2.2. Sentencias condicionales


Las sentencias condicionales permiten seleccionar qué codigo ejecutar en función del resultado
de evaluar ciertas expresiones lógicas.

2.2.1. Sentencia if-else


La sentencia if-else permite ejecutar un código de manera condicional en función del resultado
de evaluar una condición lógica. Su sintaxis es la siguiente:

if(expresión lógica){
bloque de instrucciones 1
} else {
bloque de instrucciones 2
}
CAPÍTULO 2. SENTENCIAS CONDICIONALES Y REPETITIVAS 17

Figura 2.1: Flujograma sentencia if - else

La sentencia if-else primero evalúa la expresión lógica (condición). Si la expresión es verdadera,


entonces se ejecuta el bloque de instrucciones 1, en caso de ser falsa se ejecuta el bloque de
instrucciones 2.

Sobre la sintaxis de la sentencia if-else se debe tener en cuenta lo siguiente:

La expresión lógica debe aparecer encerrada entre paréntesis.

Los bloques de instrucciones se encierran entre llaves.

La parte else es opcional.

Se recomienda escribir los bloques de instrucciones un poco a la derecha (con sangrado o


indentados), pues esto aumenta la legibilidad del programa.

A continuación, un ejemplo que permite identificar si el número entero ingresado por el usuario
es par o impar:
1 # include < iostream >
2 using namespace std ;
3
4 int main (){
5 int a ;
6 cout << " Ingrese un numero entero " << endl ;
7 cin >> a ;
8
9 // Sentencia condicional
10 if (( a % 2) == 0){
11 cout << " El numero ingresado es par " << endl ;
12 } else {
13 cout << " El numero ingresado es impar " << endl ;
14 }
15 return 0;
16 }

Las raíces reales de un polinomio de segundo grado de la forma: ax2 + bx + c = 0, pueden ser
obtenidas mediante la expresión:

−b ± b2 − 4ac
x1,2 =
2a
a continuación, se presenta un programa que permite obtener dichas raíces en el caso que existan.
CAPÍTULO 2. SENTENCIAS CONDICIONALES Y REPETITIVAS 18

1 # include < iostream >


2 # include < cmath >
3 using namespace std ;
4
5 int main (){
6 double a , b , c , d ;
7 cout << " Raices del polinomio : ax ^2 + bx + c = 0 " << endl ;
8 cout << " Ingrese los coeficientes : " << endl ;
9 cin >> a >> b >> c ;
10
11 // Calculo del discriminante
12 d = pow (b ,2) - 4* a * c ;
13
14 // Sentencia condicional
15 if ( d < 0){
16 cout << " El polinomio no tiene raices reales " << endl ;
17 } else if ( d == 0) {
18 cout << " Las raices son iguales a : "
19 << ( float ) -b /(2* a ) << endl ;
20 } else {
21 cout << " La primera raiz es : "
22 << ( float ) ( -b - pow (d ,0.5))/(2* a ) << endl ;
23 cout << " La segunda raiz es : "
24 << ( float ) ( - b + pow (d ,0.5))/(2* a ) << endl ;
25 }
26 return 0;
27 }

2.2.2. Sentencia switch


La sentencia switch permite realizar una selección múltiple.

Figura 2.2: Flujograma sentencia switch

La sintaxis de la sentencia switch es la siguiente:


CAPÍTULO 2. SENTENCIAS CONDICIONALES Y REPETITIVAS 19

switch (expresion){
case literal1:
bloque de instrucciones 1
break;
case literal2:
bloque de instrucciones 2
break;
......
case literaln:
bloque de instrucciones n
break;
default:
bloque de instrucciones por defecto
break;
}

La sentencia switch primero evalúa la expresión, misma que aparece en el paréntesis. La expresión
debe producir un resultado de tipo entero, caractér o lógico. A continuación, se compara el
resultado de evaluar la expresión con los literales que aparecen en los casos.

1 # include < iostream >


2 using namespace std ;
3
4 int main (){
5 cout << " Ingrese la opcion a ejecutar : " << endl ;
6 char opcion ;
7 cin >> opcion ;
8
9 switch ( opcion ){
10 case ’a ’:
11 cout << " Ha seleccionado la opcion a " << endl ;
12 break ;
13 case ’b ’:
14 cout << " Ha seleccionado la opcion b " << endl ;
15 break ;
16 case ’c ’:
17 cout << " Ha seleccionado la opcion c " << endl ;
18 break ;
19 default :
20 cout << " Ha ingresado una opcion incorrecta " << endl ;
21 }
22
23 return 0;
24 }

Si el resultado de evaluar la expresión coincide con el literal de algún caso, entonces se ejecuta
el conjunto de instrucciones asociado al caso y el conjunto de instrucciones asociadas al resto de
casos que aparecen con posterioridad hasta que se ejecuta la instrucción break que provoca que
se salga de la ejecución de la instrucción switch.

A continuación, se presenta un programa que convierte centímetros a pulgadas y libras a kilo-


gramos:
CAPÍTULO 2. SENTENCIAS CONDICIONALES Y REPETITIVAS 20

1 # include < iostream >


2 using namespace std ;
3
4 int main () {
5 int x ;
6 float pulgadas , kilo , distancia , peso ;
7 cout << " Que desea convertir , distancia o peso ? " << endl ;
8 cout << " Escriba 1 para distancia o 2 para peso " << endl ;
9 cin >> x ;
10
11 switch ( x ){
12 case 1:
13 cout << " Ingrese la distancia en centimetros : " << endl ;
14 cin >> distancia ;
15 pulgadas = distancia / 2.54;
16 cout << " Las pulgadas son : " << pulgadas << endl ;
17 break ;
18 case 2:
19 cout << " Ingrese el peso en libras : " << endl ;
20 cin >> peso ;
21 kilo = peso * (1 / 2.21);
22 cout << " Los kilogramos son : " << kilo << endl ;
23 break ;
24 default :
25 cout << " Opcion no valida " << endl ;
26 }
27
28 return 0;
29 }

2.3. Sentencias repetitivas


Las sentencias repetitivas o iterativas, también llamadas ciclos o bucles, permiten ejecutar un
conjunto de instrucciones de manera reiterada mientras que se verifique una condición lógica.

2.3.1. Sentencia while


La sentencia while permite ejecutar un bloque de instrucciones mientras la expresión lógica sea
verdadera.

Figura 2.3: Flujograma sentencia while


CAPÍTULO 2. SENTENCIAS CONDICIONALES Y REPETITIVAS 21

La sintaxis es la siguiente:

while(expresión lógica){
bloque de instrucciones
}

En primer lugar, se evalúa la expresión lógica. Si el resultado de la evaluación es el valor falso, en-
tonces termina la ejecución de la instrucción while. Si el resultado de la evaluación es verdadero,
entonces se ejecuta el conjunto de instrucciones asociado a la instrucción while. Una vez ejecu-
tado el conjunto de instrucciones se vuelve a evaluar la expresión lógica y se procede como antes.

A continuación, un programa que solicita un número mayor a 10 para finalizar el proceso:


1 # include < iostream >
2 using namespace std ;
3
4 int main () {
5 int numero ;
6 cout << " Ingrese un numero entero " << endl ;
7 cin >> numero ;
8
9 // Sentencia repetitiva
10 while ( numero <= 10){
11 cout << " Ingrese otro numero : " ;
12 cin >> numero ;
13 }
14 return 0;
15 }

Ahora analicemos un programa que suma todos los números ingresados por el usuario, para
finalizar el proceso es necesario teclear el número 999:
1 # include < iostream >
2 using namespace std ;
3
4 int main () {
5 int num , suma ;
6
7 cout << " ------- Programa Suma ------- " << endl ;
8 num = 0;
9 suma = 0;
10
11 while ( num != 999){
12 suma += num ;
13 cout << " Ingresa un numero ( teclea 999 para terminar ): "
14 << endl ;
15 cin >> num ;
16 }
17 cout << " La suma total es : " << suma << endl ;
18
19 return 0;
20 }
CAPÍTULO 2. SENTENCIAS CONDICIONALES Y REPETITIVAS 22

Finalmente, se muestra un programa que recibe dos números a, x con |x| < 1 y determina el
menor valor de n para el que se cumple la expresión:
a ∑
n
− axi < 10−7
1 − x i=0

1 # include < iostream >


2 # include < cmath >
3 using namespace std ;
4
5 int main () {
6 double a , x ;
7 const double ERROR = pow (10 , -7);
8 cout << " Ingrese los valores de a y x : " << endl ;
9 cin >> a >> x ;
10
11 // Sentencia condicional sobre x
12 if ( x > -1 && x < 1){
13 double sum = 0;
14 int i = 0;
15 // Sentencia repetitiva para hallar el valor de n
16 while ( a /(1 - x ) - sum > ERROR ){
17 sum += a * pow (x , i );
18 i ++;
19 }
20 cout << " El valor de n buscado es : " << i -1 << endl ;
21 } else {
22 cout << " El valor de x no es valido " << endl ;
23 }
24
25 return 0;
26 }

2.3.2. Sentencia do - while


La sentencia do-while es muy parecida a la sentencia while. La principal diferencia con la senten-
cia while es que en la sentencia do-while el conjunto de instrucciones se ejecutará por lo menos
una vez.

Figura 2.4: Flujograma sentencia do - while


CAPÍTULO 2. SENTENCIAS CONDICIONALES Y REPETITIVAS 23

La sintaxis es la siguiente:
do {
bloque de instrucciones
} while (expresión lógica);
Una vez ejecutado el conjunto de instrucciones se evalúa la expresión lógica. Si el resultado de
la evaluación es verdadero se vuelve a ejecutar el conjunto de instrucciones, así hasta que la
expresión lógica sea falsa, en cuyo momento termina la ejecución de la instrucción.

A continuación, un programa que transforma los grados centígrados a fahrenheit y viceversa:


1 # include < iostream >
2 using namespace std ;
3
4 int main (){
5 int opcion ;
6 float centi , fahre ;
7 bool terminar = false ;
8 cout << " --- Conversion de temperaturas ---" << endl ;
9
10 do {
11 cout << " Escoja una opcion : " << endl ;
12 cout << " 1. Convertir Grados centigrados a Fahrenheit : "
13 << endl ;
14 cout << " 2. Convertir Grados Fahrenheit a Centigrados : "
15 << endl ;
16 cout << " 3. Salir del programa " << endl ;
17 cin >> opcion ;
18
19 switch ( opcion ){
20 case 1:
21 cout << " Ingrese los grados centigrados : " << endl ;
22 cin >> centi ;
23 fahre = ( centi *1.8) + 32;
24 cout << " Su equivalente en fahrenheit es : "
25 << fahre << endl ;
26 break ;
27 case 2:
28 cout << " Ingrese los grados fahrenheit : " << endl ;
29 cin >> fahre ;
30 centi = ( fahre - 32)/1.8;
31 cout << " Su equivalente en centigrados es : "
32 << centi << endl ;
33 break ;
34 default :
35 cout << " Gracias por usar el programa " << endl ;
36 terminar = true ;
37 }
38 } while (! terminar );
39
40 return 0;
41 }
CAPÍTULO 2. SENTENCIAS CONDICIONALES Y REPETITIVAS 24

2.3.3. Sentencia for


La sentencia for está pensada principalmente para expresar ciclos que se ejecutan un número fijo
de veces. La sentencia for resulta más legible que las sentencias while y do while, pues permite
expresar la iniciación, incremento y condición lógica asociada a la variable que controla el ciclo
en una única línea al principio del ciclo.

Figura 2.5: Flujograma sentencia for

La sintaxis de la instrucción for es la siguiente:


for (inicializacion; expresión lógica; incremento){
conjunto de instrucciones
}
El funcionamiento de la instrucción es el siguiente:
Se ejecuta la inicialización del ciclo, esta expresión se ejecuta una única vez.
A continuación se evalúa la expresión lógica. Mientras que el resultado de evaluar la ex-
presión lógica sea verdadero se ejecuta el conjunto de instrucciones.
Por último, se realiza el incremento o decremento del contador.
A continuación, un programa que calcula el factorial de un número entero:
1 # include < iostream >
2 using namespace std ;
3
4 int main () {
5 int numero , fact = 1;
6 cout << " Introduzca un entero positivo : " << endl ;
7 cin >> numero ;
8 for ( int i = 1; i <= numero ; i ++){
9 fact *= i ;
10 }
11 cout << " El factorial de " << numero << " es " << fact << endl ;
12 return 0;
13 }

Para finalizar esta sección revisemos un programa que determina si un número entero positivo
ingresado por el usuario es primo:
CAPÍTULO 2. SENTENCIAS CONDICIONALES Y REPETITIVAS 25

1 # include < iostream >


2 using namespace std ;
3
4 int main (){
5 int numero , i ;
6 bool primo = false ;
7
8 cout << " Ingrese un entero positivo (0 para terminar ): "
9 << endl ;
10 cin >> numero ;
11
12 while ( numero != 0){
13 for ( i = 2; i < numero ; i ++){
14 if ( numero % i == 0)
15 primo = true ;
16 }
17 if ( primo ){
18 cout << " El numero " << numero << " no es primo "
19 << endl ;
20 } else {
21 cout << " El numero " << numero << " es primo " << endl ;
22 }
23 cout << " Ingreses un entero positivo (0 para terminar ): " ;
24 cin >> numero ;
25 primo = false ;
26 }
27
28 return 0;
29 }

2.4. Ámbito de las variables


C++ proporciona unas reglas muy flexibles para elegir el lugar en el que se define una variable.
En función del lugar de su definición, una variable tiene un ámbito, que es la zona del programa
en la que puede ser usada. A continuación, se enumeran las principales reglas sobre el lugar de
definición y ámbito de las variables:

Una variable puede definirse en cualquier lugar en el que se puede escribir una instrucción.
El ámbito de la variable abarca desde su lugar de definición hasta el final del bloque
más interno en que se ha definido la variable (un bloque es un conjunto de instrucciones
encerradas entre llaves).

Se puede definir una variable en la parte de iniciación de una sentencia for. En ese caso el
ámbito de la variable es el cuerpo y cabecera de la instrucción for.

Se puede definir más de una vez una misma variable, es decir, con el mismo identifica-
dor dentro del cuerpo de una función siempre que las definiciones ocurran en bloques no
solapados o en bloques solapados de distinto nivel de profundidad.

Un código que intenta explicar de mejor modo el ámbito de aplicación de las variables:
CAPÍTULO 2. SENTENCIAS CONDICIONALES Y REPETITIVAS 26

1 # include < iostream >


2 using namespace std ;
3
4 int main (){
5 int z =3;
6 int x =8;
7
8 if ( true ){
9 int x = 0;
10 cout << x << endl ;
11 }
12
13 for ( int x = 1; x < 11; x ++){
14 cout << x << endl ;
15 }
16 cout << x << endl ;
17
18 if ( true ){
19 int z =4;
20 cout << z << endl ;
21 }
22 cout << z << endl ;
23
24 return 0;
25 }

Una aplicación importante del ámbito de las variables se presenta en la sentencia switch, al
poner entre llaves los bloques de instrucciones y el break; de cada caso. Al hacer esto si definimos
variables dentro de las llaves solamente serán efectivas para ese caso, pero si no hacemos uso
de ellas las variables definidas dentro de un caso serán validas para todos los casos dentro de la
sentencia switch.

2.5. Ejercicios
1. Realice un programa que lea de la entrada estándar números hasta que se introduzca un
cero. En ese momento el programa debe terminar y mostrar en la salida estándar el máximo
y mínimo número ingresado.

2. Escriba un programa que calcule el valor de las siguientes sumas:



n
a) 2i − 1 = 1 + 3 + 5 + . . . + 2n − 1
i=1
∑n
b) k! = 1! + 2! + 3! + . . . + n!
k=1
∑n
n!
c) = 1 + n + ... + 1
j=0
j!(n − j)!

El programa debe leer de la entrada estándar un número entero positivo n y debe mostrar
en la salida estándar el resultado de cada una de las sumas.
CAPÍTULO 2. SENTENCIAS CONDICIONALES Y REPETITIVAS 27

3. Existen diversos métodos numéricos capaces de aproximar el número π. Uno de ellos, es


el siguiente: v
u∞
u∑ 6
π=t
i=1
i2

Escriba un programa que lea de la entrada estándar el grado de aproximación ϵ (|πi −


πi−1 | < ϵ) y devuelva el valor aproximado de π.

4. El método de Newton-Raphson (llamado también método de la tangente) es frecuentemen-


te usado para resolver ecuaciones no lineales de la forma f (x) = 0. Este método consiste
tomar un valor inicial x0 , y a continuación, se obtiene una aproximación más refinada
mediante la siguiente fórmula:

f (xi−1 )
xi = xi−1 − , i = 1, 2, 3, . . .
f ′ (xi−1 )

el algoritmo termina cuando |xi − xi−1 | < ϵ.

Aplique el método de Newton-Raphson a las siguientes funciones:

a) f (x) = ex + x3 − 5, con x0 = 0.
b) f (x) = x2 + x ∗ cos(x), con x0 = −2.

considere una tolerancia ϵ = 10−5 .

5. Escriba un programa que lea de la entrada estándar un número entero positivo n, a con-
tinuación, determine del conjunto de números 1, 2, . . . , n:

a) El número de múltiplos de 3.
b) La cantidad de números primos.
c) La cantidad de números impares.

6. En una clase de 5 alumnos se han realizado tres exámenes y se requiere determinar el


número de:

a) Alumnos que aprobaron todos los exámenes.


b) Alumnos que aprobaron al menos un examen.
c) Alumnos que aprobaron únicamente el último examen.

Realice un programa que permita la lectura de los datos (A:aprobado, R: reprobado) y el


cálculo de las estadísticas.
3 | Datos estructurados

En los primeros capítulos del curso se han estudiado los tipos de datos primitivos de C++, es
decir, los tipos de datos numéricos, lógicos y carácter. Ahora, analizaremos los tipos de datos
estructurados, estos se utilizan para almacenar colecciones de datos del mismo tipo o diferentes
tales como: vectores, estructuras y cadenas de caracteres.

3.1. Vectores
Un vector es una estructura unidimensional que almacena una secuencia de datos del mismo
tipo. Los elementos de un vector se almacenan en zonas contiguas de memoria y se puede acceder
a ellos de manera directa mediante un índice o posición.

Figura 3.1: Estructura de un vector

Para definir un vector se utiliza la siguiente sintaxis:

tipo nombre[tamaño];

donde tipo es el tipo de los elementos del vector, nombre es el nombre de la variable que sirve
para referenciar al vector y tamaño indica el número de elementos del vector.

En C++ los índices de los vectores empiezan en cero.

El tamaño debe expresarse mediante una expresión constante de tipo entero.

No es válido definir el tamaño de un vector a partir de una variable ingresada por el usuario.

int x; // Variable
cout << "Ingrese un entero" << endl;
cin >> x;
double vector[x]; // No valido

28
CAPÍTULO 3. DATOS ESTRUCTURADOS 29

Para acceder a los elementos de un vector se utiliza la sintaxis:

nombre[posicion];

donde nombre es el nombre de la variable de tipo vector y posicion es una expresión entera que
indica el índice del elemento del vector al que se quiere acceder.

La utilidad de los vectores es que permiten crear múltiples datos de un mismo tipo con una
única sentencia de definición y una única variable. Además, el acceso a los datos almacenados
en el vector es muy eficiente y sencillo a partir de su posición.

A continuación, un programa que almacena las componentes de dos vectores de R3 y obtiene la


suma vectorial y el producto interno:
1 # include < iostream >
2 using namespace std ;
3
4 int main (){
5 float vector1 [3];
6 float vector2 [3];
7 float Suma [3];
8 float Producto = 0;
9 // Datos del primer vector
10 for ( int i =0; i <3; i ++){
11 cout << " Introduce la componente " << i + 1
12 << " del primer vector : " ;
13 cin >> vector1 [ i ];
14 }
15 // Datos del segundo vector
16 for ( int i =0; i <3; i ++){
17 cout << " Introduce la componente " << i + 1
18 << " del segundo vector : " ;
19 cin >> vector2 [ i ];
20 }
21 // Suma de vectores
22 for ( int i =0; i <3; i ++){
23 Suma [ i ] = vector1 [ i ] + vector2 [ i ];
24 }
25 // Producto interno
26 for ( int i =0; i <3; i ++){
27 Producto += vector1 [ i ] * vector2 [ i ];
28 }
29 // Mostramos el resultado
30 cout << " El vector suma es " ;
31 for ( int i =0; i <3; i ++)
32 cout << Suma [ i ] << " " ;
33 cout << endl ;
34
35 cout << " El producto interno es : " << Producto << endl ;
36
37 return 0;
38 }
CAPÍTULO 3. DATOS ESTRUCTURADOS 30

3.1.1. Inicialización de vectores


Se puede inicializar un vector en la misma definición de la variable. Para realizar esto hay que
encerrar entre llaves la lista de valores con que se inicia el vector, separando los valores entre sí
mediante comas.

A continuación, un programa que obtiene el total de gastos de una familia X:


1 # include < iostream >
2 using namespace std ;
3
4 int main (){
5 int gastos [6] = {200 , 150 , 100 , 250 , 300 , 285};
6 int suma ;
7
8 suma = 0;
9 for ( int i =0; i <=4; i ++){
10 suma += gastos [ i ];
11 };
12
13 cout << " El gasto total es : " << suma ;
14
15 return 0;
16 }

Si inicializamos un vector, no será necesario que indiquemos su tamaño, porque el compilador


lo puede saber contando los valores ingresados en la lista.

1 # include < iostream >


2 using namespace std ;
3
4 int main (){
5 int diasMes [] = {31 , 28 , 31 , 30 , 31 , 30 ,
6 31 , 31 , 30 , 31 , 30 , 31};
7
8 string Mes [] = { " Enero " , " Febrero " , " Marzo " , " Abril " , " Mayo " ,
9 " Junio " , " Julio " , " Agosto " , " Septiembre " , " Octubre " ,
10 " Noviembre " , " Diciembre " };
11
12 for ( int i =0; i <12; i ++){
13 cout << " El mes de " << Mes [ i ] << " tiene " << diasMes [ i ]
14 << " dias " << endl ;
15 };
16
17 return 0;
18 }

3.2. Matrices
Una matriz es una estructura bidimensional que almacena una secuencia de datos del mismo tipo
en filas y columnas. Los elementos de una matriz se almacenan en zonas contiguas de memoria
y se puede acceder a ellos de manera directa mediante la posición (fila y columna).
CAPÍTULO 3. DATOS ESTRUCTURADOS 31

Figura 3.2: Estructura de una matriz

La sintaxis para declarar una matriz en C++ es la siguiente:

tipo nombreMatriz[filas][columnas];

donde tipo corresponde al tipo de elementos que se van almacenar, nombreMatriz corresponde al
nombre de la estructura matriz, filas y columnas son expresiones enteras que indican el número
de filas y columnas, respectivamente, que tendrá la estructura matriz.

Al igual que en los vectores, los índices de las filas y columnas de una matriz empiezan en cero.

A continuación, un programa que suma dos matrices de orden 2 × 2:


1 # include < iostream >
2 using namespace std ;
3
4 int main (){
5 double matriz1 [2][2];
6 double matriz2 [2][2];
7 double Suma [2][2];
8
9 // Ingreso valores matriz 1
10 cout << " Matriz 1 " << endl ;
11 for ( int i =0; i <2; i ++){
12 for ( int j =0; j <2; j ++){
13 cout << " Ingrese el elemento " << i +1 << j +1 << " : " ;
14 cin >> matriz1 [ i ][ j ];
15 }
16 }
17
18 // Ingreso valores matriz 2
19 cout << " Matriz 2 " << endl ;
20 for ( int i =0; i <2; i ++){
21 for ( int j =0; j <2; j ++){
22 cout << " Ingrese el elemento " << i +1 << j +1 << " : " ;
23 cin >> matriz2 [ i ][ j ];
24 }
25 }
26
27 // Suma de matrices
28 for ( int i =0; i <2; i ++){
29 for ( int j =0; j <2; j ++){
30 Suma [ i ][ j ] = matriz1 [ i ][ j ] + matriz2 [ i ][ j ];
31 }
CAPÍTULO 3. DATOS ESTRUCTURADOS 32

32 }
33
34 // Resultado
35 cout << " El resultado es : " << endl ;
36 for ( int i =0; i <2; i ++){
37 for ( int j =0; j <2; j ++){
38 cout << Suma [ i ][ j ] << " " ;
39 }
40 cout << endl ;
41 }
42 return 0;
43 }

En cuanto tenemos declarado una matriz, es posible asignarle valores a cada una de sus casillas,
evidentemente estos valores deben coincidir con el tipo de dato que le asignamos a dicha matriz.

3.2.1. Inicialización de matrices


Se puede inicializar una matriz en la misma definición de la variable. Para realizar esto hay que
encerrar entre llaves la lista de valores de cada fila con que se inicia la matriz, separando los
valores entre sí mediante comas.

A continuación, un programa que almacena la notas del examen de dos grupos de 10 alumnos
cada uno y compara el promedio de cada curso:
1 # include < iostream >
2 using namespace std ;
3
4 int main (){
5 int Notas [][10] = {{17 , 20 , 13 , 14 , 15 , 19 , 17 , 18 , 19 , 10} ,
6 {18 , 12 , 19 , 14 , 15 , 16 , 17 , 13 , 19 , 20 }};
7
8 // Promedio por curso
9 double prom1 =0 , prom2 =0;
10 for ( int i =0; i <10; i ++){
11 prom1 += 0.1* Notas [0][ i ];
12 prom2 += 0.1* Notas [1][ i ];
13 }
14
15 // Comparacion promedios
16 if ( prom1 > prom2 ){
17 cout << " El primer curso tiene mejor promedio " << endl ;
18 } else if ( prom1 < prom2 ){
19 cout << " El segundo curso tiene mejor promedio " << endl ;
20 } else {
21 cout << " Ambos cursos tienen igual promedio " << endl ;
22 }
23
24 return 0;
25 }
CAPÍTULO 3. DATOS ESTRUCTURADOS 33

Es posible inicializar matrices únicamente especificando el número de columnas. Por default, el


compilador analiza la lista de datos y contabiliza el número de filas.

3.3. Arrays
C++ permite trabajar con arrays multidimensionales, es decir, de varias dimensiones.

Figura 3.3: Estructura de un array

Para definir un array multidimensional de dimensión n se utiliza la siguiente sintaxis:

tipo nombreArray[tam1][tam2]...[tamn];

donde tipo es el tipo de los elementos del array, nombreArray es el nombre de la variable asocia-
da al array y tam1, tam2, . . . , tamn son expresiones constantes de tipo entero que indican los
tamaños de las distintas dimensiones del array.

A continuación, un programa que almacena las ventas de 4 tipos de productos de golosinas en


3 diferentes ciudades durante 2 días y calcula el total de ventas por producto:
1 # include < iostream >
2 using namespace std ;
3
4 int main (){
5 int Ventas [4][3][2] = {12 , 20 , 13 , 34 , 15 , 24 , 16 , 28 , 11 , 18 ,
6 31 , 25 , 23 , 34 , 21 , 10 , 18 , 28 , 31 , 17 ,
7 15 , 19 , 28 , 34};
8
9 // Vista Array
10 for ( int k =0; k <2; k ++){
11 for ( int i =0; i <4; i ++){
12 for ( int j =0; j <3; j ++){
13 cout << Ventas [ i ][ j ][ k ] << " " ;
14 }
15 cout << endl ;
16 }
17 cout << endl ;
18 cout << endl ;
19 };
20
21 // Total Ventas por producto
22 int TPro [4]; // Vector que almacena los totales
23 for ( int i =0; i <4; i ++){
24 TPro [ i ] = 0; // Inicializamos la celda
CAPÍTULO 3. DATOS ESTRUCTURADOS 34

25 for ( int j =0; j <3; j ++){


26 for ( int k =0; k <2; k ++){
27 TPro [ i ] += Ventas [ i ][ j ][ k ];
28 }
29 }
30 };
31
32 // Resultados por producto
33 for ( int i =0; i <4; i ++){
34 cout << " Total Producto " << i +1 << " : " << TPro [ i ] << endl ;
35 }
36
37 return 0;
38 }

Se debe tener mucho cuidado con el manejo de los índices en los arrays para no confundir las
dimensiones sobre las cuales se pretende trabajar.

3.4. Estructuras
C++ permite que el programador defina nuevos tipos de datos. Una forma de hacerlo es me-
diante una estructura. Una estructura define un nuevo tipo de dato que está compuesto por una
colección de datos de tipos existentes ya sean tipos básicos o estructurados como arrays, cadenas
de caracteres o estructuras ya definidas. Las estructuras son muy útiles pues permiten definir
tipos de datos que se ajustan con exactitud a las necesidades de representación de cualquier
objeto. Con una estructura se puede representar un alumno, un seguro, un vehículo, etc.
Rojo
Toyota
Modelo 2018
230 CV

Verde
Ford
Modelo 2016
280 CV

Azul
Mercedes Benz
Modelo 2020
350 CV

Figura 3.4: Ejemplo de un estructura

La sintaxis de definición de una estructura es:


struct nombre{
tipo1 campo1;
tipo2 campo2;
...
tipon campon;
};
La definición de una estructura comienza con la palabra reservada struct, seguida del nombre
del nuevo tipo que se está definiendo. A continuación, y encerrados entre llaves, aparecen los
CAPÍTULO 3. DATOS ESTRUCTURADOS 35

datos que componen el nuevo tipo. A cada uno de los datos se le llama campo o miembro. La
definición de cada campo tiene la estructura de la definición de una variable, es decir, en primer
lugar se especifica el tipo del campo y a continuación su nombre.

A continuación, un programa que registra la información de 5 individuos definiendo una nueva


estructura y obtiene la edad promedio:
1 # include < iostream >
2 using namespace std ;
3
4 // Definicion nueva estructura
5 struct persona {
6 char nombre [15];
7 int edad ;
8 char sexo [15];
9 int telefono ;
10 };
11
12 int main (){
13 persona amigo [5];
14 // Ingreso de informacion
15 for ( int i = 0; i < 5; i ++){
16 cout << " Escriba el Nombre " << i +1 << ":";
17 cin >> amigo [ i ]. nombre ;
18 cout << " \ nEscriba la Edad de " << i +1 << " : " ;
19 cin >> amigo [ i ]. edad ;
20 cout << " \ nEscriba el sexo " << i +1 << ":";
21 cin >> amigo [ i ]. sexo ;
22 cout << " \ nEscriba el Telefono de " << i +1 << " : " ;
23 cin >> amigo [ i ]. telefono ;
24 cout << endl ;
25 };
26
27 // Impresion registros
28 cout << " El registro de personas que se introdujeron es :\ n \ n " ;
29 for ( int i = 0; i < 5; i ++){
30 cout << " \ t " << amigo [ i ]. nombre ;
31 cout << " \ t " << amigo [ i ]. edad ;
32 cout << " \ t " << amigo [ i ]. sexo ;
33 cout << " \ t " << amigo [ i ]. telefono << " \ n \ n " ;
34 };
35
36 // Edad promedio
37 double EProm = 0;
38 for ( int i = 0; i < 5; i ++){
39 EProm += 0.2* amigo [ i ]. edad ;
40 };
41
42 cout << " La edad promedio es : " << EProm << endl ;
43
44 return 0;
45 }
CAPÍTULO 3. DATOS ESTRUCTURADOS 36

3.4.1. Estructuras Anidadas


C++ permite que se incluya un struct dentro de otro, de este modo, podemos encontrarnos con
un registro que tenga varios datos, y a su vez ocurra que uno de esos datos se encuentre formado
por varios datos más sencillos.

A continuación, un ejemplo en el que se emplea una estructura anidada:


1 # include < iostream >
2 # include < string >
3 using namespace std ;
4
5 struct FechaNac {
6 int anio , mes , dia ;
7 };
8
9 struct estudiante {
10 string nombre , genero ;
11 FechaNac fecha ;
12 };
13
14 int main (){
15 estudiante E1 = { " Luis " , " Masculino " , {1997 , 10 , 29}};
16
17 cout << " Nombre del estudiante : " << E1 . nombre << endl ;
18 cout << " Genero : " << E1 . genero << endl ;
19 cout << " Fecha de nacimiento : " << E1 . fecha . dia << " / "
20 << E1 . fecha . mes << " / " << E1 . fecha . anio << endl ;
21 return 0;
22 }

3.5. Ejercicios
1. Realice un programa que calcule el producto de dos matrices cuadradas. El usuario debe
ingresar la dimensión n de las matrices a emplearse.

2. Realice un programa que lea de la entrada estándar una matriz de orden 3 × 3. Y mediante
la regla de Sarrus, obtenga el determinante de la matriz.

3. Defina una estructura que indique el tiempo empleado por Richard Carapaz en cubrir
cada una de las etapas del Giro de Italia. La estructura debe tener 4 campos: etapa, horas,
minutos y segundos. Escriba un programa que dado un vector con las etapas y tiempos
empleados, calcule lo siguiente:

Total de tiempo empleado por etapa (contrareloj, montaña, llano)


Identifique la etapa en la cual ha empleado el mayor y menor tiempo.

4. Realice un programa que pueda ser de utilidad para la elección de la directiva estudiantil
de la EPN. El programa debe leer primero el número de candidatos que se presenten
para obtener un cargo. Para cada uno de los candidatos, el programa deberá almacenar la
siguiente información:

Nombre
CAPÍTULO 3. DATOS ESTRUCTURADOS 37

Cédula
Género
Fecha de nacimiento

A continuación, el programa debe ir leyendo y almacenando en una estructura adecuada


los votos emitidos por cada alumno de la EPN.

El voto podrá ser un número entero que indica lo siguiente:

Si el número es 0, el voto se considera voto en blanco.


Si el número está en el intervalo [1, N ], siendo N el número de candidatos, el voto se
contabilizará como voto para el candidato correspondiente.
Si el número es −1, significa que la votación ha finalizado.
Si el número es distinto a los anteriores, el voto se considera voto nulo.

5. Realice un programa que trabaje con un vector de personas. Cada persona se almacena en
una estructura con los siguientes campos:

Nombre
Peso (kg)
Estatura (m)

El programa debe comenzar leyendo de la entrada estándar los datos de varias personas.
Y realizará lo siguiente:

Mostrar en la salida estándar un listado con los datos de las personas, el mismo que
debe incluir el índice de masa corporal de cada persona, éste índice se calcula como:
peso
IM C =
estatura2
Mostrar en la salida estándar el nombre de la persona con menor y mayor IMC.
Mostrar un listado de nombres de las personas cuya estatura supera la media.
4 | Números aleatorios

Una característica importante en la gran mayoría de lenguajes de programación es la posibilidad


de generar números aleatorios.

Los números aleatorios son pieza clave en la programación de juegos de azar, simulaciones,
cifrado de datos, en modelos estadísticos, etc. En esta capítulo aprenderemos a generar números
aleatorios para automatizar el proceso de llenado de arreglos y más.

4.1. Generación de números aleatorios enteros


Uno de los métodos más comunes para generar números aleatorios, llamado método congruen-
cial multiplicativo, comienza con un valor inicial x0 , llamado semilla, y luego se calcula de
manera recursiva los valores sucesivos xn , n ≥ 1, haciendo:

xn = axn−1 mód m

donde a y m son enteros positivos dados y lo anterior significa que axn−1 se divide entre m y el
residuo se considera como el valor de xn .
xn
Así, cada xn toma valores entre: 0, 1, . . . m − 1 y la expresión
(llamada número pseudoalea-
m
torio) se considera como una aproximación del valor de una variable aleatoria uniforme en el
intervalo (0, 1).

Figura 4.1: Números aleatorios

La generación de números aleatorios en C++ se realiza por medio de la función rand(), mis-
ma que se encuentra definida en la librería cstdlib. La función rand() devuelve un número
entero aleatorio en el rango de 0 a RAND_MAX, donde RAND_MAX es el límite superior y es-
te último depende de la capacidad computacional del ordenador, así como del sistema operativo.

A continuación, se muestra un programa que genera y almacena 20 números enteros aleatorios


entre 0 y RAND_MAX:

38
CAPÍTULO 4. NÚMEROS ALEATORIOS 39

1 # include < iostream >


2 # include < cstdlib >
3 using namespace std ;
4
5 int main (){
6 int vec [20];
7
8 // Generamos valores entre 0 y RAND_MAX
9 for ( int i =0; i <20; i ++){
10 vec [ i ] = rand ();
11 cout << vec [ i ] << " " ;
12 }
13
14 // Limite superior permitido por el equipo
15 cout << " \ n El RAND_MAX para este equipo es : " << RAND_MAX ;
16
17 return 0;
18 }

Si ejecutamos varias veces el programa anterior se puede observar que los números obtenidos
en cada ejecución coinciden. Esto se debe principalmente a que la semilla es exactamente la
misma en cada ejecución. Para solventar este problema se recomienda resetear la semilla en
cada llamado del código por medio del siguiente comando:

srand(time(NULL));

donde srand accede al valor de la semilla y time reemplaza el valor de la semilla por la fecha y
hora de ejecución.

Siempre que se desee replicar un experimento o análisis lo recomendado es fijar una semilla.

A continuación, un programa que genera 5 números aleatorios enteros distintos en cada ejecución:
1 # include < iostream >
2 # include < cstdlib >
3 using namespace std ;
4
5 int main (){
6 int vec [5];
7
8 // Semilla aleatoria
9 srand ( time ( NULL ));
10
11 // Generamos valores entre 0 y RAND_MAX
12 for ( int i =0; i <5; i ++){
13 vec [ i ] = rand ();
14 cout << vec [ i ] << " " ;
15 };
16
17 return 0;
18 }
CAPÍTULO 4. NÚMEROS ALEATORIOS 40

En ocasiones, se hace necesario generar números aleatorios enteros comprendidos en el rango


[0, M ], con M ∈ N. Para ello, definiremos un nuevo límite superior empleado la notación del
módulo ( %):

rand() % (Limite superior + 1)

A continuación, un programa que genera 100 números aleatorios entre [0, 20] y obtiene la suma
de dichos números:
1 # include < iostream >
2 # include < cstdlib >
3 using namespace std ;
4
5 int main (){
6 int vec [100];
7
8 // Semilla aleatoria
9 srand ( time ( NULL ));
10
11 // Valores aleatorios
12 cout << " Los valores generados son : " << endl ;
13 for ( int i =0; i <100; i ++){
14 vec [ i ] = rand () % 21;
15 };
16
17 // Calculo suma
18 int suma = 0;
19 for ( int i =0; i <100; i ++){
20 cout << vec [ i ] << endl ;
21 suma += vec [ i ];
22 };
23
24 cout << " La suma de los valores generados : " << endl ;
25 cout << suma << endl ;
26
27 return 0;
28 }

4.2. Generación de números aleatorios decimales


Ahora nos centraremos en la generación de números aleatorios decimales, para ello basta recordar
xn
que el número pseudoaleatorio yn = se distribuye uniformemente en el intervalo (0, 1). Es
m
decir,
yn ∼ U [0, 1]
por tanto,
b · yn ∼ U [0, b], para b ∈ R+
y además,
a + b · yn ∼ U [a, a + b], para a ∈ R y b ∈ R+
A continuación, se muestra un programa que genera 10 números aleatorios con 4 decimales en
el intervalo [1, 4].
CAPÍTULO 4. NÚMEROS ALEATORIOS 41

1 # include < iostream >


2 # include < cstdlib >
3 using namespace std ;
4
5 int main (){
6 double vec [10];
7
8 // Semilla aleatoria
9 srand ( time ( NULL ));
10
11 // Generamos valores entre 0 y RAND_MAX
12 for ( int i =0; i <10; i ++){
13 vec [ i ] = 1 + ( double ) ( rand () % 30001)/10000;
14 cout << vec [ i ] << " " ;
15 };
16
17 return 0;
18 }

4.3. Evaluación de integrales


Una de las primeras aplicaciones de los números aleatorios fue el cálculo de integrales. Sea g(x)
una función y supongamos que queremos calcular θ, donde:
∫ 1
θ= g(x)dx
0

Para calcular el valor de θ note que si U está distribuida uniformemente en (0, 1), entonces
podemos expresar θ como:
θ = E[g(U )]
Si U1 , U2 , . . . , Uk son variables aleatorias independientes y uniformes en (0, 1), esto implica que
g(U1 ), g(U2 ), . . . , g(Uk ) son variables aleatorias independientes e idénticamente distribuidas con
media θ.

Por lo tanto, por la ley fuerte de los grandes números, se tiene, con probabilidad igual a 1 que:


k
g(Ui )
→ E[g(U )] = θ, cuando k → ∞
i=1
k

De lo anterior, podemos aproximar θ generando un gran número de números aleatorios ui y con-


siderando como nuestra aproximación a θ el valor medio de g(ui ). Este método de aproximación
de integrales es conocido como el método de Monte Carlo.

A continuación, se muestra un programa que aproxima la integral:


∫ 1 x
e −1
θ= dx
0 e−1
mediante el método de Monte Carlo.
CAPÍTULO 4. NÚMEROS ALEATORIOS 42

1 # include < iostream >


2 # include < cmath >
3 # include < cstdlib >
4 using namespace std ;
5
6 int main (){
7 int k ;
8 double u , sum =0;
9
10 cout << " Ingrese el valor k " << endl ;
11 cin >> k ;
12
13 // Semilla aleatoria
14 srand ( time ( NULL ));
15
16 // Calculo de la integral
17 for ( int i =0; i < k ; i ++){
18 u = ( double ) (1 + rand () % 10000)/10000;
19 sum += ( double ) ( exp ( u ) -1)/( exp (1) -1);
20 };
21
22 // Impresion resultado
23 cout << " Valor integral : " << ( double ) sum / k << endl ;
24
25 return 0;
26 }

Si quisiéramos calcular la integral:


∫ b
θ= g(x)dx
a
entonces, al hacer la sustitución:
x−a dx
y= y dy =
b−a b−a
vemos que:
∫ 1
θ= g (a + [b − a]y) (b − a)dy
0
∫ 1
= h(y)dy
0

donde h(y) = (b − a)g (a + [b − a]y). Así, podemos aproximar θ al generar de manera continua
números aleatorios y luego considerar el valor promedio de h evaluada en estos números aleato-
rios.

A continuación, un programa que calcula la integral definida:


∫ 5
x
θ= dx
2 x2 −1
mediante el método de Monte Carlo.
CAPÍTULO 4. NÚMEROS ALEATORIOS 43

1 # include < iostream >


2 # include < cmath >
3 # include < cstdlib >
4 using namespace std ;
5
6 int main (){
7 int k , a =2 , b =5;
8 double u , z , sum =0;
9
10 cout << " Ingrese el valor k " << endl ;
11 cin >> k ;
12
13 // Semilla aleatoria
14 srand ( time ( NULL ));
15
16 // Calculo integral
17 for ( int i =0; i < k ; i ++){
18 u = ( double ) (1 + rand () % 10000)/10000;
19 z = a + (b - a )* u ;
20 sum += (b - a )*(( double ) z /( pow (z ,2) -1));
21 }
22
23 // Impresion resultado
24 cout << " Valor integral : " << ( double ) sum / k << endl ;
25
26 return 0;
27 }

De manera análoga, si queremos el valor de


∫ ∞
θ= g(x)dx
0

podríamos aplicar la sustitución


1 −dx
y= , dy = = −y 2 dx
x+1 (x + 1)2

para obtener la identidad ∫ 1


θ= h(y)dy
0
donde ( )
g 1
y −1
h(y) =
y2

4.4. Ejercicios
1. Si x0 = 9 y
xn = 4 · xn−1 mód 20
determine x1 , x2 , . . . , x10 .

2. Emplee el método de Monte Carlo para aproximar las siguientes integrales:


CAPÍTULO 4. NÚMEROS ALEATORIOS 44
∫ 1 ∫ 2
2
a) (1 − x2 )3/2 dx c) ex+x dx
0 −2
∫ 5 ∫ ∞
b) log(x2 − 4x)dx d) x(1 + x2 )−2 dx
0 0
5 | Funciones

Una función es un fragmento de código que permite ejecutar una serie de instrucciones para-
metrizadas. Las funciones son de gran utilidad porque permiten estructurar el código de un
programa. Una función realiza una tarea concreta y puede ser diseñada, implementada y depu-
rada de manera independiente al resto del código.

5.1. Definición de función


La sintaxis básica para la definición de una función en C++ es la siguiente:

tipo nombre(tipo1 var1, tipo2 var2, ... , tipon, varn){


bloque de instrucciones
.....
return expresion;
}

A la primera línea se le llama signatura de la función e incluye el tipo del valor devuelto por la
función o valor de retorno, el nombre de la función y la lista de parámetros formales de la fun-
ción que consiste en un listado de variables separadas por comas y encerradas entre paréntesis.
Cada variable de la lista de parámetros formales viene precedida por su tipo. A continuación, y
delimitado por llaves, viene el bloque de instrucciones asociado a la función, también llamado
cuerpo de la función.

El efecto de la sentencia return es evaluar su expresión asociada y terminar la ejecución de la


función devolviendo el resultado de evaluar la expresión. Se permite una expresión de un tipo
que admita una conversión implícita al tipo de retorno de la función.

Las funciones devuelven únicamente tipos básicos: int, double, float, string, etc.

A continuación, un programa que devuelve una etiqueta:


1 # include < iostream >
2 using namespace std ;
3
4 string escala ( double n ){
5 string etiqueta ;
6 if ( n < 5){
7 etiqueta = " Reprobado " ;
8 } else if ( n < 9){
9 etiqueta = " Aprobado " ;
10 } else {
11 etiqueta = " Sobresaliente " ;

45
CAPÍTULO 5. FUNCIONES 46

12 }
13 return etiqueta ;
14 };
15
16 int main (){
17 double nota ;
18 cout << " Ingrese la nota obtenida en el examen : " << endl ;
19 cin >> nota ;
20 cout << " La escala alcanzada es : " << escala ( nota ) << endl ;
21
22 return 0;
23 }

Una función puede contener más de una instrucción return, en ese caso la ejecución de la función
terminará cuando se ejecute por primera vez una instrucción return.

A continuación, un programa que define una función con doble return:


1 # include < iostream >
2 using namespace std ;
3
4 double maximo ( double x , double y ){
5 if (x > y )
6 return x ;
7 return y ;
8 }
9
10 int main (){
11 double a , b ;
12 cout << " Ingrese dos números " << endl ;
13 cin >> a >> b ;
14 // Se imprime el máximo de los dos numeros
15 cout << " El máximo es : " << maximo (a , b ) << endl ;
16 return 0;
17 }

5.2. Parámetros por defecto


El uso de parámetros por defecto es otra característica propia de C++ que no está presente en
algunos lenguajes de programación. Un parámetro por defecto es un parámetro que no tiene por
qué ser especificado al invocar a una función. Si en la invocación de la función no se especifica
un parámetro por defecto entonces se le asigna un valor por defecto al parámetro.

A continuación, un programa que calcula el logaritmo en diferentes bases (por defecto se mantiene
la base 2):

1 # include < iostream >


2 # include < cmath >
3 using namespace std ;
4
5 double logn ( double valor , double base =2){
CAPÍTULO 5. FUNCIONES 47

6 return log ( valor )/ log ( base );


7 }
8
9 int main (){
10 double x , n ;
11 cout << " Ingrese un valor y la base : " << endl ;
12 cin >> x >> n ;
13 cout << " El logaritmo de " << x << " en base " << n << " es : "
14 << logn (x , n ) << endl ;
15 cout << " El logaritmo de " << x << " en base 2 es : "
16 << logn ( x ) << endl ;
17 return 0;
18 }

5.3. Tipos de datos que devuelve una función


En C++, una función puede devolver valores de aquellos tipos de datos para los que la asigna-
ción está definida, la asignación a un tipo de dato está definida si es posible asignar valores a
las variables de dicho tipo con el operador de asignación (=).

De los tipos de datos que hemos visto los únicos para los que la asignación no está definida son
los tipos vector y array. Para el resto de tipos: tipos básicos, estructuras y cadenas de caracteres
la asignación está definida y, por tanto, una función puede devolver un dato de tipo básico, de
tipo string o de tipo estructura, pero no puede devolver un vector.

A continuación, un programa que devuelve una estructura:


1 # include < iostream >
2 using namespace std ;
3
4 // Definimos una nueva estructura que almacena dos valores
5 struct ValMM {
6 double max , min ;
7 };
8
9 // Definimos una función que devuelve la estructura anterior
10 ValMM MaxMin ( double x , double y ){
11 ValMM num ;
12 if ( x > y ){
13 num . max = x ;
14 num . min = y ;
15 } else {
16 num . max = y ;
17 num . min = x ;
18 }
19 return num ;
20 };
21
22 int main (){
23 double a , b ;
24 ValMM numeros ;
CAPÍTULO 5. FUNCIONES 48

25 cout << " Ingrese dos valores : " << endl ;


26 cin >> a >> b ;
27 numeros = MaxMin (a , b );
28 cout << " El valor máximo es : " << numeros . max << endl ;
29 cout << " El valor mínimo es : " << numeros . min << endl ;
30 return 0;
31 }

5.4. Funciones void


Se suele utilizar el término función void para designar a una función que no tiene valor de re-
torno. Puesto que la sintaxis de C++ obliga a indicar un tipo de retorno, las funciones void
utilizan el tipo especial void como tipo de retorno.

A continuación, el programa de Hola mundo mejorado:


1 # include < iostream >
2 using namespace std ;
3
4 void saludo (){
5 cout << " Hola Mundo \ n " ;
6 }
7
8 int main (){
9 saludo ();
10 return 0;
11 }

Aunque una función no tenga valor de retorno, es decir, aunque sea una función void es posible
utilizar la sentencia return en su cuerpo para terminar la ejecución de la función. En una función
void la sentencia return debe utilizarse sin expresión asociada, es decir:

return ;

Si una función void no utiliza ninguna sentencia return, la ejecución de la función termina cuan-
do se ejecuta la última instrucción de la función.

Las funciones void deben invocarse mediante una instrucción que incluya únicamente la llamada
a la función.

A continuación, un programa que calcula una aproximación de pi con un error de 0.00001:



π ∑ (−1)n

4 i=0
2n + 1

1 # include < iostream >


2 # include < cmath >
3 using namespace std ;
4
5 double termino ( int n ){
6 return ( float ) pow ( -1 , n )/(2* n +1);
7 }
CAPÍTULO 5. FUNCIONES 49

8
9 void pi (){
10 float error = 0.00001 , suma = 0 , xn , xm ;
11 int i =0;
12 do {
13 xn = termino ( i );
14 xm = termino ( i +1);
15 suma += xn ;
16 i ++;
17 } while ( abs ( xn - xm ) >= error );
18
19 cout << " Valor aproximado de pi es : " << 4* suma << endl ;
20 cout << " Numero de iteraciones : " << i << endl ;
21 return ;
22 }
23
24 int main (){
25 cout << " Aproximacion de pi \ n " << endl ;
26 pi ();
27 return 0;
28 }

5.5. Almacenamiento de variables


A las variables definidas en una función se les llama variables locales, en contraste con las varia-
bles definidas fuera de las funciones que son llamadas variables globales.

El ámbito de una variable global abarca desde el lugar de su definición hasta el final del fichero
en que se ha definido, pudiendo ser utilizada en cualquier función situada en dicho ámbito. Una
variable local con el mismo nombre que una variable global oculta a la variable global.

A continuación, un programa en el que una variable local oculta a la variable global:


1 # include < iostream >
2 using namespace std ;
3
4 int fun ( int anio ){
5 anio = 2019;
6 return anio ;
7 }
8
9 int main (){
10 int anio =2000;
11 cout << " Nos encontramos en el anio " << fun ( anio ) << endl ;
12 cout << " Naci en el anio " << anio << endl ;
13 return 0;
14 }

El ámbito de una variable local abarca desde su lugar de definición en la función hasta el final
del bloque más interno en que ha sido definida. Los parámetros formales de una función son
variables locales de la función y, a efecto de ámbito, se encuentran definidas en el bloque más
CAPÍTULO 5. FUNCIONES 50

externo de la función, es decir, entre las llaves que delimitan el cuerpo de la función.

El uso de variables globales para implementar la comunicación entre funciones presenta algunos
inconvenientes:

1. Una función que se comunica con el resto mediante variables globales no es reutilizable,
salvo en un entorno en el que se utilicen las mismas variables globales. Se dice que la
función está fuertemente acoplada al resto del código.

2. El uso de variables globales puede producir los llamados efectos colaterales. Esto ocurre
cuando una variable global es ocultada por una variable local inadvertidamente.

Las variables globales se almacenan en una zona de memoria denominada memoria global. Una
variable global permanece almacenada en la memoria global durante todo el tiempo que dure la
ejecución de un program. Esto resulta necesario porque una variable global puede ser utilizada
por más de una función.

5.5.1. La Pila
Las variables locales de una función se almacenan en la pila. La pila es una zona de memoria
contigua donde se almacenan las variables locales de las funciones y alguna otra información,
como la dirección de memoria de retorno de una función. El tamaño de la pila varía dinámi-
camente durante la ejecución de un programa; cuando se invoca a una función la pila crece
hacia direcciones superiores de memoria para albergar a sus variables locales, se dice que las
variables se apilan; cuando una función termina la pila decrece y sus variables locales dejan de
ser accesibles, se dice que las variables se desapilan.

Figura 5.1: Esquema de una pila

Una variable almacenada en la pila tiene un tiempo de existencia limitado al tiempo en que se
ejecuta el código asociado al ámbito de la variable.

5.5.2. Estado de la pila


Para analizar el estado de una pila durante algunos instantes de una ejecución se analizará el
siguiente programa:

1 # include < iostream >


2 using namespace std ;
3
4 double maximo ( double x , double y ){
5 double m ;
6 if (x > y ){
7 m = x;
8 } else {
9 m = y;
CAPÍTULO 5. FUNCIONES 51

10 }
11 return m ;
12 }
13
14 int main (){
15 double a , b ;
16 cout << " Ingrese dos números " << endl ;
17 cin >> a >> b ;
18
19 // Se imprime el máximo de los dos numeros
20 cout << " El máximo es : " << maximo (a , b ) << endl ;
21
22 // Se vuelve a invocar a maximo
23 cout << " El máximo de a y 10 es : " << maximo (a , 10) << endl ;
24 a = 8;
25 double z = 3 + maximo (a , a -1);
26 cout << " z vale : " << z << endl ;
27 return 0;
28 }
Ejecutamos el programa anterior considerando a = 6 y b = 8.

Figura 5.2: Estado de la pila durante la ejecución del programa

5.6. Funciones recursivas


Se dice que una función es recursiva cuando dentro de su bloque de sentencias hay una llamada
a la propia función.

En principio cualquer función puede hacerse una llamada a sí misma, sin embargo, tiene que
estar especialmente diseñada para que funcione correctamente, ya que al llamarse a sí misma
provoca que ésta se vuelva a ejecutar, y dentro de sus instrucciones se vuelve a llamar, creando
un bucle que si no está controlado se vuelve infinito.

Por lo tanto, una función recursiva forma un bucle al ser llamada a si misma. Este bucle debe
ser controlado de alguna manera para poder salir de él y no caer en estructuras indeseadas como
CAPÍTULO 5. FUNCIONES 52

bucles infinitos o estructuras que se autorreplican indefinidamente.

A continuación, un programa que calcula el factorial de un número entero positivo:


1 # include < iostream >
2 using namespace std ;
3
4 long int factorial ( int n ){
5 if ( n == 1){
6 return 1;
7 } else {
8 return n * factorial (n -1);
9 }
10 };
11
12 int main (){
13 long int n ;
14 cout << " Ingrese un numero entero positivo : " << endl ;
15 cin >> n ;
16 cout << n << " ! = " << factorial ( n ) << endl ;
17
18 return 0;
19 }

La recursividad facilita la escritura de código que trabaja con estructuras de datos o problemas
que tienen una naturaleza recursiva como la estructura de datos árbol. Además, produce un
código más legible para este tipo de problemas.

5.7. Paso por variable o referencia


Una función en C++ sólo tiene un valor de retorno. Sin embargo, a veces se necesita que una
función devuelva más de un valor; por ejemplo, podríamos necesitar una función que devuelva
tanto el máximo como el mínimo de los valores recibidos como parámetros. Se puede conseguir
devolver más de un valor utilizando como tipo de retorno una estructura que contenga tantos
campos como valores a devolver. Ver ejemplo de la sección 4.3. Esta solución no es muy elegante
pues implica la definición de una estructura con el único objeto de almacenar los valores de
retorno.

En C++ se pueden utilizar los parámetros formales de una función para que la misma devuelva
datos. En esta sección nos centraremos en estudiar como utilizar variables de tipo referencia.

5.7.1. Referencias
Una referencia es un nombre alternativo para un dato u objeto. La sintaxis T& significa refe-
rencia a un objeto del tipo T.

Una variable de tipo referencia debe iniciarse en su definición con un objeto del mismo tipo que
el tipo asociado a la referencia. Al objeto con que se inicia la referencia lo llamaremos el objeto
referenciado por la referencia.

A continuación, un programa que define una referencia y muestra la dirección de memoria en la


que se almacena una variable:
CAPÍTULO 5. FUNCIONES 53

1 # include < iostream >


2 using namespace std ;
3
4 int main (){
5 int x =4;
6 // Definición e inicialización de la referencia
7 int & ref_x = x ;
8
9 cout << " Valor del objeto referenciado : " << ref_x << endl ;
10 cout << " Direccion del objeto referenciado : " << & x << endl ;
11 return 0;
12 }

Una referencia es por así decirlo un alias o etiqueta de una variable.

Figura 5.3: Estado de la pila durante la ejecución del programa

Ahora, analicemos que sucede si se modifica el valor de x:


1 # include < iostream >
2 using namespace std ;
3
4 int main (){
5 int x =4;
6 // Definición e inicialización de la referencia
7 int & ref_x = x ;
8
9 cout << " Valor del objeto referenciado : " << ref_x << endl ;
10 cout << " Direccion del objeto referenciado : " << & x << endl ;
11
12 // Modificamos el valor de x
13 x = 9;
14
15 cout << " Valor del objeto referenciado : " << ref_x << endl ;
16 cout << " Direccion del objeto referenciado : " << & x << endl ;
17 return 0;
18 }

Una referencia siempre tiene asociado el mismo objeto referencia, a saber, el objeto con que se ha
iniciado la referencia. Una vez iniciada una referencia, cuando un programa utiliza la referencia
CAPÍTULO 5. FUNCIONES 54

realmente se trabaja con su objeto referenciado.

A continuación, otro programa que intenta mostrar el manejo de referencias:


1 # include < iostream >
2 using namespace std ;
3
4 int main (){
5 int x = 6;
6 int v [] = {1 ,2};
7 int & r1 = x ;
8 int & r2 = v [0];
9
10 cout << x << " \ t " << v [0] << " \ t " << v [1] << endl ;
11 r1 = 4;
12 r2 ++;
13 cout << x << " \ t " << v [0] << " \ t " << v [1] << endl ;
14 cout << r1 << " \ t " << r2 << endl ;
15 return 0;
16 }

Analicemos el estado de la pila en algunos momentos de la ejecución del programa:

Figura 5.4: Estado de la pila durante la ejecución del programa

5.7.2. Paso por referencia


Las referencias se utilizan principalmente para implementar el paso por variable o por referencia.
El paso por variable se puede utilizar para que una función devuelva información mediante un
parámetro.

A continuación, un primer programa que usa referencias:


1 # include < iostream >
2 using namespace std ;
3
4 // Paso por variable
5 void incremento1 ( int a ) {
6 a = a + 1;
7 return ;
8 }
9
10 // Paso por referencia
CAPÍTULO 5. FUNCIONES 55

11 void incremento2 ( int & a ) {


12 a = a + 1;
13 return ;
14 }
15
16 int main () {
17 int x = 3;
18 // Funcion con paso por variable
19 incremento1 ( x );
20 cout << " x tiene el valor : " << x << endl ;
21
22 int y = 3;
23 // Funcion con paso por referencia
24 incremento2 ( y );
25 cout << " y tiene el valor : " << y << endl ;
26
27 return 0;
28 }

Notemos que los cuerpos de las funciones incremento1 e incremento2 son iguales, sin embargo,
los parámetros formales de la función son diferentes, para la primera función se hace un paso
por variable, mientras que la segunda función realiza un paso por referencia.

Para el siguiente programa nos encontramos interesados en realizar la división entre dos número
enteros y obtener dos resultados: el cociente y el residuo.

1 # include < iostream >


2 using namespace std ;
3
4 int division ( int dividendo , int divisor , int & residuo ){
5 residuo = dividendo % divisor ;
6 return dividendo / divisor ;
7 }
8
9 int main () {
10 int num , den , res ;
11 cout << " Ingrese el dividendo y divisor : " << endl ;
12 cin >> num >> den ;
13 int cociente = division ( num , den , res );
14
15 cout << " El cociente es : " << cociente << endl ;
16 cout << " El residuo es : " << res << endl ;
17 cout << " Se verifica que : " << cociente << " * " << den
18 << " + " << res << " = " << num << endl ;
19
20 return 0;
21 }

En el programa anterior a partir de una referencia es posible obtener 2 o más valores resultantes
de la ejecución de una función.

A continuación, retomamos nuestro trillado ejemplo del mínimo y máximo de dos números:
CAPÍTULO 5. FUNCIONES 56

1 # include < iostream >


2 using namespace std ;
3
4 void MaxMin ( double x , double y , double & min , double & max ){
5 if ( a > b ){
6 max = x ;
7 min = y ;
8 } else {
9 max = y ;
10 min = x ;
11 }
12 return ;
13 }
14
15 int main (){
16 double a , b , maximo , minimo ;
17 cout << " Ingrese dos números : " << endl ;
18 cin >> a >> b ;
19 // Invocamos a la función
20 MaxMin (a , b , minimo , maximo );
21 // Imprimos los resultados
22 cout << " El maximo es : " << maximo << endl ;
23 cout << " El minimo es : " << minimo << endl ;
24 return 0;
25 }

Ejecutemos el anterior programa con: a = 3 y b = 7

Figura 5.5: Estado de la pila durante la ejecución del programa


CAPÍTULO 5. FUNCIONES 57

El programa incluye una función, llamada MaxMin, cuyos dos últimos parámetros formales,
max y min, tienen semántica de paso por referencia. Cuando se invoca a la función MaxMin,
max y min se inician con los dos objetos pasados como parámetros reales. Cuando la función
MaxMin realiza alguna modificación o consulta sobre las variables max o min realmente está
modificando o consultando los objetos referenciados por estas dos variables. Esto permite que
tras la ejecución de la función MaxMin, la función main pueda consultar los valores de máximo
y mínimo calculados por la función MaxMin.

Cuando la función MaxMin asigna valores a las referencias max y min los valores asignados se
almacenan en las variables maximo y minimo respectivamente. Esto permite que tras ejecutar
la función MaxMin las variables maximo y minimo contengan los dos valores calculados por
MaxMin.

Cuando un parámetro formal es de tipo referencia, el parámetro real utilizado en la invocación


debe ser una variable, si se usa el calificativo const como calificador del parámetro formal no es
necesario utilizar una variable, de ahí el nombre de paso por variable.

5.8. Paso de parámetros tipo estructura


El paso de parámetros de tipo estructura se realiza de la misma manera que el de un tipo básico.
El paso de una estructura como parámetro por valor de una función puede ser algo ineficiente
pues implica la iniciación de la estructura de todos sus campos. Cuantos más campos tenga la
estructura más costoso resultará su paso por valor.

A continuación, un ejemplo de la suma de números complejos:


1 # include < iostream >
2 using namespace std ;
3
4 struct complejo {
5 double real ;
6 double imaginario ;
7 }
8
9 complejo suma ( complejo x , complejo y ){
10 complejo res ;
11 res . real = x . real + y . real ;
12 res . imaginario = x . imaginario + y . imaginario ;
13 return res ;
14 }
15
16 void impcomplejo ( complejo w ){
17 cout << w . real << " + " << w . imaginario << " . i " << endl ;
18 }
19
20 int main (){
21 complejo x ,y , z ;
22 cout << " Ingrese el primer complejo : " << endl ;
23 cin >> x . real ;
24 cin >> x . imaginario ;
25 cout << " Ingrese el segundo complejo : " << endl ;
26 cin >> y . real ;
CAPÍTULO 5. FUNCIONES 58

27 cin >> y . imaginario ;


28 z = suma (x , y );
29 cout << " El resultado es : " ;
30 impcomplejo ( z );
31
32 return 0;
33 }

5.9. Sobrecarga de funciones


La sobrecarga de funciones es una característica de C++ que no está presente en la gran mayo-
ría de lenguajes de programación. Consiste en poder definir más de una función con el mismo
nombre, siempre que los parámetros de las funciones difieran en número o tipo.

A continuación, un programa que presenta una sobrecarga:


1 # include < iostream >
2 using namespace std ;
3
4 double maximo ( double x , double y ){
5 if ( x > y )
6 return x ;
7 return y ;
8 };
9
10 double maximo ( const double x [] , int dim ){
11 double max = x [0];
12 for ( int i = 1; i < dim ; i ++){
13 if ( x [ i ] > max ){
14 max = x [ i ];
15 }
16 }
17 return max ;
18 };
19
20 int main (){
21 double a , b ;
22 double vec [5];
23 cout << " Ingrese dos números : " << endl ;
24 cin >> a >> b ;
25 cout << " El mayor valor es : " << maximo (a , b ) << endl ;
26 cout << " Ingrese 5 números : " << endl ;
27 for ( int j = 1; j <= 5; j ++){
28 cin >> vec [j -1];
29 }
30 cout << " El máximo valor ingresado es : " << maximo ( vec , 5) << endl ;
31
32 return 0;
33 }
CAPÍTULO 5. FUNCIONES 59

5.10. Paso de parámetros de tipo vector


Un parámetro de tipo vector se especifica de la misma forma que se define una variable de tipo
vector, salvo que no es necesario especificar su tamaño. Como a través de una variable de tipo
vector no es posible saber cuántos elementos almacena el vector, se utiliza otro parámetros para
recibir el número de elementos que almacena el vector.

A continuación, un programa que recibe como parámetro un vector:


1 # include < iostream >
2 # include < cmath >
3 using namespace std ;
4
5 void cuadrado ( double x [] , int dim ){
6 for ( int i = 0; i < dim ; i ++){
7 x [ i ] = pow ( x [ i ] ,2);
8 }
9 };
10
11 void impvector ( double x [] , int dim ){
12 for ( int i = 0; i < dim ; i ++){
13 cout << x [ i ] << " \ t " ;
14 }
15 };
16
17 int main (){
18 double vec [5];
19 cout << " Ingrese 5 números : " << endl ;
20 for ( int j = 1; j <= 5; j ++){
21 cin >> vec [j -1];
22 }
23 cuadrado ( vec , 5);
24 cout << " Los números al cuadrado son : " << endl ;
25 impvector ( vec ,5);
26 return 0;
27 }

Una variable de tipo vector almacena la dirección de memoria a partir de la cual se almacenan
los elementos del vector. Por lo tanto, lo que recibe un parámetro formal de tipo vector es la
dirección de memoria donde se almacena un vector. Al recibir la dirección de memoria donde
se almacena el vector, la función tiene total acceso a los elementos originales del vector y, por
tanto, las modificaciones que realice en los elementos del vector serán visibles al terminar la
ejecución de la función.

A continuación, se muestra un programa que genera estadísticas a partir de la información de


10 estudiantes:
1 # include < iostream >
2 using namespace std ;
3
4 void leer ( double a []){
5 int i ;
6 cout << " Ingrese las estaturas de los alumnos : " << endl ;
CAPÍTULO 5. FUNCIONES 60

7 for ( i =0; i <10; i ++){


8 cout << " Alumno " << i +1 << " : " ;
9 cin >> a [ i ];
10 }
11 }
12
13 double estatura_media ( double a []){
14 double media = 0;
15 int i ;
16 for ( i =0; i <10; i ++){
17 media = media + a [ i ];
18 }
19 media = media / 10;
20 return media ;
21 }
22
23 void max_min ( double a [] , double & max , double & min ){
24 int i ;
25 max = min = a [0];
26 for ( i =1; i <10; i ++){
27 if ( a [ i ] > max ){
28 max = a [ i ];
29 } else {
30 if ( a [ i ] < min )
31 min = a [ i ];
32 }
33
34 }
35 }
36
37 void c u a n t o s _ m a y o r _ m e n o r _ m e d i a ( double a [] , double media ,
38 int & mayores_media , int & menores_media ){
39 int i ;
40 for ( i =0; i <10; i ++){
41 if ( a [ i ] > media )
42 mayores_media ++;
43 else if ( a [ i ] < media )
44 menores_media ++;
45 }
46 }
47
48 void mostr ar _r es ul ta do s ( double a [] , double media , double mayor ,
49 double menor , int mayores_media , int menores_media ){
50 int i ;
51 cout << " Estatura de los alumnos de la clase " << endl ;
52 cout << " - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - " << endl ;
53 for ( i =0; i <10; i ++){
54 cout << " Alumno " << i +1 << " : " << a [ i ] << endl ;
55 }
56 cout << " Mayor estatura : " << mayor << endl ;
57 cout << " Menor estatura : " << menor << endl ;
CAPÍTULO 5. FUNCIONES 61

58 cout << " Estatura media : " << media << endl ;
59 cout << " Hay " << mayores_media << " alumnos con estatura " ;
60 cout << " superior a la media " << endl ;
61 cout << " Hay " << menores_media << " alumnos con estatura " ;
62 cout << " inferior a la media " << endl << endl ;
63 }
64
65 int main (){
66 double estaturas [10] , media , mayor , menor ;
67 int cont_mas = 0 , cont_menos = 0;
68 leer ( estaturas );
69 max_min ( estaturas , mayor , menor );
70 media = estatura_media ( estaturas );
71 cu a n t o s _ m a y o r _ m e n o r _ m e d i a ( estaturas , media , cont_mas , cont_menos );
72 mos tr ar_resultado s ( estaturas , media , mayor , menor , cont_mas ,
73 cont_menos );
74 return 0;
75 }

5.11. Paso de parámetros de tipo array


Para realizar el paso de un array a una función se debe tener en cuenta lo siguiente:

En la función se debe declarar el parámetro como un array del tipo adecuado. En los
arrays unidimensionales no es necesario especificar el tamaño por lo tanto aparecerán los
corchetes vacíos.

En la llamada a la función a la que se envía el array, el nombre del array aparecerá solo,
sin corchetes ni índices

Los arrays en C++ se pasan siempre a las funciones por referencia. El nombre de un array
realmente es un puntero que contiene la dirección de memoria donde comienza el array, o lo
que es lo mismo, la dirección de memoria del primer elemento. Cuando se pasa un array a una
función, la función recibe la dirección de memoria donde se encuentra el primer elemento del
array. Por lo tanto, la función trabaja sobre el array original.

No es necesario utilizar el operador & en el paso de arrays a funciones para indicar que se hace
por referencia ya que siempre pasan por referencia.

A continuación, un programa que pasa un array por una función:


1 # include < iostream >
2 using namespace std ;
3
4 const int MAXFIL = 20;
5 const int MAXCOL = 30;
6
7 void leerMatriz ( int matriz [][ MAXCOL ] , int nf , int nc ){
8 int fila , col ;
9 for ( fila =0; fila < nf ; fila ++ ){
10 cout << " \ nFila : " << fila +1 << endl ;
11 for ( col =0; col < nc ; col ++){
CAPÍTULO 5. FUNCIONES 62

12 cout << " Elemento : " << col +1 <<" : " ;


13 cin >> matriz [ fila ][ col ];
14 }
15 }
16 }
17
18 void sumarMatrices ( int matriz1 [][ MAXCOL ] , int matriz2 [][ MAXCOL ] ,
19 int matriz3 [][ MAXCOL ] , int nf , int nc ){
20 int fila , col ;
21 for ( fila =0; fila < nf ; fila ++ ){
22 for ( col =0; col < nc ; col ++)
23 matriz3 [ fila ][ col ] = matriz1 [ fila ][ col ] + matriz2 [ fila ][ col ];
24 }
25 }
26
27 void mostrarResultado ( int matriz [][ MAXCOL ] , int nf , int nc ){
28 int fila , col ;
29 for ( fila =0; fila < nf ; fila ++ ){
30 for ( col =0; col < nc ; col ++)
31 cout << matriz [ fila ][ col ] << " \ t " ;
32 cout << endl ;
33 }
34 }
35
36 int main (){
37 int nfilas , ncols ;
38 int matriz1 [ MAXFIL ][ MAXCOL ];
39 int matriz2 [ MAXFIL ][ MAXCOL ];
40 int matriz3 [ MAXFIL ][ MAXCOL ];
41
42 do {
43 cout < < " \ nIntroduce numero de filas . Maximo " << MAXFIL << " : " ;
44 cin >> nfilas ;
45 } while ( nfilas <=0 or nfilas > MAXFIL );
46
47 do {
48 cout < < " \ nIntroduce numero de columnas . Maximo " << MAXCOL < < " : " ;
49 cin >> ncols ;
50 } while ( ncols <=0 or ncols > MAXCOL );
51
52 // Lectura de datos de la primera matriz
53 cout << " \ n Introduce datos de la primera matriz " ;
54 leerMatriz ( matriz1 , nfilas , ncols );
55
56 // Lectura de datos de la segunda matriz
57 cout << " \ n Introduce datos de la segunda matriz " ;
58 leerMatriz ( matriz2 , nfilas , ncols );
59
60 // Calcular la suma de las dos matrices
61 sumarMatrices ( matriz1 , matriz2 , matriz3 , nfilas , ncols );
62
CAPÍTULO 5. FUNCIONES 63

63 // Mostrar el resultado por pantalla


64 cout << " \ nmatriz 1: " << endl ;
65 mostrarResultado ( matriz1 , nfilas , ncols );
66
67 cout << " \ nmatriz 2: " << endl ;
68 mostrarResultado ( matriz2 , nfilas , ncols );
69
70 cout << " \ nmatriz 3 = matriz1 + matriz2 " << endl ;
71 mostrarResultado ( matriz3 , nfilas , ncols );
72
73 return 0;
74 }

5.12. Ejercicios
1. Realice un programa que permita al usuario ingresar 10 valores enteros y muestre en
pantalla los elementos impares ingresados.

2. Realice un programa que permita al usuario ingresar un vector de longitud 20 y ordene


sus elementos ascendentemente.

3. Una matriz A ∈ Rn×n se dice que es simétrica si aij = aji , ∀i, j ∈ {1, . . . , n}. Desarrolle
una función que determine si una matriz es simétrica o no.

4. Realice un programa que compruebe si es válido el relleno de un Sudoku. Para lo cual


elabore las siguientes funciones:

Función que dado un Sudoku y un número de fila del Sudoku devuelva un valor de
tipo lógico indicando si no se repiten dos dígitos en la fila.
Función que dado un Sudoku y un número de columna del Sudoku devuelva un valor
de tipo lógico indicando si no se repiten dos dígitos en la columna.
Función que dado un Sudoku y la primera fila y columna de una caja del Sudoku
devuelva un valor de tipo lógico indicando si no se repiten dos dígitos en la caja.

También podría gustarte