Vous êtes sur la page 1sur 58

Programacin en C

ndice
Introduccin: caractersticas, ventajas, desventajas, tipos de C.
Estructura de un programa en C.
Tipos de datos bsicos. Conversiones de tipos. Constantes.
Operadores y expresiones. Prioridad de los operadores.
Sentencias condicionales: if, switch
Sentencias repetitivas: while, do...while, for
Sentencias break y continue
Funciones y macros. Paso de parmetros por valor.
Arrays y punteros. Strings: librera string.h. Paso de parmetros por
referencia.
Gestin de memoria dinmica.
Estructuras de datos: struct, union, enum, typedef.
Declaracin de variables: mbito y tipo de almacenamiento.
Entrada/Salida: librera stdio.h
Libreras estndares de C: ctype.h, stdlib.h, math.h, time.h
Desarrollo de programas: compilacin separada, directivas al compilador.
Resmenes

Programacin en C. Teora

Dpto. ATC (UPV/EHU)

Introduccin
Caractersticas
-

Creado en 1972 por D. Ritchie en AT&T para desarrollar el sistema operativo UNIX.

Lenguaje de nivel medio: elementos de un lenguaje de alto nivel combinados con la


funcionalidad de los lenguajes de bajo nivel.

Diseado para desarrollo de sistemas operativos. Hoy en da se usa para una amplia
gama de aplicaciones, sobre todo desarrollo de paquetes y libreras. Por ejemplo:
editores, paquetes de bases de datos, sistemas grficos, etc.

Ventajas
* Lenguaje simple, con una potente librera estndar.
* Produce programas ejecutables muy eficientes y compactos.
* Lenguaje portable y abundancia de compiladores.
* Posibilidad de manejo directo de recursos fsicos (bit, registros generales, direcciones
fsicas, etc.), con lo que rara vez hay que recurrir al ensamblador.

Desventajas
* Programas crpticos e ilegibles si el programador no se esmera.
* No se produce verificacin en tiempo de ejecucin (ndices de array, ...).
* En ausencia de declaracin de tipos se interpreta tipo int.
* Necesidad de conocimiento y uso de debuggers y otras herramientas para depuracin de
programas.

Tipos de C
* Fundamentalmente dos: C AT&T (o simplemente C) y ANSI C con pocas diferencias
entre ellos.
* C++ asimilable a lenguaje orientado a objetos.

Programacin en C. Teora

Dpto. ATC (UPV/EHU)

Estructura de un programa en C
/* Comentarios

- no pueden anidarse */

// Comentario hasta final de lnea- ANSI C


// includes de las libreras a utilizar
// definiciones globales
void f1()
/* procedimiento definido por el usuario */
{
variables locales
sentencias del procedimiento
}
int f2()
/* funcin definida por el usuario */
{
variables locales
sentencias de la funcin
}
...
...
...
char fN(int a, char *b, float c)
/* funcin con parmetros definida por el usuario */
{
variables locales
sentencias de la funcin
}
main ()
/* programa principal */
{
variables locales
sentencias del programa principal
}
int addition()
{
return(2+2);
}
main ( )
{
int n1, n2; /* declaracin de variables */
n1=addition(); /* llamar a la funcin y recoger resultado*/
n2=n1/3;
}

Programacin en C. Teora

Dpto. ATC (UPV/EHU)

scanf / printf
#include <stdio.h>
main ( )
{
int r;
float area, perimetro;
printf ("Introduce el radio del crculo: \n");
scanf ("%d", &r);
/* &->referencia */
area=3.14159*r*r;
perimetro=2*3.14159*r;
printf ("En un crculo de radio %d\n", r);
printf ("rea: %f\n", area);
printf ("permetro: %f\n", perimetro);
}
printf ("formato", expresin)
%
s
\n

reemplazar
cadena de caracteres (string)
salto de lnea

d nmero decimal
f nmero real
c carcter

Tipos de datos bsicos


TIPO
void
char
unsigned char
signed char
int
unsigned int
signed int
short int
unsigned short
int
signed short int
long int
unsigned long int
signed long int
float
double
long double

NMERO DE
BITS
0
8
8
8
16 32*
16 32*
16 32*
16
16

RANGO REPRESENTACIN

16
32
32
32
32
64
128

-32768/32767
-231/231-1
0/232-1
-231/231-1
Precisin de 7 cifras decimales
Precicin de 15 cifras decimales
Precicin de 31 cifras decimales

caracteres ASCII
0/255
-128/127

-32768/32767
0/65535

Notas:
El fichero estndar <limits.h> contiene las definiciones de estos tipos bsicos
Atencin a la codificacin UNICODE de caracteres

sizeof (tipo): devuelve el tamao en bytes que ocupa el tipo de dato

Constantes
Programacin en C. Teora

Dpto. ATC (UPV/EHU)

Ejemplo
a
25
25L
25.
12.5
12.5E0
1.15E8
0123
0x53
Curso de C

Descripcin
carcter a
25 int
25 long
25 float
12.5 float
12.5 double (notacin cientfica)
1.15*108 double
123 octal = 83 int
53 hexadecimal = 83 int
cadena de 10 caracteres

#include <stdio.h>
#define PI

3.14159

main ()
{
float r, area, perimetro;
printf ("Introduce el tamao del radio\n");
scanf ("%f", &r);
perimetro = 2 * PI * r;
area = PI * r * r;
printf ("rea: %f\n", area);
printf ("perimetro: %f\n", perimetro);
}
#include <stdio.h>
main()
{
int x1=10, y;
float x2=10.0;
y=4;
printf("%d %f", x1/y, x2/y);
}

Programacin en C. Teora

Dpto. ATC (UPV/EHU)

Conversiones de tipos
impcitas
char

short
int
unsigned int
long
unsigned long
float
long double

casting: conversin de tipos explcita


#include <stdio.h>
main ( )
{
char car_min, car_may;
printf ("Introduce un carcter minscula\n");
scanf ("%c", &car_min);
car_may = car_min 'a' + 'A';
printf ("%c", car_may);
}
#include <stdio.h>
main ( )
{
char car_min, car_may;
printf ("Introduce un carcter minscula\n");
scanf ("%c", &car_min);
car_may = (char)((int)car_min (int)'a' + (int)'A');
printf ("%c", car_may);
}

Programacin en C. Teora

Dpto. ATC (UPV/EHU)

Operadores
Prioridad y asociatividad
OPERACIN
Parntesis y corchetes
Campo de estructuras
Negacin
Incremento, decremento
Signo, Punteros
casting, sizeof
Producto, divisin, mdulo
Suma, resta
Deplazamiento
Comparacin
Lgicas
Composicin condicional
Expresiones condicionales
Asignacin

OPERADOR
() [].

->

! ~ ++ -- + - * &
(type) sizeof
* / %
+ >> <<
< <= > >=
== !=
&
^
|
&&
||
? :
= *= -= /= %=
&= |= ^= >>= <<=

ASOCIATIVIDAD
Hacia la derecha

Hacia la izquierda
Hacia la derecha
Hacia la derecha
Hacia la derecha
Hacia la derecha
Hacia la derecha
Hacia la derecha
Hacia la izquierda
Hacia la izquierda

Operadores aritmticos
OPERACIN
Negacin
Suma
Resta
Producto
Divisin
Mdulo
Incremento
Decremento

OPERADOR
+
*
/
%
++
--

FORMATO
-x
x+y
x-y
x*y
x/y
x%y
x++ ++x
x-- --x

DESCRIPCIN
Cambio de signo al valor de x
x+y
x-y
x*y
x/y
resto x/y
x=x+1
x=x-1

#include <stdio.h>
main()
{
int x=10, y=3;
printf("%d %d", x/y, x%y);
}

Programacin en C. Teora

Dpto. ATC (UPV/EHU)

Operadores
#include <stdio.h>
main()
{
int x, y, z=10;
float f,g;
printf("Introduce el valor de x:\n");
scanf("%d", &x);
f=x/z;
g=(float)x*z;
y++; // y=y+1; y+=1;
printf("f %f, g %f, y %d:\n", f, g, y);
y/=z; // y=y/z;
printf("ahora el valor de y es: %d\n", y);
}

Operadores lgicos
OPERACIN
AND
OR
XOR
Negacin lgica
Desplazamiento a la
izquierda
Desplazamiento a la
derecha

OPERADOR
&
|
^
~

FORMATO
x&y
x|y
x^y
~x

<<

x << y

>>

x >> y

DESCRIPCIN
x AND y
x OR y
x XOR y
Cambian todos los bits de x
Se desplazan y veces los
bits de x hacia la izda
Se desplazan y veces los
bits de x hacia la dcha

#include <stdio.h>
main()
{
short int x;
printf("Introduce el valor de x:\n");
scanf("%d", &x);
printf("Su complemento a uno es: %d.\n", ~x);
printf("Si el valor introducido no es negativo\n");
printf("se imprimir un 0; en otro caso, no\n");
printf("%d\n", x & 0x80);
}

Programacin en C. Teora

Dpto. ATC (UPV/EHU)

Sentencias condicionales: if
Operadores relacionales
OPERACIN

OPERADOR

FORMATO

Mayor

>

x>y

Menor

<

x<y

Igual

==

x == y

Mayor o igual

>=

x >= y

Menor o igual

