You are on page 1of 30

Introducción a C++.

Asignatura Estructuras de Datos
Curso 2015/2016
ETSISI UPM

C vs. C++
 C es un lenguaje procedural  el elemento central del

son las funciones.

 Cualquier función se puede comunicar con las demás a

través de variables globales, parámetros (valor o
referencia), y valores de retorno

 C++ es un lenguaje orientado a objetos  el elemento

central son los objetos que contienen datos (variables
miembro) y funciones que permiten manipularlos y
trabajar con ellos.
 La definición de los objetos se realiza a través de clases
 Existen dos ficheros:
 *.h  contiene la definición de la clase
 *.cpp  contiene la definición de las funciones de la clase
2

Tipos de Datos C++
 Tipos básicos:
 Booleano (bool).
 Carácter (char).
 Entero (int).
 Punto flotante (ej. double, long, float).
 Definidos por el usuario (enum).
 A partir de los anteriores, se pueden construir:
 tipo punteros (ej. int *)
 tipo array (ej. char [])
 tipo referencia (ej. double&)
 estructuras y clases.
3

Constantes literales
 bool: true, false
 char: ‘a’,
 string: “hola”
 int: 15, 15u (unsigned), 017 (octal), 0xf (hexadecimal)
 long: 15L
 float: 15.0F
 double: 15.0, 3e2

4

Declaración de variables
 <Tipo> <identificador> (=valor inicial)
char caracter = '.';
int numerito = 9;

 Constantes: palabra const
const int TAM_MAXIMO = 50;

 Identificadores:
 Han de comenzar por carácter alfabético
 Se distingue entre mayúsculas y minúsculas.
 No puede coincidir con una palabra reservada

5

Palabras reservadas

6

Ámbito de variables

 Ámbito de una variable o constante es el bloque donde se ha declarado.
 Una declaración introduce un nombre dentro de un ámbito, y sólo se
puede usar en este ámbito.
 Globales: definidas fuera del cuerpo de las funciones y están disponibles
para todo el programa.
 Locales: definidas en su lugar utilización.
 Operador de resolución de ámbito ::

7

Operadores (I)
Aritméticos

Relacionales

Lógicos

a+b

a == b (igualdad)

a && b (AND)

a-b

a != b (desigualdad)

a || b (OR)

a*b

a > b (mayor que)

!a (NOT)

a/b

a < b (menor que)

a % b (módulo)

>= (mayor o igual que)

a++ (post incremento)

<= (menor o igual que)

++a (pre incremento)
a-- (post decremento)
--a (pre decremento)
Operadores de bits
a&b

a|b

~a

a^b

a <<b

a>>b

Manipulan las expresiones bit a bit.
Solo se pueden aplicar a expresiones
enteras
8

Operadores (II)
Asignación

=

var = exp
var += exp
Equivale a: var = var + exp

Todos los operadores binarios
(excepto && y ||) pueden
combinarse con el operador de
asignación (+=, *=, -= …)

Referencia

Entrada y salida

[] (miembro de array)

cin >> var

. (miembro de clase)

cout << var

-> (miembro cuando se trabaja con punteros)
&v (dirección de memoria de v)
*p (lo apuntado por p)
:: (ámbito)
9

Estructura de un programa en C++
#include <iostream>
using namespace std;
int main() {
cout << "Hello World!!!" << endl;
// escribe Hello World!!!
return 0;
}

Directivas de inclusión
Espacios con nombre
Espacio global

Comentarios

Ejemplos de directivas:
#include <ctime>
#include <cstdlib>
#include <string>
10

Concepto de CLASE

Las clases de C++ son una generalización de las estructuras de C
struct Alumno {
int numMatricula;
char nombre[41];
}
Alumno alu1 = {3041, “Antonio”}, alu2 = {2054, “David”};

Alumno.cpp
#include "Alumno.h"
#include <iostream>
using namespace std;

