Documentos de Académico
Documentos de Profesional
Documentos de Cultura
2
Í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
Introducción al lenguaje C
Características generales
●
Lenguaje compilado
●
Lenguaje de nivel mediobajo
●
“casesensitive”
●
Especificaciones:
– K&R (Dennis Ritchie and Brian Kernighan)
– ANSI C (X3.1591989) e ISO C
– C99
●
Más información en:
http://en.wikipedia.org/wiki/C_programming_language
4
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
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
Introducción al lenguaje C
Estructura de un fichero fuente .c
7
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
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
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
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
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 BN1
●
Desbordamientos u overflow.
12
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
Sistemas numéricos
y de caracteres
Equivalencias
●
1 byte = 8 bits
●
1 K = 1024
●
1 M = 1024 K
●
1 G = 1024 M
14
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 “\nKaixo\tama”
de Internamente terminan en '\0'
caracteres Caracteres no imprimibles: Secuencias de Escape
29
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
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
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”
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
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
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
Expresiones y Operadores
Clasificación de operadores
Grupo Nº args
Aritméticos unarios expr++ expr-- ++expr --expr + -
binarios + - * / %
35
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
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
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
Expresiones y Operadores
Tabla de precedencia
Grupo Operador Dirección
39
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
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
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
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
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
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
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
Control de Flujo
Sentencia if
●
Sintaxis:
if (<expresión>) {
<bloque sentencias ok>
} [else {
<bloque sentencias no ok>
}]
47
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
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
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
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
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
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
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
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
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
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
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
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
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]) ...
– Separados por comas.
– Los valores reales en el momento de la llamada
– Pueden ser:
●
Variables
●
Expresiones de variables y/o constantes
60
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
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
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
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
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
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
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
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
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
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
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
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
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
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 arraypuntero:
– 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
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
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
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
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,...};
(siendo array_u1,... arrays unidimensionales de num_cols elementos)
<tipo> <nombre_var_array> [][num_cols]={valor1, valor2,...};
(siendo array_u1,... arrays unidimensionales de num_cols elementos)
78
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
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
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ño1>
– 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
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
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
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
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
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
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
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
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
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
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
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
Estructuras
Declaraciones
●
Sintaxis para declarar variables y valores de retorno de
funciones de tipo estructura:
struct <nombre_estructura> <variable>;
struct <nombre_estructura> <funcion> ...
93
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
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
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
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
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
Gestión de memoria dinámica
Precauciones
●
Comprobar errores devueltos
●
Liberar siempre lo reservado
99
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
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
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
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
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
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
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
Referencias
●
http://www.lysator.liu.se/c/
●
http://www.faqs.org/faqs/Cfaq/faq/
107