<=

x <= y

Distintos

!=

x != y

&&

x && y

||

x || y

no

!x

DESCRIPCIN
si x>y TRUE (1)
si no FALSE (0)
si x<y TRUE (1)
si no FALSE (0)
si x==y TRUE (1)
si no FALSE (0)
si x>=y TRUE (1)
si no FALSE (0)
si x<=y TRUE (1)
si no FALSE (0)
si x!=y TRUE (1)
si no FALSE (0)
si x eta y TRUE (1)
si no FALSE (0)
si x edo y TRUE (1)
si no FALSE (0)
si x FALSE (0)
si no TRUE (1)

Notas:

En las comparaciones por igual hay que utilizar == (y no =)


(j!=0) y (j) son equivalentes, al igual que (j==0) y (!j)
En los if-s anidados, la rama else se corresponde siempre con el ltimo if escrito. En
caso de no ser as, hay que utilizar llaves.

#include <stdio.h>
main()
/* mayor de dos nmeros */
{
int a, b, mayor;
printf("Introduce dos nmeros:\n");
scanf("%d", &a);
scanf("%d", &b);
if (a > b)
mayor = a;
else
mayor = b;

// tambin { ins1; ins2;}

/* tambin: mayor = (a > b) ? a : b; */


printf ("El mayor entre %d y %d: %d", a, b, mayor);
}

Programacin en C. Teora

Dpto. ATC (UPV/EHU)

Sentencias condicionales: switch


#include <stdio.h>
main()
{
char c;
int a=10,b=5;
printf ("Introduce +, -, * /:\n");
scanf ("%c", &c);
switch (c)
{
case '+': printf
break;
case '-': printf
break;
case '*': printf
break;
case '/': printf
break;
default: printf
break;
}

("%d\n", a+b);
// sin break, al siguiente case
("%d\n", a-b);
("%d\n", a*b);
("%d\n", a/b);
("Signo errneo\n");

}
#include <stdio.h>
main()
{
char c;
printf("Vocal?\n");
scanf("%c", &c);
switch (c)
{
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
case 'A':
case 'E':
case 'I':
case 'O':
case 'U': printf ("Es vocal\n");
break;
default: printf ("No es vocal\n");
break;
}
}

Programacin en C. Teora

10

Dpto. ATC (UPV/EHU)

Sentencias repetitivas: while, do...while


#include <stdio.h>
main ()
{
char ch;
printf ("Introduce una letra\n");
ch=getchar();
while (ch!='a' && ch!='A')
{
switch (ch)
{
case '\n': break;
default:
printf ("Has fallado\n");
}
ch=getchar();
}
printf ("Muy bien!!!");
printf ("Agur\n");
}
#include <stdio.h>
main ()
{
char ch;
printf ("Introduce una letra\n");
do
{
ch=getchar();
switch (ch)
{
case 'a':
case 'A': printf ("Muy bien!!!");
printf ("Agur\n");
break;
case '\n': break;
default: printf ("Has fallado\n");
}
}
while (ch!='a' && ch!='A');
}

Notas:

Se puede utilizar la sentencia vaca como cuerpo del bucle:


while (cond){};
while (cond);
Por ejemplo, para hacer un bucle infinito: while (1);

Programacin en C. Teora

11

Dpto. ATC (UPV/EHU)

Sentencias repetitivas: for


Notas:

Funcionamiento de la sentencia for:


for (a; b; c)
a.- Inicializacin
b.- Evaluacin de la condicin:
si FALSE, fin del for
si TRUE, se ejecuta el cuerpo del for
c.- Actualizacin y vuelta al punto b
Si no se evala ninguna condicin, el bucle sera infinito, equivalente a while(1)
Si no aparece ninguna inicializacin ni actualizacin, for y while son equivalentes
Las expresiones de la inicializacin y actualizacin pueden ser compuestas:
for (x=0, y=10; x<y; x++, y--)

