Lenguaje C (pdf)

61,744 views

Published on

0 Comments
15 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
61,744
On SlideShare
0
From Embeds
0
Number of Embeds
2,200
Actions
Shares
0
Downloads
1,671
Comments
0
Likes
15
Embeds 0
No embeds

No notes for slide

Lenguaje C (pdf)

  1. 1. Lenguaje C Copyleft (c) 2006, Jose Daniel Gutiérrez Porset josedaniel.gutierrez@ehu.es
  2. 2. Licencia de Uso Acerca de este documento Copyright (c) 2006, Jose Daniel Gutiérrez Porset josedaniel.gutierrez@ehu.es Se otorga permiso para copiar, distribuir y/o modificar este documento bajo los términos de la Licencia de Documentación Libre de GNU en su versión 1.2 o cualquier otra versión posterior publicada por la Free Software Foundation, siendo todo él invariante. Una copia de la licencia está disponible en la web de la Free Software Foundation, dentro de la sección titulada GNU Free Documentation License. Este documento ha sido realizado íntegramente con software libre. 2
  3. 3. Índice ● Licencia de uso de este documento ● Introducción al lenguaje C ● El preprocesador ● Variables, constantes y literales ● Expresiones y Operadores ● Punteros ● Control de flujo ● Funciones ● Arrays ● Cadenas de caracteres ● Estructuras ● Tipos combinados ● Gestión de memoria dinámica ● Ficheros y streams 3
  4. 4. Introducción al lenguaje C Características generales ● Lenguaje compilado ● Lenguaje de nivel medio­bajo ● “case­sensitive” ● Especificaciones: – K&R (Dennis Ritchie and Brian Kernighan) – ANSI C (X3.159­1989) e ISO C – C99 ● Más información en: http://en.wikipedia.org/wiki/C_programming_language 4
  5. 5. Introducción al lenguaje C Fases vim, emacs, eclipse 1. Edición Editor nano, kate, gedit,... Fuente .h,.c Precompilador 2. Precompilación cpp Fuente precompilado 3. Compilación Compilador gcc Fuente GNU/Linux: .o compilado Ms: .obj 4. Enlazamiento o Linkado Librerías Enlazador Librería 1 ld Librería 1 Ejecutable Ms: .exe GNU/Linux: .a,.la,.so 5 Ms: .lib
  6. 6. Introducción al lenguaje C Edición de ficheros fuente ● Claridad y facilidad de lectura: – Usar indentaciones – Dejar espacios – Ejemplos de malas prácticas: http://www.es.ioccc.org/main.html ● Sintaxis de estructura correcta. Palabras reservadas. ● Tipos de errores y avisos: – Error de compilación: el compilador indica un error y no llega a  compilar el fuente – Warning: el compilador compila el fuente pero avisa de algo. – Error de ejecución – Errores de funcionalidad y/o diseño 6
  7. 7. Introducción al lenguaje C Estructura de un fichero fuente .c int main (void) 7
  8. 8. Introducción al lenguaje C Tipo de líneas de un fichero fuente .c ● Instrucciones de precompilador: # ● Comentarios – 1 sola línea: // – Más de 1 línea: entre /* y */ ● Sentencias simples acabadas en ; ● Líneas no acabadas en ; (ej. sentencias if de una línea). ● Bloques de sentencias entre { y } ● Líneas vacías 8
  9. 9. Introducción al lenguaje C Estructura de un fichero cabecera .h ● Símbolos y macros de preprocesador ● Declaraciones de estructuras, uniones y enumeraciones ● Declaraciones typedef ● Declaraciones de funciones externas ● Declaraciones de variables globales 9
  10. 10. El preprocesador Introducción ● Preprocesador = Precompilador  ● Usos: – Incluir ficheros externos en compilación. – Definir y reemplazar etiquetas y macros. – Realizar compilaciones condicionales. Ej. un único fuente compilable para más de un sistema operativo 10
  11. 11. El preprocesador Sintaxis ● Sintaxis: líneas comienzan por # Uso Sintaxis Inclusión de ficheros #include < > externos #include “ “ Definición de símbolos y #define macros #undef Condiciones #ifdef #ifndef #if expresión #elif expresión #else #endif Operadores para #if y #elif defined && || ● Algunos símbolos definidos: __DATE__, __FILE__,  __LINE__, __TIME__ 11
  12. 12. Sistemas numéricos y de caracteres Sistemas numéricos ● Conceptos: – Conjunto de símbolos=base – Tamaño de palabra. – Rango de valores representables en un sistema de base B con N  símbolos: ● Se pueden formar BN palabras ● Los valores van de 0 a BN­1 ● Desbordamientos u overflow. 12
  13. 13. Sistemas numéricos y de caracteres Sistemas numéricos ● Bases más empleadas: – Personas: decimal (base 10) – Ordenadores: ● binario (2): 0, 1. Bit y byte. Valores negativos: en C complemento a 2  (“rueda”, ej. 100 binario =­4 decimal, 111 binario=­1 decimal) ● hexadecimal (16): 0,1,...,9,A,B,C,D,E,F ● octal (8): 0, 1,...,7 ● Conversión entre sistemas (base 10 a binario y viceversa). 13
  14. 14. Sistemas numéricos y de caracteres Equivalencias ● 1 byte = 8 bits ● 1 K = 1024 ● 1 M = 1024 K ● 1 G = 1024 M 14
  15. 15. Sistemas numéricos y de caracteres Tabla ASCII de caracteres ● Representación de 128 caracteres con 7 bits. – 33 no imprimibles – 95 imprimibles. Ej. '0'=48,'A'=65.  !"#$%&'()*+,-./0123456789:;<=>? @ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_ `abcdefghijklmnopqrstuvwxyz{|}~ – No están ej. acentos ñ º ª ● Dualidad carácter – número y uso de tipo char 15
  16. 16. Variables, Constantes y Literales Variables y Constantes ● Variables y constantes: son representaciones de una  dirección de memoria en la que se guardará un dato o  conjunto de datos de un tipo concreto. ● Conceptos básicos: – Dirección de memoria. – Valor. Valor inicial. Cambio en tiempo de ejecución. – Ámbito de acceso o zona del programa de validez. 16
  17. 17. Variables, Constantes y Literales Declaración de variables y constantes ● Concepto de declaración: – Se reserva de espacio en memoria para almacenar el valor o  valores que representa. – Especificación del ámbito y el tipo. ● Es obligatorio antes del uso. ● Si son variables locales a una función, se suelen declarar al  principio de la misma (aunque no es estrictamente  obligatorio). 17
  18. 18. Variables, Constantes y Literales Declaración de variables y constantes ● Sintaxis para la declaración: [<modificador>] <tipo_dato> <nombre_var>; o bien: <tipo_dato> [<modificador>] <nombre_var>; ● Elementos: – 18
  19. 19. Variables, Constantes y Literales Identificadores ● Identificador o nombre ● Normas para identificadores: – 1er carácter: sólo ‘A’,…,’Z’, ’a’,…, ’z’, ‘_’, (‘$’ según versiones) – Resto de caracteres: ‘A’,…,’Z’, ’a’,…, ’z’, ‘0’,..., ‘9’, ‘_’, (‘$’ según  versiones) – No se permiten palabras clave de C ● Por convenio (no obligatorio): – Las variables se escriben en minúsculas – Las constantes se escriben en mayúsculas – Si constan de varias palabras, van separadas por _ 19
  20. 20. Variables, Constantes y Literales Tipos ● El tipo de un dato especifica: – La naturaleza o uso de los datos que representa – El nº de bytes que ocupa en memoria – El rango de valores que puede contener ● Los tipos de datos pueden ser: – Predefinidos o propios del lenguaje C – Combinados a partir de los definidos – Definidos por quien programa 20
  21. 21. Variables, Constantes y Literales Tipos de datos predefinidos en C ● Números enteros Palabra clave Tamaño (bytes) Rango char 1 [-128, 127] unsigned char 1 [0,255] short 2 (>=2 según S.O.) [-32.768, 32.767] unsigned short 2 (>=2 según S.O.) [0, 65.535] int 4 (>=2 según S.O.) [-2.147.438.648, 2.147.438.647] unsigned int 4 (>=2 según S.O.) [0, 232-1] long 4 (>=4 según S.O.) [-2.147.438.648, 2.147.438.647] unsigned long 4 (>=4 según S.O.) [0, 232-1] ● Números reales Palabra Tamaño Rango clave (bytes) float 4 [-3,4 * 1038, -1,18 * 10-38] 0 [1,18 * 10-38, 3,4 * 1038] double 8 [-1,79 * 10308, -2,23 *10-308] 0 [1,79 * 10-308, 2,23 * 10308] long double 12 (Para ver los rangos, mirar /usr/include/limits.h) 21
  22. 22. Variables, Constantes y Literales Tipos de datos predefinidos en C ● Otros Palabra clave Tamaño (bytes) struct depende union depende [] depende * 4 (según S.O.) (bitfields) depende enum depende – Nota: void no representa un tipo como tal pero aplica a: ● Funciones que no devuelven nada ● Argumento para funciones que no tienen parámetros ● Punteros 22
  23. 23. Variables, Constantes y Literales Modificadores ● Elemento sintáctico para indicar características como: – Ámbito. Si no se indica nada, en una declaración dentro de una  función indica ámbito local, y fuera de una función indica ámbito  global. – Si es constante o variable. Si no se indica nada es variable (no  constante) 23
  24. 24. Variables, Constantes y Literales (Modificadores) ● const: – El valor es una constante en tiempo de ejecución – Ámbito: idem que lo indicado ● static – En una declaración dentro de una función indica ámbito local, y: ● El valor se mantiene entre llamadas a la función. ● El valor se inicializa a 0. – En una declaración fuera de una función, indica ámbito de  módulo. ● extern: Se emplea para referenciar a variables y constantes  globales declaradas en otro fichero. 24
  25. 25. Variables, Constantes y Literales Clasificación de variables ● Variables y Constantes locales – Ámbito: la función en la que se declaran – Valor inicial: si se usa static 0 y si no indeterminado ● Parámetros de una función – Ámbito: la función en la que se declaran – Valor inicial: el valor de la llamada 25
  26. 26. Variables, Constantes y Literales (Clasificación de variables) ● Variables y Constantes de módulo o fichero fuente – Ámbito: el fichero fuente – Valor inicial: 0 ● Variables y Constantes globales – Ámbito: todo el programa, incluso distintos módulos – Valor inicial: 0 26
  27. 27. Variables, Constantes y Literales Asignación de variables ● Concepto de Asignación: dar un valor a la variable. ● Sintaxis para la asignación: <nombre_var> = <valor>; ● La primera vez que se asigna un valor se llama  “inicialización”. Hasta ese momento el valor de la variable  es indeterminado. ● Puede inicializarse en la declaración. Sintaxis para la  declaración con inicialización: [<modificador>] <tipo_dato> <nombre_var> = <valor>; 27
  28. 28. Variables, Constantes y Literales Constantes ● No cambian de valor en tiempo de ejecución ● Definición de constantes: – En el preprocesador, mediante #define – En el compilador, declarando una variable con el modificador  const. Es obligatorio inicializarlas en la declaración. Ej: int const PI=3.14; 28
  29. 29. Variables, Constantes y Literales Literales ● Son las apariciones de números, caracteres y cadenas de  caracteres. Constante Representación Tipo Ejs Números -Formato decimal int o 3 enteros -Formato octal: 0nn siendo nn cifras de 0 a 7 long ('L') 5L -Formato hexadecimal: 0xnnnn... siendo nnnn...: 047 0,...,9,a,...,f,A,...,F 067L 0xA4 0x123L Números -Formato decimal: M.N double o 3.0 reales -Formato exponencial (equivalente a Mx 10N): float (‘f’ o 45.6F MeN ‘F’). 2.4e3f Caracteres Valor entre comillas simples char 'a' Caracteres no imprimibles: Secuencias de Escape 't' Cadenas Valor entre comillas dobles “nKaixotama” de Internamente terminan en '0' caracteres Caracteres no imprimibles: Secuencias de Escape 29
  30. 30. Variables, Constantes y Literales Literales – secuencias de escape ● Las secuencias de escape son literales formados por parejas  de caracteres donde el primer carácter es  que tienen un  significado especial. Secuencia de Escape Carácter " " ' ' ? ? a BEL (timbre) b BS (backspace) f FF (form feed) n NL (newline) r CR (Carriage Return) t HT ( Horizontal Tab) v VT (Vertical Tab) 0 NULL 30
  31. 31. Funciones básicas de E/S ● (Más adelante se verán las funciones en profundidad) ● Funciones: E S Comentarios scanf printf Según formato getchar putchar Carácter gets puts Cadena ● Necesario:     #include <stdio.h> 31
  32. 32. Funciones básicas de E/S ● Cadenas de formato para printf y scanf: Tipo Cadena Comentarios char "%c” Con printf muestra el carácter del código ASCII correspondiente int “%d” o “%i” Con printf de char muestra el valor numérico del código ASCII long “%li” float y double “%f” Cadena “%s” Puntero “%p” ● Uso de & en scanf: – Sí para leer variables de tipo número o carácter – No para leer contenidos de arrays o cadenas y se hace con el  nombre del array o la cadena 32
  33. 33. Funciones básicas de E/S Precauciones ● En funciones con formato (printf, scanf) hacer  corresponder el nº y tipo de parámetros al nº y tipos  indicados con % ● En scanf usar adecuadamente & 33
  34. 34. Expresiones y Operadores Introducción ● Expresiones: combinación de operadores y operandos. ● Operadores: indican la operación a realizar para evaluar un  valor. ● Operandos: variables y constantes ● Conversión de tipos de datos: implícita y explícita 34
  35. 35. Expresiones y Operadores Clasificación de operadores Grupo Nº args Aritméticos unarios expr++ expr-- ++expr --expr + - binarios + - * / % Aritméticos bits unarios ~ binarios >> << & | ^ Lógicos unarios ! binarios > < >= <= == != && || ternarios ?: Asignación binarios = += -= *= /= %= Asignación bits binarios >>= <<= &= |= ^= Memoria unarios * & binarios . -> [] Otros unarios () (casting) sizeof binarios , 35
  36. 36. Expresiones y Operadores Operador sizeof ● Indica el tamaño en bytes ocupado por el operando, que  puede ser: – una variable – una constante literal – una constante en tiempo de ejecución – un tipo de dato; es obligatorio que el tipo esté entre ( ) 36
  37. 37. Expresiones y Operadores Comentarios a operadores ● % sólo opera entre números enteros ● Operadores lógicos: – Dan como resultado numérico 1 si es verdadero y 0 si es falso  es. – El operador ! aplicado a números da 1 si el argumento es  distinto de 0 y 0 en caso contrario. Equivale a arg!=0 ● () puede tener 3 usos: función, agrupación y casting. ● Operador coma ,: se usa para separar expresiones y el resultado  es la última expresión. Poco empleado. 37
  38. 38. Expresiones y Operadores Precauciones ● No confundir = con ==. El operador = siempre devuelve  el valor de la asignación. ● Cuidado con la precisión y los overflows o  desbordamientos. Especialmente en el operador casting 38
  39. 39. Expresiones y Operadores Tabla de precedencia Grupo Operador Dirección Expresiones varias () [] . -> expr++ expr-- izda-a-dcha * & + - ! ~ ++expr --expr Operadores unarios (typecast) sizeof() dcha-a-izda Operadores binarios */% izda-a-dcha +- >> << < > <= >= == != & ^ | && || Operador ternario ?: dcha-a-izda = += -= *= /= %= >>= <<= &= Asignación ^= |= dcha-a-izda Coma , izda-a-dcha 39
  40. 40. Punteros Concepto ● Conceptos: dirección y contenido ● En una dirección de memoria puede haber uno de estos  contenidos: – Datos: variables y constantes en tiempo de ejecución – Código: funciones ● Puntero: tipo de dato que representa una dirección de  memoria en la cual se almacena un dato o bien se  encuentra una función 40
  41. 41. Punteros Declaración ● Se reserva memoria para almacenar una dirección (4  bytes). ● Sintaxis para la declaración: <tipo_apuntado> * <nombre_var_puntero>; ● Si <tipo_apuntado> es void, el puntero puede usarse para  apuntar a una función, o para apuntar a cualquier tipo de  dato. 41
  42. 42. Punteros Operador * ● Usos: – (Multiplicación) – Declaración de puntero. – Contenido de una dirección de memoria. El operando puede ser: ● Una variable de tipo puntero ● Una constante en tiempo de ejecución de tipo puntero ● Un número entero (esté en una variable, constante en tiempo de  ejecución, o sea un literal) al que se hace un casting a puntero. 42
  43. 43. Punteros Operador & ● Usos: – (and lógico de bits) – Dirección de memoria (donde hay una variable,...). El operando  puede ser: ● Una variable ● Una constante en tiempo de ejecución ● Una función ● (Nunca un literal) ● Ejemplo: uso en función scanf 43
  44. 44. Punteros Operadores aritméticos, de comparación y asignación ● Operadores aritméticos +, ­, ++, ­­: tienen en cuenta el  tipo apuntado. ● Operadores de comparación (==,!=) entre punteros: – Comparan las direcciones de los punteros, pero no el contenido. ● Operador de asignación (=) entre punteros: – Copia una dirección en la otra, no los contenidos. 44
  45. 45. Punteros Precauciones ● Acceso indebido a memoria: no se debe acceder a zonas de  memoria no declaradas por el programa – Puede ocasionar errores graves en lectura, y muy graves en  escritura. – No es un error detectado en tiempo de compilación ● Saber cuándo hay que usar &,  * o ninguno de los  anteriores 45
  46. 46. Control de Flujo Clasificación de sentencias ● Condicionales: ejecutan una sola vez una o varias líneas de  código dependiendo de una condición – if – switch ● Repetitivas: ejecutan varias veces una o varias líneas de  código dependiendo de una condición – while – do – while – for 46
  47. 47. Control de Flujo Sentencia if ● Sintaxis: if (<expresión>) { <bloque sentencias ok> } [else { <bloque sentencias no ok> }] 47
  48. 48. Control de Flujo Sentencia switch ● Sintaxis: switch (<expresión>) { case <constante 1>: [<bloque sentencias 1> [break;]] case <constante 2>: [<bloque sentencias 2> [break;]] ... case <constante n>: [<bloque sentencias n> [break;]] [default: <bloque sentencias default>] } – Si no se indica break, se ejecuta el siguiente bloque siempre,  48 aunque no se cumpla su condición case
  49. 49. Control de Flujo Sentencias while y do-while ● Sintaxis while: while (<expresión>) { <bloque sentencias ok> } ● Sintaxis do while: do { <bloque sentencias> } while (<expresión>); 49
  50. 50. Control de Flujo Sentencia for ● Sintaxis: for ([<inicialización>];[<expresión>];[<actualización>]) { <bloque sentencias> } ● Funcionamiento: – 1) <inicialización> – 2) La expresión se evalúa a verdadero o falso – 3.a) Si <expresión> es verdadera se ejecuta el bloque, después se  ejecuta <actualización> y finalmente se vuelve a 2) – 3.b) Si <expresión> es falsa se termina 50
  51. 51. Control de Flujo Resumen y Comentarios ● Uso de <expresión> – En if, while, do while, for: se evalúa a verdadero o falso – En switch: se compara con constantes enteras ● En if, while, do while, for si <bloque de sentencias> tiene  sólo 1 línea no es necesario encerrarlo entre { }, e incluso  se puede escribir todo en una línea. ● Claridad en la escritura: – Indentación – Distintos lugares posibles de { } ● Posibilidad de anidamientos. 51
  52. 52. Control de Flujo Precauciones ● Bucles infinitos para las sentencias repetitivas ● Si <bloque de sentencias> tiene más de 1 línea: – En if, while, do while, for es obligatorio el uso de { } – En switch no es obligatorio lo anterior ● Anidamientos: ojo a indentaciones, else, {} y ; ● if y while no llevan ; después de la condición, a no ser que  se ponga a propósito por algo ● Casos especiales de expresiones condicionales: – Si no es una expresión de comparación – Uso de = en vez de == 52
  53. 53. Funciones Introducción ● Filosofía de programación modular: – Dividir problema complejo en problemas sencillos – Razones: ● Claridad ● Facilidad de desarrollo ● Facilidad de mantenimiento: detección de errores, modificaciones,... 53
  54. 54. Funciones Conceptos ● Función: Bloque de sentencias que realizan una tarea de  mayor o menor nivel (=más general o más concreta) ● Función que hace la llamada y función que es llamada ● Llamada una o, en general, más veces ● Resultado ● Parámetros o argumentos: – Formales: los de la declaración. – Reales: los valores concretos pasados en tiempo de ejecución. 54
  55. 55. Funciones Introducción ● En C: – Puede recibir o no parámetros concretos en cada llamada – Puede devolver uno o ningún resultado – Puede modificar los valores originales de los parámetros que recibe – En un fichero fuente no puede haber más de una función con un  mismo nombre – Función especial: main ● 3 Sentencias de funciones: – Declaración, Definición, Llamada 55
  56. 56. Funciones Declaración de Funciones ● Concepto: indicar al compilador y al enlazador: – El nombre de la función – El tipo de dato que devuelve – El nº y tipo de parámetros – (El ámbito:) ● static: local al fichero fuente; el nombre no se exporta al linker ● extern: el código está en otro fichero ● Sinónimo: prototipo. 56
  57. 57. Funciones Declaración de Funciones ● Sintaxis: <tipo> <nombre funcion> ([lista de parámetros]); – <tipo>: si no devuelve nada, se indica void – <lista de parámetros>: ● Tipos y, opcionalmente nombres (útil a nivel descriptivo, ej. caso de  funciones de librerías), separados por comas. ● Si no recibe ningún parámetro, se puede indicar void ● Lugar para la declaración: antes de ser llamadas – Las funciones definidas por el usuario van antes del main – Las funciones no definidas por el usuario (ej. las del sistema, otras  librerías,...) van en un fichero .h. 57
  58. 58. Funciones Definición de Funciones ● Concepto: programación del código o implementación ● Sintaxis: <tipo> <nombre funcion> ([lista de tipos y nombres de parámetros]) { [<declaración de variables locales a la función>] [<sentencias de la función>] [return <expresión>;] } 58
  59. 59. Funciones Definición de Funciones ● Comentarios: – Primera línea semejante a la declaración. Diferencias: ● No termina en ; ● Además de los tipos ha de incluir los nombres de los parámetros ● Lugar de la definición: suelen ir en el mismo fichero  después del main, pero podrían estar: – En un fichero fuente .c aparte. – En un fichero ya compilado (objeto o librería), ej. printf 59
  60. 60. Funciones Llamadas a Funciones ● Concepto: salto a la primera línea del código de la función ● Sintaxis: ... <nombre funcion> ([lista de valores de parámetros]) ... <lista de valores de parámetros> – Separados por comas. – Los valores reales en el momento de la llamada – Pueden ser: ● Variables ● Expresiones de variables y/o constantes 60
  61. 61. Funciones Llamadas a Funciones ● Lugares de la llamada: puede llamarse una o varias veces  en el programa, siempre desde una función que puede ser: – La main – Otra función – La misma función: recursividad 61
  62. 62. Funciones Contextos ● Contexto = ámbito = zona del programa donde unas  variables tienen sentido ● Se distinguen: – Contexto de la función desde la que se hace la llamada – Contexto de la función llamada ● Los parámetros pasados a una función existen en ambos  contextos: – En el de la función desde la que se llama y a la que se vuelve.  Pueden ser: ● Variables ● Expresiones de variables y/o constantes – En el de la función llamada. Son idénticos a las variables locales 62
  63. 63. Funciones Paso de parámetros ● En el caso de que un parámetro sea una variable (no una  expresión de variables y/o constantes), al volver al  contexto de la función desde la que se llamó pueden ocurrir  dos casos: – Que  el valor de la variable no se haya modificado en la  función llamada – Que  el valor de la variable se haya modificado en la  función  llamada 63
  64. 64. Funciones Paso de parámetros ● Paso por valor: – Al volver no se ha modificado la variable original – En la llamada se pasa su valor ● Por referencia – Al volver se ha modificado la variable original – En la llamada se pasa la referencia o dirección de memoria en la  que se encuentran – Utilidad: para que una función calcule más de un valor (return  sólo puede devolver, como mucho, un único valor) 64
  65. 65. Funciones Sencuencia en la llamada a una función ● Almacenamiento del contexto del punto desde el que se llama  (posición de ejecución, entorno de variables locales) y de los valores  de los argumentos ● Salto al nuevo punto de ejecución ● Creación de nuevo ámbito o contexto: – Parámetros, como variables locales a la función – Variables locales propias de la función ● (Ejecución de sentencias de la función) 65
  66. 66. Funciones Sencuencia en la vuelta de una función ● Almacenamiento del posible valor de retorno ● Destrucción del contexto (variables locales) de la función llamada ● Vuelta (salto) al punto original de la ejecución ● Recuperación del valor devuelto por la función ● Recuperación del contexto de la función llamante 66
  67. 67. Funciones Función especial: main ● Declaración con varias posibilidades: – int main (void) – int main (int argc, char*argv[]) – Menos estándar: int main (int argc, char*argv[], char **envp) (envp: array de cadenas siendo el elemento final la cadena NULL) ● El valor de retorno se puede recoger desde el programa que  hace la llamada en tiempo de ejecución. Ej. en bash, de la forma: echo $? o bien: a=$? echo $a 67
  68. 68. Funciones Documentación de una función ● Declaración: – Nombre – Tipo del valor de retorno – Nº y tipo de Parámetros ● Fichero(s) cabecera ● Objetivo y descripción ● Valor de retorno ● Observaciones 68
  69. 69. Funciones Librerías ● Definición: – Conjunto de ficheros objeto (compilados), con funciones y/o  variables listas para ser enlazadas – Paquetizados según un formato específico ● Clasificaciones: – Estándares o no; http://en.wikipedia.org/wiki/C_standard_library – Programadas por el usuario o del sistema 69
  70. 70. Funciones Librerías ● Toda librería consta de: – Fichero .h: con declaraciones de funciones externas,... (En GNU/Linux están en /usr/include) – Fichero .o,.a,.la de código compilado (En GNU/Linux están en /usr/lib, ej. libc.a) – Ficheros .c de código fuente. Importancia del Software libre ● Correspondencia de fichero compilado a fichero cabecera  no siempre 1 a 1: libm.a ............ math.h libc.a ............. stdio.h, stdlib.h, string.h,... 70
  71. 71. Arrays Concepto de Arrays ● Tipo de dato que representa un conjunto de datos de igual  tipo, almacenados en posiciones contiguas de memoria ● Tiene una o varias dimensiones: – Unidimensionales (semejante avectores) – Bidimensionales (semejante a matrices de 2 dimensiones) – ... – Multidimensionales 71
  72. 72. Arrays Concepto de Arrays ● Distinguir: – Nº máximo de elementos : no puede ser modificado  dinámicamente en tiempo de ejecución – Nº de elementos inicializados ● Tamaño en bytes de un array = nº máximo de elementos x tamaño de cada elemento 72
  73. 73. Arrays Arrays unidimensionales ● Disposición en memoria ● Sintaxis para la declaración: – Modalidad 1: sin inicialización <tipo> <nombre_var_array> [num_elem]; – Modalidad 2: con inicialización. En este caso el nº de elementos es  opcional: <tipo> <nombre_var_array> [num_elem]={valor1, valor2,...}; <tipo> <nombre_var_array> []={valor1, valor2,...}; ● En caso de indicar el nº de elementos, éste ha de ser una  constante 73
  74. 74. Arrays Arrays unidimensionales ● Acceso a los elementos de un array: – Cada elemento se referencia como: <nombre_var_array> [<indice>] siendo <indice> un valor entre 0 y <num_elem>­1 ● Dualidad array­puntero: – Los elementos de un array se pueden referenciar con notación de  puntero, de la forma: var_array + N ≡ &var_array[N] – El nombre del array representa la dirección de memoria en la que  se encuentra el primer elemento: var_array ≡ &var_array[0] 74
  75. 75. Arrays Arrays unidimensionales como parámetros de funciones ● Posibilidades: – Elementos del array uno a uno. Problema: muchos parámetros – Array completo ● Array completo: por referencia – Pasando el nombre se pasa la dirección de todo el array. – Los valores de los elementos del array pueden ser modificados  dentro de la función – Para informar a la función del nº de elementos, puede hacerse: ● Empleando otro parámetro para la función ● Usando constantes con igual valor en la función llamante y la función  llamada 75
  76. 76. Arrays Arrays unidimensionales como parámetros de funciones ● Sintaxis de la declaración de un array unidimensional como  parámetro por referencia: – Con notación array: <tipo_func><nombre_func (...,<tipo> [],...); – Con notación puntero: <tipo_func><nombre_func (...,<tipo> *,...); 76
  77. 77. Arrays Arrays unidimensionales como resultado de funciones ● No se debe devolver un array como resultado de una  función en el caso de que dicho array se haya declarado  como variable local a la función, ya que al finalizar ésta la  zona de memoria del array no es válida (se destruye el  contexto de la función llamada). ● Otras formas: – Modificar por referencia un array pasado como parámetro desde la  función que hace la llamada. – Devolver un puntero a una zona de memoria reservada  dinámicamente dentro de la función. 77
  78. 78. Arrays Arrays bidimensionales ● Disposición en memoria: primero filas y luego columnas ● Sintaxis para la declaración: – Modalidad 1: sin inicialización <tipo> <nombre_var_array> [num_filas][num_cols]; – Modalidad 2: con inicialización. En este caso el nº de filas es  opcional: <tipo> <nombre_var_array> [num_filas][num_cols]={valor1, valor2,...}; <tipo> <nombre_var_array> [num_filas][num_cols]={array_u1, array_u2,...}; (siendo array_u1,... arrays unidimensionales de num_cols elementos) <tipo> <nombre_var_array> [][num_cols]={valor1, valor2,...}; <tipo> <nombre_var_array> [][num_cols]={array_u1, array_u2,...}; (siendo array_u1,... arrays unidimensionales de num_cols elementos) 78
  79. 79. Arrays Arrays bidimensionales ● Sintaxis de acceso a los elementos de un array  bidimensional: <nombre_var_array> [<indice_fila>][<indice_col>] ● Sintaxis de la declaración de un array bidimensional como  parámetro por referencia: indicar el tamaño de todas las  dimensiones menos la primera. <tipo_func><nombre_func (...,<tipo> [][num_cols],...); 79
  80. 80. Arrays Operadores de comparación y asignación ● Operadores de comparación (==,!=) entre arrays: – Comparan las direcciones de los arrays, pero no el contenido. – Para comparar los contenidos hay que emplear un bucle. ● Operador de asignación (=) entre arrays: – No es aplicable. – Para hacer la copia de un array a otro hay que hacerlo elemento a  elemento o mediante funciones de librería. 80
  81. 81. Arrays Precauciones ● Acceso indebido a memoria: no se debe acceder a zonas de  memoria no declaradas por el programa, ej. en arrays, acceso a elementos más allá de <tamaño­1> – Puede ocasionar errores graves en lectura, y muy graves en  escritura. – No es un error detectado en tiempo de compilación ● Inicialización de arrays completos, de la forma { }: sólo en  la declaración. Si no, elemento a elemento. ● Los elementos de un array declarado como variable local  dentro de una función llamada, no son válidas a la vuelta  en la función llamante. 81
  82. 82. Cadenas de caracteres Introducción ● Definición: es un array de caracteres que termina con el  carácter '0' (NULL). ● Una constante literal de cadena tiene dos posibles  representaciones: – Entre “ “. El compilador reserva automáticamente un byte más  para el carácter final '0'. Ej. “cadena” – Caracteres entre { } siendo el último '0'. Ej: {'c','a','d','e','n','a','0'} 82
  83. 83. Cadenas de caracteres Declaración ● No son un tipo predefinido en C. Hay dos posibilidades: – Array de char. En memoria: char a[]=”kaixo”; +---+---+---+---+---+---+ a | k | a | i | x | o |0 | +---+---+---+---+---+---+ – Puntero a char. En memoria: char *p=”kaixo”; +---+ +---+---+---+---+---+---+ p | * =====>| k | a | i | x | o |0 | +---+ +---+---+---+---+---+---+ 83
  84. 84. Cadenas de caracteres Declaración ● Array de char: – Se hace una reserva de memoria igual al nº de elementos indicado  en la longitud del array, o si ésta no se indica igual a la longitud de  la cadena a la que se inicializa más uno. – Sólo se puede igualar a una cadena constante en la inicialización.  Más adelante no se puede igualar a otras cadenas, sean constantes  o variables ● Puntero a char: – Se hace una reserva de memoria para almacenar el tamaño del  puntero, y otra para almacenar los caracteres igual que en el caso  anterior. – Se puede igualar a otras cadenas en cualquier momento. – Si al declararlo se inicializa, su contenido no puede ser modificado 84
  85. 85. Cadenas de caracteres Sintaxis para la declaración como array de char ● Sin inicialización: char str[<longitud>]; ● Con inicialización. En este caso la longitud es opcional: char str[<longitud>]=”cadena”; char str[<longitud>]={'c','a','d','e','n','a','0'}; char str[]=”cadena”; char str[]={'c','a','d','e','n','a','0'}; char str[]={num1,num2,...,,numN,0}; – En caso de indicarse <longitud>, se almacena ese nº de bytes,  independientemente de que no coincida con la longitud de  cadena+1 85
  86. 86. Cadenas de caracteres Sintaxis para la declaración como puntero a char ● Sin inicialización: char *str; ● Con inicialización: char *str=”cadena”; – No es posible modificar a posteriori el contenido. – No es válida la sintaxis: char *str={'c','a','d','e','n','a','0'}; 86
  87. 87. Cadenas de caracteres Operadores de comparación y asignación ● Operadores de comparación (==,!=) entre cadenas de  caracteres: – Comparan las direcciones de los punteros, pero no el contenido. – Para comparar los caracteres de las cadenas se debe emplear la  función strcmp ● Operador de asignación (=) entre cadenas de caracteres: – Si una cadena se declara como array de char, no se puede igualar a  otra cadena (excepto en la inicialización a un literal string). – Si una cadena se declara como char *: ● Para copiar los caracteres de una cadena a otra no vale con igualar los  punteros que las designan. Hay que copiar caracter a caracter (ej. con  un bucle o con la función strcpy). ● Si se iguala a un literal string después no puede variar su contenido. 87
  88. 88. Cadenas de caracteres Funciones ● Declaradas en stdio.h: – E/S en stdin y stdout: printf, scanf, puts, gets – E/S en un stream: fprintf, fscanf, fputs, fgets – E/S en otra cadena: sprintf, sscanf ● Declaradas en string.h: – Longitud (nº de caracteres) de una cadena: strlen – Copia de una cadena a otra: strcpy – Concatenación de una cadena detrás de otra: strcat – Comparación de dos cadenas: strcmp – Búsqueda de en una cadena: strchr, strrchr, strstr 88
  89. 89. Cadenas de caracteres Precauciones ● Carácter '0' final: – A nivel de almacenamiento, considerar un byte adicional para el  carácter '0' final – Diferenciar entre la longitud de la cadena (el nº de caracteres), y el  nº de bytes ocupados – Todas las funciones que operan sobre cadenas sólo se detienen (ej.  strlen, sprintf, strcpy) cuando encuentran '0'. 89
  90. 90. Cadenas de caracteres Precauciones ● Memoria controlada: – No se puede modificar el contenido de una cadena de tipo puntero  a char si apunta a un literal. – Gestión de memoria: al copiar una cadena a otra (sprintf, strcat,  strcpy), hay que tener espacio previamente reservado en el  destino. Posibles problemas: ● Array demasiado corto. ● Puntero sin reserva de espacio. – La función gets es insegura porque no comprueba desbordamiento  de buffers. Mejor usar fgets (ver tema de ficheros y streams). 90
  91. 91. Estructuras Introducción ● Tipo de dato que almacena un conjunto de datos de  distinto tipo bajo un mismo nombre. ● Pasos para el empleo de estructuras: – Declaración de la estructura fuera de funciones, antes de usarla en  variables y funciones. – Declaración de las variables de tipo struct y/o funciones que  devuelvan tipo struct 91
  92. 92. Estructuras Declaraciones ● Sintaxis para declarar la estructura: struct <nombre_estructura> { <declaración [e inicialización] campo 1>; <declaración [e inicialización] campo 2>; ... <declaración [e inicialización] campo n>; }; ● Ha de hacerse fuera de y antes de la función donde se use  (main u otras): variables o valor de retorno de ese tipo. ● Si se inicializa algún campo, queda inicializado por defecto  para todas las variables de tipo estructura 92
  93. 93. Estructuras Declaraciones ● Sintaxis para declarar variables y valores de retorno de  funciones de tipo estructura: struct <nombre_estructura> <variable>; struct <nombre_estructura> <funcion> ... 93
  94. 94. Estructuras Uso de estructuras ● Acceso a los campos de estructura: – Si es una variable de tipo estructura: operador . <nombre_variable_estructura>.<nombre_campo> – Si es una variable de tipo puntero a estructura: operador ­> <ptr_a_estructura> -> <nombre_campo>    Equivale a: (*<ptr_a_estructura>).<nombre_campo> ● Paso de parámetros de tipo estructuras a funciones: mejor pasar por referencia, en vez de por valor 94
  95. 95. Estructuras Operadores de comparación y asignación ● Operadores de comparación (==,!=) entre variables de  tipo struct: no son válidos, y hay que hacer una  comparación campo a campo. ● Operador de asignación (=) entre estructuras: sí es posible  copiar una variable de tipo estructura a otra del mismo tipo  (internamente se produce una copia campo a campo),  incluso aunque alguno de los campos sea de tipo array. 95
  96. 96. Tipos combinados ● Array de punteros char *nombres[10]; ● Array de estructuras struct persona mi_clase[10]; ● Estructura con tipos de campos variados: struct alumna { struct nom_ap1_ap2 identificador; float notas[10]; char *mem_dinamica; }; 96
  97. 97. Tipos combinados Puntero a ... ● En general útil para funciones con paso de parámetros por  referencia ● Puntero a estructura: struct persona * ptr_struct; ● Puntero a puntero. Como parámetro de una función se  modificaría el valor de un puntero (no el contenido  apuntado por el mismo). int ** ptr_ptr; ● Puntero a array: su uso es infrecuente, y se emplea para  pasar por referencia un array multidimensional con  notación de puntero: char (*ptr_a_array)[]; 97
  98. 98. Gestión de memoria dinámica Introducción ● Reserva estática: – En tiempo de compilación. Ej. arrays – No puede modificarse el tamaño ni liberarse en tiempo de  ejecución ● Reserva dinámica: – En tiempo de ejecución. – Sí puede modificarse el tamaño de la reserva y liberarse en tiempo  de ejecución ● Funciones: – Declaradas en malloc.h o en stdlib.h (con incluir uno es suficiente) – Reserva: calloc, malloc, realloc – Liberación: free 98
  99. 99. Gestión de memoria dinámica Precauciones ● Comprobar errores devueltos ● Liberar siempre lo reservado 99
  100. 100. Ficheros y streams Introducción ● Ficheros físicos: información almacenada en un dispositivo:  disco (HD, CD, DVD), USB, memoria,... – Características: nombre, tamaño, ubicación, permisos, propietario – Ubicación o path: en GNU/Linux directorios separados por '/' ● Fichero lógico: abstracción de un lenguaje de programación  para acceder a los ficheros físicos. 100
  101. 101. Ficheros y streams Introducción ● Contenido de los ficheros: – Caracteres ASCII, con líneas separadas. ('n' en GNU/Linux) – Caracteres no ASCII binarios (posiblemente contendrá caracteres  ASCII). Ejs: ● Audio, video, ejecutables ● Texto formateado (rtf, openoffice,...) ● El contenido es independiente del nombre, ej. fichero1.dat,  fichero.txt 101
  102. 102. Ficheros y streams Streams ● Son los ficheros lógicos empleados en C: objetos para  manejar ficheros y dispositivos. ● El tipo de un stream es: FILE* ● Definición en stdio.h. Otros símbolos: – NULL: 0 – EOF: ­1 (end of file) 102
  103. 103. Ficheros y streams Conceptos de streams ● Nombres de ficheros físicos ● Operaciones típicas: – Lectura y escritura. Caracteres ascii o binarios. Buffers de streams – Desplazamiento. Indicador de posición. ● Abrir streams. Lo primero para trabajar con streams. Modos  de apertura: – r, r+, w, w+, a, a+ – Diferenciación binario/ASCII: está definido en el estándar ANSI C,  pero en los sistemas POSIX (GNU/Linux incluido) no hay  distinción ● Indicadores de error y de fin de fichero ● Cerrar streams. Obligatorio para los streams abiertos. 103
  104. 104. Ficheros y streams Funciones ● Declaradas en stdio.h y stdio_ext.h (éste no es estándar) ● Streams: – E/S: contenido texto(=ASCII) o binario. Ver cuadro sinóptico – Volcado de buffers de salida y entrada: fflush,__fpurge – Abrir, cerrar y reasignar stream: fopen, fclose,freopen – Indicadores  de fin de fichero y error: feof, ferror, clearerr – Desplazar y obtener indicador de posición: fseek, rewind, ftell ● Ficheros: – Borrar, renombrar: remove, rename 104
  105. 105. Ficheros y streams Streams predefinidos ● Hay 3 streams especiales: Stream Definición Por defecto Valor stdin Entrada estándar Teclado 0 stdout Salida estándar Pantalla 1 stderr Salida de errores Pantalla 2 ● Al ejecutar un programa ya están abiertos, y además de los  dispositivos a los que están asignados por defecto, pueden  ser redirigidos. Útiles en redirecciones y pipes. Ej. en bash: – programa >fichero1 <fichero2 – programa1 | programa 2 > fichero – programa 2>fichero1 105
  106. 106. Ficheros y streams Precauciones ● Comprobar errores devueltos ● Fijarse si la función de lectura o escritura opera sobre un  fichero de texto o binario ● Fijarse si la función opera sobre un nombre de fichero o  sobre un stream. En este caso, tener en cuenta el orden: – Abrir el stream antes de leer/escribir – Cerrar el stream tras su uso, antes o después ● En funciones con formato (fprintf, fscanf,...) hacer  corresponder el nº de parámetros al nº de % 106
  107. 107. Referencias ● http://www.lysator.liu.se/c/  ● http://www.faqs.org/faqs/C­faq/faq/ 107

×