Download TEMA 1 - Universidad Salesiana de Bolivia
Document related concepts
no text concepts found
Transcript
Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO Tema # 1 LENGUAJES DE PROGRAMACION 1.- Antecedentes. Con la aparición de la MARK I que fue la primera computadora electromecánica surgió la necesidad de crear el software (programas). Con la aparición de las computadoras de la primera generación se introdujo también el lenguaje de máquina basado en el sistema binario; este lenguaje de máquina es muy difícil para el ser humano de usar es por eso que paralelamente a la segunda generación de computadoras apareció el lenguaje ensamblador basado en códigos simbólicos, aún así seguían siendo complicados. Por los años 1950 se desarrollo el primer lenguaje denominado FORTRAN desarrollados por IBM dirigida a aplicaciones científicas y cálculos matemáticos. Mas o menos por las mismas épocas apareció el COBOL (Conmon Bussines Oriented Languaje) para aplicaciones comerciales; el LISP, el ALGOL y otros. Dentro de lo que se llama lenguajes de alto nivel fueron desarrollados una infinidad de lenguajes de programación como: PL/1, BASIC, PROLOG, PASCAL, ... , etc. 2.- Concepto de Lenguaje de Programación. Un lenguaje de programación es una notación conformada por instrucciones que son generalmente palabras en inglés, los cuales además de permitirnos comunicarnos de manera escrita con la computadora nos ayuda a realizar tareas en la computadora. 3.- Que es un procesador de lenguaje. Un procesador de lenguaje convierte a código binario las instrucciones escritas en un lenguaje de programación. El conjunto de instrucciones escritas en el lenguaje de programación se llama código fuente y el conjunto de traducciones binarias ya traducidas que la computadora puede ejecutar es el código objeto. 4. Clasificación de los lenguajes. Los estudiosos en lenguajes de programación clasifican en tres tipos: 4.1. Lenguajes de nivel máquina. Son lenguajes cuyas instrucciones son directamente entendibles por cada computador, utiliza números binarios (0 y 1). Ejemplo: 0010, 10110 Características: No necesitan traducción intermedia Cada computadora tiene su propio lenguaje de máquina específico Resulta muy lento y complicado programar 4.2. Lenguajes de bajo nivel (ensambladores) Las instrucciones se escriben en códigos alfabéticos conocidos como nemotécnicos (abreviaturas de palabras inglesas o españolas). Ejemplo: ADD a, b, c. El programa ensamblador traducirá la instrucción a código de máquina. Universidad Salesiana de Bolivia Page 1 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO 4.3. Lenguajes de alto nivel Las instrucciones utilizan palabras similares a los lenguajes humanos (son palabras en inglés) lo que facilita la escritura y la fácil comprensión para el programador. Ejemplo: c = a+b read (f) write (c) Características: Son parecidos a nuestro lenguaje habitual y facilitan la programación La computadora no entiende directamente, necesitan emplear un traductor Los programas son transportables Los lenguajes de alto nivel se clasifican en dos grupos: Lenguajes procedimentales Se caracterizan porque son imperativos, es decir se escribe estrictamente los pasos a seguir para resolver los problemas. Ejemplo: COBOL, LOGO, PASCAL, etc. Lenguajes declarativos Dicen que hay que hacer, pero no determinan el como y cuando, dan reglas a seguir para la resolución de problemas, el mas difundido es PROLOG que está orientado a la Inteligencia Artificial. 5.- Generación de lenguajes. La generación de los lenguajes de programación se desarrolla paralelamente a la generación de computadoras y a la clasificación de los mismos. Primera Generación.- Los lenguajes de máquina utilizados en computadoras ENIAC. Segunda Generación.- Los lenguajes de bajo nivel o denominados ensambladores. Ejemplo: Asembler, Turbo Asembler. Tercera Generación.- Se encuentran los lenguajes de alto nivel: BASIC, FORTRAN, COBOL, PROLOG. Cuarta Generación.- Son aquellos lenguajes de programación orientado a la gestión administrativa como: INFORMIX 4GL, FOXPRO, C++. Quinta Generación.- Son los lenguajes Orientados a Objetos y a eventos, ejemplos: Visual Basic, Visual Foxpro, Delphi, etc. 6.- Traductores.- Son programas que traducen un programa escrito en lenguaje de alto nivel a código de máquina . Existen dos tipos de traductores: 6.1.- Compiladores Traduce de una vez todo un programa fuente convirtiéndolo en programa objeto listo para su ejecución. Utilizan compiladores el PASCAL, el C, el FOXPRO. Universidad Salesiana de Bolivia Page 2 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO 6.2.- Intérprete Traduce paso a paso, conforme va ejecutando ya a medida que el ordenador lo necesite, ejemplo: el BASIC, GOFHER. 7,. - Concepto de programa.Un programa es una secuencia o lista de actividades a realizar, normalmente se desarrolla un programa cuando encontramos algún problema especifico y queremos resolver. PROBLEMA Ejemplos: 1. PROGRAMA SOLUCION Resolver la siguiente ecuación 4x + 3x –x = 0 Pasos a realizar: Sumar las constantes Despejar la x Obtener el resultado 2. Inscripción a una carrera Pasos a realizar: Averiguar las diferentes Universidades y carreras Tomar en cuenta la disponibilidad económica Tomar en cuenta los horarios Elegir la Universidad, Carrera y turno Presentar los requisitos 8.- Concepto de algoritmo Es un método para resolver un problema mediante una serie de pasos, procedimientos y reglas para resolver un problema. 8.1.- Características de un algoritmo. a) Precisión. Cada paso debe ser precisado claramente b) Determinístico. El resultado siempre debe ser el mismo por más que se hayan hecho varias pruebas. c) Finitud. El algoritmo por más complejo que sea debe terminar en algún momento. 8.2.- Partes de un algoritmo La entrada El Proceso La salida Universidad Salesiana de Bolivia Page 3 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO Tema 2 Construcción de un programa 1.- Diseño de un programa.Para la realización de un programa óptimo el programador en lo posible debe seguir los siguientes pasos: a) Definir el problema Tiene la particularidad de establecer que es lo que se tiene, que es lo que se quiere, cuál es el problema y cual debe ser la solución. b) Análisis de la solución Esto requiere el conocimiento teórico y lógico de procedimientos que nos pueden ayudar a determinar los proceso para resolver el problema, generalmente son de tipo aritmético. c) Formulación del algoritmo Un algoritmo o pseudocódigo es una sucesión de pasos finitos que se supone que la computadora debe seguir paso a paso hasta encontrar la solución del problema, por lo tanto debe ser claro y definido en lo posible de propósito general. d) Representación del algoritmo El algoritmo se puede representar de manera gráfica a través de un diagrama de flujo utilizando símbolos especiales, también se puede representar a través de un seudó cogido. e) Codificación Consiste en transcribir el detalle del diagrama de flujo o seudó código a un determinado lenguaje de programación utilizando instrucciones propias de dicho lenguaje. f) Corrida del prueba Es la ejecución y compilación del programa, y la conversión del programa fuente en programa objeto. g) Verificación y depuración del programa Depurar es encontrar errores en el programa, existen tres tipos de errores: error de compilación, de ejecución y error lógico. h) Documentación Se utiliza para identificar el propósito del programa, poner comentarios, poner anexos. 2.- Elementos de un programa Un programa en Lenguaje C se construye a base de un conjunto de instrucciones (líneas de programa). Las instrucciones están compuestas por diferentes objetos: símbolos especiales, números, constantes, variables, expresiones, identificador, etc. 2.1.- Identificador.- Es una secuencia de caracteres que pueden ser de cualquier longitud, pero sólo los 63 primeros caracteres son significativos. Universidad Salesiana de Bolivia Page 4 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO Un identificador sirve para almacenar en la memoria del computador un dato. En la mayoría de los lenguajes de programación para declarar un identificador se siguen las siguientes reglas: Debe comenzar con una letra (A a Z) mayúscula o minúscula y no puede contener blancos. Están permitidos letras, dígitos y caracteres subrayados ( _ ) después del primer carácter. No se puede utilizar una palabra reservada como identificador. Consejos: No se aconseja utilizar identificadores cortos ni demasiados largos No hay distinción en letras mayúsculas y minúsculas El nombre de identificador debe ser significativo Ejemplos: Datos María 15 años Arce Identificador NOMPER EDAD APELLIDO 3.- Dato.Son hechos que no han sido procesados, es un antecedente que permite llegar más fácilmente al conocimiento de una cosa. 3.1.- Clasificación de los datos. Numéricos Simples Estáticos De carácter De cadena Lógicos Estructurados Dinámicos Alfanuméricos Enteros Reales Vectores Registros Conjuntos Archivos lista cola Pila Arbol 3.2 - Tipos de datos en lenguaje C++ Universidad Salesiana de Bolivia Page 5 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO A toda variable que se use en un programa, se le debe asociar (generalmente al principio del programa) un tipo de dato específico. Un tipo de dato define todo el posible rango de valores que una variable puede tomar al momento de ejecución del programa y a lo largo de toda la vida útil del propio programa. Los tipos de datos más comunes en C++ son: TIPO DATO ESPACIO MEMORIA RANGO unsigned char 8 bits 0 a 255 Char 8 bits -128 a 127 Short int 16 bits -32,768 a 32,767 unsigned int 32 bits 0 a 4,294,967,295 int 32 bits -2,147,483,648 a 2,147,483,647 unsigned long 32 bits 0 a 4,294,967,295 Enum 16 bits -2,147,483,648 a 2,147,483,647 Long 32 bits -2,147,483,648 a 2,147,483,647 float 32 bits 3.4 x 10-38 a 3.4 x 10+38(6 dec) double 64 bits 1.7 x 10-308 a 1.7*10+308(15 dec) Long double 80 bits 3.4 x 10-4932 a 1.1 x 10+4932 Void sin valor Para manejar cadenas de caracteres (strings), se deberá usar un arreglo de caracteres con el siguiente formato. Universidad Salesiana de Bolivia Page 6 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO Char nomstring[cant de elementos]; Ejemplo Char nombre [30]; Char ciudad [20]; Para cargar con un dato se usa el siguiente código; Strcpy (carrera,"ing sistemas"); Variables arreglos de caracteres, tienen que usar sus funciones de manipulación que vienen en la librería string h, algunas de estas funciones son: strcpy(), strcat(), strcmp(), strlen(), etc. 4.- Expresiones y operadores aritmeticos Un operador es un símbolo especial que indica al compilador que debe efectuar una operación matemática o lógica. C++ reconoce los siguientes operadores aritméticos: Operador Operación + SUMA - RESTA * MULTIPLICACION / DIVISION % MODULO O RESIDUO El operador (%) devuelve el residuo entero de una división entre enteros, ejemplo; // área de declaración int alfa; // área de operaciones Universidad Salesiana de Bolivia Page 7 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO alfa = 23 % 4; // área de despliegue desplegar alfa; --- El resultado en pantalla es 3 Otro ejemplo; alfa = 108 % 10; desplegar alfa; -- El resultado en pantalla es 8 Para resolver los problemas de potencias y raíces, se usan ciertas instrucciones especiales que proporciona el lenguaje, llamadas funciones matemáticas, en C++ existe toda una librería de instrucciones o funciones matemáticas. Recordar que todas las funciones reciben uno o más datos o valores y regresan siempre un resultado, una de estas funciones matemáticas es: #include <math.h> double pow(double base, double exp); Esta función ocupa dos valores o datos( base y exp) ambos de tipo double, y regresa un resultado también de tipo double, ejemplo; Resolver el problema de calcular #include <math.h> // área de declaración de variables double base, exponente, potencia; // área de asignación o carga o inicialización de // variables base=5; exponente=3; // área de operaciones potencia =pow( base, exponente); // Despliegue desplegar potencia; El resultado en pantalla es 125.000000000 Universidad Salesiana de Bolivia Page 8 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO 5.- Reglas para escribir un programa en C++: a) Comienza con las instrucciones #include etc y cada una de ellas es una librería de instrucciones especializadas en tareas especificas. b) Todas las palabras reservadas del lenguaje deben ser minúsculas. (main, include, cout ,etc.) c) Todo programa comienza con una función llamada void main(). d) El cuerpo de instrucciones del programa deberá encerrarse entre llaves. e) Todas las instrucciones ejecutables terminan con punto y coma. f) Los comentarios se ponen encerrados entre /* comentario */ o // comentario g) La declaración de variables ocupa la primera posición. h) Se utiliza una instrucción llamada cout() para desplegar mensajes u otros elementos en el dispositivo de salida standar(pantalla). i.- Se utiliza una instrucción llamada cin>>() para capturar datos desde el dispositivo de entrada standar (teclado). j.- Se usa una instrucción getchar(); al final para detener la pantalla hasta que el usuario pulse la tecla "any key" para continuar o el programa responde tan aprisa que no se alcanza a ver y se regresa al editor. i.-C es case-sensitiva, es decir trata a mayúsculas y minúsculas como caracteres diferentes. 6.- Símbolos para un diagrama de flujo. NOMBRE SIMBOLO SIGNIFICADO Terminal Se utiliza para marcar el inicio y fin de un D.F. y se representa mediante un óvalo Entrada Se representa mediante un paralelogramo que señala la entrada de datos. Proceso Es un rectángulo, representa cualquier proceso (asignación, operación aritmética, cambios de valor) Salida Se utiliza para representar la salida del resultado de los datos ya sea por pantalla o por impresora. Líneas de Son líneas horizontales y verticales con una flecha de flujo dirección utilizados para unir los diferentes símbolos y expresa la dirección del flujo del algoritmo. Conectores Se utilizan para realizar cortes a un D.F. de un lugar a otro, el círculo pequeño conecta en la misma página, mientras que el otro conecta en otra página. Universidad Salesiana de Bolivia Page 9 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO Reglas para la construcción de un D.F. Todo diagrama de flujo debe tener un inicio y un final Las líneas de flujo deben ser rectas verticales u horizontales Deben ser construidos de arriba hacia abajo y de izquierda a derecha Si el D.F. es complejo se aconseja utilizar comentarios que ayuden a entender Si el D.F. requiere más de una hoja se deben utilizar los conectores No puede llegar más de una línea a un símbolo. Ejemplos: 1. Dado como dato el radio de una circunferencia. Calcular e imprimir la longitud y el área de la circunferencia. 2. Conocidos la base y altura de un triángulo rectángulo. Encontrar su hipotenusa y su área. 3. Escribir un D.F. que lea dos números y calcule e imprima su suma, resta, producto y división. Prueba de escritorio Es el seguimiento del algoritmo, se debe hacer la prueba con diferentes datos. 7.- Notación Pseudocódigo El pseudocódigo es una herramienta para el diseño de programas que permite obtener la solución a un problema determinado. Esta notación utilizan estructuras también de tipo standart. NOMBRE Entrada PSEUCOCODIGO Leer var Proceso Var exp Salida Escribir Exp Así como un D.F. tiene inicio y final el pseudocódigo también lo tiene. El inicio normalmente refleja el nombre del programa y el fin el final del pseudocódigo. EJERCICIOS: 1.- Realizar el D.F. y su seudo código para calcular el promedio de tres números cualesquiera. N.P. N1, N2 y N3 son identificadores que representan números P será el resultado del promedio Universidad Salesiana de Bolivia Page 10 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO Leer N1, N2 y N3 Calcular P = (N1 + N2 + N3) / 3 Escribir P 8.- INSTRUCCION COUT() Es una de las mas poderosas herramientas de despliegue de datos que posee el lenguaje. Su formato completo es: cout <<"mensaje” << lista de variables; ejemplos; a).-MENSAJE O TEXTO cout<<"pato"; cout<< varentera; 9.- INSTRUCCION CIN(); Esta instrucción permite que el dato entrado desde el teclado sea capturado y almacenado en la variable correspondiente su formato completo es: cin>>"mensaje">> lista de variables; Ejemplo: cin>>area; cin >>area,base; 10.- INSTRUCCIONES DE CONTROL Instrucciones de control de programa permiten alterar la secuencia normal de ejecución de un programa. Estas instrucciones se dividen en tres grandes categorías: Instrucciones Condicionales que en C++ se implementan con las instrucciones if() y switch(). Instrucciones de ciclos con, for, while, do-while. Instrucción de salto incondicional goto. 10.1.- Instrucciones condicionales Universidad Salesiana de Bolivia Page 11 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO Se utiliza cuando en el desarrollo de la solución de un problema debemos tomar una decisión que se basa en la evaluación de una o más condiciones, lo cual nos señala las alternativas a seguir. Se clasifican en: Alternativa simple, Alternativa doble y alternativa múltiple 10.1.1- Alternativa simple (SI ENTONCES) Permite que el flujo del diagrama de flujo siga por un camino específico si se cumple una condición. Si al evaluar la condición es verdadera se ejecutan ciertas operaciones o acciones, si la condición es falsa se continúa con la secuencia. Su diagrama de flujo es: ` Su Notación Pseudocódigo es: Si condición Entonces Acciones Fin si En general todas las condiciones simples se forman con: variables operadores relaciónales constante o var. sexo = 'm' sueldo > 300000 Una condición simple se define como el conjunto de variables y/o constantes unidas por los llamados operadores relaciónales. Los operadores relaciónales que reconoce el lenguaje CPP son: Operador Significado == Igual que > Mayor que Universidad Salesiana de Bolivia Page 12 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO < Menor que >= Mayor o igual que <= Menor o igual que != No es igual que o es diferente que Observar y tener cuidado sobre todo con el operador de igualdad(=), y el operador relacional de comparación por igualdad(==), es decir; sueldo = 500 , Se esta pidiendo cargar o asignar la variable sueldo con el valor 500 sueldo == 500 , Se esta pidiendo que se compare el valor o dato que se encuentra en la variable sueldo, contra el numero 500. Solo este ultimo formato es valido dentro de una condición en una instrucción condicional. INSTRUCCION IF() Es la instrucción condicional mas usada en los diversos lenguajes de programación, su formato completo en C++ es : if (condición) { grupo cierto de instrucciones;} else { grupo falso de instrucciones; }; Primus.- Observar donde van y donde no van los puntos y comas; Secundus.- La condición va entre paréntesis; Tertius.- Si un if no ocupa un grupo falso de instrucciones, entonces no se pone el else, y la llave antes del else si terminaría con punto y coma. Ejemplo: #include <stdio.h> #include <iostream.h> Universidad Salesiana de Bolivia Page 13 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO #include <string.h> void main() { // declaración variables int edad; char ciudad[30]; //capturando clrscr(); gotoxy(10,5);cout<<("dame edad : "); cin>>("%d",&edad);getchar(); gotoxy(10,7);cout<<("dame ciudad : "); gets(ciudad); //comparando if( edad>20) { gotoxy(30,5);puts("mayor de 20"); } else{ gotoxy(30,5);puts("menor de 20"); }; if( strcmp(ciudad,"tijuana")==0) { gotoxy(35,7);puts("es de tijuana"); }; getchar(); } PROBLEMAS SUGERIDOS 1.- Realizar el D.F. y N.P. para escribir la palabra positivo si el número es positivo. 2.- Se tiene el sueldo de un empleado si este sueldo es inferior a 1000 Bs. Aumentarle un 15%, imprimir su nombre y su sueldo nuevo. 3.- Imprimir el nombre, apellidos, edad si su sexo es femenino 4.- Capturar un numero cualesquiera e informar si es o no es mayor de 100 Universidad Salesiana de Bolivia Page 14 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO 5.- Capturar un numero entero cualesquiera e informar si es o no es múltiplo de 4 ( recordar el operador mod(%), analizado en el tema de operadores aritméticos). 6.- Capturar los cinco datos mas importantes de un Empleado, incluyendo el sueldo diario y los días trabajados , desplegarle su cheque semanal solo si ganó mas de $500.00 en la semana, en caso contrario desplegarle un bono de despensa semanal de $150.00 . 7.- Capturar los datos mas importantes de un estudiante incluyendo tres calificaciones, una pagina que contiene una boleta de calificaciones es llamada si el estudiante es de la carrera de medicina, en caso contrario otra pagina despliega un oficio citando a los padres del estudiante a una platica amistosa con los maestros de la escuela. 10.1..2.- Alternativa doble Permite bifurcar el flujo en dos ramas diferentes en el punto de la toma de desiciones. Si al evaluar la condición (es) el resultado es verdadero entonces se ejecutan ciertas operaciones, si es falso entonces también se ejecutan otras operaciones; en ambos casos luego de ejecutarse las operaciones indicadas se continúa con la secuencia normal del diagrama. Su D.F. es: En muchas ocasiones es necesario presentar mas de una condición para su evaluación al computador. Por ejemplo que el computador muestre la boleta de un alumno, si este estudia la carrera de medicina y su promedio de calificaciones es mayor de 70. Una condición compuesta se define como dos o mas condiciones simples unidas por los llamados operadores lógicos. Los operadores lógicos que CPP reconoce son: OPERADOR SIGNIFICADO && "Y" LOGICO || "O" LOGICO ! "NO" NEGACION Ejemplo: if ( (sueldo> 700) && ( sexo=='m') ) etc, etc, etc. Universidad Salesiana de Bolivia Page 15 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO Notas: Observar que cada condición simple lleva sus propios paréntesis. Si la variable es de tipo string el dato va entre comillas("), pero si la variable es de tipo char el dato va entre apostrofes('). Recordar además que para comparar arreglos de chars se deberá usar strcmp(). Para que el computador evalúe como CIERTA una condición compuesta que contiene el operador lógico "y", las dos condiciones simples deben ser ciertas. Para que el computador evalúe como CIERTA una condición compuesta que contiene el operador lógico "o", basta con que una de las condiciones simples sea cierta. La cantidad total de casos posibles cuando se unen dos o mas condiciones simples esta dada por la relación donde n = cantidad de condiciones, la primera mitad de ellos ciertos y la segunda mitad falsos. En la practica, cada condición simple debe ir encerrada en su propio paréntesis y las dos condiciones simples también deben encerrarse entre sus propios paréntesis, como en el siguiente ejemplo; if((sueldo> 500)%%(strcmp(departamento,"VENTAS")==0 ) { // aquí se construye la pagina que despliegue su cheque semanal } else { // aquí se construye y despliega la pagina del bono de despensa o un oficio de motivación } ; Recordar, cada condición simple debe estar entre paréntesis y las dos condiciones simples también deben estar entre paréntesis. Observar donde se deben incluir los puntos y comas y donde no se deben incluir los puntos y comas. PROBLEMAS SUGERIDOS 1.- Construir un programa que capture un numero cualesquiera e informe si es o no es mayor de 50 y múltiplo de tres. ( solo escribir el mensaje de respuesta de manera muy clara y esto resuelve el problema ) 2.- Construir un programa que indique si un numero es un par positivo. 3.- Capturar los datos de un producto incluyendo su cantidad en existencia, desplegar una orden de compra si la cantidad en existencia del producto es menor que el punto de reordena, o si el origen del producto es nacional. Universidad Salesiana de Bolivia Page 16 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO 4.- Construir un programa que capture los datos de un empleado, desplegar en una pagina su cheque semanal si gana mas de $500.00 y si esta en el departamento de producción, en caso contrario desplegarle en otra pagina un bono de despensa del 25% de su sueldo semanal. INSTRUCCION SWITCH() También existen ocasiones o programas donde se exige evaluar muchas condiciones a la vez, en estos casos o se usa una condición compuesta muy grande o se debe intentar convertir el problema a uno que se pueda resolver usando la instrucción switch(); La instrucción switch() es una instrucción de decisión múltiple, donde el compilador prueba o busca el valor contenido en una variable contra una lista de constantes ints o chars, cuando el computador encuentra el valor de igualdad entre variable y constante, entonces ejecuta el grupo de instrucciones asociados a dicha constante, si no encuentra el valor de igualdad entre variable y constante, entonces ejecuta un grupo de instrucciones asociados a un default, aunque este ultimo es opcional. El formato de esta instrucción es el siguiente; capturar o asignar variable de condición; switch(var int o char) { case const1: instrucción(es); break; case const2: instrucción(es); break; case const3: instrucción(es); break; .................. default: instrucción(es); }; Ejemplo: #include <stdio.h> #include <iostream.h> #include <string.h> Universidad Salesiana de Bolivia Page 17 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO void main() { // declaracion variables char letra; //capturando clrscr(); gotoxy(10,5);cout<<("dame una letra : "); letra=getchar();getchar(); //empieza switch() switch(letra) { case 'a': gotoxy(30,5);puts("aguila");break; case 'b': case 'B': gotoxy(30,5);puts("baca");break; case 'c': gotoxy(30,5);puts("caballo ");puts("camello");break; default:gotoxy(30,5);puts("no hay"); } getchar(); } Notas: 1.- Solo se puede usar como variable de condición una variable entera o variable char. 2.- Las constantes que estamos buscando y comparando son de tipo char, por eso se deben encerrar entre apóstrofes ( '). 3.- Si se quiere resolver el problema de mayúsculas o minúsculas en el teclado, observar que se usan dos case, pero con un solo break; 6.- Recordar que switch() solo trabaja con constantes y variables de tipo char o int, en este ultimo caso, solo usar una variable de opción de tipo entero y en los case poner la constante numérica, sin apóstrofes decir por ejemplo Universidad Salesiana de Bolivia Page 18 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO case 5: instrucciones; break; En particular, instrucciones de tipo switch() se usan para construir programas de selección de menús, donde al usuario se le plantean dos o tres problemas distintos y el propio usuario seleccionaba cual de ellos se ejecuta PROBLEMAS SUGERIDOS 1.- Construir una pagina que contenga el siguiente menú a. conversión de pesos a dólares b. conversión de libras a kilogramos c. conversión de kilómetros a millas d. fin de menú Seleccionar opción [ ] Este es el edit del switch(). 2.- Construir un programa que capture un deporte y despliegue dos implementos deportivos apropiados. 3.- Evaluar cualquier función vista para cuando x = 3, -4, 5 10.2.- Instrucciones de control repetitivas 11.2.1 Estructura para (FOR ) Controla la ejecución de un conjunto de instrucciones que configuran su rango, de tal forma que estos se ejecuten un número determinado de veces que queda definido en los que se denomina la cabecera del bucle, en ella se define un idebtificador de variable, que va a actuar como contador asociado, definiendose al mismo tiempo su valor inicial, su valor final y su incremento. Su diagrama de flujo es: VAR = PI ---> PF A1 Su Notación pseudocódigo es: Para VAR desde PI hasta PF hacer Acción 1 Acción 2 .... Acción n Fin para A2 An VAR Universidad Salesiana de Bolivia Page 19 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO Este ciclo es uno de los mas usados para repetir una secuencia de instrucciones, sobre todo cuando se conoce la cantidad exacta de veces que se quiere que se ejecute una instrucción simple o compuesta. Su formato general es: for (inicialización; condición; incremento) { instrucción(es); }; ejemplo: for(x=1;x<=10;x=x+1) { puts(" MAMA "); }; En su forma simple la inicialización es una instrucción de asignación que carga la variable de control de ciclo con un valor inicial. La condición es una expresión relacional que evalúa la variable de control de ciclo contra un valor final o de parada que determina cuando debe acabar el ciclo. El incremento define la manera en que la variable de control de ciclo debe cambiar cada vez que el computador repite un ciclo. Se deben separar esos 3 argumentos con punto y coma (;) EJEMPLO #include <stdio.h> #include <iostream.h> #include <string.h> void main() { clrscr(); Universidad Salesiana de Bolivia Page 20 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO // declaracion variables int x; // instruccion for for(x=1;x<=10;x=x+1) { gotoxy(10, x+4); cout<<("%d MAMA",x); }; getchar(); } Casos Particulares del ciclo for; 1.- El ciclo comienza en uno y se incrementa de uno en uno este es el caso mas general. 2.- Pero el valor inicial puede se diferente de uno, ejemplo; for(x=5;x<=15;x=x+1){ etc.}; 3.- Incluso el valor inicial puede ser negativo, ejemplo; for (x = -3 ;x<= 8; x=x+1) { etc.}; 4.- Los incrementos también pueden ser diferentes al de uno en uno, ej.; for (x=1; x<= 20; x=x+3){ etc. }; 5.- Incluso pueden ser decrementos, solo que en este caso, recordar; 5.1.-el valor inicial de la variable debe ser mayor que el valor final. 5.2.-cambiar el sentido de la condición. ejemplo; for (x= 50 ; x >= 10; x= x-4 ) { etcétera }; 6.- Solo para los casos de incrementos y decrementos de una en una unidad substituir en el for: el x = x + 1 por x++ el x = x - 1 por x-PROBLEMAS SUGERIDOS: 1.- CONSTRUIR UN PROGRAMA QUE DESPLIEGUE LOS NÚMEROS DEL 20 AL 30. Universidad Salesiana de Bolivia Page 21 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO 2.- DESPLEGAR LOS ENTEROS ENTRE 50 Y 30 ACOMPAÑADOS DE SU POTENCIA CUADRADA Y RAÍZ CUBICA RESPECTIVA(revisar el tema de operadores aritmeticos). 3.- DESPLEGAR LOS MÚLTIPLOS DE 5, ENTRE 10 Y 50, ACOMPAÑADOS DE SU FACTORIAL Y LOGARITMO RESPECTIVO(revisar el tema de operadores aritmeticos tambien). 4.- DESPLEGAR LA TABLA DE MULTIPLICAR QUE EL USUARIO INDIQUE. 5.- EVALUAR LA FUNCION Y=5X^2 + 3X + 8 CUANDO X--> -3...10 (RANGO DE -3 HASTA 10) 10.2.2.- La estructura Mientras (WHILE) Se utiliza cuando no sabemos el número de veces que se ha de repetir y el cuerpo o las instrucciones se repiten mientras se cumple una determinada condición. Su diagrama de flujo es el siguiente: condicion Primero se evalúa la expresión (condición) si es falsa, no se realiza ninguna acción y el flujo continúa, si es verdadero se ejecuta las sentencias, este proceso continúa mientras la expresión sea verdadera. Su Notación Pseudocódigo es: sentencias Mientras condición hacer sentencias fin_mientras Su codificación es la siguiente: WHILE expresión DO sentencias; En este ciclo el cuerpo de instrucciones se ejecuta mientras una condición permanezca como verdadera en el momento en que la condición se convierte en falsa el ciclo termina. Su formato general es : cargar o inicializar variable de condición; while(condición) { grupo cierto de instrucciones; instrucción(es) para salir del ciclo; }; Universidad Salesiana de Bolivia Page 22 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO Un error muy común con el while, es poner un punto y coma(;) después de la (condición) ejemplo while(condición); <--esto es y causa un error. #include <stdio.h> #include <iostream.h> #include <string.h> void main() { clrscr(); // declaracion variables int x=1; // instruccion while while(x<=10) { gotoxy(10, x+3); cout<<("%d PATO",x); x++; }; getchar(); } While puede llevar dos condiciones en este caso inicializar 2 variables de condición y cuidar que existan 2 de rompimiento o terminación de ciclo. El grupo cierto de instrucciones puede ser una sola instrucción o todo un grupo de instrucciones. La condición puede ser simple o compuesta. Los casos generales de for también se aplican a while. A este ciclo también se le conoce también como ciclo de condición de entrada o prueba por arriba porque este ciclo evalúa primero la condición y posteriormente ejecuta las instrucciones. PROBLEMAS SUGERIDOS 1.- DESPLEGAR ENTEROS ENTRE 50 Y 80 2.- DESPLEGAR MULTIPLOS DE 4 ENTRE 60 Y 20 ACOMPAÑADOS DE SU LOGARITMOS DE BASE 10 Y BASE e RESPECTIVOS. 3.- CONSTRUIR LA TABLA DE DIVIDIR QUE EL USUARIO INDIQUE. Universidad Salesiana de Bolivia Page 23 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO 4.- CALCULAR LA SUMA DE LOS N PRIMEROS NÚMEROS NATURALES INGRESADOS POR EL TECLADO. 10.2.3.- Estructura repetir (REPEAT) Es un ciclo donde se puede establecer a priori que el ciclo se repetirá un número definido de veces. Las instrucciones que están dentro del bucle se repiten hasta que la condición sea verdadera, la diferencia en la anterior estructura es que la posición de la condición se encuentra después. Su diagrama de flujo es: Su Notación Pseudocódigo es: Cuerpo del prog. Repetir sentencias hasta condición Su codificación en Pascal es: Condición REPEAT sentencias; UNTIL condición Su diferencia básica con el ciclo while es que la prueba de condición es hecha al finalizar el ciclo, es decir las instrucciones se ejecutan cuando menos una vez porque primero ejecuta las instrucciones y al final evalúa la condición; También se le conoce por esta razón como ciclo de condición de salida. Su formato general es : cargar o inicializar variable de condición; do { grupo cierto de instrucción(es); instrucción(es) de rompimiento de ciclo; } while (condición); #include <stdio.h> #include <iostream.h> #include <string.h> void main() Universidad Salesiana de Bolivia Page 24 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO { clrscr(); // declaración variables int x=1; // instruccion do while do{ gotoxy(10, x+3); cout<<("%d GATO",x); x++; } while(x<=10); getchar(); } Otra diferencia básica con el ciclo while es que, aunque la condición sea falsa desde un principio el cuerpo de instrucciones se ejecutara por lo menos una vez. Universidad Salesiana de Bolivia Page 25 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO Tema 3. PROCEDIMIENTOS Y FUNCIONES 1.- PROCEDIMIENTOS Un camino para dividir un gran programa en partes mas pequeñas es el uso de los llamados procedimientos. Un procedimiento es un grupo de instrucciones, variables, constantes, etc, que están diseñados con un propósito particular y tiene su nombre propio. Es decir un procedimiento es un modulo de un programa que realiza tareas especificas y que no puede regresar valores a la parte principal del programa u otro procedimiento que lo este invocando. Después de escribir un procedimiento se usa su propio nombre como una sola instrucción o llamada al procedimiento. Los procedimientos se podrán escribir después del cuerpo principal del programa utilizando el formato: void NomProc(){instrucciones;}; Pero también los procedimientos deberán declararse antes del main como lo muestra el programa ejemplo. Sin embargo el procedimiento se construye antes del main() entonces no hay necesidad de declararlo antes. Un programa puede tener tantos procedimientos como se deseen para hacer una llamada o invocación al procedimiento durante la ejecución de un programa solo se deberá escribir el nombre del procedimiento y los paréntesis en blanco. #include <stdio.h> #include <iostream.h> #include <string.h> void main() { clrscr(); Universidad Salesiana de Bolivia Page 26 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO // recordar declarar primero proc y funciones void proc1(); //llamando o activando procedimiento proc1(); } // fin del main void proc1() { // area de declaracion de variables y captura de datos int base1,altura; float area; //area de captura cout<<("dame base: ");cin>>("%d",&base1); cout<<("dame altura: ");cin>>("%d",&altura); // area de operaciones area = base1 * altura / 2; // area de despliegue cout<<("area=%0.2f",area); getchar();getchar(); } // fin proc Recordar que se pueden crear el procedimiento o los procedimientos (aunque realmente es una función) arriba o abajo de la parte principal del programa. Recordar tambien que un programa puede tener muchos procedimientos, y estos pueden llamarse o invocarse entre si. MUCHO OJO con la nota anterior, es valido que un procedimiento se llame o invoque o se active a si mismo o usando una referencia circular, por ejemplo proc1, activa proc2 que a su vez llama a proc1 esto se llama recursión y si no se controla con una instrucción if(condición)break o exit(no me acuerdo cual de las dos) se va a obtener un hermoso ciclo infinito, muy divertido cuando le pasa a los programas de los compañeros, estan avisados. Universidad Salesiana de Bolivia Page 27 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO Como se observa un procedimiento puede ser un programa completo. Construir los siguientes programas con procedimientos a) Convertir $800.00 Pesos a dolares. b) Calcular el Area de un triangulo de base=20 y altura=30. c) Desplegar una Boleta de calificaciones. 2.- PARAMETROS Un parámetro es una variable que puede pasar su valor a un procedimiento desde el principal o desde otro procedimiento. Existen ocasiones en que es necesario mandar al procedimiento ciertos valores para que los use en algún proceso. Estos valores que se pasan del cuerpo principal del programa o de un procedimiento a otros procedimientos se llaman parámetros. Entonces la declaración completa de un procedimiento es : Void Nom_Proc(lista de parametros) { cuerpo de instrucciones;}; Donde lista de parámetros es una o mas variables separadas por coma, como lo muestra el programa ejemplo. #include <stdio.h> #include <iostream.h> #include <string.h> // recordar declarar primero proc y funciones // y observar como se pasa como parámetro una string void proc1(char nom[], int suma); void main() { clrscr(); //llamando o activando procedimiento Universidad Salesiana de Bolivia Page 28 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO // y pasando dos parámetros uno de ellos string proc1("juan perez", 3 + 4); } //fin main // ya se fijaron como se pasa la string void proc1(char nom[], int suma) { //declarando variables int edad; // capturando cout<<("dame edad: "); cin>>("%d",&edad); // Operaciones sumando parámetro edad = edad + suma; //construyendo y desplegando la pagina de salida cout<<("%s \n",nom); cout<<("EDAD= %d", edad); getchar();getchar(); } // fin proc Y no olvidar declarar el procedimiento antes del main() incluyendo sus parámetros como lo muestra el ejemplo. Recordar también que se pueden mandar como parámetros, datos, variables y expresiones algebraicas(no formulas o ecuaciones algebraicas) Observar que en el procedimiento los parámetros son dos variables locales es decir variables que solo se pueden usar dentro del procedimiento estas variables son quienes reciben los datos o valores. REGLAS PARA EL USO DE PARAMETROS Universidad Salesiana de Bolivia Page 29 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO 1.- Cuando se usan variables como parámetros, la variable que se manda debe ser declarada dentro del principal o del procedimiento de donde se esta enviando. 2.- La variable que se manda tiene un nombre, la que se recibe puede tener otro nombre o el mismo nombre por claridad de programa, pero recordar que internamente en la memoria del computador existirán dos variables diferentes. 3.- La cantidad de variables que se envían deben ser igual en cantidad, orden y tipo a las variables que reciben. 4.- La variable que se recibe tiene un ámbito local dentro del procedimiento, es decir solo la puede usar ese procedimiento. 5.- Se puede mandar a un procedimiento un dato, una variable (como lo muestran los ejemplos) o una expresión algebraica (no ecuación o formula, pero siempre se deberán recibir en una variable. TAREAS 1.- Programa que captura 3 calificaciones en principal, calcular promedio en procedimiento uno e imprimir nombre y promedio en un segundo procedimiento. 2.- Construir una tabla de multiplicar que el usuario indique captura y control de ciclo en principal, calculo y despliegue en un procedimiento. 3.- Construir un procedimiento que reciba un numero entero y que mande llamar a un segundo procedimiento pasando el letrero "PAR O IMPAR" 3.- VARIABLES LOCALES Y GLOBALES El lugar donde sea declarada una variable afectara el uso que el programa quiera hacer de esa variable. Las reglas básicas que determinan como una variable puede ser usada depende de 3 lugares donde se puede declarar una variable. En primer lugar es dentro de cualquier función o procedimiento a estas se les llama variables locales y solo pueden ser usadas por instrucciones que estén dentro de esa función o procedimiento. En segundo lugar es como parámetro de una función donde después de haber recibido el valor podrá actuar como variable local en esa función o procedimiento. En esencia una variable local solo es conocida por el código de esa función o procedimiento y es desconocida por otras funciones o procedimientos. En tercer lugar es fuera de todas los procedimiento o funciones a este tipo de variables se les llama variables globales y podran ser usadas por cualquier función o procedimiento del Universidad Salesiana de Bolivia Page 30 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO programa, sin embargo hay que agregarle la palabra reservada STATIC y a partir del momento en que se declara, acompañada de dicha palabra reservada static se considera y puede usarse como variable global. En programación en serio no es acostumbrado usar muchas variables globales por varias razones, una de ellas es que variables globales estan vivas todo el tiempo de ejecución del programa y si una global solo la ocupan unos cuantos procedimientos no tiene caso que este viva para todo el resto, otra razón es que es peligroso tener variables globales porque todo el conjunto de procedimiento y funciones que componen un programa tienen acceso o comparten su valor y se corre el riesgo de que inadvertidamente alguno de ellos modifique su valor. #include <stdio.h> #include <iostream.h> #include <string.h> // recordar declarar primero proc y funciones void proc1(); // variables globales float base, altura, area; void main() { clrscr(); //capturando datos cout<<("dame base: ");cin>>("%f",&base); cout<<("dame altura: ");cin>>("%f",&altura); //llamando procedimiento proc1(); } void proc1(){ // area de operaciones area = base * altura / 2; // area de construccion de pagina de salida Universidad Salesiana de Bolivia Page 31 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO cout<<(" area =%0.2f",area); getchar();getchar(); } Es muy agradable trabajar sin parametros pero recordar la nota de arriba que no es muy bueno usar muchas variables globales: PROBLEMAS SUGERIDOS 1.- BOLETA DE CALIFICAIONES Y SOLO USAR DOS VARIABLES GLOBALES 2.- UNA TABLA DE MULTIPLICAR Y SOLO USAR UNA VARIABLE GLOBAL 4.- FUNCIONES Una funcion es un modulo de un programa separado del cuerpo principal, que realiza una tarea especifica y que puede regresar un valor a la parte principal del programa u otra funcion o procedimiento que la invoque. La forma general de una funcion es: Tipodato Nomfun(parametros) { cuerpo de instrucciones; return [dato,var,expresion]; } Donde tipodato especifica el tipo de dato que regresara la función. La instrucción RETURN es quien regresa un y solo un dato a la parte del programa que la este llamando o invocando, sin embargo es de considerar que return puede regresar un dato, una variable o una expresión algebraica(no ecuación o formula) como lo muestran los siguientes ejemplos; a) return 3.1416; b) return area; c) return x+15/2; Universidad Salesiana de Bolivia Page 32 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO La lista de parámetros formales es una lista de variables separadas por comas (,) que almacenaran los valores que reciba la función, estas variables actúan como locales dentro del cuerpo de la función. Aunque no se ocupen parámetros los paréntesis son requeridos. INSTRUCCION RETURN Dentro del cuerpo de la función deber haber una instrucción return cuando menos para regresar el valor, esta instrucción permite regresar datos. Recordar además que cuando se llame una función deberá haber una variable que reciba el valor que regresara la función, es decir generalmente se llama una función mediante una sentencia de asignación, por ejemplo resultado=función(5, 3.1416); #include <stdio.h> #include <iostream.h> #include <string.h> //todos los proc y funciones deben declararse antes del main float fun1(float b, float a); void main() { clrscr(); //capturando datos // area de declaracion de variables y captura de datos int base,altura; float area; //area de captura cout<<("dame base: ");cin>>("%d",&base); cout<<("dame altura: ");cin>>("%d",&altura); //llamando o invocando la funcion fun1 area= fun1(base, altura); //desplegando cout<<(" area =%0.2f",area); getchar();getchar(); Universidad Salesiana de Bolivia Page 33 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO } float fun1(float b, float a) { return b * a / 2; } Usar de preferencia solo ints y doubles como parametros. Es permitido poner mas de un return en el cuerpo de instrucciones sobre todo en condiciones, pero solo un return se ejecutara, ejemplo; if (suma >= 10) { return 10; } else { return 20; } EXISTEN 3 CLASES USUALES DE FUNCIONES. Las primeras son de tipo computacional que son diseñadas para realizar operaciones con los argumentos y regresan un valor basado en el resultado de esa operación. Las segundas funciones son aquellas que manipulan información y regresan un valor que indican la terminación o la falla de esa manipulación. Las terceras son aquellas que no regresan ningún valor, es decir son estrictamente procedurales. Esto quiere decir que en general toda operación o calculo en un programa deberá convertirse a una o muchas funciones y el resto deberán ser procedimientos. TAREAS 1.- Capturar 3 calificaciones y nombre en un procedimiento, calcular promedio en una función, desplegar en otro procedimiento. 2.- Crear una tabla de multiplicar, captura y control de ciclo en el principal, operaciones en una función, despliegue en el principal. 5.- ARREGLOS COMO PARAMETROS Para pasar un arreglo completo como parámetro a un procedimiento a una función solo se manda el nombre del arreglo sin corchetes e índices, en el procedimiento o función que recibe solo se Universidad Salesiana de Bolivia Page 34 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO declara un arreglo del mismo tipo y se puede usar el mismo o diferente nombre del arreglo sin corchetes e índices. Sin embargo es conveniente aclarar, que a diferencia de variables escalares normales, cpp no genera una nueva variable en memoria ni tampoco copia los datos al arreglo que recibe, en su lugar cpp sigue usando los datos que están en el arreglo original, es por esta razón que cambios que se le hagan a los datos del arreglo que recibe realmente se esta haciendo al arreglo original como lo muestra el siguiente ejemplo: #include <stdio.h> #include <iostream.h> #include <string.h> void proc1(int vector[]); void main() { clrscr(); //creando arreglo y cargandolo int lista[5]= {10,11,12,13,14}; // mandandolo a procedimiento recordar como se manda sin [] proc1(lista); // desplegando arreglo lista y observar que datos salen for(int reng=0; reng<=4; reng++) cout<<("%d \n",lista[reng]); getchar(); } // termina main void proc1(int vector[]) { // sumandole 50 a lo que se tenia en arreglo lista // es decir vector queda cargado con 60,61,62,63,64 for(int reng=0; reng<=4; reng++) vector[reng]=vector[reng]+ 50; Universidad Salesiana de Bolivia Page 35 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO // observar que no se regresa nada } //termina proc1 Es de recordar que los cambios que le hagan al arreglo dentro de la función se reflejaran en el arreglo original, es por esto que si se quiere modificar un arreglo en una función no hay necesidad de regresar ningún valor. TAREAS 1.- Inicializar 10 edades en el principal mandar la lista a un procedimiento que la convierte a meses, desplegar en principal. 2.- Capturar un arreglo de 7 ciudades en principal, sortear u ordenar o alfabetizar (sorteo burbuja) en un procedimiento y desplegar en otro procedimiento tanto la lista original como la lista ordenada. Universidad Salesiana de Bolivia Page 36 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO TEMA 3 ARCHIVOS 1.- Introducción Hasta el momento en todo lo que abarca la programación estructurada, hemos trabajado inicialmente con datos simples junto con todas las estructuras selectivas y repetitivas para hacer programas, también con los vectores y matrices se logra trabajar con un conjunto de datos homogéneos, pero existen básicamente dos problemas el primero : las variables que puedan almacenar un conjunto de valores y no necesariamente del mismo tipo, el segundo el de almacenar en forma permanente los datos que se generan dentro de un programa ya sea por captura, proceso, etc; El primer problema se resuelve usando el concepto de estructuras o registros el segundo problema se resuelve usando el concepto de archivos. Variables simples o escalares pueden almacenar un dato de información y arreglos pueden almacenar conjuntos de ellos del mismo tipo y al mismo tiempo, estos dos mecanismos pueden manejar una gran variedad de situaciones pero a menudo se necesita trabajar sobre datos de diversos tipos en este caso ni variables escalares ni arreglos son adecuados. 2.- Concepto de Estructura. Es un conjunto de datos no necesariamente del mismo tipo, los cuales se podrán manipular o realizar cualquier operación sobre cada uno de ellos o sobre toda la estructura. Los elementos individuales de una variable estructura reciben el nombre de campos. Ejemplo: struct alumno nombre -> campo1 direccion -> campo2 edad -> campo3 etc EL FORMATO GENERAL DE UNA ESTRUCTURA ES: tipo de almacenamiento struct { tipo campo1; tipo campo2; Universidad Salesiana de Bolivia Page 37 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO }lista de variables; Es el registro completo quien se declara en cualquiera de los lugares adecuados para ello. Son los campos del registro a quienes se les va a asignar, inicializar, capturar, etc y de esta manera a los campos se les considera como variables normales. Para indicar a "C" durante cualquier proceso que la variable a utilizar es un campo de una estructura se utiliza el siguiente formato. nomregistro.nombredelcampo Ejemplo. #include <stdio.h> #include <iostream.h> #include <string.h> struct { int matricula; char nombre[30]; int edad;}alumno; void main() { clrscr(); // captura de campos cout<<("dame matricula :");cin>>("%d",&alumno.matricula);getchar(); cout<<("dame nombre :");gets(alumno.nombre); cout<<("dame edad :");cin>>("%d",&alumno.edad); // area de operaciones alumno.edad = alumno.edad * 12; // area de salida cout<<("MATRICULA =%d \n",alumno.matricula); Universidad Salesiana de Bolivia Page 38 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO cout<<("NOMBRE =%s \n",alumno.nombre); cout<<("MESES =%d \n",alumno.edad); getchar();getchar();} Las operaciones mas elementales con los campos de una estructura incluyen captura e inicialización. 3.- Conceptos de registro y archivo Si bien es cierto que ya se pueden manejar gran cantidad de datos del mismo y diferente tipo al mismo tiempo el problema es que al terminar de ejecutarse el programa los datos se pierden. De esta situación nace el concepto de archivos que son medios que facilita el lenguaje para almacenar los datos en forma permanente, normalmente en los dispositivos de almacenamiento standar. Otro concepto teórico de archivo que se suele manejar es; conjunto de registros que contienen campos y en cada campo se almacena los datos simples. Como nota a tomar en cuenta los datos que se van almacenando en un archivo de disco, se almacenan en renglones consecutivos y cada renglón en disco, se conoce como registro del archivo, favor de no confundir el concepto de registro de archivo y registro o estructura como variable ya analizada, son dos cosas totalmente diferentes aunque desafortunadamente se llamen igual. Primero: Operaciones con archivos ESCRIBIR O GRABAR: Es la operación mas elemental con un archivo, consiste en tomar un o unos datos en variables de cualquier tipo (escalar, mezcla de datos, arreglos, estructuras) y almacenarlas en un archivo de datos en disco. LEER: Operación consistente en sacar los datos del archivo en disco y mandarlos o cargar la variable respectiva Segundo: Organización de archivos En general existen dos tipos de archivos: a) Archivos Secuenciales.En este caso los datos se almacenan en forma consecutiva y no es posible leer (recuerdan que significa esta operación) ningún registro (recuerdan la nota de arriba) directmente, es decir para leer el registro n se deberá recorrer o acensar los n-1 registros anteriores. b) Archivos Directos o Random.- (aleatorios) Universidad Salesiana de Bolivia Page 39 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO Para este caso si se puede acceder o leer un renglón n cualquiera, el acceso a todas las operaciones sobre archivos es directamente a un registro especifico. c) Archivos Indexados Este un último tipo de archivos tiene adicionalmente un campo denominado campo índice, el cual permite acceder y realizar todas las operaciones con archivos. Tercero: Tipo de archivos En general existen tantos tipos de archivos como tipos de datos existen, es decir: El paquete standar de input/output de "C", hace disponible 4 métodos o maneras diferentes de leer y escribir los datos a disco. Tres de ellas corresponden exactamente a lo aprendido de leer y escribir datos desde el teclado hacia la pantalla. 1.- Datos a ser grabados o leídos como un carácter a la vez, se utilizaran funciones análogas a getchar y putchar. 2.- Datos que pueden ser leídos o grabados como una string se usaran funciones análogas a gets y puts. 3.- Datos que se capturen o desplieguen con formatos parecidos a los usados por cin>> y cout se usaran funciones similares, es decir serán problemas que involucran mezclas de strings, caracteres, floats, etc. 4.- También se podrán leer y escribir datos de tipo arreglo y registros utilizando instrucciones apropiadas. Caracter string Formateado Registros y arreglos Leer getc() fgets( ) fcin>>() fread() Escribir putc() fputs( ) fcout() fwrite() Cuarto: Almacenamiento en archivos Modo Texto: en este caso los datos son almacenados usando Ascii y por tanto son plenamente visibles usando cualquier editor. Modo Binario: en este caso los datos son almacenados en notación hexadecimal y por tanto se ocupa un editor binario para reconocerlos, sin embargo un archivo binario es mas compacto que un archivo texto. Universidad Salesiana de Bolivia Page 40 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO 4.- Operaciones con archivos Existen muchas operaciones asociadas a archivos, las mas elementales son: 1.- Creación de Archivo.- En este proceso se pretende solamente crear un archivo nuevo en disco con su nombre tipo y especialidad de almacenamiento de datos apropiado. 2.- Apertura de Archivos.- En este caso se pretende abrir un archivo ya existente en disco para procesarlo ya sea para cargar o grabar estructuras en sus registros o leer algún registro en especial para mandarlo a una variable de cualquier tipo. No confundir creación con apertura, creación es un proceso que solo se ejecuta una sola vez en la vida de un archivo, mientras que apertura, siempre se está realizando por los programas especializados en algún proceso. 3.-Cierre de archivos: Es la operación más importante en cualquier programa que maneje archivos, o se cierra el archivo como ultima instrucción del programa o se verá el anuncio ABORT,RETRY,FAIL. 4.-Altas en archivo.- En este proceso se captura una estructura en memoria con sus datos pertinentes y después se graba la estructura al archivo en disco. 5.-Lectura de archivo.- En este proceso se abre el archivo, se manda el registro de disco a una estructura en memoria para su procesamiento. 6.- Consulta de archivos: En este proceso se pretende desplegar todos los registros del archivo en disco a la pantalla ya sea consola o mejor aún, a una pagina html 7.-Busqueda en archivos: Una de las operaciones más comunes consiste en que el usuario pide toda la información de algún renglón en disco proporcionando la información de algún campo generalmente el campo clave de la estructura. 8.- Filtros.- En este proceso el usuario está interesado en algún conjunto de renglones con características comunes (condición), por ejemplo todos los alumnos de "sistemas" o todos los empleados que ganen más de $500.00 pesos, o todos los clientes que sean de "Tijuana", etc 9.-Modificaciones de registros o archivos: Problema muy común, donde los datos originales ya grabados se tienen que cambiar o actualizar, por ejemplo el nombre no era "juan" es "juana", o la calificación no es 100 es 20, etc. 10.- Bajas de registros: también muy común este proceso, por ejemplo el alumno ya egreso, el cliente huyo, etc. 5.- Creación Universidad Salesiana de Bolivia Page 41 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO Lo primero que se crea es una variable de tipo puntero o apuntador a un archivo a disco(instrucción FILE y debe ser en MAYUSCULAS) llamada archdisco (solo es nombre). Su formato es; FILE * nom_archivo Variables apuntadores son tipos especiales de variables que tienen la capacidad de almacenar no datos, pero si direcciones ya sean de la memoria del computador o como en este caso de una direccion fisica del disco. En "C" una variable apuntador se declara anteponiendo un asterisco antes del nombre. En el programa se está creando una variable apuntador bautizada con el nombre de archdisco que almacenara la direccion fisica de el archivo en disco, en algun cilindro, track , sector debera quedar el archivo no es verdad??. Como segundo paso se abre el archivo con la instruccion fopen( ), siendo su formato el siguiente: nom_archivo = fopen("ruta o dirección","modo”); Observar que la ruta es la direccion fisica de tu sitio en TU PC. Donde se guardara los datos del archivo. Observar el doble diagonal(\\) en el parametro. La funcion fopen( ) cuando realiza el trabajo de abrir un archivo, regresa la direccion fisica donde crea o graba el archivo en disco. El primer parametro o argumento en esta función es la unidad de disco y el nombre del archivo. El segundo parametro o argumento es llamado modo y es una de los varios modos que podemos usar. "r" ----> Lectura. "w" ----> Escritura. "a" ----> Append, si el archivo ya existe append empieza a añadir los nuevos datos al final del archivo ya existente. "r+" ---> Lectura y escritura, ya debe existir el archivo. "w+" ---> Crea para lectura y escritura y si ya existe, sobreescribe. "a+" ---> Crea o abre para lectura y append, sino existe el archivo sera creado. Universidad Salesiana de Bolivia Page 42 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO En adicion a los valores listados tambien es permitido agregar uno de los siguientes caracteres, pero insertandolo antes del signo + modo significado. t lo abre en modo texto. b lo abre en modo binario. Cuando se ha finalizado de escribir al archivo se debe cerrar y esto se hace con la instrucción: fclose(archdisco); En este proceso se pretende solamente crear un archivo secuencial en Disco de la unidad A. Ejemplo: #include <stdio.h> #include <iostream.h> #include <string.h> struct { int matricula; char nombre[30]; int edad;}alumno; void main() { clrscr(); //creando y cerrando el archivo en disco FILE *archdisco; archdisco = fopen("A:\\alumnos.dat","w"); fclose(archdisco); cout("ARCHIVO CREADO"); getchar();getchar(); } Universidad Salesiana de Bolivia Page 43 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO 6.- GRABACION Y LECTURA DISCO Como ya se menciono grabar y lectura de registros o estructuras a renglones o registros de archivos en disco. Estos dos procesos son los casos mas comunes y frecuentes que se pueden realizar con un archivo de disco. Lo primero que se debe hacer es usar la instrucció "fopen( )" en modo "at+" en lugar de modo "w" pero es para matar dos pajaros de un tiro. En segundo lugar se debe utilizar la instrución fwrite ( ) y su formato es: fwrite(&persona,sizeof(alumno),1,archdisco); Como se observa ocupa 4 parametros que son: Con apuntadores se manejan dos operadores diferentes que son ( * y &) el asterisco como ya se indico se usa para crear una variable apuntador, es decir variables que almacenaran direcciónes físicas de algún lugar de la memoria del computador. Por supuesto tambien que en ese espacio o bodega en memoria se almacenaran datos o información, es el operador &(ampersand) quien se usa para accesar a esos datos, ejemplo: Float *pi; // aquí se crea una variable apuntador que guardara la dirección donde se almacenara un valor de tipo float. Si en ese programa, se usa: pi= 3.1416, el compilador protesta porque se esta pretendiendo almacenar un valor float en una variable que solo puede almacenar direcciones de memoria. Pero si es valido &pi=3.1416, es decir cuando usamos el operador ampersand estamos trabajando con el contenido de una dirección de memoria, es por eso que: 1.-PRIMER PARAMETRO: fwrite() ocupa primero conocer cuales datos va a almacenar en disco, aquí se le está indicando que es el dato que se tiene en la dirección de memoria donde esta el registro "alumno". 2.- SEGUNDO PARAMETRO: fwrite(), ocupa conocer cuántos bytes de información debe grabar, para esto se tienen dos opciones o se le da el valor exacto por ejemplo 64 bytes o 39 bytes o mas fácil aun se usa sizeof() que regresa el tamaño del dato. 3.- TERCER PARAMETRO: fwrite(), necesita conocer también cuantas estructuras o registros a la vez debe grabar por lo general es un solo registro, pero más adelante estudiaran que es posible grabar mas de un registro a la vez y esto es de mucho provecho, porque por ejemplo si en un sistema se ocupa grabar 1000 registros y usamos fwrite() de uno en uno, quiere decir que habría mil accesos a disco. Universidad Salesiana de Bolivia Page 44 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO 4.-CUARTO PARAMETRO: fwrite() también ocupa conocer exactamente en que clúster, sector y byte exacto del disco duro debe grabar el registro, la primera opción seria desarmar el disco duro y ver donde hay lugar para poner el archivo J o mejor aun usar la variable archdisco que ya tiene esa dirección física del archivo en disco. Ejemplo: #include <stdio.h> #include <iostream.h> #include <string.h> struct { int matricula; char nombre[30]; int edad;} alumno; void main() { clrscr(); // captura de campos cout("matricula :");cin>>("%d",&alumno.matricula);getchar(); cout("nombre :");gets(alumno. nombre); cout("edad :");cin>>("%d",&alumno.edad); // grabando a disco FILE *archdisco; archdisco = fopen("A:\\alumnos.dat","at+”); fwrite(&alumno,sizeof(alumno),1,archdisco); fclose(archdisco); cout("alumno insertado"); getchar();getchar(); Universidad Salesiana de Bolivia Page 45 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO } 7.- ESCRITURA o IMPRESION DE REGISTROS Para poder visualizar o imprimir los registros primeramente se abre el archivo junto con el apuntador, es decir usar FILE y fopen, en segundo lugar se utiliza la instrucción fwrite ( ), con los mismos cuatro parametros que el fread( ). El programa ejemplo es: #include <stdio.h> #include <iostream.h> #include <string.h> struct { int matricula; char nombre[30]; int edad;} alumno; void main() { clrscr(); // leyendo disco FILE *archdisco; archdisco = fopen("A:\\alumnos.dat","w"); // aqui siempre debe empezar el ciclo de lectura // y fread() regresa siempre cuantas estructuras leyo while(fread(&alumno,sizeof(alumno),1,archdisco)==1) { // desplegando estructuras cout("MATRICULA =%d ",alumno.matricula); cout(" NOMBRE =%s ",alumno.nombre); cout(" MESES =%d ",alumno.edad); Universidad Salesiana de Bolivia Page 46 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO cout("\n"); }; // aqui termina while // no olvidar cerrar archivo y siempre fuera de while fclose(archdisco); getchar();getchar(); } 8: BUSQUEDA En este proceso el usuario del programa quiere que se despliegue un y solo un registro de información proporcionando un dato de búsqueda generalmente la clave del registro. Recordar que la característica principal de un archivo secuencial, es que no es posible acceder o acezar a un registro o renglón especifico o determinado sino que se deberá recorrer todos los n-1 renglones anteriores. Esta situación se da porque al construir un registro cualquiera con una montón de campos strings a la hora de almacenar dichos registros, estos registros tendrán tamaños diferentes, esta es la razón principal por la cual al buscar un registro especifico se tiene que recorrer y validar todos los registros anteriores. En el programa ejemplo se esta usando un ciclo while fread para recorrer todos los registros del archivo, por supuesto que si se tiene un archivo con 5000 registro y el buscado es el 4500 al menos se se tendrá que recorrer todos los 4499 registros anteriores. Programa ejemplo: #include <stdio.h> #include <iostream.h> #include <string.h> struct { int matricula; char nombre[30]; int edad;} alumno; void main() { Universidad Salesiana de Bolivia Page 47 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO clrscr(); // cargando clave a buscar cout("dame matricula buscar:"); int clave; cin>>("%d",&clave);getchar(); //abriendo, leyendo,cargando estructura FILE *archdisco; archdisco = fopen("A:\\alumnos.dat","at+"); // aqui siempre debe empezar el ciclo de lectura // y fread() regresa siempre cuantas estructuras leyo while(fread(&alumno,sizeof(alumno),1,archdisco)==1) { // desplegando estructura buscada if ( clave == alumno.matricula) { cout("MATRICULA =%d ",alumno.matricula); cout(" NOMBRE =%s ",alumno.nombre); cout(" MESES =%d ",alumno.edad); cout("\n");}; }; // aqui termina while // no olvidar cerrar archivo y siempre fuera de while fclose(archdisco); getchar(); } 9: FILTROS Otro problema similar al anterior es el de filtros, es decir en muchas ocasiones es necesario obtener información acerca de un subconjunto de renglones de el archivo. Por ejemplo todos los estudiantes que sean mayores de 17 años, o cualquier otro filtro que cumpla una condicion. Universidad Salesiana de Bolivia Page 48 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO Ejemplo: #include <stdio.h> #include <iostream.h> #include <string.h> struct { int matricula; char nombre[30]; int edad;} alumno; void main() { clrscr(); // cargando variable condicion cout("EDAD MAYOR QUE >= :"); int edad; cin>>("%d",&edad);getchar(); //abriendo, leyendo,cargando estructura FILE *archdisco; archdisco = fopen("A:\\alumnos.dat","at+"); // aqui siempre debe empezar el ciclo de lectura // y fread() regresa siempre cuantas estructuras leyo while(fread(&alumno,sizeof(alumno),1,archdisco)==1) { // desplegando estructuras buscadas if (alumno. edad >= edad) { cout("%d ",alumno.matricula); cout(" %s ",alumno.nombre); Universidad Salesiana de Bolivia Page 49 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO cout(" %d ",alumno.edad); cout("\n");}; }; // aqui termina while // no olvidar cerrar archivo y siempre fuera de while fclose(archdisco); getchar(); } 10.- ELIMINACIONES Eliminación o bajas es el proceso por medio del cual algunos registros del archivo son purgados del archivo, existen dos maneras por las cuales se puede realizar ese proceso. En la primera manera de la cual se proporciona el ejemplo correspondiente se usaran dos archivos, el archivo original y un archivo temporal, el procedimiento o algoritmo es muy sencillo, se lee el registro del archivo original y si no es el registro a eliminar entonces se almacena en el archivo temporal, cuando se termina de procesar todo el archivo original, el archivo temporal solo contendra todos los registros que no se quisieron eliminar, ya con estos dos archivo se procede a eliminar o borrar usando la instruccion remove de el archivo original y se procede a renombrar usando la instrucción rename de el archivo temporal como nuevo archivo original. Ejemplo #include <stdio.h> #include <stdlib.h> #include <io.h> #include <iostream.h> #include <string.h> struct { int matricula; char nombre[30]; int edad;} alumno; Universidad Salesiana de Bolivia Page 50 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO void main() { clrscr(); // cargando clave a eliminar cout("dame matricula eliminar:"); int clave; cin>>("%d",&clave);getchar(); FILE *arch1; FILE *arch2; arch1 = fopen("A:\\alumnos.dat","r+"); arch2 = fopen("A:\\temporal.dat","at+"); // aqui siempre debe empezar el ciclo de lectura // y fread() regresa siempre cuantas estructuras leyo while(fread(&alumno,sizeof(alumno),1,arch1)==1) { if ( clave != alumno.matricula) fwrite(&alumno,sizeof(alumno),1,arch2); }; // aqui termina while //cerrando archivos fclose(arch1); fclose(arch2); // removiendo y renombrando archivos remove("A:\\ALUMNOS.DAT "); rename("A:\\TEMPORAL.DAT","A:\\ALUMNOS.DAT "); //avisando puts("registro eliminado"); getchar(); Universidad Salesiana de Bolivia Page 51 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO } EL problema con esta manera de eliminar incluso fisicamente los registros del archivo es que no hay manera de recuperar esa información posteriormente. Es por eso que otra tecnica común de eliminación es incluir un campo de estado, status o bandera o semaforo en el registro y conforme se va cargando el registro y antes de mandarlo a disco se le agrega a dicho campo el caracter 'A' -->alta, asi que cuando se quiera una baja solo se pondria dicho campo en 'B' y todos los programas de lectura, busqueda y filtros deberan revisar esta campo de estado antes de hacer algo con el registro. 11: EDICION DE REGISTROS Editar registros significa cambiar el contenido de algunos de los campos o columnas por nueva informacíón o para corregir algun error de captura original o para agregar alguna columna que no existia por modificación de la tabla o la base de datos. La solucion es similar a los temas anterior, es decir se ocupan los dos archivos el original y el temporal y ya sea que se modifique una sola clave o se modifiquen todos los registros el ejemplo que se construye va mostrando los registros del archivo y pregunta y modifica o edita el registro pedido. Ejemplo: #include <stdio.h> #include <stdlib.h> #include <io.h> #include <iostream.h> #include <string.h> struct { int matricula; char nombre[30]; int edad;} alumno; void main() { clrscr(); // cargando clave a editar Universidad Salesiana de Bolivia Page 52 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO cout("dame matricula editar:"); int clave; cin>>("%d",&clave);getchar(); FILE *arch1; FILE *arch2; arch1 = fopen("A:\alumnos.dat","r+"); arch2 = fopen("A:\\temporal.dat","at+"); // aqui siempre debe empezar el ciclo de lectura while(fread(&alumno,sizeof(alumno),1,arch1)==1) { if ( clave == alumno.matricula) { cout("dame nuevo nombre :");gets(alumno.nombre); cout("dame nueva edad :");cin>>("%d",&alumno.edad); fwrite(&alumno,sizeof(alumno),1,arch2); } else { fwrite(&alumno,sizeof(alumno),1,arch2); }; }; // aqui termina while //cerrando archivos fclose(arch1); fclose(arch2); // removiendo y renombrando archivos remove("C:\\AC\\ALUMNOS.DAT "); rename("C:\\AC\\TEMPORAL.DAT","C:\\AC\\ALUMNOS.DAT "); // imprimiendo un mensaje puts("REGISTRO EDITADO"); getchar();getchar();} Universidad Salesiana de Bolivia Page 53 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO 12.- REGISTROS Y ARCHIVOS DIRECTOS SE DICE QUE UN ARCHIVO ES DE ACCESO U ORGANIZACION DIRECTA CUANDO PARA ACCEDER A UN REGISTRO N CUALESQUIERA NO SE TIENE QUE PASAR POR LOS N-1 REGISTROS ANTERIIORES. Como se observa de esta definición los archivos directos tienen una gran ventaja( son mucho mas rapidos) cuando se comparan con los archivos de acceso u organizacion secuencial Aunque lo anterior no quiere decir que son mejores que los secuenciales, es decir es el propio problema planteado quien exigira una solucion u otra, por ejemplo si se quiere construir un archivo para almacenar los datos de un guestbook, si se construye de manera directa seria muy rapido pero si lo construimos de manera secuencial, se podran almacenar datos con cantidades de información mas adecuados al problema. Es decir un archivo de acceso directo tiene que tener sus registros o renglones de un tamaño fijo o predeterminado de antemano. Un archivo de acceso directo permite posicionar el apuntador de interno de registros, a cualquier registro determinado sin necesidad de pasar por todos los registros anteriores, usando las siguiente instrucción: fseek(apuntador, long offset, origen); El primer parametro posiciona el apuntador de registro en el byte indicado. Regresa 0 si se pudo posicionar. apuntador = fopen("a:archivo.dat","r+"); fseek (apuntador,(long)(clave)*(sizeof(registro)),0); El segundo parametro long ffset (apuntador); Regresa un valor long indicando la posicion actual del cursor interno de registros de archivo. fseek (apuntador,(long)(clave)*(sizeof(registro)),0); El tercer parámetro origen es el punto de referencia en el archivo respecto del cual ha de efectuarse el movimiento, puede tomar los siguientes valores: 0 ---> SEEK_SET principio del archivo. 1 ---> SEEK_CUR posicion actual. 2 ---> SEEK_END fin del archivo Regresa el apuntador al principio del archivo. Ejemplo para hacer modificaciones, filtros, ediciones y eliminaciones se debe utilizar asi: Universidad Salesiana de Bolivia Page 54 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO fseek(apuntador,(long)(clave)*(sizeof(registro)),0); Ejemplo: busqueda con archivos directos con la estructura alumno #include <stdio.h> #include <iostream.h> #include <string.h> struct { int matricula; char nombre[30]; int edad;} alumno; void main() { clrscr(); // cargando clave a buscar cout("dame clave buscar:"); int claveb; cin>>("%d",&claveb); //abriendo, leyendo,cargando estructura FILE *archdisco; archdisco = fopen("A:\\alumno.dat","at+"); // usar fseek() para posicionarse al principio de registro buscado fseek (archdisco, (long)(claveb)* sizeof(alumno), 0 ); // ahora se lee el registro fread(&alumno,sizeof(alumno),1,archdisco); // desplegando estructura y asegurandose cout("%d ",alumno.matricula); cout("%s ",alumno.nombre); cout("%d ",alumno.edad); Universidad Salesiana de Bolivia Page 55 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO cout("\n"); fclose(archdisco); getchar();getchar(); } Universidad Salesiana de Bolivia Page 56 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO Tema 5. OOP 1.- INTRODUCCION Podemos decir que un objeto es una estructura de datos (coleccion de datos organizados eficientemente para su facil manipulacion en memoria), este objeto contiene los llamados campos, como en registros, campos que pueden ser de diferente tipo. Para declarar y trabajar normalmente con los elementos o campos del objeto se usaran las reglas ampliamente aprendidas para los campos de los tipos registros. #include <iostream.h> #include <stdio.h> class { public : int x; char nombre[30]; }obj; main() { clrscr(); gets(obj.nombre); cin>>("%d",obj.x); puts(obj.nombre); return 0; } En adicion los objetos pueden contener campos especiales llamados metodos. Los metodos son procedimientos o funciones que representan simples campos dentro del objeto. #include <iostream.h> class{ public: Universidad Salesiana de Bolivia Page 57 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO int x; char nombre[30]; int proc1(void) }obj; void main(void) { obj.proc1(); } Un metodo podra recibir parametros, tambien podra accesar a los otros campos del objeto, incluso a otros metodos. class { public: int x; void proc(int y) { for( x = 1; x <= y; x++) cout("Pato); } }obj; void main(void) { obj.proc(5); }; El real poder de OOP es la habilidad que tienen para heredar mucha de su naturaleza a otro objeto. Por ejemplo. Universidad Salesiana de Bolivia Page 58 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO a. Pueden utilizar los elementos o campos del objeto del cual descienden, a esta propiedad se le llama herencia. #include <iostream.h> #include <stdio.h> class papa { public : int x; }; class hijo : public papa { int z; }; void main(void) { hijo hijo1; hijo1.x = 5; cout("%d",hijo1.x); } b. pasar parametros al objeto del cual desciende. #include <iostream.h> #include <stdio.h> class papa { public : void funcion(int x) { cout("%d",x+6); } }; Universidad Salesiana de Bolivia Page 59 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO class hijo : public papa { int z; }; void main(void) { hijo hijo1; hijo1.funcion(5); } c. Si el metodo del padre es una funcion podra recibir dicho valor. #include <iostream.h> #include <stdio.h> class papa { public : int funcion(int n) { return n+5; } }; class hijo : public papa { int z; }; void main(void) { hijo hijo1; char nombre[30]; int parametro; Universidad Salesiana de Bolivia Page 60 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO clrscr(); cout <<"Dame tu nombre.. "; cin >>nombre; cout <<"Dame el parametro"; cin >>parametro; hijo.z = hijo.funcion(parametro); cout <<"\n"<<nombre<<"la funcion regreso : "<<hijo.z; getch(); }; Universidad Salesiana de Bolivia Page 61 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO Tema Adicional LECTURA COMPLEMENTARIA PUNTEROS La utilizacion de punteros es amplio, por lo que podemos mencionar que colabora muy estrechamente al manejo de funciones en cuanto a sus argumentos, Lo mas importante de los punteros es que trabaja con direcciones de memoria, eso hace que muchas veces sea complicado de entender. A pesar de todo esto no hay que tenerles miedo. Casi todos los programas C usan punteros. Si aprendemos a usarlos bien no tendremos mas que algún problema esporádico. La memoria del ordenador Si tienes bien claro lo que es la memoria del ordenador puedes saltarte esta sección. Pero si confundes la memoria con el disco duro o no tienes claro lo que es no te la pierdas. Cuando hablamos de memoria nos estamos refiriendo a la memoria RAM del ordenador. Son unas pastillas que se conectan a la placa base y nada tienen que ver con el disco duro. El disco duro guarda los datos permanentemente (hasta que se rompe) y la información se almacena como ficheros. Nosotros podemos decirle al ordenador cuándo grabar, borrar, abrir un documento, etc. La memoria Ram en cambio, se borra al apagar el ordenador. La memoria Ram la usan los programas sin que el usuario de éstos se de cuenta. Hay otras memorias en el ordenador aparte de la mencionada. La memoria de video (que está en la tarjeta gráfica), las memorias caché (del procesador, de la placa...) y quizás alguna más que ahora se me olvida. Definición de puntero. Un puntero es una variable que contiene una dirección de menoría. Normalmente esta dirección es una posición de otra variable en la memoria. Si una variable conviene la dirección de otra variable, entonces se dice que la primera variable apunta a la segunda. Con un puntero podemos almacenar direcciones de memoria. En un puntero podemos tener guardada la dirección de una variable. Vamos a ver si cogemos bien el concepto de puntero y la diferencia entre éstos y las variables normales. Universidad Salesiana de Bolivia Page 62 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO En el dibujo anterior tenemos una representación de lo que sería la memoria del ordenador. Cada casilla representa un byte de la memoria. Y cada número es su dirección de memoria. La primera casilla es la posición 00001 de la memoria. La segunda casilla la posición 00002 y así sucesivamente. Variable Puntero Vamos a ir como siempre por partes. Primero vamos a ver qué pasa cuando declaramos una variable. Al declarar una variable estamos diciendo al ordenador que nos reserve una parte de la memoria para almacenarla. Cada vez que ejecutemos el programa la variable se almacenará en un sitio diferente, eso no lo podemos controlar, depende de la memoria disponible y otros factores misteriosos. Puede que se almacene en el mismo sitio, pero es mejor no fiarse. Dependiendo del tipo de variable que declaremos el ordenador nos reservará más o menos memoria. Una variable puntero se declara siempre antecediendo el operador *. Su formato es el siguiente: Tipo * nom_var_pun; Donde tipo es cualquiera de los tipos de variables ya conocidos en el lenguaje C, y nom_var_pun es el nombre de la variable puntero. Ejemplo: char *punt; El * (asterisco) sirve para indicar que se trata de un puntero, debe ir justo antes del nombre de la variable, sin espacios. En la variable punt sólo se pueden guardar direcciones de memoria, no se pueden guardar datos. Los operadores punteros Los dos operadores que se utilizan con punteros es el * que sirve para declarar una variable puntero, Y el &, que devuelve la dirección de memoria, Vamos a ver un ejemplo: Declaramos la variable 'a' y obtenemos su valor y dirección. #include <stdio.h> void main() { int a; a = 10; cout( "Dirección de a = %p, valor de a = %i\n", &a, a ); } Universidad Salesiana de Bolivia Page 63 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO Para mostrar la dirección de la variable usamos %p en lugar de %d, sirve para escribir direcciones de punteros y variables. El valor se muestra en hexadecimal. No hay que confundir el valor de la variable con la dirección donde está almacenada la variable. La variable 'a' está almacenada en un lugar determinado de la memoria, ese lugar no cambia mientras se ejecuta el programa. El valor de la variable puede cambiar a lo largo del programa, lo cambiamos nosotros. Ese valor está almacenado en la dirección de la variable. El nombre de la variable es equivalente a poner un nombre a una zona de la memoria. Cuando en el programa escribimos 'a', en realidad estamos diciendo, "el valor que está almacenado en la dirección de memoria a la que llamamos 'a'". Supongamos que ahora declaramos una variable char: char numero = 43. El ordenador nos guardaría por ejemplo la posición 00003 para esta variable. Esta posición de la memoria queda reservada y ya no la puede usar nadie más. Además esta posición a partir de ahora se le llama numero. Como le hemos dado el valor 43 a numero, el valor 43 se almacena en numero, es decir, en la posición 00003. Si ahora usáramos el programa anterior: #include <stdio.h> void main() { int numero; numero = 43; cout( "Dirección de numero = %p, valor de numero = %i\n", &numero, numero ); } El resultado sería: Dirección de numero = 00003, valor de numero = 43 Creo que así ya está clara la diferencia entre el valor de una variable (43) y su dirección (00003). #include <stdio.h> void main() { int numero; int *punt; numero = 43; Universidad Salesiana de Bolivia Page 64 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO punt = &numero cout( "Dirección de numero = %p, valor de numero = %i\n", &numero, numero ); } Explicación: •En la primera int numero reservamos memoria para numero (supongamos que queda como antes, posición 00003). Por ahora numero no tiene ningún valor. •Siguiente línea: int *punt;. Reservamos una posición de memoria para almacenar el puntero. Lo normal es que según se declaran variables se guarden en posiciones contiguas. De modo que quedaría en la posición 00004. Por ahora punt no tiene ningún valor, es decir, no apunta a ninguna variable. Esto es lo que tenemos por ahora: •Tercera línea: numero = 43;. Aquí ya estamos dando el valor 43 a número. Se almacena 43 en la dirección 00003, que es la de número. •Cuarta línea: punt = &numero. Por fin damos un valor a punt. El valor que le damos es la dirección de numero (ya hemos visto que & devuelve la dirección de una variable). Así que punt tendrá como valor la dirección de numero, 00003. Por lo tanto ya tenemos: Cuando un puntero tiene la dirección de una variable se dice que ese puntero apunta a esa variable. Si en vez de querer apuntar a una variable tipo char como en el ejemplo hubiese sido de tipo int: int *punt; Para qué sirve un puntero y cómo se usa Los punteros tienen muchas utilidades, por ejemplo nos permiten pasar argumentos (o parámetros) a una función y modificarlos. También permiten el manejo de cadenas y de arrays. Otro uso importante es que nos permiten acceder directamente a la pantalla, al teclado y a todos los componentes del ordenador. Pero esto ya lo veremos más adelante. Pero si sólo sirvieran para almacenar direcciones de memoria no servirían para mucho. Nos deben dejar también la posibilidad de acceder a esas posiciones de memoria. Para acceder a ellas se usa el operador *, que no hay que confundir con el de la multiplicación. #include <stdio.h> void main() { int numero; int *punt; Universidad Salesiana de Bolivia Page 65 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO numero = 43; punt = &numero cout( "Dirección de numero = %p, valor de numero = %i\n", &numero, *punt ); } Si nos fijamos en lo que ha cambiado con respecto al ejemplo anterior, vemos que para acceder al valor de número usamos *punt en vez de numero. Esto es así porque punt apunta a numero y *punt nos permite acceder al valor al que apunta punt. #include <stdio.h> void main() { int numero; int *punt; numero = 43; punt = &numero *punt = 30; cout( "Dirección de numero = %p, valor de numero = %i\n", &numero, numero ); } Ahora hemos cambiado el valor de numero a través de *punt. En resumen, usando punt podemos apuntar a una variable y con *punt vemos o cambiamos el contenido de esa variable. Un puntero no sólo sirve para apunta a una variable, también sirve para apuntar una dirección de memoria determinada. Esto tiene muchas aplicaciones, por ejemplo nos permite controlar el hardware directamente (en MS-Dos y Windows, no en Linux). Podemos escribir directamente sobre la memoria de video y así escribir directamente en la pantalla sin usar cout. Usando punteros en una comparación Veamos el siguiente ejemplo. Queremos comprobar si dos variables son iguales usando punteros: #include <stdio.h> void main() Universidad Salesiana de Bolivia Page 66 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO { int a, b; int *punt1, *punt2; a = 5; b = 5; punt1 = &a punt2 = &b if ( punt1 == punt2 ) cout( "Son iguales\n" ); } Alguien podría pensar que el if se cumple y se mostraría el mensaje Son iguales en pantalla. Pues no es así, el programa es erróneo. Es cierto que a y b son iguales. También es cierto que punt1 apunta a 'a' y punt2 a 'b'. Lo que queríamos comprobar era si a y b son iguales. Sin embargo con la condición estamos comprobando si punt1 apunta al mismo sitio que punt2, estamos comparando las direcciones donde apuntan. Por supuesto a y b están en distinto sitio en la memoria así que la condición es falsa. Para que el programa funcionara deberíamos usar los asteriscos: #include <stdio.h> void main() { int a, b; int *punt1, *punt2; a = 5; b = 5; punt1 = &a punt2 = &b if ( *punt1 == *punt2 ) cout( "Son iguales\n" ); } Ahora sí. Estamos comparando el contenido de las variables a las que apuntan punt1 y punt2. Debemos tener mucho cuidado con esto porque es un error que se cuela con mucha facilidad. Punteros como argumentos de funciones Universidad Salesiana de Bolivia Page 67 Materia: PROGRAMACION I Docente: Ing. NELA O. BENAVIDEZ IGNACIO Hasta ahora para pasar una variable a una función hacíamos lo siguiente: #include <stdio.h> int suma( int a, int b ) { return a+b: } void main() { int var1, var2; var1 = 5; var2 = 8; cout( "La suma es : %i\n", suma(var1, var2) ); } Bien aquí hemos pasado a la función los parámetros 'a' y 'b' (que no podemos modificar) y nos devuelve la suma de ambos. Supongamos ahora que queremos tener la suma pero además queremos que var1 se haga cero dentro de la función. Para eso haríamos lo siguiente: #include <stdio.h> int suma( int *a, int b ) { *a = 0; return a+b: } void main() { int var1, var2; var1 = 5; var2 = 8; cout( "La suma es: %i y a vale: %i\n", suma(&var1, var2), var1 ); } Universidad Salesiana de Bolivia Page 68