FUNDAMENTOS DE INFORMÁTICA. EXAMEN DE TEORÍA. CONVOCATORIA FEBRERO. CURSO 2003-2004. Apellidos Nombre Ingeniería Turno 1. (0,4p, 0,05p por casilla) Complete la siguiente tabla en la que deberá traducir los números en decimal a unos determinados sistemas de representación numérica: Binario Natural Complemento a 2 (8 bits) Signo magnitud (8 bits) Hexadecimal DNI Nota 5. (0,4p, -0,1p por fallo en casilla) Complete la siguiente tabla para cada una de las tres técnicas de gestión de E/S, indicando en cada caso quien solicita y quien realiza la transferencia de E/S: Número 128(10 1000 0000 Número -127(10 NO Técnica de gestión de E/S: Quien inicia: Quien transfiere: E/S programada CPU CPU NO 1000 0001 Interrupciones NO 1111 1111 DMA Dispositivo Dispositivo CPU Dispositivo 80 NO 6. (0,3p, 0,15p por cuestión) Se tiene un procesador (CPU) con las siguientes características: 8 registros generales, un registro de instrucciones IR de 16 bits, memoria principal de 1KB, y 32 posibles instrucciones diferentes entre las que se incluyen operaciones aritméticas, de acceso a memoria, movimiento de datos. Responda a las siguientes cuestiones: a. Indique el tamaño mínimo del registro PC para direccionar la memoria principal: _Si la memoria tiene 1KB = 210 bytes à como mínimo 10 ______ bits. b. ¿Cuántas instrucciones tendrá como máximo un programa para dicho procesador? 1KB / 16 bits = 512 ___ instrucciones. Nota: si no es posible una determinada representación numérica indíquelo con un NO en la casilla correspondiente. 2. (0,3p) Diferencia, en pocas palabras, entre un lenguaje interpretado y un lenguaje compilado: Véase la teoría 7. (0,4p, 0,2 por cuestión) Aplicando las leyes de Morgan y el álgebra de Boole, simplifique las siguientes expresiones lógicas (incluya los pasos intermedios de la simplificación): S = a +b + a⋅b 3. (0,3p, 0,1p por cuestión completa) Enumere y diga la función de los buses atendiendo a la información que transporta (complete las líneas en blanco con la información pertinente): a. Bus ___de datos____________ : para __transferir b. c. datos entre los diferentes componentes del sistema_. Bus ___de direcciones_______ : para _ acceder a los dispositivos/memoria y dentro de ellos a una posición en concreto_. Bus de control : para _controlar el acceso y uso de las líneas de datos y direcciones_. 4. (0,3p, 0,1 por cuestión correcta) Enumere en orden de ejecución y describa brevemente, cada una de las fases de realización de una instrucción en código máquina: Fase: = (a + b)’= a’.b’ S = a +b + d + c⋅d + a =((a+b+d)’+a’)’= (a+b+d).a = a +a.b+a.d = a+a.d = a 8. (0,3p, 0,15 por cuestión) Convierta a hexadecimal los siguientes números escritos en binario: 1100 00101010 10011110 00010101 01011110 ________ C2A9E155E____________ 1 01111100 00110011 01010110 10110110 ________17C3356B6___________ IF Descripción: Búsqueda de la instruccion ID Decodificacion y búsqueda de operandos Orden Elemento EX Ejecución de la instrucción 3 Memoria RAM MEM Acceso a memoria (opcional) 1 Registro de la CPU 4 Disco duro 2 Memoria caché 9. (0,4p, 0,1p por acierto) Enumere, ordenándolos de mayor a menor velocidad de acceso, los siguientes elementos pertenecientes a la jerarquía de memoria. EXAMEN DE TEO RÍA. FEBRERO 2004. Apellidos Nombre 10. (0,5p, 0,1p por acierto) Dadas las siguientes declaraciones en un determinado programa: unsigned int a, b, c; int si; int uno (unsigned int x, unsigned int y){ ....... } void dos (unsigned int *x, unsigned int y){ ....... } unsigned int tres (unsigned int x){ …. } Señale cuáles de las siguientes sentencias son correctas (C) o incorrectas (I): Sentencia if(uno(a,b))... si=uno(c,5); dos(&a, tres(a)); b=tres(dos(&a,5)); si=uno(dos(a,5)); Correcta/Incorrecta CORRECTA CORRECTA CORRECTA INCORRECTA INCORRECTA 11. (0,3p, 0,1p por acierto) Dado el vector de caracteres: char v[5]={’a’,’b’,’c’,’d’,’e’}; 19: 20: } Nºlinea 1 <stdio.h> 4 flota 8 &horas 10 ); 11 &dias 14 total = horas*dias; 17 %12.5f”, 19 “, neto); Valor: v[’e’-’a’] ‘e’ v[v[3]-’b’] ‘c’ v[’d’-2-’c’] NO 12. (0,4p, 0,05p por acierto) El siguiente programa escrito en C tiene errores. Corríjalos usando para ello el espacio indicado, y escribiendo para cada línea que considere errónea, el número de línea más el texto corregido. 1: #include <studio.h> 2: #define tasa 25.0 3: main(){ 4: flota horas, dias, total, neto; 5: do{ 6: printf(“Introduce las horas 7: trabajadas: “); 8: scanf(“%f”, horas); 9: printf(“Introduce los días 10: trabajados: “) 11: scanf(“%f”, dias); 12: }while((horas<0 || horas>24) 13: || (dias<1 || dias>7)); 14: 15: 16: 17: 18: horas*dias=total; neto=total-tasa; printf(“El valor total a pagar es:%12.5f, total); printf(“El valor neto a pagar Texto corregido 13. (0,3p, 0,05p por acierto) Indica cual es el valor numérico ó lógico (verdadero o falso) de las siguientes expresiones, dado que la variable a ha sido inicializada a 0, b a 10 y c a -6: Expresión Valor Expresión Valor !(a>b) 1 !a 1 ++a 1 a>b&&c<5 0 b>=(a+c) 1 (a==b) 0 14. (0,4p) Escriba la salida que produce el siguiente fragmento de código (todas las variables son enteras): for(i=1;i<4;i++) for(j=1;j<4;j++) if(i%j==0) printf(“%d/%d=%d\n”, i,j,i/j); Complete la siguiente tabla con el valor de las siguientes expresiones (ponga NO si considera que la expresión no se puede evaluar): Expresión: es:%12.5f”, NETO); 1/1=1 2/1=2 2/2=1 3/1=3 3/3=1 15. (0,4p) Escriba la salida que produciría por pantalla la ejecución de este programa: #include <stdio.h> void f1(int a, int *b, int *c){ a++; *b=a*a; *c= a*a*a; } void main(){ int x=2, y=3,z=4; f1(y, &x,&z); printf(“%d\t%d\t%d\n”, x,y,z) ; f1(x, &y,&z); printf(“%d\t%d\t%d\n”, x,y,z) ; } 16 16 3 289 64 4913 EXAMEN DE TEO RÍA. FEBRERO 2004. Apellidos Nombre 16. (0,4p) Escriba una función que dada una palabra de cuatro letras mayúsculas la codifique sustituyendo cada letra por la que la sigue en el alfabeto: la A se transforma en B, la B en C,…y la Z se sustituye por la A: void SiguienteLetra (char palabra[4]) { int i; devuelve el valor de esa suma. Si alguna fila suma un valor distinto a las otras, esta función devuelve -1 int SumarColumnas(int m[3][3]); Esta función debe comprobar si la suma de los elementos de cada columna es la misma. Si las tres columnas suman lo mismo, devuelve el valor de esa suma. Si alguna columna suma un valor distinto a las otras, esta función devuelve -2 int SumarDiagonales (int m[3][3]); for (i=0;i<4;i++) { //si es ‘Z’ if(palabra[i] == ‘Z’) palabra[i] = ‘A’; else palabra[i] = palabra[i]+1; } } Esta función debe comprobar si la suma de los elementos de las dos diagonales es la misma. Si las dos diagonales suman lo mismo, devuelve el valor de esa suma. Si alguna diagonal suma un valor distinto a la otra, esta función devuelve -3 int SumarFilas (int m[3][3]) { int suma[3]; // contiene la suma de cada fila int i,j; // para moverse por la matriz // seguir a partir de aqui... for(i=0;i<3;i++) suma[i]=0; for(j=0;j<3;j++) suma[i]+=m[i][j]; if(suma[0]==suma[1]&& suma[1]==suma[2]) return suma[0]; else return -1; 17. (1,5p, 0,5p por función) Un cuadrado mágico es una matriz cuadrada con un número impar de filas y columnas, cuyas filas y columnas (e incluso sus diagonales) suman el mismo valor. Por ejemplo la matriz siguiente es un cuadrado mágico de 3x3: 6 7 2 1 5 9 8 3 4 Fíjese que los números en cada fila, columna y cada diagonal suman 15. Se pide: complete la función que comprueba si una matriz cuadrada de números naturales, de orden 3, es un cuadrado mágico o no. Para ello, deberá escribir las funciones auxiliares SumarFilas(), SumarColumnas() y SumarDiagonales(). Dichas funciones serán utilizadas por la función EsCuadradoMagico() que se detalla a continuación. int EsCuadradoMagico (int matriz[3][3]) { int SumaF, SumaC, SumaD; } int SumarColumnas(int m[3][3]){ int i,j, suma[3]; for(i=0;i<3;i++) suma[i]=0; for(j=0;j<3;j++) suma[i]+=m[j][i]; if(suma[0]==suma[1]&& suma[1]==suma[2]) return suma[0]; else return -2; } int SumarDiagonal(int m[3][3]){ int i,j, suma[2]; Suma[0]=0; //diagonal principal for(i=0;i<3;i++) for(j=0;j<3;j++) if(i==j) Suma[0]+=m[i][j]; SumaF = SumarFilas(matriz); SumaC = SumarColumnas(matriz); SumaD = SumarDiagonales(matriz); if((SumaF == SumaC) && (SumaF == SumaD)) return 1; else return 0; Suma[1]=0; //diagonal secundaria for(i=0;i<3;i++) for(j=0;j<3;j++) if((i+j)==2) Suma[1]+=m[i][j]; } Prototipos (y descripción) de las funciones a implementar: if(suma[0]==suma[1]) return suma[0]; else return -3; int SumarFilas (int m[3][3]); Esta función debe comprobar si la suma de los elementos de cada fila es la misma. Si las tres filas suman lo mismo, } EXAMEN DE TEO RÍA. FEBRERO 2004. Apellidos Nombre 18. (0,5p) Implementar una función que devolverá un dato de tipo cadena que se corresponderá con la sigla de la cadena que toma como argumento. La sigla estarán formadas por las letras en mayúsculas de todas las palabras, separadas por un punto. Ejemplo, si la frase del argumento es “Tren Articulado Ligero, Goicochea, Oriol”, la cadena que devolverá será: “T.A.L.G.O.”. PISTA: puede usar la función strcat() que sirve para concatenar dos cadenas.Su prototipo es: 20. (0,6p, 0,3p por estructura y 0,3p por la función) Usando la estructura “s_fecha” definida a continuación, defina una estructura para almacenar la información del DNI (nombre, numero de dni y fecha de expiración); e implemente una función que verifique si un DNI cuya información está en el argumento “carnet” está o no caducado. Para ello, se tiene también como argumento la fecha de hoy. La función devuelve 1 si el carné es válido, y 0 si está caducado. void strcat (char *dest, char *fuen); Concatena la cadena fuen al final de la cadena dest. void Siglas (char cadena[80], char sigla[80]) { int i,j; for (i=0;i<strlen(cadena);i++) { // seguir a partir de aquí... struct s_fecha { int dia; int mes; int anyo; }; struct s_dni { char nombre[20]; char apellido1[20]; char apellido2[20]; char numero[9]; struct s_fecha fecha_exped; struct s_fecha fecha_valid; if(cadena[i]>=’A’ && cadena[i]<=’Z’){ siglas[j++] = cadena[i]; siglas[j++] = ‘.’; } } siglas[j] = ‘\0’; }; } 19. (0,4p, 0,1p por cuestión) Exprese, en lenguaje C, las siguientes construcciones iterativas o selectivas (en las que sean iterativas, el cuerpo del bucle se pone con puntos suspensivos): Construcción Equivalente en C Mientras no se haya char cadena[100]; i; //i se mueve a llegado al fin de la cadena int través de las sucesivas hacer … posiciones de la cadena Mientras no sea fin de fichero de fentrada hacer … int DniValido(struct s_dni carnet, struct s_fecha hoy) { int valido =1; if( carnet.fecha_valid.anyo< hoy.anyo || (carnet.fecha_valid.anyo == hoy.anyo && carnet.fecha_valid.mes< hoy.mes) || (carnet.fecha_valid.anyo == hoy.anyo && carnet.fecha_valid.mes== hoy.mes && carnet.fecha_valid.dia< hoy.dia)) valido = 0; return valido; while(cadena[i]!=’\0’){ ... } Ó while(i<strlen(cadena)){ ... } FILE *fentrada; while(!feof(fentrada)){ ... } Si num es impar, positivo y menor que 30 entonces … int num; Hacer … mientras la variable opc sea una letra mayúscula o una letra minúscula. char opc; do{ ... }while( (opc>=’a’ && opc<=’z’) || (opc>=’A’ && opc<=’Z’)); if(num%2!=0&&num>0&&num<30) } EXAMEN DE TEO RÍA. FEBRERO 2004. Apellidos Nombre 22. (0,6p) Dada la siguiente declaración: 21. (0,6p) Hacer un programa que lea un fichero llamado “c:\binario.txt”. Este fichero contiene una sucesión de caracteres “1” y “0” seguidos, formando un gran número binario. El programa deberá calcular la paridad de dicho número, es decir, un valor que será 0 si el número de caracteres “1” leídos es par, y 1 si es impar. El valor calculado, 0 ó 1, se mostrará en pantalla. struct coche { int puertas; char color[15]; char marca[10]; char matricula[10]; int plaza; }; struct coche garage[100]; #include <stdio.h> main() { FILE *f; int paridad=0; //para ir almacenando el número de caracteres ‘1’ que estamos leyendo. char caracter; //para almacenar el carácter que se acaba de leer del fichero. f=fopen (“c:\\binario.txt”, “rt”); if(f != NULL){ fscanf(f, “%c”, &caracter); while(!feof(f)){ if(caracter == ‘1’) paridad++; fscanf(f, “%c”, &caracter); } fclose(f); printf(“La paridad es:%d”, (paridad%2)); } else printf(“ERROR al abrir fichero\n”); } Que representa un garage con 100 plazas, ocupada cada una por un coche cuya descripción se guarda en la estructura dada. (garage es una variable global). Escriba una función que compruebe si un coche con una determinada matrícula está dentro del garage. Devolverá el número de la plaza en caso afirmativo o el valor -1 en caso contrario. El prototipo de la función sería el siguiente: int BuscaPlaza (char matrícula[10]); PISTA: para comparar dos cadenas se puede usar la función strcmp() que tiene el siguiente prototipo: int strcmp (char *c1, char *c2); Devuelve 0 si c1 y c2 son iguales, >0 si c1 es mayor que c2, y <0 si c1 es menor que c2. int BuscaPlaza (char matrícula[10]) { int encontrado = 0; //No encontrado int i;//recorro cada coche del garage for(i=0;(!encontrado&& i<100);i++){ if(strcmp(garage[i].matricula, matricula)==0) encontrado = 1; } if(encontrado) return (garage[i].plaza); else return -1; } }