#include <stdio.h>
main ()
{
char ch;
int i;
printf ("Acierta la letra. 3 intentos\n");
for (i=1; i<=3; i++)
{
ch=getchar();
switch (ch)
{
case 'a': printf ("Muy bien!!!\n");
printf ("Agur\n");
exit();
case '\n': --i;
break;
default: printf ("Has fallado\n");
}
}
printf ("Lo siento\n");
for (i=0; i<1000; i++);
printf ("Agur\n");

/* for (; ; ;); */

Programacin en C. Teora

12

Dpto. ATC (UPV/EHU)

Sentencias repetitivas: for


#include <stdio.h>
main()
{
int con, suma=0;
printf("Introduce los nmeros a sumar\n");
scanf("%d", &con);
for (;con>=0 && con<=9;)
{
suma+=con;
scanf("%d", &con);
}
printf("%d",suma);
}
#include <stdio.h>
main()
{
char dato, mascara=0x01;
int i, cont=0;
printf("Introduce un carcter:\n");
scanf("%c",&dato);
for (i=0; i<8; i++)
{
if (dato & mascara) cont++;
mascara = mascara << 1;
}
printf("En el carcter %c (%x) hay %d unos\n",
dato, dato, cont);
}

Programacin en C. Teora

13

Dpto. ATC (UPV/EHU)

Sentencias break y continue


break: provoca el fin del bucle
continue: provoca el paso a la siguiente iteracin del bucle
#include <stdio.h>
main () /* contar maysculas */
{
int i, cont=0;
char c;
printf("Introduce 80 caracteres\n");
for (i=0; i<80; i++)
{
scanf("%c", &c);
if (c>=A && c<=Z) cont++;
if (c==.) break;
}
printf("Hemos contado %d maysculas\n",cont);
}
#include <stdio.h>
main ()
{
char c;
int a, b;
a=b=0;
scanf ("%c",&c);
while (c != '*')
{
if (c=='a' || c=='A')
{
a++;
scanf ("%c",&c);
continue;
}
if (c=='b' || c=='B') b++;
scanf ("%c",&c);
}
printf("Nmero de As:%d y nmero de Bs: %d\n",
a,b);
}
for (i = 0; i <
scanf
if (c
if (c
if (c
}

Programacin en C. Teora

80; i++) {
("%c", &c);
==' ') continue;
>= 'A' && c <= 'Z') cont ++;
=='.') break;

14

Dpto. ATC (UPV/EHU)

Funciones
Notas:

La sentencia return indica el final de la funcin. Puede devolver un resultado; en caso de


no indicar nada, devuelve 0. Es habitual devolver 1 en caso de error. Sintaxis:
a.- return expresin;
b.- return (expresin);
c.- return;
Si la funcin no devuelve ningn resultado se declara como void
Los argumentos formales y los reales (utilizados en la llamada a la funcin) deben ser del
mismo tipo. Los argumentos se pueden pasar de dos formas:
a.- Por valor: no se modifican los parmetros reales
b.- Por referencia: se pasa como parmetro la direccin de la variable, por lo que
el parmetro real s se puede modificar en la ejecucin de la funcin
Las variables locales se crean al comienzo de la funcin y se destruyen al finalizar la misma

Sintaxis de una funcin:


tipo_resultado nombre_funcin (parmetros formales)
{
/* declaracin de variables locales */
/* cuerpo de la funcin */
}
tipo_resultado: void, int, char, char*, struct, ...

Ejemplo:
#include <stdio.h>
int cuadrado(int j)
{
j=j*j;
return(j);
}
main() /* ejemplo de paso de parmetros por valor */
{
int j=10;
printf("El valor %d es el cuadrado de %d\n", cuadrado(j), j);
}

Programacin en C. Teora

15

Dpto. ATC (UPV/EHU)

Funciones
#include <stdio.h>
long facto(int n)
{
long fact;
int i;

/* definicin de la funcin */

fact = 1;
i = 2;
while (i <= n) {
fact = fact * i;
i++;
}
return(fact);
}
main() /* primera versin de factorial */
{
int num;
printf("Introduce un nmero:\n");
scanf("%d", &num);
if (num<0) printf("Error: nmero negativo!\n");
else printf("El factorial de %d es %ld\n",num, facto(num));
}
#include <stdio.h>
main() /* segunda versin de factorial */
{
int num;
long facto(int n); /* prototipo de la funcin */
printf("Introduce un nmero:\n");
scanf("%d", &num);
if (num<0) printf("Error: nmero negativo!\n");
else printf("El factorial de %d es %ld\n",num, facto(num));
}
long facto(int n)
/* definicin de la funcin */
{
long fact;
int i;
fact = 1;
i = 2;
while (i <= n) {
fact = fact * i;
i++;
}
return(fact);
}

Programacin en C. Teora

16

Dpto. ATC (UPV/EHU)

Macros
Notas:

No son funciones. La llamada a una macro no genera la ejecucin de un subprograma. El


compilador sustituye cada llamada a una macro por el cuerpo de esa macro en tiempo de
compilacin.

Las macros no estn sujetas a ningn tipo de datos.


#include <stdio.h>
#define PI 3.14159
#define area(rad) (PI*(rad)*(rad))
#define perimetro(rad) (2*PI*(rad))
main ( )
{
float r;
printf ("Introduce el tamao del radio\n");
scanf ("%f", &r);
printf ("rea: %f\n", area(r));
printf ("perimetro: %f\n", perimetro(r));
}
/* definicin */
#define mayor(x,y) ((x)>(y) ? (x) : (y))
/* referencia */
res=mayor(num1, num2);
/* tras el preprocesado */
res=((num1)>(num2) ? (num1) : (num2))

Programacin en C. Teora

17

Dpto. ATC (UPV/EHU)

Arrays y punteros
1.- Declaracin de arrays
- tipo nombre[dimensin];
- tipo nombre[filas][columnas];
- El ndice del vector va desd 0 a (n-1)
- C no comprueba que el ndice supere la dimensin del vector
int x[10];
int x[10] = {-1,4,6,-9,78,12,-34,0,-1,612};
char y[5];
int men[ ] = {1,2}; /* NO int men [ ]; */
int vector_2[2][5]={ {1,2,3,4,5}, {5,4,3,2,1} };
int vector_2[2][5]={1,2,3,4,5,5,4,3,2,1};
int vector_2[][5]={ {1,2,3,4,5}, {5,4,3,2,1} };
vector_2[2]=1; /* error */
vector_2=3; /* error */

2.- Declaracin de punteros


OPERACIONES

Referencia
Puntero
Vector
Campo de una
estructura de datos

OPERADOR

FORMATO

DESCRIPCIN

&x
*p
x [i]
x.y

->

p -> a

Direccin de x
Dato apuntado por p
Elemento i del vector x
Campo y de la estructura x
Campo a de la estructura de datos

&
*
[]

apuntada por p
En C los vectores y punteros estn muy relacionados: el nombre de un vector es un
puntero al primer elemento del vector

Programacin en C. Teora

18

Dpto. ATC (UPV/EHU)

Arrays y punteros
int * pointr;
int x=10, y=0;
pointr=&x;
y=*pointr;
*pointr=100;
y=(*pointr)+1;
int *x[10];
int var=4;
x[2]=&var;

/* y=10 */
/* y=101*/

/*printf ("%d", *x[2]);*/

/* Aritmtica de punteros*/
char *p1; short *p2; long *p3;
p1++; p2++; p3++;
Aritmtica de punteros: se pueden utilizar operadores aritmticos (++, +, -, --) y
relacionales (<, >, ==, <=, >= y !=). La unidad que se suma o resta depende del tamao del
dato apuntado.

#include <stdio.h>
main ()
{
long total, ventas [12]; /* declaracin del vector */
int i;
...
leer_vector (ventas, 12); /* por referencia */
for (i=0; i<12; i++)
total = total + ventas[i];
...
void leer_vector (long v[], int elementos)
{
int i;
for (i= 0; i < elementos; i++)
scanf ("%ld", &v[i]);
}
void leer_vector (long * v, int elementos)
{
int i;
for (i= 0; i < elementos; i++)
scanf ("%ld", &v[i]);
}

Programacin en C. Teora

19

Dpto. ATC (UPV/EHU)

Arrays y punteros
3.- Cadenas de caracteres (strings)
- Una cadena de caracteres es un vector cuyos elementos son caracteres. En C el
ltimo carcter de una cadena es siempre el carcter de fin de string: '\0'

- La constante \0 se utiliza para detectar el fin del string.


- La librera estndar de C string.h contiene un conjunto de funciones para el manejo
de los strings
char y[5];
char y[5] = "agur";
char y[5] = {'a','g','u','r','\0'};
char x[5]="agur";
char *pointr;
pointr=x;
/* printf("%c",*pointr); */
pointr++;
/* *pointr='o'<=> x[1] */
char *men[]={"hola",adios","agur", "kaixo"};
char **p;
p=&(men[2]);

/* printf ("%s", *p); */


/* printf ("%c", **p); */

#include <string.h>
Funcin
char *strcat (char *s1, const char *s2)

Aade el string s2 tras el string s1.


Modifica el string s1 y devuelve tambin
un puntero al nuevo string
char *strchr (const char *s, char c)
Devuelve un puntero a la posicin del
string s en el que se encuentra la primera
aparicin del carcter c. Si el carcter no se
encuentra en el string devuelve NULL
int strcmp (const char *s1, const char *s2) Compara los strings s1 y s2. Devuelve 0 si
son iguales
char *strcpy (char *s1, const char *s2)
Copia el string s2 en el string s1. Devuelve
un puntero al string s1
int strlen (const char *s)
Devuelve el nmero de caracteres del
string s (sin incluir el carcter de fin de
string)
char *strncat
Funciones idnticas a las anteriores strcat,
(char *s1, const char *s2, int n)
strcpy y strcmp, pero que actan slo
char *strncpy
sobre los primeros n caracteres de los
(char *s1, const char *s2, int n)
strings correspondientes
int strncmp
(const char *s1, const char *s
2, int n)
Programacin en C. Teora

20

Dpto. ATC (UPV/EHU)

Arrays y punteros: strings


#include <stdio.h>
#include <string.h>
#define MAX 30
char string2[]=Operativos;
int contcar(char *string, char car);
main()
{
char string1[]=Sistemas;
char string3[MAX];
strcpy(string3, string1);
strcat(string3, );
strcat(string3, string2);
printf(%d\n, contcar(string3,a));
}
/* Cuenta el nmero de apariciones del carcter car
en el string */
int contcar(char * string, char car)
{
int cont =0, i;
for (i=0; string[i]!=\0; i++)
if (string[i]== car) cont ++;
return(cont);
}
/* contcar con punteros */
int contcar(char *string, char car)
{
int cont =0;
char *p;
for (p=string; *p!=\0; p++)
if (*p== car) cont ++;
return(cont);
}

Programacin en C. Teora

21

Dpto. ATC (UPV/EHU)

Arrays y punteros
4.- Funciones para la gestin de memoria dinmica
Funcin
void * malloc (int tam)

void *calloc (int elem, int tam )

void *realloc (void *p, int tam)

void free (void *p)

#include <stdlib.h>

Descripcin
Reserva espacio en memoria para un objeto de tamao tam.
Devuelve un puntero al espacio reservado, en caso de
problemas devuelve NULL (no hay espacio suficiente,
etc.). El espacio de memoria queda sin inicializar
Reserva espacio en memoria para elem elementos de
tamao tam (tamao de un elemento en bytes). Devuelve
un puntero al espacio reservado, en caso de problemas
devuelve NULL. Inicializa a 0 el espacio de memoria
Cambia el tamao del espacio apuntado por el puntero p al
tamao tam. Reorganiza la memoria reservada previamente
con malloc, calloc o realloc, cambiando el tamao de ese
espacio. Devuelve un puntero al espacio reservado.
Libera el espacio de memoria apuntado por p, reservado
previamente con malloc, calloc o realloc.

#include <stdio.h>
#define MAX 1000
main ( )
{ int n,i;
int list [MAX];
printf ("Cuntos valores?:");
scanf ("%d",&n);
if (n>MAX)
{
printf("Error!\n");
exit(-1);
}
for (i=0; i<n; i++)
scanf ("%d",&list[i]);
}
/* utilizando memoria dinmica */
#include <stdio.h>
#include <stdlib.h>
main ( )
{ int n,i;
int * list;
printf ("Cuntos valores?:");
scanf ("%d",&n);
list = (int *) malloc (n*sizeof (int));
for (i=0; i<n; i++)
scanf ("%d", list+i);
}

Arrays y punteros: memoria dinmica


// producto de dos matrices
// dimensiones: m, n y p (se leen desde el teclado)
// C[m,p]=sumar(A[m,n]*B[n,p])
Programacin en C. Teora

22

Dpto. ATC (UPV/EHU)

#include <stdio.h>
#include <stdlib.h>
void leer_matriz (float **M, int filas, int col);
void print_matriz (float **M, int filas, int col);
void borrar_matriz (float **M, int filas)
{
int i;
for (i=0;i<filas;i++) free(M[i]);
free(M);
}
main ()
{
int m,n,p,i,j,k;
float **A, **B, **C;

/* memoria dinmica */

printf (Introduce las dimensiones m,n y p\n);


scanf (%d %d %d,&m,&n,&p);
A= (float **) malloc (m*sizeof (float*));
for (i=0;i<m;i++) A[i]=(float *) malloc (n*sizeof(float));
B= (float **) malloc (n*sizeof (float*));
for (i=0;i<n;i++) B[i]=(float *) malloc (p*sizeof(float));
C= (float **) malloc (m*sizeof (float*));
for (i=0;i<m;i++) C[i]=(float *) malloc (p*sizeof(float));
leer_matriz(A,m,n);
leer_matriz(B,n,p);
for (i=0; i<m; i++)
for(j=0; j<p; j++)
{
C[i][j]=0;
for(k=0; k<n; k++)
C[i][j]= C[i][j]+A[i][k]*B[k][j];
}
print_matriz(C,m,p);
borrar_matriz(A,m);
borrar_matriz(B,n);
borrar_matriz(C,m);
}

Programacin en C. Teora

23

Dpto. ATC (UPV/EHU)

Arrays y punteros
5.- Parmetros por referencia
void main()
{ int a , b;
printf(Introduce dos valores\n);
scanf(%d %d, &a, &b);
intercambiar (&a, &b); /* por referencia
printf (%d %d\n, a, b);
}
void intercambiar (int
/* los parmetros son
{
int tmp; /* variable
tmp = *x; *x = *y;*y
}

@ variables */

*x, int *y)


punteros */
local */
= tmp;

6.- Parmetros de la funcin main


- int argc: indica el nmero de parmetros que se reciben

- char *argv[]: es un vector de strings. Cada string es un parmetro que


recibe la funcin main. El primer parmetro, argv[0], es siempre el nombre
del programa
void main(int argc, char * argv[])
/*vector de strings */
{
printf("nombre del programa:%s\n",argv[0]);
for (int i=1; i<argc; i++)
printf("argumentos %d:%s\n",i,argv[i]);
}
#include <stdio.h>
#include <stdlib.h>
long facto (int n)
{
long res; int i;
for (i=1, res=1; i<=n; i++) res*=i;
return(res);
}
void main (int argc, char *argv[])
{
int num;long factorial;
num = atoi(argv[1]);
factorial = facto(num);
printf (El factorial de %d es %ld\n,
num,factorial);
}
Programacin en C. Teora

24

Dpto. ATC (UPV/EHU)

Arrays y punteros
7.- Punteros a funciones
La funcin representa en una direccin de memoria que se puede asignar a un
puntero. La direccin de la funcin es el punto de entrada de la funcin y se puede
utilizar para llamar a la funcin.
#include <stdio.h>
void main ()
{
int y, x=5;
int (*funcion)(int);
int pot2(int);
int pot3(int);
funcion=pot2;
y=funcion(x);
printf("%d al cuadrado: %d\n",x,y);
funcion=pot3;
y=funcion(x);
printf("%d al cubo: %d\n",x,y);
}
int pot2 (int x)
{
return (x * x);
}
int pot3 (int x)
{
return (x * x * x);
}

Programacin en C. Teora

25

Dpto. ATC (UPV/EHU)

Estructuras de datos
1.- Estructuras (struct)
- La definicin de una estructura se realiza en dos fases: primero se definen los
campos que forman parte de la estructura, y a continuacin se define una variable
de esa estructura.
- Para definir estructuras se utiliza la palabra clave struct.
struct libro
{
int cod;
int preciov;
};
struct libro lib;

struct libro
{
int cod;
int preciov;
}lib;

struct
{
int kod;
int preciov;
}lib;

# include <stdio.h>
# include <string.h>
struct libro
{
int cod;
int preciov;
char titulo[30];
};
/* funcin para leer los datos de un libro */
int leer_lib ( struct libro *plib)
{
char aux2[30];
int aux1;
printf(\n\n cdigo del libro: \n);
scanf(%d, &aux1);
plib->cod=aux1;
if (plib->cod>=0)
{
printf(ttulo del libro: \n);
scanf(%s, aux2);
strcpy(plib->titulo, aux2);
printf(precio de venta del libro: \n);
scanf(%d, &aux1);
plib->preciov=aux1;
}
return(plib->cod);
}

Programacin en C. Teora

26

Dpto. ATC (UPV/EHU)

Estructuras de datos: struct


void print_libro (struct libro *plib)
{
printf ("%d %s %d \n",plib->cod,
plib->titulo, plib->preciov);
// plib->cod y (*plib).cod es el mismo acceso
}
void print_lib (int min, int max)
{
struct libro lib; /* variable de tipo libro */
int cod-fin;
cod-fin = leer_lib(&lib);
while (cod-fin > = 0)
{
if ((lib.preciov<=max)&&(lib.preciov>=min))
printf(%d %s %d \n,lib.cod, lib.titulo,
lib.preciov);
cod-fin = leer_lib (&lib);
}
}

#define MAX 40
#define NMAX 20
struct nodo {
char nombre [MAX];
struct nodo *izda, *dcha;
};
struct nodo arbol[NMAX]; /* vector de estructuras */
void print_arbol(struct nodo *pnodo)
{
if (pnodo!=NULL){
print_arbol(pnodo->izda);
printf("%s\n", pnodo->nombre);
print_arbol(pnodo->dcha);
}
}

Programacin en C. Teora

27

Dpto. ATC (UPV/EHU)

Estructuras de datos
2.- Campos de bits
struct dispositivo {
unsigned activado: 1;
unsigned listo: 1;
unsigned error: 1;
unsigned operacion: 4;
}cdis;
......
void inicializar_escritura ()
{
cdis.activado=1;
cdis.listo=1;
cdis.error=0;
cdis.operacion=3;
}
byte
0

cdis.activado

cdis.listo

cdis.error

3
4
5

cdis.operacion

6
7

sin uso

3.- Enumerados (enum)


enum semana {lunes, martes, miercoles, jueves,
viernes, sabado, domingo};
long tarifa (enum dia, long tar1, long tar2)
{
switch (dia){
case sabado:
case domingo: return (tar2);
default: return (tar1); }
}

4.- Sinnimos
typedef short bool; /* bool es sinnimo de short */
bool and_logica (bool a, bool b)
{
return (a&b);
}
Programacin en C. Teora

28

Dpto. ATC (UPV/EHU)

Estructuras de datos
5.- Uniones (union)
union numero{
int entero;
double real;
char string[16];
};
int main()
{
union numero dato;
printf(El tamao de un int es %d\n, sizeof(int));
printf(El tamao de un double es %d\n, sizeof(double));
printf(El tamao de un char[16] es %d\n,
sizeof(char[16]));
printf(El tamao del union es %d\n,
sizeof(union numero));
dato.entero = 8;
printf(El valor entero del union es %d\n,dato.entero);
dato.real = 8.24;
printf(El valor real del union es %f\n,dato.real);
strcpy(dato.string, 8.24132);
printf(El valor del string del union es %s\n,
dato.string);
return(0);
}
struct fecha
{
char dia[2];
char mes[2];
char anyo[4]
};
union fecha_facil
{
char fecha1[8];
struct fecha fecha2;
};

Programacin en C. Teora

29

Dpto. ATC (UPV/EHU)

Declaracin de variables
register
static
extern

interno

static
extern

externo

tipo_almac.

tipo_dato

void escalares

nombre

inicializacion

estructurados

puntero char num. enum


string array struct union bits
enteros

reales

int long short

float double

mbito
Programa
Fichero fuente
Funcin
Bloque

Tipo de almacenamiento
Register. La variable se almacena en los registros internos del procesador. Se utiliza para
variables de tipo int o char, y slo dentro de un bloque
Static. Para variables definidas fuera de una funcin (globales) limita su mbito al fichero en
el que estn definidas. En el caso de variables definidas dentro de una funcin (locales), hace
que el tiempo de vida de la variable sea permanente.
Extern. Cuando se quiere utilizar una variable definida fuera del mdulo de compilacin, hay
que definir esa variable en el mdulo como externa, indicando que su definicin est fuera del
mdulo actual.
Programacin en C. Teora

30

Dpto. ATC (UPV/EHU)

Declaracin de variables
int var_global=-1;

/* variable global */

main (int argc, char *argv[])


{
int i, j, k;
/* variables locales */
struct tipo_local
{
int k;
int j;
} var_local[MAX];

for (i=0; i<20; i++)


{
int k=5;

}
var_global--;

/* variable local */

}
int desde_aqui=0;

/* variable global */

void funcion_desde_aqui()
{
desde_aqui++;
var_global++;
}
#include <stdio.h>
int j=10;

/* definida para todo el programa */

int f1()
{
int j=0;

/* definida para la funcin */

for (;j<3;j++) printf(j: %d\t,j);


}
main ()
{
f1();
printf(J: %d,j);
}

Imprimir:

j: 0

Programacin en C. Teora

j: 1

j: 2

J: 10

31

Dpto. ATC (UPV/EHU)

Declaracin de variables
char *n_mes[]={"error","enero","febrero","marzo",
"abril","mayo","junio","julio",
"agosto", "setiembre", "octubre",
"noviembre", "diciembre"};
char * nom_mes(int n)
{
return (((n<1) || (n>12))?n_mes[0]:n_mes[n]);
}
char * nom_mes(int n)
{
static char * n_mes[]={"error",
"enero", "febrero", "marzo",
"abril", "mayo", "junio", "julio",
"agosto", "setiembre", "octubre",
"noviembre", "diciembre"};
return (((n<1) || (n>12))?n_mes[0]:n_mes[n]);
}
/*Con variables static son vlidas las inicializaciones
static char c[5]="hola";
dentro de funciones */
#include <stdio.h>
void funcion1 ()
{
static int k=5;
k++;
printf (k: %d\t,k);
}
main ()
{
int k=-1;
for (int i=0;i<3;i++) funcion1();
printf (K: %d\n,k);
}

Imprimir:

k: 6

Programacin en C. Teora

k: 7

k: 8

K: -1

32

Dpto. ATC (UPV/EHU)

Declaracin de variables
/* fichero pila.c */
#define MAXVAL 100

/*profundidad mxima de la pila*/

static int sp=0;


/*apuntador de la pila*/
static double val [MAXVAL];
/*pila*/
double push(double f)
/*introduce f en la pila*/
{
if (sp<MAXVAL)
return (val[sp++]=f);
else{
printf("error: stack full\n");
return (0);
}
}
double pop ()
/*extrae el elemento superior de la pila*/
{
if (sp>0)
return (val [--sp]);
else{
printf ("error: stack empty\n");
return (0);
}
}
void clear()
{
sp=0;
}

/*limpia la pila*/

Variables CONST
Garantiza que el valor de la variable no se modificar despus de su inicializacin. Su objetivo
es asegurar que no se modifican variables que se suponen de solo lectura.
const char cadena[100]=Este string no se puede modificar!!!
int var1=19;
int *const var2=&var1;

Programacin en C. Teora

/* se puede modificar */
/ el puntero var2 no se puede modificar */

33

Dpto. ATC (UPV/EHU)

Entrada/Salida (#include <stdio.h>)


1.- E/S por caracteres: printf (sprintf)
int printf (char *formato, lista_argumentos_valor)
Imprime por la salida estndar (stdout) la lista de argumentos formateada de acuerdo al string
de formato. La lista de argumentos est compuesta de expresiones separadas por comas.
Devuelve un valor negativo si hay error y, en caso contrario, devuelve el nmero de
caracteres escritos.
El string de formato contiene dos tipos de objetos:
-

caracteres ordinarios: que sencillamente se copian en la salida estndar,


especificadores de conversin: originan la conversin e impresin del siguiente
argumento de la lista de argumentos. Cada especificacin de conversin comienza con el
carcter % y acaba en un carcter de conversin. En medio puede haber un modificador.

% [modificador] carcter de conversin


Si el carcter que sigue al % no es ninguno de los indicados como caracteres de conversin,
dicho carcter se imprime tal cual.

Caracteres de conversin:
d,i
Conversin a decimal con signo (int)
o
x,X
u
c

El argumento se convierte a notacin octal (int)


Conversin a notacin hexadecimal sin signo. (int)
Conversin a entero decimal sin signo (unsigned int)
El argumento se imprime como un carcter (char)

El argumento es un string de caracteres (char *). Se imprimen los caracteres del


string hasta encontrar el carcter \0 de fin de string o hasta alcanzar el nmero de
caracteres indicado como precisin.
Conversin a coma flotante con formato [-]mmm.nnnnnn (double). La precisin
por defecto es 6.

g,G

Conversin a coma flotante con signo en notacin [-]m.nnnnnnE[]xx (double). La


precisin por defecto es 6.
Emplea el ms corto de %e o %f (double). Se usa %f, salvo si el exponente es

menor que 4
Imprime en hexadecimal el valor de un puntero (void *)

e,E

Programacin en C. Teora

34

Dpto. ATC (UPV/EHU)

Modificadores [%flagsanchura.precisionhlLcarcter_conversin]
flags Por defecto, el argumento se imprime justificado a la derecha. Se puede cambiar la
forma de imprimir un argumento teniendo en cuenta los siguientes flags.
- justifica a la izquierda
+ imprime siempre el signo del nmero
espacio imprime un espacio si el primer carcter no es un signo
0: rellena a ceros el nmero
# imprime con 0, 0x, 0X en el caso de o, x, X
mantiene el punto decimal en e, E, f, g, G
no elimina los ceros por detrs en g, G
anchura El argumento se imprime como mnimo con la anchura indicada por este valor. Si
es necesario se rellena el campo hasta conseguir esa anchura
punto Se utiliza para separar la anchura y la precisin
precisin Indica el mximo nmero de caracteres a imprimir si se trata de un string, el
mnimo nmero de dgitos si se trata de un entero o el mnimo nmero de
dgitos decimales para un valor real
hlL El carcter h, l o L se combina con el carcter de conversin para indicar la conversin
a realizar a la hora de imprimir ese argumento: h para short o unsigned short, l para
long o unsigned long y L para long double.
Por ejemplo, dada la variable char *s=hello, world(12 caracteres), a continuacin se
muestran varios ejemplos de posibles impresiones de esa variable de acuerdo a los
modificadores utilizados. Se ha marcado con el carcter : los lmites del campo impreso.
%s
%10s
%.10s
%.15s

:hello,
:hello,
:hello,
:hello,

world:
world:
wor:
world:

%-10s
%-15s
%15.10s
%-15.10s

:hello, world:
:hello, world
:
:
hello, wor:
:hello, wor
:

Tambin se puede indicar la anchura o la precisin con el carcter *. Esto indica que ste
nmero se proporciona como argumento:
double valor;
int anchura, precision;
printf (%*.*f,anchura,precision,valor);
Otros caracteres importantes:
\'
\n

comilla simple
nueva lnea

\"
\t

comillas dobles
tabulacin horizontal

\\ barra invertida

int sprintf (char *s, char *formato, lista_argumentos_valor)


Similar a printf, pero en lugar de imprimir en la salida estndar, crea un string s de acuerdo al
formateo de los argumentos proporcionados.

Programacin en C. Teora

35

Dpto. ATC (UPV/EHU)

Entrada/Salida
2.- E/S por caracteres: scanf (sscanf)
int scanf (char *formato, lista_argumentos_referencia)
Lee caracteres desde la entrada estndar (stdin), los formatea de acuerdo a la especificacin
de la lista de argumentos y almacena los resultados en las variables indicadas como
argumento (todos las variables deben ser punteros, variables por referencia). Finaliza cuando
se ha acabado de procesar la lista de argumentos (devuelve el nmero de argumentos
procesados), si se llega al fin de entrada (devuelve EOF, -1) o si no hay concordancia entre la
entrada y el tipo de argumento a leer (devuelve 0).
El string de formato puede contener:
- blancos, tabuladores o fines de linea: que no se tienen en cuenta.
- especificadores de conversin: formado por:
a) el carcter %
b) un carcter opcional de suspensin de asignacin (el carcter *). El siguiente
campo no se asigna a ninguna variable
c) un nmero opcional que indica el tamao mximo del campo
d) el carcter h o l, para indicar short o long (debe preceder a d, i, o, u, x), o el
carcter l o L para indicar double o long double (slo para e, f, g)
e) el carcter de conversin.
% [* ] [n] [hlL]carcter de conversin
Caracteres de conversin:
d,i
se espera un nmero decimal a la entrada. Argumento int *
o
se espera un entero octal (con o sin 0 a la izquierda). Argumento int *
x,X
se espera un entero hexadecimal (con o sin ceros a la entrada). El argumento debe
ser int *
u