Alumno.h
#include <string>
using namespace std;
#ifndef ALUMNO_H_
#define ALUMNO_H_
class Alumno {
public:
int numMatricula;
string nombre;

Operador de resolución
de visibilidad

Variables
miembro

Alumno(int num,string nom);
~Alumno();
};
#endif /* ALUMNO_H_ */
• Constructor
• Destructor
• Otras funciones miembro

Prueba.cpp
#include "Alumno.h"
#include <iostream>
using namespace std;

//constructor
Alumno::Alumno(int num, string nom){
numMatricula = num;
nombre = nom;
}
//destructor
Alumno::~Alumno() {
}

int main(void){
//se crean objetos de la clase alumno
Alumno a1 (3041, "Antonio");
Alumno a2 (2054, "David");
cout << "nombre del primer alumno " << a1.nombre << endl;
cout << "nombre del segundo alumno " << a2.nombre <<endl;
}
11

Memoria Dinámica
 Datos estáticos: su tamaño y forma es constante

durante la ejecución de un programa y se determinan
en tiempo de compilación. Ej. arrays
int numbers[5];
int numbersprima[] = {10,20,30}
for (int n=0; n<3; n++)
cout << numbersprima[n] << ", ";
cout << endl;;

 Datos dinámicos: su tamaño y forma puede ser variable

a lo largo de un programa, se crean y destruyen en
tiempo de ejecución  se asigna memoria según se va
necesitando. Ej. punteros

12

Memoria Dinámica
 PUNTERO: nos permite referenciar datos dinámicos.

Es una dirección de memoria
 Variable apuntadora

 Variable apuntada (anónima o referenciada)

Declaración de punteros:
typedef int * PtrInt;
PtrInt mypointer;

O bien, directamente
int * mypointer;

13

Memoria Dinámica
 PUNTERO
Gestión de memoria dinámica:
#include <iostream>
using namespace std;
int main () {
int * mypointer;
//reserva de memoria de forma dinámica
mypointer = new int;
//inicialización
*mypointer = 10;
cout << “mypointer is " << *mypointer << '\n';
//se libera memoria
delete mypointer;
}

Tras la declaración del puntero

mypointer
(memoria estática)

posición de memoria
indefinida
basura

basura

Tras el NEW

mypointer
0xdir

memoria dinámica
basura

Tras la asignación

mypointer
0xdir

memoria dinámica
10

14

Memoria Dinámica
 PUNTEROS
Gestión de memoria dinámica :
#include "Alumno.h"
#include <iostream>
using namespace std;

Alumno.cpp

//constructor
[…]
//destructor
[…]

Tras la declaración del
puntero antes del NEW

pAlumno

posición de memoria
indefinida

basura

basura

Prueba.cpp
#include "Alumno.h"
#include <iostream>
using namespace std;
int main(void){
Alumno *pAlumno;
//reserva memoria de forma dinámica y creación objeto Alumno
pAlumno = new Alumno(1111, "Pepe");
cout << "matricula alumno " << pAlumno->numMatricula << endl;
cout << “nombre alumno " << pAlumno->nombre << endl;
//se libera memoria
delete pAlumno;
}

Tras el NEW y la inicialización
(opcional) del objeto Alumno
posición de memoria
dinámica

pAlumno
0xdir

:Alumno

numMatricula = 1111
Nombre = Pepe

15

Memoria Dinámica
 PUNTERO
Operaciones con punteros:
memoria estática

0x 28FED0
#include <iostream>
using namespace std;

0x 28FED4

int main () {
int myvar;
int * mypointer;
mypointer = &myvar;
*mypointer = 10;
cout << "myvar is " << myvar << '\n';
}

mypointer

