Fundamentos de Programación 2017-I FUNCIONES La programación modular es una técnica que consiste en dividir un programa en tareas y dar origen a la creación de pequeños programas llamados módulos, subprogramas o subrutinas con la finalidad de simplificar la elaboración y mantenimiento del mismo. En Lenguaje C a cada módulo o subprograma se le conoce como función. 100 Fundamentos de Programación 2017-I Ventaja de la programación modular: Facilita el diseño descendente Se simplifica un algoritmo complejo Cada módulo se puede elaborar de manera independiente La depuración se lleva a cabo en cada módulo Creación de bibliotecas con módulos específicos 101 Fundamentos de Programación 2017-I Función Es un subprograma que realiza una tarea específica que puede o no recibir valores –parámetros-, en lenguaje C se puede devolver valores de tipo puntero, numérico, carácter, un valor nulo y no se pueden regresar arreglos ni estructuras. 102 Fundamentos de Programación 2017-I Ejemplo de funciones sin paso de parámetros: Ejem25. #include<stdio.h> void funcionTexto() /*función secundaria*/ { printf("\nSaludos!!!\n"); } main() /*función principal*/ { funcionTexto(); 103 Fundamentos de Programación 2017-I return 0; } Ejem25a. #include<stdio.h> void funcionTexto();/*prototipo de funcion*/ main() /*función principal*/ { funcionTexto(); return 0; } 104 Fundamentos de Programación 2017-I void funcionTexto() /*función secundaria*/ { printf("\nSaludos!!!\n"); } Ejem26. #include<stdio.h> void suma(); void resta(); void multiplicacion(); void division(); float a=0, b=0, c=0; /*variables globales*/ 105 Fundamentos de Programación 2017-I main() /*función principal*/ { int menu, res; do{ printf("\nSeleccione una opción\n"); printf("\n1 -suma\n"); printf("\n2 -resta\n"); printf("\n3 -multiplicación\n"); printf("\n4 -división\n\n"); scanf("%d",&menu); switch(menu){ 106 Fundamentos de Programación 2017-I case 1: suma(); break; case 2: resta(); break; case 3: multiplicacion(); break; case 4: division(); 107 Fundamentos de Programación 2017-I break; default: printf("\nOpcion no valida\n"); break; } printf("\n\nIngrese 1 si quieres ver el menu nuevamente\\nn"); scanf("%d",&res); }while(res==1); return 0; } void suma() /*función secundaria*/ 108 Fundamentos de Programación 2017-I { printf("\nIngrese dos valores\n"); scanf("%f %f",&a ,&b); c=a+b; printf("\n%f+%f=%f", a, b, c); } void resta() /*función secundaria*/ { printf("\nIngrese dos valores\n"); scanf("%f %f",&a ,&b); c=a-b; 109 Fundamentos de Programación 2017-I printf("\n%f-%f=%f", a, b, c); } void multiplicacion() /*función secundaria*/ { printf("\nIngrese dos valores\n"); scanf("%f %f",&a ,&b); c=a*b; printf("\n%f*%f=%f", a, b, c); } void division() /*función secundaria*/ { 110 Fundamentos de Programación 2017-I printf("\nIngrese dos valores\n"); scanf("%f %f",&a ,&b); if(b!=0){ c=a/b; printf("\n%f/%f=%f", a, b, c); } else printf("\nError!!!\n"); } 111 Fundamentos de Programación 2017-I Funciones con paso de parámetros Estas funciones son las más utilizadas en la programación ya que pueden recibir uno o más valores llamados parámetros y regresan un solo valor de tipo entero, real o carácter. Si se desea regresar un arreglo de carácter es necesario hacerlo desde los parámetros. Los parámetros o valores son enviados del programa principal o de otras funciones. Por lo tanto dentro de la función se realizan solamente las instrucciones. Es importante revisar que el tipo de dato que regresará la 112 Fundamentos de Programación 2017-I función sea del mismo tipo que el valor declarado en el encabezado de la misma. Tipos de parámetros: Formales o ficticios Ejemplo: flot div(int x, int y) Siempre los argumentos formales son variables. 113 Fundamentos de Programación 2017-I Actuales o reales Z=div(a,b) Los argumentos reales pueden ser variables, constantes o una expresión aritmética. 114 Fundamentos de Programación 2017-I Ventajas de usar funciones con parámetros: Reducen el tamaño del código Pueden reutilizarse en otro programa Se pueden crear librerías o bibliotecas personales que incluyan funciones desarrolladas por el propio programador 115 Fundamentos de Programación 2017-I Ejemplo de funciones con paso de parámetros: Ejem27. #include<stdio.h> int funcionEntera(int a) /*función secundaria*/ { int y; y=a*a; return y; } main() /*función principal*/ 116 Fundamentos de Programación 2017-I { int x; x= funcionEntera(5); printf("\n%d\n",x); return 0; } 117 Fundamentos de Programación 2017-I Ejem27a. #include<stdio.h> int funcionEntera(int a); /*prototipo de funcion*/ main() /*función principal*/ { int x; x= funcionEntera(5); printf("\n%d\n",x); return 0; } int funcionEntera(int a) /*función secundaria*/ 118 Fundamentos de Programación 2017-I { int y; y=a*a; return y; } 119 Fundamentos de Programación 2017-I Ejem28. #include<stdio.h> float suma(int a, int b); float resta(int a, int b); float multiplicacion(int a, int b); float division(int a, int b); float c=0; int a, b; main() /*función principal*/ { int menu, res; 120 Fundamentos de Programación 2017-I do{ c=0; printf("\nSeleccione una opción\n"); printf("\n1 -suma\n"); printf("\n2 -resta\n"); printf("\n3 -multiplicación\n"); printf("\n4 -división\n\n"); scanf("%d",&menu); switch(menu){ case 1: printf("\nIngrese dos valores\n"); 121 Fundamentos de Programación 2017-I scanf("%d %d",&a ,&b); c=suma(a,b); printf("\n%d+%d=%f", a, b, c); break; case 2: printf("\nIngrese dos valores\n"); scanf("%d %d",&a ,&b); c=resta(a, b); printf("\n%d-%d=%f", a, b, c); break; case 3: 122 Fundamentos de Programación 2017-I printf("\nIngrese dos valores\n"); scanf("%d %d",&a ,&b); c=multiplicacion(a,b); printf("\n%d*%d=%f", a, b, c); break; case 4: printf("\nIngrese dos valores\n"); scanf("%d %d",&a ,&b); if(b!=0){ c=division(a,b); printf("\n%d/%d=%f", a, b, c); 123 Fundamentos de Programación 2017-I } else printf("\nError\n"); break; default: printf("\nOpcion no valida\n"); break; } printf("\n\nIngrese 1 si quieres ver el menu nuevamente\n\n"); scanf("%d",&res); }while(res==1); 124 Fundamentos de Programación 2017-I return 0; } float suma(int a, int b) /*función secundaria*/ { c=a+b; return c; } float resta(int a, int b) /*función secundaria*/ { c=a-b; return c; 125 Fundamentos de Programación 2017-I } float multiplicacion(int a, int b) /*función secundaria*/ { c=a*b; return c; } float division(int a, int b) /*función secundaria*/ { c=a/b; return c; } 126 Fundamentos de Programación 2017-I Apuntadores La memoria de una PC puede verse como un vector de valores, donde cada una de sus posiciones es referenciada por un número hexadecimal llamado “dirección de memoria”. Los apuntadores son variables cuyo contenido es una dirección de memoria, almacenan la dirección de memoria de otras variables -int, float, char-, por lo que un apuntador apunta a la variables cuyo valor se 127 Fundamentos de Programación 2017-I almacena a partir de la dirección de memoria de contiene. Debido a que los apuntadores trabajan directamente con la memoria, a través de ellos se accede con rapidez a un dato. Los apuntadores solo pueden apuntar a direcciones de memoria del mismo tipo con el que fueron declarados. 128 Fundamentos de Programación 2017-I Declaración de apuntadores: int *ap1; //ap1 apunta a un valor de tipo entero char *ap2; //ap2 apunta a un valor de tipo carácter float *ap3; //ap3 apunta a un valor de tipo real Recuerden que para declarar un apuntador se antepone un *. 129 Fundamentos de Programación 2017-I Operadores unitarios en apuntadores: & Para decir dirección de memoria. * Para decir contenido de la dirección de memoria. 130 Fundamentos de Programación 2017-I Ejem29. #include<stdio.h> main(){ int x=10, *ap1, *ap2; ap1=&x; printf("\n%p", ap1); ap2=ap1; printf("\n%p", ap2); *ap1=20; printf("\n%d", x); } 131 Fundamentos de Programación 2017-I Es posible sumar y restar valores enteros a un apuntador. El resultado de estas operaciones es el desplazamiento de la dirección de memoria hacia adelante (suma) o hacia atrás (resta) por bloques de bytes del tamaño del tipo de dato apuntado por el apuntador. Esto permite recorrer arreglos utilizando apuntadores. 132 Fundamentos de Programación 2017-I Ejem30. #include<stdio.h> main(){ int x=10, *ap1, *ap2; ap1=&x; printf("\n%p", ap1); ap2=ap1+1; printf("\n%p", ap2); *ap1=20; printf("\n%d", x); } 133 Fundamentos de Programación 2017-I Ejem31. #include<stdio.h> main(){ int x=10, y=50, *ap1, *ap2; ap1=&x; printf("\n%p", ap1); ap2=ap1+1; printf("\n%p", ap2); *ap1=20; printf("\n%d", x); *ap2=y; printf("\n%d", *ap2); } 134 Fundamentos de Programación 2017-I Ejem32. #include<stdio.h> main(){ int x=10, y=50, *ap1, *ap2; ap1=&x; printf("\n%p", &x); printf("\n%p", ap1); ap2=&y; printf("\n%p", &y); printf("\n%p", ap2); *ap1=20; printf("\n%d", *ap1); printf("\n%d", x); 135 Fundamentos de Programación 2017-I *ap2=100; printf("\n%d", *ap2); printf("\n%d", y); } Ejem33. #include<stdio.h> main(){ int x=10, y=50, *ap1, *ap2; ap1=&x; ap2=&y; x=y; 136 Fundamentos de Programación 2017-I if(ap1==ap2) printf("\nSon iguales\n"); else printf("\nHola\n"); } Ejem34. #include<stdio.h> main(){ int x=10, y=50, *ap1, *ap2; ap1=&x; 137 Fundamentos de Programación 2017-I ap2=&y; x=y; if(*ap1==*ap2) printf("\nSon iguales\n"); else printf("\nHola\n"); } Ejem35. #include<stdio.h> main(){ int x=10, y=50, *ap1, *ap2; 138 Fundamentos de Programación 2017-I ap1=&x; ap2=&y; x=y; if(&x==&y) printf("\nSon iguales\n"); else printf("\nHola\n"); } 139 Fundamentos de Programación 2017-I Estructuras Una estructura es una colección de una o más variables iguales o de distinto tipo, agrupadas bajo un mismo nombre, es decir un tipo de dato compuesto que permite almacenar un conjunto de datos de diferente tipo -agrupar un grupo de variables relacionadas entre si- que pueden ser tratadas como una unidad –bajo un mismo nombre se definen.- 140 Fundamentos de Programación 2017-I Las estructuras pueden contener tipos simples y tipos compuestos. Simples: variables de tipo carácter, entero y real. Compuestos: variables tipo arreglos y estructuras. Declaración de una estructura. //Global struct nombreEstructura{ variablesInvulocradas; }; 141 Fundamentos de Programación 2017-I O bien //Local struct { variablesInvulocradas; }nombreEstructura; Una vez definida una estructura global, es posible crear variables de ese tipo en la función que se use por ejemplo: struct nombreEstructura nombreVariable; 142 Fundamentos de Programación 2017-I Ejem36. #include<stdio.h> #include<math.h> #define p printf #define s scanf struct polar{ int a, b; }; 143 Fundamentos de Programación 2017-I main(){ struct polar p1; float r, A; p("\t **Programa que lee un numero complejo y obtiene su forma polar**\n"); p("\n Introduce la parte real del número complejo: \n"); s("%i",&p1.a); p("\n Introduce la parte imaginaria del número complejo: \n"); s("%i",&p1.b); r=sqrt(p1.a*p1.a+p1.b*p1.b); A=p1.b/p1.a; A=atan(A); p("\n r es %.3f\n",r); p("\n A es %.3f\n",A);} 144 Fundamentos de Programación 2017-I Ejem37. #include<stdio.h> #include<math.h> #define p printf #define s scanf main(){ struct{ int a, b; }polar; float r, A; p("\t **Programa que lee un numero complejo y obtine su forma polar**\n"); 145 Fundamentos de Programación 2017-I p("\n Introduce la parte real del numero complejo: \n"); s("%i",&polar.a); p("\n Introduce la parte imaginaria del numero complejo: \n"); s("%i",&polar.b); r=sqrt(polar.a*polar.a+polar.b*polar.b); A=polar.b/polar.a; A=atan(A); p("\n r es %.3f\n",r); p("\n A es %.3f\n",A); } 146 Fundamentos de Programación 2017-I Archivos Lectura y Escritura de Datos Los archivos de datos se utilizan cuando el volumen de datos es significativo. En la actualidad, prácticamente todas las aplicaciones requieren almacenar datos en un archivo; por ejemplo, las aplicaciones de los bancos, casas de bolsa, líneas aéreas para la reservación de vuelos y asientos, hospitales, hoteles, escuelas, etc. 147 Fundamentos de Programación 2017-I El formato de los archivos generalmente es de texto o binario y la forma de acceso a los mismos es secuencial o de acceso directo. En los primeros lenguajes de alto nivel como Pascal existía prácticamente una relación directa entre el formato del archivo y el método de acceso utilizado. Sin embargo, las cosas han cambiado con el tiempo, en el lenguaje C existen funciones que permiten trabajar con métodos de acceso directo aun cuando el archivo tenga un formato tipo texto. 148 Fundamentos de Programación 2017-I En los archivos de texto los datos se almacenan en formato texto y ocupan posiciones consecutivas en el dispositivo de almacenamiento secundario. La única forma de acceder a los componentes de un archivo de texto es hacerlo en forma secuencial. Es decir, accediendo al primer componente, luego al segundo, y así sucesivamente hasta llegar al último, y por consiguiente al fin del archivo. Un elemento importante cuando se trabaja con archivos de texto es el área del buffer, que es el lugar donde los datos se almacenan 149 Fundamentos de Programación 2017-I temporalmente mientras se transfieren de la memoria al dispositivo secundario en que se encuentran o viceversa. El lenguaje de programación C no impone restricciones ni formatos específicos para almacenar elementos en un archivo. Además, proporciona un conjunto extenso de funciones de biblioteca para el manejo de archivos. Es importante señalar que antes de trabajar con un archivo debemos abrirlo y cuando terminamos de trabajar con él debemos cerrarlo por seguridad de la información que se haya almacenado. 150 Fundamentos de Programación 2017-I En el lenguaje C un archivo básicamente se abre y cierra de la siguiente forma: /* El siguiente conjunto de instrucciones muestra la sintaxis para abrir y cerrar un archivo en el lenguaje de programación C. */ ... FILE *apuntador_archivo; apuntador_archivo = fopen (nombre_archivo, “tipo_archivo”); if (apuntador_archivo != NULL) { proceso; /* trabajo con el archivo. */ fclose(apuntador_archivo); } 151 Fundamentos de Programación 2017-I else printf(“No se puede abrir el archivo”); ... La primera instrucción: FILE *apuntador_archivo; Indica que apuntador_archivo es un apuntador al inicio de la estructura FILE, área del buffer que siempre se escribe con mayúsculas. 152 Fundamentos de Programación 2017-I Un apuntador a un archivo es un hilo común que unifica el sistema de e/s con un buffer donde se transportan los datos. Señala la información que contiene y define ciertas características sobre él, nombre, estado, posición actual del archivo, etc. Los apuntadores a un archivo se manejan en C como variables de tipo apuntador FILE que define la librería stdio.h 153 Fundamentos de Programación 2017-I La segunda instrucción: apuntador_archivo = fopen (nombre_archivo, “tipo-archivo”); Permite abrir un archivo llamado nombre_archivo que puede ser una variable de tipo cadena de caracteres, o bien, una constante sin extensión o con extensión txt para realizar actividades de tipo_archivo. 154 Fundamentos de Programación 2017-I La función fopen tiene dos argumentos: nombre del archivo tipo de archivo, que puede ser de lectura, escritura, etc. En la siguiente tabla se muestran los diferentes tipos de archivos.- modos- 155 Fundamentos de Programación 2017-I Tipo de archivo –modos“r” Se abre un archivo sólo para lectura. “w” Se abre un archivo sólo para escritura. Si el archivo ya existe, el apuntador se coloca al inicio y sobrescribe, destruyendo al archivo anterior. “a” Se abre un archivo para agregar nuevos datos al final. Si el archivo no existe, crea uno nuevo. “r+” Se abre un archivo para realizar modificaciones. Permite leer y escribir. El archivo tiene que existir. “w+” Se abre un archivo para leer y escribir. Si el archivo existe, el apuntador se coloca al inicio, sobrescribe y destruye el archivo anterior. “a+” Se abre un archivo para lectura y para incorporar nuevos datos al final. Si el archivo no existe, se crea uno nuevo 156 Fundamentos de Programación 2017-I La instrucción: if (apuntador_archivo != NULL) Permite evaluar el contenido del apuntador. Si éste es igual a NULL, implica que el archivo no se pudo abrir, en cuyo caso es conveniente escribir un mensaje para notificar esta situación. Por otra parte, si el contenido del apuntador es distinto de NULL entonces se comienza a trabajar sobre el archivo. 157 Fundamentos de Programación 2017-I La instrucción: fclose (apuntador_archivo); Se utiliza para cerrar el archivo. 158 Fundamentos de Programación 2017-I Funciones fscanf y fprintf Estas funciones se comportan como las funciones de entrada y salida que hemos venido manejando en el curso, scanf y printf respectivamente, solo que operan sobre archivos: Ejemplos fscanf(fileApuntador,"%d",&M[i][j]); //lectura desde un archivo fprintf(fileApuntador,"%d\t",M[i][j]) ;//escritura en un archivo 159 Fundamentos de Programación 2017-I Ejem38./*Leer desde un archivo la matriz M*/ #include<stdio.h> void main(){ FILE *fileApuntador; int M[3][3],i,j; if (fileApuntador!= NULL) { fileApuntador=fopen("matriz1.txt","r"); for (i=0; i<3;i++){ for (j=0; j<3;j++){ fscanf(fileApuntador,"%d",&M[i][j]); } 160 Fundamentos de Programación 2017-I } fclose(fileApuntador); for(i=0;i<3;i++){ for(j=0;j<3;j++){ printf("%d\t",M[i][j]); } printf("\n"); } } else printf("No se puede abrir el archivo"); } 161 Fundamentos de Programación 2017-I Ejem39. /*Crear un archivo que contenga los valores de M*/ #include <stdio.h> main(){ FILE *fA; int M[3][3],i,j,a; fA=fopen("matriz2.txt","w"); for(i=0;i<3;i++){ for(j=0;j<3;j++){ scanf("%d", &M[i][j]); } } 162 Fundamentos de Programación 2017-I for(i=0;i<3;i++){ for(j=0;j<3;j++){ fprintf(fA,"%d\t",M[i][j]); } fprintf(fA,"\n"); } fclose(fA); return 0; } 163 Fundamentos de Programación 2017-I Investigar las siguientes funciones: putchar(); getchar(); gets(); puts(); fgets(); fputs(); 164 Fundamentos de Programación 2017-I Ejem40./*Crear un archivo de tipo texto*/ #include<stdio.h> main(){ FILE *fA; char c; int salto=0; fA=fopen("Texto.txt","w"); while(salto<2){ c=getchar(); fprintf(fA,"%c",c); if(c=='\n'){ salto++; 165 Fundamentos de Programación 2017-I } else{ salto=0; } } fclose(fA); } 166