Ejercicios Lenguaje C Relación 3a (2010/2011) - cs.us.es - LenguajeC 3... · gets(palabra);...

43
Ejercicios Lenguaje C Relación 3a (2010/2011) Luis Valencia Cabrera [email protected] ( http://www.cs.us.es/~lvalencia) Ciencias de la Computacion e IA ( http://www.cs.us.es/) Universidad de Sevilla

Transcript of Ejercicios Lenguaje C Relación 3a (2010/2011) - cs.us.es - LenguajeC 3... · gets(palabra);...

Ejercicios

Lenguaje C

Relación 3a

(2010/2011)

Luis Valencia Cabrera

[email protected]

(http://www.cs.us.es/~lvalencia)

Ciencias de la Computacion e IA

(http://www.cs.us.es/)

Universidad de Sevilla

Tablas (arrays) en C (I) Declaración de tablas:

Unidimensional: tipo nombre [dim];

Multidimensional: Tipo nombre [dim1][dim2]…[dimn];

Ejemplos: #define TAM 10

#define MAXCAR 80 #define NHORAS 24 #define NFIL 2 #define NCOL 5

int v[TAM]={1,2,3,4,5,6,7,8,9,10}; char palabra[MAXCAR];

double temperaturas[NHORAS]; int m[NFIL][NCOL] = {{1,2,3,4,5},{6,7,8,9,10}};

Tablas (arrays) en C (II) Definición de tipos tabla:

typedef tipo Nombre[dim1][dim2]…[dimn];

Ejemplos: typedef int Vector10[TAM]; typedef char Cadena[MAXCAR]; typedef double Tempe[NHORAS];

typedef int Matriz2x5[NFIL][NCOL];

Vector10 v; Cadena palabra; Tempe temperaturas;

Matriz2x5 m;

Tablas (arrays) en C (III) Acceso a un elemento de una tabla:

variable_tabla[indice]; // indice comienza en 0

Ejemplos:

i = v[5];

palabra[0] = ‘A’;

m[1][4] = 5;

Nota El nombre de una tabla es un «puntero» a la propia tabla, es decir, contiene la dirección de comienzo donde el compilador ubica la tabla (m = m[0] = m[0][0]).

Tablas (arrays) en C (IV) Paso de una tabla como parámetro de entrada:

Prototipo: void funcion1 (const Vector10, int); void funcion1 (const int [TAM], int); void funcion1 (const int [], int);

Llamada: Vector10 v;

int n; funcion1(v,n);

Definición: void funcion1 (const Vector10 vector, int num){ int i; for (i=0; i<num; i++)

printf("%d\n", vector[i]); }

Tablas (arrays) en C (V) Paso de una tabla como parámetro de entrada/salida:

Prototipo: void funcion2 (Vector10, int); void funcion2 (int [TAM], int); void funcion2 (int [], int);

Llamada: Vector10 v;

int n; funcion2(v,n);

Definición: void funcion2 (Vector10 vector, int num){ int i; for (i=0; i<num; i++)

vector[i]++; }

Tablas (arrays) en C (VI) Tabla multidimensional:

Prototipo: void funcion3 (const Matriz2x5, int,int);

void funcion3 (const int [NFIL][NCOL], int);

void funcion3 (const int [][NCOL], int);

Llamada: Matriz2x5 m;

int n, l;

funcion3(m,n,l);

Definición: void funcion3 (const Matriz2x5 matriz, int elem_x, int elem_y){

int i, j;

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

for (j=0; j < elem_y; j++)

printf("%d\n", matriz[i][j]);

}

Ejercicio 4.1: ¿es correcto? #include <stdio.h>

#define TAM 10

typedef int Tabla [TAM];

int main (){

Tabla t1, t2;

int i;

for (i=0; i <= TAM; i++){

t1[i]=2*i;

t2[i]=i*i;

}

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

printf("\n%d %d\n", t1[i],t2[i]);

return 0;

}

Ejercicio 4.2: ¿se comporta

como esperaba? #include <stdio.h> #define TAM 10

typedef int Tabla [TAM]; void muestraTabla (const Tabla); int main (){ Tabla tab; int i, n=7; for (i=0; i <n; i++)

tab[i]=i; muestraTabla(tab); return 0; } void muestraTabla (const Tabla t){ int i;

for (i=0; i < TAM; i++) printf("\nElemento %d: %d", i, t[i]); }

Ejercicio 4.3: Traduzca este

pseudocódigo a lenguaje C Objetivo: ordenar array de menor a mayor

proc ordenacion_intercambio (ent n: entero; entsal v: Tt) var

i: entero

ordenado: logico

Prin ordenado := falso

mientras NO ordenado

ordenado := cierto

desde i:=1 hasta n-1 si v[i]>v[i+1]

<v[i], v[i+1]> := <v[i+1],v[i]>

ordenado := falso

fsi

fdesde

fmientras

fin

Ejercicio 4.4: Lee, almacena,

ordena y muestra

Escriba un programa que lea una lista de

un máximo de 50 números enteros

positivos, los almacene en una tabla, los

ordene de menor a mayor y los imprima

en dicho orden.

Cadenas de Caracteres (I) Como sabemos, C no tiene tipo predefinido

para almacenar cadenas de caracteres.

Se puede hacer mediante el uso de tablas: char nombre [dimensión];

Ejemplos: #define MAXCAR 256 char palabra[MAXCAR];

char palabra[MAXCAR]={‘H’,’o’,’l’,’a’,’\0’};

char palabra[MAXCAR]=«Hola»;

char palabra[]=«Hola»; /* Dimensión por tamaño del valor inicial. Último carácter \0 */

Cadenas de Caracteres (II) Definición del Tipo Cadena:

#define MAXCAR 256 typedef char Cadena[MAXCAR]; Cadena palabra;

Acceso a los elementos: palabra[0]=‘H’;

Lectura: scanf(«%s»,palabra); /* Ojo, sin & ya que la propia

cadena es una dirección. */ gets(palabra);

Escritura: printf(«%s», «Hola»); puts(«Hola»);

Cadenas de Caracteres (III)

Longitud: strlen(s)

Asignación/copia: strcpy(s, ct)

/* Copiar ct en s. */

Comparar: strcmp(cs,ct)

/* Comparar cs con ct. */

Concatenar: strcat

/* Concatenar ct tras cs. */

Todas estas y otras funciones sobre cadenas están definidas en <string.h>

Tablas de cadenas Declaración:

Cadena nombre[dim];

Ejemplos: #define NDIAS 7

#define MAXCAR 256

typedef char Cadena[MAXCAR];

Cadena diasSemana[NDIAS];

Cadena diasSemana[NDIAS]={«lunes»,«martes», «miércoles», «jueves», «viernes», «sábado», «domingo»}

Cadenas en C y punteros Declaración de variables:

Cadena palabra;

char palabra[MAXCAR];

char *palabra;

/* No equivalente al anterior. */

Declaración de prototipos: void funcion (Cadena cadena1, Cadena cadena2);

void funcion (char cadena1[], char cadena2[]);

void funcion (char *cadena1, char *cadena2); /* Válido porque el nombre de una tabla es un

Puntero al comienzo de la tabla de memoria. */

Ejercicio 4.5. ¿Qué falta? #include <stdio.h> #define MAXCAR 256

typedef char Cadena [MAXCAR]; void lee_cadena(Cadena); int main (){ Cadena cad; lee_cadena(?????); printf("Cadena leida: %s", cad); return 0;

} void lee_cadena(?????){ int i = 0; char c; c = getchar(); while (c!='\n' && i<MAXCAR-1){

cadena[i] = c; i++; c = getchar(); } cadena[i]=????????; }

Ejercicio 4.6. Cuenta carac

Escriba una función: int cuenta_caracter (const Cadena cad, char c)

que cuente el número de apariciones de

un carácter c en una cadena cad,

devolviéndolo como resultado.

Estructuras (registros) (I)

Una estructura es un conjunto de datos

(llamados campos) con las siguientes

propiedades:

Pueden ser de distinto tipo (int, char, float,

etc.)

Se denominan por identificadores distintos.

Estructuras (registros) (II) Definición de un registro (estructura):

typedef struct

{

T1 c1;

T2 c2;

Tn cn;

} Tr;

typedef Tr * PTr;

Tr r;

PTr pr;

Tr r = {v1, v2, …, vn};

Estructuras (registros) (III) Ejemplos:

typedef struct { Cadena nombre, apellido1, apellido2; int edad; long dni;

char sexo; } Tpersona; /* Tipo de datos. No reserva memoria! */ Tpersona empleado; Tpersona empleado = {«Alicia», «Gómez», «Cruz», 21, 12345678, ‘m’}; /* Se puede inicializar en la declaración. */

Estructuras (registros) (IV) Acceso a los campos de una estructura:

A través de una variable estructura: Si hemos declarado: Tr r;

Accedemos al campo c1 con: r.c1;

A través de puntero a estructura: Si hemos declarado: Tr *pr;

Accedemos con pr->c1; o (*pr).c1;

Ejemplo: Normal:

printf(«%d»,empleado.edad);

Strcpy(empleado.nombre, «Alicia»);

Puntero:

p->sexo = ‘m’; o bien (*p).sexo = ‘m’;

Tablas de estructuras

Declaración de tipo, y variable del tipo:

typedef Tr Ttabla [dim];

Ttabla nombre;

Ejemplos:

#define N 200

Typedef Tpersona Ttpersona [N];

Ttpersona clase;

Clase del elemento i-ésimo de la clase:

clase[i-1].nombre

Paso de parámetros Entrada:

void escribe_empleado (Tpersona e) {

printf(«%s %s %s\n», e.nombre, e.apellido1, e.apellido2);

printf(«%d %ld %c», e.edad, e.dni, e.sexo);

}

Salida: Typedef Tpersona * Ptpersona;

//En main tendremos empleado, y lo pasamos como &empleado.

void lee_empleado (PTpersona e) {

gets(e->nombre);

gets((*e).apellido1);

gets(e->apellido2);

scanf(«%d%ld%c»,&e->edad, &e->dni, &(*e).sexo);

}

Estructuras anidadas #include <stdio.h> #define MAXCAR 256

typedef char Cadena [MAXCAR]; typedef struct { int dia; int mes; int anyo; } Fecha;

typedef struct { Cadena nombre, apellido1, apellido2; Fecha fechaNacimiento; long dni; char sexo; } Tpersona;

int main (){ Tpersona empleado = {"José", "López", "Pérez", {10,10,1999}, 87654321, 'm'}; printf("\nNacido el %d...", empleado.fechaNacimiento.dia); return 0; }

Ejercicio 4.7. Nºs complejos Utilizando la siguiente estructura para representar

números complejos: typedef struct { double a, b; // Forma dinámica double r, arg; // Forma polar (r: módulo, arg: alfa). } Complejo;

escriba una función que, dado un número complejo en forma binómica, calcule las coordenadas en forma polar: void binomica_a_polar (Pcomplejo pc), siendo:

Ficheros de Texto (I) Un fichero o archivo es un conjunto de datos del

mismo tipo, almacenados en un soporte externo.

En lenguaje C, atendiendo al tipo de datos que almacenan, los ficheros se dividen en:

Ficheros de texto.

Ficheros binarios.

Los ficheros de texto son aquellos en los que la información almacenada son secuencias de caracteres (letras, números, símbolos, etc.) y se utilizan funciones de lectura y escritura que manejan caracteres.

Ficheros de Texto (II) Declaración de ficheros de texto:

typedef FILE * Fichero;

Fichero variable_fichero;

Ejemplos:

typedef FILE * Fichero;

Fichero fcad, fent;

Apertura de ficheros de texto:

Variable_fichero = fopen(nombre_fichero, modo), pudiendo tomar modo los valores:

«r», «w», «r+», «a».

Ficheros de Texto (III) Ejemplo de apertura de ficheros de texto:

typedef FILE * Fichero; Fichero f; f = fopen("datos.txt","r");

f = fopen("datos.txt","w");

f = fopen("datos.txt","r+");

f = fopen("datos.txt","a");

Si la apertura no puede llevarse a cabo devuelve NULL: En modo «r» (leer) si no existe el fichero. En modo «w» (escribir) si disco lleno o protegido contra

escritura.

En modo «r+» (lectura/escritura) si no existe el fichero. En modo «a» (añadir detrás» si disco lleno o protegido contra

escritura.

Cierre de fichero: fclose(f);

Ficheros de Texto (IV)

Detección de fin de fichero:

feof(variable_fichero);

Leer elementos del fichero:

While (!feof(f)){

//tratar elemento

//leer siguiente elemento

}

Ficheros de Texto (V) Lectura y escritura de ficheros de texto:

Caracteres: fgetc, fputc

Cadenas: fgets, fputs

Con formato: fscanf, fprintf

Lectura 1 carácter: c = fgetc(fcar);

Lectura cadena: fgets(s, MAXCAR, fcad);

Lectura entero: fscanf(fent, «%d», &i);

Diferencia entre gets/fgets y puts/fputs: gets lee hasta \n y sustituye por \0

fgets añade \0 detrás del último carácter leído

puts imprime \n tras la cadena, y fputs no lo hace

Ficheros de Texto (VI) Algoritmo de recorrido de fichero de texto:

#include <stdio.h>

typedef FILE * Fichero;

int main {

T r;

Fichero f;

f = fopen(nombre_fichero, "r");

if (f == NULL)

puts("\nError al abrir el fichero");

else {

//leer r de f

while (!feof(f)){

//tratamiento de r

//leer f de r

}

fclose(f)

}

return 0;

}

Ficheros de Texto (VII) #include <stdio.h>

typedef FILE * Fichero;

int main (){

char c;

Fichero f;

f = fopen("Libro1.txt", "r");

if (f == NULL)

puts("\nError al abrir el fichero");

else {

c = fgetc(f);

while (!feof(f)){

putchar(c);

c = fgetc(f);

}

fclose(f);

}

return 0;

}

Ficheros Binarios (I)

Ficheros Binarios:

Son aquellos en los que la información

almacenada está organizada en base a

registros (estructuras), y se utilizan funciones de

lectura y escritura que manejan registros.

Ficheros Binarios (II) Declaración de ficheros binarios:

typedef FILE * Fichero;

Fichero variable_fichero;

Ejemplos:

typedef FILE * Fichero;

Fichero f;

Apertura de ficheros binarios:

Variable_fichero = fopen(nombre_fichero, modo), pudiendo tomar modo los valores:

«rb», «wb», «r+b», «ab».

Ficheros Binarios (III) Ejemplo de apertura de ficheros de texto:

typedef FILE * Fichero; Fichero f; f = fopen("datos.dat","rb");

f = fopen("datos.dat","wb");

f = fopen("datos.dat","r+b");

f = fopen("datos.dat","ab");

Si la apertura no puede llevarse a cabo devuelve NULL: En modo «rb» (leer) si no existe el fichero. En modo «wb» (escribir) si disco lleno o protegido contra

escritura.

En modo «r+b» (lectura/escritura) si no existe el fichero. En modo «ab» (añadir detrás» si disco lleno o protegido contra

escritura.

Cierre de fichero: fclose(f);

Ficheros Binarios (IV)

Detección de fin de fichero:

feof(variable_fichero);

Leer elementos del fichero:

While (!feof(f)){

//tratar elemento

//leer siguiente elemento

}

Ficheros Binarios (V) Lectura y escritura de ficheros de texto:

fread(d, l, n, variable_fichero);

fwrite(d, l n, variable_fichero);

Donde:

d: dirección de la variable donde lee o desde donde se graba

l: longitud en bytes de la información que se lee o graba

n: número de elementos, de longitud l, que se leen o se graban

Ficheros Binarios (VI)

Ejemplos:

int i, n;

Tpersona empleado;

Tpersona tablaemp [N];

Fichero femp;

1 empleado:

fread(&empleado,sizeof(Tpersona),1,temp);

N empleados:

Fread(tablaemp,sizeof(Tpersona),n,femp);

Ficheros Binarios (VII) int main (){

Tpersona empleado, empleadoEscribir={"Jose", "Lopez", "Perez", {10,10,1999}, 87654321, 'm'};

Fichero f;

f = fopen("datos.bin", "wb");

fwrite(&empleadoEscribir,sizeof(Tpersona),1,f);

fclose(f);

f = fopen("datos.bin", "rb");

if (f == NULL)

puts("\nError al abrir el fichero");

else {

fread(&empleado,sizeof(Tpersona),1,f);

while (!feof(f)){

escribe_empleado(empleado);

fread(&empleado,sizeof(Tpersona),1,f);

}

fclose(f);

}

return 0;

}

Ficheros Binarios (VIII) Acceso directo:

fseek(variable_fichero, desp, pos_inicial);

Donde: desp: nueva posición en bytes, desde la

posición inicial, de desplazamiento del fichero. Ojo: puede ser negativo.

pos_inicial: desde qué posición se cuenta el desplazamiento: SEEK_SET: comienzo del fichero

SEEK_CUR: posición actual

SEEK_END: fin del fichero

Ficheros Binarios (IX) Lectura (fichero abierto modo «rb»):

fseek(variable_fichero, (pos-1)*sizeof(Tr),SEEK_SET); fread(dir_variable, sizeof(Tr), 1, variable_fichero);

Escritura (fichero abierto modo «wb»): fseek(variable_fichero, (pos-1)*sizeof(Tr),SEEK_SET); Fwrite(dir_variable, sizeof(Tr), 1, variable_fichero);

Modificación(fichero abierto modo «r+b»): fseek(variable_fichero, (pos-1)*sizeof(Tr),SEEK_SET); fread(dir_variable, sizeof(Tr), 1, variable_fichero); //modificar el dato en dir_variable para luego escribirlo fflush(variable_fichero);

fseek(variable_fichero, (pos-1)*sizeof(Tr),SEEK_SET); fwrite(dir_variable, sizeof(Tr), 1, variable_fichero);

Ficheros Binarios (X) int pos;

Tpersona empleado; Fichero femp; Lectura empleado posición pos (fichero modo «rb»):

fseek(femp, (pos-1)*sizeof(Tpersona),SEEK_SET);

fread(&empleado, sizeof(Tpersona), 1, femp);

Modificación empleado posición pos (fichero modo «r+b»): fseek(femp, (pos-1)* sizeof(Tpersona),SEEK_SET);

fread(&empleado, sizeof(Tpersona), 1, femp);

//modificar el dato en dir_variable para luego escribirlo

fflush(femp);

fseek(femp, (pos-1)* sizeof(Tpersona),SEEK_SET);

fwrite(&empleado, sizeof(Tpersona), 1, femp);