You are on page 1of 162

Conceptos bsicos de programacin

Introduccin a la programacin en C

Ordenador y perifricos

Ordenador: "mquina tonta"

Operaciones muy bsicas: aritmticas, comparaciones, almacenar y recuperar informacin/datos, ...

Dependencia del usuario/programador

Operaciones + Potencia de clculo Procesos complejos

Perifricos: interaccin con el exterior, particularmente con el usuario

Entrada: teclado, ratn, lpiz ptico, escner, ...

Salida: pantalla, impresora, plotter, ...

Entrada y salida: discos, cintas magnticas, ...

Comunicaciones: mdem, tarjetas de red, ...

Unidades de memoria

Bit : Unidad bsica de informacin

0 (falso) 1 (cierto)

Byte : 8 bits

256 combinaciones de 0s y 1s

Palabra : unidad natural de memoria en un ordenador: 32 bits, 64 bits, ...


210 bytes = 1024 bytes 210 Kb = 1024 Kb 220 = 1048576 bytes 210 Mb = 1024 Mb 230 = 1073741824 bytes 210 Gb = 1024 Gb 240 = 1099511627776 bytes

1 Kilobyte 1 Megabyte 1 Gigabyte 1 Terabyte

1 Kb 1 Mb 1 Gb 1 Tb

Lenguajes de programacin (I)


Programador
Lenguaje natural Lenguaje de programacin Lenguaje mquina

Notacin, conjunto de smbolos

Sintaxis predefinida

Dar instrucciones al ordenador Traduccin

Abstraccin

Ordenador

Lenguajes de programacin (II)

Lenguajes de bajo nivel: prximos a la arquitectura

Lenguaje mquina: 0s y 1s, crptico, etc. Lenguaje ensamblador: uso de mnemotcnicos, optimizado (menos memoria, ms velocidad, ...), etc.

Lenguajes de alto nivel: abstraccin de la arquitectura, portabilidad, traduccin a lenguaje mquina

Ciclo de vida de un programa

Anlisis: contacto con el cliente, estudio del problema y necesidades, especificacin de alto nivel, documentacin

Diseo: solucin adecuada a los recursos, lenguaje, algoritmos, herra mientas de desarrollo, bases de datos, etc., documentacin

Codificacin: traduccin de los algoritmos al lenguaje elejido, depurar errores, documentacin

Explotacin: instalacin, manuales, formacin, etc.

Mantenimiento: correccin de errores, aadir o modificar funcionali dades, etc.

Traductores (I)
lenguaje mquina

Ensambladores: lenguaje ensamblador

Intrpretes: traduccin y ejecucin de cada instruccin

Verificacin de sintaxis

Traduccin a cdigo mquina

Ejecucin

Lentitud de ejecucin !

Traductores (II)
programa ejecutable

Compiladores: programa fuente

Edicin: escritura del programa fuente

Compilacin: verificacin de sintaxis y generacin de cdigo objeto

Montaje (linkado): con otros mdulos o libreras

Velocidad de ejecucin !

Primer contacto con C

Introduccin a la programacin en C

Un poco de historia

Dennis Ritchie, 1972 (Laboratorios Bell de AT&T)

Primero: diseo del sistema operativo UNIX

Al poco tiempo: muy potente y flexible expansin

" El lenguaje de programacin C ", Kerninghan y Ritchie (1978)

Estndar ANSI ANSI C (1989)

C debe su nombre al lenguaje B

Caractersticas del lenguaje

Potencia y flexibilidad : usado en diferentes contextos

Popularidad: programadores, libreras, herramientas, ...

Portabilidad: ANSI C

Sencillez de sintaxis: pocas palabras clave

Estructura y modularidad: reutilizacin de cdigo

Aspectos no triviales: paso de parmetros, punteros, ...

Los primeros programas

