Upload
phungdat
View
216
Download
0
Embed Size (px)
Citation preview
El lenguaje C++
Isidro González Caballero
(Universidad de Oviedo)
Técnicas de Comp. en Física
Santander, 08/11/2010 1
Introducción
El C++ es un superconjunto del C
– Soporta tanto metodologías de programación estructurada
como OOP
– Tiene la capacidad de usar librerías C y FORTRAN
Características ajenas a la OOP y al C:
– Chequeo de tipos mejorado (más estricto)
– Constantes simbólicas (const) (chequeo de tipos constantes)
– Sustitución de funciones inline (eficiencia de ejecución)
– Argumentos por defecto (ahorro de código)
– Sobrecarga de funciones y operadores (los tipos derivados
tienen sintaxis iguales a los nativos)
– Manejo de memoria dinámica
– El tipo referencia (alias)
Compilar
g++ -o main.cc
Escribir, compilar, linkar, ejecutar
Código
(.cc, .C, .cpp…) #include <iostream>
int main() {
cout << “Hola mundo”
<< endl;
return 0;
}
Diseñar
Escribir
Fichero objeto
(.obj, .o)
Ejecutable
(a.out, .exe, …)
Ejecutar
./a.out
Linkar
g++ main.o
main.o
libMyLib.so
other.o
a.out
Compilación
Preprocesador
No son comandos C++…
– … pero están presentes en
cualquier compilador
Muy utilizadas en C…
– … suprimidas algunas en C++
Se escriben con el símbolo # al
comienzo
Es una especie de parser
Algunas posibilidades
Incluir código de otros ficheros
Remplazar variables o símbolos
– en gral. no necesario en C++
Trucos sucios
– no recomendable
Incluye cierta lógica
Compilar
g++ -o main.cc
Código
(.cc, .C, .cpp…) #include <iostream>
int main() {
cout << “Hola mundo”
<< endl;
return 0;
}
Fichero objeto
(.obj, .o)
main.o
libMyLib.so
other.o
Ficheros
intermedios
(.i, .ii) Preproceso
Directivas de preprocesador
#include ″header.h″
– Incluye el fichero header.h
#include <header.h>
– Idem para “ficheros estándar”… algo subjetivo
#define VAR value
– Reemplaza la secuencia VAR por value
#ifdef, #ifndef, #else, #endif
– Lógica para chequer el valor de variables
#pragma
– Mensajes al compilador. Poco utilizado
Tipos fundamentales
Nombre ¿Qué representa? Entero, real,
lógico
char Un carácter Entero
short int Un entero corto Entero
int Un entero Entero
long int Un entero con mayor rango de
validez
Entero
float Un real Real
double Un real de doble precisión Real
long double Un real de doble precisión y
mayor
Real
bool cierto (true) o falso (false) Lógico
unsigned
Declaraciones
Antes de utilizar una variable tenemos que declarar su tipo
Para las funciones debemos declarar su signatura y tipo de retorno
– La signatura está formada por el nombre de la función y el tipo de los argumentos que espera
Podemos inicializar una variable al declararla
No siempre una declaración reserva un espacio en memoria definición
char letra; //Declaración y definición de un caracter
int total = 10; //Decl., def. e inic. de un entero
double random(double seed); //Declaración de una función
Output básico
Debe incluirse el cabecero (header) iostream.h
Se utilizan los objetos
– cout para la salida estándar o
– cerr para los mensajes de error...
... seguido del operador << …
… y el mensaje de salida
#include <iostream.h> //Hoy en dia <iostream>
cout << "Hola\n";
cout << "La suma de 2 y 4 es " << 2+4 << endl;
cout << "El valor var=" << var << endl;
Funciones
Tienen un tipo de retorno (void si no devuelven nada)
Se debe especificar el tipo de cada uno de sus
parámetros (signatura)
El cuerpo de la función va entre llaves { }
La función principal del sistema es int main()
#include <iostream.h>
float cuadrado(float r); int main() {
cout << "El cuadrado de 7 es " << cuadrado(7);
return 0;
}
float cuadrado(float r) {
float c = r*r;
return c;
}
Ámbito (scope) y tiempo de vida
El ámbito es el espacio del programa en que
un nombre (variable) es válido
Normalmente es el espacio entre su
declaración y la siguiente llave cerrada, }
Las variables solo existen (ocupan espacio en
memoria) mientras su ámbito es válido
– Salvo las declaradas static que duran hasta el
final del programa
Aunque solo pueden ser utilizadas en el código dentro de
su ámbito
Tipos derivados, static, const...
Nombre/Símb ¿Qué representa? Delante/Detras
[] Array Detrás
* Puntero, posición en memoria En medio
& Referencia, alias de la var. En medio
struct Una estructura Delante
class Una clase Delante
static Ámbito del programa Delante
const No puede modificarse Delante
Tipos derivados, static, const...
//Punteros
int* ptrNumero; //Puntero a un entero
//Arrays
float reales[20]; //Un array de 20 floats
double punto[2] = {1.2, 3.4}; //Con inicializacion
//Struct
struct punto2D {short int x; short int y;};
//static
static int contador;
//const
const char la_letra_c = 'c';
const double pi = 3.1415926;
Ejercicio 1: Programa
#include <iostream>
using namespace std; //Necesario para cout y endl
double cuadrado(double); //Declaramos funcion
int main() { //Funcion principal
int siete = 7;
cout << "El cuadrado de " << siete << " es "
<< cuadrado(7) << endl;
const double pi = 3.1415926;
cout << "pi*pi = " << cuadrado(pi) << endl;
return 0;
}
double cuadrado(double r) {
double c = r*r;
return c;
}
[host] tar xvfz ejercicio1.tar.gz
[host] cd ejercicio1
[host] ls
ejercicio1.cpp
[host] g++ ejercicio1.cpp
[host] ls
ejercicio1.cpp a.out
[host] ./a.out
El cuadrado de 7 es 49
pi^2 = 9.8696
[host] g++ ejercicio1.cpp –o ejercicio1.exe
[host] ls
a.out ejercicio1.cpp ejercicio1.exe
[host] ./ejercicio1.exe
El cuadrado de 7 es 49
pi^2 = 9.8696
Ejercicio 1: Compilar y ejecutar
Descomprimimos
el fichero tras
descargarlo
Compilar y linkar. El
resultado es…
Ejecutar Compilar y linkar
elegiendo el
fichero de salida
Ejecutar
Ejercicio 2: Varios ficheros
Descargar y descomprimir ejercicio2.tar.gz
Los ficheros de código: – cuadrado.h: Declaración de la función double cuadrado (double)
– cuadrado.cpp: Implementación
– ejercicio2.cpp: Función main
El script compila.csh compila y enlaza todo: – Crea los ficheros objeto cuadrado.o y ejercicio2.o
– Enlaza los objetos en el ejecutable ejercicio2.exe
[host] g++ -c -o cuadrado.o cuadrado.cpp
[host] g++ -c -o ejercicio2.o ejercicio2.cpp
[host] g++ -o ejercicio2.exe cuadrado.o ejercicio2.o
Operadores aritméticos
Operador Función Uso
= asignación int i = 7;
* multiplicación double r = 3.5 * i;
/ división double t = r / 1.2;
% modulo (resto) i = 21 % 6; // i = 3
+ suma double rt = r + t;
- resta r = rt – t;
++,-- incremento int i = 0;
int j = i++; //j = 0
int k = --i; //k = 0
+=,-=,
*=,/=
opera y asigna r += 2.6; //r = r + 2.6
r *= 2.6; //r = r * 2.6
Operadores lógicos
Operador Función Uso
< menor que i < 5
<= menor o igual que r <= 5
> mayor que i > 5
>= mayor o igual que i >= 5
== igualdad i == 5
!= desigualdad i != 5
! NOT lógico !true; //false
&& Y lógico i < 5 && j > 4
|| O lógico i < 5 || j > 4
Control de flujo: if-then-else
Ejecución condicional
Sintaxis simple:
– Si la expresión lógica es cierta se ejecuta sentencia1
Sintaxis completa:
– Si la expresión lógica es falsa se ejecuta la sentencia2
Si hay más de una sentencia a ejecutar por caso se meten entre { }
if (expresión lógica) sentencia1;
if (expresión lógica) sentencia1;
else
sentencia2;
if-then-else ejemplo
int mifuncion(); //Una funcion que devuelve un numero
entero
....
....
int i = mifuncion();
cout << "El valor devuelto por mifuncion es ";
if (i < 0)
cout << "negativo" << endl;
else if (i > 0)
cout << "positivo" << endl;
else
cout << "nulo" << endl;
Control de flujo: switch
Ejecución condicional
Se trata de evitar if-then-else encadenados
Sintaxis:
switch (variable) case (valor1):
setencia1;
break;
case (valor2):
setencia2;
break; ...
default:
setenciadef;
break;
Se ejecuta si variable == valor1
Se ejecuta si variable == valor1
Se ejecuta si no se ha ejecutado ninguna
de las anteriores
switch: ejemplo
int mifuncion(); //Una funcion que devuelve un numero
entero
....
....
int i = mifuncion();
cout << "El valor devuelto por mifuncion es ";
switch (i) {
case (0):
cout << "nulo" << endl;
break;
case(1):
cout << "uno" << endl;
break;
default:
cout << "otro valor" << endl;
}
Control de flujo: for
Iteraciones
Sintaxis:
– La inicialización (de un contador) solo se ejecuta la
primera vez que entra en el bloque
– La parada es una expresión lógica
Mientras sea cierta se sigue iterando
Cuando sea falsa se sale del bucle
– La acción (normalmente el incremento de un
contador) se ejecuta al comienzo de cada iteración
for (inicialización; parada; acción) sentencia;
Control de flujo: while y do-while
Sintaxis:
– Sólo si expresión es cierta se ejecuta una nueva iteración
– La comprobación se hace al inicio
Sintaxis
– Sólo si expresion es cierta se ejecuta una nueva iteración
– La comprobación se hace al final: La sentencia se ejecuta al
menos una vez!
while (expresion) sentencia;
do
sentencia;
while (expresion)
Ejemplo Iteración: Tabla del 3
cout << "Tabla de multiplicar del 3..." << endl;
for (int i = 1; i <= 10; i++) {
cout << "3 * " << i << " = " << 3 * i << endl;
}
int i = 1;
while (i <= 10) {
cout << "3 * " << i << " = " << 3 * i << endl;
i++;
}
int i = 1
do {
cout << "3 * " << i << " = " << 3 * i << endl;
i++;
} while (i <= 10)
Argumentos por valor y por referencia
Por valor A la función le llega una
copia en memoria de la variable que pasamos
Cuando la función termina esa copia se destruye
Las modificaciones del valor de la variable dentro de la función no salen al exterior
Es la forma por de pasar variables por defecto
Por referencia A la función le llega la
dirección de memoria de la variable que pasamos
– ¡No hay copia!
Cuando la función termina no se destruye ese espacio en memoria
Las modificaciones del valor de la variable sí salen al exterior de la llamada
Se utiliza & para indicarlo
Nota: Para comprimir un directorio en un solo fichero y poder enviarlo
por correo
Ejercicios:
Hacer un programa que calcule los cuadrados de los 10 primeros números aprovechando el código del ejercicio2
Hacer un programa que calcule el cuadrado de un numero cualquiera (usar cin)
Hacer un programa que muestre los 10 primeros números primos
double variable;
cout << “Introduce un numero real: “ << endl;
cin >> variable;
[host] tar cvfz ficherocomprimido.tar.gz directorio
Clases
class MiClase {
public:
MiClase(...); //Constructor
~MiClase(); //Destructor
//Metodos
int metodo1(...); //ejemplo
protected:
//Data members
int dato1; //ejemplo
float dato2; //ejemplo
};
MiClase es el nombre de la clase
Visibilidad:
• public: Visible para cualquier
otra clase
• protected: Visible solo para
subclases
• private: Visible solo para la
propia clase
Datos: Definen el estado de los
objetos de esta clase
Clases
class MiClase {
public:
MiClase(...); //Constructor
~MiClase(); //Destructor
//Metodos
int metodo1(...); //ejemplo
protected:
//Data members
int dato1; //ejemplo
float dato2; //ejemplo
};
Constructor:
• Puede haber varios
• Puede tomar argumentos
• Es la función que se ejecuta
cuando se crea un objeto
Destructor:
• Solo puede haber uno
• No toma argumentos
• Es lo último que se ejecuta
cuando se destruye un objeto
Métodos: Definen el
comportamiento de una clase
Objetos de una clase
Los objetos de una clase se declaran: – Como cualquier variable si hay constructor que no
toma argumentos
– Pasándole los parámetros del constructor a la variable como si fuera una función
Los métodos se acceden usando el operador punto (.) (o flecha, ->, para punteros)
class MiClase {
public:
MiClase(int a=0);
bool foo() {return true;}
};
MiClase miobj; //== miobj(0)
MiClase miobj3(3);
MiClase* ptrmiobj;
miobj.foo(); //true
ptrmiobj->foo();
(*ptrmiobj).foo();