Fundamentos de Informática 1 2 INTRODUCCIÓN A LA PROGRAMACIÓN IMPERATIVA Programación en lenguaje C Capítulo 3: INSTRUCCIÓN DE ASIGNACIÓN Y COMPOSICIÓN SECUENCIAL { Variables: { { { { Declaraciones Tipos de datos Modificadores de tipos de datos Constantes La Sentencia de Asignación Expresiones aritméticas Conversiones de tipos de datos 3 { Funciones estándar de E/S: scanf y printf { Expresiones de condición Expresiones relacionales Expresiones lógicas Precedencia de operadores ESTRUCTURAS CONDICIONALES { Especificación de formatos Secuencias de escape Estructura if-else 4 FUNCIONES { PUNTEROS VECTORES { Ámbito de variables: variables locales y globales Cadenas de caracteres MATRICES FICHEROS ESTRUCTURAS ESTRUCTURAS ITERATIVAS { { { bucle while bucle do … while bucle for Dpto. de ATC, Universidad de Sevilla - Página 1 de 18 Fundamentos de Informática 5 6 El ordenador sólo reconoce el lenguaje máquina (lenguaje ensamblador). Las programadores tienen dificultades para trabajar con este lenguaje. Solución: lenguajes de programación de alto nivel (por ejemplo el lenguaje C). { { Código ensamblador Código lenguaje C MOV R3, [R4] ; R3 Å variable2 variable3 = variable2 + 5; ADD R3, 5 ; R3 Å variable2 + 5 MOV [R5], R3 ; variable3 Å R3 Pueden sustituir varias instrucciones en lenguaje máquina por una sola instrucción de un lenguaje más cercano al lenguaje matemático Æ Más fácil desarrollo/mantenimiento software. No es necesario conocer el hardware del ordenador Æ Portabilidad software. Es necesario un proceso de traducción de lenguaje en alto nivel a lenguaje máquina (lenguaje ensamblador) Æ Traducción Dos posibilidades de traducción: compilar o interpretar un programa escrito en un lenguaje de alto nivel. 7 { { { Compilar: mediante un programa llamado compilador se genera un fichero ejecutable (.exe) a partir de un fichero con código fuente escrito en un lenguaje de alto nivel (.c). Interpretar: mediante un programa llamado intérprete se traduce sentencia a sentencia (instrucción a instrucción) y a continuación se ejecuta el código de la sentencia traducida. Ventajas/desventajas: la compilación permite la ejecución de programas más rápida y da la posibilidad de optimizar código. La traducción ahorra compilación, necesita menos tamaño (no hay .exe) y facilita la portabilidad. 8 1. 2. 3. 4. El proceso de compilación y ejecución tiene varios pasos: Escribir código fuente a partir algoritmo Æ archivo .c “Compilar” el código fuente Æ archivo código objeto .obj “Enlazar” (“link”) el fichero .obj con otros ficheros con código objeto. Necesarios para poder generar un fichero ejecutable Æ archivo .exe Ejecutar el archivo .exe por medio del S.O. Dpto. de ATC, Universidad de Sevilla - Página 2 de 18 PROCESO DE COMPILACIÓN ALGORITMO PROGRAMADOR LENGUAJE DE ALTO NIVEL (.C) COMPILADOR FICHERO OBJETO (.OBJ) OTROS OBJ, LIBRERIAS, S.O. (I/O) “LINKADOR” FICHERO EJECUTABLE (.EXE) EJECUCIÓN (S.O.) HARDWARE Fundamentos de Informática 9 10 ESTRUCTURA DE UN PROGRAMA EN C: la función main Todos los programas en C tienen una función main o principal. Su formato ó sintaxis: main () { // Esto es un comentario y no se trata como sentencia /* Esto también es un comentario y no se traduce a código máquina */ lista_de_sentencias/instrucciones; } Los paréntesis () denotan que es una función. Todo en C se divide en funciones. 11 12 Las llaves { y } denotan inicio y fin de programa respectivamente. La lista de sentencias en la función main puede incluir la declaración de numerosos tipos de datos (por ej. vectores), estructuras selectivas, estructuras iterativas (por ej. bucles), ... e incluso llamadas a otras funciones. Comentarios: sirven para hacer anotaciones en el código fuente para facilitar su comprensión a otros programadores. Dos tipos: // (comentan una línea) y /* */ (comentan varias líneas). Datos que pueden variar a lo largo de la ejecución del programa. Hay diversos tipos de variables en C: enteras, caracteres, flotantes, booleanas, vectores, ... Son necesarias declararlas al principio (después de main () { ...). Esto tiene el objetivo de indicar al compilador que reserve un espacio determinado en memoria. La longitud en bytes de este espacio será función del tipo de variable. Formato ó sintaxis: { Especificador_de_tipo Lista_de_nombres ; Especificador_de_tipo: indica el tipo de dato que se almacena en la variable (entero, flotante, carácter ASCII, ...). Lista_de_nombres: uno o más nombres de variables separados por comas. Nombres de variables: pueden contener el carácter guión bajo (_), dígitos numéricos y letras del código ASCII estándar (no pueden contener eñes ni caracteres con tildes). No pueden comenzar por un dígito numérico. Se diferencian mayúsculas y minúsculas. Ejemplos: Nombre correctos: importe3, hora_comienzo, dia, Dia, DIA Nombres incorrectos: día, 3importe, año { Dpto. de ATC, Universidad de Sevilla - Página 3 de 18 Fundamentos de Informática 13 Tipos de variables simples: RANGO Número entero con signo de 8 bits (carácter ASCII). Rango entre -128 y 127. int Número entero con signo de 32 bits. Rango entre -231 y 231 -1 float Números reales de simple precisión (32 bits) double Números reales de doble precisión (64 bits) Modificadores de tipos de variables: TIPO unsigned char unsigned int short int long int long double TIPO char Ejemplos: 14 Datos que permanecen invariables a lo largo de la ejecución de un programa. Formato o sintaxis: { #define IDENTIFICADOR_CTE VALOR_CTE #define DIAS_DE_LA_SEMANA 7 RANGO Número entero entre 0 y 255 (8 bits). Número entero entre 0 y 232 -1 (32 bits). Número entero entre -215 y 215 -1 (16 bits). Número entero entre -231 y 231 -1 (32 bits). Número real de precisión extendida (80 bits). #define PTS_POR_EURO 166.386 #define SALUDO char letra_dni; unsigned int dni; float nota_media, importeCompras; “¡Hola, amigo!” Se definen al principio del programa, antes de la función main(). No se dice explícitamente de qué tipo es la constante ya que el compilador lo reconoce por el aspecto de valor_cte. 15 16 Ejemplo Forma básica de almacenar un dato en una variable. Todas las sentencias de asignación acaban con el carácter (;) Formato ó sintaxis: { Nombre_de_variable = expresión ; nombre_de_variable: Nombre de variable declarada previamente en alguna sentencia de declaración. operador de asignación (=): Indica que el valor calculado en la expresión debe ser almacenado en Nombre_de_variable. expresión: Indica cómo se calcula el valor a almacenar. El operador de asignación se puede utilizar también en la inicialización de variables: float dolares, euros = 0.0 ; ... euros = pesetas /166.386 ; dolares = 5.0 + euros ; Declaración con inicialización. No es una sentencia de asignación propiamente dicha. #define PI 3.14 Declaración sin inicialización. main() { double radio = 3e6; double perimetro; radio = perimetro; perimetro = 2 * PI * radio; 30 = radio; PI = perimetro; area = PI * radio * radio ; } ERROR: El valor de la variable perimetro no está definido. Asignamos a la variable perimetro el valor de la expresión 2 ⋅ PI ⋅ radio ERROR: se está intentando asignar un valor a una constante. ERROR: la variable area no está declarada. Dpto. de ATC, Universidad de Sevilla - Página 4 de 18 Fundamentos de Informática 17 18 Ejemplos Constante #define PI 3.14 double radio = 3e6; double perimetro; Supongamos las siguientes declaraciones Resultado de la expresión EXPRESIÓN ARITMÉTICA El resultado de la expresión es el valor de la constante Nombre_de_Variable función(lista_parámetros) El resultado de la expresión es el valor de la variable Expresión1 + Expresión2 Suma Expresión1 y Expresión2, que son, a su vez, expresiones más pequeñas Expresión1 – Expresión2 Resta Expresión2 a Expresión1 Expresión1 * Expresión2 Multiplica Expresión1 por Expresión2 Expresión1 / Expresión2 Divide Expresión1 entre Expresión2 - Expresión Constante 3.32 PI ‘A’ perimetro area radio sqrt(34) sqrt(area+1) pow(sqrt(3),5) Expresión1 + Expresión2 area+perimetro 3+radio+34 ‘A’+3 Expresión1 – Expresión2 perimetro-PI ‘A’-’a’+3 3+4-5.6-3 Expresión1 * Expresión2 2*PI*radio PI*radio*radio Expresión1 / Expresión2 perimetro/PI 3/2 -2 -PI Nombre_de_Variable función(lista_parámetros) El resultado es la Expresión cambiada de signo (operador unario) Expresión1 % Expresión2 EJEMPLOS EXPRESIÓN ARITMÉTICA El resultado de la expresión es el valor devuelto por la función Operador módulo: Devuelve el resto de la división entera Expresión1 entre Expresión2 PI*(radio+2) resultado: 1 3.0/2.0 resultado: 1.5 variable -- Post-Decremento: Devuelve el valor de la variable; después resta 1 al valor de la variable -- variable Pre-Decremento: Resta 1 al valor de la variable; luego devuelve su valor (ya decrementado). 7.0%5 ERROR variable ++ Post-Incremento: Devuelve el valor de la variable; después suma 1 al valor de la variable. variable -- radio-- (area+3)-- ERROR PI-- ERROR ++ variable Pre-Incremento: Suma 1 al valor de la variable; luego devuelve su valor (ya incrementado). -- variable --perimetro --(2*area) ERROR --3 ERROR variable ++ area++ sqrt(34)++ ERROR PI++ ERROR ++ variable ++area ++(3/radio) ERROR ++3 ERROR - Expresión Expresión1 % Expresión2 3%2 resultado: 1 7%4 -sqrt(radio) resultado: 3 19 Precedencia y orden de evaluación (1) La precedencia de los operadores nos indica en el orden en que se realizan las operaciones en una expresión compleja (con varios operadores de distinto tipo). La precedencia de los operadores aritméticos es la siguiente: Más alta Más baja ++ -- (unario) * / % + - Las operaciones con mayor precedencia se realizan antes 20 Precedencia y orden de evaluación (2) Ejemplos -x + 2 * z + n + y / x - 7 Ejemplo 1 Expresión equivalente Las operaciones marcadas se realizan antes que las sumas y restas (-x) + (2*z) + n + (y/x) - 7 -x + 2 * ( z + n + y ) / x - 7 Ejemplo 2 Se calcula la suma Cuando en una expresión aparecen varios operadores con el mismo tipo, se evalúan de izquierda a derecha Se pueden utilizar paréntesis para cambiar el orden de precedencia de las expresiones Se calcula el producto Expresión equivalente Se calcula la división Dpto. de ATC, Universidad de Sevilla - Página 5 de 18 (-x) + ((2*( z + n + y ))/x) - 7 Fundamentos de Informática 21 22 Conversiones de tipos de datos (2) Conversiones de tipos de datos (1) Ejemplo con conversiones Reglas de conversión en las expresiones aritméticas: result = 3 / 2; 1. Promoción a entero: todos los operandos de tipo char o short se convierten a int. Los unsigned char o unsigned short se convierten a unsigned int. 2. Cuando un operador opera sobre dos operandos del mismo tipo, el resultado es un valor de dicho tipo. 3. Cuando un operador opera sobre dos tipos diferentes, el tipo de menor rango se convierte al de mayor rango. + rango long double double Ejemplos sin conversiones: float int x; unsigned long double y; long int + int Æ resultado int 3 + 5 unsigned int x * 3 int * int Æ resultado int - rango int y + 3.5 double + double Æ resultado double 3 / 2 int / int Æ resultado 1, int 3.0 / 2.0 double / double Æ resultado 1.5, double int: 1 main() { char c; int i; float f; double d; float result; result result result result = = = = 3 / 3 / 3.0 c / float: 1.0 result = 3 / 2.0; float: 3.0 float: 1.5 result = 3.0 + 3/2; 2; 2.0; + 3/2; i + f * d – (f + i); } int: 1 float: 1.0 float: 4.0 23 24 Conversiones de tipos de datos (3) Conversiones de tipos de datos (4) Ejemplo con conversiones Sentencia de asignación main() { char c; int i; float f; double d; double result; ... result = c / i + f * d – (f + i); } int double int Todos los valores que se asignan a una variable se convierten al tipo de dicha variable. Ejemplo: main() { char c; int i; double d = 3.56; i = 3 / 2.0; i = d + 4; c = i; float double double float En las conversiones a entero no se redondea El resultado de la expresión es de tipo float y se convierte a int: 1.5 Æ 1 El resultado de la expresión es de tipo double y se convierte a int: 3.56 Æ 3 } double El resultado de la expresión es de tipo int y se convierte a char double double Dpto. de ATC, Universidad de Sevilla - Página 6 de 18 Fundamentos de Informática 25 26 printf Los compiladores de C incluyen una serie de funciones estándar que facilitan ciertas tareas. Estas funciones se agrupan en librerías. La librería de entrada/salida estándar de C se llama stdio Formato o sintáxis: printf ( texto_de_formato, lista_argumentos ); { Para utilizarla hay que escribir la siguiente sentencia antes de la función main: texto_de_formato: #include <stdio.h> { { Estudiaremos dos funciones para la entrada/salida (incluidas en la librería stdio). { printf : imprime mensajes por pantalla { scanf : lee datos simples por teclado tales como números o caracteres. lista_argumentos: { Cadena de caracteres que contiene el texto que se va a escribir en pantalla Puede contener secuencias de escape y/o especificaciones de formato Variables o expresiones, separadas por comas, que contienen los datos que se van a escribir en pantalla Debe existir un argumento por cada especificación de formato Las especificaciones de formato se utilizan para insertar en el texto el valor de las expresiones o variables que aparecen en la lista de argumentos 27 28 Especificación de formatos y secuencias de escape: Especificación de formato: CÓDIGO FORMATO printf Secuencias de escape: CÓDIGO SIGNIFICADO %d int \a Carácter de alarma %u unsigned int \b Retroceso %x unsigned int Se escribe en pantalla en formato hexadecimal \f Avance de hoja \n Nueva línea %f float \t Tabulador horizontal \v Tabulador vertical %lf double \r Retorno de carro %c Carácter ASCII (char) \” Dobles comillas %s Cadena de caracteres \’ Comillas simples \\ Barra invertida \? Signo de interrogación \xhh int x, y; x = 32; y = 100; printf ( “La variable x vale %d”, x ) ; La variable x vale 32 La variable x vale 32mm La variable y vale 34 printf ( “mm\nLa variable y vale %d\n”, x+2 ) ; printf ( “(x,y) = (%d,%d)\n”, x, y ) ; printf ( “x=%d y+x = %d+%d = %d\n”, x, y, x, x+y ) ; Código ASCII en hexadecimal Dpto. de ATC, Universidad de Sevilla - Página 7 de 18 La variable x vale 32mm La variable y vale 34 (x,y) = (32,100) La variable x vale 32mm La variable y vale 34 (x,y) = (32,100) x=32 y+x = 100+32 = 132 Fundamentos de Informática 29 30 scanf Formato o sintáxis: & scanf ( texto_de_formato, &variable, &variable, ... ); { texto_de_formato: { Usadas en las condiciones de las estructuras selectivas e iterativas. Se modelan como variables y/o expresiones del álgebra de Boole Æ una expresión de condición es cierta ó falsa. Cadena de caracteres que contiene información sobre el tipo de dato que se va a leer del teclado Recomendamos utilizar solamente especificaciones de formato Expresión RELACIONAL variable: Ejemplo: Operando1 > Operando2 Variable en la que se guardará el valor leído Cada variable debe ir precedida del carácter & Resultado de la expresión Es verdadero si Operando1 ES MAYOR QUE Operando2 Operando1 >= Operando2 Es verdadero si Operando1 ES MAYOR O IGUAL QUE Operando2 Operando1 < Operando2 Es verdadero si Operando1 ES MENOR QUE Operando2 (Existen excepciones a esta regla, por ejemplo para variables tipo puntero o cadena de caracteres. Se estudiarán dichas excepciones en los temas correspondientes) Operando1 <= Operando2 Es verdadero si Operando1 ES MENOR O IGUAL QUE Operando2 Deben aparecer tantas variables como especificaciones de formato Operando1 == Operando2 Es verdadero si Operando1 ES IGUAL QUE Operando2 Operando1 != Operando2 Es verdadero si Operando1 ES DISTINTO QUE Operando2 int peso; scanf ( “%d”, &peso) ; 31 32 Operador Expresión LÓGICA Resultado de la expresión Operando1 && Operando2 Es verdadero si Operando1 es verdadero Y Operando2 es verdadero Operando1 || Operando2 Es verdadero si Operando1 es verdadero O Operando2 es verdadero ! Operando1 Precedencia de los operadores: ++ -(operador ~ * Es verdadero si Operando1 NO es verdadero < Alta unario de signo) ! / % + - <= > == != >= && (Los paréntesis alteran el orden evaluación) || = Dpto. de ATC, Universidad de Sevilla - Página 8 de 18 Prioridad -- += -= Baja Fundamentos de Informática 33 34 if-else if-else Esta estructura permite elegir entre dos posibles grupos de sentencias en función de una condición Es equivalente a la estructura selectiva doble del pseudocódigo Pseudocódigo El grupo de sentencias del else es opcional: if (condición) { grupo_sentencias1 } Código C SI condición ENTONCES grupo sentencias1 SINO grupo sentencias2 FINSI if (condición) { grupo_sentencias1 }else { grupo_sentencias2 } Las llaves no son necesarias si el grupo de sentencias esta formado por una sola sentencia: if (condición) sentencia; if (condición) sentencia1; else sentencia2; Funcionamiento: si la condición es verdadera, La condición puede ser: { se ejecuta el grupo de sentencias1 { en otro caso (es decir, si es falsa), Una expresión de condición (expresión lógica) Una expresión aritmética cuyo resultado se interpreta como un valor booleano: se ejecuta el grupo de sentencias2 Distinto de cero Æ VERDADERO Igual a cero Æ FALSO 35 Ejercicio 1: Enunciado 36 Ejercicio 1: Solución en pseudocódigo Escribir en código C el algoritmo correspondiente al ejercicio 2 de las Prácticas de Algorítmica: Construya un algoritmo en pseudocódigo tal que, dados los valores enteros P y Q, que deben leerse del teclado, determine si los mismos satisfacen la siguiente expresión: ALGORITMO Problema2 VARIABLES p, q SON ENTEROS INICIO LEE p P +Q − P < 3 4 2 LEE q SI p*p*p + q*q*q*q – 2*p*p < 680 ENTONCES En caso afirmativo debe escribir por pantalla los valores de P y Q. ESCRIBE “Los valores de P y Q son:” ESCRIBE “P = “, p, “Q = “, q FINSI FIN Dpto. de ATC, Universidad de Sevilla - Página 9 de 18 Fundamentos de Informática 37 38 Ejercicio 1: Solución en código C Ejercicio 2: Enunciado ALGORITMO Problema2 VARIABLES p, q SON ENTEROS INICIO LEE p LEE q SI p*p*p + q*q*q*q – 2*p*p < 680 ENTONCES ESCRIBE “Los valores de P y Q son:” main() { int p, q; ESCRIBE “P = “, p, “Q = “, q FINSI FIN Modificar el programa anterior para que los valores de P y Q se escriban en pantalla en orden creciente; es decir, primero aparece en pantalla la variable con el mayor valor. Además, en el caso de que los valores de P y Q no cumplan la expresión, se debe escribir el siguiente mensaje: “Los valores no satisfacen la expresión” scanf( “%d”, &p ); scanf( “%d”, &q ); if (p*p*p + q*q*q*q – 2*p*p > 680) { printf( “Los valores de P y Q son:\n” ); printf( “p = %d, q = %d\n”, p, q ); } } 39 40 Ejercicio 2: Solución en código C main() { int p, q; Las llaves en el if son obligatorias porque contiene varias sentencias scanf( “%d”, &p ); scanf( “%d”, &q ); if (p*p*p + q*q*q*q – 2*p*p > 680) { printf( “Los valores de P y Q son:\n” ); if (p > q) printf( “p = %d, q = %d\n”, p, q ); else printf( “q = %d, p = %d\n”, q, p ); }else { printf( “Los valores no satisfacen la expresion\n” ); } } Ejercicio 3: Enunciado Las llaves en el else son opcionales porque contiene una sola sentencia Escribir en código C el algoritmo correspondiente al ejercicio 3 de las Prácticas de Algorítmica: Elabore un algoritmo en pseudocódigo que lea del teclado una temperatura en grados Centígrados, calcule los grados Fahrenheit y escriba por pantalla el deporte que es apropiado practicar a esa temperatura, teniendo en cuenta la siguiente tabla: DEPORTE TEMPERATURA en grados Fahrenheit > 85 70 < TEMP <= 85 35 < TEMP <= 70 32 < TEMP <= 35 <= 32 Natación Tenis Golf Esquí Marcha Para convertir grados Centígrados (variable c) a Fahrenheit (variable f) se utiliza la siguiente ecuación: f = c⋅ Dpto. de ATC, Universidad de Sevilla - Página 10 de 18 9 + 32 5 Fundamentos de Informática 41 Ejercicio 3: Solución en pseudocódigo 42 Ejercicio 3: Solución en código C (1) main() { float cent, fah; scanf( “%f”, &cent ); fah = 9.0 / 5 * cent + 32; if (fah > 85) printf( “Natacion” ); else if (fah > 70) printf( “Tenis” ); else if (fah > 35) printf( “Golf” ); else if (fah > 32) printf( “Esqui” ); else printf( “Marcha” ); } ALGORITMO Problema3 VARIABLES cent, fah SON REALES INICIO LEER cent fah ← (9 / 5) * cent + 32 SI fah > 85 ENTONCES ESCRIBE “Natacion” SINO SI fah > 70 ENTONCES ESCRIBE “Tenis” SINO SI fah > 35 ENTONCES ESCRIBE “Golf” SINO SI fah > 32 ENTONCES ESCRIBE “Esqui” SINO ESCRIBE “Marcha” FINSI FINSI FINSI FINSI FIN Escribimos 9.0 para que la división sea con decimales. Puesto que los operadores de división (/) y producto (*) tienen la misma prioridad, se evalúan izquierda a derecha. La expresión anterior es equivalente a: fah = (9.0/5) * cent + 32; 43 Ejercicio 3: Solución en código C (2) main() { float cent, fah; scanf( “%f”, &cent ); fah = 9/5 * cent + 32; if (fah > 85) printf( “Natacion” ); else if (fah > 70) printf( “Tenis” ); else if (fah > 35) printf( “Golf” ); else if (fah > 32) printf( “Esqui” ); else printf( “Marcha” ); } Cada else contiene una única sentencia: la sentencia if En estos casos se puede poner el if en la misma línea que el else para que el código quede más legible. if (condición) { sentencias }else if (condición) { sentencias }else { sentencias } 44 Ejercicio 3: Solución en código C (3) main() { float cent, fah; scanf( “%f”, &cent ); fah = 9/5 * cent + 32; if (fah > 85) printf( “Natacion” ); else if (fah > 70) printf( “Tenis” ); else if (fah > 35) printf( “Golf” ); else if (fah > 32) printf( “Esqui” ); else printf( “Marcha” ); } Dpto. de ATC, Universidad de Sevilla - Página 11 de 18 Fundamentos de Informática 45 46 Permite repetir la ejecución de un grupo de sentencias (es decir, de una o varias sentencias) mientras se cumpla una condición. Es equivalente a la estructura repetitiva MIENTRAS del pseudocódigo. Las estructuras iterativas también se llaman bucles. Pseudocódigo ... sentencia; while (condición) { grupo_de_sentencias } sentencia; ... Código C MIENTRAS condición HACER grupo de sentencias FIN MIENTRAS sentencia; while (condición) { FALSA while (condición) { grupo_de_sentencias } Funcionamiento: Mientras la condición es verdadera, se ejecuta el grupo de sentencias VERDADERA grupo_de_sentencias Flujo de ejecución de las sentencias El grupo de sentencias está formado por las sentencias que se encuentran entre las llaves del bucle while } sentencia; 47 48 Ejercicio 1: Enunciado Si el grupo de sentencias esta formado por una sola sentencia, las llaves no son necesarias: while (condición) sentencia; La condición sigue las mismas reglas que en la sentencia if Cada ejecución de las sentencias de un bucle se llama iteración El bucle while puede iterar de cero a N veces: si la condición nunca es verdadera, el grupo de sentencias del bucle no se ejecuta Escriba en código C el algoritmo correspondiente al ejercicio 4 de las Prácticas de Algorítmica: Escriba un algoritmo que lea del teclado un número entero y que compruebe si es menor que 5. Si no lo es, debe volver a leer un número, repitiendo la operación hasta que el usuario escriba un valor correcto. Finalmente debe escribir por pantalla el valor leído. Dpto. de ATC, Universidad de Sevilla - Página 12 de 18 Fundamentos de Informática 49 50 Ejercicio 1: Solución en pseudocódigo Ejercicio 1: Solución en código C main() { int num; printf( “Teclee un número menor que 5: “ ); scanf( “%d”, &num ); while (num >= 5) { printf( “Teclee un número menor que 5: “ ); scanf( “%d”, &num ); } printf( “El numero leído es %d\n”, num ); } ALGORITMO problema4 VARIABLES num ES ENTERO INICIO ESCRIBE “Teclee un número menor que 5” LEE num Dentro del bucle debe cambiar el valor de alguna de las variables que aparecen en la condición para que pueda llegar a ser falsa alguna vez. MIENTRAS num >= 5 HACER ESCRIBE “Teclee un número menor que 5” Las llaves son obligatorias porque el bucle while contiene más de una sentencia LEE num FIN MIENTRAS En el siguiente ejemplo, si num es mayor o igual que 5, el bucle while se convierte en un bucle sin fin ESCRIBE “El número leído es “, num while (num >= 5) { printf( “Teclee ...: “ ); } FIN 51 52 Ejercicios para hacer en casa Ejemplo 1 (versión 1) El siguiente programa calcula la potencia de un número real elevado a un exponente entero positivo. Los valores de la base y el exponente se leen del teclado. Escriba en código C los algoritmos correspondiente a los ejercicios 5, 6 y 7 de las Prácticas de Algorítmica: main() { float base, potencia; int exponente, contador; scanf( “%d”, &exponente ); scanf( “%f”, &base ); contador = 0; potencia = 1; while (contador < exponente) { potencia = potencia * base; contador++; } } Se asigna un valor inicial a las variables de la condición del bucle. El número de iteraciones es igual al valor del exponente: el bucle se repite para los valores de contador desde 0 hasta exponente-1 Se modifica el valor de alguna de las variables de la condición. El contador se incrementa en cada iteración Dpto. de ATC, Universidad de Sevilla - Página 13 de 18 Fundamentos de Informática 53 54 Ejemplo 1 (versión 2) Ejemplo 1 (versión 3) Esta transparencia muestra otra versión del código anterior. main() { float base, potencia; int exponente, contador; En negrita aparecen los cambios realizados. scanf( “%d”, &exponente ); scanf( “%f”, &base ); contador = 1; potencia = 1; while (contador <= exponente) { potencia = potencia * base; contador++; } } Esta transparencia muestra otra versión del código anterior. main() { float base, potencia; int exponente; En negrita aparecen los cambios realizados. scanf( “%d”, &exponente ); scanf( “%f”, &base ); potencia = 1; while (exponente>0) { potencia = potencia * base; exponente--; } } El número de iteraciones es el mismo que en la versión anterior. El número de iteraciones es el mismo que en la versión anterior. Ahora el bucle se repite para los valores de contador desde 1 hasta exponente Ahora el bucle se repite para los valores de exponente desde su valor inicial hasta 1 El exponente se decrementa en cada iteración. 55 Permite repetir la ejecución de un grupo de sentencias mientras se cumpla una condición. Es parecida, pero no igual, a la estructura repetitiva HASTA del pseudocódigo. do { grupo_de_sentencias }while (condición); El grupo de sentencias está formado por las sentencias que se encuentran entre las llaves del bucle do-while 56 ... sentencia; do { grupo_de_sentencias }while (condición); sentencia; ... do { grupo_de_sentencias }while (condición); El bucle do-while termina con un punto y coma (;) FALSA Flujo de ejecución de las sentencias Funcionamiento: sentencia; Se ejecuta el grupo de sentencias y se repiten mientras la condición es verdadera Dpto. de ATC, Universidad de Sevilla - Página 14 de 18 sentencia; VERDADERA Fundamentos de Informática 57 58 Ejemplo 1: Enunciado Las llaves no son necesarias si el grupo de sentencias esta formado por una sola sentencia: do sentencia; while (condición); La condición sigue las mismas reglas que en la sentencia if El bucle do-while puede iterar de 1 a N veces: aunque la condición nunca sea verdadera, el grupo de sentencias del bucle se ejecuta siempre la primera vez Escriba en código C el algoritmo correspondiente al ejercicio 4 de las Prácticas de Algorítmica utilizando un bucle do-while: Escriba un algoritmo que lea del teclado un número entero y que compruebe si es menor que 5. Si no lo es, debe volver a leer un número, repitiendo la operación hasta que el usuario escriba un valor correcto. Finalmente debe escribir por pantalla el valor leído. 59 Ejemplo 1: Solución 60 Equivalencia entre bucles while y do-while Solución con bucle do-while main() { int num; do { printf( “Teclee un número menor que 5: “ ); scanf( “%d”, &num ); }while (num >= 5); printf( “El numero leído es %d\n”, num ); } main() { int num; printf( “Teclee un número menor que 5: “ ); scanf( “%d”, &num ); while (num >= 5) { printf( “Teclee un número menor que 5: “ ); scanf( “%d”, &num ); } printf( “El numero leído es %d\n”, num ); Solución con bucle while do { grupo_de_sentencias }while (condición); grupo_de_sentencias while (condición) { grupo_de_sentencias } } Dpto. de ATC, Universidad de Sevilla - Página 15 de 18 El grupo de sentencias del bucle do-while se duplica en el bucle while: debe aparecer delante y dentro del bucle Fundamentos de Informática 61 Permite repetir la ejecución de un grupo de sentencias mientras se cumpla una condición. Su sintaxis es la siguiente: for (inicialización; condición; grupo_de_sentencias } 62 Flujo de ejecución de las sentencias actualización) { sentencia; for (inicialización; condición; actualización){ FALSA VERDADERA grupo_de_sentencias La inicialización y la actualización son expresiones aritméticas. La condición es una expresión lógica o aritmética que sigue las mismas reglas que en la sentencia if La inicialización, la condición y la actualización son opcionales. { { } El bucle for se ejecuta mientras la condición sea verdadera sentencia; Los caracteres ‘;’ son obligatorios: deben aparecer siempre. 63 64 Ejemplos 1 y 2 Si el grupo de sentencias esta formado por una sola sentencia, las llaves no son necesarias: for (inicialización; sentencia; condición; inicialización actualización) El bucle for puede iterar de cero a N veces: si la condición nunca es verdadera, el grupo de sentencias del bucle no se ejecuta Si un bucle for no tiene condición, se convierte en un bucle sin fin: for (inicialización ;; actualización) { grupo_de_sentencias } Ejemplo 1: bucle for con llaves condición actualización for (i=0; i<N; i++) { printf( “%d\n”, i ); x = x + i; } Ejemplo 2: bucle for sin llaves for ( ; i<N; i++) printf( “%d\n”, i ); x = x + i; Dpto. de ATC, Universidad de Sevilla - Página 16 de 18 Sentencias que forman parte del cuerpo del bucle for Bucle for sin inicialización Sólo una sentencia forma parte del cuerpo del bucle for Fundamentos de Informática 65 66 Equivalencia entre bucles while y for Ejemplo 3 El siguiente programa calcula la potencia de un número real elevado a un exponente entero positivo utilizando un bucle for. Los valores de la base y el exponente se leen del teclado. for (inicialización; condición; actualización) { grupo_de_sentencias } inicialización; while (condición) { grupo_de_sentencias actualización; } main() { float base, potencia; int exponente, contador; scanf( “%d”, &exponente ); scanf( “%f”, &base ); main() { potencia = 1; float base, potencia; for (contador = 0; contador < exponente; contador++) { int exponente, contador; potencia = potencia * base; } scanf( “%d”, &exponente ); Un bucle for sin inicialización ni actualización es igual que un bucle while for (; condición;) { grupo_de_sentencias } Solución con bucle for } Solución con bucle while while (condición) { grupo_de_sentencias } scanf( “%f”, &base ); contador = 0; potencia = 1; while (contador < exponente) { potencia = potencia * base; contador++; } } 67 68 Ejemplo 1: Enunciado Se dice que dos bucles están anidados cuando uno de ellos se encuentra dentro del cuerpo del otro En el siguiente ejemplo se muestran tres bucles anidados: for (i=N; i>0; i--) { ... while (contador*j<k) { ... do { ... }while (!encontrado); ... } ... } Escriba un programa que muestre en pantalla las tablas de multiplicar del 1 al 10 con el siguiente formato: Tabla del 1: 1 x 1 = 1 1 x 2 = 2 ... 1 x 10 = 10 Tabla del 2: 2 x 1 = 2 2 x 2 = 4 ... Dpto. de ATC, Universidad de Sevilla - Página 17 de 18 Fundamentos de Informática 69 70 Ejemplo 1: Solución Ejemplo 2: Enunciado El bucle externo se encarga de iterar desde la tabla del 1 hasta la del 10 main() { int ntabla, i; for ( ntabla=1; ntabla<=10; ntabla++ ) { printf( “Tabla del %d:\n”, ntabla ); for ( i=1; i<=10; i++ ) { printf( “%d x %d = %d\n”, ntabla, i, i*ntabla ); } printf(“\n”); } 0 1 2 3 0 1 El bucle interno se encarga de escribir la tabla del número ntabla } Escriba un programa que muestre por pantalla las coordenadas de los elementos que pertenecen a la matriz triangular inferior de una matriz de orden NxN. Supongamos que las filas y las columnas de la matriz se numeran comenzando por cero; es decir, que los índices de la primera fila y columna son cero. N debe ser definida como una constante. Por ejemplo, para una matriz de orden 4x4 (N=4), el programa mostraría lo siguiente: 2 3 71 Ejemplo 2: Solución #define N 10 main() { int f, c; El bucle externo se encarga de iterar desde la fila 0 hasta la fila N-1 for ( f=0; f<N; f++ ) { for ( c=0; c<=f; c++ ) { printf( “(%d, %d) ”, f, c ); } printf(“\n”); } } El bucle interno se encarga de escribir las coordenadas de los elementos de la fila f Dpto. de ATC, Universidad de Sevilla - Página 18 de 18 (0,0) (1,0) (1,1) (2,0) (2,1) (2,2) (3,0) (3,1) (3,2) (3,3)