void main() {

/* Mi primer programa en C */ void main() { /* Otro comentario /* Comentario ilegal */ */ } /* ... y otro comentario */

/* Mi primer programa en C */ void main() { printf("Mi primer mensaje en pantalla \n"); }

Modelo de compilacin de C

Preprocesador: eliminacin de comentarios y proceso de directivas

Compilador: traduccin a ensamblador

Ensamblador: traduccin a cdigo mquina

Montador: creacin del programa ejecutable, combinando libreras y otros ficheros objeto

Empezando a programar

Introduccin a la programacin en C

Identificadores

Nombre para referir una constante, variable, funcin, ...

Secuencia de letras, nmeros y _

No puede empezar con un nmero

Distingue maysculas y minsculas

Palabras reservadas en ANSI C:


double else enum extern float for goto if int long register return short signed sizeof static struct switch typedef union unsigned void volatile while

auto break case char const continue default do

Estructura de un programa

Directivas del preprocesador

Definiciones de tipos de datos

Declaraciones de funciones. Entre ellas el programa principal : main()

/* Evaluando una expresin */ Constante #include <stdio.h> void main() { int a, b, c = 5; Variables Sentencias

Cuerpo del programa

a = 3 * c; b = 32 / 4; c = a b;

printf("Valor resultante: %d\n", c);

Fin de sentencia

Variables

Objeto abstracto donde se almacena un valor. Se puede consultar y modificar durante la ejecucin del programa.

Declaracin: antes de ser usadas por primera vez:

Reservar espacio en memoria

Asociar un identificador

Opcionalmente, asignar un valor (inicializacin)


nombre_de_variable; nombre_de_variable, nombre_de_variable, ... ; nombre_de_variable = valor_inicial;

tipo_de_datos

tipo_de_datos

tipo_de_datos

Ejemplo:

int

a, b, c = 5;

Constantes

Se puede consultar pero no modificar su valor.

Literal: aparece cada vez que se necesita el valor:

Decimal: signo + dgito no 0 + dgitos 0 al 9 Octal: signo + 0 + dgitos 0 al 7 Hexadecimal: signo + 0x o 0X + dgitos 0 al 9 y A a F Coma flotante: signo + parte entera + . + parte decimal signo + mantisa + exponente

Simblica: asocia un valor fijo a un nombre.


#define PI 3.14 ... perimetro = 2 * PI * radio; area = PI * radio * radio;

perimetro = 2 * 3.14 * radio;

area = 3.14 * radio * radio;

Entrada y salida bsica

C proporciona entrada y salida con formato (entre comillas).

Mostrar mensajes y valores en pantalla. Ejemplo:

char int

ch; num;

. . .

printf("Un carcter: %c . Y un entero: %d\n", ch, num);

Introducir valores por teclado. Ejemplo:

char int

ch; num;

. . .

scanf("%c %d", &ch, &num);

Expresiones aritmticas
variable = expresin; Unarios

Frmula matemtica que especifica un valor

Asignacin:

Operadores:
Binarios

Cambio de signo Incremento Decremento Suma Resta Multiplicacin Divisin Mdulo

++ + * / %
z++; x = (z w) % 100; w; i += 5; x *= (y + 2);

Forma prefija y postfija de ++ y . Ejemplo:

x = ((++z) (w)) % 100;

Operacin y asignacin de forma compacta. Ejemplo:

i = i + 5; x = x * (y + 2);

Expresiones relacionales
Menor que Mayor que Menor o igual que Mayor o igual que Igual que Distinto que

Condiciones bsicas en sentencias condicionales e iterativas

Operadores:

< > <= >= == !=

Resultado lgico: falso cero cierto distinto de cero


4 > 8

Ejemplos:

falso 3 <= 24 cierto

23 == 22

falso 4 != 5 cierto

No confundir asignacin (=) con comparacin (==): x = 3 es tambin una expresin, ..., no cero cierto

Expresiones lgicas
Conjuncin Y lgico Disyuncin O lgico Negacin NO lgico

Expresiones condicionales complejas

Operadores:

&& || !

Tabla de verdad:

A cierto cierto falso falso

B cierto falso cierto falso

!A falso falso cierto cierto

A && B cierto falso falso falso

A || B cierto cierto cierto falso

Ejemplos:
(5 <= 0) || !(x > x 1) 2 && (4 > 9)

4 && 0

falso falso
(8 == 4 * 2) && (5 > 2)

!(4 > 1)

falso falso falso

(x < x 8) || 4

cierto

Prioridad de operadores
Operador Asociatividad
Izquierda a derecha Derecha a izquierda Parntesis

10

+
NO lgico
Cambio de signo () ! Izquierda a derecha Izquierda a derecha Izquierda a derecha

Smbolo

Incremento Decremento Multiplicacin Divisin Mdulo Suma Resta Menor que Menor o igual que Mayor que Mayor o igual que Igual que Distinto que Y lgico O lgico Asignaciones

Izquierda a derecha Izquierda a derecha Izquierda a derecha Derecha a izquierda

++ * / % + < <= > >= = != && || = += = *= /= %=

11

Ejercicios

Pedir la base y la altura de un rectngulo, calcular su rea y su permetro, y mostrar los resultados por pantalla.

Pedir una cantidad de segundos y mostrar por pantalla a cuntas horas, minutos y segundos corresponden.

Suponiendo la declaracin previa: int x = 7, y; , calcular el valor de la variable y tras evaluar cada una de las siguientes asignaciones:

y = 2 + x;

y += 2;

y = (y == x);

y = y++ x;

Evaluar las siguientes expresiones:

5 / 2 + 20 % 6

4 * 6 / 2 15 / 2

5 * 15 / 2 / (4 2)

8 == 16 || 7 != 4 && 4 < 1

(4 * 3 < 6 || 3 > 5 2) && 3 + 2 < 12

Estructuras condicionales

Introduccin a la programacin en C

Introduccin

Ejecucin de un grupo de sentencias u otro, en funcin del valor de una expresin condicional.

C no dispone de valores booleanos. Los "simula" como:

Falso : valor 0

Cierto : cualquier valor distinto de 0 (tambin negativos)

Diversas estructuras: if , ifelse y ifelseif Operador condicional ? switch

Alternativa simple: if (I)


if (condicin) { sentencia_1; sentencia_2; . . . sentencia_N; }

if (condicin) sentencia;

Evaluacin de la condicin (expresin entera)

Si la expresin es cierta, entonces se ejecuta la sentencia o grupo de sentencias

Si la expresin es falsa, se ignora la sentencia o grupo de sentencias, y se ejecuta la siguiente sentencia en orden secuencial.

Alternativa simple: if (II)

Ejemplo:

#include <stdio.h> void main() { int a;

scanf("%d", &a); if (a % 2 == 0) a = a + 1;

printf("Ahora es impar: %d\n", a);

Alternativa doble: ifelse (I)


if (condicin) { grupo_de_sentencias_1; } else { grupo_de_sentencias_2; }

if (condicin) sentencia_1; else sentencia_2;

Generalizacin de la anterior

Evaluacin de la condicin (expresin entera)

Si la expresin es cierta, entonces se ejecuta el primer grupo de sentencias, y si es falsa, entonces se ejecuta el segundo grupo de sentencias

La ejecucin continua en la siguiente sentencia en orden secuencial

Alternativa doble: ifelse (II)

Ejemplo:

#include <stdio.h> void main() { int a, b, max;

scanf("%d %d", &a, &b); if (a > b) max = a; else max = b;

prinf("El mximo es: %d\n", max);

Alternativa doble: ifelse (III)

else es opcional ambigedad en anidaciones

Regla: else se asocia al if ms cercano, si no est ya asociado a otro else

Para romper la regla se usan { }

Ejemplo: . . . if (n > 0){ if (a > b) z = a; } else z = b; . . .

. . .

if (n > 0) if (a > b) z = a; else z = b;

. . .

Alternativa mltiple: ifelseif (I)

if (condicin_1) { grupo_de_sentencias_1; } else if (condicin_2) { grupo_de_sentencias_2; } . . . else if (condicin_N) { grupo_de_sentencias_N; } else { grupo_de_sentencias_por_defecto; }

Evaluacin secuencial de arriba hacia abajo sentencias por defecto mejor legibilidad

Si ninguna condicin es cierta

El ltimo else es opcional

Uso adecuado de { } y sangrado/indentacin

Alternativa mltiple: ifelseif (II)

Ejemplo:

#include <stdio.h> void main() { int hora;

scanf("%d", &hora); if ((hora >= 0) && (hora < 12)) printf("Buenos das"); else if ((hora >= 12) && (hora < 18)) printf("Buenas tardes"); else if ((hora >= 18) && (hora < 24)) printf("Buenas noches"); else printf("Hora no vlida");

10

El operador condicional: ?

expresin_1 ? expresin_2 : expresin_3;

La expresin toma el valor de la expresin_2 o la expresin_3, en funcin de si la expresin_1 es cierta o falsa, respectivamente.

Ejemplo: if (a > b) c = a; else c = b;

c = (a > b) ? a : b;

Puede usarse en lugares donde no puede usarse ifelse :

printf("El mnimo es %d \n", ((x < y) ? x : y) );

11

Estructura switch (I)

switch ( expresin ) { case constante_1: grupo_de_sentencias_1; break; case constante_2: grupo_de_sentencias_2; break; . . . case constante_N: grupo_de_sentencias_N; break; default: grupo_de_sentencias_por_defecto; break; }

Alternativa mltiple de forma compacta, legible y elegante

Expresin y constantes: tipo entero o carcter

default es opcional

12

Estructura switch (II)


#include <stdio.h> void main() { int num; scanf("%d", &num); switch ( num ) { case 1 : case 3: case 7: printf("Uno, tres o siete.\n"); break; case 4 : case 8 : printf("Cuatro u ocho.\n"); break; default : printf("No esperado.\n"); break; }

#include <stdio.h> void main() { int num;

scanf("%d", &num); switch ( num ) { case 1 : printf("Uno.\n"); break; case 2 : printf("Dos.\n"); break; . . . case 5 : printf("Cinco.\n"); break; default : printf("No esperado.\n"); break; } }

break finaliza forzadamente la ejecucin de un bloque de cdigo case vaco

default opcional

Ejercicios (I)

13

Escribir un programa que lea tres valores enteros y muestre por pantalla el mximo y el mnimo de ellos.

Dado el siguiente programa, realizar un seguimiento de la ejecucin en los siguientes supuestos:


(a, b, c, d) = (2, 1, 5, 3) (a, b, c, d) = (2, 1, 0, 0)

(a, b, c, d) = (0, 0, 5, 3) (a, b, c, d) = (2, 1, 2, 2)

#include <stdio.h> void main() { int a, b, c, d;

scanf("%d %d %d %d", &a, &b, &c, &d); if ( ((a > 0) || (b > a)) && (c != d) ) { a = c; b = 0; } else { c += d; c = (c == 0) ? (c + b) : (c a); b = a + c + d; } printf("%d %d %d %d\n", a, b, c, d);

Ejercicios (II)

14

Escribir un programa que lea un valor entero y determine si es mltiplo de 2 y de 5.

Escribir un programa que muestre por pantalla la ecuacin de una recta en un plano, Ax + By + C = 0, leyendo previamente las coordenadas de dos de sus puntos (x1, y1) y (x2, y2). Recordar que: B = y1 * (x2 x1) x1 * (y2 y1)

A = y2 y1

Estructuras iterativas

Introduccin a la programacin en C

Introduccin

Ejecucin repetida de un grupo de sentencias:

De acuerdo a ciertas condiciones, o

Un nmero prefijado de veces

Diversas estructuras: while dowhile for

Estructura while (I)


while (condicin) { grupo_de_sentencias; }

while (condicin) sentencia;

#include <stdio.h> void main() { int num, cont, suma;

cont = 0; suma = 0; scanf("%d", &num); while (num != 1) { cont++; suma+=num; scanf("%d", &num); } if (cont != 0) printf("La media es %d.\n", suma/cont); else printf("Secuencia vacia.\n");

Estructura while (II)

La condicin se evala al principio del bucle

El cuerpo se ejecuta entre 0 y N veces

Cuidado con crear bucles infinitos el cuerpo modifica la condicin

En C toda sentencia es una expresin la condicin puede ser cualquier cosa. Ejemplos:

while (x) { . . . }

while (x = x+1);

El cuerpo del bucle puede ser nulo

Estructura dowhile (I)


do { grupo_de_sentencias; } while (condicin);

do

sentencia; while (condicin);

Similar a while

Primero se ejecuta el cuerpo del bucle y luego se verifica la condicin

El cuerpo se ejecuta entre 1 y N veces

Tanto while como dowhile suelen usarse cuando el nmero de iteraciones se desconoce a priori

Estructura dowhile (II)

Ejemplo:

#include <stdio.h> void main() { int num, cont;

cont = 0; do { scanf("%d", &num); if (num == 3) cont++; } while (num != 1);

prinf("El 3 aparece %d veces\n", cont);

Estructura for (I)

for (sentencia_inicial; condicin; incr/decr) sentencia;

for (sentencia_inicial; condicin; incr/decr) { grupo_de_sentencias; }

