INTRODUCCIÓN
En este bloque introduciremos el lenguaje de programación C++. Comenzaremos por dar una visión general del lenguaje y después trataremos de forma práctica todos los conceptos estudiados en el bloque anterior, viendo como se implementan en el C++.
Trataremos de que el tema sea fundamentalmente práctico, por lo que estos apuntes se deben considerar como una pequeña introducción al lenguaje, no como una referencia completa.
En este bloque introduciremos el lenguaje de programación C++. Comenzaremos por dar una visión general del lenguaje y después trataremos de forma práctica todos los conceptos estudiados en el bloque anterior, viendo como se implementan en el C++.
Trataremos de que el tema sea fundamentalmente práctico, por lo que estos apuntes se deben considerar como una pequeña introducción al lenguaje, no como una referencia completa.
CONCEPTOS BÁSICOS
Comenzaremos estudiando el soporte del C++ a la programación imperativa, es decir, la forma de definir y utilizar los tipos de datos, las variables, las operaciones aritméticas, las estructuras de control y las funciones. Es interesante remarcar que toda esta parte está heredada del C, por lo que también sirve de introducción a este lenguaje.
Estructura de los programas
El mínimo programa de C++ es:
main() { }
Lo único que hemos hecho es definir una función (main) que no tiene argumentos y no hace nada. Las llaves { } delimitan un bloque en C++, en este caso el cuerpo de la función main. Todos los programas deben tener una función main() que es la que se ejecuta al comenzar el programa.
Un programa será una secuencia de líneas que contendrán sentencias, directivas de compilación y comentarios.
Las sentencias simples se separan por punto y coma y las compuestas se agrupan en bloques mediante llaves.
Las directivas serán instrucciones que le daremos al compilador para indicarle que realice alguna operación antes de compilar nuestro programa, las directivas comienzan con el símbolo # y no llevan punto y coma.
Los comentarios se introducirán en el programa separados por /* y */ o comenzándolos con //. Los comentarios entre /* y */ pueden tener la longitud que queramos, pero no se anidan, es decir, si escribimos /* hola /* amigo */ mío */, el compilador interpretará que el comentario termina antes de mío, y dará un error. Los comentarios que comienzan por // sólo son válidos hasta el final de la línea en la que aparecen.
Un programa simple que muestra todo lo que hemos visto puede ser el siguiente:
/* Este es un programa mínimo en C++, lo único que hace es escribir una frase en la pantalla */
#include <iostream.h>
Estructura de los programas
El mínimo programa de C++ es:
main() { }
Lo único que hemos hecho es definir una función (main) que no tiene argumentos y no hace nada. Las llaves { } delimitan un bloque en C++, en este caso el cuerpo de la función main. Todos los programas deben tener una función main() que es la que se ejecuta al comenzar el programa.
Un programa será una secuencia de líneas que contendrán sentencias, directivas de compilación y comentarios.
Las sentencias simples se separan por punto y coma y las compuestas se agrupan en bloques mediante llaves.
Las directivas serán instrucciones que le daremos al compilador para indicarle que realice alguna operación antes de compilar nuestro programa, las directivas comienzan con el símbolo # y no llevan punto y coma.
Los comentarios se introducirán en el programa separados por /* y */ o comenzándolos con //. Los comentarios entre /* y */ pueden tener la longitud que queramos, pero no se anidan, es decir, si escribimos /* hola /* amigo */ mío */, el compilador interpretará que el comentario termina antes de mío, y dará un error. Los comentarios que comienzan por // sólo son válidos hasta el final de la línea en la que aparecen.
Un programa simple que muestra todo lo que hemos visto puede ser el siguiente:
/* Este es un programa mínimo en C++, lo único que hace es escribir una frase en la pantalla */
#include <iostream.h>
int main()
{
cout << "Hola guapo\n"; // imprime en la pantalla la frase "hola guapo"
}
La primera parte separada entre /* y */ es un comentario. Es recomendable que se comenten los programas, explicando que es lo que estamos haciendo en cada caso, para que cuando se lean sean más comprensibles.
La línea que empieza por # es una directiva. En este caso indica que se incluya el fichero "iostream.h", que contiene las definiciones para entrada/salida de datos en C++.
En la declaración de main() hemos incluido la palabra int, que indica que la función devuelve un entero. Este valor se le entrega al sistema operativo al terminar el programa. Si no se devuelve ningún valor el sistema recibe un valor aleatorio.
La sentencia separada entre llaves indica que se escriba la frase "Hola guapo". El operador <<
("poner en") escribe el segundo argumento en el primero. En este caso la cadena "Hola guapo\n" se escribe en la salida estándar (cout). El carácter \ seguido de otro carácter indica un solo carácter especial, en este caso el salto de línea (\n).
Veremos el tema de la entrada salida estándar más adelante. Hay que indicar que las operaciones de E/S se gestionan de forma diferente en C y C++, mientras que el C proporciona una serie de funciones (declaradas en el fichero "stdio.h"), el C++ utiliza el concepto de stream, que se refiere al flujo de la información (tenemos un flujo de entrada que proviene de cin y uno de salida que se dirige a cout que se maneja mediante operadores de E/S.
Por último señalar que debemos seguir ciertas reglas al nombrar tipos de datos, variables, funciones, etc. Los identificadores válidos del C++ son los formados a partir de los caracteres del alfabeto (el inglés, no podemos usar ni la ñ ni palabras acentuadas), los dígitos (0..9) y el subrayado ( _ ), la única restricción es que no podemos comenzar un identificador con un dígito (es así porque se podrían confundir con literales numéricos). Hay que señalar que el C++ distingue entre mayúsculas y minúsculas, por lo que Hola y hola representan dos cosas diferentes. Hay que evitar el uso de identificadores que sólo difieran en letras mayúsculas y minúsculas, porque inducen a error.
cout << "Hola guapo\n"; // imprime en la pantalla la frase "hola guapo"
}
La primera parte separada entre /* y */ es un comentario. Es recomendable que se comenten los programas, explicando que es lo que estamos haciendo en cada caso, para que cuando se lean sean más comprensibles.
La línea que empieza por # es una directiva. En este caso indica que se incluya el fichero "iostream.h", que contiene las definiciones para entrada/salida de datos en C++.
En la declaración de main() hemos incluido la palabra int, que indica que la función devuelve un entero. Este valor se le entrega al sistema operativo al terminar el programa. Si no se devuelve ningún valor el sistema recibe un valor aleatorio.
La sentencia separada entre llaves indica que se escriba la frase "Hola guapo". El operador <<
("poner en") escribe el segundo argumento en el primero. En este caso la cadena "Hola guapo\n" se escribe en la salida estándar (cout). El carácter \ seguido de otro carácter indica un solo carácter especial, en este caso el salto de línea (\n).
Veremos el tema de la entrada salida estándar más adelante. Hay que indicar que las operaciones de E/S se gestionan de forma diferente en C y C++, mientras que el C proporciona una serie de funciones (declaradas en el fichero "stdio.h"), el C++ utiliza el concepto de stream, que se refiere al flujo de la información (tenemos un flujo de entrada que proviene de cin y uno de salida que se dirige a cout que se maneja mediante operadores de E/S.
Por último señalar que debemos seguir ciertas reglas al nombrar tipos de datos, variables, funciones, etc. Los identificadores válidos del C++ son los formados a partir de los caracteres del alfabeto (el inglés, no podemos usar ni la ñ ni palabras acentuadas), los dígitos (0..9) y el subrayado ( _ ), la única restricción es que no podemos comenzar un identificador con un dígito (es así porque se podrían confundir con literales numéricos). Hay que señalar que el C++ distingue entre mayúsculas y minúsculas, por lo que Hola y hola representan dos cosas diferentes. Hay que evitar el uso de identificadores que sólo difieran en letras mayúsculas y minúsculas, porque inducen a error.
Tipos de datos y operadores
Los tipos elementales definidos en C++ son:
char, short, int, long, que representan enteros de distintos tamaños (los caracteres son enteros de 8 bits)
float, double y long double, que representan números reales (en coma flotante).
Para declarar variables de un tipo determinado escribimos el nombre del tipo seguido del de la variable. Por ejemplo:
int i;
double d;
char c;
Sobre los tipos elementales se pueden emplear los siguientes operadores aritméticos:
+ (más, como signo o como operación suma)
- (menos, como signo o como operación resta)
* (multiplicación)
/ (división)
% (resto)
Y los siguientes operadores relacionales:
== (igual)
!= (distinto)
< (menor que)
> (mayor que)
<= (menor o igual que)
>= (mayor o igual que)
El operador de asignación se representa por =.
En la bibliografía del C++ se suelen considerar como tipos derivados los construidos mediante la aplicación de un operador a un tipo elemental o compuesto en su declaración. Estos operadores son:
* Puntero
& Referencia
[] Vector (Array)
() Función
Los tipos compuestos son las estructuras (struct), las uniones (unión) y las clases (class).
Estructuras de control
Como estructuras de control el C++ incluye las siguientes construcciones:
condicionales:
- if instrucción de selección simple
- switch instrucción de selección múltiple
bucles:
- do-while instrucción de iteración con condición final
- while instrucción de iteración con condición inicial
- for instrucción de iteración especial (similar a las de repetición con contador)
de salto:
- break instrucción de ruptura de secuencia (sale del bloque de un bucle o instrucción condicional)
- continue instrucción de salto a la siguiente iteración (se emplea en bucles para saltar a la posición donde se comprueban las condiciones)
- goto instrucción de salto incondicional (salta a una etiqueta)
- return instrucción de retorno de un valor (se emplea en las funciones)
Tipos de datos
Para declarar una variable ponemos el nombre del tipo seguido del de la variable. Podemos declarar varias variables de un mismo tipo poniendo el nombre del tipo y las variables a declarar separadas por comas:
int i, j,k;
Además podemos inicializar una variable a un valor en el momento de su declaración:
int i=100;
Cada tipo definido en el lenguaje (o definido por el usuario) tiene un nombre sobre el que se pueden emplear dos operadores:
- sizeof, que nos indica la memoria necesaria para almacenar un objeto del tipo, y
- new, que reserva espacio para almacenar un valor del tipo en memoria.
El C++ tiene un conjunto de tipos elementales correspondientes a las unidades de almacenamiento típicas de un computador y a las distintas maneras de utilizarlos:
Enteros:
- char
- short int
- int
- long int
Reales (números en coma flotante):
- float
- double
- long doublé
La diferencia entre los distintos tipos enteros (o entre los tipos reales) está en la memoria que ocupan las variables de ese tipo y en los rangos que pueden representar. A mayor tamaño, mayor cantidad de valores podemos representar. Con el operador sizeof podemos saber cuanto ocupa cada tipo en memoria.
Para especificar si los valores a los que se refieren tienen o no signo empleamos las palabras signed y unsigned delante del nombre del tipo (por ejemplo unsigned int para enteros sin signo).
Para tener una notación más compacta la palabra int se puede eliminar de un nombre de tipo de más de una palabra, por ejemplo short int se puede escribir como short, unsigned es equivalente a unsigned int, etc.
El tipo entero char es el que se utiliza normalmente para almacenar y manipular caracteres en la mayoría de los computadores, generalmente ocupa 8 bits (1byte), y es el tipo que se utiliza como base para medir el tamaño de los demás tipos del C++.
Un tipo especial del C++ es el denominado void (vacío). Este tipo tiene características muy peculiares, ya que es sintácticamente igual a los tipos elementales pero sólo se emplea junto a los derivados, es decir, no hay objetos del tipo void Se emplea para especificar que una función no devuelve nada o como base para punteros a objetos de tipo desconocido (esto lo veremos al estudiar los punteros). Por ejemplo:
void BorraPantalla (void);
Indica que la función BorraPantalla no tiene parámetros y no retorna nada.
Tipos enumerados
Un tipo especial de tipos enteros son los tipos enumerados. Estos tipos sirven para definir un tipo que sólo puede tomar valores dentro de un conjunto limitado de valores. Estos valores tienen nombre, luego lo que hacemos es dar una lista de constantes asociadas a un tipo.
La sintaxis es:
enum booleano {FALSE, TRUE}; // definimos el tipo booleano
Aquí hemos definido el tipo booleano que puede tomar los valores FALSE o TRUE. En realidad hemos asociado la constante FALSE con el número 0, la constante TRUE con 1, y si hubiera más constantes seguiríamos con 2, 3, etc.
Un tipo especial de tipos enteros son los tipos enumerados. Estos tipos sirven para definir un tipo que sólo puede tomar valores dentro de un conjunto limitado de valores. Estos valores tienen nombre, luego lo que hacemos es dar una lista de constantes asociadas a un tipo.
La sintaxis es:
enum booleano {FALSE, TRUE}; // definimos el tipo booleano
Aquí hemos definido el tipo booleano que puede tomar los valores FALSE o TRUE. En realidad hemos asociado la constante FALSE con el número 0, la constante TRUE con 1, y si hubiera más constantes seguiríamos con 2, 3, etc.
Si por alguna razón nos interesa dar un número concreto a cada valor podemos hacerlo en la declaración:
enum colores {rojo = 4, azul, verde = 3, negro = 1};
enum colores {rojo = 4, azul, verde = 3, negro = 1};
azul tomará el valor 5 (4+1), ya que no hemos puesto nada. También se pueden usar números negativos o constantes ya definidas.
Para declarar un variable de un tipo enumerado hacemos:
booleano test; // sintaxis de C
Literales carácter
Los caracteres se delimitan entre dos apóstrofes ''. Dentro de los apóstrofes sólo podemos escribir un carácter, excepto cuando son caracteres especiales, que se codifican mediante el carácter de escape \ seguido de otro carácter .
Ejemplos:
- 'a' // carácter a
- ' ' // espacio en blanco (es un carácter)
- '\\' // carácter \ (es un carácter especial)
- '' // error: debe haber un carácter entre los apóstrofes
- 'ab' // error: pero sólo uno
Caracteres especiales más utilizados:
\n // salto de línea
\t // tabulador horizontal
\v // tabulador vertical
\b // retroceso
\r // retorno de carro
\f // salto de página
\a // alerta (campana)
\\ // carácter \
\? // interrogante
\' // comilla simple
\" // comilla doble
\ooo // carácter ASCII dado por tres dígitos octales (ooo serán dígitos)
\xhh // carácter ASCII dado por dos dígitos hexadecimales (hh serán dígitos)
\0 // carácter nulo
Literales cadena
Una cadena es un a secuencia de caracteres escrita entre comillas dobles y terminada con el carácter nulo (\0).
Ejemplos:
- "hola" // equivale a 'h','o','l','a','\0'
- "" // equivale a '\0'
- "'" // equivale a '\'', '\0'
- "\'" // equivale a '\'', '\0'
- """ // error, para escribir " dentro de una cadena lo correcto sería "\""
- "ho""la" // se concatenan, equivale a 'h','o','l','a','\0'
El C++, como todo lenguaje de programación basado en la algorítmica, posee una serie de estructuras de control para gobernar el flujo de los programas. Aquí estudiaremos las estructuras de control de la misma manera que las vimos en el bloque anterior, es decir, separando entre estructuras condicionales o de selección, de repetición y de salto.
Antes de comenzar debemos recordar que la evaluación de una condición producirá como resultado un cero si es falsa y un número cualquiera distinto de cero si es cierta, este hecho es importante a la hora de leer los programas, ya que una operación matemática, por ejemplo, es una condición válida en una estructura de control.
Estructuras de selecciónDentro de las estructuras de selección encontramos dos modelos en el C++, las de condición simple (sentencias if else) y las de condición múltiple (switch). A continuación estudiaremos ambos tipos de sentencias.
La sentencia if
Se emplea para elegir en función de una condición. Su sintaxis es:
if (expresión)
sentencia 1
else
sentencia 2
Los paréntesis de la expresión a evaluar son obligatorios, la sentencia 1 puede ser una sola instrucción (que no necesita ir entre llaves) o un bloque de instrucciones (entre llaves pero sin punto y coma después de cerrar). El else es opcional, cuando aparece determina las acciones a tomar si la expresión es falsa.
El único problema que puede surgir con estas sentencias es el anidamiento de if y else: Cada else se empareja con el if más cercano:
if (expr1)
if (expr2)
acción 1
else // este else corresponde al if de expr 2
acción 2
else // este corresponde al if de expr1
acción 3
if (expr2)
acción 1
else // este else corresponde al if de expr 2
acción 2
else // este corresponde al if de expr1
acción 3
Para diferenciar bien unas expresiones de otras (el anidamiento), es recomendable tabular
correctamente y hacer buen uso de las llaves:
if (expr1)
correctamente y hacer buen uso de las llaves:
if (expr1)
{
if (expr2)
acción 1
} // Notar que la llave no lleva punto y coma después, si lo pusiéramos
// habríamos terminado la sentencia y el else se quedaría suelto
else // Este else corresponde al if de expr1
acción 3
Por último indicaremos que cuando anidamos else - if se suele escribir
if (e1)
a1
else if (e2)
a2
else if (e3)
a3
…
else
an
de esta manera evitamos el exceso de tabulación.
La sentencia switch
Esta sentencia nos permite seleccionar en función de condiciones múltiples. Su sintaxis es:
switch (expresión)
{
case valor_1: sentencia 11;
sentencia 12;
…
sentencia 1n;
break;
case valor_2: sentencia 21;
sentencia 22;
…
sentencia 2m;
break;
…
default: sentencia d1;
sentencia d2;
…
sentencia dp
}
El paréntesis en la expresión es obligatorio. El funcionamiento es el siguiente, si al evaluar la
expresión se obtiene uno de los valores indicados por case valor_i se ejecutan todas las sentencias que encontremos hasta llegar a un break (o al cierre de las llaves). Si no se verifica ningún case pasamos a las sentencias default, si existe (default es opcional) y si no existe no hacemos nada.
Indicaremos que si queremos hacer lo mismo para distintos valores podemos escribir los case seguidos sin poner break en ninguno de ellos y se ejecutará lo mismo para todos ellos.
Ejemplo:
void main()
{
int i;
cin >> i;
switch (i)
{
case 0:
case 2:
case 4:
case 6:
case 8:
cout << " El número " << i << " es par\n";
break
case 1:
case 3:
case 5:
case 7:
case 9:
cout << " El número " << i << " es impar\n";
break;
default:
cout << " El número " << i << " no está reconocido\n";
}
}
if (expr2)
acción 1
} // Notar que la llave no lleva punto y coma después, si lo pusiéramos
// habríamos terminado la sentencia y el else se quedaría suelto
else // Este else corresponde al if de expr1
acción 3
Por último indicaremos que cuando anidamos else - if se suele escribir
if (e1)
a1
else if (e2)
a2
else if (e3)
a3
…
else
an
de esta manera evitamos el exceso de tabulación.
La sentencia switch
Esta sentencia nos permite seleccionar en función de condiciones múltiples. Su sintaxis es:
switch (expresión)
{
case valor_1: sentencia 11;
sentencia 12;
…
sentencia 1n;
break;
case valor_2: sentencia 21;
sentencia 22;
…
sentencia 2m;
break;
…
default: sentencia d1;
sentencia d2;
…
sentencia dp
}
El paréntesis en la expresión es obligatorio. El funcionamiento es el siguiente, si al evaluar la
expresión se obtiene uno de los valores indicados por case valor_i se ejecutan todas las sentencias que encontremos hasta llegar a un break (o al cierre de las llaves). Si no se verifica ningún case pasamos a las sentencias default, si existe (default es opcional) y si no existe no hacemos nada.
Indicaremos que si queremos hacer lo mismo para distintos valores podemos escribir los case seguidos sin poner break en ninguno de ellos y se ejecutará lo mismo para todos ellos.
Ejemplo:
void main()
{
int i;
cin >> i;
switch (i)
{
case 0:
case 2:
case 4:
case 6:
case 8:
cout << " El número " << i << " es par\n";
break
case 1:
case 3:
case 5:
case 7:
case 9:
cout << " El número " << i << " es impar\n";
break;
default:
cout << " El número " << i << " no está reconocido\n";
}
}
**Información obtenida del manual Aprenda C++
como si estuviera en primero. Autores: Javier Garcia de Jalón de la Fuente, José Ignacio Rodríguez Garrido y otros. Publicado en http://www.aulaclic.net/cursos/enlace.php?idp=108&id=27&texto=c++&clase=c