conversin a entero decimal sin signo (unsigned int *)

lee y asigna uno (por defecto) o ms caracteres (incluye espacio en blanco).


Argumento char *
lee y asigna un string de caracteres (con el \0). El argumento debe ser char*
se espera un nmero en coma flotante, en notacin de punto fijo [-]mmm.nnnnnn o
cientfica [-]m.nnnnnnE[]xx. El argumento debe ser float *

s
e,f,g

Entrada: 25 enero 2005


int dia, anno;
char mes[20];
scanf (%d %s %d,&dia,mes,&anno); // salta los blancos

int sscanf (char *s, char *formato, lista_argumentos_referencia)


Similar a scanf, pero en lugar de leer desde la entrada estndar, procesa los caracteres desde el
string s pasado como parmetro.
Programacin en C. Teora

36

Dpto. ATC (UPV/EHU)

Entrada/Salida
3.- Otras funciones de E/S por caracteres: getchar, putchar, gets, puts
Funcin
int getchar ()
int getch()
int putchar (int c)
char *gets (char *s)
int puts (const char *s)

Descripcin
Lee el siguiente carcter de la entrada estndar, convertido en int
Imprime el carcter c en la salida estndar
Lee la siguiente lnea de la entrada estndar en s. Reemplaza \n
por \0. Devuelve s o NULL (error o EOF)
Escribe el string s en la salida estndar. Sustituye \0 por \n.
Devuelve un valor no negativo si no hay error o EOF si error.

