Codigo en C++ Para Crear un Archivo y
Guardar datos
//librerias
#include<stdio.h>
#include<iostream.h>
#include<conio.h>
#include <string.h>
//V.G
//Estructuras
struct autos{///estructura donde seguarda las variable
char placas[20];
char marca[20];
char modelo[20];
int ano;
};
//funciones
//funcion principal
void main() //inicio de main
{
//variables locales
FILE * archivo;//define donde se guarda el archivo
autos consul;
char siono,placas3[10];//definicion de variablas
int opcion;
//Inicio de ciclo do while
do{//apertura de do
cout<<"tGiovanny Castellanos"<<endl;
cout<<"nArchivo de Carro";//menu de operaciones//Muestra en pantala
cout<<"n1.-Guardar";//Muestra en pantala
cout<<"n2.-Consultar";//Muestra en pantala
cout<<"n3.-salirn";//Muestra en pantala
cout<<"selecciona una opcion: ";//Muestra en pantala
cin>>opcion;
switch(opcion)
{//apertura del switch
case 1://primera opcion de menu
archivo=fopen("[Link]", "a+" ;//definicion del archivo
cout<<"nDame el numero de placas: ";//menu para agregar los datos
cin>> [Link];
cout<<"nMarca: ";
cin>> [Link];
cout<<"nModelo: ";
cin>> [Link];
cout<<"nAño: ";
cin>> [Link];
cout<<"Desea Guardar?";//regresa al menu
siono=getch();
if(siono=='s')//condicion if
{
fwrite(&consul, sizeof(struct autos),1,archivo);//afirmacion de guardar el arch
cout<<"n Registro Guardadon"<<endl;
}
else//si no se cumple la condicion ejecuta esto
{
cout<<"nla informacion no se a guardadon"<<endl;
}
fclose(archivo);//cierre del archivo
break;//cierre del primer case
case 2://apertura del 2°do menu
cout<<"nDame el numero de placas:n ";//para buscar lo que se guardo
fread(&consul, sizeof(struct autos),1, archivo);//consulta el archivo
while(!feof(archivo))
{ //apertura del while
if(strcmp(placas3,[Link])==0)//compara una cadena de caracteres
{ cout<<"Marca: "<<[Link]<<endl;//muestra lo guardado
cout<<"Modelo: "<<[Link]<<endl;
cout<<"Año: "<<[Link]<<endl;
}
fread(&consul, sizeof(struct autos),1, archivo);
} //cierre del while
fclose(archivo);//cierre del archivo
cout<<"nRegresar al Menu: ";
siono=getch();//regresa al menu
clrscr();//limpia pantalla
break;
case 3 ://tercera opcion para salir de programa
cout<<"Salirn";//Muestra en pantala
break;
} //cierre del switch
}while(siono=='s');
////////cierre del ciclo do while
} //cierre del main
Choc Cac, Mynor R.
correo: mynorrene arroba choccac punto com
lmcc
*/
#include <iostream>
#include <fstream>
using namespace std;
/*
Solo usara estas tres variales, creo que ocn eso es suficiente.
*/
struct MisDatos{
char nombre[50];
char apellido[50];
char direccion[50];
};
void Guardar(MisDatos guardar)
{
fstream archivo ;
[Link]("[Link]",ios::out | ios::app | ios::binary);
[Link]( (char *)&guardar,sizeof(MisDatos));
[Link]();
}
void getMostar()
{
MisDatos mostrar;
fstream archivo("[Link]", ios::in | ios::binary);
if([Link]())
cerr << "Error al abrir [Link]" << endl;
else
while(![Link]())
{
[Link]((char*)&mostrar,sizeof(MisDatos));
if(![Link]())
{
cout << "\n\nNombre: " <<[Link];
cout << "\nApellido: " <<[Link];
cout << "\nDireccion: " <<[Link];
}
}
[Link]();
}
int main()
{
int opcion=0;
char amor[2];
MisDatos acc;
do{
cout << "\n\nmenu\n\n";
cout << "1. Agregar.\n";
cout << "2. mostrar.\n";
cout << "3. Salir.\n";
cout << "Que opcion desea: "; cin >> opcion;
switch(opcion)
{
case 1:
[Link](amor,2);
cout << "Nombre: ";
[Link]([Link],50,'\n');
cout << "Apellido: ";
[Link]([Link],50,'\n');
cout << "Direccion: ";
[Link]([Link],50,'\n');
Guardar(acc);
break;
case 2:
getMostar();
break;
}
}while(opcion != 3);
return
// Introducción a C++, Nacho Cabanes
// Ejemplo 07.03:
// Array de registros
#include <iostream>
#include <string>
using namespace std;
int main()
{
struct datosPersona
{
string nombre;
char inicial;
int edad;
float nota;
};
datosPersona *persona = new datosPersona[50];
for (int i=0; i<5; i++)
{
cout << "Dime el nombre de la persona " << i << endl;
cin >> persona[i].nombre;
}
cout << "La persona 3 es " << persona[2].nombre << endl;
return 0;
}
// Introducción a C++, Nacho Cabanes
// Ejemplo 07.04:
// Registros anidados
#include <iostream>
#include <string>
using namespace std;
struct fechaNacimiento
{
int dia;
int mes;
int anyo;
};
struct datosPersona
{
string nombre;
char inicial;
struct fechaNacimiento diaDeNacimiento;
float nota;
};
int main()
{
datosPersona persona;
[Link] = "Ignacio";
[Link] = 'I';
[Link] = 8;
[Link] = 7.5;
cout << "La nota es " << [Link];
return 0;
}
7. Registros (struct)
Curso: Introducción a C++
7. Registros (struct)
7.1. Definición y acceso a los datos
Un registro es una agrupación de datos, los cuales no necesariamente son del mismo tipo.
Se definen con la palabra “struct”.
Para acceder a cada uno de los datos que forman el registro, tanto si queremos leer su valor
como si queremos cambiarlo, se debe indicar el nombre de la variable y el del dato (o
campo) separados por un punto:
// Introducción a C++, Nacho Cabanes
// Ejemplo 07.01:
// Registros (struct)
#include <iostream>
using namespace std;
int main()
{
struct
{
string nombre;
char inicial;
int edad;
float nota;
} persona;
[Link] = "Juan";
[Link] = 'J';
[Link] = 20;
[Link] = 7.5;
cout << "La edad es " << [Link];
return 0;
}
Como es habitual en C++, para declarar la variable hemos indicado primero el tipo de datos
(struct { ...} ) y después el nombre que tendrá esa variable (persona).
También podemos declarar primero cómo van a ser nuestros registros, y más adelante
definir variables de ese tipo:
// Introducción a C++, Nacho Cabanes
// Ejemplo 07.02:
// Registros (2)
#include <iostream>
#include <string>
using namespace std;
int main()
{
struct datosPersona
{
string nombre;
char inicial;
int edad;
float nota;
};
datosPersona persona;
[Link] = "Juan";
[Link] = 'J';
[Link] = 20;
[Link] = 7.5;
cout << "La edad es " << [Link];
return 0;
}
Ejercicios propuestos:
(7.1.1) Un “struct” que almacene datos de una canción en formato MP3: Artista,
Título, Duración (en segundos), Tamaño del fichero (en KB). Un programa debe
pedir los datos de una canción al usuario, almacenarlos en dicho “struct” y después
mostrarlos en pantalla.
7.2. Arrays de registros
Hemos guardado varios datos de una persona. Se pueden almacenar los de varias
personas si combinamos el uso de los “struct” con las tablas (arrays) que vimos
anteriormente. La sintaxis no es exactamente la misma, y tendremos que añadir la palabra
"new" en el momento de reservar espacio. Por ejemplo, si queremos guardar los datos de
100 alumnos podríamos hacer:
// Introducción a C++, Nacho Cabanes
// Ejemplo 07.03:
// Array de registros
#include <iostream>
#include <string>
using namespace std;
int main()
{
struct datosPersona
{
string nombre;
char inicial;
int edad;
float nota;
};
datosPersona *persona = new datosPersona[50];
for (int i=0; i<5; i++)
{
cout << "Dime el nombre de la persona " << i << endl;
cin >> persona[i].nombre;
}
cout << "La persona 3 es " << persona[2].nombre << endl;
return 0;
}
La inicial del primer alumno sería “alumnos[0].inicial”, y la edad del último sería
“alumnos[99].edad”.
Ejercicios propuestos:
(7.2.1) Ampliar el programa del ejercicio 7.1.1, para que almacene datos de hasta
100 canciones. Deberá tener un menú que permita las opciones: añadir una nueva
canción, mostrar el título de todas las canciones, buscar la canción que contenga un
cierto texto (en el artista o en el título). Nota: si te parece demasiado complicado, en
el apartado 7.4 tienes un ejemplo parecido, desarrollado de principio a fin.
(7.2.2) Un programa que permita guardar datos de "imágenes" (ficheros de
ordenador que contengan fotografías o cualquier otro tipo de información gráfica).
De cada imagen se debe guardar: nombre (texto), ancho en píxeles (por ejemplo
2000), alto en píxeles (por ejemplo, 3000), tamaño en Kb (por ejemplo 145,6). El
programa debe ser capaz de almacenar hasta 700 imágenes (deberá avisar cuando
su capacidad esté llena). Debe permitir las opciones: añadir una ficha nueva, ver
todas las fichas (número y nombre de cada imagen), buscar la ficha que tenga un
cierto nombre.
7.3. Estructuras anidadas
Podemos encontrarnos con un registo que tenga varios datos, y que a su vez ocurra que
uno de esos datos esté formado por varios datos más sencillos. Para hacerlo desde C++,
incluiríamos un “struct” dentro de otro, así:
// Introducción a C++, Nacho Cabanes
// Ejemplo 07.04:
// Registros anidados
#include <iostream>
#include <string>
using namespace std;
struct fechaNacimiento
{
int dia;
int mes;
int anyo;
};
struct datosPersona
{
string nombre;
char inicial;
struct fechaNacimiento diaDeNacimiento;
float nota;
};
int main()
{
datosPersona persona;
[Link] = "Ignacio";
[Link] = 'I';
[Link] = 8;
[Link] = 7.5;
cout << "La nota es " << [Link];
return 0;
}
Ejercicios propuestos:
(7.3.1) Ampliar el programa del ejercicio 7.2.1, para que el campo “duración” se
almacene como minutos y segundos, usando un “struct” anidado que contenga a su
vez estos dos campos.
7.4. Ejemplo completo
Vamos a hacer un ejemplo completo que use tablas (“arrays”), registros (“struct”) y que
además manipule cadenas.
La idea va a ser la siguiente: Crearemos un programa que pueda almacenar datos de hasta
1000 ficheros (archivos de ordenador). Para cada fichero, debe guardar los siguientes
datos: Nombre del fichero (max 40 letras), Tamaño (en KB, número de 0 a [Link]).
El programa mostrará un menú que permita al usuario las siguientes operaciones:
1- Añadir datos de un nuevo fichero
2- Mostrar los nombres de todos los ficheros almacenados
3- Mostrar ficheros que sean de más de un cierto tamaño (por ejemplo, 2000 KB).
4- Ver todos los datos de un cierto fichero (a partir de su nombre)
5- Salir de la aplicación (como todavía no sabemos almacenar los datos, éstos se perderán).
No debería resultar difícil. Vamos a ver directamente una de las formas en que se podría
plantear y luego comentaremos alguna de las mejoras que se podría (incluso se debería)
hacer.
Una opción que podemos a tomar para resolver este problema es la de contar el número de
fichas que tenemos almacenadas, y así podremos añadir de una en una. Si tenemos 0
fichas, deberemos almacenar la siguiente (la primera) en la posición 0; si tenemos dos
fichas, serán la 0 y la 1, luego añadiremos en la posición 2; en general, si tenemos “n”
fichas, añadiremos cada nueva ficha en la posición “n”. Por otra parte, para revisar todas las
fichas, recorreremos desde la posición 0 hasta la n-1, haciendo algo como
for (i=0; i<=n-1; i++) { ... más órdenes ...}
o bien algo como
for (i=0; i<n; i++) { ... más órdenes ...}
El resto del programa no es difícil: sabemos leer y comparar textos y números. Sólo
haremos dos consideraciones:
No se comportará correctamente si los textos (nombre del fichero, por ejemplo)
contienen espacios, porque aún no sabemos leer textos con espacios.
Hemos limitado el número de fichas a 1000, así que, si nos piden añadir,
deberíamos asegurarnos antes de que todavía tenemos hueco disponible.
Con todo esto, nuestro fuente quedaría así:
// Introducción a C++, Nacho Cabanes
// Ejemplo 07.05:
// Array con muchos struct y menu para manejarla
#include <iostream>
#include <string>
using namespace std;
struct tipoDatos
{
string nombreFich; // Nombre del fichero
long tamanyo; // El tamaño en bytes
};
int numeroFichas=0; // Número de fichas que ya tenemos
int i; // Para bucles
int opcion; // La opcion del menu que elija el usuario
string textoTemporal; // Para pedir datos al usuario
int numeroTemporal;
int main()
{
tipoDatos *fichas = new tipoDatos[1000];
do
{
// Menu principal
cout << endl;
cout << "Escoja una opción:" << endl;
cout << "1.- Añadir datos de un nuevo fichero" << endl;
cout << "2.- Mostrar los nombres de todos los ficheros" << endl;
cout << "3.- Mostrar ficheros que sean de mas de un cierto
tamaño" << endl;
cout << "4.- Ver datos de un fichero" << endl;
cout << "5.- Salir" << endl;
cin >> opcion;
// Hacemos una cosa u otra según la opción escogida
switch(opcion)
{
case 1: // Añadir un dato nuevo
if (numeroFichas < 1000) // Si queda hueco
{
cout << "Introduce el nombre del fichero: ";
cin >> fichas[numeroFichas].nombreFich;
cout << "Introduce el tamaño en KB: ";
cin >> fichas[numeroFichas].tamanyo;
numeroFichas++; // Y tenemos una ficha más
}
else // Si no hay hueco para más fichas, avisamos
cout << "Máximo de fichas alcanzado (1000)!" <<
endl;
break;
case 2: // Mostrar todos
for (i=0; i<numeroFichas; i++)
cout << "Nombre: " << fichas[i].nombreFich
<< "; Tamaño: " << fichas[i].tamanyo
<< "Kb" << endl;
break;
case 3: // Mostrar según el tamaño
cout << "¿A partir de que tamaño quieres que te muestre?
";
cin >> numeroTemporal;
for (i=0; i<numeroFichas; i++)
if (fichas[i].tamanyo >= numeroTemporal)
cout << "Nombre: " << fichas[i].nombreFich
<< "; Tamaño: " << fichas[i].tamanyo
<< " Kb" << endl;
break;
case 4: // Ver todos los datos (pocos) de un fichero
cout << "¿De qué fichero quieres ver todos los datos?";
cin >> textoTemporal;
for (i=0; i<numeroFichas; i++)
if (fichas[i].nombreFich == textoTemporal)
cout << "Nombre: " << fichas[i].nombreFich
<< "; Tamaño: " << fichas[i].tamanyo
<< " Kb" << endl;
break;
case 5: // Salir: avisamos de que salimos
cout << "Fin del programa" << endl;
break;
default: // Otra opcion: no válida
cout << "Opción desconocida!" << endl;
break;
}
} while (opcion != 5); // Si la opcion es 5, terminamos
return 0;
}
Funciona, y hace todo lo que tiene que hacer, pero es mejorable. Por supuesto, en un caso
real es habitual que cada ficha tenga que guardar más información que sólo esos dos
apartados de ejemplo que hemos previsto esta vez. Si nos muestra todos los datos en
pantalla y se trata de muchos datos, puede ocurrir que aparezcan en pantalla tan rápido que
no nos dé tiempo a leerlos, así que sería deseable que parase cuando se llenase la pantalla
de información (por ejemplo, una pausa tras mostrar cada 25 datos). Por supuesto, se nos
pueden ocurrir muchas más preguntas que hacerle sobre nuestros datos. Y además,
cuando salgamos del programa se borrarán todos los datos que habíamos tecleado, pero
eso es lo único “casi inevitable”, porque aún no sabemos manejar ficheros.
Ejercicios propuestos:
(7.4.1) Un programa que pida el nombre, el apellido y la edad de una persona, los
almacene en un “struct” y luego muestre los tres datos en una misma línea,
separados por comas.
(7.4.2) Un programa que pida datos de 8 personas: nombre, dia de nacimiento, mes
de nacimiento, y año de nacimiento (que se deben almacenar en una tabla de
structs). Después deberá repetir lo siguiente: preguntar un número de mes y mostrar
en pantalla los datos de las personas que cumplan los años durante ese mes.
Terminará de repetirse cuando se teclee 0 como número de mes.
(7.4.3) Un programa que sea capaz de almacenar los datos de 50 personas:
nombre, dirección, teléfono, edad (usando una tabla de structs). Deberá ir pidiendo
los datos uno por uno, hasta que un nombre se introduzca vacío (se pulse Intro sin
teclear nada). Entonces deberá aparecer un menú que permita:
o Mostrar la lista de todos los nombres.
o Mostrar las personas de una cierta edad.
o Mostrar las personas cuya inicial sea la que el usuario indique.
o Salir del programa
(lógicamente, este menú debe repetirse hasta que se escoja la opción de
“salir”).
(7.4.4) Mejorar la base de datos de ficheros (ejemplo 07.05) para que no permita
introducir tamaños incorrectos (números negativos) ni nombres de fichero vacíos.
(7.4.5) Ampliar la base de datos de ficheros (ejemplo 07.05) para que incluya una
opción de búsqueda parcial, en la que el usuario indique parte del nombre y se
muestre todos los ficheros que contienen ese fragmento.
(7.4.6) Ampliar la base de datos de ficheros (ejemplo 07.05) para que se pueda
borrar un cierto dato (habrá que “mover hacia atrás” todos los datos que había
después de ese, y disminuir el contador de la cantidad de datos que tenemos).
(7.4.7) Mejorar la base de datos de ficheros (ejemplo 07.05) para que se pueda
modificar un cierto dato a partir de su número (por ejemplo, el dato número 3). En
esa modificación, se deberá permitir al usuario pulsar Intro sin teclear nada, para
indicar que no desea modificar un cierto dato, en vez de reemplazarlo por una
cadena vacía.
(7.4.8) Ampliar la base de datos de ficheros (ejemplo 07.05) para que se permita
ordenar los datos por nombre. Para ello, deberás buscar información sobre algún
método de ordenación sencillo, como el "método de burbuja" (en el siguiente
apartado tienes algunos), y aplicarlo a este caso concreto.
7.5. Ordenaciones simples
Es muy frecuente querer ordenar datos que tenemos en un array. Para conseguirlo, existen
varios algoritmos sencillos, que no son especialmente eficientes, pero son fáciles de
programar. La falta de eficiencia se refiere a que la mayoría de ellos se basan en dos bucles
“for” anidados, de modo que en cada pasada quede ordenado un dato, y se dan tantas
pasadas como datos existen, de modo que para un array con 1.000 datos, podrían llegar a
tener que hacerse un millón de comparaciones.
Existen ligeras mejoras (por ejemplo, cambiar uno de los “for” por un “while”, para no
repasar todos los datos si ya estaban parcialmente ordenados), así como métodos
claramente más efectivos, pero más difíciles de programar, alguno de los cuales veremos
más adelante.
Veremos tres de estos métodos simples de ordenación, primero mirando la apariencia que
tiene el algoritmo, y luego juntando los tres en un ejemplo que los pruebe:
Método de burbuja
(Intercambiar cada pareja consecutiva que no esté ordenada)
Para i=1 hasta n-1
Para j=i+1 hasta n
Si A[i] > A[j]
Intercambiar ( A[i], A[j])
(Nota: algunos autores hacen el bucle exterior creciente y otros decreciente, así:)
Para i=n descendiendo hasta 1
Para j=2 hasta i
Si A[j-1] > A[j]
Intercambiar ( A[j-1], A[j])
Selección directa
(En cada pasada busca el menor, y lo intercambia al final de la pasada)
Para i=1 hasta n-1
menor = i
Para j=i+1 hasta n
Si A[j] < A[menor]
menor = j
Si menor <> i
Intercambiar ( A[i], A[menor])
Inserción directa
(Comparar cada elemento con los anteriores -que ya están ordenados- y desplazarlo hasta
su posición correcta).
Para i=2 hasta n
j=i-1
mientras (j>=1) y (A[j] > A[j+1])
Intercambiar ( A[j], A[j+1])
j = j - 1
(Es mejorable, no intercambiando el dato que se mueve con cada elemento, sino sólo al
final de cada pasada, pero no entraremos en más detalles).
Ejercicios propuestos:
(7.5.1) Un programa que pida al usuario 5 números reales y los muestre ordenados,
usando el método de la burbuja.
(7.5.2) Un programa que cree un array de 7 números enteros y lo ordene con cada
uno de estos tres métodos, mostrando el resultado de los pasos intermedios.
[Link] de texto (1 - al estilo de C)
Curso: Introducción a C++
6. Cadenas de texto
6.1. Cadenas de texto al estilo de C
6.1.1. Definición y lectura desde teclado
C++ tiene un tipo de datos específico para almacenar cadenas de texto, pero vamos a
comenzar por conocer el el estándar marcado por C, en el que las cadenas de texto, se
crean como “arrays” de caracteres. Están formadas por una sucesión de caracteres
terminada con un carácter nulo (\0), de modo que tendremos que reservar una letra más
de las que necesitamos. Por ejemplo, para guardar el texto “Hola” usaríamos “char
saludo[5]”.
Este carácter nulo lo utilizarán todas las órdenes estándar que tienen que ver con manejo
de cadenas: las que las muestran en pantalla, las que comparan cadenas, las que dan a
una cadena un cierto valor, etc. Por tanto, si no queremos usar esas funciones y sólo vamos
a acceder letra a letra (como hemos hecho con los números en los últimos ejemplos) nos
bastaría con “char saludo[4]”, pero si queremos usar cualquiera de esta posibilidades (que
será lo habitual), deberemos tener la prudencia de reservar una letra más de las
“necesarias”, para ese carácter nulo, que indica el final de la cadena, y que todas esas
órdenes utilizan para saber cuando deben terminar de manipular la cadena.
Un primer ejemplo que nos pidiese nuestro nombre y nos saludase sería:
// Introducción a C++, Nacho Cabanes
// Ejemplo 06.01:
// Primer ejemplo de cadenas de texto al estilo C
#include <iostream>
using namespace std;
int main()
{
char texto[40]; // Para guardar hasta 39 letras
cout << "Introduce tu nombre: ";
cin >> texto;
cout << "Hola " << texto << endl;
return 0;
}
Ejercicios propuestos:
([Link]) Un programa que te pida tu nombre y una cifra numérica, y escriba tu
nombre tantas veces como indique esa cifra numérica.
Si la cadena contiene espacios, se lee sólo hasta el primer espacio. Esto se puede
considerar una ventaja o un inconveniente, según el uso que se le quiera dar. En cualquier
caso, dentro de muy poco veremos cómo evitarlo si queremos.
6.1.2. Entrada de cadenas al estilo de C
Un primer ejemplo que nos pidiese nuestro nombre y nos saludase sería:
// Introducción a C++, Nacho Cabanes
// Ejemplo 06.01b:
// Cadenas de texto al estilo C... con funciones de C
#include <cstdio>
int main()
{
char texto[40]; // Para guardar hasta 39 letras
printf("Introduce tu nombre: ");
scanf("%s", texto);
printf("Hola, %s\n", texto);
return 0;
}
Si se trata de algún otro tipo de datos, la idea es la misma, con dos diferencias:
Habrá que indicar el tipo de datos correspondiente en la cadena de formato. Por
ejemplo, se usa "%d" para un número entero (int) y "%f" para un número real (float).
"scanf" necesitará un símbolo de "ampersand" (&) antes del nombre de la variable
cuando ésta no sea una cadena de texto (nuevamente, los motivos son un poco
avanzados, así que los aplazamos para más adelante).
De modo que podríamos pedir un entero y un real así:
// Introducción a C++, Nacho Cabanes
// Ejemplo 06.01c:
// Entrada/salida de enteros al estilo C
#include <cstdio>
int main()
{
int n;
float x;
printf("Dime un entero: ");
scanf("%d", &n);
printf("Y un real: ");
scanf("%f", &x);
printf("El entero es %d y el real es %f\n", n,x);
return 0;
}
En lo que sigue de este apartado, aunque usemos cadenas al estilo de C, emplearemos
"cin" y "cout" para leer sus datos y mostrarlos.
Ejercicios propuestos:
([Link]) Un programa que te pida tu nombre y una cifra numérica, y escriba tu
nombre tantas veces como indique esa cifra numérica, usando "scanf" para pedir los
datos.
6.1.3. Cómo acceder a las letras que forman una cadena
Podemos leer (o modificar) una de las letras de una cadena de igual forma que leemos o
modificamos los elementos de cualquier tabla: el primer elemento será texto[0], el segundo
será texto[1] y así sucesivamente:
// Introducción a C++, Nacho Cabanes
// Ejemplo 06.02:
// Cadenas de texto: acceder letra a letra
#include <iostream>
using namespace std;
int main()
{
char texto[40];
cout << "Introduce tu nombre: ";
cin >> texto;
cout << "Hola, " << texto << ". Tu inicial es "
<< texto[0] << endl;
return 0;
}
Ejercicio propuesto:
([Link]) Un programa que pida al usuario que introduzca una palabra, cambie su
primera letra por una "A" y muestre la palabra resultante.
6.1.4. Longitud de la cadena.
En una cadena que definamos como “char texto[40]” lo habitual es que realmente no
ocupemos las 39 letras que podríamos llegar a usar. Si guardamos 9 letras (y el carácter
nulo que marca el final), tendremos 30 posiciones que no hemos usado. Pero estas 30
posiciones generalmente contendrán “basura”, lo que existiera previamente en esas
posiciones de memoria, porque el compilador las reserva para nosotros pero no las “limpia”.
Si queremos saber cual es la longitud real de nuestra cadena tenemos dos opciones:
> Podemos leer la cadena carácter por carácter desde el principio hasta que
encontremos el carácter nulo (\0) que marca el final.
> Hay una orden predefinida que lo hace por nosotros, y que nos dice cuantas letras
hemos usado realmente en nuestra cadena. Es “strlen”, que se usa así:
// Introducción a C++, Nacho Cabanes
// Ejemplo 06.03:
// Longitud de una cadena
#include <cstring>
#include <iostream>
using namespace std;
int main()
{
char texto[40];
cout << "Introduce una palabra: ";
cin >> texto;
cout << "Has tecleado " << strlen(texto)
<< " letras." << endl;
return 0;
}
Como es de esperar, si escribimos “Hola”, esta orden nos dirá que hemos tecleado 4 letras
(no cuenta el \0 que se añade automáticamente al final).
Si empleamos “strlen”, o alguna de las otras órdenes relacionadas con cadenas de texto
que veremos en este tema, debemos incluir <cstring> , que es donde se definen todas
ellas.
Ejercicios propuestos:
([Link]) Un programa que te pida tu nombre y lo muestre en pantalla separando
cada letra de la siguiente con un espacio. Por ejemplo, si tu nombre es “Juan”,
debería aparecer en pantalla “J u a n”.
([Link]) Un programa que te pida tu nombre y lo muestre en pantalla separando al
revés. Por ejemplo, si tu nombre es “Juan”, debería aparecer en pantalla “nauJ”.
6.1.5. Asignando a una cadena el valor de otra: strcpy, strncpy; strcat
Cuando queremos dar a una variable el valor de otra, normalmente usamos construcciones
como a =2, o como a = b. Pero en el caso de las cadenas de texto, esta NO es la forma
correcta, no podemos hacer algo como saludo="hola" ni algo como texto1=texto2. Si
hacemos algo así, haremos que las dos cadenas estén en la misma posición de memoria, y
que los cambios que hagamos a una de ellas se reflejen también en la otra. La forma
correcta de guardar en una cadena de texto un cierto valor es:
strcpy (destino, origen);
Es decir, debemos usar una función llamada “strcpy” (string copy, copiar cadena), que se
encuentra también en “string.h”. Vamos a ver dos ejemplos de su uso:
strcpy (saludo, "hola");
strcpy (textoDefinitivo, textoProvisional);
Es nuestra responsabilidad que en la cadena de destino haya suficiente espacio reservado
para copiar lo que queremos. Si no es así, estaremos sobreescribiendo direcciones de
memoria en las que no sabemos qué hay.
Para evitar este problema, tenemos una forma de indicar que queremos copiar sólo los
primeros n bytes de origen, usando la función “strncpy”, así:
strncpy (destino, origen, n);
Vamos a ver un ejemplo, que nos pida que tecleemos una frase y guarde en otra variable
sólo las 4 primeras letras:
// Introducción a C++, Nacho Cabanes
// Ejemplo 06.04:
// Tomar 4 letras de una cadena
#include <cstring>
#include <iostream>
using namespace std;
int main()
{
char texto1[40], texto2[40], texto3[10];
cout << "Introduce un frase: ";
cin >> texto1;
strcpy(texto2, texto1);
cout << "Una copia de tu texto es " << texto2 << endl;
strncpy(texto3, texto1, 4);
cout << "Y sus 4 primeras letras son " << texto3 << endl;
return 0;
}
Finalmente, existe otra orden relacionada con estas dos: podemos añadir una cadena al
final de otra (concatenarla), con
strcat (destino, origen);
Vamos a ver un ejemplo de su uso, que nos pida nuestro nombre, nuestro apellido y cree
una nueva cadena de texto que contenga los dos, separados por un espacio:
// Introducción a C++, Nacho Cabanes
// Ejemplo 06.05:
// Concatenar dos cadenas
#include <cstring>
#include <iostream>
using namespace std;
int main()
{
char texto1[40], texto2[40];
cout << "Introduce tu nombre: ";
cin >> texto1;
cout << "Introduce tu apellido: ";
cin >> texto2;
strcat(texto1, " "); // Añado un espacio al nombre
strcat(texto1, texto2); // Y luego el apellido
cout << "Te llamas " << texto1 << endl;
return 0;
}
Ejercicio propuesto:
([Link]) Un programa que te pida una palabra, y la almacene en la variable llamada
“texto”. Luego deberá pedir una segunda palabra, y añadirla al final de “texto” (y
mostrar el resultado). Finalmente, deberá pedir una tercera palabra, y guardarla en
la variable “texto” y en otra variable llamada “texto2” (y mostrar ambas variables).
6.1.6. Comparando cadenas: strcmp
Para comparar dos cadenas alfabéticamente (para ver si son iguales o para poder
ordenarlas, por ejemplo), usamos
strcmp (cad1, cad2);
Esta función devuelve un número entero, que será:
0 si ambas cadenas son iguales.
Un número negativo, si cadena1 < cadena2.
Un número positivo, si cad1 > cad2.
Hay que tener cuidado, porque las cadenas se comparan como en un diccionario, pero hay
que tener en cuenta ciertas cosas:
Al igual que en un diccionario, todas las palabras que empiecen por B se consideran
“mayores” que las que empiezan por A.
Si dos cadenas empiezan por la misma letra (o las mismas letras), se ordenan
basándose en la primera letra diferente, también al igual que en el diccionario.
La primera diferencia está que en que se distingue entre mayúsculas y minúsculas.
Para más detalles, en el código ASCII las mayúsculas aparecen antes que las
minúsculas, así que las palabras escritas en mayúsculas se consideran “menores”
que las palabras escritas en minúsculas. Por ejemplo, “ala” es menor que “hola”,
porque una empieza por “a” y la otra empieza por “h”, pero “Hola” es menor que “ala”
porque la primera empieza con una letra en mayúsculas y la segunda con una letra
en minúsculas.
La segunda diferencia es que el código ASCII estándar no incluye eñe, vocales
acentuadas ni caracteres internacionales, así que estos caracteres “extraños”
aparecen después de los caracteres “normales”, de modo que “adiós” se considera
“mayor” que “adiposo”, porque la o acentuada está después de todas las letras del
alfabeto inglés.
Vamos a ver un primer ejemplo que nos pida dos palabras y diga si hemos tecleado la
misma las dos veces:
// Introducción a C++, Nacho Cabanes
// Ejemplo 06.06:
// Comparar dos cadenas
#include <cstring>
#include <iostream>
using namespace std;
int main()
{
char texto1[40], texto2[40];
cout << "Introduce una palabra: ";
cin >> texto1;
cout << "Introduce otra palabra: ";
cin >> texto2;
if (strcmp(texto1, texto2)==0)
cout << "Son iguales" << endl;
else
cout << "Son distintas" << endl;
return 0;
}
Podemos mejorarlo ligeramente para que nos diga qué palabra es “menor” de las dos:
// Introducción a C++, Nacho Cabanes
// Ejemplo 06.06:
// Comparar dos cadenas
#include <cstring>
#include <iostream>
using namespace std;
int main()
{
char texto1[40], texto2[40];
cout << "Introduce una palabra: ";
cin >> texto1;
cout << "Introduce otra palabra: ";
cin >> texto2;
int comparacion = strcmp(texto1, texto2);
if (comparacion==0)
cout << "Son iguales" << endl;
else
if (comparacion>0)
cout << "La primera palabra es mayor" << endl;
else
cout << "La segunda palabra es mayor" << endl;
return 0;
}
Ejercicio propuesto:
([Link]) Un programa que te pida una clave de acceso, y no te deje "seguir" hasta
que aciertes la contraseña correcta (que estará prefijada en el programa, y será
"clave").
6.1.7. Buscando en cadenas
Podemos ver si una cadena contiene un cierto texto, usando "strstr", que devuelve 0 si no la
contiene, o un valor distinto en caso de que sí la contenga, así:
// Introducción a C++, Nacho Cabanes
// Ejemplo 06.07:
// Buscar una subcadena dentro de otra cadena
#include <cstring>
#include <iostream>
using namespace std;
int main()
{
char texto1[40], texto2[40];
cout << "Introduce una palabra: ";
cin >> texto1;
cout << "Introduce otra palabra a buscar en ella: ";
cin >> texto2;
if (strstr(texto1, texto2)==0)
cout << "La primera NO contiene a la segunda" << endl;
else
cout << "La primera contiene a la segunda" << endl;
return 0;
}
Ejercicio propuesto:
([Link]) Un programa que te pida una frase y luego varias palabras. Deberá decir si
esas palabaras son parte de la frase o no. Terminará cuando se pulse Intro sin
introducir ninguna palabra (la palabra introducida será una cadena vacía, de longitud
cero).
6.1.8. Array de cadenas
Crear un array de cadenas de texto es tan sencillo como crear un array bidimensional de
"char", así:
// Introducción a C++, Nacho Cabanes
// Ejemplo 06.08:
// Array de cadenas
#include <iostream>
using namespace std;
int main()
{
char mensajeError[5][80] = {
"Fichero no encontrado",
"El fichero no se puede abrir para escritura",
"El fichero está vacío",
"El fichero contiene datos de tipo incorrecto"
"El fichero está siendo usado"
};
cout << "El segundo mensaje de error es: "
<< mensajeError[1] << endl;
cout << "La primera letra del tercer mensaje de error es: "
<< mensajeError[2][0] << endl;
return 0;
}
Ejercicio propuesto:
([Link]) Un programa que te pida 5 frases y luego varias las muestre en el orden
contrario al que se introdujeron.
6.1.9. Valor inicial de una cadena de texto
Podemos dar un valor inicial a una cadena de texto, usando dos formatos distintos:
El formato “clásico” para dar valores a tablas:
char nombre[50]= {'J','u','a','n'};
O bien un formato más compacto:
char nombre[50]="Juan";
Pero cuidado con este último formato: hay que recordar que sólo se puede usar cuando
se declara la variable, al principio del programa. Si ya estamos dentro del programa,
deberemos
[Link] de texto (2 - al estilo de C+
+)
Curso: Introducción a C++
6.2. Cadenas de texto al estilo de C++
6.2.1. Definición y lectura desde teclado
Será básicamente igual que cuando leemos cualquier otro tipo de dato nativo del sistema.
En este caso, el tipo de datos se llama "string":
// Introducción a C++, Nacho Cabanes
// Ejemplo 06.11:
// Primer ejemplo de cadenas de texto al estilo C++
#include <iostream>
#include <string>
using namespace std;
int main()
{
string texto;
cout << "Introduce tu nombre: ";
cin >> texto;
cout << "Hola " << texto << endl;
return 0;
}
Dos cosas a tener en cuenta:
Al igual que ocurría con las cadenas "al estilo de C", si el texto contiene espacios, se
lee sólo hasta el primer espacio.
Habrá que incluir <string> al principio de nuestro programa. Cuidado: no es
<string.h>, que es el nombre que recibe <cstring> si usamos la nomenclatura de C
en vez de la de C++, sino sólo <string>, sin la "c" inicial y sin el ".h" final.
Ejercicio propuesto:
([Link]) Un programa que te pida tu nombre y una cifra numérica, y escriba tu
nombre tantas veces como indique esa cifra numérica, usando cadenas al estilo de
C++.
6.2.2. Acceder letra a letra
Lo haríamos igual que si cuando se trata de una cadena "al estilo de C" o de un array,
usando corchetes:
// Introducción a C++, Nacho Cabanes
// Ejemplo 06.12:
// Cadenas de texto al estilo C++: acceder letra a letra
#include <iostream>
#include <string>
using namespace std;
int main()
{
string texto;
cout << "Introduce tu nombre: ";
cin >> texto;
cout << "Hola, " << texto
<< ". Tu inicial es " << texto[0]
<< " y tu segunda letra " << [Link](1)
<< endl;
return 0;
}
Ejercicio propuesto:
([Link]) Un programa que pida al usuario que introduzca una palabra y muestre su
segunda y tercera letras.
([Link]) Un programa que pida al usuario que introduzca una palabra, cambie su
primera letra por una "A" y muestre la palabra resultante.
6.2.3. Longitud de la cadena.
Para saber la cantidad de letras que contiene una cadena de texto, añadiremos ".length()" a
su nombre, así:
// Introducción a C++, Nacho Cabanes
// Ejemplo 06.13:
// Longitud de una cadena de C++
#include <string>
#include <iostream>
using namespace std;
int main()
{
string texto;
cout << "Introduce una palabra: ";
cin >> texto;
cout << "Has tecleado " << [Link]()
<< " letras." << endl;
return 0;
}
Ejercicios propuestos:
([Link]) Un programa que te pida tu nombre y lo muestre en pantalla separando
cada letra de la siguiente con un espacio. Por ejemplo, si tu nombre es “Juan”,
debería aparecer en pantalla “J u a n”.
([Link]) Un programa que te pida tu nombre y lo muestre en pantalla separando al
revés. Por ejemplo, si tu nombre es “Juan”, debería aparecer en pantalla “nauJ”.
6.2.4. Subcadenas
Podemos extraer un fragmento de una cadena si usamos ".substr(inicio, longitud)", como en
este ejemplo:
// Introducción a C++, Nacho Cabanes
// Ejemplo 06.14:
// Tomar 4 letras de una cadena de C++
#include <string>
#include <iostream>
using namespace std;
int main()
{
string texto1, texto2, texto3;
cout << "Introduce un frase: ";
cin >> texto1;
texto2 = texto1;
cout << "Una copia de tu texto es " << texto2 << endl;
texto3 = [Link](0, 4);
cout << "Y sus 4 primeras letras son " << texto3 << endl;
return 0;
}
Ejercicio propuesto:
([Link]) Un programa que te pida tu nombre y escriba un triángulo que empiece con
una letra, siga con 2 y vaya aumentando hasta llegar a la longitud total, así:
Na
Nac
Nach
Nacho
6.2.5. Unir (concatenar) cadenas
Podemos juntar dos cadenas en una simplemente "sumándolas", con el símbolo de la suma.
De forma alternativa, también podemos usar ".append" para añadir al final de una cadena
existente o ".assign" para cambiar su valor (para lo que hasta ahora hemos usado el
símbolo de "igual"):
// Introducción a C++, Nacho Cabanes
// Ejemplo 06.15:
// Concatenar dos cadenas de C++
#include <string>
#include <iostream>
using namespace std;
int main()
{
string texto1, texto2, texto3;
cout << "Introduce tu nombre: ";
cin >> texto1;
cout << "Introduce tu apellido: ";
cin >> texto2;
texto3 = texto1 + " " + texto2;
cout << "Te llamas " << texto3 << endl;
string texto4;
[Link](texto1);
[Link](" ");
[Link](texto2);
cout << "O bien " << texto4 << endl;
return 0;
}
Ejercicio propuesto:
([Link]) Un programa que te pida una un número y palabra, y cree una nueva
palabra formada por la concatenación de esa palabra varias veces. Por ejemplo, si
la palabra es "C++" y el número es el 4, la cadena resultante deberá ser "C++C++C+
+C++". Finalmente, se deberá mostrar esta cadena en pantalla.
6.2.6. Comparar
Para ver si son iguales dos cadenas podemos usar el doble símbolo de igualdad (==),
como hacíamos con los números. De igual modo, podemos usar el símbolo de desigualdad
(!=) para ver si no contienen el mismo texto. También podemos usar ".compare(texto2)", que
nos dará 0 como resultado si son siguales u otro número si no lo son:
// Introducción a C++, Nacho Cabanes
// Ejemplo 06.16:
// Comparar dos cadenas de C++
#include <string>
#include <iostream>
using namespace std;
int main()
{
string texto1, texto2;
cout << "Introduce una palabra: ";
cin >> texto1;
cout << "Introduce otra palabra: ";
cin >> texto2;
if (texto1 == texto2)
cout << "Son iguales" << endl;
else
cout << "Son distintas" << endl;
cout << "De otra manera: " << endl;
if ([Link](texto2) == 0)
cout << "Son iguales" << endl;
else
cout << "Son distintas" << endl;
return 0;
}
De hecho, "compare" nos dará un resultado positivo si la primera cadena es mayor que la
segunda, y un resultado negativo si la mayor es la segunda. Incluso podemos utilizar
también los símbolos de "mayor que" y "menor que":
// Introducción a C++, Nacho Cabanes
// Ejemplo 06.17:
// Comparar dos cadenas de C++
#include <string>
#include <iostream>
using namespace std;
int main()
{
string texto1, texto2;
cout << "Introduce una palabra: ";
cin >> texto1;
cout << "Introduce otra palabra: ";
cin >> texto2;
int comparacion = [Link](texto2);
if (comparacion==0)
cout << "Son iguales" << endl;
else
if (comparacion>0)
cout << "La primera palabra es mayor" << endl;
else
cout << "La segunda palabra es mayor" << endl;
cout << "Volvemos a intentar... " << endl;
if (texto1 == texto2)
cout << "Son iguales" << endl;
else
if (texto1 > texto2)
cout << "La primera palabra es mayor" << endl;
else
cout << "La segunda palabra es mayor" << endl;
return 0;
}
Las precauciones que debemos tener son las mismas que en el caso de C (se compara
como en un diccionario, pero consderando que las mayúsculas son menores que las
minúsculas, y podemos tener problemas con las vocales acentuadas y otros símbolos que
no sean parte del alfabeto inglés).
Ejercicio propuesto:
([Link]) Crear un programa que pida al usuario su contraseña. Deberá terminar
cuando introduzca como contraseña la palabra "clave", pero volvérsela a pedir
tantas veces como sea necesario.
([Link]) Crear un programa que pida al usuario su nombre y su contraseña, y no le
permita seguir hasta que introduzca como nombre "Pedro" y como contraseña
"Peter".
6.2.7. Convertir a cadena "al estilo C"
Muchas órdenes existentes en C y en C++ esperan que, si se le indica algún texto, éste sea
"al estilo de C" (un array de caracteres), y no trabajan correctamente con datos de tipo
"string".
No es un gran problema: podemos obtener una cadena "al estilo C" a partir de un string si le
añadimos al final ".c_str()"
printf("%s", texto.c_str());
Ejercicio propuesto:
([Link]) Crear un programa que pida al usuario su nombre (como "string") y luego lo
muestre usando "printf".
5. Vectores y matrices
Curso: Introducción a C++
5. Vectores y matrices
5.1. Definición de una tabla y acceso a los datos
Una tabla, vector, matriz o array (que algunos autores traducen por “arreglo”) es un
conjunto de elementos, todos los cuales son del mismo tipo. Estos elementos tendrán todos
el mismo nombre, y ocuparán un espacio contiguo en la memoria.
Por ejemplo, si queremos definir un grupo de 4 números enteros, usaríamos
int ejemplo[4];
Podemos acceder a cada uno de los valores individuales indicando su nombre (ejemplo) y el
número de elemento que nos interesa, pero con una precaución: se empieza a numerar
desde 0, así que en el caso anterior tendríamos 4 elementos, que serían ejemplo[0],
ejemplo[1], ejemplo[2], ejemplo[3].
Como ejemplo, vamos a definir un grupo de 5 números enteros y hallar su suma:
// Introducción a C++, Nacho Cabanes
// Ejemplo 05.01:
// Primer ejemplo de tablas
#include <iostream>
using namespace std;
int main()
{
int numero[5]; // Un array de 5 numeros enteros
int suma; // Un entero que guardará la suma
numero[0] = 200; // Les damos valores
numero[1] = 150;
numero[2] = 100;
numero[3] = -50;
numero[4] = 300;
suma = numero[0] + // Y hallamos la suma
numero[1] + numero[2] + numero[3] + numero[4];
cout << "Su suma es " << suma;
/* Nota: esta es la forma más ineficiente e incómoda...
Ya lo iremos mejorando */
return 0;
}
Ejercicios propuestos:
(5.1.1) Un programa que pida al usuario 4 números, los memorice (utilizando una
tabla), calcule su media aritmética y después muestre en pantalla la media y los datos
tecleados.
(5.1.2) Un programa que pida al usuario 5 números reales y luego los muestre en el
orden contrario al que se introdujeron.
5.2. Valor inicial de una tabla
Al igual que ocurría con las variables “normales”, podemos dar valor a los elementos de una
tabla al principio del programa. Será más cómodo que dar los valores uno por uno, como
hemos hecho antes. Esta vez los indicaremos todos entre llaves, separados por comas:
// Introducción a C++, Nacho Cabanes
// Ejemplo 05.02:
// Segundo ejemplo de tablas
#include <iostream>
using namespace std;
int main()
{
int numero[5] = // Un array de 5 números enteros
{200, 150, 100, -50, 300};
int suma; // Un entero que guardará la suma
suma = numero[0] + // Y hallamos la suma
numero[1] + numero[2] + numero[3] + numero[4];
cout << "Su suma es " << suma;
/* Nota: esta forma es algo menos engorrosa, pero todavía no */
/* está bien hecho. Lo seguiremos mejorando */
return 0;
}
Ejercicios propuestos:
(5.2.1) Un programa que almacene en una tabla el número de días que tiene cada
mes (supondremos que es un año no bisiesto), pida al usuario que le indique un mes
(1=enero, 12=diciembre) y muestre en pantalla el número de días que tiene ese mes.
(5.2.2) Un programa que almacene en una tabla el número de días que tiene cada
mes (año no bisiesto), pida al usuario que le indique un mes (ej. 2 para febrero) y un
día (ej. el día 15) y diga qué número de día es dentro del año (por ejemplo, el 15 de
febrero sería el día número 46, el 31 de diciembre sería el día 365).
5.3. Recorriendo los elementos de una tabla
Es de esperar que exista una forma más cómoda de acceder a varios elementos de un
array, sin tener siempre que repetirlos todos, como hemos hecho en
suma = numero[0] + numero[1] + numero[2] + numero[3] + numero[4];
El “truco” consistirá en emplear cualquiera de las estructuras repetitivas que ya hemos visto
(while, do..while, for). Lo más habitual, ya que sabemos cuántos elementos tiene un array,
es usar un "for" para contar, así:
// Introducción a C++, Nacho Cabanes
// Ejemplo 05.03:
// Tercer ejemplo de tablas (for)
#include <iostream>
using namespace std;
int main()
{
int numero[5] = // Un array de 5 números enteros
{200, 150, 100, -50, 300};
int suma; // Un entero que guardará la suma
int i; // Para recorrer el array
suma = 0; // Valor inicial
for (i=0; i<=4; i++) // Y hallamos la suma
suma += numero[i];
cout << "Su suma es " << suma;
return 0;
}
En este caso, que sólo sumábamos 5 números, no hemos escrito mucho menos, pero si
trabajásemos con 100, 500 o 1000 números, la ganancia en comodidad sí que está clara.
Ejercicios propuestos:
(5.3.1) A partir del programa propuesto en 5.2.2, que almacenaba en una tabla el
número de días que tiene cada mes, crear otro que pida al usuario que le indique la
fecha, detallando el día (1 al 31) y el mes (1=enero, 12=diciembre), como respuesta
muestre en pantalla el número de días que quedan hasta final de año.
(5.3.2) Crear un programa que pida al usuario 10 números enteros y luego los
muestre en orden inverso (del último al primero), usando "for".
(5.3.3) Crear un programa que pida al usuario 10 números reales, calcule su media y
luego muestre los que están por encima de la media.
(5.3.4) Un programa que pida al usuario 10 números enteros y calcule (y muestre)
cuál es el mayor de ellos.
En física se usan mucho los "vectores", para representar magnitudes que no se pueden
expresar sólo con un número. Por ejemplo, para una temperatura basta con decir cosas
como "tengo 39 grados", pero para una fuerza no basta con decir que es de 200 N, sino que
también es importante en qué dirección (y sentido) se aplica esa fuerza: no tendrá el mismo
efecto si se aplica en el centro de un cuerpo o en un extremo, ni si comprime que si estira.
Un vector se suele representar a partir de sus "componentes", que son las coordenadas de
su extremo (suponiendo que comienza en el punto (0,0). Un vector en el plano tendrá dos
componentes (x,y) y un vector en el espacio tendrá 3 componentes (x,y,z).como un conjunto
de varias coordenadas. Así, un programa que pida al usuario las coordenadas de 2 vectores
en el espacio y halle su vector suma sería:
// Introducción a C++, Nacho Cabanes
// Ejemplo 05.04:
// Vectores, primer contacto
#include <iostream>
using namespace std;
int main()
{
float vector1[3];
float vector2[3];
float vectorSuma[3];
int i;
// Pedimos los datos del primer vector
for (i=0; i<3; i++)
{
cout << "Introduce la componente " << i
<< " del primer vector: ";
cin >> vector1[i];
}
// Pedimos los datos del segundo vector
for (i=0; i<3; i++)
{
cout << "Introduce la componente " << i
<< " del segundo vector: ";
cin >> vector2[i];
}
// Calculamos la suma
for (i=0; i<3; i++)
vectorSuma[i] = vector1[i] + vector2[i];
// Y mostramos el resultado
cout << "El vector suma es ";
for (i=0; i<3; i++)
cout << vectorSuma[i] << " ";
return 0;
}
No veremos más detalles sobre vectores, porque este no es un curso de física. Pero sí
propondemos algunos ejercicios para que pueda aplicar sus conocimientos quien ya ha
estudiado con anterioridad lo que es un vector...
Ejercicios propuestos sobre vectores:
(5.3.5) Un programa que pida al usuario los datos de dos vectores en el plano (2
coordenadas) y calcule su diferencia.
(5.3.6) Un programa que pida al usuario las componentes de dos vectores en el
espacio (3 coordenadas) y calcule su producto escalar.
(5.3.7) Un programa que pida al usuario las componentes de dos vectores en el
espacio y calcule su producto vectorial.
(5.3.8) Un programa que pida al usuario dos vectores en el plano (2 coordenadas) y
diga si son linealmente dependientes (sus componentes son proporcionales).
5.4. Tablas bidimensionales
Podemos declarar tablas de dos o más dimensiones. Por ejemplo, si queremos guardar
datos de dos grupos de alumnos, cada uno de los cuales tiene 20 alumnos, tenemos dos
opciones:
Podemos usar int datosAlumnos[40] y entonces debemos recordar que los 20
primeros datos corresponden realmente a un grupo de alumnos y los 20 siguientes a
otro grupo.
O bien podemos emplear int datosAlumnos[2][20] y entonces sabemos que los datos
de la forma datosAlumnos[0][i] son los del primer grupo, y los datosAlumnos[1][i] son
los del segundo.
En cualquier caso, si queremos indicar valores iniciales, lo haremos entre llaves, igual que si
fuera una tabla de una única dimensión. Vamos a verlo con un ejemplo de su uso:
// Introducción a C++, Nacho Cabanes
// Ejemplo 05.05:
// Array de dos dimensiones
#include <iostream>
using namespace std;
int main()
{
int notas[2][10] =
{
{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
{11, 12, 13, 14, 15, 16, 17, 18, 19, 20 }
};
cout << "La nota del tercer alumno del grupo 1 es "
<< notas[0][2];
return 0;
}
Este tipo de tablas son las que se usan también para guardar matrices, cuando hay que
resolver problemas matemáticos más complejos. Por ejemplo, un programa que pida al
usuario los datos de dos matrices de 3x3 y luego muestre su suma podría ser así:
// Introducción a C++, Nacho Cabanes
// Ejemplo 05.06
// Matrices, primer contacto
#include <iostream>
using namespace std;
int main()
{
float matriz[2][3][3];
float matrizSuma[3][3];
int m, fila, columna;
// Pedimos los datos de las dos matrices
for (m=0; m<2; m++)
for (fila=0; fila<3; fila++)
for (columna=0; columna<3; columna++)
{
cout << "En la matriz " << m+1
<< ", dime el dato de la fila " << fila+1
<< " y la columna " << columna+1 << ": ";
cin >> matriz[m][fila][columna];
}
// Calculamos la suma
for (fila=0; fila<3; fila++)
for (columna=0; columna<3; columna++)
matrizSuma[fila][columna] = matriz[0][fila][columna]
+ matriz[1][fila][columna];
// Y mostramos el resultado (puede salir un poco descolocado)
cout << "La matriz suma es " << endl;
for (fila=0; fila<3; fila++)
{
for (columna=0; columna<3; columna++)
cout << matrizSuma[fila][columna] << " ";
cout << endl;
}
return 0;
}
Cuidado: no podemos dar por sentado que los datos de un array tengan valor inicial 0, sino
que pueden contener "basura" (lo que hubiera en cada posición de memoria anteriormente),
de modo que este programa es incorrecto y puee mostrar resultados incorrectos:
// Introducción a C++, Nacho Cabanes
// Ejemplo 05.06b:
// Matrices, lógica errónea (sin dar valor inicial)
#include <iostream>
using namespace std;
int main()
{
float matriz[2][3][3];
float matrizSuma[3][3];
int m, fila, columna;
// Pedimos los datos de las dos matrices
for (m=0; m<2; m++)
for (fila=0; fila<3; fila++)
for (columna=0; columna<3; columna++)
{
cout << "En la matriz " << m+1
<< ", dime el dato de la fila " << fila+1
<< " y la columna " << columna+1 << ": ";
cin >> matriz[m][fila][columna];
}
// Calculamos la suma
for (m=0; m<2; m++)
for (fila=0; fila<3; fila++)
for (columna=0; columna<3; columna++)
matrizSuma[fila][columna] += matriz[m][fila][columna];
// La línea anterior es errónea: estamos dando por sentado
// que la matriz suma contiene ceros, y quizá no sea así
// Y mostramos el resultado (puede salir un poco descolocado)
cout << "La suma es ";
for (fila=0; fila<3; fila++)
{
for (columna=0; columna<3; columna++)
cout << matrizSuma[fila][columna] << " ";
cout << endl;
}
return 0;
}
Ejercicios propuestos sobre matrices:
(5.4.1) Un programa pida datos al usuario los datos de una matriz de 2x2 y muestra
su traspuesta (el resultado de intercambiar filas por columnas).
(5.4.2) Un programa que pida al usuario los datos de una matriz de 3x3, y muestre
su determinante.
(5.4.3) Un programa que pida al usuario los datos de una matriz de 3x3, y calcule y
muestre su matriz adjunta.
(5.4.4) Un programa que pida al usuario los datos de una matriz de 3x3, y calcule y
muestre su matriz inversa.
(5.4.5) Un programa que pida al usuario los datos de dos matrices de 2x2, y calcule
y muestre su producto.
(5.4.6) Un programa que use una matriz de 3x4 para resolver un sistema de 3
ecuaciones con 3 incógnitas usando el método de Gauss (hacer ceros por debajo de la
diagonal principal para luego aplicar sustitución regresiva).
5.5. Arrays indeterminados.
Si damos un valor inicial a un array, no será necesario que indiquemos su tamaño, porque el
compilador lo puede saber contando cuantos valores hemos detallado, así:
// Introducción a C++, Nacho Cabanes
// Ejemplo 05.07:
// Arrays en los que no se indica el tamaño
#include <iostream>
using namespace std;
int main()
{
int diasMes[] = // Días de cada mes
{31, 28, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31};
cout << "Los días de noviembre son: " << diasMes[10];
return 0;
}
Ejercicios propuestos:
(5.5.1) Un programa que, a partir de los datos prefijados de los días de cada mes,
diga qué meses tienen 30 días. Se deberá mostrar el número de cada mes, pero
empezando a contar desde 1 (abril será el mes 4).
4. Bucles
Curso: Introducción a C++
4. Bucles
Hemos visto cómo comprobar condiciones , pero no cómo hacer que una cierta parte de un
programa se repita un cierto número de veces o mientras se cumpla una condición (lo que
llamaremos un “bucle”). En C y en C++ tenemos varias formas de conseguirlo.
4.1. while
Si queremos hacer que una sección de nuestro programa se repita mientras se cumpla una
cierta condición, usaremos la orden “while”. Esta orden tiene dos formatos distintos, según
comprobemos la condición al principio o al final.
En el primer caso, su sintaxis es
while (condición)
sentencia;
Es decir, la sentencia se repetirá mientras la condición sea cierta. Si la condición es falsa
ya desde un principio, la sentencia no se ejecuta nunca. Si queremos que se repita más de
una sentencia, basta agruparlas entre { y }. Como ocurria con "if", puede ser recomendable
incluir siempre las llaves, aunque sea una única sentencia, para evitar errores posteriores
difíciles de localizar.
Un ejemplo que nos diga si cada número que tecleemos es positivo o negativo, y que pare
cuando tecleemos el número 0, podría ser:
// Introducción a C++, Nacho Cabanes
// Ejemplo 04.01:
// La orden "while"
#include <iostream>
using namespace std;
int main()
{
int numero;
cout << "Teclea un numero (0 para salir): ";
cin >> numero;
while (numero!=0)
{
if (numero > 0)
cout << "Es positivo" << endl;
else
cout << "Es negativo" << endl;
cout << "Teclea otro numero (0 para salir): ";
cin >> numero;
}
return 0;
}
En este ejemplo, si se introduce 0 la primera vez, la condición es falsa y ni siquiera se entra
al bloque del “while”, terminando el programa inmediatamente.
Nota: si recordamos que una condición falsa se evalúa como el valor 0 y una condición
verdadera como una valor distinto de cero, veremos que ese “while (numero != 0)” se podría
abreviar como “while (numero)”.
Ejercicios propuestos:
(4.1.1) Crear un programa que pida al usuario su contraseña (numérica). Deberá
terminar cuando introduzca como contraseña el número 4567, pero volvérsela a
pedir tantas veces como sea necesario.
(4.1.2) Crea un programa que escriba en pantalla los números del 1 al 10, usando
“while”.
(4.1.3) Crea un programa que escriba en pantalla los números pares del 26 al 10
(descendiendo), usando “while”.
(4.1.4) Crear un programa calcule cuantas cifras tiene un número entero positivo
(pista: se puede hacer dividiendo varias veces entre 10).
4.2. do ... while
Este es el otro formato que puede tener la orden “while”: la condición se comprueba al final.
El punto en que comienza a repetirse se indica con la orden “do”, así:
do
sentencia;
while (condición);
Al igual que en el caso anterior, si queremos que se repitan varias órdenes (es lo habitual),
deberemos encerrarlas entre llaves. Nuevamente, puede ser recomendable incluir siempre
las llaves, como costumbre.
Como ejemplo, vamos a ver cómo sería el típico programa que nos pide una clave de
acceso y nos nos deja entrar hasta que tecleemos la clave correcta. Eso sí, como todavía no
sabemos manejar cadenas de texto, la clave será un número:
// Introducción a C++, Nacho Cabanes
// Ejemplo 04.02:
// La orden "do..while"
#include <iostream>
using namespace std;
int main()
{
int valida = 711;
int clave;
do
{
cout << "Introduzca su clave numérica: ";
cin >> clave;
if (clave != valida)
cout << "No válida!" << endl;
}
while (clave != valida);
cout << "Aceptada." << endl;
return 0;
}
En este caso, se comprueba la condición al final, de modo que se nos preguntará la clave al
menos una vez. Mientras que la respuesta que demos no sea la correcta, se nos vuelve a
preguntar. Finalmente, cuando tecleamos la clave correcta, el ordenador escribe “Aceptada”
y termina el programa.
Ejercicios propuestos:
(4.2.1) Crear un programa que pida números positivos al usuario, y vaya calculando
la suma de todos ellos (terminará cuando se teclea un número negativo o cero).
(4.2.2) Crea un programa que escriba en pantalla los números del 1 al 10, usando
"do..while".
(4.2.3) Crea un programa que escriba en pantalla los números pares del 26 al 10
(descendiendo), usando "do..while".
(4.2.4) Crea un programa que pida al usuario su código de usuario (un número
entero) y su contraseña numérica (otro número entero), y no le permita seguir hasta
que introduzca como código 1024 y como contraseña 4567.
4.3. for
Ésta es la orden que usaremos habitualmente para crear partes del programa que se repitan
un cierto número de veces. El formato de “for” es
for (valorInicial; CondiciónRepetición; Incremento)
sentencia;
Así, para contar del 1 al 10, tendríamos 1 como valor inicial, <=10 como condición de
repetición, y el incremento sería de 1 en 1. Por tanto, el programa quedaría:
// Introducción a C++, Nacho Cabanes
// Ejemplo 04.03:
// Uso básico de "for"
#include <iostream>
using namespace std;
int main()
{
int contador;
for (contador=1; contador<=10; contador++)
cout << contador << " ";
return 0;
}
Recordemos que “contador++” es una forma abreviada de escribir “contador=contador+1”,
de modo que en este ejemplo aumentamos la variable de uno en uno.
Ejercicios propuestos:
(4.3.1) Crear un programa que muestre los números del 15 al 5, descendiendo
(pista: en cada pasada habrá que descontar 1, por ejemplo haciendo i--).
(4.3.2) Crear un programa que muestre los primeros ocho números pares (pista: en
cada pasada habrá que aumentar de 2 en 2, o bien mostrar el doble del valor que
hace de contador).
En un “for”, realmente, la parte que hemos llamado “Incremento” no tiene por qué
incrementar la variable, aunque ése es su uso más habitual. Es simplemente una orden que
se ejecuta cuando se termine la “Sentencia” y antes de volver a comprobar si todavía se
cumple la condición de repetición.
Por eso, si escribimos la siguiente línea:
for (contador=1; contador<=10; )
la variable “contador” no se incrementa nunca, por lo que nunca se cumplirá la condición de
salida: nos quedamos encerrados dando vueltas dentro de la orden que siga al “for”.
Un caso todavía más exagerado de algo a lo que se entra y de lo que no se sale sería la
siguiente orden:
for ( ; ; )
Los bucles “for” se pueden anidar (incluir uno dentro de otro), de modo que podríamos
escribir las tablas de multiplicar del 1 al 5 con:
// Introducción a C++, Nacho Cabanes
// Ejemplo 04.04:
// "for" anidados - tablas de multiplicar
#include <iostream>
using namespace std;
int main()
{
int tabla, numero;
for (tabla=1; tabla<=5; tabla++)
for (numero=1; numero<=10; numero++)
cout << tabla << " por " << numero
<< " es " << tabla*numero << endl;
return 0;
}
En estos ejemplos que hemos visto, después de “for” había una única sentencia. Si
queremos que se hagan varias cosas, basta definirlas como un bloque (una sentencia
compuesta) encerrándolas entre llaves. Por ejemplo, si queremos mejorar el ejemplo
anterior haciendo que deje una línea en blanco entre tabla y tabla, sería:
// Introducción a C++, Nacho Cabanes
// Ejemplo 04.05:
// "for" anidados (2) - tablas de multiplicar separadas
#include <iostream>
using namespace std;
int main()
{
int tabla, numero;
for (tabla=1; tabla<=5; tabla++)
{
for (numero=1; numero<=10; numero++)
cout << tabla << " por " << numero
<< " es " << tabla*numero << endl;
cout << endl;
}
return 0;
}
Al igual que ocurría con "if" y con "while", suele ser buena costumbre incluir siempre las
llaves, aunque haya una única orden que se repita en el "for", para evitar funcionamientos
incorrectos si después hay que añadir más sentencias que deban repetirse y se olvida
incluir las llaves en ese momento.
Para “contar” no necesariamente hay que usar números. Por ejemplo, podemos contar con
letras así:
// Introducción a C++, Nacho Cabanes
// Ejemplo 04.06:
// "for" que usa "char"
#include <iostream>
using namespace std;
int main()
{
char letra;
for (letra='a'; letra<='z'; letra++)
cout << letra;
return 0;
}
Como se ve en este ejemplo, el tipo de datos que se utiliza para almacenar una letra es el
tipo "char" (carácter). Los valores de un carácter se indican entre comillas simples.
En este caso, empezamos en la “a” y terminamos en la “z”, aumentando de uno en uno.
Si queremos contar de forma decreciente, o de dos en dos, o como nos interese, basta
indicarlo en la condición de finalización del “for” y en la parte que lo incrementa:
// Introducción a C++, Nacho Cabanes
// Ejemplo 04.07:
// "for" que descuenta
#include <iostream>
using namespace std;
int main()
{
char letra;
for (letra='z'; letra>='a'; letra-=2)
cout << letra;
return 0;
}
Ejercicios propuestos:
(4.3.3) Crear un programa que muestre las letras de la Z (mayúscula) a la A
(mayúscula, descendiendo).
(4.3.4) Crear un programa que escriba en pantalla la tabla de multiplicar del 6.
(4.3.5) Crear un programa que escriba en pantalla los números del 1 al 50 que sean
múltiplos de 3 (pista: habrá que recorrer todos esos números y ver si el resto de la
división entre 3 resulta 0).
4.4. Sentencia break: termina el bucle
Podemos salir de un bucle “for” antes de tiempo con la orden “break”:
// Introducción a C++, Nacho Cabanes
// Ejemplo 04.08:
// "for" interrumpido con "break"
#include <iostream>
using namespace std;
int main()
{
int i;
for (i=0; i<=10; i++)
{
if (i==5) break;
cout << i << " ";
}
return 0;
}
El resultado de este programa es:
01234
(en cuanto se llega al valor 5, se interrumpe el “for”, por lo que no se alcanza el valor 10).
Ejercicio propuesto:
(4.4.1) Crear un programa que pida un número al usuario (entre 1 y 100) y muestre
tantas letras A como indique ese número, usando "break" para terminar.
4.5. Sentencia continue: fuerza la siguiente iteración
Podemos saltar alguna repetición de un bucle con la orden “continue”:
// Introducción a C++, Nacho Cabanes
// Ejemplo 04.09:
// "for" interrumpido con "continue"
#include <iostream>
using namespace std;
int main()
{
int i;
for (i=0; i<=10; i++)
{
if (i==5) continue;
cout << i << " ";
}
return 0;
}
El resultado de este programa es:
0 1 2 3 4 6 7 8 9 10
En él podemos observar que no aparece el valor 5.
Ejercicio propuesto:
(4.5.1) Crear un programa que pida un número al usuario (entre 1 y 20) y muestre
los números el 1 al 20, excepto el indicado por el usuario, usando "continue" para
evitar ese valor.
Ejercicios resueltos:
> ¿Qué escribiría en pantalla este fragmento de código?
for (i=1; i<4; i++) cout << i << " ";
Respuesta: los números del 1 al 3 (se empieza en 1 y se repite mientras sea menor que 4).
> ¿Qué escribiría en pantalla este fragmento de código?
for (i=1; i>4; i++) cout << i << " ";
Respuesta: no escribiría nada, porque la condición es falsa desde el principio ("i" vale 1, que
no es mayor que 4).
> ¿Qué escribiría en pantalla este fragmento de código?
for (i=1; i<=4; i++); cout << i << " ";
Respuesta: escribe un 5, porque hay un punto y coma después del “for”, de modo que repite
cuatro veces una orden vacía, y cuando termina, “i” ya tiene el valor 5.
> ¿Qué escribiría en pantalla este fragmento de código?
for (i=1; i<4; ) cout << i << " ";
Respuesta: escribe “1” continuamente, porque no aumentamos el valor de “i”, luego nunca
se llegará a cumplir la condición de salida.
> ¿Qué escribiría en pantalla este fragmento de código?
for (i=1; ; i++) cout << i << " ";
Respuesta: escribe números continuamente, comenzando en uno y aumentando una unidad
en cada pasada, pero si terminar nunca.
> ¿Qué escribiría en pantalla este fragmento de código?
for ( i= 0 ; i<= 4 ; i++)
{
if ( i == 2 ) continue ;
cout << i << " ";
}
Respuesta: escribe los números del 0 al 4, excepto el 2.
> ¿Qué escribiría en pantalla este fragmento de código?
for ( i= 0 ; i<= 4 ; i++)
{
if ( i == 2 ) break ;
cout << i << " ";
}
Respuesta: escribe los números 0 y 1 (interrumpe en el 2).
> ¿Qué escribiría en pantalla este fragmento de código?
for ( i= 0 ; i<= 4 ; i++)
{
if ( i == 10 ) continue ;
cout << i << " ";
}
Respuesta: escribe los números del 0 al 4, porque la condición del “continue” nunca se llega
a dar.
> ¿Qué escribiría en pantalla este fragmento de código?
for ( i= 0 ; i<= 4 ; i++)
if ( i == 2 ) continue ;
cout << i << " ";
Respuesta: escribe 5, porque no hay llaves tras el “for”, luego sólo se repite la orden “if”.
4.6. Sentencia goto
Los lenguajes C y C++ también permiten usar la orden “goto”, para hacer saltos
incondicionales. Su uso indisciplinado está muy mal visto, porque puede ayudar a hacer
programas llenos de saltos, difíciles de seguir. Pero en casos concretos puede ser muy útil,
por ejemplo, para salir de un bucle muy anidado (un “for” dentro de otro “for” que a su vez
está dentro de otro “for”: en este caso, “break” sólo saldría del “for” más interno).
El formato de “goto” es
goto donde;
y la posición de salto se indica con su nombre seguido de dos puntos (:)
donde:
como en el siguiente ejemplo:
// Introducción a C++, Nacho Cabanes
// Ejemplo 04.10:
// "for" y "goto"
#include <iostream>
using namespace std;
int main()
{
int i, j;
for (i=0; i<=5; i++)
for (j=0; j<=20; j+=2)
{
if ((i==1) && (j>=7))
goto salida;
cout << "i vale " << i << " y j vale "
<< j << endl;
}
salida:
cout << "Fin del programa" << endl;
return 0;
}
El resultado de este programa es:
i vale 0 y j vale 0.
i vale 0 y j vale 2.
i vale 0 y j vale 4.
i vale 0 y j vale 6.
i vale 0 y j vale 8.
i vale 0 y j vale 10.
i vale 0 y j vale 12.
i vale 0 y j vale 14.
i vale 0 y j vale 16.
i vale 0 y j vale 18.
i vale 0 y j vale 20.
i vale 1 y j vale 0.
i vale 1 y j vale 2.
i vale 1 y j vale 4.
i vale 1 y j vale 6.
Fin del programa
Vemos que cuando i=1 y j>=7, se sale de los dos “for” a la vez, tal y como indicaba la orden
"goto".
4.7. Recomendación de uso de los distintos tipos de bucle
En general, nos interesará usar “while” cuando puede que la parte repetitiva no se
llegue a repetir nunca (por ejemplo: cuando leemos un fichero, si el fichero está
vacío, no habrá datos que leer).
De igual modo, “do...while” será lo adecuado cuando debamos repetir al menos una
vez (por ejemplo, para pedir una clave de acceso, se le debe preguntar al menos
una vez al usuario, o quizá más veces, si la teclea correctamente).
En cuanto a “for”, es equivalente a un “while”, pero la sintaxis habitual de la oren
“for” hace que sea especialmente útil cuando sabemos exactamente cuantas veces
queremos que se repita (por ejemplo: 10 veces sería “for (i=1; i<=10; i++)”).
Ejercicios propuestos:
(4.7.1) Crear un programa que dé al usuario la oportunidad de adivinar un número
del 1 al 100 (prefijado en el programa) en un máximo de 6 intentos. En cada pasada
deberá avisar de si se ha pasado o se ha quedado corto.
(4.7.2) Crear un programa que descomponga un número (que teclee el usuario)
como producto de su factores primos. Por ejemplo, 60 = 2 · 2 · 3 · 5
3. Condiciones
Curso: Introducción a C++
3. Condiciones
3.1. if
Vamos a ver cómo podemos comprobar si se cumplen condiciones. La primera construcción
que usaremos será "si ... entonces ...". El formato equivalente en C++ es
if (condición) sentencia;
Vamos a verlo con un ejemplo:
// Introducción a C++, Nacho Cabanes
// Ejemplo 03.01:
// Condiciones con if
#include <iostream>
using namespace std;
int main()
{
int numero;
cout << "Escribe un numero: ";
cin >> numero;
if (numero>0) cout << "El numero es positivo.";
return 0;
}
Nota: para comprobar si un valor numérico es mayor que otro, usamos el símbolo “>”, como
se ve en este ejemplo. Para ver si dos valores son iguales, usaremos dos símbolos de
“igual”: if (numero==0). Las demás posibilidades las veremos algo más adelante. En todos
los casos, la condición que queremos comprobar deberá indicarse entre paréntesis.
Ejercicios propuestos:
(3.1.1) Crear un programa que pida al usuario un número entero y diga si es par
(pista: habrá que comprobar si el resto que se obtiene al dividir entre dos es cero: if (x
% 2 == 0) …).
(3.1.2) Crear un programa que pida al usuario dos números enteros y diga cual es el
mayor de ellos.
(3.1.3) Crear un programa que pida al usuario dos números enteros y diga si el
primero es múltiplo del segundo (pista: igual que antes, habrá que ver si el resto de la
división es cero: a % b == 0).
3.2. if y sentencias compuestas
La "sentencia" que se ejecuta si se cumple la condición puede ser una sentencia simple o
una compuesta. Las sentencias compuestas se forman agrupando varias sentencias
simples entre llaves ( { y } ):
// Introducción a C++, Nacho Cabanes
// Ejemplo 03.02:
// Condiciones con if (2)
// Sentencias compuestas
#include <iostream>
using namespace std;
int main()
{
int numero;
cout << "Escribe un numero: ";
cin >> numero;
if (numero>0)
{
cout << "El numero es positivo." << endl;
cout << "Recuerda que tambien puedes usar negativos." << endl;
} // Aqui acaba el "if"
return 0;
} // Aqui acaba el cuerpo del programa
En este caso, si el número es negativo, se hacen dos cosas: escribir un texto y luego...
¡escribir otro! (Claramente, en este ejemplo, esos dos “cout” podrían ser uno solo; más
adelante iremos encontrando casos en los que necesitemos hacer cosas “más serias”
dentro de una sentencia compuesta).
Se pueden incluir siempre las llaves después de un "if", como medida de seguridad: un fallo
frecuente es escribir una única sentencia tras "if", sin llaves, luego añadir una segunda
sentencia y olvidar las llaves... de modo que la segunda orden no se ejecutará si se cumple
la condición, sino siempre, como en este ejemplo:
// Introducción a C++, Nacho Cabanes
// Ejemplo 03.02b:
// Condiciones con if (2b)
// Sentencias compuestas... incorrectas
#include <iostream>
using namespace std;
int main()
{
int numero;
cout << "Escribe un numero: ";
cin >> numero;
if (numero>0)
cout << "El numero es positivo." << endl;
cout << "Recuerda que tambien puedes usar negativos." << endl;
return 0;
}
En este caso, siempre se nos dirá "Recuerde que también puede usar negativos", incluso
cuando hemos tecleado un número negativo. En un vistazo rápido, vemos las dos
sentencias tabuladas a la derecha y tendemos a pensar que las dos dependen del "if", pero
no es así. Se trata de un error difícil de detectar. Por eso, muchos autores recomiendan
incluir siempre las llaves tras un "if", e incluso algún lenguaje de programación moderno
obliga a que siempre sea así.
3.3. Operadores relacionales: <, <=, >, >=, ==, !=
Hemos visto que el símbolo “>” es el que se usa para comprobar si un número es mayor
que otro. El símbolo de “menor que” también es sencillo, pero los demás son un poco
menos evidentes, así que vamos a verlos:
Operador Operación
< Menor que
> Mayor que
<= Menor o igual que
>= Mayor o igual que
== Igual a
!= No igual a (distinto de)
Y un ejemplo:
// Introducción a C++, Nacho Cabanes
// Ejemplo 03.03:
// Condiciones con if (3): distinto de
#include <iostream>
using namespace std;
int main()
{
int numero;
cout << "Escribe un numero: ";
cin >> numero;
if (numero!=0) cout << "El numero no es cero.";
return 0;
}
Los operadores sólo se pueden usar tal y como aparecen en esa tabla. Por ejemplo, no es
un operador válido “!<” para expresar que un número no es menor que otro.
Ejercicios propuestos:
(3.3.1) Crear un programa que multiplique dos números enteros de la siguiente
forma: pedirá al usuario un primer número entero. Si el número que se que teclee es 0,
escribirá en pantalla “El producto de 0 por cualquier número es 0”. Si se ha tecleado un
número distinto de cero, se pedirá al usuario un segundo número y se mostrará el
producto de ambos.
(3.3.2) Crear un programa que pida al usuario dos números reales. Si el segundo no
es cero, mostrará el resultado de dividir entre el primero y el segundo. Por el contrario,
si el segundo número es cero, escribirá “Error: No se puede dividir entre cero”.
3.4. if-else
Podemos indicar lo que queremos que ocurra en caso de que no se cumpla la condición,
usando la orden “else” (en caso contrario), así:
// Introducción a C++, Nacho Cabanes
// Ejemplo 03.04:
// Condiciones con if y else
#include <iostream>
using namespace std;
int main()
{
int numero;
cout << "Escribe un numero: ";
cin >> numero;
if (numero>0) cout << "El numero es positivo.";
else cout << "El numero es cero o negativo.";
return 0;
}
Podríamos intentar evitar el uso de “else” si utilizamos un “if” a continuación de otro, así:
// Introducción a C++, Nacho Cabanes
// Ejemplo 03.05:
// Intentando esquivar "else"
#include <iostream>
using namespace std;
int main()
{
int numero;
cout << "Escribe un numero: ";
cin >> numero;
if (numero>0) cout << "El numero es positivo.";
if (numero<=0) cout << "El numero es cero o negativo.";
return 0;
}
Pero el comportamiento no es el mismo: en el primer caso (ejemplo 03.04) se mira si el
valor es positivo; si no lo es, se pasa a la segunda orden, pero si lo es, el programa ya ha
terminado. En el segundo caso (ejemplo 03.05), aunque el número sea positivo, se vuelve a
realizar la segunda comprobación para ver si es negativo o cero, por lo que el programa es
algo más lento.
Podemos enlazar los “if” usando “else”, para decir “si no se cumple esta condición, mira a
ver si se cumple esta otra”:
// Introducción a C++, Nacho Cabanes
// Ejemplo 03.06
// Condiciones con if encadenados
#include <iostream>
using namespace std;
int main()
{
int numero;
cout << "Escriba un numero: ";
cin >> numero;
if (numero < 0)
cout << "El numero es negativo.";
else
if (numero == 0)
cout << "El numero es cero.";
else
cout << "El numero es positivo.";
return 0;
}
Ejercicio propuesto :
(3.4.1) Mejorar la solución a los dos ejercicios del apartado anterior, usando “else”.
3.5. Operadores lógicos: &&, ||, !
Estas condiciones se puede encadenar con “y”, “o”, etc., que se indican de la siguiente
forma
OperadorSignificado
&& Y
|| O
! No
De modo que podremos escribir cosas como
if ((opcion==1) && (usuario==2)) ...
if ((opcion==1) || (opcion==3)) ...
if ((!(opcion==opcCorrecta)) || (tecla==teclaEscape)) ...
La siguiente forma de escribir una condición es incorrecta (y es un error muy frecuente en
los que empiezan a programar en C y en C++):
if ( opcion1 || opcion2 == 3 ) ...
porque la forma correcta de comprobar si la variable “opcion1” o bien “opcion2” valen “3”
sería ésta:
if (( opcion1 == 3 ) || ( opcion2 == 3 )) ...
Ejercicios propuestos :
(3.5.1) Crear un programa que pida una letra al usuario y diga si se trata de una
vocal.
(3.5.2) Crear un programa que pida al usuario dos números enteros y diga “Uno de
los números es positivo”, “Los dos números son positivos” o bien “Ninguno de los
números es positivo”, según corresponda.
(3.5.3) Crear un programa que pida al usuario tres números reales y muestre cuál es
el mayor de los tres.
(3.5.4) Crear un programa que pida al usuario dos números enteros cortos y diga si
son iguales o, en caso contrario, cuál es el mayor de ellos.
3.6. Cómo funciona realmente la condición en un “if”
Como suele ocurrir en C++, lo que hemos visto tiene más miga de la que parece: una
condición cuyo resultado sea “falso” nos devolverá un 0, y otra cuyo resultado sea
“verdadero” devolverá el valor 1:
// Introducción a C++, Nacho Cabanes
// Ejemplo 03.07:
// "Valor de verdad" de una condición
#include <iostream>
using namespace std;
int main()
{
cout << "2==3 vale " << (2==3); // Escribe 0
cout << "2!=3 vale " << (2!=3); // Escribe 1
return 0;
}
En general, si la “condición” de un if es algo que valga 0, se considerará que la condición es
falsa (no se cumple), y si es algo distinto de cero, se considerará que la condición es
verdadera (sí se cumple). Eso nos permite hacer cosas como ésta:
// Introducción a C++, Nacho Cabanes
// Ejemplo 03.08:
// Condiciones con if (8): valor numérico
#include <iostream>
using namespace std;
int main()
{
int numero;
cout << "Escribe un numero: ";
cin >> numero;
if (numero!=0) // Comparacion normal
cout << "El numero no es cero.";
if (numero) // Comparacion "con truco"
cout << "Y sigue sin ser cero.";
return 0;
}
En este ejemplo, la expresión “if (numero)” se fijará en el valor de la variable “numero”. Si es
distinto de cero, se considerará que la condición es correcta, y se ejecutará la sentencia
correspondiente (el “cout”). En cambio, si la variable “numero” vale 0, es considera que la
condición es falsa, y no se sigue analizando.
En general, es preferible evitar este tipo de construcciones. Resulta mucho más legible algo
como “if (numero!=0)” que “if(numero)”.
3.7. El peligro de la asignación en un “if”
Cuidado con el operador de igualdad: hay que recordar que el formato es if (a==b) ... Si no
nos damos cuenta y escribimos if (a=b) estamos asignando a “a” el valor de “b”.
Afortunadamente, la mayoría de los compiladores nos avisan con un mensaje parecido a
“Possibly incorrect assignment” (que podríamos traducir por “posiblemente esta asignación
es incorrecta”) o “Possibly unintended assignment” (algo así como “es posible que no se
pretendiese hacer esta asignación”). Aun así, sólo es un aviso, la compilación prosigue, y se
genera un ejecutable, que puede que se comporte incorrectamente. Vamos a verlo con un
ejemplo:
// Introducción a C++, Nacho Cabanes
// Ejemplo 03.09:
// Condiciones con if:
// Comportamiento incorrecto
#include <iostream>
using namespace std;
int main()
{
int numero;
cout << "Escriba un numero: ";
cin >> numero;
if (numero < 0)
cout << "El numero es negativo.";
else
if (numero = 0)
cout << "El numero es cero.";
else
cout << "El numero es positivo.";
return 0;
}
En este caso, si tecleamos un número negativo, se comprueba la primera condición, se ve
que es correcta y se termina sin problemas. Pero si se teclea cualquier otra cosa (0 o
positivo), la expresión “if (numero=0)” no comprueba su valor, sino que le asigna un valor 0
(falso), por lo que siempre se realiza la acción correspondiente a el “caso contrario” (else):
siempre se escribe “El número es positivo”... ¡aunque hayamos tecleado un 0!
Y si esto es un error, ¿por qué el compilador “avisa” en vez de parar y dar un error “serio”?
Pues porque no tiene por qué ser necesariamente un error: podemos hacer
a = b;
if (a > 2) ...
o bien
if ((a=b) > 2) ...
Es decir, en la misma orden asignamos el valor y comparamos (algo parecido a lo que
hacíamos con “b = ++a”, por ejemplo). En este caso, la asignación dentro del “if” sería
correcta.
Ejercicios resueltos:
> ¿Qué escribiría en pantalla este fragmento de código?
int x = 5; if (x==5) cout << x;
Respuesta: x vale 5, luego se cumple la condición y se escribe un 5.
> ¿Qué escribiría en pantalla este fragmento de código?
int x = 5; if (x) cout << "Si"; else cout << "No";
Respuesta: x vale 5, luego la condición se evalúa como verdadera y se escribe Si.
> ¿Qué escribiría en pantalla este fragmento de código?
int x = 0; if (x=5) cout << "Si"; else cout << "No";
Respuesta: no hemos escrito una comparación dentro de “if”, sino una asignación. Por
tanto, lo que hay escrito dentro del paréntesis se evalúa como verdadero (distinto de cero) y
se escribe Si.
> ¿Qué escribiría en pantalla este fragmento de código?
int x = 5; if (x=0) cout << "Si"; else cout << "No";
Respuesta: de nuevo, no hemos escrito una comparación dentro de “if”, sino una
asignación. Por tanto, lo que hay escrito dentro del paréntesis se evalúa como falso (cero) y
se escribe No.
> ¿Qué escribiría en pantalla este fragmento de código?
int x = 0; if (x==5) cout << "Si" else cout << "No";
Respuesta: no compila, falta un punto y coma antes de “else”.
3.8. Operador condicional: ?
En C y C++ hay otra forma de asignar un valor según se dé una condición o no. Es el
“operador condicional” ? : que se usa
condicion ? valor1 : valor2;
y equivale a decir “si se cumple la condición, toma el valor v1; si no, toma el valor v2”. Un
ejemplo de cómo podríamos usarlo sería
numeroMayor = (a>b) ? a : b;
que, aplicado a un programa sencillo, podría ser
// Introducción a C++, Nacho Cabanes
// Ejemplo 03.10:
// El operador condicional
#include <iostream>
using namespace std;
int main()
{
int a, b, mayor;
cout << "Escriba un numero: ";
cin >> a;
cout << "Escriba otro: ";
cin >> b;
mayor = (a>b) ? a : b;
cout << "El mayor de los numeros es " << mayor;
return 0;
}
Un segundo ejemplo, que sume o reste dos números según la opción que se escoja, sería:
// Introducción a C++, Nacho Cabanes
// Ejemplo 03.11:
// Operador condicional - 2
#include <iostream>
using namespace std;
int main()
{
int a, b, resultado;
int operacion;
cout << "Escriba un numero: ";
cin >> a;
cout << "Escriba otro: ";
cin >> b;
cout << "Escriba una operacion (1 = resta; otro = suma): ";
cin >> operacion;
resultado = (operacion == 1) ? a-b : a+b;
cout << "El resultado es " << resultado;
return 0;
}
Ejercicios propuestos:
(3.8.1) Crear un programa que use el operador condicional para mostrar un el valor
absoluto de un número de la siguiente forma: si el número es positivo, se mostrará tal
cual; si es negativo, se mostrará cambiado de signo.
(3.8.2) Crear un programa que use el operador condicional para dar a una variable
llamada “iguales” (entera) el valor 1 si los dos números que ha tecleado el usuario son
iguales, o el valor 0 si son distintos.
(3.8.3) Usar el operador condicional para calcular el mayor de dos números.
3.9. switch
Si queremos ver varios posibles valores, sería muy pesado tener que hacerlo con muchos
“if” seguidos o encadenados. La alternativa es la orden “switch”, cuya sintaxis es
switch (expresión)
{
case valor1: sentencia1;
break;
case valor2: sentencia2;
sentencia2b;
break;
...
case valorN: sentenciaN;
break;
default:
otraSentencia;
}
Es decir, se escribe tras “switch” la expresión a analizar, entre paréntesis. Después, tras
varias órdenes “case” se indica cada uno de los valores posibles. Los pasos (porque
pueden ser varios) que se deben dar si se trata de ese valor se indican a continuación,
terminando con “break”. Si hay que hacer algo en caso de que no se cumpla ninguna de las
condiciones, se detalla tras “default”.
Vamos con un ejemplo:
// Introducción a C++, Nacho Cabanes
// Ejemplo 03.12:
// Condiciones con switch
#include <iostream>
using namespace std;
int main()
{
int numero;
cout << "Introduce un numero del 1 al 10: ";
cin >> numero;
switch (numero)
{
case 1: cout << "Uno";
break;
case 2: cout << "Dos";
break;
case 3: cout << "Tres";
break;
case 4: cout << "Cuatro";
break;
case 5: cout << "Cinco";
break;
case 6: cout << "seis";
break;
case 7: cout << "Siete";
break;
case 8: cout << "Ocho";
break;
case 9: cout << "Nueve";
break;
case 10: cout << "Diez";
break;
default: cout << "Valor incorrecto!";
}
return 0;
}
Si varios casos dan el mismo resultado, se pueden apilar en cascada, sin usar "break" entre
uno y otro:
// Introducción a C++, Nacho Cabanes
// Ejemplo 03.13:
// Condiciones con switch (2): casos en cascada
#include <iostream>
using namespace std;
int main()
{
int numero;
cout << "Introduce un numero del 1 al 10: ";
cin >> numero;
switch (numero)
{
case 1:
case 3:
case 5:
case 7:
case 9:
cout << "Impar";
break;
case 2:
case 4:
case 6:
case 8:
case 10:
cout << "Par";
break;
default:
cout << "Valor incorrecto!";
}
return 0;
}
Ejercicios propuestos:
(3.9.1) Crea un programa que pida al usuario un número del 1 al 10 y diga si es
múltiplo de 3 o no lo es.
(3.9.2) Crea una versión del ejemplo 3.12, empleando “if” en lugar de “switch”.
(3.9.3) Crea una versión del ejemplo 3.13, empleando “if” en lugar de “switch”.
2. Operaciones aritméticas y variables
Curso: Introducción a C++
2. Operaciones aritméticas y variables
2.1. Escribir varios textos
Si no queremos escribir sólo un texto, podemos indicar varios textos entre comillas, siempre
precedidos por dos símbolos de "menor que":
// Ejemplo 02.01 en C++
#include <iostream>
int main ()
{
std::cout << "Hola, " << "Nacho";
return 0;
}
Parece que no aporta mucho: el resultado es el mismo que en el programa del apartado
anterior, así que sigamos mejorándolo
Ejercicios propuestos
(2.1.1) Crea un programa, que en vez de decir "Hola, mundo", te salude a ti por tu
nombre (por ejemplo, "Hola, Nacho", usando varios textos independientes, como en
el ejemplo 2.
2.2. Escribir números
Esta variante del programa anterior sí resulta más interesante:
// Ejemplo 02.02 en C++
#include <iostream>
int main ()
{
std::cout << "5+7=" << 5+7;
return 0;
}
Su resultado será 5+7=12. Es decir, lo que hemos escrito entre comillas se muestra "tal
cual". Por el contrario, lo que escribamos sin comillas, se analiza para ver cual puede ser
su significado. En este caso, nuestro compilador (la herramienta que analiza nuestro
programa en C++ y genera un programa ejecutable) ve que se trata de una operación, y
calcula (y muestra) el resultado de dicha operación.
Ejercicios propuestos
(2.2.1) Crea un programa que muestre la suma de 25 y 34.
(2.2.2) Crea un programa que muestre la suma de 12345, 112233 y 67890.
(2.2.3) Crea un programa que muestra la suma de 123456789012 y 90123456789.
2.3. Operaciones matemáticas
Doy por sentado que sabes que el símbolo "+" se usa para sumar. Lo que quizá no sea tan
evidente para ti es que el símbolo "*" es el que se emplea para multiplicar. Las operaciones
básicas son:
Operador Operación
+ Suma
- Resta, negación
* Multiplicación
/ División
Ejercicios propuestos
(2.3.1) Crea un programa que muestre la diferencia entre 100 y 39.
(2.3.2) Crea un programa que muestre el producto de 36 y 59.
(2.3.3) Crea un programa que muestre el producto de 72 y -14.
(2.3.4) Crea un programa que muestre el producto de 123456789 y 987654321.
(2.3.5) Crea un programa que muestre la división de 100 entre 25
(2.3.4) Crea un programa que muestre la división de 10 entre 4
2.4. Pedir datos al usuario
Un programa en el que todos los datos estén prefijados es poco útil: no tiene sentido
necesitar modificar el puente y recompilar cada vez que hay que probar datos nuevos. Lo
habitual es que esos datos los introduzca el usuario, o se lean de un fichero, o de una base
de datos, o desde una red de ordenadores (Internet o cualquier otra). Iremos viendo esas
alternativas, pero vamos a empezar por la más fácil: que sea el usuario quien introduzca los
datos.
Usaremos la orden "cin" para leer datos, y deberemos indicar dónde queremos guardarlos.
Ese lugar donde guardar los datos será un espacio de memoria al que daremos un nombre.
Esto es lo que se conoce como una "variable". Una variable necesita dos datos: el nombre
con el que nos referiremos a ella y el tipo de datos que queremos guardar en ella. Por ahora
sólo .Usaremos la orden "cin" para leer datos, y deberemos indicar dónde queremos
guardarlos.
Así, un program que pida un número al usuario y muestre su triple podría ser así:
// Ejemplo 02.03 en C++
#include <iostream>
int main ()
{
int numero;
std::cout << "Dime un número: ";
std::cin >> numero;
std::cout << "El triple de tu número es " << numero*3;
return 0;
}
Donde:
int numero; sirve para declarar una variable llamada "numero", que usaremos para
almacenar un número entero ("int").
std::cin >> numero; se encarga de leer lo que introduzca el usuario y de guardarlo
dentro de la variable "numero". (Atención: se usan símbolos de "mayor que", al
contrario que en "cout", como forma de expresar que los datos van "hacia la
variable".
std::cout << numero*3; escribe el triple del número. Como ya habíamos visto, no
hay comillas, por lo que el compilador realiza la operación correspondiente y
muestra su resultado.
Y un programa que sume dos números introducidos por el usuario sería:
// Ejemplo 02.04 en C++
#include <iostream>
int main ()
{
int n1;
int n2;
int suma;
std::cout << "Dime un numero: ";
std::cin >> n1;
std::cout << "Dime otro numero: ";
std::cin >> n2;
suma = n1 + n2;
std::cout << "Su suma es " << suma;
return 0;
}
Hay muy pocas novedades. Sólo merece la pena destacar que usamos dos variables para
los datos que introduce el usuario, y una tercera variable para calcular la suma antes de
mostrarla.
Cuando vamos, como en este caso, a usar varias variables que son todas del mismo tipo,
podemos declarar todas ellas a la vez, así:
// Ejemplo 02.05 en C++
#include <iostream>
int main ()
{
int n1, n2, suma;
std::cout << "Dime un numero: ";
std::cin >> n1;
std::cout << "Dime otro numero: ";
std::cin >> n2;
suma = n1 + n2;
std::cout << "Su suma es " << suma;
return 0;
}
Ejercicios propuestos
(2.4.1) Crea un programa que pida dos números al usuario y muestre su producto.
(2.4.2) Crea un programa que pida dos números al usuario y muestre su diferencia.
(2.4.3) Crea un programa que pida dos números al usuario y muestre la división del
primero entre el segundo.
(2.4.4) Crea un programa que pida tres números al usuario y muestre su suma.
(2.4.5) Crea un programa que pida dos números al usuario (que llamaremos "a" y
"b"), y muestre el resultado de (a+b)(a-b) y el de a2-b2.
2.5. Escribir en varias líneas
Hasta ahora, hemos escrito todo en la misma línea. No es grave, porque los primeros
programas eran muy sencillos, y en los últimos, el hecho de usar "cin" ayudaba a que el
cursor bajase a la línea siguiente de pantalla tras cada introducción de datos. Pero en
ocasiones querremos que un texto aparezca en una línea y otro en la línea siguiente, sin
necesidad de que el usuario introduzca datos. Para conseguirlo, enviaremos a cout algo
llamado "std::endl", así:
// Ejemplo 02.6 en C++
#include <iostream>
int main ()
{
std::cout << "Primera línea" << std::endl;
std::cout << "Segunda" << std::endl << "y tercera"
<< std::endl;
return 0;
}
Ejercicios propuestos
(2.5.1) Crea un programa que te pida tu nombre, y te salude en dos líneas. En la
primer línea aparecerá "Hola" y tu nombre; en la segunda línea aparecerá "¿Cómo
estás?"
2.6. Evitemos escribir "std::"
Si nos resulta pesado escribir "std::" delante de cada "cout" y de cada "cin", existe una
solución, sencilla: añadir "using namespace std; al principio del programa. Ya hablaremos
de "espacios de nombres" más adelante, pero de momento nos limitaremos a ver una
versión alternativa del ejercicio 02.05 que emplee esa construcción:
// Ejemplo 02.07 en C++
#include <iostream>
using namespace std;
int main ()
{
int n1;
int n2;
int suma;
cout << "Dime un numero: ";
cin >> n1;
cout << "Dime otro numero: ";
cin >> n2;
suma = n1 + n2;
cout << "Su suma es " << suma;
return 0;
}
Ejercicios propuestos
(2.6.1) Crea un programa que pida te pida tres números y muestre su producto. No
debes usar "std::" sino "using".
2.7. Números con decimales
Si has hecho todos los ejercicios propuestos, habrás notado que, como siempre estamos
usando números enteros, el resultado también es un número entero. Eso es especialmente
desconcertante en el caso de las divisiones: podríamos esperar que 10/2 diera como
resultado 2.5, pero obtenemos 2.
La alternativa es usar otro tipo de datos, uno que sí permite guardar números reales (con
cifras decimales), de modo que los resultados también tengan decimales. Bastará con
cambiar "int" por "float":
// Ejemplo 02.08 en C++
#include <iostream>
using namespace std;
int main ()
{
float n1, n2, suma;
cout << "Dime un numero: ";
cin >> n1;
cout << "Dime otro numero: ";
cin >> n2;
suma = n1 + n2;
cout << "Su suma es " << suma;
return 0;
}
Pronto detallaremos que existen más tipos de datos: enteros que permiten almacenar más o
menos cifras, y reales que tienen más o menos precisión. Pero para empezar a practicar
nos bastará con "int" y "float".
Ejercicios propuestos
(2.7.1) Crea un programa que pida te pida dos números reales y muestre su división.
Comprueba si esta vez sí aparecen correctamente los decimales.
2.8. La operación "módulo"
Una quinta operación aritmética, que no es especialmente frecuente en "el mundo real",
pero sí en la programación de ordenadores, es la operación "módulo", el resto de la división.
Para ella se usa el símbolo "%". Así, una operación como "25%4" (25 módulo 4) daría como
resultado "1" (el resto que se obtiene al dividir 25 entre 4).
¿Y por qué se usa con frecuencia? Porque es una forma sencilla de saber si un número es
múltiplo de otro: en ese caso, el resto de la división será 0. Así podremos darnos cuenta de
cuándo un número es par (múltiplo de 2), o hacer una pausa tras mostrar cada bloque de 25
datos, por ejemplo. Lo usaremos mucho en los dos siguientes temas.
Ejercicios propuestos
(2.8.1) Crea un programa que pida te pida dos números enteros y muestre su
división y el resto de esa división.
2.9. Incremento y decremento
Hay otra operación que es muy frecuente cuando se crean programas, pero que no tiene un
símbolo específico para representarla en matemáticas. Es incrementar el valor de una
variable en una unidad:
a = a+1;
Pues bien, en C y C++, existe una notación más compacta para esta operación, y para la
opuesta (el decremento):
a++; // es lo mismo que a = a+1;
a--; // es lo mismo que a = a-1;
Pero esto tiene más misterio todavía del que puede parecer en un primer vistazo: podemos
distinguir entre "preincremento" y "postincremento". En C es posible hacer asignaciones
como
b = a++;
Así, si "a" valía 2, lo que esta instrucción hace es dar a "b" el valor de "a" y aumentar el valor
de "a". Por tanto, al final tenemos que b=2 y a=3 (postincremento: se incrementa "a" tras
asignar su valor).
En cambio, si escribimos
b = ++a;
y "a" valía 2, primero aumentamos "a" y luego los asignamos a "b" (preincremento), de
modo que a=3 y b=3.
Por supuesto, también podemos distinguir postdecremento (a--) y predecremento (--a).
Ejercicios propuestos:
(2.9.1) Crear un programa que use tres variables x,y,z. Sus valores iniciales serán
15, -10, [Link]. Se deberá incrementar el valor de estas variables. ¿Qué
valores esperas que se obtengan? Contrástalo con el resultado obtenido por el
programa.
(2.9.2) ¿Cuál sería el resultado de las siguientes operaciones? a=5; b=++a; c=a++;
b=b*5; a=a*2;
Y ya que estamos hablando de las asignaciones, hay que comentar que en C y en C++ es
posible hacer asignaciones múltiples:
a = b = c = 1;
2.10. Operaciones abreviadas: +=
Pero aún hay más. Tenemos incluso formas reducidas de escribir cosas como "a = a+5".
Allá van
a += b ; // es lo mismo que a = a+b;
a -= b ; // es lo mismo que a = a-b;
a *= b ; // es lo mismo que a = a*b;
a /= b ; // es lo mismo que a = a/b;
a %= b ; // es lo mismo que a = a%b;
Ejercicios propuestos:
(2.10.1) Crear un programa que use tres variables x,y,z. Sus valores iniciales serán
15, -10, 214. Se deberá incrementar el valor de estas variables en 12, usando el
formato abreviado. ¿Qué valores esperas que se obtengan? Contrástalo con el
resultado obtenido por el programa.
(2.10.2) ¿Cuál sería el resultado de las siguientes operaciones? a=5; b=a+2; b-=3;
c=-3; c*=2; ++c; a*=b;