Recordando C 1 © Alexis Quesada Arencibia – José Miguel Santos Espino Sistemas Operativos Características n Lenguaje de programación estructurada n Extremadamente simple n Permite generar código pequeño y eficiente n n Poca comprobación de errores en el compilador (ej. tipado débil, punteros) Impone poca disciplina, da mucha libertad al programador 2 © Alexis Quesada Arencibia – José Miguel Santos Espino Sistemas Operativos Estructura general de un programa //cabeceras #include<stdio.h> /* declaraciones de funciones */ //definiciones (cuerpos de funciones) //declaraciones de variables globales main() { //cuerpo del main } //otras definiciones de funciones 3 © Alexis Quesada Arencibia – José Miguel Santos Espino Sistemas Operativos Generación de un programa ejecutable cabeceras hola.h Fuente hola.cc stdio.h math.h preprocesador compilador Objeto hola.o bibliotecas libm.o libc.o enlazador Ejecutable hola 4 © Alexis Quesada Arencibia – José Miguel Santos Espino Sistemas Operativos Elementos de programación n Estructuras de datos n n n n n literales, tipos básicos, tipos enumerados tipos estructurados (struct, union) punteros y vectores Tipos nuevos : typedef Construcciones algorítmicas n n n construcciones condicionales (if, switch) construcciones iterativas (while, for, do...while) subrutinas (funciones) 5 © Alexis Quesada Arencibia – José Miguel Santos Espino Sistemas Operativos Variables n tipo nombre {, nombre}; n tipo nombre=valor_inicial; n ¡OJO!, distingue mayúsculas int una=1, otra, Una, UNA=3; long int entero_largo; unsigned int entero_sin_signo; 6 © Alexis Quesada Arencibia – José Miguel Santos Espino Sistemas Operativos Expresiones, operadores n n Expresión: operación sobre literales o variables que devuelve un resultado Las asignaciones son expresiones n n c=20-(b=2*(a=5)+4); Operadores n n n n n Aritméticos: + - * / Manip. de bits: | & ^ Lógicos: == != > < Pre-post in/decremento: Asignacion compuesta: n n % ~ << >> >= <= || && ! x++, x--,++x, --x a+=3 es como a=a+3 a*=x+1 es como a=a*(x+l) 7 © Alexis Quesada Arencibia – José Miguel Santos Espino Sistemas Operativos 8 Más sobre expresiones n n n n No se detectan desbordamientos En las divisiones, si los operandos son enteros, se devuelve solo el cociente (sin decimales) Las operaciones booleanas devuelven un cero o un uno, en C no existe el tipo booleano Conversión de tipos: (nuevo_tipo)expresion n Por ejemplo, se puede utilizar para forzar que una división de enteros se realice en coma flotante © Alexis Quesada Arencibia – José Miguel Santos Espino Sistemas Operativos Vectores y matrices n tipo variable[dimension1][dimension2]... n Los índices van de 0 a N-1 n ¡No se comprueban accesos fuera de rango! int vector[10]; float M[3][3]; int vector2[3]={1,2,3}; int M2[2][3]={{1,2,3},{4,5,6},{7,8,9}}; vector[5]=1; vector[0][2]=18.5; 9 © Alexis Quesada Arencibia – José Miguel Santos Espino Sistemas Operativos 10 Cadenas n n n Vectores de caracteres: char cadena[5]; Toda cadena termina en un carácter nulo (‘\0’ o simplemente 0) El C no tiene operaciones con cadenas; se usan funciones de la biblioteca <string.h> n n n n strcpy(s1,s2); (s1:=s2) strcat(s1,s2); (s1:=s1 & s2); strcmp(s1,s2); (compara s1 con s2) strlen(s); (longitud de s) © Alexis Quesada Arencibia – José Miguel Santos Espino Sistemas Operativos Funciones n tipo nombre_función(parámetros) n Se sale con una sentencia return n n n Los procedimientos son las “funciones void” (void funcion(){...}) Los parámetros siempre se pasan por valor (el paso por referencia se hace mediante punteros) Si no tiene argumentos se declaran con void (sólo en C; en C++ sólo paréntesis) 11 © Alexis Quesada Arencibia – José Miguel Santos Espino Sistemas Operativos Funciones n n En la llamada siempre se usan paréntesis En la llamada no es obligatorio recoger el valor n En C no se permiten anidar funciones n Si se permiten llamadas recursivas 12 © Alexis Quesada Arencibia – José Miguel Santos Espino Sistemas Operativos Ambito y existencia n n n n Un identificador (tipo, variable o función) puede ser global o local Las funciones sólo pueden ser globales Variables static (mantienen su valor en sucesivas llamadas) Modificador “extern” 13 © Alexis Quesada Arencibia – José Miguel Santos Espino Sistemas Operativos Punteros n n Un puntero es un valor que representa una dirección de memoria donde hay un dato de un determinado tipo Declaración n n tipo *puntero; Operadores n n Dirección de una variable: &var; desreferenciar un puntero: *ptr; 14 © Alexis Quesada Arencibia – José Miguel Santos Espino Sistemas Operativos Punteros int *ptr; int var=15; ptr=&var; *ptr=33; int vec[30]; *(vec+2)=5; //vec[2]=5 struct cosa *ptr; struct cosa A; ptr=&A; ptr->campo=xxx; //(*ptr).campo=xxx 15 © Alexis Quesada Arencibia – José Miguel Santos Espino Sistemas Operativos Punteros //paso de parámetros por referencia void duplica(int *variable) { *variable=*variable*2; } int a=3; duplica(&a); // a valdrá seis //memoria dinámica ptr=(int*)malloc(100^*sizeof(int)) free(ptr) 16 © Alexis Quesada Arencibia – José Miguel Santos Espino Sistemas Operativos Entrada / Salida n n printf, scanf (%d, %c, %f, %s) Para la lectura de cadenas, scanf CASI NUNCA FUNCIONA; mejor utilizar n gets, fgets printf(“El doble de %d es %d\n”,x,2*x); scanf(“%d %d”, &x,&y); gets(cadena); fgets(cadena,80,stdin); 17 © Alexis Quesada Arencibia – José Miguel Santos Espino Sistemas Operativos Preprocesador n Órdenes al preprocesador # n n n n n n n #include <> o “” #define #undef #ifdef, #ifndef, #if #elif #else, #endif 18 Salto a C++ 19 © Alexis Quesada Arencibia – José Miguel Santos Espino Sistemas Operativos Características básicas n Entrada/salida n cin >>, cout << #include<iostream.h> main() { int i; cout << “Esto es C++.\n”; cout << “Escriba un número: “; cin >> i; cout << “El número escrito es” << i << “\n”; } 20 © Alexis Quesada Arencibia – José Miguel Santos Espino Sistemas Operativos 21 Características básicas n Comentarios n n A diferencia de C, las declaraciones de variables no tienen que estar necesariamente al comienzo del bloque n n /* */ y además // for(int i=0;i<N;i++) Todas las funciones tienen que ser declaradas (en C los prototipos eran opcionales) © Alexis Quesada Arencibia – José Miguel Santos Espino Sistemas Operativos 22 Clases n n Es la herramienta que C++ nos proporciona para definir tipos abstractos de datos (encapsulamiento) Consiste en: n n n n Unas estructuras de datos Conjunto de operaciones asociadas a tales estructuras (funciones miembro o métodos) Una clase puede contener partes privadas y partes públicas Por defecto, todos los elementos definidos en una clase son privados © Alexis Quesada Arencibia – José Miguel Santos Espino Sistemas Operativos Clases class nombre_clase { datos y funciones privados public: datos y funciones públicos } [lista de nombres de objetos]; tipo nombre_clase::nombre_funcion(params) { cuerpo de la función { ... 23 © Alexis Quesada Arencibia – José Miguel Santos Espino Sistemas Operativos Clases #include <iostream.h> class ejemplo { int p; public: void dar_valor(int val); void mostrar_valor(); }; void ejemplo::dar_valor(int val) { p=val; } void ejemplo::mostrar_valor() { cout << p << “\n”; } main() { ejemplo ob; ob.dar_valor(5); ob.mostrar_valor(); } 24 © Alexis Quesada Arencibia – José Miguel Santos Espino Sistemas Operativos Clases n n n Es muy normal que una parte de un objeto necesite una inicialización antes de poder usarse C++ permite que los objetos se inicialicen ellos solos cuando se crean Esta inicialización automática se realiza a través del uso de una función constructora o constructor 25 © Alexis Quesada Arencibia – José Miguel Santos Espino Sistemas Operativos Clases n El constructor es una función miembro especial que tiene el mismo nombre que la clase n n Se llama al constructor cuando se crea el objeto (al declararlo o crearlo dinámicamente) El complemento del constructor es el destructor: n Se llama al destructor cuando se destruye el objeto (en el caso de objetos locales, al salir del bloque y en el caso de objetos globales al terminar el programa) 26 © Alexis Quesada Arencibia – José Miguel Santos Espino Sistemas Operativos Clases #include <iostream.h> class ejemplo { int p; public: ejemplo(int val=0); ~ejemplo(); void dar_valor(int val); void mostrar_valor(); }; void ejemplo::dar_valor(int val) { p=val; } void ejemplo::mostrar_valor() { cout << p << “\n”;} void ejemplo::ejemplo(int val) { p=val; cout << “Constructor”; } void ejemplo::~ejemplo() { cout << “Destructor”; } main(){ ejemplo ob(2),ob2; ob.mostrar_valor(); ob.dar_valor(5); ob.mostrar_valor(); ob2.mostrar_valor(); } 27 © Alexis Quesada Arencibia – José Miguel Santos Espino Sistemas Operativos 28 Funciones de línea n n Es una función que se expande en el punto donde llama en vez de ser llamada Formas de crear una función de línea: n n Modificador inline Definiendo el código de una función miembro dentro de la definición de la clase © Alexis Quesada Arencibia – José Miguel Santos Espino Sistemas Operativos Funciones de línea #include <iostream.h> class ejemplo { int p; public: ejemplo(int val) {p=val;} ~ejemplo(){cout << “Destructor”;} void dar_valor(int val) {p=val}; void mostrar_valor() {cout <<p <<“\n”;} }; main() { ejemplo ob,ob2; ob.mostrar_valor(); ob2.mostrar_valor(); } #include <iostream.h> inline int f(params) { ... } main() { f(params); } 29 © Alexis Quesada Arencibia – José Miguel Santos Espino Sistemas Operativos 30 Paso de objetos a funciones n n Un objeto se puede pasar a una función de la misma forma que cualquier otro tipo de dato Paso por valor n Lo que se pasa es una copia del objeto © Alexis Quesada Arencibia – José Miguel Santos Espino Sistemas Operativos Paso de objetos a funciones #include <iostream.h> void f(Objeto x); class Objeto { int p; public: Objeto(int val) {p=val;} ~Objeto(){cout << “Destructor”;} void dar_valor(int val) {p=val}; void mostrar_valor() {cout <<p <<“\n”;} }; void f(Objeto x) { x.dar_valor(5); x.mostrar_valor(); } main() { ejemplo ob(2); f(ob); ob.mostrar_valor(); } 31 © Alexis Quesada Arencibia – José Miguel Santos Espino Sistemas Operativos Arrays de objetos n Se pueden crear array de objetos de la misma manera que se crean arrays de cualquier otro tipo de datos main() { Objeto ob[5]={Objeto(30), Objeto(2), Objeto(33), Objeto(40), Objeto(5)}; ob[1].mostrar_valor(); } 32 © Alexis Quesada Arencibia – José Miguel Santos Espino Sistemas Operativos Punteros a objetos n Referencia a un objeto n n Directamente Usando un puntero a ese objeto main() { Objeto ob(1), *p; ob.mostrar_valor(); p=&ob; p->dar_valor(4); p->mostrar_valor(); } main() { Objeto ob[2], *p; ob[0].dar_valor(1); ob[1].dar_valor(2); p=&ob[0]; (p++)->mostrar_valor(); p->mostrar_valor(); } 33 © Alexis Quesada Arencibia – José Miguel Santos Espino Sistemas Operativos 34 Otras características n Inicialización dinámica n n En C++, las variables locales y globales pueden inicializarse en tiempo de ejecución Cada vez que se invoca una función miembro, se pasa automáticamente un puntero al objeto que la invoca n Se puede acceder a este puntero usando this n Asignación dinámica usando new y delete n ASSERT(condición a cumplir); n n Si no se cumple la condición (0) veremos un mensaje: Assertion failed: file <archivo>, line <numlinea> © Alexis Quesada Arencibia – José Miguel Santos Espino Sistemas Operativos Ejemplos class Objeto { int p; public: Objeto(int val) {this->p=val;} ~Objeto(){cout << “Destructor”;} void dar_valor(int val) {this->p=val}; void mostrar_valor() {cout <<p <<“\n”;} }; gets(cadena) int k=strlen(cadena); scanf(“%d”,x); Objeto ob(x); assert(p>=0); int *p; p=new int; if (!p) { cout <<“fallo”;} *p=20; delete p; p=new int(23); p=new int[10]; for(int i=0;i<10;i++) { p[i]=0;} delete [10]p; p=new Objeto(2); p->mostrar_valor(); 35 © Alexis Quesada Arencibia – José Miguel Santos Espino Sistemas Operativos Compilación n Compilación programa sencillo hola.cc $g++ -c hola.cc $g++ -o hola hola.o // en un solo paso $g++ -o hola hola.cc 36 © Alexis Quesada Arencibia – José Miguel Santos Espino Sistemas Operativos Ejercicio n Realizar un pequeño programa que maneje una pila de elementos enteros (empleando para la pila un vector) 37