#include <stdio.h>
int leer_linea (char *linea)
{
int c, i=0;
do {
c=getchar(); // conversin char --> int
linea[i]=c;
// conversin int --> char
i++;
}
while ((c!=\n) && (c!=EOF));
linea[i]=\0; // fin de string
return (i);
}
#include <stdio.h>
int leer_linea (char *linea)
{
int i;
gets(linea);
for (i=0; linea[i]!=\0; i++); // sin cuerpo
return (i+1);
}

Programacin en C. Teora

37

Dpto. ATC (UPV/EHU)

Entrada/Salida
4.- E/S con ficheros: fopen y fclose
FILE* fopen (const char * nombre_fichero, const char *modo)
Abre el fichero especificado (nombre_fichero) en el modo indicado (modo). Devuelve un puntero al
fichero (FILE*) si todo ha sido correcto o NULL si ha habido algn problema.

int fclose (FILE *fp)


Cierra el fichero especificado por el descriptor fp Devuelve EOF en caso de error y 0 en caso
contrario.
Modo
r

Descripcin
lectura (error si no existe)

Posicin puntero

escritura
(si el fichero existe, borra su contenido)
escritura al final (append)
(si no existe, lo crea)
lectura + escritura (error si no existe)

comienzo

a
r+
w+
a+

lectura + escritura
(si el fichero existe, borra su contenido)
lectura + escritura al final (append)

Funcin
int fprintf (FILE *fp,
char *formato, lista_argumentos_valor)
int fscanf (FILE *fp,
char *formato, lista_argumentos_ref)
char *fgets (char *s, int n, FILE *fp)

int fputs (const char *s, FILE *fp)


int getc (FILE *fp)
int fgetc (FILE *fp)
int putc (int c, FILE *fp)
int fputc (int c, FILE *fp)
int ungetc (int c, FILE *fp)

