Lenguaje y Programación II Unidad I Tema 1: El Lenguaje de Programación C Ing. Luis E. Padilla M. [email protected] Introducción Características generales de C Origen del lenguaje C Un primer programa Características generales de C Ventajas C es un lenguaje de programación de propósito general Permite la recursividad. Utilización simple de las primitivas del SO Intimamente relacionado con UNIX Juego de operadores muy rico Concisión de los programas Alta expresividad Compilador y código generado son rápidos y compactos Portabilidad: estandar ANSI Características generales de C Inconvenientes Lenguaje debilmente tipado Tipos demasiado próximos a la máquina Control de tipo poco severo No dispone de gestor de memoria integrado ni de instrucciones de E/S Se usan funciones de biblioteca Es fácil escribir programas poco legibles Origen del lenguaje C • Los acontecimientos claves: Un primer programa Editar, compilar y ejecutar un programa Editar fichero fuente con nombre terminado en .c, usando un editor de textos (vi, emacs, jed, joe, textedit, ...) vi programa.c Compilar el programa con cc: cc programa .c cc -o programa programa.c Ejecutar: a.out programa El modelo de compilación de C Editor Preprocesador Compilador Enlazador Disco Disco Disco Disco Memoria principal El programa se crea en el editor y se almacena en disco El programa preprocesador procesa el código El compilador crea el código objeto y lo almacena en disco El enlazador relaciona el código objeto con la bibliotecas, crea a.out y lo almacena en disco Cargador El cargador coloca el programa en memoria Disco CPU Memoria principal La CPU toma cada instrucción y la ejecuta, posiblemente almacena nuevos valores de datos mientras el programa se ejecuta Ejemplo: roman.c ... y hablando de programas poco legible... Elementos fundamentales del lenguaje Identificadores Tipos de datos Constantes y variables Operadores, expresiones y sentencias Procedencia y asociatividad Conversión de tipos Identificadores Identificador: combinación de letras, números y guiones de subrayado que no empiezan por número. Como en UNIX, las mayúsculas minúsculas son distintas. Palabras claves en minúscula. Tipos de datos Tipos fundamentales: char, int, float, double, void Modificadores: short, long, unsigned, signed Rango dependiente de implementación: Consultar limits.h y float.h Definición de tipos: typedef tipo nombre_de_tipo, typedef unsigned short int UNSHORT; Constantes y Variables Constantes Enteras: Reales: Carácter: Cadena: 19, -213, 3, 023, 0xA, 0xff .7, 4.7, -5.65, 4e3, -7.5E-2 'a', 'Z', '\n', '\32' “Cadena”, “Fin\n\n” Las variables pueden ser declaradas... Fuera de funciones: variables globales Dentro de una función: variables locales En la cabecera de una función: parámetros formales de la función (también son variables locales) Constantes y Variables Declaración de variables: tipo var1, var2, ... , ; int i, j, k; unsigned char a; unsigned long int m,n; Inicialización en la declaración int a = 0, k = 100; Modificador de acceso const (ANSI) const int x = 20; const char a = 'A'; Operadores, expresiones y sentencias Una expresión se construye mediante la combinación de expresiones y operadores. La expresión más simple puede ser una constante, una variable o una función. Una expresión acabada en ; se convierte en sentencia. Una secuencia de sentencias dentro de llaves {} forma una sentencia. Operadores Operadores aritméticos + * / % -++ Sustracción y signo unario Adición Multiplicación División (entera o real) Modulo (resto de la división entera) Pre o Post decremento Pre o Post incremento Operadores Operadores relacionales > Mayor que >= < <= Mayor o igual que Menor que Menor o igual que == Igual != Distinto Operadores relacionales Falso: 0 (cero) Cierto: distinto de 0 Operadores Operadores lógicos && || ! Y lógico O lógico Negación Operadores Operadores de manejo de bits & | ^ ~ << >> AND bit a bit OR Inclusivo bit a bit OR exclusio (XOR) bit a bit Complemento a 1 unario Desplazamiento a la izquierda Desplazamiento a la derecha Operadores Operador de asignación = operador= Asignación Asignación especial Operadores Operador condicional exp1 ? exp2 : exp3 Se evalúa como exp2 si exp1 es cierto o como exp3 en caso contrario. Operadores Otros operadores & * [] sizeof() ' . -> Dirección de un objeto (unario) Direccionamiento indirecto (unario) Direccionamiento indexado Da la talla de la variable o el tipo entre paréntesis Sirve para reunir varias expresiones en una instrucción Da acceso a los campos de las estructuras Idem de estructuras accedidas por punteros Precedencia y asociatividad Precedencia (mayor arriba) y asociatividad Conversión de tipos Cuando en una expresión aparecen operandos de distintos tipos... Conversión automática sin perdida de información. Los datos se convierte al más general (char a int, int a float, etc) int i = 20; float f; f = i * 3.1416; Conversión explícita o type casting Obligamos a una expresión a evaluarse con un tipo concreto x = (unsigned int) (y/65536) % 32768; Estructuras de control Estructuras de selección Estructuras de repetición Control en las estructuras de repetición Estructuras de selección Estructuras de selección Estructuras de repetición Estructuras de repetición Estructuras de repetición Control en las estructuras de repetición break Finaliza el bucle (o bloque switch) continue Salta una iteracción del bucle Ejemplo 2.- Escriba un programa en C que imprima la tabla correspondiente Fahrenheit a Celsius. Formula: °C = (5/9) (°F-32) La tabla resultante debe ser parecida a la siguiente: Ejemplo 0 -17 20 -6 40 4 60 15 80 26 100 37 120 48 140 60 160 71 180 82 200 93 220 104 240 115 260 126 280 137 300 148 Ejercicio 1.- Escriba un programa que imprima la tabla correspondiente Celsius a Fahrenheit. 2.- Modifique el programa de temperatura resuelto en clase de manera que escriba la tabla en orden inverso, esto es, desde 300 grados hasta 0. Tip: Use la estructura repetitiva for. Investigar: Estructura de un programa en C Componentes de un programa C. Subprogramación. Validez de las variables. El preprocesador. Estructura de un programa en C Componentes de un programa C Subprogramación Validez de las variables El preprocesador Componentes de un programa C Un programa está formado por: Comandos del preprocesador (líneas que comienzan por #) Definiciones de tipos Prototipos de funciones Declaración de variables Funciones Subprogramación A nivel de tratamiento, un programa está compuesto por un grupo de funciones, todas ellas en el mismo nivel. La ejecución de un programa empieza por la función main(). La comunicación entre funciones se efectúa: Mediante el acceso a variables globales. Mediante el paso de parámetros (siempre por valor). Mediante el valor de retorno de la función. Declaración de funciones Declaración clásica (K & R) (evitar su uso) Declaración de funciones Declaración moderna (ANSI): Protótipo de una función: Llamada a una función Llamada a una función El paso de parametros en C es siempre por valor. Los valores 5 y 15 son copiados en el instante de la invocación de la función media(). El valor 10 es devuelto como resultado de la invocación al finalizar la ejecución de la función media(). Por tanto, la expresión media (a,b) se evalúa con el valor 10. Funciones void Las funciones void permiten definir funciones que no devuelven nada. El tipo void también permite declarar funciones que no admiten nada como argumento. Validez de las variables Variables externas (extern) El compilador no asigna espacio de almacenamiento para las variables declaradas como extern., permitiendo así utilizar en un fichero variables declaradas en otro: Fichero 1: long costeTotal; Fichero 2: extern long costeTotal; Variables automáticas (auto) Las variables locales son auto por defecto. Dejan de existir cuando acaba la función donde están definidas. Variables estáticas (static) Son variables locales que no dejan de existir cuando acaba la ejecución de la función en la que están definidas y , por tanto, recuerdan el valor que tenían en la anterior invocación. Variables registro (register) Se almacenan en registros internos de la CPU. Tareas del preprocesador Sustitución simbólica Inclusión de ficheros Compilación condicional Tareas del preprocesador #if !defined (HDR) #define HDR /* el contenido de hdr.h va aquí */ #endif #if SYSTEM == SYSV #define HDR “sysv.h” #elif SYSTEM == BSD #define HDR “bsd.h” #elif SYSTEM == MSDOS #define HDR “msdos.h” #else #define HDR “msdos.h” #endif #include HDR #ifndef HDR #define HDR /* contenido de hdr.h va aquí */ #endif La compilación separada Resulta conveniente, en general, escribir un programa en varios ficheros. Un único fichero es considerado como principal y en él se implementa la función main(). Los demás ficheros deben ir en parejas de fichero-cabecera / fichero-implementación. En el ejemplo, principal.c es el fichero principal, biblioteca.h es un fichero de cabecera y biblioteca.c es un fichero de implementación. La compilación separada: un ejemplo La compilación separada: generación del fichero ejecutable Para conseguir el fichero ejecutabledel ejemplo anterior, podemos invocar en UNIX el comando gcc: Investigar: Tipos estructurados de datos en C: Arrays y strings. Estructuras y uniones. Tipos enumerados. Investigar: Punteros o Apuntadores en C: ¿Qué es un puntero? Punteros y funciones Punteros y arrays Punteros y estructuras Memoria dinámica Arrays de punteros Errores típicos Ejemplo: estrcutura dinámica pila de enteros