Sentencia inicial: inicializacin de variables de control del bucle. Se ejecuta una sola vez, antes de entrar. El cuerpo

Condicin de final de bucle (igual que en while) se ejecuta entre 0 y N veces

Incremento o decremento de la variable de control. Se ejecuta al final del cuerpo del bucle.

Estructura for (II)


10 3

Ejemplo:

i=1 i

#include <stdio.h> void main() { int i, cubo, suma;

suma = 0; for (i = 1 ; i <= 10 ; i++) { cubo = i * i * i; suma += cubo; } printf("El sumatorio es %d\n", suma);

Estructura for (III)

Las tres partes son opcionales. Ejemplo:

for ( ; 1 ; ) { /* Grupo de sentencias */ }

El operador coma ( , ) . Ejemplo:

for ( i=0, j=10 ; i<10, j>0 ; i++, j=2 ) { /* Grupo de sentencias */ }

for suele usarse cuando el nmero de iteraciones es conocido a priori y puede controlarse con una variable contador

10

Equivalencia for while

for (sentencia_inicial; condicin; incr/decr) { grupo_de_sentencias; }

sentencia_inicial; while (condicin) { grupo_de_sentencias; incremento/decremento; }

11

Sentencias break y continue

break finaliza forzadamente la ejecucin de un bucle.

continue evita la ejecucin del resto del cuerpo del bucle en una iteracin determinada.

do { scanf("%d", &num); if (num < 0) { printf("Valor ilegal\n"); break; /* Abandonar el bucle. */ }

if (num > 100) { printf("Valor demasiado grande\n"); continue; /* No ejecutar el resto de sentencias */ /* e ir al final del bucle. */ }

/* Procesar el valor ledo */ . . .

} while (num != 0 );

No muy elegante, pero puede simplificar el cdigo.

Ejercicios (I)

12

Escribir un programa que calcule la suma de los 20 primeros nmeros mltiplos de 5 o de 7.

Escribir un programa que calcule la potencia de un nmero entero, dado su valor y el del exponente.

Escribir un programa que lea N nmeros enteros y muestre el mayor y el menor de todos ellos.

Escribir un programa que escriba la tabla de multiplicar de un nmero entero ledo por teclado.

Escribir un programa que muestre la serie de Fibonacci hasta un lmite dado. Recordar que la serie de Fibonacci se define como:

F0 = 1

F1 = 1

Fi = Fi1 + Fi2

Ejercicios (II)

13

Escribir un programa que convierta un nmero entero positivo a cualquier base de numeracin dada, igual o inferior a 10.

Escribir un programa que determine si un nmero entero dado, es primo o no.

Escribir un programa que calcule el factorial de un nmero entero ledo por teclado.

Escribir un programa que calcule la suma de todos los nmeros mltiplos de 5 comprendidos entre dos enteros ledos por teclado.

Escribir un programa que muestre los 15 primeros nmeros de la serie de Fibonacci.

Tipos de datos elementales

Introduccin a la programacin en C

Enteros (I) Introduccin

Palabra reservada int

Declaracin : int lista_de_variables;

Rango de representacin limitado a 16 o 32 bits

16 bits [215, 2151] = [32768, 32767]

32 bits [231, 2311] = [2147483648, 21474836477]

Notacin:

Decimal 27 4026 149

Octal 33 07672 0225

Hexadecimal 0X1B 0xFBA 0x95

Enteros (II) Modificadores


short lista_de_variables;

short : nmeros enteros de 16 bits

short int lista_de_variables;

Rango: [215, 2151] = [32768, 32767]

No pueden especificarse constantes

long : nmeros enteros de 32 o 64 bits


long lista_de_variables;

long int lista_de_variables;

Rango: [231, 2311] o [263, 2631]


long x; ... x = 554L; x = 187387632;

Constantes: L o l postfija

Ejemplo:

Enteros (III) Modificadores


no se usa
signed lista_de_variables;

signed : por defecto, implcitamente

signed int lista_de_variables;

unsigned : nmeros enteros sin signo (positivos)


unsigned lista_de_variables;

unsigned int lista_de_variables;

16 bits

Rango: [0, 2161] = [0, 65535] Rango: [0, 2321] = [0, 4294967295]

32 bits

Puede combinarse con short y long


unsigned x; ... x = 45728; x = 345U;

Constantes: U postfija

Ejemplo:

Enteros (IV) Resumen

int unsigned int short int unsigned short int long int unsigned long int

Tipo

Rango [2147483648, 2147483647] [0, 4294967295] [32768, 32767] [0, 65535] [2 63 , 2 63 1] [0, 2 64 1]

Tamao 32 bits 32 bits 16 bits 16 bits 64 bits 64 bits

Formato %d %u %d %u %ld %lu

Caracteres (I) Introduccin

Palabra reservada char

Declaracin : char lista_de_variables;

Conjunto ordenado de caracteres

Representados por cdigos numricos (estndar ASCII, 8 bits)

Constantes: el carcter entre comillas:


char x, y; ... x = f; y = ?; x = 5;

Caracteres (II) Tabla ASCII


char SP ! " # $ % & ( ) * + . / ASCII 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 char @ A B C D E F G H I J K L M N O ASCII 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 char a b c d e f g h i j k l m n o

ASCII 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

char ASCII NUL \0 32 SOH 33 STX 34 ETX 35 EOT 36 ENQ 37 ACK 38 BEL \a 39 BS \b 40 HT \t 41 LF \n 42 VT \v 43 FF \f 44 CR \r 45 SO 46 SI 47

Caracteres (III) Tabla ASCII


ASCII 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 char 0 1 2 3 4 5 6 7 8 9 : ; = ? ASCII 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 char P Q R S T U V W X Y Z [ \ ] ^ _ ASCII 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 char p q r s t u v w x y z { } ~ DEL

ASCII 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31

char DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US

Caracteres (IV) Son enteros

Internamente representados como enteros de 8 bits

