Programación en C
(Segunda Parte)
DATSI, FI, UPM
José M. Peña
[email protected]
Programación en C
1
Índice
• Estructura de un programa C.
• Variables básicas.
• Operaciones aritméticas.
• Sentencias de control.
• Arrays y Strings.
• Funciones.
• Estructuras de datos.
• Entrada/Salida básica.
• Ejemplos I.
• Modificadores de
ámbito de las variables.
• Punteros y memoria
dinámica.
• Operadores de bit.
• Preprocesador C y
compilación.
• Librerías estándar.
• Ejemplos II.
Programación en C
2
Programación en C
Modificadores de Ámbito
Programación en C
3
Modificadores de Variables
• La declaración de variables acepta los siguientes
modificadores:
– static (Local): El valor de la variable se conserve entre
llamadas. Comportamiento similar a una variable global.
– register : La variable es almacenada siempre (si es
posible) en un registro de la CPU (no en memoria).
– volatile : Un proceso exterior puede modificar la
variable.
– const : La variable no puede ser modificada.
Programación en C
4
Modificadores de Variables
int una_funcion(int a, int b)
{
char last;
static
register int i;
const
volatile long acc;
....
int max=12;
}
Programación en C
5
Modificadores de Variables (static)
void cuenta()
{
static int cnt=0;
printf(“%d\n”,cnt++)
}
int main()
{
Salida:
0
1
2
3
cuenta();cuenta();cuenta();cuenta();
return 0;
}
Programación en C
6
Modificadores de Variables (const)
const int max=10;
int letra(const char* text, char l)
{
int i,acc=0;
for(i=0;i<max && text[i];i++)
if(text[i]==l)
acc++;
return acc;
}
Programación en C
7
Modificadores de Funciones
• Las funciones también pueden ser declaradas con
ciertos modificadores:
– static : Restricción de enlace. Sólo se puede usar
dentro del mismo fichero (también variables globales).
– extern : La función o variable se encuentra declara
pero no definida. Usada con variables globales.
– inline : La función es expandida íntegramente al ser
invocada. No hay un salto a la función. Incrementa la
eficiencia y aumenta el tamaño del código.
Programación en C
8
Modificadores de Funciones
Fichero1.c:
static void func()
{
Fichero2.c:
extern void aux();
...
}
void aux()
{
func();
}
int main()
{
aux();
func(); /* NO
VISIBLE */
}
Programación en C
9
Modificadores de Funciones
Fichero1.c
compilación
compilación
Fichero1.o
aux Impl G
aux Impl G
func Impl L
func Impl L
Fichero2.c
compilación
compilación
Fichero2.o
aux Undef
aux Undef
func Undef
func Undef
main Impl G
main Impl G
enlace
enlace
EJECUTABLE
Programación en C
10
Modificadores de Funciones
inline int max(int a, int b)
{
if(a>b)
return a;
else
return b;
}
....
x=max(x+1,y);
{
if(x+1>y)
else
}
x=x+1;
x=y;
Programación en C
11
Programación en C
Punteros y Memoria Dinámica
Programación en C
12
Aritmética de Punteros
• Las variables de tipo puntero soportan ciertas
operaciones aritméticas.
char v[]=“Colección”;
char *p=v;
*(p+2)
v
C o l e c c i ó n \0
}
for(p=v;*p;p++)
{
printf(“%c”,*p)
v[7]
Programación en C
13
Aritmética de Punteros
Las operaciones soportadas sobre punteros son:
– Suma y resta de valores enteros (+,-,++ y --).
– Comparación y relación (<,>,<=,>=,== y !=).
– Valor booleano (comparación con NULL).
void copiar(char* dest, const char* orig)
{
if(orig && dest)
while(*orig)
*dest++=*orig++;
}
Programación en C
14
Aritmética de Punteros
Las operaciones de suma o resta sobre punteros
modifican el valor del dependiendo del tipo del puntero:
int* p_int; char* p_char; p_int=p_char;
p_int++; /* Suma sizeof(int) */
p_char++; /* Suma sizeof(char) */
p_char
++
p_char + 1
3F0
3F1 3F2 3F3 3F4 3F5 3F6 3F7 3F8 3F9 3FA 3FB
p_int
++
sizeof(int)=4
p_int + 1
Programación en C
15
Punteros a Funciones
Mecanismo para pasar funciones como argumento:
char (*f)(int,int);
f es un puntero a una función que devuelve un char y
recibe dos enteros como argumento.
A un puntero a función se le puede asignar como valor
cualquier identificador de función que tenga los mismos
argumentos y resultado.
Programación en C
16
Punteros a Funciones
char* menor (char** text,
int tam,
int (*compara)(char*,char*))
{
}
int i;
char* min=text[0];
for(i=1;i<tam;i++)
if(*compara(menor,text[i]))
min=text[i];
return min;
Programación en C
17
Punteros a Funciones
int main()
{
char *palabras[]={“hola”,“casa”,“perro”,
“coche”,“rio”};
printf(“Menor:%s”,
menor(palabras,5,alfabetico));
return 0;
}
int alfabetico(char* a,char* b)
{ .... }
Programación en C
18
Memoria Dinámica
Además de la reserva de espacio estática (cuando se
declara una variable), es posible reservar memoria de
forma dinámica.
Funciones de gestión de memoria dinámica:
– void* malloc(size_t): Reserva memoria
dinámica.
– free(void*): Libera memoria dinámica.
– void* realloc(void*,size_t): Ajusta el
espacio de memoria dinámica.
Programación en C
19
Memoria Dinámica
int a,b[2];
int* i;
char* c;
i=(int*)malloc(sizeof(int));
c=(char*)malloc(sizeof(char));
free(i);
c=(char*)realloc(c,sizeof(char)*9);
Estática
a
b[0]
b[1]
i
c
a
b[0]
b[1]
i
c
a
b[0]
b[1]
i
c
Dinámica
*i
*c
*c
Programación en C
20
Programación en C
Operadores de Bit
Programación en C
21
Operadores de Bit
Además de los operadores aritméticos y booleanos
existen operadores numéricos a nivel de bit:
– AND: &
– OR: |
– XOR: ^
– NOT: ~
– Desplazamientos: << y >>
Programación en C
22
Operadores de Bit
char a=48;
char b=19;
char x,y,z,w,t,s;
00110000
00010011
a
b
x=a & b;
y=a | b;
z=a ^ b;
w=~a;
t=a>>2;
s=b<<3;
00010000 x = 16
00110011 y = 51
00100011 z = 35
11001111 w = 207
00001100 t = 12
10011000 s = 152
Programación en C
23
Uso de los Operadores de Bit
const char LECTURA =1;
const char ESCRITURA=2;
const char EJECUCION=3;
char permisos=LECTURA | ESCRITURA;
parmisos|=EJECUCION;
permisos&=~ESCRITURA;
if(permisos & EJECUCION)
printf(“Es ejecutable”);
Programación en C
24
Programación en C
Preprocesador y Compilación
Programación en C
25
Fase de Compilación
.c.c
Preprocesamiento .c.c Paso a Ensamblador .s.s
Fichero Fuente
Compilación
Ensamblar
Enlazado
EXEEXE
Fichero Ejecutable
Programación en C
.o.o
.a.a
.o.o.o.o.o.o.o.o
Librerías
26
Directrices del Preprocesador
Son expandidas en la fase de preprocesado:
– #define : Define una nueva constante o macro del
preprocesador.
– #include : Incluye el contenido de otro fichero.
– #ifdef #ifndef : Preprocesamiento condicionado.
– #endif : Fin de bloque condicional.
– #error : Muestra un mensaje de error
Programación en C
27
Constantes y Macros
Permite asociar valores constantes a ciertos
identificadores expandidos en fase de
preprocesamiento:
#define variable valor
Define funciones que son expandidas en fase de
preprocesamiento:
#define macro(args,...) función
Programación en C
28
Constantes y Macros
3.14
#define PI
#define NUM_ELEM 5
#define AREA(rad) PI*rad*rad
#define MAX(a,b) (a>b ? a : b)
int main()
{
int i;
float vec[NUM_ELEM];
for(i=0;i<NUM_ELEM;i++)
vec[i]=MAX((float)i*5.2,AREA(i));
}
Programación en C
29
Constantes y Macros
Tras la fase de prerpocesamiento
int main()
{
int i;
float vec[5];
for(i=0;i<5;i++)
vec[i]=((float)i*5.2>3.14*i*i ?
(float)i*5.2 :
3.14*i*i);
}
Programación en C
30
Macros vs Funciones
int func_max(int a, int b)
{ return (a>b ? a : b); }
#define macro_max(a,b) (a>b ? a : b)
int a=2,b=3,max;
Usando funciones
max=func_max(a++,b--);
Usando macros
max=macro_max(a++,b--);
max
3
a
3
b
2
max
2
a
3
b
1
Programación en C
31
Inclusión de Ficheros
Los prototipos de las funciones usadas por varios
ficheros fuente se suelen definir en fichero de cabecera.
#include <stdio.h>
#include “mis_func.h” Ficheros de cabecera locales.
Cabeceras del sistema.
aux.h
int func1(int a);
int func1(int a);
viod func2();
viod func2();
fich.c
#include “aux.h”
#include “aux.h”
int main()
int main()
{ ...}
{ ...}
Preprocesamiento
int func1(int a);
int func1(int a);
viod func2();
viod func2();
int main()
int main()
{ ...}
{ ...}
Programación en C
32
Inclusión de Ficheros
La inclusión de ficheros esta sujeta a las siguientes
recomendaciones:
– Por lo general los ficheros de cabecera tienen como
extensión .h
– En los ficheros de cabecera no se incluyen
implementación de funciones
– Las variables en un fichero de cabecera son declaradas
extern y se encuentran declaradas en algún otro
fichero .c
Programación en C
33
Sentencias Condicionales
Para incluir código cuya compilación es dependiente de
ciertas opciones, se usan los bloques:
#ifdef variable
<bloque de sentencias>
...
#endif
#ifndef variable
<bloque de sentencias>
...
#endif
Programación en C
34
Ejemplo: Depuración
#define DEBUG
int main()
{
int i,acc;
for(i=0;i<10;i++)
acc=i*i-1;
#ifdef DEBUG
printf(“Fin bucle acumulador: %d”,acc);
#endif
return 0;
}
Programación en C
35
Ejemplo: Fichero de Cabecera
aux.h
#ifndef _AUX_H_
#ifndef _AUX_H_
#define _AUX_H_
#define _AUX_H_
<definiciones>
<definiciones>
#endif
#endif
Evita la redefinicion de
funciones y variables
#include “aux.h”
#include “aux.h”
int main()
{
...
}
Programación en C
36
Enlace de Ficheros
extern int v;
int main() {.h().}
extern void k();
static h() {.k().}
gcc -c
3A00: f
3A08: main
3B12: h
v <undef>
k <undef>
.c.c
.o.o
.c.c
.o.o
int k() {.l().}
int l() {...}
int v;
Compilación
gcc -c
1600: k
17FF: l
1812: v
Enlace
gcc -o
EXEEXE
Programación en C
37
Programación en C
Librerías Estándar
Programación en C
38
Manejo de Cadenas
• char* strcat(char*,char*): Concatena cadenas.
• char* strchr(char*,char): Busca un carácter.
• int strcmp(char*,char*): Comparación de cadenas.
• char* strcpy(char*,char*): Copia cadenas.
• char* strdup(char*): Duplica una cadena.
• int strlen(char*): Longitud de una cadena.
• char* strncpy(int,char*,char*): Copia cadenas.
• cha
Comentarios de: Programación en C (Segunda Parte) (0)
No hay comentarios