0x 28FED8 0x 28FEE0(16
0x 28FEDC

myvar

0x 28FEE0

10 (10

Operador de dirección
(address-of operator)
Operador de indirección
(dereference operator)
16

Memoria Dinámica
 PUNTERO
Operaciones con punteros:

Suponiendo que mypointer está en la
dirección de memoria 0x28FED8, es posible
comprobar que el contenido de mypointer es
la dirección de memoria 0x28FEE0
(dirección de la variable myvar).

Debug con Eclipse

El contenido de la variable myvar es
0x0A000000 que en decimal es 10.

17

Memoria Dinámica
 PUNTEROS

Operaciones con punteros:

Alumno.cpp

Prueba.cpp

p1

Alumno1

numMatricula = 3041
nombre = Antonio

• p1 es la dirección de un objeto alumno
• *p1 es un objeto alumno
• (*p1).nombre es una variable miembro
• p1->nombre es una variable miembro

#include "Alumno.h"
#include <iostream>
using namespace std;
//constructor
Alumno::Alumno(int num, string nom){
numMatricula = num;
nombre = nom;
}
//destructor
Alumno::~Alumno() {
}

#include "Alumno.h"
#include <iostream>
using namespace std;
int main(void){
//se crean objetos de la clase alumno
Alumno a1 (3041, "Antonio");
Alumno a2 (2054, "David");
cout << "nombre del primer alumno " << a1.nombre << endl;
cout << "nombre del segundo alumno " << a2.nombre << endl;
Alumno *p1, *p2;
p1 = &a1;
p2 = &a2;
cout << "matricula primer alumno " << p1->numMatricula << endl;
cout << "matricula segundo alumno " << p2->numMatricula << endl;
}
18

Parámetros por Referencia
 Tipos no punteros
#include <iostream>
using namespace std;
void duplicate (int &a, int &b, int &c);
int main(void){
int x=1, y=3, z=7;
duplicate (x, y, z);
cout << "x=" << x << ", y=" << y << ", z=" << z << endl;
}
void duplicate (int &a, int &b, int &c) {
a*=2;
b*=2;
c*=2;
}

19

Parámetros por Referencia
 Tipos punteros

pAlumno1

void cambiarValorObjetoApuntado(Alumno *p, Alumno *newp);
int main(void){
//se crean objetos de la clase alumno
Alumno a1 (3041, "Antonio");
Alumno a2 (2054, "David");
Alumno *pAlumno1, *pAlumno2;
pAlumno1 = &a1; pAlumno2 = &a2;
cout << "matricula primer alumno " << pAlumno1->numMatricula << endl;
cout << "matricula segundo alumno " << pAlumno2->numMatricula << endl;

p

Alumno1
pAlumno2

3041
3041
Antonio
Antonio

pnew

Alumno2

cambiarValorObjetoApuntado(pAlumno1, pAlumno2);
cout << "matricula primer alumno " << pAlumno1->numMatricula << endl;

2054
David

}
//se pasa por valor (una copia) la dirección de memoria a la que apunta p
//se pasa por referencia el objeto apuntado
void cambiarValorObjetoApuntado(Alumno *p, Alumno *newp){
p->numMatricula = 0;
p = newp; //No surte efecto. El valor de la dirección NO se modifica
}

p

pAlumno1

Alumno1
0
Antonio

20

Parámetros por Referencia
 Tipos punteros

p/pAlumno1

void cambiarDireccionObjetoApuntado(Alumno *&p, Alumno *newp);
int main(void){
//se crean objetos de la clase alumno
Alumno a1 (3041, "Antonio");
Alumno a2 (2054, "David");
Alumno *pAlumno1, *pAlumno2;
pAlumno1 = &a1; pAlumno2 = &a2;
cout << "matricula primer alumno " << pAlumno1->numMatricula << endl;
cout << "matricula segundo alumno " << pAlumno2->numMatricula << endl;

Alumno1
pAlumno2

3041
Antonio

pnew

cambiarDireccionObjetoApuntado(pAlumno1, pAlumno2);
cout << "matricula primer alumno " << pAlumno1->numMatricula << endl;
}

Alumno2
2054
David

//se pasa por referencia la dirección de memoria a la que apunta p
void cambiarDireccionObjetoApuntado(Alumno *&p, Alumno *newp){
p = newp; //Sí surte efecto. El valor de la dirección se modifica
}

p / pAlumno1

21

Entrada/salida
 Librería iostream
 Entrada:
 Representa al dispositivo de entrada por defecto, generalmente el teclado.
 El stream asociado es cin, de la clase istream.
 Salida:
 Representa al dispositivo de salida por defecto, generalmente la pantalla.
 El stream asociado es cout, de la clase ostream.
 Salida de error:
 Representa al dispositivo de salida por defecto donde se envían los mensajes de
error, generalmente la pantalla.
 Los streams asociados son cerr y clog, de la clase ostream.
 Operadores:
 Inserción <<
 Extracción >>

22

Salida: cout

 El objeto cout puede enviar a la pantalla cualquier

combinación de variables, cadenas y expresiones aritméticas.
 Caracteres especiales:
 \n

\t

\\

\”

 Formateo de la salida:
 precision: número de cifras después de la coma
 width: número de caracteres mínimo del output
 fill: indica el carácter de relleno
 left: siguiente número en el extremo izquierdo
 right: siguiente número en el extremo derecho
 ios::fixed: formato de punto fijo
 ioss:showpoint: incluye el punto decimal en número de coma
flotante
23

Ejemplo

24

Entrada: cin
 Flujo estándar
 Operador >> sobrecargado para tipos estándar en c++ y

para leer cadenas.
 La lectura se interrumpe al encontrar el carácter nulo ('\0'),
un espacio en blanco (' '), o un salto de línea ('\n')

 get: lee un carácter
 getline: lee hasta el carácter delimitador

25

Tratamiento de ficheros
#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;

 Clases para ficheros:
 ofstream: abre ficheros para escritura
 ifstream: abre ficheros para lectura
 fstream: abre ficheros para lectura/escritura

int main () {
ofstream salida ("ficherito");
//FICHERO DE ESCRITURA
for (int i = 1; i < 20; i++)
salida << setw(20) << setiosflags(ios::left) << setfill('.') << "Lin. " << i << endl;
salida.close ();
ifstream lectura;
string s;
lectura.open ("ficherito");
while (getline (lectura, s))
cout << s << endl;
lectura.close ();
return 0;
}

//FICHERO DE LECTURA

26

Arrays (I)
 Declaración
const int TOTAL = 45;
float mediaCalificaciones [TOTAL];
float notasParciales [TOTAL] [2];

 Los subíndices comienzas en 0.
 Inicialización:
float altura [] = {1.8, 1.65, 1.74};
int matrizTemperaturas [7] [2] = {{0, 3}, {2,4}, {5,8}, {3,7}, {3,5}, {5,10}, {5,9} };
string nombres [] = {"Julio", "Tomás", "Virginia", "Santiago"};

28

Arrays (II)
 El nombre del array es un puntero constante al primer

elemento:

int array[10];
int *p; //puntero a entero
p = array; //asigna a p la dirección del primer elem de array
*p = 6;
//igual que array[0]=6
cout << *p << " at " << p << endl;
p++;
//suma a p sizeof(int) y lo posiciona en &array[1]
cout << *p << " at " << p;

29

Arrays (III)

 Arrays dinámicos: se reserva espacio de memoria en tiempo

de ejecución

int main () {
int n;
cout << "Tamaño del array: " << endl;
cin >> n;
int *miarraydinamico ;
miarraydinamico = new int [n]
for (int i = 0; i < n; i++)
miarraydinamico [i] = i;
for (int i = 0; i < n; i++)
cout << miarraydinamico[i] << " ";
cout << endl;
return 0;
}

30

Arrays (IV)

 Solo la primera dimensión de un vector n-dimensional

puede declararse de manera dinámica

int main () {
int n;
cout << "Tamaño de la matriz: " << endl;
cin >> n;
int **matriz = NULL;
//Matriz dinámica de n*n
matriz = new int *[n];
//Array de filas
for (int i = 0; i < n; i++)
matriz [i] = new int [n];
//Completo el vector
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
matriz [i] [j] = i*j;
cout << matriz [i] [j] << " ";
}
cout << endl;
}
return 0;
}
31