Pueden realizarse operaciones aritmticas: F + 5 70 + 52 = 123 { 70 + 5 = 75 K

F + 5

Se establece un orden entre los caracteres: a <= h cierto K > V falso


Rango [128, 127] [128, 127] [0, 255]

char char signed char unsigned char

Tipo

Tamao 8 bits 8 bits 8 bits 8 bits

Formato %c %d %d %u

10

Caracteres (V) Especiales

Caracteres especiales, "no imprimibles"

Usar el cdigo ASCII (decimal, octal o hexadecimal): \9 tabulador (ASCII decimal) espacio en blanco (ASCII octal)

\040

Secuencias de escape:
Cdigo
\a \n \r \t

\ \" \0

Significado pitido nueva lnea retorno de carro tabulador comilla simple comillas nulo

11

Caracteres (VI) Conversiones


int char ... cod = \97; c = (char) cod; ... cod; c;

Obtencin del cdigo ASCII y viceversa:

int char

cod; c;

... c = a; cod = (int) c; ...

Aspectos prcticos: Cdigo numrico de un carcter c : d = (int)c (int)0; Carcter correspondiente a un dgito entero d : c = (char)((int)0 + d);

12

Reales (I) Introduccin


aproximacin 6 dgitos de precisin 10 dgitos de precisin

Infinitos decimales, pero memoria finita

Coma flotante: float . 32 bits

Doble precisin: double . 64 bits

Notacin decimal: 5.034 , 443.43, ...

Notacin cientfica: 3.56E67 , 7.9e15, ...

Las constantes son, por defecto, double. Usar F para float:


double x; float y; ... x = 34E23; y = 2.3E12F;

13

Reales (II) Ejemplo

Calcular y i 1000

i=1 1i

con un error inferior a un valor e ,

#include <stdio.h> #define LIMITE 1000 void main () { int i, fin; float suma, epsilon;

suma = 0.0; fin = 0; i = 1; scanf("%f", &epsilon); while ( ! fin ) { suma += (1/i); i++; fin = ((1/i < epsilon) || ( i> LIMITE)); } printf("La suma es %f\n", suma);

14

Reales (III) Resumen

Algunos compiladores admiten el modificador long

math.h : librera estndar con funciones matemticas (sqrt, sin, cos, ...)

float

Tipo

Formato %f, %e, %g %f, %e, %g %f, %e, %g

double

long double

Rango Tamao 1.1754945E38 4 bytes 3.4028232E+38 2.225073858507202E308 8 bytes 1.797693134862312E+308 8.4...E4932 16 bytes 5.9...E+4932

Ejercicios (I)

15

Escribir un programa que cuente el nmero de veces que aparece un letra en una secuencia de caracteres acabada en . .

Escribir un programa que lea un carcter de teclado e informe de si es alfabtico, numrico, blanco o un signo de puntuacin.

Escribir un programa que convierta una secuencia de dgitos entrados por teclado, al nmero entero correspondiente. Supngase que el primer dgito ledo es el de mayor peso, y obsrvese que no se conoce su peso en el nmero, puesto que inicialmente se desconoce el nmero de dgitos en la secuencia.

Escribir un programa que calcule y muestre por pantalla las races de una ecuacin de segundo grado, leyendo previamente los coeficientes A, B y C de la misma : Ax 2 + Bx + C = 0 .

Escribir un programa para calcular de forma aproximada el nmero e. Recordar que:

e= i=0 1i!

Tipos de datos estructurados: tablas

Introduccin a la programacin en C

Introduccin

Creacin de tipos de datos complejos: vectores, matrices, tablas multidimensionales y cadenas de caracteres

Coleccin de datos del mismo tipo bsico

Referenciados mediante un mismo nombre

Almacenados en posiciones de memoria contiguas:

Direccin de memoria ms baja primer elemento, y

Direccin de memoria ms baja ltimo elemento

Vectores Una dimensin (I)


: tipo de los elementos del vector

tipo_de_datos nombre_tabla[tamao];

tipo_de_datos

nombre_tabla

: identificador para el vector y sus elementos

: expresin constante que indica el nmero de elementos del vector

tamao

Espacio de memoria: nmero de elementos por el tamao de cada uno de stos

Vectores (II)
nombre_vector[ndice];

Indice entre 0 y N1 !!!

Ejemplos:
#define TAM 100 void main () { int vector[TAM], i; for (i=0; i<TAM; i++) vector[i] = 0; }

int int

contador[10]; i, j, x;

... x = contador[1]; x = contador[i]; contador[i*2+j] = 24; ...

Vectores (III)

Inicializacin:

tipo_de_datos nombre_tabla[tam1]...[tamN] = {lista_valores};

Ejemplos:
/* Correcto */ /* Correcto */ /* Correcto */ /* Incorrecto */

int contador[3] = {24, 12, 6};

char vocales[5] = {a, e, i, o, u};

int num[10] = {3, 5, 7, 11, 13};

int v[4] = {2, 6, 8, 9, 10, 38};

No se puede comparar un vector con otro, ni copiar (asignar) un vector en otro directamente elemento a elemento

Vectores (IV) Ejemplo


#include <stdio.h> #define MAX 100 void main () { int i, num, cont[MAX]; for (i=0; i<MAX; i++) cont[i]=0; scanf("%d", &num); while ( num != 1 ) { if ((num >= 0) && (num<MAX)) cont[num]++; scanf("%d", &num); } for (i=0; i<MAX; i++) printf("c%d = %d\n",i, cont[i]); }

Contar las apariciones de ciertos nmeros en una secuencia de enteros acabada en 1:

#include <stdio.h> void main () { int num; int c0=0, c1=0, c2=0, c3=0;

scanf("%d", &num); while ( num != 1 ) { if (num == 0) c0++; if (num == 1) c1++; if (num == 2) c2++; if (num == 3) c3++; scanf("%d", &num); } %d\n", %d\n", %d\n", %d\n", c0); c1); c2); c3);