int feof (FILE *fp)


int fflush (FILE *fp)
FILE * tmpfile ()

Programacin en C. Teora

comienzo

final fichero
comienzo
comienzo
final fichero

Descripcin
Similar a printf, con salida a un fichero
Similar a scanf, con entrada desde un fichero
Lee una cadena de n-1 caracteres desde el fichero
sobre el string s. Acaba si encuentra \n o EOF.
Aade al string el carcter \0. Devuelve s o NULL
si ha habido error
Similar a puts, con salida a un fichero.
Devuelve el siguiente carcter del fichero, convertido
en int. Si fin de fichero o error, devuelve EOF
Escribe el carcter c convertido en char en el fichero.
Devuelve c o EOF en caso de error
Devuelve el carcter c (en principio, el ltimo ledo
previamente mediante getc) al fichero. La siguiente
lectura vuelve a leer el mismo carcter c
Devuelve TRUE (!=0) si una lectura o escritura
previa han llegado a fin de fichero
Fuerza el almacenamiento del buffer en el fichero
Crea un fichero temporal en escritura. El fichero se
borra automticamente en fclose o al acabar el
programa

38

Dpto. ATC (UPV/EHU)

Entrada/Salida
#include <stdio.h>
#define MAX 80
main ()
{
FILE *infile, *outfile;
char f1[20],f2[20],palabra[MAX];
int total_palabra;
printf ("\nIntroduce el fichero de lectura: ");
scanf ("%s",f1);
infile=fopen(f1,"r");
printf ("\nIntroduce el fichero de salida: ");
scanf ("%s",f2);
outfile=fopen(f2,"w");
while (fscanf(infile,"%s",palabra)!= EOF)
{
total_palabra=strlen(palabra);
fprintf(outfile,"%d %s\n",total_palabra,palabra);
}
fclose(infile);
fclose(outfile);
}
#include <stdio.h>
#define MAX 80
main ()
{
FILE *infile, *outfile;
char f1[20],f2[20],linea[MAX];
int total_linea;
printf ("\nIntroduce el fichero de lectura: ");
scanf ("%s",f1);
infile=fopen(f1,"r");
printf ("\nIntroduce el fichero de salida: ");
scanf ("%s",f2);
outfile=fopen(f2,"w");
while (fgets(linea,MAX,infile)!= NULL)
{
total_linea=strlen(linea);
fprintf(outfile,"%d %s\n",total_linea,linea);
}
fclose(infile);
fclose(outfile);
}
Programacin en C. Teora

39

Dpto. ATC (UPV/EHU)

Entrada/Salida
5.- E/S binaria: fread y fwrite
int fread (void *p, int lon, int num_elem, FILE *fp)
Lee del fichero un bloque de num_elem elementos, cada uno de los cuales tiene de longitud lon
bytes. Almacena el bloque ledo en el espacio apuntado por el puntero p. La funcin acabar cuando
se lea el bloque, se llegue a fin de fichero u ocurra algn error. En cualquier caso, devuelve el
nmero de elementos ledos.

int fwrite (void *p, int lon, int num_elem, FILE *fp)
Escribe en el fichero un bloque de num_elem elementos de tamao lon bytes cada uno, almacenados
en el espacio apuntado por p. Devuelve el nmero de elementos escritos (num_elem salvo que haya
existido algn error).
#include <stdio.h>
main(int argc, char *argv[])
{
FILE *infile,*outfile;
char buffer[200];
int lon;
------do {
lon=fread(buffer,1,200,infile);
fwrite(buffer,1,lon,outfile);
}
while(lon==200);
}

6.- Acceso directo: fseek


int fseek (FILE *fp, long num_bytes, int origen)
Posiciona el fichero en num_bytes a partir del origen indicado. Devuelve 0 si la operacin ha sido
correcta. Posibles valores para el origen:
SEEK_SET: posicin respecto al principio del fichero
SEEK_CUR: posicin respecto a la posicin en curso
SEEK_END: posicin respecto al fin de fichero

long ftell (FILE *fp)


Devuelve el nmero de bytes desde el comienzo del fichero hasta la posicin actual, es decir,
devuelve la posicin actual dentro del fichero. En caso de error, devuelve 1.

void rewind (FILE *fp)


Sita la posicin del fichero al comienzo del fichero.
Programacin en C. Teora

40

Dpto. ATC (UPV/EHU)

Entrada/Salida
// programa cp
cp f1 f2
# include <stdio.h>
# define SALTO 10L
# define TAM 50
void error(int tipo);
main ()
{
FILE *fentrada, *fsalida;
char buffer[TAM];
int n;
if ((fentrada=fopen("fich1.c","r"))==NULL) error(1);
if ((fsalida=fopen("fich2.c","w"))==NULL) error(1);
if (fseek(fentrada,SALTO,SEEK_SET)!=0) error(2);
while ((n=fread(buffer,sizeof(char),TAM,fentrada))!=0)
if (fwrite(buffer,sizeof(char),n,fsalida)!=n) error(3);
if (!feof(fentrada)) error(4);
if (fclose(fentrada)==EOF) error(5);
if (fclose(fsalida)==EOF) error(5);
}
// programa cat
cat f1 f2 f3
#include <stdio.h>
void volcar_fichero (FILE *file)
{
char c;
do
{
c = fgetc (file);
fputc (c, stdout);
}
while (c!= EOF);
}
main (int argc, char *argv[])
{
FILE *fp;
int i;
if
(argc < 2) volcar_fichero(stdin);
else
for (i=1; i<argc; i++){
fp = fopen (argv [i], "r");
if
(fp == NULL)
{ fprintf (stderr,"error al abrir\n");
exit (1);}
else volcar_fichero (fp);
fclose (fp); }
exit (0);
}

Entrada/Salida
struct libro {
Programacin en C. Teora

41

Dpto. ATC (UPV/EHU)

int cod;
char titulo[30],autor[30];
int precio;
};
#define TOPE 10
void escribirf_libros (char *nombref)
{
struct libro unlibro;
FILE *fd;
int i;
fd=fopen(nombref,wb);
for (i=0;i<TOPE;i++)
{
printf (Introduce el cdigo del libro: \n);
scanf (%d,&(unlibro.cod));
printf (Introduce el ttulo y autor del libro: \n);
scanf (%s %s,unlibro.titulo, unlibro.autor);
printf (Introduce el precio del libro: \n);
scanf (%d,&(unlibro.precio));
printf (Datos introducidos: %d\t%s\t%s\t%d\n,
unlibro.cod, unlibro.titulo,
unlibro.autor, unlibro.precio);
fwrite (&unlibro,sizeof(struct libro),1,fd);
}
fclose(fd);
}
void leerf_libros (char *nombref)
{
struct libro unlibro;
FILE *fd;
int i;
fd=fopen(nombref,rb);
for (i=0;i<TOPE;i++)
{
fread (&unlibro,sizeof(struct libro),1,fd);
printf (Datos ledos: %d\t%s\t%s\t%d\n,
unlibro.cod, unlibro.titulo,
unlibro.autor, unlibro.precio);
}
fclose(fd);
}

Programacin en C. Teora

42

Dpto. ATC (UPV/EHU)

Entrada/Salida
#include <stdio.h>
#include <ctype.h>
main(int argc, char *argv[])
{
FILE *update;
int fpos;
char c;
if((update=fopen(argv[1],r+))==NULL)
{
fprintf(stderr,%s: error al abrir %s\n,
argv[0],argv[1]);
exit(-1);
}
while ((c=fgetc(update))!=EOF)
{
if (isupper(c))
{
fpos=ftell(update);
fseek(update,fpos-1,SEEK_SET);
fputc(tolower(c), update);
}
/* OTRA POSIBILIDAD
if (isupper(c))
{
ungetc(c,update);
fputc(tolower(c), update);
}
*/
}
fclose(update);
}

Programacin en C. Teora

43

Dpto. ATC (UPV/EHU)

Libreras estndares de C
1.- Funciones para el manejo de caracteres
Funcin
int tolower (int car)
int toupper (int car)
int islower (int car)
int isupper (int car)
int isalpha (int car)
int isdigit (int car)
int isalnum (int car)
int iscntrl (int car)
int isspace (int car)

#include <ctype.h>

Descripcin
Si car es un carcter mayscula, devuelve su correspondiente
minscula. En otro caso, devuelve car
Si car es un carcter minscula, devuelve su correspondiente
mayscula. En otro caso, devuelve car
True si car es minscula
True si car es mayscula
True si islower (car) o isupper (car)
True si car es dgito decimal
True si isalpha (car) o isdigit (car)
True si car es un carcter de control
True si car es SPACE, \f, \n, \r, \t, \v

#include <ctype.h>
#include <stdio.h>
main()
{ char car;
int num, i;
for (i=0; i<10; i++)
{ printf("Introduce un carcter:");
scanf("%c", &car);
if (isdigit((int)car))
printf("%c es numrico\n", car);
else
if (!isalpha((int)car))
printf("%c no es ni letra ni numrico\n", car);
else
if (islower((int)car))
{ num=toupper((int)car);
printf("El carcter mayscula de %c es %c\n",
car,(char)num);
}
else
{ num=tolower((int)car);
printf (El carcter minscula de %c es %c \n", car,
(char)num);
}
}
}

