Lenguaje C.pdf

238
1 Introducción al lenguaje C Marta Zorrilla Universidad de Cantabria

Transcript of Lenguaje C.pdf

  • 1Introduccin al lenguaje C

    Marta ZorrillaUniversidad de Cantabria

  • Marta Zorrilla Universidad de Cantabria

    2

    Introduccin al C

    Objetivos: Presentar la historia del lenguaje C y sus

    caractersticas principales. Presentar la estructura de un programa en C

    mediante ejemplos sencillos.

    Contenidos: 1. La historia del C. 2. Caractersticas. 3. Mi primer programa en C.

  • Marta Zorrilla Universidad de Cantabria

    3

    Historia del C

    Muchas ideas provienen de BCPL (Martin Richards, 1967) y de B (KenThompson, 1970).

    C fue diseado originalmente en 1972 para el SO UNIX en el DEC PDP-11 por Dennis Ritchie en los Laboratorios Bell.

    Primer Libro de referencia de C: The C Programming Language (1978) de Brian Kernighan y Dennis Ritchie.

    En los 80, gran parte de la programacin se realiza en C. En 1983 aparece C++ (orientado a objetos). En 1989 aparece el estndar ANSI C. En 1990 aparece el estndar ISO C (actual estndar de C). WG14 se

    convierte en el comit oficial del estndar ISO C. En dcada de los 90, WG14 trabaja en el estndar C9X/C99 que resuelve

    problemas de fiabilidad del ANSI C, amplia su funcionalidad con nuevos tipos de dato, funciones matemticas, arrays irrestringidos, etc.

  • Marta Zorrilla Universidad de Cantabria

    4

    Caractersticas del C

    Lenguaje de programacin de propsito general, muy adecuado paraprogramacin de sistemas (unix fue escrito en C).

    Lenguaje relativamente pequeo: solo ofrece sentencias de control sencillas y funciones.

    La E/S no forma parte del lenguaje, sino que se proporciona a travs de una biblioteca de funciones.

    Permite la agrupacin de instrucciones. Programacin estructurada. Permite la separacin de un programa en mdulos que admiten

    compilacin independiente. Diseo modular. Programas portables.

  • Marta Zorrilla Universidad de Cantabria

    5

    Inconvenientes del C

    No es un lenguaje fuertemente tipado. Es bastante permisivo con la conversin de datos. Sin una programacin metdica puede ser propenso a errores

    difciles de encontrar. La versatilidad de C permite crear programas difciles de leer.

    #define _ -F

  • Marta Zorrilla Universidad de Cantabria

    6

    Primer programa en C

    /* Ejemplo 1. Programa DOCENA.C */

    #include

    main (){

    int docena;

    docena = 12;printf ("Una docena son %d unidades\n", docena);

    }

  • Marta Zorrilla Universidad de Cantabria

    7

    Segundo programa en C/* Ejemplo 1. Programa saludo.c*/

    #include #define MENSAJE alumnos

    /*prototipo funciones*/int imprimir_saludo (char * destino);

    int main (void){

    int error=0;error=imprimir_saludo (MENSAJE);return(0);

    }int imprimir_saludo (char * destino){

    printf (hola %s \n", destino); return(0);

    }

  • Marta Zorrilla Universidad de Cantabria

    8

    Crear, compilar y ejecutar un programa C

    Crear un fichero con extensin .c con un editor de texto Mandato de compilacin bsico:

    cc ejemplo.c- Genera el cdigo objeto ejemplo.o- Genera el ejecutable a.out- El programa se ejecuta tecleando a.out

    El mandato cc -c ejemplo.c genera el fichero objeto ejemplo.o

    El mandato cc ejemplo.o -o ejemplo genera el ejecutable ejemplo

    - El programa se ejecuta tecleando ejemplo.

  • Marta Zorrilla Universidad de Cantabria

    9

    Modelo de compilacin C

  • Marta Zorrilla Universidad de Cantabria

    10

    Entorno desarrollo IDE

  • Marta Zorrilla Universidad de Cantabria

    11

    Ejercicio#include int cuadrado (int);

    int main (void){

    int lado2, lado1;

    printf ("dame lado del cuadrado 1:");scanf( "%d",&lado1);

    printf ("dame lado del cuadrado 2:");scanf(" %d",&lado2);

    printf ("El resultado de la diferencia es %d", cuadrado(lado1)-cuadrado(lado2));

    return(0);}

    int cuadrado (int lado){

    return(lado*lado);}

    Sean dos cuadrados de lados L1 y L2 inscritos uno en otro. Calcula el rea de la zona comprendida entre ambos, utilizando para ello una funcin (que se llamarAreaCuadrado) que devuelve el rea de un cuadrado cuyo lado se pasa como argumento

  • 12

    Elementos de un programa en C

  • Marta Zorrilla Universidad de Cantabria

    13

    Elementos de un programa C Objetivos:

    Mostrar la utilidad de documentar el cdigo utilizando los comentarios.

    Explicar los conceptos de variable y tipo de dato. Conocer los identificadores vlidos y tipos de constantes. Ensear las instrucciones de lectura y escritura junto con el formato

    de los datos.

    Contenidos:1. Comentarios2. Identificadores y palabras reservadas 3. Constantes4. Variables y tipos de dato5. Escritura de datos con printf()6. Lectura de datos con scanf()

  • Marta Zorrilla Universidad de Cantabria

    14

    Elementos de un programa C

    Bsicamente el C est compuesto por los siguientes elementos:

    Comentarios Identificadores Palabras reservadas Variables y tipos de datos Constantes Operadores

  • Marta Zorrilla Universidad de Cantabria

    15

    Comentarios

    Sirven para incrementar la legibilidad de los programas. No se pueden anidar. Dentro de un comentario no puede

    aparecer el smbolo /*

    /* Este es un comentario queocupa ms de una lnea */

    // Este comentario ocupa una sola lnea

  • Marta Zorrilla Universidad de Cantabria

    16

    Identificador

    Nombre que se asigna a los distintos elementos del programa (variables, funciones,).

    Identificadores NO vlidos: Empezar por Empezar por un nmero Utilizar la "

    Ejemplos vlidos:numeroarea_circulovalor_1

  • Marta Zorrilla Universidad de Cantabria

    17

    Palabras reservadas

    auto do for return typedefbreak double goto short unioncase else if sizeof unsignedchar enum int static voidconst extern long struct volatilecontinue float register switch whiledefault

    Es preciso insistir en que C hace distincin entre maysculas y minsculas. Por lo tanto, la palabra reservada for no puede escribirse como FOR, pues el compilador no la reconoce como una instruccin, sino que la interpreta como un nombre de variable.

  • Marta Zorrilla Universidad de Cantabria

    18

    Variables

    Identificador utilizado para representar un cierto tipo de informacin.

    Cada variable es de un tipo de dato determinado.

    Una variable puede almacenar diferentes valores en distintas partes del programa.

  • Marta Zorrilla Universidad de Cantabria

    19

    Tipos de datos bsicos

    8doublecoma flotante (doble precisin)

    4floatcoma flotante (simple precisin)

    2intentero1charcarcter0voidsin valor

    TAMAO EN BYTES

    PALABRA RESERVADA

    TIPO

  • Marta Zorrilla Universidad de Cantabria

    20

    Tipos de datos. Modificadores

    10 bytes3,4*10-4932 a 1,1*10+4932long8 bytes1,7*10-308 a 1,7*10+308double4 bytes3,4*10-38 a 3,4*10+38float4 bytes-2.147.483.648 a 2.147.483.647signed4 bytes0 a 4.294.967.295unsignedlong2 bytes-32.768 a 32.767signed2 bytes0 a 65.535unsignedshortint1 byte-128 a 127signed1 byte0 a 255unsignedcharOcupaRangoModificadoresTipo

    El tipo de dato int coincide con el tamao de palabra del procesador, generalmente 4 bytes

  • Marta Zorrilla Universidad de Cantabria

    21

    Declaracin de variables Una declaracin asocia un tipo de datos determinado a una o

    ms variables.

    El formato de una declaracin es:

    tipo_de_dato var1, var2, ..., varN;

    Ejemplos:int a, b, c;float numero_1, numero_2;char letra;unsigned long entero;

    Deben declararse todas las variables antes de su uso.

    Deben asignarse a las variables nombres significativos.int temperatura;int k;

  • Marta Zorrilla Universidad de Cantabria

    22

    Tipos definidos Permite dar nuevo nombre a tipos de datos que ya existen,

    siendo estos ms acordes con aquello que representan.

    Sintaxis:

    typedef tipo_basico nombre;

    Declaracin :

    typedef float Kg;typedef float Mts;

    Y su uso al declarar variables:

    Kg peso;Mts longitud;

  • Marta Zorrilla Universidad de Cantabria

    23

    La funcin printf()

    Permite imprimir informacin por la salida estndar (pantalla)

    Formato:

    printf(formato, argumentos);

    Ejemplos:printf("Hola mundo\n");printf("El numero 28 es %d\n", 28);printf("Imprimir %c %d %f\n", 'a', 28, 3.0e+8);

  • Marta Zorrilla Universidad de Cantabria

    24

    La funcin printf() (y 2)

    Formatos.

    TIPO DE ARGUMENTO

    CARCTER DE FORMATO

    FORMATO DE SALIDA

    Numrico %d signed decimal int %i signed decimal int %o unsigned octal int %u unsigned decimal int %x unsigned hexadecimal int (con a, ..., f) %X unsigned hexadecimal int (con A, ..., F) %f [-]dddd.dddd %e [-]d.dddd o bien e[+/-]ddd %g el ms corto de %e y %f %E [-]d.dddd o bien E[+/-]ddd %G el ms corto de %E y %f

    Carcter %c carcter simple %s cadena de caracteres %% el carcter %

    Punteros %n se refieren a punteros y se %p estudiarn en el Captulo 7

    14

  • Marta Zorrilla Universidad de Cantabria

    25

    La funcin printf() (y 3)

    Secuencias de escape.

    CARCTER BARRA SIGNIFICADO

    \a Alarma (Beep)

    \b Retroceso (BS)

    \t Tabulador Horizontal (HT)

    \n Nueva Lnea (LF)

    \v Tabulador Vertical (VT)

    \f Nueva Pgina (FF)

    \r Retorno

    \" Comillas dobles

    \' Comilla simple

    \\ Barra invertida

  • Marta Zorrilla Universidad de Cantabria

    26

    La funcin printf (y 4)

    Especificadores de ancho de campo:

    printf("Numero entero = %5d \n", 28);produce la salida:

    Numero entero = 28

    printf("Numero real = %5.4f \n", 28.2);produce la salida:

    Numero real = 28.2000

  • Marta Zorrilla Universidad de Cantabria

    27

    Funcin scanf()

    Permite leer datos del usuario. La funcin devuelve el nmero de datos que se han

    ledo bien. Formato:

    scanf(formato, argumentos);

    Especificadores de formato igual que printf().

    Ejemplos:scanf("%f", &numero);scanf("%c\n", &letra);scanf("%f %d %c", &real, &entero, &letra);scanf("%ld", &entero_largo);scanf("%s", cadena); no &

    &

    No va texto

  • Marta Zorrilla Universidad de Cantabria

    28

    Funcin scanf() (y 2) Ejemplo: lee un nmero entero y lo eleva al

    cuadrado:

    #include

    void main(){

    int numero;int cuadrado;printf("Introduzca un numero:");scanf("%d", &numero);cuadrado = numero * numero;printf("El cuadrado de %d es %d\n", numero,cuadrado);

    }

    Comenzar

    ESCRIBIRDame numero

    LEER numero

    ESCRIBIRnumero y cuadrado

    FIN

    cuadrado=numero * numero

  • Marta Zorrilla Universidad de Cantabria

    29

    Constantes simblicas

    Para evitar el uso de valores constantes dentro del cdigo, se definen las constantes simblicas

    Suele escribirse en maysculas.

    #define PI 3.141593#define CIERTO 1#define FALSO 0#define AMIGA "Marta"

    no acaba en ;

  • Marta Zorrilla Universidad de Cantabria

    30

    Constantes o literales Caracteres:

    Ejemplos: "Marta ", " barco"

    Valores enteros: Notacin decimal: 987 Notacin hexadecimal: 0x25 0X25 Notacin octal: 034 Enteros sin signo: 485U Enteros de tipo long: 485L Enteros sin signo de tipo long: 485UL Valores negativos (signo menos): -987

    Valores reales (coma flotante): Ejemplos: 12, 14, 8., .34 Notacin exponencial: .2e+9, 1.04E-12 Valores negativos (signo menos): -12 -2e+9

  • Marta Zorrilla Universidad de Cantabria

    31

    Ejemplo. Programa que lee el radio de un crculo y calcula su rea

    #include #define PI 3.141593void main(){

    float radio;float area;printf("Introduzca el radio: ");scanf("%f", &radio);area = PI * radio * radio;printf("El area del circulo es %5.4f \n", area);

    }

    Comenzar

    ESCRIBIRDame radio

    LEER radio

    ESCRIBIRarea

    FIN

    area = PI * radio * radio

    PI =3.141593

  • Marta Zorrilla Universidad de Cantabria

    32

    Ejercicios

    Encuentra erroresinclude studio.h

    /* Programa que dice cuntos das hay en una semana /*

    main {}(

    int d

    d := 7;print (Hay d das en una semana);

  • Marta Zorrilla Universidad de Cantabria

    33

    Ejercicios Indica cul sera la salida de cada uno de los

    siguientes grupos de sentencias:

    a) printf ("Historias de cronopios y famas.");printf ("Autor: Julio Cortzar");

    b) printf ("Cuntas lneas \nocupa esto?");c) printf ("Estamos \naprendiendo /naprogramar en C");d) int num;

    num = 2;printf ("%d + %d = %d", num, num, num + num);

  • 34

    Operadores y expresiones

  • Marta Zorrilla Universidad de Cantabria

    35

    Operadores y expresiones

    Objetivos: Mostrar el concepto de expresin, operador y sentencia. Mostrar el repertorio de operadores de C y el orden de precedencia.

    Contenidos:1. Expresiones y sentencias2. Operador asignacin. Conversin de tipos3. Operadores aritmticos4. Operadores relacionales5. Operadores lgicos6. Operadores de asignacin compuestos7. Precedencia

  • Marta Zorrilla Universidad de Cantabria

    36

    Expresiones y sentencias

    Sentencia: especifica una accin a realizar Ej. printf()

    Expresin: secuencia de operadores y operandos que especifican un valor Ej. 4 + 5

    Una expresin se convierte en una sentencia cuando va seguida de un punto y coma. Cuando un grupo de sentencias se encierran entre llaves { }, forman un bloque, sintcticamente equivalente a una

    sentencia.

  • Marta Zorrilla Universidad de Cantabria

    37

    Operador de asignacin Forma general: identificador = expresin ; Ejemplos:

    a = 3;area = lado * lado;

    El operador de asignacin = y el de igualdad ==

    Asignaciones mltiples:id_1 = id_2 = ... = expresin

    Las asignaciones se efectan de derecha a izquierda.En i = j = 5

    1. A j se le asigna 52. A i se le asigna el valor de j

  • Marta Zorrilla Universidad de Cantabria

    38

    Reglas de asignacin

    Si los dos operandos en una sentencia de asignacin son de tipos distintos, entonces el valor del operando de la derecha ser automticamente convertido al tipo del operando de la izquierda.Adems: 1. Un valor en coma flotante se puede truncar si se asigna a una variable

    de tipo entero. 2. Un valor de doble precisin puede redondearse si se asigna a una

    variable de coma flotante de simple precisin. 3. Una cantidad entera puede alterarse si se asigna a una variable de tipo

    entero corto o a una variable de tipo carcter.

    Es importante en C utilizar de forma correcta la conversin de tipos.

  • Marta Zorrilla Universidad de Cantabria

    39

    Conversin de tipos(tipo de dato) expresin

    int x;x = 5;y = x / 2;

    el valor asignado a la variable y ser 2, pues / realiza una divisin entera.

    int x;x = 5;y = (float) x / 2;

    Ahora, la variable y almacena el valor 2.5.

    int x;x = 5;y = (float) (x / 2);

    no se asigna a y el valor 2.5, sino 2, ya que los parntesis que envuelven a la expresin x / 2 hacen que primero se efecte la divisin entera y luego la conversin a flotante

  • Marta Zorrilla Universidad de Cantabria

    40

    Operadores aritmticos

    OPERADOR DESCRIPCIN

    UNARIOS - Cambio de signo

    - - Decremento

    ++ Incremento

    BINARIOS - Resta

    + Suma

    * Producto

    / Divisin

    % Resto de divisin entera

    Divisin entera ( / ): divisin de una cantidad entera por otra se desprecia la parte decimal del cociente.

    El operador % requiere que los dos operandos sean enteros.

    La mayora de las versiones de C asignan al resto el mismo signo del primer operando.

    Valores negativos con el signo -

  • Marta Zorrilla Universidad de Cantabria

    41

    Ejemploint x, y;x = 9;y = 2;

    la operacin x / y devuelve el valor 4, mientras que la operacin x % y devuelve 1. Sin embargo, despus de las sentencias

    float x;int y;x = 9.0;y = 2;

    la operacin x / y devuelve 4.5, no pudindose aplicar, en este caso, el operador % puesto que uno de los operandos no es entero.

  • Marta Zorrilla Universidad de Cantabria

    42

    Operadores incremento, decremento

    La expresin es equivalente ai++; i = i + 1;++i; i = i + 1;i--; i = i - 1;--i; i = i - 1;

    Si el operador sigue al operando el valor del operando se modificar despus de su utilizacin. Si el operador precede al operando el valor del operando se modificar antes de su utilizacin.

    Ejemplo: si a = 1 Imprime:

    printf("a = %d \n", a); a = 1printf("a = %d \n", ++a); a = 2printf("a = %d \n", a++); a = 2printf("a = %d \n", a); a = 3

  • Marta Zorrilla Universidad de Cantabria

    43

    Operadores relacionales

    OPERADOR DESCRIPCIN

    BINARIOS > Mayor que

    >= Mayor o igual que

    < Menor que

    b 0 falso(a + b) ! = 3 0 falsoa == b 0 falsoa == 1 1 cierto

  • Marta Zorrilla Universidad de Cantabria

    44

    Operadores lgicos

    OPERADOR DESCRIPCIN

    UNARIOS ! not

    BINARIOS && and

    || or

    Actan sobre operandos que son a su vez expresiones lgicas que se interpretan como:

    cierto, cualquier valor distinto de 0

    falso, el valor 0

    VVFVV

    VFFFV

    VFVVF

    FFVFF

    a || ba && b!abaTabla de verdad

  • Marta Zorrilla Universidad de Cantabria

    45

    Ejemplo

    && y || se evalan de izquierda a derecha. ! se evala de derecha a izquierda.

    Ejemplos: si a = 7 y b = 3

    Expresin Valor Interpretacin(a + b) < 10 0 falso!((a + b) < 10) 1 cierto(a ! = 2) || ((a +b) 4) && (b < 5) 1 cierto

  • Marta Zorrilla Universidad de Cantabria

    46

    Operadores de asignacin compuestos

    El operador de asignacin se puede combinar con otros operadores como *, /, %, +, -, , &, |, ^ para operaciones acumulativas

    m *= 5; m = m * 5;

    m += b; m = m + b;

    m += y - 3; m = m + y - 3;

    m - = (y = 5); m = m - (y = 5);

    es equivalente a

  • Marta Zorrilla Universidad de Cantabria

    47

    Precedencia

    ,15operadores de asignacin14?:13||12&&11|10^9&8== !=7< >=6>5+ -4* / %3! ~ ++ -- (cast) * & sizeof2( ) [ ] . ->1

    OperadoresNivel de prioridad

    Evaluacin a igual nivel de

    prioridad

  • Marta Zorrilla Universidad de Cantabria

    48

    Ejercicios Indica cules de los siguientes identificadores no son correctos y por

    qu.

    a) contador b) CONTADOR c) _hola d) hola_e) dias2 f) 2dias g) Suma_Total h) Suma-Total

    Sean x, y, z, u, v y t, variables que contienen, respectivamente, los valores 2, 3, 4, 5, 6 y 7, qu almacenarn despus de ejecutar las siguientes sentencias?

    x++;y = ++z;t = - -v;v = x + (y *= 3) / 2;u = x + y / 2;

  • Marta Zorrilla Universidad de Cantabria

    49

    Ejemplo

    C = (5/9) * (F - 32)

    #include void main(){

    float centigrados;float fahrenheit;

    printf("Introduzca una temperatura en grados fahrenheit: ");scanf("%f", &fahrenheit);centigrados = 5.0/9 * (fahrenheit - 32);printf("%f grados fahrenheit = %f grados centigrados \n", fahrenheit, centigrados);

    }

    Programa que convierte grados Fahrenheit a grados centgrados.

  • Marta Zorrilla Universidad de Cantabria

    50

    ERRORES COMUNES

    Olvidar que el resultado de dividir dos enteros es entero Realizar divisin por cero Olvidar la prioridad de los operadores Errores en la conversin de tipos Confundir el operador de igualdad y el de asignacin

  • 51

    Funciones

  • Marta Zorrilla Universidad de Cantabria

    52

    Introduccin a funciones

    Objetivos: Introducir al alumno en el diseo estructurado. Presentar el concepto de funcin. Mostrar la definicin y declaracin de funciones en C.

    Contenidos:1. Introduccin al diseo estructurado. Concepto de funcin2. Definicin de funciones

    o Argumentoso Valor de retornoo Llamada a funcin

    3. Declaracin de funciones. Prototipos4. Ejemplos

  • Marta Zorrilla Universidad de Cantabria

    53

    Introduccin

    Una funcin es un segmento de programa que realiza una determinada tarea.

    Todo programa C consta de una o ms funciones.

    Una de estas funciones se debe llamar main()

    Todo programa comienza su ejecucin en la funcin main()

    El uso de funciones permite la descomposicin y desarrollo modular. Permite dividir un programa en componentes ms pequeos. reutilizacin

  • Marta Zorrilla Universidad de Cantabria

    54

    Definicin de una funcintipo nombre_func (tipo1 arg1, ..., tipoN argN)

    {/* CUERPO DE LA FUNCION */

    }

    Los argumentos se denominan parmetros formales. La funcin devuelve un valor de tipo de dato tipo

    Si se omite tipo se considera que devuelve un int Si no devuelve ningn tipo void Si no tiene argumentos void

    void explicacion(void)

    Entre llaves se encuentra el cuerpo de la funcin (igual que main()). La sentencia return finaliza la ejecucin y devuelve un valor a la funcin que

    realiz la llamada. return(expresion);

    En C no se pueden anidar funciones

  • Marta Zorrilla Universidad de Cantabria

    55

    Declaracin de funciones: prototipos

    No es obligatorio pero si aconsejable. Permite la comprobacin de errores entre las llamadas a

    una funcin y la definicin de la funcin correspondiente.

    tipo nombre_func (tipo1 arg1, ..., tipoN argN);

  • Marta Zorrilla Universidad de Cantabria

    56

    Llamadas a funciones Para llamar a una funcin se especifica su nombre y la lista de argumentos

    sin poner el tipo de dato.

    nombre_func (var1,var2,,varN);

    Parmetros formales: los que aparecen en la definicin de la funcin. Parmetros reales: los que se pasan en la llamada a la funcin.

    En una llamada habr un argumento real por cada argumento formal, respetando el orden de la declaracin.

    Los parmetros reales pueden ser: Constantes. Variables simples. Expresiones complejas.

    Deben ser del mismo tipo de datos que el argumento formal correspondiente.

    Cuando se pasa un valor a una funcin se copia el argumento real en el argumento formal.

  • Marta Zorrilla Universidad de Cantabria

    57

    Paso de parmetros por valor

    En las llamadas por valor se hace una copia del valor del argumento en el parmetro formal.

    La funcin opera internamente con estos ltimos.

    Como las variables locales a una funcin (y los parmetros formales lo son) se crean al entrar a la funcin y se destruyen al salir de ella, cualquier cambio realizado por la funcin en los parmetros formales no tiene ningn efecto sobre los argumentos.

  • Marta Zorrilla Universidad de Cantabria

    58

    EjemploPrograma que calcula el mximo de dos nmeros.

  • Marta Zorrilla Universidad de Cantabria

    59

    Ejemplo:

    Funcin que calcula x elevado a y (con y entero)

    #include float potencia (float x, int y); /* prototipo */

    float potencia (float x, int y) /* definicin */{int i;float prod = 1;

    prod = pow(x,y);

    return(prod);}

  • Marta Zorrilla Universidad de Cantabria

    60

    Ejemplo 3 Programa que indica si un nmero es cuadrado perfecto.

    #include #include

    #define TRUE 1#define FALSE 0

    void explicacion(void);int cuadrado_perfecto(int x);

    void main(){

    int n, perfecto;explicacion();scanf("%d", &n);perfecto = cuadrado_perfecto(n);if (perfecto)

    printf("%d es cuadrado perfecto.\n", n);else

    printf("%d no es cuadrado perfecto.\n", n);}

  • Marta Zorrilla Universidad de Cantabria

    61

    Ejemplo 3 - Continuacin

    void explicacion(void){

    printf("Este programa dice si un numero ");printf("es cuadrado perfecto \n");printf("Introduzca un numero: );

    }

    int cuadrado_perfecto(int x){

    int raiz;int perfecto;raiz = (int) sqrt(x);

    if (x == raiz * raiz)perfecto = TRUE; /* cuadrado perfecto */

    elseperfecto = FALSE; /* no es cuadrado perfecto */

    return(perfecto);}

  • Marta Zorrilla Universidad de Cantabria

    62

    Paso de parmetros por referencia

    Hasta ahora las funciones solo devolvan un valor, pero qu pasa si tienen que devolver ms?

    En este caso, se requiere pasar parmetros por referencia

    La declaracin de una funcin en este caso sera

    void nombreFunc (tipo in1, ..., tipo inN, tipo *out1, tipo *outN){

    /* CUERPO DE LA FUNCION */}

    La llamada a la funcin

    nombre_func (in1, ..., inN, &out1, , &outN);

  • Marta Zorrilla Universidad de Cantabria

    63

    Paso de parmetros por referencia (II)

    En este tipo de llamadas los argumentos contienen direcciones devariables.

    Dentro de la funcin la direccin se utiliza para acceder al argumento real.

    En las llamadas por referencia cualquier cambio en la funcin tiene efecto sobre la variable cuya direccin se pas en el argumento. No hay un proceso de creacin/destruccin de esa direccin.

    Aunque en C todas las llamadas a funciones se hacen por valor, pueden simularse llamadas por referencia utilizando los operadores &(direccin) y * (en la direccin).

    Mediante & podemos pasar direcciones de variables en lugar de valores, y trabajar internamente en la funcin con los contenidos, mediante el operador *.

  • Marta Zorrilla Universidad de Cantabria

    64

    Ejemplo 3 con parmetros por referencia

    void explicacion ( int *numero){

    printf("Este programa dice si un numero ");printf("es cuadrado perfecto \n");printf("Introduzca un numero: );

    scanf("%d", *&n);}

    void main(){

    int n, perfecto;explicacion(&n);perfecto = cuadrado_perfecto(n);

    ..}

  • Marta Zorrilla Universidad de Cantabria

    65

    Ejercicio 4

    Programa que calcula la hipotenusa de un tringulo rectngulo.

    h = (a2 + b2)

    Pasos a seguir: 1. Leer a y b funcin leer 2. Calcular h segn la frmula dada definimos

    una funcin hipotenusa 3. Imprimir el valor de h usar printf().

  • Marta Zorrilla Universidad de Cantabria

    66

    Solucin

    #include #include

    void hipotenusa(float a, float b, float *h){

    *h = sqrt(pow(a,2) + pow(b, 2));}

    void leer (float *a, float *b){

    printf("Dame valores a y b:\n");scanf("%f %f", *&a, *&b);

    }

    void main(){float a, b, h;leer (&a,&b);hipotenusa(a,b,&h);printf("La hipotenusa es %f\n", h);}

  • Marta Zorrilla Universidad de Cantabria

    67

    Recapitulacin

    Antes de escribir un programa: Leerlo detenidamente Hacer pseudocdigo o diagrama de flujo Decidir divisin en funciones Determinar parmetros de entrada y salida Desde main() invocar a las funciones

  • 68

    Sentencias de control

  • Marta Zorrilla Universidad de Cantabria

    69

    Estructuras de control

    Objetivos: Introducir los tres tipos bsicos de sentencias de control: secuencia,

    seleccin e iteracin. Explicar la sintaxis y la semntica de las sentencias de control

    dedicadas a definir estructuras de seleccin.

    Contenidos:1. Tipos de estructuras2. Estructuras condicionales

    o Instruccin if - elseo Instruccin switch

    3. Instruccin break

  • Marta Zorrilla Universidad de Cantabria

    70

    Tipos de estructuras

    Secuencia: ejecucin sucesiva de dos o ms operaciones.

    Seleccin: se realiza una u otra operacin, dependiendo de una condicin.

    Iteracin: repeticin de una operacin mientras se cumpla una condicin.

  • Marta Zorrilla Universidad de Cantabria

    71

    If - else

    if (expresin) sentencia;

    o bien

    if (expresin) sentencia;else sentencia;

  • Marta Zorrilla Universidad de Cantabria

    72

    Ejemplo if - else Programa que lee un nmero y dice si es par o impar.

    #include main(){

    int numero;/* Leer el numero */printf("Introduzca un numero: ");scanf("%d", &numero);if ((numero % 2) == 0)

    printf("El numero %d es par.\n", numero);else

    printf("El numero %d es impar.\n", numero);}

  • Marta Zorrilla Universidad de Cantabria

    73

    Operador condicional

    Se utiliza para sentencias if-else simples

    y=(x>9 ? 100 : 200);

    if (x > 9) {y=100;

    } else {

    y=200;}

    LO MISMO

  • Marta Zorrilla Universidad de Cantabria

    74

    switch

    switch (variable) {case cte1: sentencia;

    break;case cte2: sentencia;

    break;......default: sentencia;

    }

    Tipo entero o letra

  • Marta Zorrilla Universidad de Cantabria

    75

    Ejemplo switchcase 'i':case 'I':

    printf("Vocal %c\n", letra);break;

    case 'o':case 'O':

    printf("Vocal %c\n", letra);break;

    case 'u':case 'U':

    printf("Vocal %c\n", letra);break;

    default:printf("Consonante %c\n", letra);

    }}

    #include void main(){

    char letra;printf("Introduzca una letra: ");scanf("%c", &letra);switch(letra){

    case 'a':case 'A':

    printf("Vocal %c\n", letra);break;

    case 'e':case 'E':

    printf("Vocal %c\n", letra);break;

  • Marta Zorrilla Universidad de Cantabria

    76

    Bucles

    Objetivos: Explicar la sintaxis y la semntica de las sentencias de control

    dedicadas a definir estructuras de iteracin. Mostrar patrones habituales de concatenacin de sentencias de

    control con vistas a su utilizacin en el seno de un programa real.

    Contenidos:1. Bucles

    a. Instruccin forb. Instruccin whilec. Instruccin do - while

    2. Instrucciones break y continue3. Bucles anidados

  • Marta Zorrilla Universidad de Cantabria

    77

    Instruccin for

    for (inicializacin; condicin; incremento)sentencia;

    Inicializacin: se inicializa algn parmetro que controla la repeticin del bucle.

    Condicin: es una condicin que debe ser cierta para que se ejecute sentencia.

    Incremento: se utiliza para modificar el valor del parmetro.

    El bucle se repite mientras condicin no sea cero (falso). Si sentencia es compuesta se encierra entre { } incializacin e incremento se pueden omitir. Si se omite condicin se asumir el valor permanente de 1 (cierto) y el

    bucle se ejecutar de forma indefinida.

  • Marta Zorrilla Universidad de Cantabria

    78

    Ejemplo for

    Programa que imprime los 100 primeros nmeros

    #include void main(){

    int numero;for (numero=0; numero

  • Marta Zorrilla Universidad de Cantabria

    79

    Instruccin while

    while (expresin)sentencia;

    sentencia se ejecutar mientras el valor de expresin sea verdadero (distinto de 0).

    Primero se evala expresin. Lo normal es que sentencia incluya algn elemento

    que altere el valor de expresin, proporcionando la condicin de salida del bucle.

    Si la sentencia es compuesta se encierra entre { }

  • Marta Zorrilla Universidad de Cantabria

    80

    Ejemplo while lee un nmero N y calcula 1 + 2 + 3 + + N

    #include void main(){

    int N;int suma = 0;/* leer el numero N */printf("N: ");scanf("%d", &N);while (N > 0){

    suma = suma + N;N = N - 1; /* equivalente a N-- */

    }printf("1 + 2 +...+ N = %d\n", suma);

    }

  • Marta Zorrilla Universidad de Cantabria

    81

    do - while

    dosentencia;

    while (expresin);

    sentencia se ejecutar mientras el valor de expresin sea verdadero (distinto de 0).

    sentencia siempre se ejecuta al menos una vez (diferente a while). Lo normal es que sentencia incluya algn elemento que altere el

    valor de expresin, proporcionando la condicin de salida del bucle. Si la sentencia es compuesta se encierra entre { } Para la mayora de las aplicaciones es mejor y ms natural

    comprobar la condicin antes de ejecutar el bucle (while).

  • Marta Zorrilla Universidad de Cantabria

    82

    Ejemplo do -while Programa que lee de forma repetida un nmero e indica si es par o

    impar. El programa se repite mientras el nmero sea distinto de cero.

    #include void main(){

    int numero;do{/* se lee el numero */printf("Introduzca un numero: ");scanf("%d", &numero);if ((numero % 2) == 0)

    printf("El numero %d es par.\n", numero);else

    printf("El numero %d es par.\n", numero);} while (numero != 0)

    }

  • Marta Zorrilla Universidad de Cantabria

    83

    Bucles anidados Los bucles se pueden anidar pero es importante estructurarlos de forma correcta. Ejemplo: Calcular 1 + 2 + N mientras N sea distinto de 0.

    #include main(){

    int N, suma, j;

    do{

    /* leer el numero N */printf("Introduzca N: ");scanf("%d", &N);suma = 0;for (j = 0; j 0); /* fin del bucle do */}

  • Marta Zorrilla Universidad de Cantabria

    84

    Instruccin break

    Se utiliza para terminar la ejecucin de bucles o salir de una sentencia switch.

    Es necesaria en la sentencia switch para transferir el control fuera de la misma.

    En caso de bucles anidados, el control se transfiere fuera de lasentencia ms interna en la que se encuentre, pero no fuera de las externas.

    No es aconsejable el uso de esta sentencia en bucles pues es contrario a la programacin estructurada.

    Puede ser til cuando se detectan errores o condiciones anormales.

  • Marta Zorrilla Universidad de Cantabria

    85

    Ej.

    #include void main(){int opcion;printf ("1 - Mensaje pantalla \n");printf ("2 - salir \n");printf (" cualquier carcter, no hace nada\n");printf("Elija la opcin: ");scanf("%d", &opcion);

    while (opcion){switch(opcion)

    {case 1:

    printf("Hola, selecciono opcion %d\n" , opcion);break;

    case 2:printf ("Adios \n");return;break;

    default:printf("Seleccion invalida. Intentelo de nuevo\n");

    }printf("Elija la opcion: ");scanf("%d", &opcion);

    }}

  • Marta Zorrilla Universidad de Cantabria

    86

    Sentencia continue

    Esta sentencia se utiliza en los bucles for, while y do/while.

    Cuando se ejecuta, fuerza un nuevo ciclo del bucle, saltndose cualquier sentencia posterior.

  • Marta Zorrilla Universidad de Cantabria

    87

    Ejemplo continue#include #include void main (){

    int n;int positivos = 0;

    do {printf ("\n Teclea un nmero (-99 finaliza): ");scanf ("%d", &n);if (n

  • Marta Zorrilla Universidad de Cantabria

    88

    Tabla de comparativas

    Dentro del ciclo despus de las instrucciones a repetir

    Dentro del ciclo despus de las instrucciones a repetir

    3 campo

    Cambios que hay que hacer

    noDespus de cada vuelta

    En el while entre parntesis

    Hay que ponerlo fuera, antes del ciclo

    do while

    NoAntes de cada vuelta

    En el while entre parntesis

    Hay que ponerlo fuera, antes del ciclo

    while

    siAntes de cada vuelta

    2 campo1 campofor

    pueden quedar campos vacos?

    Cuando se comprueba

    Cond. para seguir repitiendo

    Valores iniciales, operaciones previas

  • Marta Zorrilla Universidad de Cantabria

    89

    EjerciciosEscriba un programaque calcule xn, siendox y n dos nmeros quese introducen porteclado

    #include

    void main(){int n,x,i;float potencia=1;

    printf("Dame x y n \n: ");scanf("%d %d", &x, &n);

    for (i=0; i

  • Marta Zorrilla Universidad de Cantabria

    90

    Escriba un programa que calcule e imprima la suma de los pares y de los impares comprendidosentre dos valores que se piden por teclado (x y n)

    #include void leer (int *a, int *b){ do{

    printf("Solicito dos numeros a

  • Marta Zorrilla Universidad de Cantabria

    91

    Ejemplo - funciones y bucles#include

    mensaje (){

    printf ("\nTeclee un nmero (0 finaliza): ");}

    int lee_numero (){

    int n;scanf ("%d", &n);return n;

    }

    cuadrado (int x){

    printf ("\nEl cuadrado es %d", x * x);}

    void main (){

    int t;for (mensaje (); t = lee_numero (); cuadrado (t));

    }

  • 92

    Recursividad

  • Marta Zorrilla Universidad de Cantabria

    93

    Recursividad

    Objetivos: Repaso: paso de parmetros por valor y por referencia a

    una funcin. Mostrar la capacidad de la recursin y las funciones

    recursivas.

    Contenidos:1.Paso de parmetros a una funcin2.Recursividad

  • Marta Zorrilla Universidad de Cantabria

    94

    Paso de parmetros por valor

    En las llamadas por valor se hace una copia del valor del argumento en el parmetro formal.

    La funcin opera internamente con estos ltimos.

    Como las variables locales a una funcin (y los parmetros formales lo son) se crean al entrar a la funcin y se destruyen al salir de ella, cualquier cambio realizado por la funcin en los parmetros formales no tiene ningn efecto sobre los argumentos.

  • Marta Zorrilla Universidad de Cantabria

    95

    Ejemplo

  • Marta Zorrilla Universidad de Cantabria

    96

    Paso de parmetros por referencia

    En este tipo de llamadas los argumentos contienen direcciones devariables.

    Dentro de la funcin la direccin se utiliza para acceder al argumento real.

    En las llamadas por referencia cualquier cambio en la funcin tiene efecto sobre la variable cuya direccin se pas en el argumento. No hay un proceso de creacin/destruccin de esa direccin.

    Aunque en C todas las llamadas a funciones se hacen por valor, pueden simularse llamadas por referencia utilizando los operadores &(direccin) y * (en la direccin).

    Mediante & podemos pasar direcciones de variables en lugar de valores, y trabajar internamente en la funcin con los contenidos, mediante el operador *.

  • Marta Zorrilla Universidad de Cantabria

    97

    Ejemplo#include void funcion(int *a, int *b); /* prototipo */main(){

    int x = 2;int y = 5;printf("Antes x = %d, y = %d\n", x, y);funcion(&x, &y);printf("Despues x = %d, y = %d\n", x, y);

    }void funcion(int *a, int *b){

    *a = 0;*b = 0;printf("Dentro *a = %d, *b = %d\n", *a, *b);return;

    }

    x, y punteros

  • Marta Zorrilla Universidad de Cantabria

    98

    Ejemplo Funcin que intercambia el valor de dos variables.

    #include void swap_ref (int *a, int *b); /* prototipo */void main(){

    int x = 2;int y = 5;printf("Antes x = %d, y = %d\n", x, y);swap(&x, &y);printf("Despues x = %d, y = %d\n", x, y);

    }

    void swap_ref (int *a, int *b){

    int temp;temp = *b;*b = *a;*a = temp;

    }

  • Marta Zorrilla Universidad de Cantabria

    99

    Recursividad Una funcin se llama a s misma de forma

    repetida hasta que se cumpla alguna condicin.

    Ejemplo: el factorial de un nmero:

    long int factorial(int n){

    if (n

  • Marta Zorrilla Universidad de Cantabria

    100

    Ejemplo torres de Hanoi

    #include

    void transferir( int n, char desde, char hacia, char temp);

    void main(){int n;printf ("Bienvenido a las torres de Hanoi \n");printf ("Cuntos discos?\n");scanf("%d", &n);transferir(n,'I','D','C');}

    Izquierda Centro Derecha

  • Marta Zorrilla Universidad de Cantabria

    101

    Ejemplo torres de Hanoi (y 2)void transferir(int n, char desde, char hacia, char temp){

    /* transferir n discos de un pivote a otro*//* n = numero de discos

    desde = origenhacia = destinotemp = almacenamiento temporal */

    if (n>0){

    transferir (n-1, desde, temp, hacia);printf ("mover disco %d desde %c hasta %c\n", n, desde, hacia);transferir (n-1, temp, hacia,desde);

    }return;

    }

  • 102

    Arrays (listas y tablas)

  • Marta Zorrilla Universidad de Cantabria

    103

    Arrays (listas y tablas) Objetivos:

    Introducir el concepto de tipo de dato estructurado. Mostrar la representacin de datos mediante arrays unidimensionales y

    multidimensionales. Conocer la representacin de cadenas de caracteres y las funciones de manipulacin.

    Contenidos:1. Arrays

    o Declaracino Subndiceso Almacenamiento en memoriao Tamao de los arrays

    2. Inicializacin de un array3. Array de caracteres y cadenas de texto4. Arrays multidimensionales

  • Marta Zorrilla Universidad de Cantabria

    104

    Listas

    Conjunto de datos del mismo tipo a los que se da un nombre comny a los que se accede a travs de un ndice

    tipo_dato variable_lista[num_elementos];

    int numeros[20];float temperaturas[100];

    En un vector de N elementos, el primero se referencia con el ndice 0y el ltimo con el ndice N-1

    Inicializacinint numeros[2]={0,1}int numeros[]={0,1} el compilador asume array de 2 elementos

    El procesamiento se debe hacer elemento a elemento

  • Marta Zorrilla Universidad de Cantabria

    105

    Listas

    cmo se utilizan? Usar un elemento de la lista

    variable_lista[posicion]; temperaturas[10];

    Pasar a funciones en la declaracin

    void nombreFuncion (int variable)

    en la llamada a la funcin

    nombreFuncion (variable_lista[posicion])

    Empieza en 0

  • Marta Zorrilla Universidad de Cantabria

    106

    Listas de nmeros

    cmo se utilizan? Usar toda la lista. Podemos:

    Copiar una lista en otra

    memcpy (listadestino,listaorigen,tamao)

    Pasar la lista a una funcin

    void nombreFuncion (int nombreLista[TAMAO])

    nombreFuncion ( nombreLista );

    Sean de entrada o salida, no requieren *

    Ojo, corchetes

  • Marta Zorrilla Universidad de Cantabria

    107

    Listas de nmeros

    cmo se utilizan? Usar toda la lista. Podemos:

    Pasar la lista a una funcin de tamao ajustado

    void nombreFuncion (int tamano, int nombreLista[tamano])nombreFuncion ( tamano, nombreLista );

    Se debe declarar la lista dentro de un bloque Antes debe ser conocida la variable tamano La lista slo es conocida dentro del bloque

  • Marta Zorrilla Universidad de Cantabria

    108

    Ejemplo lista tamao fijo

    #include #define TAM_VECTOR 10

    void leer (int vector_a[TAM_VECTOR]){int j; /* variable utilizada como indice */

    for (j = 0; j < TAM_VECTOR; j++){

    printf("Elemento %d: ", j);scanf("%d", &vector_a[j]);

    }}

    void copiar (int vector_a[TAM_VECTOR], intvector_b[TAM_VECTOR])

    {int j; for (j = 0; j < TAM_VECTOR; j++)

    vector_b[j] = vector_a[j];}

    void escribir (int vector[TAM_VECTOR]){int j;

    for (j = 0; j < TAM_VECTOR; j++)printf("El elemento %d es %d \n", j, vector[j]);

    }

    void main(){int vector_a[TAM_VECTOR];int vector_b[TAM_VECTOR];

    leer ( vector_a);copiar (vector_a, vector_b);escribir (vector_b);}

  • Marta Zorrilla Universidad de Cantabria

    109

    Ejemplo lista tamao variable#include void leer (int cuantos, float lista[cuantos])

    {int i;

    printf ("teclealos :\n");for (i=0 ; i< cuantos ; i++)

    {scanf("%f", &lista[i]);}

    }void pintar(int cuantos, float lista[cuantos])

    {int i;for (i=0 ; i< cuantos ; i++)

    {printf("%i\n", lista[i]);}

    }

    void main(){

    int cuantos;

    printf ("dame cuantos \t");scanf("%i", &cuantos);{

    float lista[cuantos];

    leer(cuantos,lista);pintar (cuantos, lista);

    } }

  • Marta Zorrilla Universidad de Cantabria

    110

    Ordenacin elementos de lista#include #include

    int comparar (int *num1, int *num2) {return ((*num1)-(*num2));

    }

    void main(){

    int cuantos;printf ("dame cuantos \t");scanf("%i", &cuantos);{

    float lista[cuantos];leer(cuantos,lista);qsort(lista,cuantos, sizeof(lista[0],comparar);pintar (cuantos, lista);}

    }

  • Marta Zorrilla Universidad de Cantabria

    111

    La funcin sizeof() Devuelve el tamao en bytes que ocupa un tipo o

    variable en memoria.

    #include main(){

    char cadena[10];

    printf("un int ocupa %d bytes\n", sizeof(int));printf("un char ocupa %d bytes\n", sizeof(char));printf("un float ocupa %d bytes\n", sizeof(float));printf("un double ocupa %d bytes\n", sizeof(double));printf(" cadena ocupa %d bytes\n", sizeof(cadena));

    }

  • 112

    Algoritmos de ordenacin y bsqueda

    Transparencias en pdf aparte

  • Marta Zorrilla Universidad de Cantabria

    113

    Cadenas de caracteres Un caso particular de lista es la cadena de caracteres. Se declara:

    char nombre[num_car];

    y permite almacenar num_car-1 caracteres y el carcter nulo '\0' de terminacin.

    char frase[21];

    es apta para almacenar 20 caracteres y el nulo.

    C permite la inicializacin de cadenas de caracteres en la declaracin, mediante sentencias del tipo

    char cadena[ ] = "Esto es una cadena de caracteres";

    en la que no es necesario aadir el nulo final ni indicar el tamao, pues lo hace automticamente el compilador.

    Generalmente se utiliza tamao por exceso, no se suele preguntar al usuario cuntos caracteres va a introducir

  • Marta Zorrilla Universidad de Cantabria

    114

    Cadenas de caracteres

    Cmo se utilizan? Usar un elemento de la lista. Igual que lista de nmeros. Usar toda la lista. Hay diferencias:

    Leer una lista de letras con una sola instruccinscanf (%s, palabra) coge hasta espacio o fin de lneascanf (%[^\n], frase) coge hasta fin de lnea

    Escribir una lista de letrasprintf (%s, palabra)

    Copiar una lista de letras strcpy (str_destino, str_origen)

  • Marta Zorrilla Universidad de Cantabria

    115

    biblioteca estndar string.hchar *strcat (char *cad1, const char *cad2) Concatena cad2 a cad1 devolviendo la

    direccin de cad1. Elimina el nulo de terminacin de cad1 inicial.char *strcpy (char *cad1, const char *cad2) Copia la cadena cad2 en cad1,

    sobreescribindola. Devuelve la direccin de cad1. El tamao de cad1 debe ser suficiente para albergar a cad2.

    int strlen (const char *cad) Devuelve el nmero de caracteres que almacena cad (sin contar el nulo final).

    int isalnum (int ch) Devuelve 1 si ch es alfanumrico (letra del alfabeto o dgito) y 0 en caso contrario.

    int isalpha (int ch) Devuelve 1 si ch es una letra del alfabeto y 0 en caso contrario.int isdigit (int ch) Devuelve 1 si ch es un dgito del 0 al 9, y 0 en caso contrario.int islower (int ch) Devuelve 1 si ch es un letra minscula y 0 en caso contrario.int isupper (int ch) Devuelve 1 si ch es una letra mayscula y 0 en caso contrario.int tolower (int ch) Devuelve el carcter ch en minscula. Si ch no es una letra

    mayscula la funcin devuelve ch sin modificacin.int toupper (int ch) Devuelve el carcter ch en mayscula. Si ch no es una letra

    minscula la funcin devuelve ch sin modificacin.

  • Marta Zorrilla Universidad de Cantabria

    116

    Ejemplo: lectura y escritura de cadenas de caracteres

    #include #define TAM_CADENA 80main(){char cadena[TAM_CADENA];printf("Introduzca una cadena: ");scanf("%s", cadena);printf("La cadena es %s\n", cadena);}

    scanf deja de buscar cuando encuentra un blanco si se introduce Hola a todos, solo se leer Hola.

    No es necesario el operador de direccin (&) ya que cadena representa de forma automtica la direccin de comienzo.

    no requiere &

  • Marta Zorrilla Universidad de Cantabria

    117

    Ejemplo: lectura y escritura de cadenas de caracteres (y 2)

    La funcin gets lee una lnea completa hasta que encuentre el retorno de carro incluyendo los blancos.

    La funcin puts escribe una cadena de caracteres junto con un salto de lnea.

    #include #define TAM_LINEA 80main(){char linea[TAM_LINEA];printf("Introduzca una linea: \n");gets(linea);puts("La linea es");puts(linea);}

    Son equivalentes:puts("La linea es:"); printf("La linea es: \n");

  • Marta Zorrilla Universidad de Cantabria

    118

    Ej.#include #include #define MAXLETRAS 20

    void leer (char palabra[MAXLETRAS]){

    printf ("\nTeclee una cadena de caracteres: ");scanf(%s, palabra);

    }

    void escribir (char palabra[MAXLETRAS]){

    int primera=0, ultima=0, i;

    ultima=strlen(palabra)-1;

    for (i=ultima; i>=primera; i--)printf(%c,palabra[i]);

    }

    void main (void){

    char palabra[MAXLETRAS];leer(palabra);escribir(palabra);

    }

    Programa que lee una palabra y la escribe al revs

  • Marta Zorrilla Universidad de Cantabria

    119

    Ej.#include #include #define MAXLETRAS 100

    void leer (char cadena [MAXLETRAS]){

    printf ("\nTeclee una cadena de caracteres: ");gets (cadena);

    }

    void escribir (char cadena[MAXLETRAS]){

    int i, contador=0;for (i = 0; i

  • Marta Zorrilla Universidad de Cantabria

    120

    Vectores multidimensionales Un vector multidimensional se declara:

    tipo_dato vector[exp1] [exp2] ... [expN];

    Matrices o vectores de 2 dimensiones:

    int matriz[20][30];

    define una matriz de 20 filas por 30 columnas.

    Generalmente se declaran por exceso.

    La numeracin comienza en 0.

  • Marta Zorrilla Universidad de Cantabria

    121

    Tablas

    Cmo se utilizan? Usar un elemento de la tabla

    tabla[fila][columna]

    Pasar un elemento a una funcin. llamada

    nombreFuncion (arg1,.., nombretabla[fila][columna])

    declaracinvoid nombreFuncion (tipo arg1,, tipo variablesimple)

    Usar una columna de la tabla: NO SE PUEDE EN C

  • Marta Zorrilla Universidad de Cantabria

    122

    Tablas Usar un vector de la tabla como argumento a una funcin:

    tabla[fila] declaracin

    void nombreFuncion (tipo arg1,, tipo lista[COLUMNAS]) llamada

    nombreFuncion (arg1,.., nombretabla[fila]);

    Usar una tabla completa Copiar

    memcpy(destino, origen,tamao)Ej: memcpy ( clientes2, clientes1, sizeof(int)*filas*columnas)

    Parmetro de una funcin Declaracin de funcin

    void nombreFuncion (tipo arg1,, tipo tabla[FILAS][COLUMNAS]) Llamada a una funcin

    nombreFuncion (arg1,, tabla)

  • Marta Zorrilla Universidad de Cantabria

    123

    Ejemplo#include

    void sumar(int filas, int columnas, float tabla1[filas][columnas], float tabla2[filas][columnas]){int i,j, acumulador=0;

    for (i=0;i

  • Marta Zorrilla Universidad de Cantabria

    124

    Ejemplo Funcin que calcula el producto de dos matrices cuadradas.

    void multiplicar(float a[DIM][DIM], float b[DIM][DIM], float c[DIM][DIM]){

    int i, j, k;for(i = 0; i < DIM; i++)for(j = 0; j < DIM; j++){

    c[i][j] = 0.0;for(k = 0; k < DIM; k++)

    c[i][j] += a[i][k] * b[k][j];}

    }

  • Marta Zorrilla Universidad de Cantabria

    125

    Ej.:#include #include #define MAX 30 /*incluye el fin de lnea*/

    void leer(int numpal, int columnas, char tabla[numpal][MAX], char pal[MAX]){int i;printf("dame palabras:\n");

    for (i=0;i

  • 126

    Estructuras y uniones

  • Marta Zorrilla Universidad de Cantabria

    127

    Estructuras y uniones Objetivos:

    Conocer la posibilidad de definir tipos de datos estructurados con campos heterogneos mediante el uso de estructuras.

    Explicar la posibilidad de combinar tipos de datos estructurados. Mostrar los tipos union.

    Contenidos:1. Estructuras

    o Concepto de campoo Declaracin e inicializacin

    2. Acceso a estructuras3. Declaracin typedef4. Combinacin de datos estructurados5. Campos variables con el uso de union

  • Marta Zorrilla Universidad de Cantabria

    128

    Estructuras Es una estructura de datos compuesta de elementos individuales que

    pueden ser de distinto tipo. Cada uno de los elementos de una estructura se denomina miembro. Declaracin de una estructura:

    struct nombre_estructura{tipoDato1 miembro_1;tipoDato2 miembro_2;..tipoDatoN miembro_N;};

    Los miembros pueden ser de cualquier tipo excepto void

  • Marta Zorrilla Universidad de Cantabria

    129

    Ejemplo Declaracin de una estructura denominada CD.

    struct CD{char titulo[100];char artista[50];int num_canciones;int anio;Euros precio;};

    Declaracin de una variable denominada cd1 de tipo struct CD.struct cd1 CD;

    Se pueden copiar estructuras, pero NO comparar:struct CD cd1,cd2;cd2 = cd1;

  • Marta Zorrilla Universidad de Cantabria

    130

    Inicializacin de una estructura Dos formas:

    En la declaracin:

    struct CD{char titulo[100];char artista[50];int num_canciones;int anio;Euros precio;} cd1= {Un sueo de verano,Miguel Rios,1989,10};

    En el programa:

    struct CD cd1;strcpy(cd1.titulo, Un sueo de verano"); strcpy(cd1.artista, Miguel Rios");cd1.num_canciones = 2;c1.anio = 1989;

  • Marta Zorrilla Universidad de Cantabria

    131

    Acceso a una estructura Los miembros de una estructura se procesan individualmente. Para hacer referencia a un miembro determinado, se utiliza el operador

    . si la variable es de tipo estructuravariable_estructura.miembro

    O, se utiliza el operador -> si la variable es de tipo puntero a estructuravariable_estructura->miembro

    Ejemplo: imprimir la fecha de hoystruct fecha {int dia, mes, anio;};

    struct fecha hoy;struct fecha *ayer;

    printf("%d: %d: %d\n", hoy.dia,hoy.mes, hoy.anno);printf("%d: %d: %d\n", ayer->dia, ayer-> mes, ayer-> anno);

  • Marta Zorrilla Universidad de Cantabria

    132

    Ejemplo#include struct fecha{int dia;int mes;int anno;};

    struct cuenta{int cuenta_no;char nombre[80];float saldo;struct fecha ultimo_pago;};

  • Marta Zorrilla Universidad de Cantabria

    133

    Ejemplo (y 2)main(){struct cuenta c1, c2;/* rellena la estructura c1 */c1.cuenta_no = 2;strcpy(c1.nombre, "Pepe");c1.saldo = 100000;c1.ultimo_pago.dia = 12;c1.ultimo_pago.mes = 5;c1.ultimo_pago.anno = 1997;/* asignacion de estructuras */c2 = c1;printf("No. Cuenta %d \n", c2.cuenta_no);printf("Nombre %s \n", c2.nombre);printf("Saldo %f \n", c2.saldo);printf("Fecha de ultimo pago: %d:%d:%d \n", c2.ultimo_pago.dia,

    c2.ultimo_pago.mes, c2.ultimo_pago.anno);}

  • Marta Zorrilla Universidad de Cantabria

    134

    Combinacin de datos estructurados: vector de estructuras

    #include #include

    #define NUMCAJAS 3

    typedef struct{

    char pieza[20]; /* Tipo de pieza. */int cantidad; /* Nmero de piezas. */float precio_unitario; /* Precio de cada pieza. */char existe; /* Comprobar si el registro existe. */

    } registro_piezas;

    Programa que permita introducir las piezas de un almacn (tipo, nombre, nro, precio) e imprimirlas

    Caja 1

    Caja Ncaja ...

  • Marta Zorrilla Universidad de Cantabria

    135

    main(){

    registro_piezas cajas[NUMCAJAS];int registro=0;int i;do{ /* Leer el nombre de la pieza. */

    printf("Nombre de la pieza => ");scanf("%s", cajas[registro].pieza);

    /* Leer el nmero de piezas. */printf("Numero de piezas => ");scanf("%d", &cajas[registro].cantidad);

    /* Leer el precio de cada pieza. */printf("Precio de cada pieza => ");scanf("%f", &cajas[registro].precio_unitario);

    /* Indicar que el registro tiene datos, V */cajas[registro].existe = 'V';

    registro ++;} while (registro < NUMCAJAS);

  • Marta Zorrilla Universidad de Cantabria

    136

    Cont.

    /* Imprimir la informacin. */

    for(registro = 0; registro < NUMCAJAS; registro++){

    if(cajas[registro].existe == 'V'){

    printf("La caja %d contiene:\n", registro + 1);printf("Pieza => %s\n", cajas[registro].pieza);printf("Cantidad => %d\n",

    cajas[registro].cantidad);printf("Precio unitario => $%f\n",

    cajas[registro].precio_unitario);}

    } /* Fin for. */} /*fin main*/

  • Marta Zorrilla Universidad de Cantabria

    137

    Paso de estructuras a funciones

    Una funcin puede devolver una estructura. Se pueden pasar miembros individuales y estructuras

    completas a una funcin. Si la estructura es grande, el tiempo para copiar un estructura (paso por valor) es prohibitivo, por eso se aconseja pasarlo por referencia.

    Paso de miembros individuales

    struct punto{float x;float y;};

    void imprime_x (float x){printf ("el valor de x %f", x);}

    /*llamada a funcin*/

    imprime_x (p1.x);

  • Marta Zorrilla Universidad de Cantabria

    138

    Paso de estructuras a funciones por valor

    struct fecha leer_fecha(void){

    struct fecha f;

    printf("Dia: ");scanf("%d", &(f.dia));printf("Mes: ");scanf("%d", &(f.mes));printf("Anno: ");scanf("%d", &(f.anno));return(f);

    }

    main(){struct fecha fecha_de_hoy;fecha_de_hoy = leer_fecha();imprimir_fecha(fecha_de_hoy);}

    #include struct fecha{int dia;int mes;int anno;};

    void imprimir_fecha(struct fecha f){printf("Dia: %d\n", f.dia);printf("Mes: %d\n", f.mes);printf("Anno: %d\n", f.anno);return;}

    Ej.: leer y escribir una fecha.

  • Marta Zorrilla Universidad de Cantabria

    139

    Paso de estructuras a funciones por referencia

    void leer_punto(struct punto *p);void imprimir_punto(struct punto p);

    struct punto{float x;float y;};

    main(){struct punto p1;

    leer_punto(&p1);imprimir_punto(p1);

    }

    void leer_punto(struct punto *p){

    printf("x = ");scanf("%f", &(p->x));printf("y = ");scanf("%f", &(p->y));

    }void imprimir_punto(struct punto p){printf("x = %f\n", p.x);printf("y = %f\n", p.y);}

  • Marta Zorrilla Universidad de Cantabria

    140

    Uniones Una union contiene miembros cuyos tipos de datos pueden ser

    diferentes (igual que las estructuras). Su declaracin es similar a las estructuras:

    union nombre_estructura{tipoDato1 miembro_1;tipoDato2 miembro_2;..tipoDatoN miembro_N;};

    Todos los miembros que componen la union comparten la misma zona de memoria ahorro de memoria.

    Una variable de tipo union slo almacena el valor de uno de sus miembros.

  • Marta Zorrilla Universidad de Cantabria

    141

    Ejemplo#include #include union numero{int entero;float real;};main(){union numero num;/* leer un entero e imprimirlo */printf("Entero: ");scanf("%d", &(num.entero));printf("El entero es %d\n", num.entero);/* leer un real e imprimirlo */printf("Real: ");scanf("%f", &(num.real));printf("El entero es %f\n", num.real);}

    0 1 32enteroreal

  • Marta Zorrilla Universidad de Cantabria

    142

    Combinacin de datos estructurados: vector de estructuras y unionstruct ALUMNO {

    char grupo[15];int asignat;char repite;

    };struct PROFESOR {

    char nrp[16];char cargo[21];

    };union AL_PR {

    struct ALUMNO al;struct PROFESOR pr;

    };

    struct DATOS {char tipo;char nombre[40];int edad;char direccion[40];char telefono[15];union AL_PR ambos;

    } personal[100];

    Persona 1

    Persona nPersona ...

  • Marta Zorrilla Universidad de Cantabria

    143

    El siguiente segmento de programa muestra los datos de la matriz personal.

    for (i = 0; i < 100; i++) {printf ("\nNombre: %s", personal[i].nombre);printf ("\nEdad: %d", personal[i].edad);printf ("\nDireccin: %s", personal[i].direccion);printf ("\nTelfono: %s", personal[i].telefono);if (personal[i].tipo == 'A') {

    printf ("\nALUMNO");printf ("\nGrupo: %s", personal[i].ambos.al.grupo);printf ("\nN de Asignaturas: %d", personal[i].ambos.al.asignat);printf ("\nRepite: %d", personal[i].ambos.al.repite); }

    else {printf ("\nPROFESOR");printf ("\nN.R.P.: %s", personal[i].ambos.pr.nrp);printf ("\nCargo: %s", personal[i].ambos.pr.cargo);

    }}

  • Marta Zorrilla Universidad de Cantabria

    144

    Tipos enumerados Un tipo enumerado es similar a las estructuras. Sus miembros son constantes de tipo int. Es til definir nuevos literales para

    Asociar un nombre a un valor numrico Limitar los valores que puede tomar una variable entera Hacer el cdigo ms legible

    Definicin:

    enum nombre {m1, m2, ..., mN};

    Ejemplo:enum color {negro, blanco, rojo};

  • Marta Zorrilla Universidad de Cantabria

    145

    Ejemplo#include enum semaforo {rojo, amarillo, verde};main(){enum estado semaforo;for(estado =rojo; estado

  • Marta Zorrilla Universidad de Cantabria

    146

    Definicin de tipos de datos (typedef)

    Permite dar nuevo nombre a tipos de datos que ya existen:

    typedef tipoDato nuevo_tipo;

    Ejemplos:typedef char letra;letra c;

    typedef struct{int dia;int mes;int anio;

    } FECHA;FECHA a;

  • Marta Zorrilla Universidad de Cantabria

    147

    Combinacin de typedef y enum Usando typedef y enum se pueden definir tipos que slo pueden

    tomar ciertos valores Ej. tipo booleano en C

    typedef enum {false, true} boolean;...boolean f=false;...if(f)

    printf("f es verdadero\n");else

    printf("f es falso\n");...f=45; /* Error, no debera tomar ese valor */

  • 148

    Ficheros

    Marta Zorrilla

  • Marta Zorrilla Universidad de Cantabria

    149

    Ficheros

    Objetivos: Presentar el tipo de dato FILE y los tipos de fichero. Explicar las instrucciones para abrir, cerrar y gestionar ficheros. Capacitar al alumno a trabajar con ficheros de texto y binarios.

    Contenidos:1. Concepto de ficheros y sus tipos2. Declaracin de una variable tipo fichero3. Operaciones con ficheros:

    o Abrir y cerrar ficheroso Control de errores y fin de ficheroo Lectura/escritura de ficheros de texto: caracteres, cadenas de

    caracteres y con formatoo Lectura/escritura de ficheros binarios o Acceso directo a informacin de archivos

  • Marta Zorrilla Universidad de Cantabria

    150

    Canales y ficheros

    El sistema de E/S del ANSI C proporciona un intermediario entre el programa y el dispositivo al que se accede (pantalla, cinta, disco,...).

    Este intermediario se llama canal o flujo (stream) y es un buffer independiente del dispositivo al que se conecte.

    Existen dos tipos de canales: Canales de texto: Son secuencias de caracteres. Dependiendo del

    entorno puede haber conversiones de caracteres (LF CR + LF). Esto hace que el nmero de caracteres escritos/ledos en un canal pueda no coincidir con el nmero de caracteres escritos/ledos en el dispositivo.

    Canales binarios: Son secuencias de bytes. A diferencia de los canales de texto, en los canales binarios la correspondencia de caracteres en el canal y en el dispositivo es 1 a 1, es decir, no hay conversiones.

  • Marta Zorrilla Universidad de Cantabria

    151

    Canales y ficheros ( y 2) Hay 3 canales que se abren siempre que comienza un programa C:

    stdin Canal estndar de entrada. Por defecto el teclado. (ANSI) stdout Canal estndar de salida. Por defecto la pantalla. (ANSI) stderr Canal estndar de salida de errores. Por defecto la pantalla.

    (ANSI)

    Un canal se asocia a un archivo cuando se abre o se crea ste para lo cual se utilizan funciones de la biblioteca stdio.h.

    Tambin incluye funciones para realizar las operaciones de lectura/escritura as como para desasociar un canal de un archivo (operacin de cierre).

  • Marta Zorrilla Universidad de Cantabria

    152

    Apertura de un archivo

    Para abrir un archivo:

    desc = fopen(nombre_archivo, modo)

    donde desc, el descriptor, se declara como:

    FILE *desc;

    y modo especifica la forma de apertura del archivo. si fopen devuelve NULL, el fichero no se pudo abrir.

  • Marta Zorrilla Universidad de Cantabria

    153

    Parmetros para abrir un fichero

    MODO

    DESCRIPCIN

    r Abre un fichero slo para lectura. Si el fichero no existe fopen() devuelve un puntero nulo y se genera un error.

    w Crea un nuevo fichero para escritura. Si ya existe un fichero con este nombre, se sobreescribe, perdindose el contenido anterior.

    a Abre o crea un fichero para aadir. Si el fichero existe, se abre apuntando al final del mismo. Si no existe se crea uno nuevo.

    r+ Abre un fichero para leer y escribir. Si el fichero no existe fopen()devuelve un puntero nulo y se genera un error. Si existe, puedenrealizarse sobre l operaciones de lectura y de escritura.

    w+ Crea un nuevo fichero para leer y escribir. Si ya existe un fichero con este nombre, se sobreescribe, perdindose el contenido anterior. Sobre el archivo pueden realizarse operaciones de lectura y de escritura.

    a+ Abre o crea un fichero para leer y aadir. Si el fichero ya existe se abre apuntando al final del mismo. Si no existe se crea un fichero nuevo.

    Modo TEXTO: aadir letra t. Ej: si modo es rt, se est abriendo el fichero en modo texto slo para lecturaModo BINARIO: aadir letra b. Ej: modo es w+b se abrir o crear un fichero en modo binario para lectura y escritura

  • Marta Zorrilla Universidad de Cantabria

    154

    Cierre de un fichero

    Para cerrar un fichero y liberar el canal previamente asociado con fopen(), se debe usar la funcin fclose()

    int fclose (FILE *canal);

    Esta funcin devuelve 0 si la operacin de cierre ha tenido xito, y distinto de 0 en caso de error.

  • Marta Zorrilla Universidad de Cantabria

    155

    Ejemplo#include main(){

    FILE *desc;desc = fopen("ejemplo.txt", w");if (desc == NULL)

    {printf("Error, no se puede abrir el archivo \n");}

    else{/* se procesa el archivo *//* al final se cierra */fclose(desc);}

    exit(0);}

  • Marta Zorrilla Universidad de Cantabria

    156

    Control de errores

    Cada vez que se realiza una operacin de lectura o de escritura sobre un fichero debemos comprobar si se ha producido algn error. Para ello disponemos de la funcin ferror()

    int ferror (FILE *canal);

    Esta funcin devuelve 0 si la ltima operacin sobre el fichero se ha realizado con xito.

  • Marta Zorrilla Universidad de Cantabria

    157

    Final de fichero Cada vez que se realiza una operacin de lectura sobre un fichero, el

    indicador de posicin del fichero se actualiza.

    Es necesario, pues, controlar la condicin de fin de fichero. Por ello, debemos saber que cuando se intentan realizar lecturas ms all del fin de fichero, el carcter ledo es siempre EOF. Sin embargo en los canales binarios un dato puede tener el valor EOF sin ser la marca de fin de fichero. Es aconsejable, por ello, examinar la condicin de fin de fichero mediante la funcin feof()

    int feof (FILE *canal);

    Esta funcin devuelve un valor diferente de cero cuando se detecta el fin de fichero.

  • Marta Zorrilla Universidad de Cantabria

    158

    Ficheros de texto

    Se trata de archivos cuyo contenidos son caracteres en formato ASCII, por tanto, son legibles y editables por cualquier editor de texto. Usualmente tienen la extensin txt.

    Para abrir un archivo en modo texto se debe emplear el modificador t en el modo de apertura del archivo.

    Existen dos formas de tratar ficheros de texto: Carcter a carcter (fgetc y fputc) Cadenas de caracteres (fgets y fputs) Con formato (fprintf y fscanf)

  • Marta Zorrilla Universidad de Cantabria

    159

    Funciones de manejo carcter a carcter

    Lectura:

    int fgetc(FILE *fich)

    Lee un carcter del archivo (EOF si estamos al final del mismo)

    Escritura:

    int fputc(char c, FILE *fich)

    Escribe el carcter c en el archivo. Si es correcto devuelve el mismo carcter y si no EOF.

  • Marta Zorrilla Universidad de Cantabria

    160

    Ejemplo Ejemplo que realiza la lectura de un archivo carcter a carcter

    empleando un buffer:

    char buffer[255], lineas[100][80], c;int n, t;FILE *entrada;

    entrada = fopen(ejemplo.txt, rt);while (!feof(entrada)) {t = 0;do {

    c = fgetc(entrada);buffer[t] = c;t++;} while (c!=EOF && c!=\n); //fin de fichero o de lnea

    strcpy(lineas[n], buffer);n++;}fclose(salida);

  • Marta Zorrilla Universidad de Cantabria

    161

    Funciones de manejo cadenas de caracteres

    Lectura:

    char *fgets(const char *s, int n, FILE *fich)

    Lee n-1 caracteres o hasta carcter de fin de lnea (que tambin se almacena en s). Si no se produce error, la funcin devuelve un puntero a char; en caso contrario, devuelve un puntero nulo.

    Escritura:

    int fputs(char *s, FILE *fich)

    Escribe la cadena s en el archivo. Si es correcto devuelve un valor no negativo y si no EOF. No copia el carcter nulo ni aade el carcter de fin de lnea.

  • Marta Zorrilla Universidad de Cantabria

    162

    Ejemplo#include int main(void){

    FILE *fent;FILE *fsal;char car[120];int res = 0;char * ret;

    /* Apertura del archivo de entrada */fent = fopen("./entrada.txt", "r");if (fent == NULL){

    fprintf(stderr, "Error abriendo entrada.txt \n");return(0);

    }

    /* Apertura, con creacin si no existe, del archivo de salida */fsal = fopen("./salida.txt", "w");if (fsal == NULL){

    fprintf(stderr, "Error creando salida.txt \n");fclose(fent);return(0);

    }

  • Marta Zorrilla Universidad de Cantabria

    163

    Ejemplo (y 2)/* Bucle de lectura y escritura con lneas */

    do{

    /* Lectura de la lnea siguiente */ret = fgets(car, 110, fent);if ( car == NULL)

    fprintf(stderr, "Error al leer \n");else

    fprintf(stdin, "Longitud linea leida: %d \n", strlen(car));/* Escritura de la lnea */if (ret != NULL) {

    res = fputs(car, fsal);if (res == EOF)

    fprintf(stderr, "Error al escribir %s \n", car);}

    } while (ret != NULL);/* Cierre de los streams de entrada y de salida */fclose(fent);fclose(fsal);return(0);

    }

  • Marta Zorrilla Universidad de Cantabria

    164

    Funciones de manejo con formato

    Lectura:

    int fscanf(FILE *fich, char *formato, arg1,arg2,argN)

    Su uso es el mismo que scanf pero con la salvedad de que lee desde un archivo, en vez desde el teclado.

    Escritura:

    int fprintf(FILE *fich, char *formato, arg1,arg2,argN)

    Su uso es igual al de printf pero con la salvedad de que escribe en un archivo en vez de en la pantalla.

  • Marta Zorrilla Universidad de Cantabria

    165

    Ejemplo

    Veamos un ejemplo para escribir una cadena de caracteres en un fichero:

    char cadena[255];FILE *salida;salida = fopen(salida.txt, wt);strcpy(cadena, Prueba de escritura);fprintf(salida,%s,cadena);fclose(salida);

  • Marta Zorrilla Universidad de Cantabria

    166

    Ficheros binarios

    Son archivos cuyo contenido son caracteres en formato binario, por tanto NO son legibles ni editables. Para asegurarnos que la apertura de un archivo se hace en modo binario se debe emplear el modificador b en el modo de apertura del archivo. Si noponemos nada se asume el modo binario por defecto.

    Las funciones bsicas de escritura y lectura asociadas a este modo son: fwrite y fread.

    Generalmente se utilizan para leer estructuras

  • Marta Zorrilla Universidad de Cantabria

    167

    Escribir a fichero binario

    Escritura

    int fwrite(void *datos, int tam, int ndatos, FILE *fich);

    Devuelve:Nmero de elementos (no bytes) escritos en el archivo.

    Parmetros:*ptr = puntero al origen de los datos.tam = tamao de cada elemento.ndatos = nmero de elementos.*fich = puntero a FILE (archivo donde escribir).

  • Marta Zorrilla Universidad de Cantabria

    168

    Ejemplo

    FILE *archivo;int valor;Tficha ficha;int n;archivo=fopen(c:\archivo.dat,w);n = fwrite(&valor, sizeof(int), 1, archivo);if (n!=1) printf(Error: escritura incompleta.);n = fwrite(&ficha, sizeof(TFicha), 1, archivo);if (n!=1) printf(Error: escritura incompleta.);

  • Marta Zorrilla Universidad de Cantabria

    169

    Lectura de fichero binario

    Sintaxis:

    int fread(void *datos, int tam, int ndatos, FILE *fich);

    Devuelve el nmero de elementos (no bytes) ledos del archivo.

    Parmetros:*ptr = puntero al destino de los datos.tam = tamao de cada elemento.ndatos = nmero de elementos.*fich = puntero a FILE (archivo de donde leer).

  • Marta Zorrilla Universidad de Cantabria

    170

    Ejemplo

    TFicha fichas[100];int nfichas;FILE *agenda;nfichas =0;

    agenda = fopen(agenda.dat, rb);while (!feof(agenda)) {

    fread(&fichas[nfichas], sizeof(TFicha), 1, agenda);nfichas ++;

    }fclose(agenda);

  • Marta Zorrilla Universidad de Cantabria

    171

    Ejemplo agenda

    El registro de ese archivo constar de los siguientes campos:Nombre 40 caracteresDomicilio 40 caracteresPoblacin 25 caracteresProvincia 15 caracteresTelfono 10 caracteres

    El programa crea el fichero llamado LISTIN.TEL con los datos suministrados por el usuario

  • Marta Zorrilla Universidad de Cantabria

    172

    Ejemplo#include

    typedef struct {char nom[41];char dom[41];char pob[26];char pro[16];char tel[11];

    } REG;

    void main (void){

    FILE *f;REG var;

    if (!(f = fopen ("LISTIN.TEL", "wb"))) {perror ("LISTIN.TEL");return;

    }printf ("Nombre: ");gets (var.nom);

  • Marta Zorrilla Universidad de Cantabria

    173

    Ejemplo (y 2)while (var.nom[0]) {

    printf ("\nDomicilio: ");gets (var.dom);printf ("\nPoblacin: ");gets (var.pob);printf ("\nProvincia: ");gets (var.pro);printf ("\nTelfono: ");gets (var.tel);

    fwrite (&var, sizeof (var), 1, f);if (ferror (f)) {

    puts ("No se ha almacenado la informacin");getch ();

    }printf ("Nombre: ");gets (var.nom);

    }fclose (f);

    }

  • Marta Zorrilla Universidad de Cantabria

    174

    Ejemplo: Lectura en bloques#include typedef struct {

    char nom[41];char dom[41];char pob[26];char pro[16];char tel[11];

    } REG;void main (void){

    FILE *f;REG var[4];int i, n;if (!(f = fopen ("LISTIN.TEL", "rb"))) {

    perror ("LISTIN.TEL");exit (1);

    }do {

    n = fread (var, sizeof (REG), 4, f);for (i = 0; i < n; i++) printf ("\n%-41s %s", var[i].nom, var[i].tel);puts ("\nPulse una tecla ...");getch ();

    } while (!feof (f));fclose (f);

    }

  • Marta Zorrilla Universidad de Cantabria

    175

    Acceso directo

    El acceso directo a un archivo, se realiza con la ayuda de la funcin fseek() que permite situar el indicador de posicin del archivo en cualquier lugar del mismo.

    int fseek (FILE *canal, long nbytes, int origen);

    Esta funcin sita el indicador de posicin del fichero nbytescontados a partir de origen.

    La funcin devuelve 0 cuando ha tenido xito. En caso contrario devuelve un valor diferente de 0.

    Esta funcin simplemente maneja el indicador de posicin del fichero, pero no realiza ninguna operacin de lectura o escritura. Por ello, despus de usar fseek() debe ejecutarse una funcin de lectura o escritura.

  • Marta Zorrilla Universidad de Cantabria

    176

    Acceso directo (y 2)

    int fseek (FILE *canal, long nbytes, int origen);

    Los valores posibles del parmetro origen y sus macros asociadas

    SEEK_END2Fin del fichero

    SEEK_CUR1Posicin actual

    SEEK_SET0Principio del fichero

    MACROVALORORIGEN

  • Marta Zorrilla Universidad de Cantabria

    177

    Ejemplo: Se crea un archivo llamado FRASE.TXT con una cadena de caracteres. Posteriormente lee un carcter de la cadena cuya posicin se teclea.

    #include #include

    void main (void){

    FILE *f;int nbyte, st;char frase[80], caracter;if (!(f = fopen ("FRASE.TXT", "w+t"))) {

    perror ("FRASE.TXT");return;

    }

    printf ("Teclee frase: ");gets (frase);fwrite (frase, strlen (frase) + 1, 1, f);printf ("\nLeer carcter n: ");scanf ("%d", &nbyte);st = fseek (f, nbyte, SEEK_SET);if (st) puts ("Error de posicionamiento");else {

    caracter = getc (f);if (caracter != EOF) printf ("\nEl carcter es: %c", caracter);else puts ("Se sobrepas el fin de fichero");

    }fclose (f);

    }

  • Marta Zorrilla Universidad de Cantabria

    178

    Ejemplo: programa escribe registros ayudndose de fseek().#include

    typedef struct {char nombre[40];int edad;float altura;

    } REGISTRO;

    void main (void){

    FILE *f1;REGISTRO mireg;int num;long int puntero;if (!(f1 = fopen ("REGISTRO.DAT", "r+b"))) {

    puts ("Error de apertura");return;

    }printf ("Escribir registro n: ");scanf ("%d", &num);

  • Marta Zorrilla Universidad de Cantabria

    179

    Ejemplo: programa escribe registros ayudndose de fseek(). (y2)

    while (num > 0) {getchar ();printf ("Nombre: ");gets (mireg.nombre);printf ("Edad: ");scanf ("%d", &mireg.edad);printf ("Altura: ");scanf ("%f", &mireg.altura);puntero = (num - 1) * sizeof (REGISTRO);if (fseek (f1, puntero, SEEK_SET)) puts ("Error de posicionamiento");else {

    fwrite (&mireg, sizeof (mireg), 1, f1);if (ferror (f1)) {

    puts ("ERROR de escritura");getch ();

    }}printf ("Escribir registro n: ");scanf ("%d", &num);

    }fclose (f1);

    }

  • 180

    Programacin modular

    Tema 13

  • Marta Zorrilla Universidad de Cantabria

    181

    Tema 13

    Objetivos: Explicar el mbito de las variables del programa. Familiarizar al alumno con la creacin de programas

    modularizados y la creacin de libreras de funciones propias.

    Contenidos:1. Variables globales y locales 2. Variables estticas 3. El preprocesador C: #include y #define.4. Programas modulares5. Bibliotecas de funciones

  • Marta Zorrilla Universidad de Cantabria

    182

    mbito de las variables y tipos de almacenamiento Existen dos formas de caracterizar una variable:

    Por su tipo de dato Por su tipo de almacenamiento

    El tipo de dato se refiere al tipo de informacin que representa la variable (int, char, . . . ).

    El tipo de almacenamiento se refiere a su permanencia y a su mbito. El mbito de una variable es la porcin del programa en la cual se reconoce la variable.

    Segn el mbito, las variables pueden ser: Variables locales. Variables globales.

    Segn el tipo, las variables pueden ser: Variables automticas. Variables estticas. Variables externas. Variables de tipo registro.

  • Marta Zorrilla Universidad de Cantabria

    183

    Variables globales Se declaran fuera de las funciones y antes de su uso. Pueden ser accedidas desde cualquier funcin.

    #include void funcion1(void);

    int a = 1000; /* variable global */main(){

    int b = 2; /* variable local */funcion1();printf("a = %d, b = %d \n", a, b);

    }void funcion1(void){

    int c = 4; /* variable local */printf("a = %d, c = %d \n", a, c);return;

    }

  • Marta Zorrilla Universidad de Cantabria

    184

    Variables globales (y 2) Mantienen los valores que se les asignan en las funciones. Es mejor hacer uso de variables locales para evitar efectos secundarios

    o laterales.

    #include void funcion1(void);int a=10; /* variable global */main(){

    printf("Antes a = %d\n", a);funcion1();printf("Despues a = %d\n", a);

    }void funcion1(void){

    a = 1000;return;

    }

  • Marta Zorrilla Universidad de Cantabria

    185

    Variables locales

    Las variables locales que se definen en las funciones. Su mbito es local. Su vida se restringe al tiempo en el que esta activa la funcin. Los parmetros formales se tratan como variables automticas. Se pueden especificar con la palabra reservada auto aunque no

    es necesario.

    #include main(){auto int valor; /* equivalente a int valor */valor = 5;printf("El valor es %d\n", valor);}

  • Marta Zorrilla Universidad de Cantabria

    186

    Variables estticas Su mbito es local a la funcin. Su vida coincide con la del programa retienen sus valores durante toda la vida del

    programa. Se especifican con static.

    #include void funcion(void);

    main(){

    funcion();funcion();funcion();

    }

    void funcion(void){

    static int veces = 0;veces = veces + 1;printf("Se ha llamado %d veces a funcion\n", veces);

    }

  • Marta Zorrilla Universidad de Cantabria

    187

    Variables de tipo registro

    Informan al compilador que el programador desea que la variable se almacene en un lugar de rpido acceso, generalmente en registros.

    Si no existen registros disponibles se almacenar en memoria. Se especifican con register

    #include main(){register int j;for (j = 0; j < 10; j++)printf("Contador = %d\n", j);}

  • Marta Zorrilla Universidad de Cantabria

    188

    Variables de tipo externas

    Variables globales. Hay que distinguir entre definicin y declaracin de variable

    externa. La definicin se escribe de la misma forma que las variables

    normales y reserva espacio para la misma en memoria. Una declaracin no reserva espacio de almacenamiento se

    especifica con extern. Se emplean cuando un programa consta de varios mdulos. En uno

    de ellos se define la variable. En los dems se declara (extern)

  • Marta Zorrilla Universidad de Cantabria

    189

    Ejemplo Modulo principal (main.c)

    #include extern int valor; /* se declara */void funcion(void);main(){funcion();printf("Valor = %d\n", valor);}

    Modulo auxiliar (aux.c)

    int valor; /* se define la variable */void funcion(void){valor = 10;}

    - Se compila por separado:gcc -c -Wall

    main.cgcc -c -Wall

    aux.c- Se obtienen dos mdulos objetos: main.o y aux.o.- El ejecutable (prog) se genera:

    gcc main.o aux.o -o prog

  • Marta Zorrilla Universidad de Cantabria

    190

    Recomendaciones

    Evitar el uso de variables globales. Mantener las variables lo ms locales que se

    pueda. Cuando se precise hacer accesible el valor de una

    variable a una funcin, se pasar como argumento.

  • Marta Zorrilla Universidad de Cantabria

    191

    Macros

    Una macro es un identificador equivalente a una expresin, sentencia o grupo de sentencias.

    #include #define maximo(a,b) ((a > b) ? a : b)main(){

    int x, y;int max;printf("Introduzca dos numeros: ");scanf("%d %d", &x, &y);max = maximo(x,y); /* uso de la macro */printf("El maximo es %d\n", max);

    }

  • Marta Zorrilla Universidad de Cantabria

    192

    Macros (y 2)

    No puede haber blancos entre el identificador y el parntesis izquierdo.

    Una macro no es una llamada a funcin.

    El preprocesador sustituye todas las referencias a la macro que aparezcan dentro de un programa antes de realizar la compilacin: No se produce llamada a funcin mayor velocidad. Se repite el cdigo en cada uso de la macro mayor cdigo

    objeto.

  • Marta Zorrilla Universidad de Cantabria

    193

    Directiva #include

    Indica al preprocesador que incluya un archivo fuente nom_fich. El formato es:

    #include "nom_fich" o bien,

    #include

    El uso de comillas dobles " " o ngulos < > indica dnde debe buscar el preprocesador el fichero nom_fich. comillas dobles " " : en el directorio de trabajo o en el camino

    absoluto que se especifique en la sentencia include ngulos < >: en los directorios donde se encuentran las bibliotecas

    que proporciona el compilador

  • Marta Zorrilla Universidad de Cantabria

    194

    Archivos de cabecera (.h)

    Permiten modularizar el cdigo y favorecer la ocultacin de informacin.

    Puede contener: Definiciones de macros #define MIL 1000 Declaraciones de variables extern int dia; Declaraciones de funciones extern void f(void); Otras directivas de inclusin #include a.h Comentarios Definiciones de tipos de dato (typedef)

    Nunca debe tener: Definiciones de variables int dia; Definiciones de funciones void f(void);

  • Marta Zorrilla Universidad de Cantabria

    195

    Compilacin prog. varios mdulos

    leyOhm.h prog_ppal.c

    leyOhm.h

    prog_ppal.cleyOhm.c

    leyOhm.oprog_ppal.o

    prog_ppal.exe

    compiladorInclusin del archivo leyOhm.c

    preprocesador

    enlazador

  • Marta Zorrilla Universidad de Cantabria

    196

    La biblioteca de funciones

    Contiene parmetros para rutinas de coma flotanteFLOAT.HANSI.C

    Declara constantes simblicas utilizadas en conexiones con la biblioteca de rutinas open()

    FCNTL.H

    Declara mnemnicos constantes para cdigos de errorERRNO.HANSI C

    Declara constantes y da las declaraciones necesarias para llamadas especficas del 8086 y del DOS

    DOS.H

    Contiene definiciones para trabajar con directorios.DIR.H

    Contiene informacin utilizada por las macros de conversin y clasificacin de caracteres

    CTYPE.HANSI C

    Define varias funciones utilizadas en las llamadas a rutinas de E/S por consola en DOS

    CONIO.HC++

    Define las funciones matemticas complejasCOMPLEX.HC++

    Define funciones utilizadas en rutinas de ROM-BIOSBIOS.H

    Define la clase bcdBCD.HC++

    Declara la macro de depuracin assertASSERT.HANSI C

    Define funciones de asignacin dinmica de memoriaALLOC.H

    DESCRIPCINARCHIVODE CABECERA

    LENGUAJE

  • Marta Zorrilla Universidad de Cantabria

    197

    La biblioteca de funciones

    Declara constantes y declaraciones para utilizarlos en funciones signal() y raise()

    SIGNAL.HANSI C

    Parmetros utilizados en funciones que utilizan arhivos-compartidosSHARE.H

    Declaraciones para dar soporte a saltos no localesSETJMP.HANSI C

    Contiene estructuras y declaraciones para las funciones spawn(), exec()PROCESS.H

    Define las funciones de gestin de memoriaMEM.H

    Define prototipos para las funciones matemticasMATH.HANSI C

    Define funciones sobre el pas e idiomaLOCALE.HANSI C

    Parmetros y constantes sobre la capacidad del sistemaLIMITS.HANSI C

    Define rutinas bsicas de flujo de E/S de C++ (v2.0)IOSTREAM.HC++

    Define los gestores de flujos de E/S de C++ y contiene macros para creacin de gestores de parmetros

    IOMANIP.HC++

    Declaraciones de rutinas de E/S tipo UNIXIO.H

    Define prototipos para las funciones grficasGRAPHICS.HC++

    Contiene macros para declaraciones de clase genricasGENERIC.HC++

    Define los flujos de C++ que soportan E/S de archivosFSTREAM.HC++

    DESCRIPCINARCHIVODE CABECERA

    LENGUAJE

  • Marta Zorrilla Universidad de Cantabria

    198

    La biblioteca de funcionesDESCRIPCINARCHIVO

    DE CABECERALENGUAJE

    Declara constantes dependientes de la mquinaVALUES.H

    Estructuras y prototipos para funciones de tiempoTIME.HANSI C

    Define el tipo time_tSYS\TYPES.HC++

    Define la funcin ftime() y la estructura timebSYS\TIMEB.H

    Declara constantes simblicas utilizadas para abrir y crear archivosSYS\STAT.H

    Define varias rutinas de manipulacin de cadenas y de memoriaSTRING.HANSI C

    Define las clases de flujo de C++ para utilizarlas con arrays de bytes en memoria

    STREAM.HC++

    Define algunas de las rutinas comnmente utilizadasSTDLIB.HANSI C

    Declara las clases de flujo para utilizar con estructuras del archivo stdio.hSTDIOSTR.HC++

    Declara tipos y macros para E/S estndarSTDIO.HANSI C

    Declara varios tipos de datos y macros de uso comnSTDDEF.HANSI C

    Soporte para aceptar un nmero variable de argumentosSTDARG.HANSI C

  • 199

    Punteros y arrays

    Tema 14

  • Marta Zorrilla Universidad de Cantabria

    200

    Punteros y arrays Objetivos:

    Introducir el concepto de puntero. Introducir el concepto de tipo de dato estructurado. Mostrar la representacin de datos mediante arrays unidimensionales y

    multidimensionale