printf("c0 printf("c1 printf("c2 printf("c3

= = = =

Vectores (V) Ejemplo

Normalizar un conjunto de nmeros reales:

#include <stdio.h> #include <math.h> #define MAX 100 void main () { float v[MAX], modulo; int i;

/* Lectura del vector */ for (i=0; i<MAX; i++) scanf("%f", &v[i]);

/* Calcular el mdulo */ modulo = 0.0; for (i=0; i<MAX; i++) modulo += (v[i]*v[i]); modulo = sqrt(modulo);

/* Normalizacin */ for (i=0; i<MAX; i++) v[i] /= modulo;

/* Escritura del vector */ for (i=0; i<MAX; i++) printf("v[%d]=%f\n", i, v[i]);

Matrices Dos dimensiones (I)

tipo_de_datos nombre_tabla[tamao1][tamao2];

tamao1

: nmero de filas

tamao2

: nmero de columnas

Almacenadas por filas: (0,0), (0,1), ..., (0,M1), (1,0), etc.

Matrices (II)

nombre_matriz[ndice1][ndice2];

Indices entre 0 y N1 (filas), y 0 y M1 (columnas) !!!

Inicializacin:

int mat[3][4] = {24,12,6,17,15,28,78,32,0,44,3200,34};

int mat[3][4] = { {24, 12, 6, 17}, {15, 28, 78, 32}, {0, 44, 3200, 34} }

10

Matrices (III) Ejemplo

#include <stdio.h> #define MAX 20 void main () { int m[MAX][MAX], mt[MAX][MAX]; int fil, col, i, j;

Traspuesta de una matriz de enteros:

/* Lectura de la matriz */ printf("\nNum. Filas"); scanf("%d", &fil); printf("\nNum. Columnas"); scanf("%d", &col); printf("Introducir la matrix por filas:"); for (i=0; i<fil; i++) for (j=0; j<col; j++) { printf("\nm[%d][%d] = ", i, j); scanf("%d", &m[i][j]); }

/* Traspuesta */ for (i=0; i<fil; i++) for (j=0; j<col; j++) mt[j][i] = m[i][j];

/* Escritura de la matriz */ for (i=0; i<fil; i++) for (j=0; j<col; j++) printf("\nmt[%d][%d] = %d ", i, j, mt[i][j]);

11

Tablas multidimensionales (I)

Declaracin:

tipo_de_datos nombre_tabla[tam1][tam2]...[tamN];

Acceso:

nombre_tabla[ndice1][ndice2]...[ndiceN];

Almacenadas por orden de dimensin: filas, columnas, etc.

Rara vez se usan tablas de ms de tres dimensiones

12

Tablas multidimensionales (II)

13

Tablas multidimensionales (III)

Inicializacin aleatoria de una tabla de tres dimensiones:

#include <stdio.h> #include <stdlib.h> #define DIM 10 void main () { int tab[DIM][DIM][DIM]; int a, b, c;

/* Inicializacin */ for (a=0; a<DIM; a++) for (b=0; b<DIM; b++) for (c=0; c<DIM; c++) tab[a][b][c] = rand();

/* Escritura de la tabla, de DIM en DIM elementos */ for (a=0; a<DIM; a++) for (b=0; b<DIM; b++) { for (c=0; c<DIM; c++) { printf("\ntab[%d][%d][%d] = ", a, b, c); printf("%d", tab[a][b][c]); } printf("\nPulse ENTER para seguir"); getchar(); }

14

Cadenas de caracteres (I)

Vectores de tipo carcter (char) con un tratamiento especial

El ltimo elemento til del vector debe ser el carcter nulo (cdigo ASCII 0) \0 declarar un vector con N+1

Cadena de N caracteres elementos

Ejemplo: char cadena[6]; reserva suficiente espacio para almacenar una cadena de hasta 5 caracteres:

Definicin de constantes mediante comillas:

15

Cadenas de caracteres (II)

Consulta: igual que en los vectores

Asignacin, diferentes maneras:

char cadena[10];

... char nombre[10] = {N,U,R,I,A,\0}; char nombre[10] = "NURIA"; char nombre[] = "NURIA";

cadena[0] cadena[1] cadena[2] cadena[3] cadena[4] cadena[5]

= = = = = =

c; a; s; c; o; \0;

Cadena vaca:

char cadena[12] = "Una frase"; ... cadena = \0; /* Ahora es una cadena vacia */

16

Cadenas de caracteres (III)

Funciones de manipulacin en string.h:

strlen: longitud de una cadena,

strcpy: copiar una cadena en otra,

strcat: concatenar dos cadenas,

strcmp: comparar dos cadenas,

etc.

Entrada y salida (stdio.h):

Formato especial %s para scanf (limitado) y printf

Funciones gets y puts

17

Cadenas de caracteres (IV)

Leer dos cadenas, concatenarlas, convertir minsculas en maysculas y viceversa:

#include <stdio.h> #include <string.h> void main () { char cad1[80], cad2[80], cad3[160]; int i, delta;

printf("\nCadena 1: "); gets(cad1); printf("\nCadena 2: "); gets(cad2); /* cad3 = cad1 + cad2 */ strcpy(cad3, cad1); strcat(cad3, cad2);

i = 0; delta = a A; while (cad3[i] != \0) { if ((cad3[i]>=a) && (cad3[i]<=z)) cad3[i]=delta; /* Convierte en mayscula */ else if ((cad3[i]>=A) && (cad3[i]<=Z)) cad3[i]+=delta; /* Convierte en minscula */ i++; } printf("La cadena resultante es: %s\n", cad3);

Ejercicios (I)

18

Dnde est el error en el siguiente programa?

void main () { int vector[10]; int x = 1;

for (x=1; x<=10; x++) vector[x]=23;

Escribir un programa que lea del teclado un vector de 10 nmeros enteros, lo invierta, y finalmente lo muestre de nuevo.

Escribir un programa que cuente el nmero de palabras de ms de cuatro caracteres en una frase. sta se almacena en forma de vector cuyo ltimo elemento es el carcter ..

Escribir un programa que lea del teclado dos nmeros enteros de hasta 20 dgitos y los sume. Usar vectores para almacenar los dgitos.

Escribir un programa que decida si una palabra es palndroma.

Escribir un programa que calcule la moda de un conjunto de nmeros enteros almacenados en un vector.

Ejercicios (II)

19

Dnde est el error en el siguiente programa?

void main () { int matriz[10][3]; int x, y;

for (x=0; x<3; x++) for (y=0; y<10; y++) matriz[x][y]=0;

Escribir un programa que inicialice cada elemento de una matriz de enteros con el valor se la suma de su nmero de fila y columna.

Escribir un programa que calcule la suma de dos matrices.

Escribir un programa que calcule los puntos de silla de una matriz de enteros. Un elemento de la matriz es un punto de silla si es el mnimo de su fila y el mximo de su columna.

Escribir un programa que determine si una matriz es simtrica.

Escribir un programa que multiplique dos matrices.

Ejercicios (III)

20

Escribir un programa que dada una cadena de caracteres y un entero correspondiente a una posicin vlida dentro de ella, genere una nueva cadena de caracteres que contenga todos los caracteres a la izquierda de dicha posicin, pero en orden inverso.

Escribir un programa que dada una cadena de caracteres, la limpie de caracteres blancos. Escribirdos versiones, una utilizando una cadena auxiliar y otra versin que realice los cambios sobre la misma cadena.

Escribir un programa que lea dos cadenas de caracteres, las compare, e informe de si son iguales o diferentes.

Otros tipos de datos

Introduccin a la programacin en C

Estructuras (I) Introduccin

Agrupacin de elementos de distintos tipos de datos

Definicin (plantilla genrica). No reserva memoria:

struct nombre_estructura { tipo_campo_1 nombre_campo_1; tipo_campo_2 nombre_campo_2; ... tipo_campo_N nombre_campo_N; };

Ejemplo:

struct cliente { char nombre[100]; long int dni; char domicilio[200]; long int num_cuenta; float saldo; }

Estructuras (II) Declaracin y acceso


struct cliente { char nombre[100]; long int dni; char domicilio[200]; long int num_cuenta; float saldo; } cli1, cli2;

Declaracin de variables en la propia definicin:

struct nombre_estructura { tipo_campo_1 nombre_campo_1; tipo_campo_2 nombre_campo_2; ... tipo_campo_N nombre_campo_N; } lista_de_variables;

Declaracin posterior a la definicin:

struct nombre_estructura lista_de_variables;

struct cliente cli1, cli2;

Acceso a los campos:


variable.nombre_campo cli1.dni cli2.saldo

cli1.nombre

Estructuras (III) Asignacin

Asignacin campo a campo:

strcpy(cli2.nombre, "Federico Sancho Bruch"); cli2.dni = 23347098; gets(cli2.domicilio); scanf("%ld", &cli2.num_cuenta); cli2.saldo += 10000.0;

Asignacin completa en la declaracin:

struct cliente cli2 { "Federico Sancho Buch", 23347098, "Rue del Percebe 13 Madrid", 7897894, 1023459.34 };

Copia de variables estructura mediante asignacin:

cli2 = cli1;

Estructuras (IV) Ejemplo

Gestin de fichas personales:

#include <stdio.h> struct datos { char nombre[20], apellido[20]; long int dni; }; struct tablapersonas { int numpersonas; struct datos persona[100]; }; void main () { int i; struct tablapersonas tab;

printf("Nmero de personas: "); scanf("%d", &tab.numpersonas); for (i=0; i<tab.numpersonas; i++) { printf("\nNombre: "); gets(tab.persona[i].nombre); printf("\nApellido: "); gets(tab.persona[i].apellido); printf("\nDNI: "); scanf("%ld", &tab.persona[i].dni); }

Uniones (I) Introduccin

Agrupacin de elementos de distintos tipos de datos

Todos los campos comparten la misma zona de memoria solapamiento!

Reserva de memoria segn el campo de mayor tamao

Slo puede ocuparse un campo, alternativamente control del programador

Definicin (plantilla genrica). No reserva memoria:

union nombre_unin { tipo_campo_1 nombre_campo_1; tipo_campo_2 nombre_campo_2; ... tipo_campo_N nombre_campo_N; };

Uniones (II) Ejemplo

struct jet { int num_pasajeros; ... };

struct helicoptero { int capacidad_elevador; ... };

struct carguero { int carga_maxima; ... };

union aeroplano { struct jet jet_u; struct helicoptero helicoptero_u; struct carguero carguero_u; }

struct un_aeroplano { /* 0:jet , 1:helicoptero , 2:carguero */ int tipo; union aeroplano datos; };

Tipos enumerados (I) Introduccin

Conjunto ordenado de constantes simblicas enteras

Enumeracin de todos los valores posibles dentro del nuevo tipo

Definicin (plantilla genrica). No reserva memoria:

enum nombre_enumeracin { constante_1, constante_2, ... constante_N };

Ejemplo:

enum dia_semana { LUNES, MARTES, MIERCOLES, JUEVES, VIERNES, SABADO, DOMINGO };

Tipos enumerados (II) Ejemplo

enum dia_semana { LUNES=1, MARTES, MIERCOLES, JUEVES, VIERNES, SABADO, DOMINGO=10, FESTIVO=10 };

void main () { enum dia_semana dia;

... if (dia <= VIERNES) printf("Es laborable"); ... dia = MARTES; /* Muestra el valor de la constante: 2 */ print("Hoy es: %d", dia); ...

10

Nuevos tipos de datos (I)

Definicin de nuevos tipos de datos mediante typedef

Muy til para tipos complejos: tablas, estructuras, uniones, enumeraciones, etc.

typedef tipo_de_datos nombre_nuevo_tipo;

11

Nuevos tipos de datos (II) Ejemplo

#include <stdio.h>

typedef float Testatura;

typedef char Tstring[30];

typedef enum Tsexo = {HOMBRE, MUJER}; { nombre, apellido; alt; sex;

typedef struct Tstring Testatura Tsexo } Tpersona;

void main () { Tpersona paciente;

... scanf("%f", &paciente.alt); gets(paciente.nombre); printf("%s", paciente.apellido); paciente.sex = MUJER; ...

12

Tiras de bits (I) Introduccin

Muy tiles para programacin de bajo nivel

Variable entera con o sin signo (char, short, int, long, unsigned, etc.)

Operaciones especiales: negacin, lgicas y desplazamiento

13

Tiras de bits (II) Negacin

Tambin llamada complemento a 1

Consiste en cambiar los 1s por 0s y viceversa

Operador : ~

#include <stdio.h> void main () { unsigned short a, b; /* a = /* b = b= b= b= b= 0xa4c3 b= 42179 b= 23357 0101 1011 1010 0100 %x\n", a, %u\n", a, %d\n", a, 0011 1100 */ 1100 0011 */ b); b); b);

a = 0x5b3c; b= ~a; printf("a= %x printf("a= %u printf("a= %d

a= 0x5b3c a= 23356 a= 23356

14

Tiras de bits (III) Operadores lgicos

Operaciones lgicas bit a bit: "Y" (AND) : & "O" (OR) : | "O exclusiva" (XOR) : ^ Tabla de verdad:
y 0 1 0 1
/* /* /* /* /* a b c d e = = = = = 1101 1010 1000 1111 0111 1011 0101 0001 1111 1110

x 0 0 1 1

AND (&) 0 0 0 1

OR (|) 0 1 1 1

XOR (^) 0 1 1 0
0001 1100 0000 1101 1101 1101 1011 1001 1111 0110 */ */ */ */ */

Ejemplos:

a= b= c= d= e=

0x5b3c; 0xa4c3; a & b; a | b; a ^ b;

15

Tiras de bits (IV) Desplazamiento

Hacia la derecha: var1 >> var2 var1 es la tira de bits y var2 el nmero de bits a desplazar Se pierden los bits de menor peso y se aaden 0s por la izquierda si var1 es unsigned, o se replica el bit de ms peso si var1 es signed var >> n equivale a var/2n

Hacia la izquierda: var1 << var2 var1 es la tira de bits y var2 el nmero de bits a desplazar Se pierden los bits de mayor peso y se aaden 0s por la derecha var << n equivale a var*2n

16

Tiras de bits (V) Desplazamiento

Ejemplo:

unsigned short a, d, e; short b, c, f, g;

a= b= c= d= e= f= g=

28; 28; 3; a << a >> b << b >>

c; c; c; c;

/* /* /* /* /* /* /*

a b c d e f g

= = = = = = =

0000 1111 0000 0000 0000 1111 1111

0000 1111 0000 0000 0000 1111 1111

0001 1110 0000 1110 0000 0010 1111

1100 0100 0011 0000 0011 0000 1100

*/ */ */ = 224 */ = 3 */ = 224 */ = 3 */

Ejercicios (I)

17

Escribir un programa que, dadas dos fechas, indique cul es anterior a la otra. Definir una estructura para el tipo de datos fecha (da, mes y ao).

Definir una estructura de datos para representar polinomios de hasta grado 10. Escribir un programa capaz de sumar dos polinomios expresados con dicha estructura.

Dada la siguiente definicin de tipos de datos:

typedef char Tstring[50]; typedef struct { long int num; char letra; } Tnif; typedef struct { Tnif nif; Tstring nombre, direccion; long int telf; }

Escribir un programa que defina un vector con los datos de N empresas y permita introducirlos por teclado. Dado el NIF de una empresa, el programa deber permitir mostrar sus datos, as como eliminarla del vector, reorganizndolo para no dejar espacios vacios.

Ejercicios (II)

18

Dada la siguiente definicin de tipos de datos:

typedef char Tstring[50]; typedef struct { Tstring nombre, area; long int ventas[4]; } Tagente;

Escribir un programa que defina un vector de N agentes comerciales, permita introducir los datos por teclado, y finalmente muestre los datos del agente con la mxima media de ventas.

Dada la siguiente definicin de tipos de datos:

typedef char Tstring[50]; typedef struct { Tstring pais; int temp_max, temp_min; } Ttemp;

Escribir un programa que defina un vector con los datos de N pases y permita introducirlos por teclado. Finalmente, el programa deber mostrar el nombre de los pases cuya temperatura mnima sea inferior a la media de las temperaturas mnimas.

Funciones

Introduccin a la programacin en C

Introduccin

Estructuracin del programa en partes ms pequeas y sencillas Modularizacin

Propsito nico

Identificable

Reusable

Mayor claridad: programacin, depuracin, etc.

Construccin de libreras a medida

Generalidades

Paquete de sentencias

Identificable mediante un nombre Parmetros

Realiza una tarea genrica fija

Los datos pueden cambiar

Posibilidad de retornar un valor


Dato 1 Dato 2 Dato 3

Resultado

Ejemplo (I)
m! m = n! m n ! n

#include <stdio.h> void main() { long int m, n, fm = 1, fn = 1, fdif = 1; float res; int i;

printf( "Introduzca m y n: " ); scanf( "%d %d", &m, &n );

for (i= 2; i <= m; i++) fm = fm * i;

for (i= 2; i <= n; i++) fn = fn * i;

for (i= 2; i <= mn; i++) fdif = fdif * i;

res = (float)fm / ((float)fn * (float)fdif); printf("m sobre n = %f\n", res );

Ejemplo (II)

m! m = n! m n ! n

#include <stdio.h> long int fact ( int x ) { int i; long int f = 1;

for (i = 2; i <= x; i++) f = f * i; return(f);

void main() { long int m, n; float res;

printf( "Introduzca m y n: " ); scanf( "%d %d", &m, &n ); res = (float)fact(m) / ((float)fact(n) * (float)fact(mn)); printf( "m sobre n = %f\n", res );

Definicin

tipo nombre_funcin (tipo1 param1, ... , tipoN paramN) { cuerpo }

Previa al punto de llamada

tipo : tipo de datos del resultado de la funcin. Por defecto: int

nombre_funcin : identificador que se usar posteriormente para las llamadas

tipoi parami : tipo y nombre de los parmetros formales. Nombres con que referirse dentro de la funcin a los datos que se transfieren a sta desde la parte del programa que hace la llamada.

cuerpo: declaracin de variables + sentencias (incluyendo llamadas a funciones). Puede incluir la sentencia return para devolver un valor al punto de llamada.

Prototipos

Especificacin parcial de la funcin La definicin puede ser posterior al punto de llamada muy usados

tipo nombre_funcin (tipo1 param1, ... , tipoN paramN);

#include <stdio.h>

long int fact ( int x ); /* Prototipo */

void main() { long int m, n; float res;

printf( "Introduzca m y n: " ); scanf( "%d %d", &m, &n ); res = (float)fact(m) / ((float)fact(n) * (float)fact(mn)); printf( "m sobre n = %f\n", res );

long int fact ( int x ) { int i; long int f = 1;

for (i = 2; i <= x; i++) f = f * i; return(f);

Variables y parmetros

Variables locales: declaradas dentro de una funcin

Ambito: interior de la funcin

Tiempo de vida: ejecucin de la funcin

Variables globales: declaradas fuera de toda funcin efectos

Ambito: todas las funciones del fichero laterales

Tiempo de vida: ejecucin del programa

Parmetros formales: como las variables locales

Llamada

Nombre de la funcin y lista de parmetros reales entre parntesis

Parmetros: mismo nmero y tipo que en la definicin

Si la funcin devuelve algn valor, la llamada debera aparecer dentro de una expresin

Ejemplos:

fm = fact(m);

prod = fact(n) * fact(mn);

printf( "El facorial de 5 es: %ld\n", fact(5) );

10

Devolucin de resultados

Slo un dato o nada

Dato de tipo elemental, estructura o void

No pueden devolverse tablas

Sentencia return

11

Ejecucin (I)
parmetros formales

Parmetros reales (llamada) (definicin)

Reserva de memoria para parmetros + inicializacin

Reserva de memoria para variables locales: no hay inicializacin

Ejecucin de las sentencias

Anotacin del resultado (si lo hay)

Liberacin de memoria

Vuelta al punto de llamada y uso del resultado (si lo hay)

12

Ejecucin (II)
long int fact ( int x ) { int i; long int f = 1; for (i = 2; i <= x; i++) f = f * i; return(f);

void main() { int m; long int fm; . . . fm = fact(m); . . . } }

Memoria m fm Pila f i

13

Paso de parmetros: valor


pueden ser

Copia del valor de los parmetros reales expresiones

Los parmetros reales no se modifican

#include <stdio.h>

void cuadrado ( int x ) { x = x * x; printf( "Dentro x = %d\n", x ); }

void main() { int x = 5;

printf( "Antes x = %d\n", x ); cuadrado( x ); printf( "Despus x = %d\n", x );

14

Paso de parmetros: referencia (I)

Devolver ms de un valor?

Modificar los parmetros reales?

Operador de direccin ( & ) : obtiene la direccin en memoria de una variable

Operador de indireccin o puntero ( * ) : obtiene el dato contenido en una direccin de memoria

15

Paso de parmetros: referencia (II)

#include <stdio.h>

void swap(int *x, int *y) { int aux;

/* Se asigna a aux el valor referenciado por x */ aux = *x;

/* Se asigna el valor referenciado por y al valor referenciado por x */ *x = *y;

/* El valor referenciado por y pasa a ser el valor de aux */ *y = aux;

void main() { int a, b;

scanf( "%d %d", &a, &b ); swap( &a, &b ); printf( "Los nuevos valores son a=%d y b=%d\n", a, b );

16

Paso de parmetros: resumen

Paso por valor

Declaracin

tipo nombre_funcin (tipo1 param1, ... )

Llamada

nombre_funcin (expresin1, ... )

Paso por referencia

Declaracin

tipo nombre_funcin (tipo1 *param1, ... )

Llamada

nombre_funcin (&variable1, ... )

17

Ejercicio
#include <stdio.h> void main() { int a = 0, b = 0; < llamada > } printf( "%d %d\n", a, b );

void f1( int x, int *y, int a, int b ) { x = x + 1; *y = *y + 1; x = x + a; *y = *y + b; printf( "%d %d\n", x, *y ); }

f1(a, &b, a, b); f2(a, &b);

void f2( int a, int *b ) { a = a + 1; *b = *b + 1; a = a + a; *b = *b + *b; printf( "%d %d\n", a, *b ); }

18

Funciones y tablas (I)


normalmente

Elementos individuales de tipos elementales

Ejemplo:

#include <stdio.h> int maximo (int x, int y) { if (x > y) return(x); return(y); }

void main() { int max, v[20], i;

printf( "Introducir elementos del vector:\n" ); for (i= 0; i< 20; i++) scanf( "%d", &v[i] );

max = v[0]; for (i= 1; i< 20; i++) max = maximo( max, v[i] ); printf( "El elemento mayor es: %d\n", max );

19

Funciones y tablas (II)

Las tablas slo por referencia

El nombre de la tabla es una referencia (apunta) al primer elemento de la tabla

No se usa & ni *

No se hace una copia de la tabla

Dentro de la funcin se accede a la tabla normalmente

20

Funciones y tablas (III)

#include <stdio.h> #define DIM 20 float media( float vec[], int n ) { int j; float sum;

sum = 0.0; for (j= 0; j< n; j++) sum = sum + vec[j]; return (sum/(float)n);

void main() { float med, v[DIM]; int i;

printf( "Introducir elementos del vector:\n" ); for (i= 0; i< DIM; i++) scanf( "%f", &v[i] ); med = media( v, DIM ); printf( "La media es: %f\n", med );

float media( float vec[DIM], int n )

float media( float *vec, int n )

21

Funciones y tablas (IV)

#include <stdio.h> #define MAXFIL 3 #define MAXCOL MAXFIL

void matXvec( int nfil, int ncol, float A[], float x[], float y[] ) { /*Calcula y = A*x */ int i, j;

} void main() { int nfil, ncol; float v1[MAXCOL], v2[MAXFIL], M[MAXFIL][MAXCOL];

for (i= 0; i< nfil; i++) { y[i] = 0.0; for (i= 0; i< ncol; i++) y[i] += (A[i*MAXCOL+j] * x[j]); }

... /* Leer nfil, ncol, A, x */ matXvec( nfil, ncol, M, v1, v2 ); ... /* Mostrar y */

22

Funciones y estructuras (I)

Las estructuras tanto por valor como por referencia

Valor : acceso a los campos normalmente

Referencia: combinacin de los operadores * y . (punto)

Referencia: tambin con el operador >

23

Funciones y estructuras (II)

#include <stdio.h> typedef struct { char nombre[80]; long int ndni; } Tdni;

void leer_dni( Tdni *p ) { gets((*p).nombre); /* gets(p>nombre); */ scanf("%ld", &(*p).ndni); /* scanf("%ld", & p>ndni); */ }

void escribir_dni( Tdni p ) { printf("Nombre : %s\n", p.nombre); printf("%ld", p.ndni); }

void main() { Tdni padre, hijo;

... leer_dni(&padre); ... escribir_dni(padre); ...

24

Funcin main

Tambin puede tener parmetros: los recibe desde el S.O.

Slo dos: argc y argv

void main ( int argc, char *argv[] ) { ... }

argc : indica el nmero de parmetros dados al programa, i.e. nmero de cadenas en argv

argv:vector de cadenas de caracteres, una para cada parmetro del programa

25

Funcin main

Ejemplo:

#include <stdio.h> void main( int argc, char *argv[] ) { if (argc > 2) { printf( "Demasiados parmetros\n" ); } else if (argc < 2) { printf( "Faltan parmetros\n" ); } else { printf( "Yo te saludo %s\n", argv[1] ); } }

26

Recursividad
Iterativa

Una funcin se llama a s misma repetidamente hasta que se satisface cierta condicin

Recursiva

Ejemplos: Fibonacci
int fibo ( int n ) { if ((n == 0) || (n == 1)) return(1); return (fibo(n1)+fibo(n2)); }

Factorial

long int fact ( int x ) { if (x <= 1) return(1); return (x * fact(n1) ); }

Punteros

Introduccin a la programacin en C

Introduccin

Variable cuyo valor es una direccin de memoria

Dicha direccin suele ser la de otra variable

Se dice que apunta o referencia

Fundamentales en C : parmetros, manejo de tablas, memoria dinmica, ...

Complicados y deben usarse con precaucin

Declaracin: *

tipo_de_datos * nombre_puntero1, * nombre_puntero2, ...;

El puntero se asocia a un tipo de datos concreto

El tipo de datos puede ser elemental, estructurado, del programador, etc.

Puntero genrico: tipo de datos void *

Inicializacin: puntero NULL

Un puntero ocupa 4 bytes

Asignacin de direcciones: &


: obtiene la direccin de una variable en memoria

Operador

&

Tipo de datos del puntero Tipo de datos de la variable apuntada

Formato especial en printf : %p

double double

num; *pnum;

. . .

num = 75.435;

pnum = &num;

printf("La direccin contenida en pnum es: %p", pnum);

. . .

Indireccin: *

Acceso a una variable a travs de un puntero a ella

En general: acceso al valor almacenado en la posicin de memoria apuntada por un puntero

Operador de indireccin

... coincide con la declaracin!

. . .

int x, y; int *p;

. . .

x = 20; p = &x; *p = 5498; printf("La direccin contenida en p es: %p", p); printf("El valor de la variable apuntada por p es: %d", *p); y = *p;

. . .

Indireccin mltiple

Un puntero contiene la direccin de otro puntero que a su vez apunta a una variable

tipo_de_datos ** nombre_puntero, ...;

. . .

int num; int *pnum; int **ppnum;

pnum = &num; ppnum = &pnum; **ppnum = 24;

printf( "\nEl nmero : %d, %d, %d", num, *pnum, **ppnum );

printf( "\nEl puntero al nmero : %p, %p", pnum, *ppnum );

printf( "\nEl puntero al puntero al nmero : %p", ppnum ); . . .

Indireccin

precaucin

Manipulacin directa de posiciones de memoria

Error frecuente: no asignar una direccin vlida a un puntero

Podemos provocar fallos inesperados en el programa: acceso a cdigo o datos de otros programas, etc.

Ejemplo:

. . .

int *x;

*x = 100;

. . .

Cuidado con punteros no inicializados

El compilador no puede detectarlo

Asignacin de punteros

Ambos deben apuntar al mismo tipo de datos

Tras la asignacin ambos apuntan a la misma variable

Ejemplo:

. . .

int x, y, z; int *p1, *p2;

. . .

x = 4; p1 = &x; p2 = p1; y = *p1; z = *p2;

/* Ahora p1 y p2 apuntan a x */

. . .

Comparacin de punteros

No es necesario que ambos apunten al mismo tipo de datos

Util para saber la posicin relativa que ocupan en memoria ciertas variables

Ejemplo:

. . .

int *p1, *p2, precio, cantidad;

*p1 = &precio; *p2 = &cantidad;

. . .

Comparacin p1 > p2 , p1 < p2 , etc.

No confundir con *p1 > *p2 , *p1 < *p2 , etc.

10

Aritmtica de punteros

Suma o resta de una cantidad entera Incremento o decremento de la direccin contenida en el puntero

El nmero de posiciones de memoria incrementadas depende del tipo de datos apuntado por el puntero:

puntero = puntero + N;

Se interpreta como:

puntero = direccin_apuntada + N * tamao_tipo_datos;

Ejemplo: supongamos que la @ de la variable a es la 2088

. . .

float

a, b, *pa, *p;

pa = &a; p = pa + 3;

printf( "%p %p", pa, p );

. . .

No es una prctica muy recomendable ... Suele haber alternativas

11

Punteros y tablas (I)


tab = tab + 1 Es incorrecto!

El nombre de una tabla es un puntero que contiene la direccin del primer elemento de la tabla: tab &tab[0]

Es una constante

. . .

char car; char tab[15]; char *ptab;

. . .

ptab = tab; ptab = ptab + 3; car = *(ptab); /* Equivale a car = tab[3]; */ scanf( "%c", ptab+5 ); printf( "%c", *(ptab+10) );

. . . tab[0] */ *(ptab+7) */

/* Tambin accesibles como tablas. */ scanf( "%c", ptab[0] ); /* ptab[0] equivale a ptab[7] = R; /* ptab[7] equivale a

. . .

12

Punteros y tablas (II)


aritmtica de punteros

Manipulacin de tablas multidimensionales

Ejemplo: matriz n filas y m columnas elemento de la fila i y la fila j es el que ocupa la posicin i*m+j desde el principio de la tabla

13

Punteros y estructuras

Similar a los punteros a tipos elementales

Operador

Operador

Operador
Tnif cliente, *pc; Tempresa emp, *pe; char inicial; . . . pc = &cliente;

& : direccin del inicio de la estructura en memoria * : acceso al inicio de la estructura > : acceso a un campo de una estrutura a travs de puntero

typedef char Tstring [50];

typedef struct { long int num; char letra; } Tnif;

(*pc).letra = Z; scanf( "%ld", &(*pc).num ); pc>letra = Z; scanf( "%ld", &pc>num ); pe = &emp; pe>nif.letra = Z; scanf( "%ld", &pe>nif.num ); gets( pe>nombre ); inicial = pe>nombre[0];

typedef struct { Tnif nif; Tstring nombre; Tstring direc; long int telf; } Tempresa;

Ficheros

Introduccin a la programacin en C

Introduccin

Mecanismo de almacenamiento permanente

Hardware: disco duro, disquete, cinta, cdrom, etc.

Programador: independiente del dispositivo

El sistema operativo: concepto de fichero + libreras

Fichero: objeto abstracto sobre el que se puede escribir y leer informacin

Tipos de ficheros

Ficheros de texto

Almacenamiento usando caracteres ASCII

Pueden visualizarse

2147483648 11 bytes

Ficheros binarios

Almacenamiento como en memoria: secuencias de bits

Ocupan aprox. 3 veces menos

2147483648 4 bytes

Diferentes libreras. Ficheros de texto

stdio.h

Ejemplo

Generalidades
EOF (End Of File)

Carcter especial final de fichero:

Acceso secuencial: ventana de acceso

Tipo especial FILE . Las variables pertenecen al S.O. Pista y sector de inicio del fichero

Buffers internos

...

FILE slo puede manipularse mediante funciones del S.O.

Siempre usaremos punteros:


FILE *fp;

Operaciones

Abrir el fichero: fopen El S.O. inicializa una variable de tipo FILE

Vincula la variable a un fichero fsico en un dispositivo especfico

Retorna un puntero a la variable que gestiona el fichero

Leer o escribir en el fichero: fscanf o fprintf Basta indicar el puntero a la variable de tipo FILE y la informacin que queremos leer o escribir

Cerrar el fichero: fclose Se indica al S.O. que ya no necesitamos la variable de tipo FILE asociada al fichero

Abrir fichero : fopen (I)

FILE *fopen( char nombreFichero[], char modoAcceso[] );

nombreFichero: cadena de caracteres que indica el nombre del fichero fsico que se quiere abrir

modoAcceso: cadena de caracteres que indica el uso que haremos del fichero

"r" : abrir un fichero ya existente para lectura

"w" : abrir un fichero nuevo para escritura. Si ya exista ser destruido y creado de nuevo

"a" : abrir un fichero ya existente para aadir informacin al final del mismo. Si el fichero no exista se crear uno nuevo

Abrir fichero : fopen (II)

fopen retorna el puntero a la variable de tipo FILE que el S.O. usar para gestionar el fichero

Si el fichero no se puede abrir, retorna la constante NULL

Otros modos de acceso (muy poco frecuentes):

"r+" : abrir un fichero ya existente tanto para lectura como para escritura

"w+" : abrir un fichero nuevo tanto para lectura como para escritura. Si ya exista ser destruido y creado de nuevo

"a+" : abrir un fichero ya existente para leer y aadir informacin al final del mismo. Si el fichero no exista se crear uno nuevo

Cerrar fichero : fclose


int fclose( FILE *fp );

Indica al S.O. que hemos acabado de usar el fichero

Libera la variable de tipo FILE asociada al fichero

Si no hay errores retorna 0

Si no se puede cerrar el fichero correctamente retorna la constante EOF

10

Ejemplos (I)

#include <stdio.h>

void main( ) { FILE *fp;

fp = fopen( "mifichero.txt", "r" ); if (fp == NULL) { printf( "Error abriendo mifichero.txt\n" ); exit(0); }

. . .

/* Aqu podemos leer datos del fichero */

. . .

fclose( fp );

11

Ejemplos (II)

#include <stdio.h> #define N 256

void main( ) { FILE *fp; char nombreFichero[N];

printf( "Nombre del fichero (< %d caracteres): ", N ); scanf( "%s\%*c", nombreFichero ); fp = fopen( nombreFichero, "w" ); if (fp == NULL) { printf( "Error abriendo %s\n", nombreFichero ); exit(0); }

. . .

/* Aqu podemos escribir datos en el fichero */

. . .

fclose( fp );

12

Leer de fichero : fscanf

int fscanf( FILE *fp, char formato[], <lista variables> );

Permite leer del fichero apuntado por fp

Uso anlogo a scanf

formato es una cadena de caracteres que indica el formato de las variables a leer

<lista variables> es una lista, separada por comas, de direcciones de memoria (punteros) de variables

Retorna el nmero de variables correctamente ledas de acuerdo con el formato especificado, o EOF si se produjo algn error

13

Escribir en fichero : fprintf

int fprintf( FILE *fp, char formato[], <lista punteros> );

Permite escribir en el fichero apuntado por fp

Uso anlogo a printf

formato es una cadena de caracteres que indica el formato de las variables a escribir

<lista variables> es una lista, separada por comas, de variables

Retorna el nmero de bytes (caracteres) correctamente escritos, o un nmero negativo si se produjo algn error

14

Ejemplo

#include <stdio.h> #define MAXELE 100 void main( ) { FILE *fp; char nombreFichero[256]; int lon = 0, vec[MAXELE];

printf( "Fichero de entrada(< 256 caracteres): " ); scanf( "%s%*c", nombreFichero ); fp = fopen( nombreFichero, "r" ); /* Control de errores */ fscanf( fp, "%d", &lon ); if (lon < MAXELE) for (i=0; i<lon; i++) fscanf( fp, "%d", &vec[i] ); else printf( "El vector tiene demasiados elementos\n" ); fclose( fp );

. . . /* Aqu podemos modificar vec */ . . .

printf( "Fichero de salida(< %d caracteres): ", N ); scanf( "%s%*c", nombreFichero ); fp = fopen( nombreFichero, "w" ); /* Control de errores */ fprintf( fp, "%d\n", lon ); for (i=0; i<lon; i++) fprintf( fp, "%d\n", vec[i] ); fclose( fp );

15

Fin de fichero : feof


int feof( FILE *fp );

Comprueba si hemos llegado al final del fichero apuntado por fp

Retorna un valor diferente de 0 (cierto) si se lleg a EOF en una lectura anterior si fscanf no pudo completarse

Importante: slo previamente

En caso contrario retorna 0 (falso)

No tiene sentido si el modo de acceso es de escritura

16

Fin de fichero : ejemplo

#include <stdio.h> #define N 256 #define MAXELE 100 void main( ) { FILE *fp; char nombreFichero[N]; int lon, vec[MAXELE];

printf( " Nombre del fichero(< %d caracteres): ", N ); scanf( "%s%*c", nombreFichero ); fp = fopen( nombreFichero, "r" ); if (fp == NULL) { printf( "Error abriendo %s\n", nombreFichero ); exit(0); } lon = 0; while (!feof(fp) && (lon < MAXELE)) { kk = fscanf( fp, "%d", &vec[lon] ); if (kk == 1) lon++; if (!feof(fp) && (lon == MAXELE)) printf( "Demasiados datos en el fichero\n" ); } fclose( fp );

. . .

17

Control de errores : ferror


int ferror( FILE *fp );

Comprueba si se produjo un error en una operacin anterior sobre el fichero apuntado por fp

Retorna un valor diferente de 0 (cierto) si se produjo algn error

En caso contrario retorna 0 (falso)

18

Vaciado de buffers : fflush


int fflush( FILE *fp );

Por eficiencia, la escritura en un fichero se hace a travs de buffers del S.O.

El S.O. vaca los buffers cuando est desocupado

Los buffers se vacan automticamente al cerrar el fichero

fflush fuerza el vaciado de los buffers al fichero fsico

Permite dar ms seguridad en procesos crticos

Retorna 0 si no se produce ningn error, o EOF en caso contrario

19

Ficheros estndar

stdin, stdout, stderr son constantes de tipo FILE *

Definidas en stdio.h e inicializadas por el S.O.

stdin: apunta a un fichero abierto slo para lectura, inicialmente el teclado

stdout y stderr: apuntan a un fichero abierto slo para escritura, inicialmente la pantalla scanf("%d", &i); printf("%d", i); printf("%d", i);

fscanf(stdin, "%d", &i);

fprintf(stdout, "%d", i);

fprintf(stderr, "%d", i);

You might also like