Programacin en C. Teora

44

Dpto. ATC (UPV/EHU)

Libreras estndares de C
2.- Funciones para conversin de nmeros
Funcin
double atof (const char *s)
int atoi (const char *s)
long atol (const char *s)
int abs (int num)
long labs (long num)

#include <stdlib.h>

Descripcin
Convierte a double la cadena de caracteres apuntada por s
Convierte a int la cadena de caracteres apuntada por s
Convierte a long la cadena de caracteres apuntada por s
Devuelve el valor absoluto de num (entero)
Devuelve el valor absoluto de num (long)

3.- Funciones para la ejecucin/fin de programas


Funcin
void exit (int estado)
int system (const char *comando)
char * getenv (const char * var)

#include <stdlib.h>

Descripcin
Provoca la finalizacin del programa, el parmetro indica
cmo acaba el programa (0 xito)
Lanza la ejecucin del comando indicado por el string
comando
Devuelve el valor de la variable de entorno asociada al
string var, o NULL si no est definida

#include <stdlib.h>
#include <stdio.h>
double calcular (int par1, double par2);
main(int argc, char *argv[])
{
int num1;
double res,num2;
if (argc !=3)
{
printf (Error en parmetros. Programa: %s\n,argv[0]);
exit(-1);
}
res = calcular (atoi(argv[1]),atof(argv[2]));
printf(El resultado es: %.4f\n,res);
}

4.- Funciones para la generacin de nmeros aleatorios


Funcin
int rand ()
void srand (unsigned int semilla)

Programacin en C. Teora

#include <stdlib.h>

Descripcin
Devuelve un valor entero aleatorio, entre los valores 0 y
RAND_MAX (constante definida en stdlib.h)
Utiliza semilla como valor de comienzo de una secuencia
de nmeros aleatorios. Si no se llama a srand antes que a
rand, el valor de comienzo siempre es 1

45

Dpto. ATC (UPV/EHU)

Libreras estndares de C
5.- Funciones para el manejo de objetos en memoria
Funcin
void * memcpy
(void *p1, const void *p2, int n)
void * memmove
(void *p1, const void *p2, int n)
void * memset
(void *p, int car, int n)
int memcmp (const void *p1,
const void *p2, int n)
void * memchr
(const void *p, int car, int n)

6.- Funciones matemticas

#include <string.h>

Descripcin
Copia en el objeto apuntado por p1 n caracteres desde el
objeto apuntado por p2. Devuelve un puntero al objeto
apuntado por p1
Igual que memcpy, pero tambin funciona aunque los dos
objetos se solapen
Inicializa los n primeros caracteres del objeto apuntado por
p con el carcter car. Devuelve un puntero al objeto
apuntado por p
Compara los n primeros caracteres de los objetos
apuntados por p1 y p2. El resultado devuelto es idntico al
de la funcin strcmp
Devuelve un puntero a la primera ocurrencia del carcter
car en el objeto apuntado por p, o NULL si el carcter no
est presente en los primeros n caracteres del objeto

#include <math.h>

Funcin
double sin (double n)
double cos (double n)
double tan (double n)
double exp (double n)
double log (double n)
double log10 (double n)
double sqrt (double n)
double pow (double x, double y)
double fabs (double n)

Descripcin
Devuelve el seno del ngulo n (expresado en radianes).
Devuelve el coseno del ngulo n (expresado en radianes)
Devuelve la tangente del ngulo n (expresado en radianes)
Devuelve la exponencial de n (en)
Devuelve el logaritmo neperiano de n (ln(n)) [si x>0]
Devuelve el logaritmo en base 10 de n [si x>0]
Devuelve la raz cuadrada de n [si x0]
Devuelve xy
Devuelve el valor absoluto de n (double)

#include <math.h>
#include <stdio.h>
main()
{
double var=-1.0;
do {
printf("El seno de %lf es %lf, el coseno %lf y la tangente
%lf\n", var, sin(var), cos(var), tan(var));
if (var>=0.0)
printf("y su raz cuadrada es %lf\n", sqrt(var));
var+=0.1;
} while (var<1.1);
}

Libreras estndares de C
7.- Funciones para la gestin de la fecha y la hora
Programacin en C. Teora

46

#include <time.h>
Dpto. ATC (UPV/EHU)

Estas funciones utilizan los dos tipos de datos siguientes:


time_t: valor aritmtico para representar el tiempo
struct tm
{
int tm_sec:
/* segundos, a partir del minuto 0-59 */
int tm_min; /* minutos, a partir de la hora 0-59 */
int tm_hour; /* hora desde medianoche 0-23 */
int tm_mday; /* da del mes 1-31 */
int tm_mon; /* mes desde enero 0-11 */
int tm_year; /* ao desde 1990 */
int tm_wday; /* da de la semana, desde el domingo 0-6 */
int tm_yday; /* da del ao, desde enero 0-365 */
int tm_isdst;
};
Funcin
time_t time (time_t *tp)

double difftime
(time_t t1, time_t t2)
char * asctime
(const struct tm *tp)

struct tm * localtime
(const time_t *tp)
char * ctime
(const time_t *tp)

Descripcin
Devuelve el tiempo actual, como valor entero, o 1 si no est
disponible. Si el parmetro tp no es NULL, asigna tambin el
resultado al objeto apuntado por tp
Devuelve la diferencia en segundos entre los tiempos t2 y t1
Convierte el tiempo almacenado en la estructura tp en un string
de la forma DDD MMM dd hh:mm:ss AAAA\n\0
DDD
da de la semana (alfabtico)
MMM
mes (alfabtico)
dd
da de la semana (numrico)
hh:mm:ss horas:minutos:segundos (numricos)
AAAA
ao (numrico)
Por ejemplo: Sun Jan 3 15:14:13 1988\n\0
Convierte el tiempo almacenado en el objeto tp a una
estructura tm. Devuelve un puntero a esta estructura
Es equivalente a:
asctime(localtime(tp))

#include <time.h>
#include <stdio.h>
main()
{
time_t ltime;
time (&ltime);
printf("Fecha de comienzo: %s\n", ctime(&ltime));
llamar_funcion();
time (&ltime);
printf("Fecha de fin: %s\n", ctime(&ltime));
}

Libreras estndares de C
Tambin existe una funcin interesante para contar tiempos de ejecucin: gettimeofday. Esta
funcin est declarada en <sys/time.h> y se basa en la estructura:

Programacin en C. Teora

47

Dpto. ATC (UPV/EHU)

struct timeval {
long tv_sec;
long tv_usec;
};

/* segundos */
/* microsegundos */

int gettimeofday(struct timeval *tv, struct timezone *tz);


Esta funcin devuelve en la estructura tv un valor numrico que representa el tiempo actual. El
segundo parmetro est obsoleto y normalmente se le llama con NULL o 0. Como resultado,
devuelve 1 en caso de error y 0 si todo ha ido correctamente.
#include <sys/time.h>
#include <stdio.h>
main()
{
struct timeval tini,tfin;
double teje;
gettimeofday(&tini,0);
llamar_funcion();
gettimeofday(&tfin,0);
teje=(tfin.tv_sec-tini.tv_sec)+(tfin.tv_usec-tini.tv_usec)/1e6;
printf("Tiempo de ejecucin: %f segundos\n", teje);
}

Programacin en C. Teora

48

Dpto. ATC (UPV/EHU)

Desarrollo de programas
1.- Compilacin separada
Variables y funciones extern
Estructura de ficheros: cabeceras y declaraciones (.h) + cdigo (.c)
include de ficheros: #include <fichero.h> vs #include fichero.h

pruebalog.c
#include <stdio.h>
#include logica.h
main ()
{
bool a,b,c;
.....
c=logica(a,b);
printf (c: %d\n,c);
.....
}

logica.h
.....
typedef int bool;
.....
extern bool logica(bool x1, bool y1);
.....

logica.c
.....
typedef int bool;
.....
bool logica (bool x, bool y)
{
return (x|y);
}

cc c pruebalog.c

pruebalog.o

cc c logica.c

main
....
logica??

logica.o
logica

cc o pruebalog.exe pruebalog.o logica.o


EJECUTABLE: pruebalog.exe

Programacin en C. Teora

49

Dpto. ATC (UPV/EHU)

Desarrollo de programas
2a.- Ejemplo de compilacin separada: ordenar.c
#include <stdio.h>
#include <stdlib.h>
#define TOPE 20
long numeros[TOPE];
int num;
void leer_num ()
{
long valor;
num=0;
while (num<TOPE) {
printf("Introduce un numero:\n");
scanf("%ld",&valor);
if (feof(stdin)) break;
numeros[num++]=valor;
}
}
int el_primero(long *vector,int nelem,int modo)
{
int i, ind_primero=0;
for (i=1; i<nelem; i++)
if(modo==0) {if(vector[i]<vector[ind_primero]) ind_primero=i;}
else if(vector[i]>vector[ind_primero]) ind_primero=i;
return(ind_primero);
}
void ordenar_num(int modo)
{
int i, ind; long tmp;
for (i=0; i<num-1; i++) {
ind=el_primero(&(numeros[i]),num-i,modo);
tmp=numeros[i]; numeros[i]=numeros[i+ind]; numeros[i+ind]=tmp;}
}
main(int argc, char *argv[])
{
int i;
if (argc!=2) {
printf ("ERROR en parametros. PROGRAMA: %s 0/1\n",argv[0]);
exit(-1); }
leer_num(); ordenar_num(atoi(argv[1]));
printf("\nVector ordenado: ");
for (i=0;i<num;i++) printf("%ld ",numeros[i]);
printf("\n");
}

$gcc o ordenar ordenar.c

Programacin en C. Teora

50

Dpto. ATC (UPV/EHU)

Desarrollo de programas
2b.- Ejemplo de compilacin separada
//FICHERO: leern.h

//FICHERO: ordenarn.h

#define TOPE 20
extern long numeros[TOPE];
extern int num;
extern void leer_num();

extern void ordenar_num(int m);

#include <stdio.h>

//FICHERO: leern.c

#define TOPE 20
long numeros[TOPE];
int num;
void leer_num ()
{
long valor;
num=0;
while (num<TOPE) {
printf("Introduce un numero:\n");
scanf("%ld",&valor);
if (feof(stdin)) break;
numeros[num++]=valor;
}
}
#include "leern.h"

//FICHERO: ordenarn.c

int el_primero(long *vector,int nelem,int modo)


{
int i, ind_primero=0;
for (i=1; i<nelem; i++)
if(modo==0) {if(vector[i]<vector[ind_primero]) ind_primero=i;}
else if(vector[i]>vector[ind_primero]) ind_primero=i;
return(ind_primero);
}
void ordenar_num(int modo)
{
int i, ind;
long tmp;
for (i=0; i<num-1; i++) {
ind=el_primero(&(numeros[i]),num-i,modo);
tmp=numeros[i];
numeros[i]=numeros[i+ind];
numeros[i+ind]=tmp;
}
}

Desarrollo de programas
Programacin en C. Teora

51

Dpto. ATC (UPV/EHU)

2b.- Ejemplo de compilacin separada (continuacin)


#include <stdio.h>
#include <stdlib.h>

//FICHERO: ordenar.c

#include "leern.h"
#include "ordenarn.h"
main(int argc, char *argv[])
{
int i;
if (argc!=2)
{
printf ("ERROR en parametros. PROGRAMA: %s 0/1\n",argv[0]);
exit(-1);
}
leer_num();
ordenar_num(atoi(argv[1]));
printf("\nVector ordenado: ");
for (i=0;i<num;i++) printf("%ld ",numeros[i]);
printf("\n");
}

$gcc
$gcc
$gcc
$gcc

c
c
c
o

leern.c
ordenarn.c
ordenar.c
ordenar ordenar.o leern.o ordenarn.o

Programacin en C. Teora

52

Dpto. ATC (UPV/EHU)

Desarrollo de programas
3.- Directivas al compilador
#undef PI
#define
PI 3.14159
#define
area(r) (PI*(r)*(r))
#define

toupper(c) ((c)>='a'&&(c)<='z'? (c)&0x5F:(c))

#include
#include

<stdio.h>
"pila.h"

# if, # else, # elif, # endif


(1)

/* compilar -D_____ */

# define TRAZA 1
# if TRAZA
printf ("El valor de la variable x es %d\n",x);
# endif

(2)

# define CASTELLANO
# define EUSKERA
# define IDIOMA

1
2
CASTELLANO

# if IDIOMA == CASTELLANO
printf ("Buenos das\n");
# elif IDIOMA == EUSKERA
printf ("Egunon\n");
# else
printf ("Idioma desconocido\n");
# endif
# ifdef, # ifndef

/* compilar -D_____ */

# define TRAZA
# ifdef TRAZA
printf ("El valor de la variable x es %d\n",x);
# endif
#ifdef IBM
int reg_dat_inp = 0x378;
#else
int reg_dat_inp = 0x3B8;
#endif

$gcc DIBM ...


$gcc ...

Programacin en C. Teora

53

#IBM
#resto

Dpto. ATC (UPV/EHU)

Resumen: tipos, constantes y variables


int

float

enteros
decimal
hexadecimal
octal

ddd
0xdd
0dd

94
0x33
022

%d
%x
%o

long int
unsigned int
short int

dL
ddU
dd

l6L
987U
10

%ld
%u
%d

coma flotante
dd.ddE +-dd 3.4E -28

%f

'c', '\0' , '\n'

%c

double coma flotante


char

caracter

Arrays:
tipo nombre [n] [m] ..... [p]

(0..n-1)

String:
char nombre [n]

"ccccc"+'\0'

%s

Structs:
struct {def. variables} nombre_var;
struct tipo_struct {def. variables};
struct tipo_struct nombre_var;
Unions:
union tipo_union {def. variables} nombre_var;
Enumerados:
enum tipo_enum {elem1, elem2, ...., elemn} nombre_var;
Bits:
unsigned nombre:n;
Punteros:
tipo *nombre;
Ficheros:
FILE *descriptor_fichero;

Programacin en C. Teora

54

Dpto. ATC (UPV/EHU)

Resumen: sentencias
asignacin:
variable = expresin;
llamada a funcin:
nombre_funcion (par1,par2,...,parn);
if:
if (condicin) sentencia; else sentencia;
{
} {
}

/* cond: 0-FALSE
!=0 TRUE */

switch:
switch (expresin)
{
case cons1: sentencias;
break;
case cons2: sentencias;
break;
..............................
default:
sentencias;
}
while:
do sentencia while (condicion);
{
}
while (condicion) sentencia;
{
}
for:
for (inicializacin; condicin; cada_iteracin) sentencia;
{
}
ruptura de secuencia:
exit();
/* finaliza la ejecucin del programa */
return(expresion); /* devuelve el valor de la expresin al programa llamador */
continue;
/* nos enva al siguiente paso de la estructura repetitiva */
break;
/* nos enva fuera del switch o de la estructura repetitiva */

Programacin en C. Teora

55

Dpto. ATC (UPV/EHU)

Resumen: operadores
Aritmticos:
+
*
/
%

suma
resta
multiplicacin
divisin
mdulo

-++

decrementar (pre y post)


incrementar (pre y post)

+=
-=
*=
/=

v+=(expresin)

<=>

&
|
>>
<<

and aritmtico
or aritmtico
shift derecha
shift izquierda

^
~

v=v+(expresin)

xor aritmtico
complemento a 1

Relacionales:
== igualdad
!=
desigualdad
>
mayor estricto
<
menor estricto
>= mayor o igual
<= menor o igual
Lgicos:
&&
||
!

and lgico
or lgico
no lgico

Otros:
.
->
*
&
,
?

acceso a elementos de un struct por valor


acceso a elementos de un struct por referencia
contenido de lo apuntado por una direccin
direccin de
inicializar variables en un for
sustituir sentencias if/else con una sola expresin

Programacin en C. Teora

56

Dpto. ATC (UPV/EHU)

Resumen: operadores (por orden de evaluacin)


Primarios:

()

[]

->

(izda-dcha)

+
*
!
sizeof

&
~

++

--

(dcha-izda)

Aritmeticos1:

Aritmeticos2:

(izda-dcha)

Desplazamientos: <<

>>

(izda-dcha)

Comparacin1:

<

>

Comparacin2:

==

!=

Lgicos1:
Lgicos2:
Lgicos3:

&
^
|

(izda-dcha)

Comp_cond1:
Comp_cond2:

&&
||

(izda-dcha)

Expres_cond:

? :

(dcha-izda)

Asignaciones:

=
/=
&=

Unarios:

Separador:

(cast)

+=
%=
^=

(izda-dcha)

<=

>=

(izda-dcha)
(izda-dcha)

-=
>>=
|=

*=
<<=

(dcha-izda)

(izda-dcha)

Uso de parntesis para cambiar este orden de evaluacin.


x = y /3 - 34 * temp & 127;
int *x[]
1
2
3
char *x()[]
1
2
3
4

x = (y/3) -((34*temp)&127);

[ ]:
*:

x es
un array de
punteros a
enteros

():
[]:
*:

x es
una funcin que devuelve
un array de
punteros a
caracteres

Programacin en C. Teora

57

Dpto. ATC (UPV/EHU)

Resumen: conversin de tipos


Se convierten todos los operandos hacia el tipo del mayor operando
char ch;
float f;

int i;
double d;

result =(ch / i) + (f * d) - (f + i);


int

double float
double
double

Operador cast: (tipo) expresin


(a)

(b)

float x;
int y=4;
x = y/3;
x = (float) y / 3.0;

/* x == 1*/
/* x == 1.333 */

float x=1.25;
float z;
z = (float) exp((double) x);

Resumen: directivas al compilador


# include <stdio.h>
# include "var.h"
# define NOMBRE valor
# define toupper(c) ((c)>='a' && (c)<='z' ? (c)&0x5F : (c))
# define MIN(a,b)
((a) < (b) ? (a) : (b))
# undef PI
# define PI

2.22

# if, # else, # elif, # endif


/* compilar D_____ */
# define TRAZA 1
# if TRAZA
printf ("El valor de la variable x es %d\n",x);
# endif
# ifdef, # ifndef
/* compilar D_____ */
# define TRAZA
# ifdef TRAZA
printf ("El valor de la variable x es %d\n",x);
# endif

Programacin en C. Teora

58

Dpto. ATC (UPV/EHU)

Vous aimerez peut-être aussi