Вы находитесь на странице: 1из 115

UNIVERSIDAD VERACRUZANA

FACULTAD DE INGENIERA MECNICA ELCTRICA

MANUAL DE PROGRAMAS APLICADOS A MTODOS NUMRICOS

TRABAJO PRCTICO EDUCATIVO

PARA ACREDITAR LA EXPERIENCIA EDUCATIV A DE: TRABAJO RECEPCIONAL

P R E S E N T A:

J u an A rtu r o B ad i l l o R i o s J os L u i s Orti z d e l a lu z

DIRECTOR DE TRABAJO PRCTICO EDUCATIVO: ISC. KARLOS REYES ORTEGA

POZA RICA DE HGO; VER.

2011

NDICE
INTRODUCCIN 1

CAPITULO I
JUSTIFICACIN TIPO Y NATURALEZA DEL TRABAJO CARACTERSTICAS Y FUNCIONES ESCENCIALES 3 3 3

CAPITULO II
PROCESOS DEL TRABAJO 6 1.- ECUACIONES LINEALES 1.1.- Definicin y clasificacin 1.2.- Gauss Simple 1.2.1.- Ejemplo propuesto 1.2.2.- Diagrama de Flujo 1.2.3.- Pseudocdigo 1.2.4.- Programas en C 1.2.5.- Demostracin del Programa 1.3.- Gauss Seidel 1.3.1.- Ejemplo propuesto 1.3.2.- Diagrama de Flujo 1.3.3.- Pseudocdigo 1.3.4.- Programas en C 1.3.5.- Demostracin del Programa 1.4.- Gauss Jordan 1.4.1.- Ejemplo propuesto 1.4.2.- Diagrama de Flujo 1.4.3.- Pseudocdigo 1.4.4.- Programas en C 6 6 9 11 13 13 15 16 17 19 20 21 23 25 25 28 30 32

1.4.5.- Demostracin del Programa 2.- ECUACIONES NO LINEALES 2.1.- Definicin y tipos de ecuaciones no lineales 2.2.- Biseccin 2.2.1.- Ejemplo propuesto 2.2.2.- Diagrama de Flujo 2.2.3.- Pseudocdigo 2.2.4.- Programas en C 2.2.5.- Demostracin del Programa 2.3.- Falsa Posicin 2.3.1.- Ejemplo propuesto 2.3.2.- Diagrama de Flujo 2.3.3.- Pseudocdigo 2.3.4.- Programas en C 2.3.5.- Demostracin del Programa 2.4.- Newton-Raphson 2.4.1.- Ejemplo propuesto 2.4.2.- Diagrama de Flujo 2.4.3.- Pseudocdigo 2.4.4.- Programas en C 2.4.5.- Demostracin del Programa 3.- ECUACIONES DIFERENCIALES ORDINARIAS 3.1.- Concepto y clasificacin 3.2.- Euler 3.2.1.- Ejemplo propuesto 3.2.2.- Diagrama de Flujo 3.2.3.- Pseudocdigo

33 34 34 35 36 39 40 41 42 43 45 47 48 49 51 52 53 55 56 56 57 58 58 59 60 64 65

3.2.4.- Programas en C 3.2.5.- Demostracin del Programa 3.3.-Runge-Kutta 3.3.1.- Ejemplo propuesto 3.3.2.- Diagrama de Flujo 3.3.3.- Pseudocdigo 3.3.4.- Programas en C 3.3.5.- Demostracin del Programa 4.- INTEGRACIN 4.1.- Concepto y clasificacin 4.2.- Simpson 1/3 4.2.1.- Ejemplo propuesto 4.2.2.- Diagrama de Flujo 4.2.3.- Pseudocdigo 4.2.4.- Programas en C 4.2.5.- Demostracin del Programa COSTOS

66 67 68 69 71 72 74 75 76 76 76 77 80 81 82 83 84

CAPITULO III
APORTACIONES Y CONTRIBUCIONES AL DESARROLLO BIBLIOGRAFA ANEXOS 86 87 88

INTRODUCCIN Los mtodos numricos son tcnicas mediante las cuales es posible resolver problemas mediante el uso de operaciones aritmticas. Este manual tiene como meta dejar plasmados los mtodos ms importantes que abarca la experiencia educativa de mtodos numricos para la solucin de sistemas de ecuaciones lineales, no lineales y a su vez de derivadas e integrales. Cabe destacar que el objetivo fundamental de este trabajo es ofrecer una gua prctica para que los estudiantes puedan seguir paso a paso la elaboracin de los programas desde el desarrollo de los algoritmos a travs de los diagramas de flujo hasta la realizacin del cdigo fuente pasando por las etapas de compilacin y ejecucin exitosa del programa.

CAPITULO I

JUSTIFICACIN Dada la importancia que tienen los mtodos numricos en ingeniera, el alumno necesita entender y comprender la experiencia educativa no solo desde un enfoque terico sino tambin prctico, entendido esto como la generacin de los programas para aplicar los mtodos aprendidos durante la experiencia educativa, brindndoles as una herramienta que podrn utilizar en el mbito laboral y les permitir ahorrar tiempo y esfuerzo, debido a que mediante la aplicacin de los mtodos numricos es posible manejar sistemas de ecuaciones grandes los cuales de otra forma serian difciles de resolver de forma analtica. Sin embargo, sta materia actualmente no cuenta con un manual para el desarrollo de los programas que apliquen los diferentes mtodos vistos en clase; por tal motivo, ste trabajo pretende ser una gua al momento de cursar esta experiencia y ahorrar tiempo al alumno en la investigacin del programa, desarrollo y aplicacin de los mismos.

TIPO Y NATURALEZA DEL TRABAJO El tipo de trabajo es prctico educativo donde la informacin ser seleccionada y estructurada con el fin de contribuir en el aprendizaje de los estudiantes y como soporte acadmico para los docentes que imparten la experiencia educativa de mtodos numricos dentro de la Universidad Veracruzana, as mismo permitir mejorar las bases para la aplicacin de los mtodos numricos mediante programas los cuales sirven como herramienta para la solucin de problemas en ingeniera. CARACTERSTICAS Y FUNCIONES ESCENCIALES El manual incluir especficamente los temas de mayor inters para los estudiantes de la Facultad de Ingeniera Mecnica Elctrica, los cuales servirn como apoyo al cursar la experiencia educativa de mtodos numricos. La funcin principal de este trabajo, ser proporcionar al alumno las bases para conocer y aplicar los fundamentos de los mtodos numricos para la solucin de problemas de ingeniera, implementando diversos algoritmos a travs de un lenguaje de programacin como el Lenguaje C y de esta manera obtener por consecuencia programas que permitan mejorar el entendimiento de los mtodos numricos.

CAPITULO II

PROCESO DEL TRABAJO

1.- ECUACIONES LINEALES 1.1.- Definicin y clasificacin En este captulo estudiaremos las tcnicas de solucin de sistemas de ecuaciones lineales cuadrados Ax = b. Un sistema de ecuaciones lineales, tambin conocido como sistema lineal de ecuaciones o simplemente sistema lineal, es un conjunto de ecuaciones lineales sobre un cuerpo o un anillo conmutativo. El problema consiste en encontrar los valores desconocidos de las variables x1, x2 y x3 que satisfacen las tres ecuaciones. Para establecer la velocidad de clculo y el "trabajo computacional" en los mtodos directos, se analiza el nmero de operaciones de stos y con base en ello se determinan sus necesidades de memoria. Como consecuencia de lo anterior, se da particular atencin a los sistemas especiales: simtricos, bandeados y dispersos, entre otros. As, estudiaremos los mtodos que aprovechan estas caractersticas para lograr reducir con esto el nmero de operaciones y los requerimientos de mquina. Posteriormente se exponen y se desarrollan tres mtodos numricos aplicados a las ecuaciones lineales como son: Gauss Simple, Gauss Seidel y Gauss Jordan. Dado que el mundo real puede verse como un grupo de objetos o partes trabajando en conjunto o bien conectadas de alguna manera formando un todo, brindar al alumno una mejor comprensin de la extraordinaria cantidad de situaciones que pueden representarse con los sistemas o grupos de ecuaciones donde cada una de ellas corresponde a alguna de sus partes, por ejemplo: en circuitos, estructuras.

1.2.- Gauss Simple Esta tcnica bsica puede extenderse a sistemas grandes de ecuaciones desarrollando un esquema sistemtico o algortmico para eliminar incgnitas y sustituir hacia atrs. La eliminacin de Gauss es el ms bsico de dichos esquemas. Aqu se presentan las tcnicas sistemticas para la eliminacin hacia adelante y la sustitucin hacia atrs que la eliminacin gaussiana comprende. Dado que stas tcnicas son muy adecuadas para utilizarse en computadoras, se requieren algunas modificaciones para obtener un algoritmo confiable. En particular, el programa debe evitar la divisin entre cero. Al siguiente mtodo se le llama eliminacin gaussiana simple, ya que no evita este problema.

El mtodo est ideado para resolver un sistema general de n ecuaciones: a11x1+a12x2+a13x3+.+a1nxn=b1 a21x1+a22x2+a23x3+.+a2nxn=b2 . . . . (Ec. 1.1c) (Ec. 1.1a) (Ec. 1.1b)

an1x1+an2x2+an3x3+.+annxn=bn

Como en el caso de dos ecuaciones, la tcnica para resolver ecuaciones consiste en dos fases: la eliminacin de las incgnitas y su solucin mediante sustitucin hacia atrs. La eliminacin hacia adelante de incgnitas. La primera fase consiste en reducir el conjunto de ecuaciones a un sistema triangular superior (figura 1.1). El paso inicial ser eliminar la primera incgnita, x1, desde la segunda hasta la n-sima ecuacin. Para ello se multiplica la ecuacin (Ec. 1.1) por para obtener

(Ec. 1.2)

Ahora, esta ecuacin se resta de la ecuacin (Ec. 1.2) para dar

Donde el superndice prima indica que los elementos han cambiado sus valores originales

Eliminacin hacia adelante

Sustitucin hacia atrs


Figura 1.1

Las dos fases de la eliminacin de Gauss: eliminacin hacia adelante y sustitucin hacia atrs. Los superndices prima indican el nmero de veces que se han modificado los coeficientes y constantes. El procedimiento se repite despus con las ecuaciones restantes. Por ejemplo, la ecuacin (Ec. 1.1) se puede multiplicar por y el resultado se resta de la tercera ecuacin. Se repite el procedimiento con las ecuaciones restantes y da como resultado el siguiente sistema modificado: a11x1+a12x2+a13x3+.+a1nxn=b1 a22x2+a23x3+.+a2nxn=b2 a32x2+a33x3+.+a3nxn=b3 an2x2+an3x3+.+annxn=bn (Ec. 1.3a) (Ec. 1.3b) (Ec. 1.3c) (Ec. 1.3d)

En los pasos anteriores, la ecuacin (Ec. 1.1a) se llama la ecuacin pivote, y se denomina el coeficiente o elemento pivote. Observe que el proceso de multiplicacin del primer rengln por es equivalente a dividirla entre y multiplicarla por . Algunas veces la operacin de divisin es referida a la normalizacin. Se hace esta distincin porque un elemento pivote cero llega a interferir con la normalizacin al causar una divisin entre cero. Ms adelante se regresar a este punto importante, una vez que se complete la descripcin de la eliminacin de Gauss simple. Ahora se repite el procedimiento antes descrito para eliminar la segunda incgnita en las ecuaciones (Ec. 1.3c) hasta (Ec. 1.3d). Para realizar esto, multiplique la ecuacin (Ec. 1.3b) por y reste el resultado de la ecuacin (Ec. 1.3c). Se realiza la eliminacin en forma similar en las ecuaciones restantes para obtener. a11x1+a12x2+a13x3+.+a1nxn=b1 a22x2+a23x3+.+a2nxn=b2 a33x3+.+a3nxn=b3 . . . .

an2x2+an3x3+.+annxn=bn 8

Donde el superndice biprima indica que los elementos se han modificado dos veces. El procedimiento puede continuar usando las ecuaciones pivote restantes. La ltima manipulacin en esta secuencia es el uso de la sima ecuacin para eliminar el trmino de la -sima ecuacin. Aqu el sistema se habr transformado en un sistema triangular superior

(Ec. 1.4a) (Ec. 1.4b) (Ec. 1.4c) . . . . . (Ec. 1.4d)

1.2.1.- Ejemplo propuesto Para resolver el siguiente conjunto de ecuaciones. Emplee la eliminacin de Gauss (Ec.1.5) (Ec.1.6) (Ec.1.7) Las operaciones se efectuarn usando seis cifras significativas. La primera parte del procedimiento es la eliminacin hacia adelante. Se multiplica la ecuacin (Ec. 1.5) por (0.1)/3 y se resta el resultado de la ecuacin (Ec. 1.6) para obtener

Despus, se multiplica la ecuacin (Ec. 1.5) por (0.3)/3 y se resta de la ecuacin (Ec.1.7) para eliminar ecuaciones es . Luego de efectuar estas operaciones, el sistema de (Ec.1.8) (Ec.1.9) (Ec.1.10)

Para completar la eliminacin hacia adelante, debe eliminarse de la ecuacin (Ec.1.10). Para llevar a cabo esto, se multiplica la ecuacin (Ec.1.9) por 0.190000/7.00333 y se resta el resultado de la ecuacin (Ec.1.10). Esto elimina de la tercera ecuacin y reduce el sistema a una forma triangular superior: (Ec.1.11) (Ec.1.12) (Ec.1.13) Ahora se pueden resolver estas ecuaciones por sustitucin hacia atrs. En primer lugar, de la ecuacin (Ec.1.13) se despeja x3

(Ec.1.14)

Este resultado se sustituye en la ecuacin (Ec.1.12):

7.003332

- 0.293333 (7.00003) = -19.5617

de la que se despeja

(Ec.1.15)

Por ltimo, las ecuaciones (Ec.1.14) y (Ec.1.15) se sustituyen en la (Ec.1.8): 3 - 0.1 (-2.50000) - 0.2 (7.00003) = 7.85

de la que se despeja,

aunque hay un pequeo error de redondeo en la ecuacin (Ec.1.14), los resultados son muy cercanos a la solucin exacta, . Esto se verifica al sustituir los resultados en el sistema de ecuaciones original

10

1.2.2.- Diagrama de flujo

Diagrama de Flujo Gauss Simple eliminacin hacia adelante

11

Diagrama de Flujo Gauss Simple sustitucin hacia atrs

12

1.2.3.- Pseudocdigo a) DO k = 1, n 1 DO i = k + 1, n factor = DO j = k + 1 to n ai,j = ai,j factor . ak,j END DO bi = bi - factor END DO END DO b) xn = bn / an,n DO i=n-1, 1,-1 sum = O DO j = i + 1, n sum = sum + ai,j . xj END DO xi = (bi - sum) / ai, i END DO Pseudocdigo que realiza a) la eliminacin hacia adelante y b) la sustitucin hacia atrs. 1.2.4.- Programas en C Gauss Simple #include <math.h> #include <stdio.h> /*para printf(),scanf()*/ #include <conio.h> /*para getch(),clrscr()*/ //#include <stdlib.h>/*para exit()*/ //#include <dos.h> #define NUMEL 20 #define INTERVALOS 0 float A[25][25], B[25], S[25],X[25]; MAIN printf("\n METODO DE GAUSS SIMPLE"); printf("\n Numero de Ecuaciones = "); scanf("%d",&n); printf("\n Inserte cada uno de los coeficientes\n"); for(i=1;i<=n;i++) { printf("\n Fila %d \n",i); for(j=1;j<=n;j++) { printf(" Ingrese A(%d,%d) = ",i,j); scanf("%f",&A[i][j]); } } printf("\n Inserte cada uno de los terminos independientes\n"); for(i=1;i<=n;i++){ { printf(" Ingrese B(%d) = ",i); scanf("%f",&B[i]); } } 13

printf("\n Tolerancia para el calculo = "); scanf("%f",&tol); Gauss( n,tol, &er ); printf("\n\n RAICES DEL SISTEMA\n "); for(i=1;i<=n;i++){ printf("\n X(%d) = %6.4f",i,X[i]); } printf("\n\n Fin del programa"); getch();

} void Gauss( int n, float tol, int *er){ int i,j; /*

*/

// IMPRESION DE LOS COEFICIENTES RECIBIDOS printf("\n IMPRESION DE COEFICIENTES\n"); for(i=1;i<=n;i++) { printf("\n Fila %d \n",i); for(j=1;j<=n;j++) { printf(" A(%d,%d) = %f",i,j, A[i][j]); } printf("\n"); } getch(); *er = 0; for (i=1;i<=n;i++){ S[i] = abs(A[i][1]); for(j=2;j<=n;j++) if( abs(A[i][j]>S[i])) S[i] = A[i][j]; }

14

1.2.5.- Demostracin del programa

15

1.3.- Gauss Seidel El mtodo de Gauss-Seidel emplea valores iniciales y despus itera para obtener las mejores aproximaciones a la solucin. El mtodo de Gauss-Seidel es particularmente adecuado cuando se tiene gran nmero de ecuaciones. Los mtodos de eliminacin pueden estar sujetos a errores de redondeo. Debido a que el error en el mtodo de Gauss-Seidel es determinado por el nmero de iteraciones, no es un tema que preocupe. Aunque existen ciertos ejercicios donde la tcnica de Gauss-Seidel no converger al resultado correcto, estudiaremos otras ventajas que se tienen dicho mtodo. Una matriz bandeada es una matriz cuadrada en donde la diagonal principal son valores diferentes a cero (valor=1) y los que se encuentran fuera de la diagonal son ceros. Los sistemas bandeados se encuentran con frecuencia en la prctica cientfica y de la ingeniera. Por ejemplo, tales sistemas aparecen en la solucin de ecuaciones diferenciales. Aunque la eliminacin de Gauss o la convencional se emplean para resolver sistemas de ecuaciones bandeados, resultan ser ineficientes, debido a que si el pivoteo no es necesario, ninguno de los elementos fuera de la banda cambiar su valor original igual a cero. As, ser necesario utilizar tiempo y espacio en el almacenamiento y en el manejo de estos ceros intiles. Si se sabe de antemano que el pivoteo no es necesario, se pueden desarrollar algoritmos muy eficientes en los que no intervengan los ceros fuera de la banda. Como en muchos problemas con sistemas bandeados, no se requiere el pivoteo; los algoritmos alternos, que se describirn a continuacin, son los mtodos seleccionados para tal fin. El mtodo de Gauss-Seidel es el mtodo iterativo ms comnmente usado. Suponga que se da un sistema de n ecuaciones:

Suponga que se limita a un conjunto de ecuaciones de 3 x 3. Si los elementos de la diagonal no son todos cero, la primera ecuacin se puede resolver para la segunda para y la tercera para , para obtener (Ec.1.16a) (Ec.1.16b) (Ec.1.16c) Ahora, se puede empezar el proceso de solucin al escoger valores iniciales para las . Una forma simple para obtener los valores iniciales es suponer que todos son cero. Estos ceros se sustituyen en la ecuacin (Ec.1.16a), la cual se utiliza para calcular un nuevo valor Despus, se sustituye este nuevo valor de

junto con el valor previo cero de en la ecuacin (Ec.1.16b) y se calcula el nuevo valor de . Este proceso se repite con la ecuacin (Ec.1.16c) para calcular un nuevo valor de . Despus se regresa a la primera ecuacin y se repite todo el procedimiento hasta que la solucin converja suficientemente cerca de los valores verdaderos. La convergencia se verifica usando el criterio de la siguiente ecuacin de error relativo porcentual. 16

(Ec.1.17)

Para toda las respectivamente.

donde

son las iteraciones actuales y previas

1.3.1.- Ejemplo propuesto Planteamiento del problema. Use el mtodo de Gauss-Seidel para obtener la solucin del sistema usado en el ejemplo:

Recuerde que la verdadera solucin es

Solucin. Primero, despeje la incgnita sobre la diagonal para cada una de las ecuaciones.

(Ec.1.18a) (Ec.1.18b) (Ec.1.18c)

Suponiendo que

son cero, se utiliza la ecuacin (Ec.1.18a) para calcular

Este valor, junto con el valor de calcular

= 0, se sustituye en la ecuacin (Ec.1.18b) para

17

la primera iteracin termina al sustituir los valores calculados para ecuacin (Ec.1.18c) para dar

en la

en la segunda iteracin, se repite el mismo proceso para calcular

El mtodo es, por lo tanto, convergente hacia la verdadera solucin. Es posible aplicar iteraciones adicionales para mejorar los resultados. Sin embargo, es un problema real no se podra saber con anticipacin el resultado correcto. En consecuencia, la ecuacin (Ec.1.17) nos da un medio para estimar el error relativo porcentual. Por ejemplo, para ,

Para los errores estimados son . Observe que, como cuando se determinaron las races de una sola ecuacin, las formulaciones como la ecuacin (Ec.1.17) de Error relativo porcentual, usualmente ofrecen una valoracin conservativa de la convergencia. As, cuando estas se satisfacen aseguran que el resultado se conozca con al menos, la tolerancia especificada por .

18

1.3.2.- Diagrama de flujo

Diagrama de Flujo Gauss Seidel

19

1.3.3.- Pseudocdigo SUBROUTINE Gseid (a, b, n, x, imax, es, lambda) DO i = 1,n dummy = ai.i DO j = 1,n ai,j = ai,j / dummy END DO bi = ai / dummy END DO DO i = 1, n sum = bi DO j = 1, n IF i j THEN sum =sum ai, j *xj END DO xi = sum END DO iter =1 DO centinela = 1 DO i = 1, n old = xi sum = bi DO j = 1, n IF i j THEN sum =sum ai, j *xj END DO xi = lambda * sum +( 1 - lambda) * old IF centinela = 1 AND x1 IF ea END IF END DO iter = iter + 1 IF centinela = 1 OR (iter END DO END Gseid 20 I max) EXIT 0 . THEN ea=ABS (( xi old) / xi )*100. es THEN centinela = 0

1.3.4. - Programas en C GAUSS SEIDEL #include <stdio.h> #include <math.h> #include <iostream.h> #include <conio.h> #define L 10 #define P L MAIN cout<<"\n\n METODO DE GAUSS SEIDEL "; cout<<"\n\n Numero de incognitas Posibles en el sistema: "; scanf("%d",&n); Gauss_Seidel(n); titulo(n); resultados(); cout<<"\n\nLos resultado son "; for(x=0;x<n;x++) { RESULTADOS[x]=X[x]; cout<<"\nX["<<x<<"]= "<<RESULTADOS[x]; } getch(); } void resultados() { int q=0,i=1,t=3,s=n,r=0; int sw=0,w=0,ite=0,h=0; while((sw==0)&&(w<20)) { h=0; while(h<n) { if(tabla[r]==tabla[r+s]) { cont++; } if(cont==n) sw=1; r++; s++; h++; } ite++; w++; } w=ite-1; for(int j=0;j<w;j++) { t=t+2; if((i%10==0)) { textcolor(LIGHTRED+BLINK); gotoxy(5,t-2); cprintf("\n\n ---Presione una tecla para ingresar ala tabla!!! "); getch(); textcolor(GREEN); clrscr(); t=5; titulo(n); } gotoxy(15,t);cout<<i<<""; int y=20,z=0; for(int r=0;r<n;r++) 21

} i++;

gotoxy(y+z,t);cout<<tabla[q]; q++; z=z+10;

void main() {

22

1.3.5.- Demostracin del programa

23

24

1.4.- Gauss Jordan El mtodo de Gauss-Jordan es una variacin de la eliminacin de Gauss. La principal diferencia consiste en que cuando una incgnita se elimina en el mtodo de Gauss-Jordan. sta es eliminada de todas las otras ecuaciones, no slo de las subsecuentes. Adems, todos los renglones se normalizan al dividirlos entre su elemento pivote. De esta forma, el paso de eliminacin genera una matriz identidad en vez de una triangular (figura 1.2). En consecuencia, no es necesario usar la sustitucin hacia atrs para obtener la solucin. El mtodo se ilustra mejor con un ejemplo.

Figura 1.2

Representacin grfica del mtodo de Gauss-Jordan. 1.4.1.- Ejemplo propuesto Mtodo de Gauss-Jordan Para resolver el siguiente conjunto de ecuaciones. Con la tcnica de Gauss-Jordan

Solucin. mentada 3 0.1 0

Primero, exprese los coeficientes y el lado derecho como una matriz au-

-0.1 -0.2 7.85 7 -0.2 -0.3 10 -19.3 71.4

25

Luego normalice el primer rengln, dividindolo entre el elemento pivote, 3, para obtener 1 0.1 0.3 -0.2 -0.0333333 -0.066667 2.61667 7 -0.3 10 -19.3 71.4

El trmino se elimina del segundo rengln restando 0.1 veces al primer rengln del segundo. En forma similar, restando 0.3 veces el primer rengln del tercero, se eliminar el trmino del tercer rengln: 1 0 0 -0.0333333 -0.066667 7.00333 -0.190000 10.0200 2.61667 70.6150

-0.293333 -19.5617

En seguida, se normaliza el segundo rengln dividindolo entre 7.00333: 1 0 0 -0.0333333 1 -0.190000 -0.066667 2.61667 -0.0418848 - 2.79320 10.0200 70.6150

Al reducir los trminos x2 de las ecuaciones primera y tercera se obtiene 1 0 0 0 1 0 -0.0680629 2.52356 -0.0418848 -2.79320 10.01200 70.0843

El tercer rengln se normaliza despus al dividirlo entre 10.0120: 1 0 0 0 -0.0680629 1 0 1 2.52356 7.00003

-0.0418848 -2.79320

26

Por ltimo los trminos obtener 1 0 0 0 1 0 0 0 1 3.00000

se pueden eliminar de la primera y segunda ecuacin para

-2.50001 7.00003

De esta forma, como se muestra en la figura 1.2 la matriz de coeficientes se ha transformado en la matriz identidad, y la solucin se obtiene en el vector del lado derecho. Observe que no se requiere la sustitucin hacia atrs para llegar a la solucin.

27

1.4.2.- Diagrama de Flujo

N,M,I,A,J

Diagrama de Flujo Gauss Jordan

28

SUBROUTINE GAUSS

(N,M,A)

I,PIVOTE,A,J,K,N, M,CERO

Diagrama de Flujo principal Gauss Jordan subrutina

29

1.4.3.- Pseudocdigo SUB Gauss (a, b, n, x, tol, er) DIMENSION s (n) er = 0 DO i =l, n si = ABS (ai,1 ) DO j = 2, n IF ABS (Ai,j) END DO END DO SUB Eliminate (a, s, n, b, tol, er) IF er -1 THEN CALL Substitute (a , n , b, x) END IF END Gauss CALL Eliminate (a, s, n, b, tol, er) DO k = 1, n 1 CALL Pivot (a, b, s, n, k) IF ABS (ak, k/ sk) er = -1 EXIT DO END IF DO i = k +1, n factor = a i, k/ a k, k DO j= k + 1, n ai,j = a i, j - factor*ak,j END DO bi = bi factor * bk END DO END DO IF ABS (ak,k / sk) tol THEN er = -1 END Eliminate tol THEN si THEN si = abs (a i , j)

30

SUB Pivot (a, b, s, n, k) p=k big = ABS(ak,k/sk) DO i i= k + 1, n dummy = ABS(aii,k/sii) IF dummy > big THEN big = dummy p=ii END IF END DO IF p k THEN DO jj = k, n dummy = ap, jj ap, jj = ak, jj ak, jj = dummy END DO dummy = bp bp = bk bk = dummy dummy = sp sp = sk sk = dummy END IF END pivot SUB Substitute (a, n, b, x) xn = bn / an,n DO i = n 1, 1, -1 sum = 0 DO j = i + 1, n sum = sum + ai,j * xj END DO xi = (bi sum) / ai,i END DO END Substitute

31

1.4.4.- Programas en C GAUSS JORDAN #include <math.h> #include <stdio.h> /*para printf(),scanf()*/ #include <conio.h> /*para getch(),clrscr()*/ //#include <stdlib.h>/*para exit()*/ //#include <dos.h> #define NUMEL 20 #define INTERVALOS 0 float A[25][25], B[25], S[25],X[25]; MAIN printf("\n METODO DE GAUSS JORDAN"); printf("\n\n Ingrese el numero de incognitas \n\n Numero de Ecuaciones = "); scanf("%d",&n); printf("\n Inserte cada uno de los coeficientes\n"); for(i=1;i<=n;i++) { printf("\n Fila %d \n",i); for(j=1;j<=n+1;j++) { printf(" Ingrese a(%d,%d) = ",i,j); scanf("%f",&a[i][j]); } } m=n+1; do { if(a[1][1]==0) {k=m-1; for(i=2;i<=k;i++) {if(a[i][1]!=0) {for(j=1;j<=m;j++) { apoyo=a[i][j]; a[i][j]=a[1][j]; a[1][j]=apoyo; } } } } else {for(j=2;j<=m;j++) {for(i=2;i<=n;i++) {b[i-1][j-1]=a[i][j]-a[1][j]*a[i][1]/a[1][1];} } for(j=2;j<=m;j++) {b[n][j-1]=a[1][j]/a[1][1];} m=m-1; for(j=1;j<=m;j++) {for(i=1;i<=n;i++) {a[i][j]=b[i][j];} } } } while(m>1); printf("\n\n RAICES DEL SISTEMA\n "); for(i=1;i<=n;i++) {printf("\n X(%d) = %1.4f",i,a[i][1]);} printf("\n\n Fin del programa"); getch(); } }

32

1.4.5.- Demostracin del programa

33

2.- ECUACIONES NO LINEALES 2.1.- Definicin y tipos de ecuaciones no lineales En este captulo estudiaremos diversos mtodos para resolver ecuaciones no lineales en una incgnita , aprovechando los conceptos bsicos del clculo y las posibilidades grficas y de cmputo de la tecnologa moderna. Sistemticamente a la interpretacin grfica de los mtodos, a fin de mostrar visualmente su funcionamiento y de enriquecer las imgenes asociadas con ellos; de igual manera, se generan tablas en la aplicacin de cada tcnica para analizar el comportamiento numrico y eventualmente detener el proceso. Se ha organizado el material como mtodos de uno y dos puntos, de los segundos el de posicin falsa. Esto, junto con el concepto de orden de convergencia, nos permitir tener los elementos suficientes para seleccionar la tcnica ms adecuada para una situacin dada. Finalizamos el captulo con las tcnicas para resolver ecuaciones polinomiales. El propsito de este captulo es que el estudiante cuente con los elementos bsicos, computacionales y de criterio, apropiados para resolver el problema algebraico clsico de encontrar las races reales y complejas de la ecuacin , en donde las tcnicas algebraicas de "despejar" la incgnita no sean aplicables, como es el caso de , o bien resulten imprcticas. Por ltimo, es importante sealar lo difcil que resulta pensar en un tpico de matemticas o ingeniera que no involucre ecuaciones de esta naturaleza. La solucin de este sistema consta de un conjunto de valores hacen que todas las ecuaciones sean iguales a cero. que simultneamente

Presentamos los mtodos, para el caso en que las ecuaciones simultneas son lineales, es decir, que se puedan expresar en la forma general

donde la b y la a son constantes. A las ecuaciones algebraicas y trascendentales que no se pueden expresar de esta forma se les llama ecuaciones no lineales. Por ejemplo, Y son dos ecuaciones simultneas no lineales con dos incgnitas, expresan en la forma de la ecuacin como y , las cuales se

As, la solucin seran los valores de y de y que hacen a las funciones y iguales a cero. La mayora de los mtodos para determinar tales soluciones son extensiones de los mtodos abiertos para resolver ecuaciones simples.

34

2.2.- Biseccin Al aplicar las tcnicas grficas se observa que cambia de signo a ambos lados de la raz. En general, si es real y contina en el intervalo que va desde hasta y y tienen signos opuestos, es decir, (Ec.2.1) entonces hay al menos una raz real entre y .

Los mtodos de bsqueda incremental aprovechan esta caracterstica localizando un intervalo en el que la funcin cambie de signo. Entonces, la localizacin del cambio de signo (y, en consecuencia, de la raz) se logra con ms exactitud al dividir el intervalo en varios subintervalos. Se investiga cada uno de estos subintervalos para encontrar el cambio de signo. El proceso se repite y la aproximacin a la raz mejora cada vez ms en la medida que los subintervalos se dividen en intervalos cada vez ms pequeos.

Figura 2.1

35

El mtodo de biseccin, conocido tambin como de corte binario, de particin de intervalos o de Bolzano, es un tipo de bsqueda incremental en el que el intervalo se divide siempre a la mitad. Si la funcin cambia de signo sobre un intervalo, se evala el valor de la funcin en el punto medio. La posicin de la raz se determina situndola sobre el punto medio del subintervalo, dentro del cual ocurre un cambio de signo. El proceso se repite hasta obtener una mejor aproximacin. En la figura 2.1 se presenta un algoritmo sencillo para los clculos de la biseccin. En la figura 2.3 se muestra una representacin grfica del mtodo. Los siguientes ejemplos se harn a travs de clculos reales involucrados en el mtodo. 2.2.1.- Ejemplo propuesto Planteamiento del problema. Emplee el mtodo de biseccin para resolver el siguiente problema.

Figura 2.2

El mtodo grfico para determinar las races de una ecuacin Solucin. El primer paso del mtodo de biseccin consiste en asignar dos valores iniciales a la incgnita (en este problema, c) que den valores de con diferentes signos. En la figura 2.2 se observa que la funcin cambia de signo entre los valores 12 y 16. Por lo tanto, la estimacin inicial de la raz se encontrar en el punto medio del intervalo

Dicha aproximacin representa un error relativo porcentual verdadero de (note que el valor verdadero de la raz es 14.7802). A continuacin calculamos el producto de los valores en la funcin en un lmite inferior y en el punto medio:

36

que es mayor a cero y, por lo tanto, no ocurre cambio de signo entre el lmite inferior y el punto medio. En consecuencia, la raz debe estar localizada entre 14 y 16. Entonces, se crea un nuevo intervalo redefiniendo el lmite inferior como 14 y determinando una nueva aproximacin corregida de la raz

Figura 2.3

Una representacin grfica del mtodo de biseccin. La grfica presenta las primeras tres iteraciones del ejemplo 2.2.1 la cual representa un error porcentual verdadero , = 1.5%. Este proceso se repite para obtener una mejor aproximacin. Por ejemplo,

37

Por lo tanto, la raz est entre 14 y 15. El lmite superior se redefine como 15 y la raz estimada para la tercera iteracin se calcula as:

que representa un error relativo porcentual , = 1 .9%. Este mtodo se repite hasta que el resultado sea suficientemente exacto para satisfacer sus necesidades. En el ejemplo anterior, se observa que el error verdadero no disminuye con cada iteracin. Sin embargo, el intervalo donde se localiza la raz se divide a la mitad en cada paso del proceso. Como se estudiar en la siguiente seccin, el ancho del intervalo proporciona una estimacin exacta del lmite superior del error en el mtodo de biseccin.

38

2.2.2.- Diagrama de Flujo

Diagrama de Flujo Biseccin

39

2.2.3.- Pseudocdigo FUNCTION Bisect(xl, xu, es, imax, xr, iter, ea) iter = 0 fl = f(xl) DO xrold = xr xr = (xl + xu) / 2 fr = f( xr ) iter = iter + 1 IF xr 0 THEN ea = ABS((xr xrold) / xr) * 100 END IF test = fl * fr IF test 0 THEN 0 THEN xu = xr ELSE IF test xl = xr fl= fr ELSE ea = 0 END IF IF ea END DO Bisect = xr END Bisect es OR iter imax EXIT

40

2.2.4.- Programas en C BISECCIN #include <math.h> #include <stdio.h> /*para printf(),scanf()*/ #include <conio.h> /*para getch(),clrscr()*/ //#include <stdlib.h>/*para exit()*/ //#include <dos.h> #define NUMEL 20 #define INTERVALOS 0 float A[25][25], B[25], S[25],X[25]; MAIN printf("\n METODO DE BISECCION\n"); printf( " Teclea valor minimo = "); scanf("%f",&xmin); printf("\n"); printf( " Teclea valor maximo = "); scanf("%f",&xmax); printf("\n"); printf( " Teclea valor de error esperado = "); scanf("%f",&error); printf("\n"); printf( " Teclea iteraciones maximas = "); scanf("%f",&iteraciones); printf("\n"); c1 = Bisect(xmin, xmax, error, iteraciones); printf( " Resultado = %f", c1); } getch();

} float Bisect( float x1,float xu, float es, int imax){ int iter; float f1, fr, test; float xold, xr, ea=0; iter = 0; f1 = F(x1, 10, 40, 68.1); do{ xold = xr; xr = (x1+xu)/2; iter = iter +1; if( xr != 0 ){ ea = abs((xr-xold)/xr)*100; } fr = F(xr, 10, 40, 68.1); test = f1*fr; if( test < 0 ){ // Se determina si hay una raiz entre x1 y xr, cambio de signo xu = xr; } else if ( test > 0 ) { x1 = xr; f1 = fr; } else // Se encontro una raiz ea = 0; // imprimimos los resultados printf( " No X1 Xu Xr ea et\n"); printf( " %d %6.3f %6.3f %6.3f %6.3f %6.3f \n", iter, x1, xu, xr, ea ) ; }while( (ea >= es) || (iter<imax)); return xr; } 41

2.2.5.- Demostracin del programa

42

2.3.- Falsa Posicin Aun cuando la biseccin es una tcnica perfectamente vlida para determinar races, su mtodo de aproximacin por "fuerza bruta" es relativamente ineficiente. La falsa posicin es una alternativa basada en una visualizacin grfica.

Un inconveniente del mtodo de biseccin es que al dividir el intervalo de , a en mitades iguales, no se toman en consideracin las magnitudes de y de . Por ejemplo, si de est mucho ms cercana a cero que de , es lgico que la raz se encuentre ms cerca de que de (figura 2.4). Un mtodo alternativo que aprovecha esta visualizacin grfica consiste en unir y con una lnea recta. La interseccin de esta lnea con el eje de las x representa una mejor aproximacin de la raz. El hecho de que se reemplace la curva por una lnea recta da una "falsa posicin" de la raz; de aqu el nombre de mtodo de la falsa posicin, o en latn, regula falsi. Tambin se le conoce como mtodo de interpolacin lineal. Usando tringulos semejantes (fig.2.4) la interseccin de la lnea recta con el eje de las se estima mediante (Ec. 2.2)

en el cual se despeja (Ec. 2.3)

sta es la frmula de la falsa posicin. El valor de

calculado con la ecuacin

(Ec. 2.3), reemplazar, despus, a cualquiera de los dos valores iniciales, o , y da un valor de la funcin con el mismo signo de . De esta manera, los valores o siempre encierran la verdadera raz. El proceso se repite hasta que la aproximacin a la raz sea adecuada. El algoritmo es idntico al de la biseccin (figura 2.1), excepto en que la ecuacin (Ec. 2.3).

43

Figura 2.4

Representacin grfica del mtodo de la falsa posicin con los tringulos semejantes sombreados se obtiene la frmula para el mtodo. Desarrollo del mtodo de la falsa posicin Multiplicando en cruz la ecuacin (2.2) obtenemos Agrupando trminos y reordenando: Dividiendo entre (Ec. 2.3a)

sta es una de las formas del mtodo de la falsa posicin. Observe que permite el clculo de la raz como una funcin de los valores iniciales inferior y superior . sta puede ponerse en una forma alternativa al separar los trminos:

Sumando y restando

en el lado derecho:

44

Agrupando trminos se obtiene

La cual es la misma ecuacin (Ec. 2.3). Se utiliza esta forma porque implica una evaluacin de la funcin y una multiplicacin menos que la ecuacin (Ec. 2.3a). 2.3.1.- Ejemplo propuesto Con el mtodo de la falsa posicin determine la raz de la misma ecuacin analizada en el ejemplo 2.3 [ecuacin (Ec. 2.3a)]. Solucin. Se empieza el clculo con los valores iniciales Primera iteracin: = 12 =16 = 6.0699 = -2.2688 =12 y = 16.

que tiene un error relativo verdadero de 0.89 por ciento. Segunda iteracin: o = -1.5426 Por lo tanto, la raz se encuentra en el primer subintervalo y xr se vuelve ahora el lmite superior para la siguiente iteracin, = 14.9113: = 12 = 14.9113 f

45

el cual tiene errores relativos y verdadero y aproximado de 0.09 y 0.79 por ciento. Es posible realizar iteraciones adicionales para hacer una mejor aproximacin de las races. Se obtiene una idea ms completa de la eficiencia de los mtodos de biseccin y de falsa posicin al observar la figura 3.5 donde se muestra el error relativo porcentual verdadero de los ejemplos 3.3 y 3.3.1. Observe cmo el error decrece mucho ms rpidamente en el mtodo de la falsa posicin que en el de la biseccin, debido a un esquema ms eficiente en el mtodo de la falsa posicin para la localizacin de races. Recuerde que en el mtodo de biseccin el intervalo entre y se va haciendo ms pequeo durante los clculos. Por lo tanto, el intervalo, como se define para la primera iteracin, proporciona una medida del error en este mtodo. ste no es el caso con el mtodo de la falsa posicin, ya que uno de los valores iniciales puede permanecer fijo durante los clculos, mientras que el otro converge hacia la raz. Como en el caso del ejemplo, el extremo inferior permanece en 12, mientras que converge a la raz. En tales casos, el intervalo no se acorta, sino que se aproxima a un valor constante.

Figura 2.5

Comparacin de los errores relativos de los mtodos de biseccin y de falsa posicin

46

2.3.2.- Diagrama de Flujo

Diagrama de Flujo Falsa Posicin

47

2.3.3.- Pseudocdigo FUNCTION ModFalsepos (xl, xu, es, imax, xr, iter, ea) iter = 0 fl = f(xl) fu = f (xu) DO xrold = xr xr = xu fu * (xl xu) / (fl fu) fr = f(xr) iter= iter+1 IF xr END IF test = fl * fr IF test 0 THEN xu = xr fu = f(xu) iu= 0 il = il + 1 IF il xl=xr fl = f (xl) il=0 iu = iu + 1 IF iu ELSE ea = 0 END IF IF ea END DO modFalsepos = xr END Modfalsepos es OR iter imax THEN EXIT 2 THEN fu =fu / 2 2 THEN fl = fl / 2 O THEN ELSE IF test 0 THEN ea = Abs((xr xrold) / xr) * 100

48

2.3.4.- Programas en C #include <math.h> #include <stdio.h> /*para printf(),scanf()*/ #include <conio.h> /*para getch(),clrscr()*/ //#include <stdlib.h>/*para exit()*/ //#include <dos.h> #define NUMEL 20 #define INTERVALOS 0 float A[25][25], B[25], S[25],X[25];

MAIN printf("\n METODO DE FALSA POSICION\n"); printf( " Teclea valor minimo = "); scanf("%f",&xmin); printf("\n"); printf( " Teclea valor maximo = "); scanf("%f",&xmax); printf("\n"); printf( " Teclea valor de error esperado = "); scanf("%f",&error); printf("\n"); printf( " Teclea iteraciones maximas = "); scanf("%f",&iteraciones); printf("\n"); c1 = Bisect(xmin, xmax, error, iteraciones); c1 = FalsePos( xmin, xmax, error, iteraciones); printf( " Resultado = %f", c1); getch(); } }

49

float FalsePos( float x1,float xu, float es, int imax){ int iter=0, i1, iu; float f1, fr, fu, test; float xrold, xr, ea=0; f1 = F(x1, 10, 40, 68.1); fu = F(xu, 10, 40, 68.1); do{ xrold = xr; xr = xu-fu*(x1-xu)/(f1-fu); fr = F(xr,10,40,68.1); iter = iter +1; if ( xr != 0 ) { ea = abs( (xr - xrold)/xr )* 100; } test = f1 * fr; if( test < 0 ) { xu = xr; fu = F(xu, 10, 40, 68.1); iu = 0; i1 = i1 + 1; if ( i1 >= 2 )f1 = f1 / 2; } else if ( test > 0 ){ x1 = xr; f1 = F(x1, 10, 40, 68.1); i1 = 0; iu = iu +1; if( iu >= 2) fu = fu / 2; } else ea=0;

}while( (ea >= es) || (iter<imax)); return xr;

50

2.3.5.- Demostracin del programa

51

2.4.- Newton-Raphson Tal vez, de las frmulas para localizar races, la frmula de Newton-Raphson (figura 2.6) sea la ms ampliamente utilizada. Si el valor inicial para la raz es , entonces se puede trazar una tangente desde el punto [ , ] de la curva. Por lo comn, el punto donde esta tangente cruza al eje x representa una aproximacin mejorada de la raz. El mtodo de Newton-Raphson se deduce a partir de esta interpretacin geomtrica. De la figura 2.4, se tiene que la primera derivada en es equivalente a la pendiente:

Figura 2.6

Representacin grfica del mtodo de Newton Raphson. Se extrapola una tangente a la funcin en [esto es, ] hasta el eje x para obtener una estimacin de la raz en .

(Ec.2.4)

que se reordena para obtener


f f

(Ec.2.5)

La cual se conoce como frmula de Newton-Raphson. 52

2.4.1.- Ejemplo propuesto Planteamiento del problema. Utilice el mtodo de Newton-Raphson para calcular la raz de empleando como valor inicial y se considere como raz real la iteracin en donde exista una similitud de al menos 6 cifras significativas con la iteracin anterior. Solucin. La primera derivada de la funcin es

que se sustituye, junto con la funcin original en la ecuacin (2.5), para tener

53

Empezando con un valor inicial

, se obtuvieron los siguientes resultados:

0 1 2 3 4

100 '

0.500000000 11.8 0.566311003 0.147 0.567143165 0.0000220 0.567143290 <

As, el mtodo converge rpidamente a la raz verdadera. Observe que el error relativo porcentual verdadero en cada iteracin disminuye mucho ms rpido que con la iteracin simple de punto fijo.

54

2.4.2.- Diagrama de Flujo

INICIO

NGRAD,N,M,I,A,A PROX,NRAIZ,X,N MI,B,C,Y,REL

No convergen en NMI iteraciones

Diagrama de Flujo Newton Raphson

55

2.4.3.- Pseudocdigo function newtonIterationFunction(x) { return x - (cos(x) - x^3) / (-sin(x) - 3*x^2) } var x := 0,5 for i from 0 to 99 { print "Iteraciones: " i print "Valor aproximado: " x xold := x x := newtonIterationFunction(x) if x = xold { print "Solucin encontrada!" break } } 2.4.4.- Programas en C NEWTON RAPHSON #include <conio.h> #include <stdio.h> #include <math.h> MAIN printf("\t\tMETODO DE NEWTON RAPHSON"); printf("\n\nintruce valor inicial"); printf("\n\nX="); scanf("%f",&x1); printf("\nIteraciones="); scanf("%d",&I); do { y=exp(-x1)-x1; y2=-1*exp(-x1)-1; xr=x1 - (y/y2); a=((xr-x1)/xr)*100; e=fabs(a); x1=xr; i++; c++; } while(i<I); printf("\n\n\n\nLa raiz aproximada es x%d = %.12f ",c,xr); printf("\n\nError = %.3f",e); getch(); }

56

2.4.3.- Demostracin del programa

57

3.- ECUACIONES DIFERENCIALES ORDINARIAS 3.1.- Concepto y clasificacin En este captulo se estudiarn, las tcnicas numricas de solucin de ecuaciones diferenciales con condiciones iniciales o de frontera, denominados problemas de valor inicial o de frontera, respectivamente. Una ecuacin diferencial ordinaria (comnmente abreviada "EDO") es una relacin que contiene funciones de una sola variable independiente, y una o ms de sus derivadas con respecto a esa variable. Para esto, se inicia formulando tales problemas, y luego, a partir de las ideas de extrapolacin, se plantean mtodos como el de Euler. Ms adelante, en un proceso de ponderacin de pendientes, se obtienen mtodos con diferentes rdenes de exactitud donde no se requiere de derivaciones complicadas de funciones, pagndose como precio de ello un mayor nmero de clculos. Tales mtodos son conocidos como mtodos de Runge-Kutta. Basndose en el proceso de integracin implicado en la solucin de las ecuaciones diferenciales y en la aproximacin de funciones se plantean familias de mtodos denominados de prediccin-correccin. Dado que las ecuaciones diferenciales ordinarias permiten modelar procesos dinmicos tales como: vaciado de recipientes, reactores qumicos, movimientos amortiguados, desarrollos poblacionales e incluso situaciones estticas como la deflexin de vigas y problemas geomtricos. Estas tcnicas analticas son necesarias para ciertas ecuaciones muy particulares. Muchas de las leyes generales de la naturaleza se expresan en el lenguaje de las ecuaciones diferenciales; abundan tambin las aplicaciones en ingeniera, economa, en las mismas matemticas y en muchos otros campos de la ciencia aplicada. Esta gran utilidad de las ecuaciones diferenciales es fcil de explicar; recurdese que si se tiene la funcin su derivada puede interpretarse como la velocidad de cambio de y con respecto a . En cualquier proceso natural, las variables incluidas y sus velocidades de cambio se relacionan entre s mediante los principios cientficos que gobiernan el proceso. El resultado de expresar en smbolos matemticos estas relaciones, a menudo es una ecuacin diferencial.

58

3.2.- Euler Este tema se refiere a la solucin de ecuaciones diferenciales ordinarias de la forma

Recuerde que el mtodo fue de la forma general Nuevo valor = valor anterior + pendiente x tamao de paso o, en trminos matemticos, (Ec.3.2) De acuerdo con esta ecuacin, la pendiente estimada se usa para extrapolar desde un valor anterior a un nuevo valor en una distancia (figura 3.1). Esta frmula se aplica paso a paso para calcular un valor posterior y, por lo tanto, para trazar la trayectoria de la solucin. En otras palabras, se toma la pendiente al inicio del intervalo como una aproximacin de la pendiente promedio sobre todo el intervalo.

Figura 3.1

Ilustracin grfica del mtodo de un paso.

59

La primera derivada ofrece una estimacin directa de la pendiente en

(figura 3.2):

donde es la ecuacin diferencial evaluada en sustituye la ecuacin (Ec.3.1): f

. La estimacin se (Ec.3.2)

Esta frmula se conoce como mtodo de Euler (o de Euler-Cauchy o de punto pendiente). Se predice un nuevo valor de y, usando la pendiente (igual a la primera deriva en el valor original de x) para extrapolar linealmente sobre el tamao de paso h (figura 3.2).

Figura 3.2

Mtodo de Euler. 3.2.1.- Ejemplo propuesto Planteamiento del problema. Con el mtodo de Euler integre numricamente la ecuacin

desde es

hasta con un tamao de paso 0.5. La condicin inicial en . Recuerde que la solucin exacta est dada por la siguiente ecuacin:

60

Solucin. Euler:

Se utiliza la ecuacin (Ec.3.2) para implementar el mtodo de

donde

y la pendiente estimada en

es

Por lo tanto,

La solucin verdadera en

es

As, el error es Et = valor verdadero - valor aproximado o , expresada como error relativo porcentual,
t

= -63.1%. En el segundo paso,

La solucin verdadera en x = 1.0 es 3.0 y, entonces, el error relativo porcentual es 95.8%. El clculo se repite y los resultados se dan en la tabla 3.2.1 y en la figura 3.3. Comparacin de los valores verdadero y aproximado de la integral de y'= -2X3+ 1 2.x2 - 20x + 8.5, con la condicin inicial de que y = 1 en x = 0. Los valores aproximados se calcularon empleando el mtodo de Euler con un tamao de paso de 0.5. El error local se refiere al error en que se incurre sobre un solo paso. ste se calcula con una expansin de la serie de Taylor como en el ejemplo 3.3. El error global es la discrepancia total debida a los pasos anteriores y presentes.

61

Tabla 3.2.1

Error relativo porcentual

X 0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0

Y verdadero 1 .00000 3.21875 3.00000 2.21875 2.00000 2.71875 4.00000 4.71875 3.00000

Y euler 1 .00000 5.25000 5.87500 5.12500 4.50000 4.75000 5.87500 7.12500 7.00000

Global

Local

-63.1 -95.8 131.0 -125.0 -74.7 46.9 -51.0 -133.3

-63.1 -28.0 -1.41 20.5 17.3 4.0 -11.3 -53.0

Figura 3.3

Comparacin de la solucin verdadera con una solucin numrica usando el mtodo de Euler, para la integral de y' = -2X3 + 1 2X2 - 20x + 8.5 desde x = O hasta x = 4 con un tamao de paso de 0.5. La condicin inicial en x = O es y = 1. 62

Observe que aunque el clculo capta la tendencia general de la solucin verdadera, el error resulta considerable. Como se explica en la siguiente seccin, es posible reducir tal error usando un tamao de paso menor.

El ejemplo anterior usa un polinomio simple como ecuacin diferencial con el objetivo de facilitar el siguiente anlisis de error. De esta forma,

En efecto, un caso ms general (y ms comn) implica EDO, donde aparece una funcin que depende tanto de como de ,

Conforme avancemos en esta parte del texto, nuestros ejemplos comprendern EDO que dependen de variables independientes y dependientes.

63

3.2.2.- Diagrama de flujo

Diagrama de Flujo Euler

64

3.2.3.- Pseudocdigo nt rva o xi = 0 xf = 4 var ab s n c a s x = xi y=1 stab c nm ro dx = 0.5 nc= (xf xi) /dx con c on s PRINT x,y ciclo para implementar el mtodo de Euler sp g r s ta os DO i = 1, nc dydx = -2x3 +12x2 20x + 8.5 y = y + dydx . dx x= x + dx PRINT x, y END DO sa a tamao pasos paso c c o t rm na nt grac n

65

3.2.4.- Programas en C EULER #include <iostream.h> #include <iomanip.h> #include <conio.h> #include <math.h> #include <stdlib.h> #include <dos.h> MAIN return (-2*pow(x,3))+(12*pow(x,2))-(20*x)+8.5; case EULER: Lee(x0,xf,y0,h); Euler(x0,xf,y0,h); getch(); break;

case SALIR: gotoxy(34,20);

default:

} cout<<" METODO DE EULER "; gotoxy(10,4); cout<<"Xo = "<<setw(10)<<setprecision(5)<<x0; gotoxy(10,5); cout<<"Xf = "<<setw(10)<<setprecision(5)<<xf; gotoxy(10,6); cout<<"Yo = "<<setw(10)<<setprecision(5)<<y0; gotoxy(10,7); cout<<"h = "<<setw(10)<<setprecision(5)<<h; gotoxy(10,9); cout<<" x y"; gotoxy(9,10); cout<<"----------------------"; cout<<endl; cout<<setw(10) <<setprecision(5) << setiosflags(ios::fixed) << x; cout<<setw(20) <<setprecision(5) << setiosflags(ios::fixed) << y << endl; while(x<xf){ y+=h*f(x,y); x+=h; cout<<setw(10) <<setprecision(5) << setiosflags(ios::fixed) << x <<setw(20) <<setprecision(5) << setiosflags(ios::fixed) << y << endl; } } void Heun(float x0,float xf,float y0,float h) {

} }while(op!=SALIR); return 0;

cout<<"Fin de "<<__FILE__; gotoxy(34,21); cout<<"Espere un momento..."; sleep(1); exit(0); break; gotoxy(34,15); cout<<"Opcion no permitida"; getch(); break;

66

3.2.5. - Demostracin del programa

67

3.3.-Runge-Kutta El mtodo de Runge-Kutta (RK) logra la exactitud del procedimiento de la serie Taylor sin necesitar el clculo de derivadas de orden superior. Existen muchas variantes, pero todas tienen la forma generalizada de la siguiente ecuacin. (Ec.3.3) donde se conoce como la funcin incremento, la cual puede interpretarse como una pendiente representativa en el intervalo. La funcin incremento se escribe en forma general como (Ec.3.4) donde las son constantes y las son (Ec.3.4a) (Ec.3.4b) (Ec.3.4c) . . . (Ec.3.4d)

donde las

son constantes. Observe que las

son relaciones de recurrencia.

Es decir, aparecen en la ecuacin , la cual aparece en la ecuacin , etctera. Como cada es una evaluacin funcional, esta recurrencia vuelve eficiente al mtodo de RK para clculos en computadora. Es posible tener varios tipos de mtodos de Runge-Kutta empleando diferentes nmeros de trminos en la funcin incremento especificada por n. Observe que el mtodo de Runge-Kutta (RK) de primer orden con n=1 es, de hecho, el mtodo de Euler. Una vez que se elige n, se evalan las a, p y q igualando la ecuacin (Ec.3.3) a los trminos en la expansin de la serie de Taylor. As, al menos para las versiones de orden inferior, el nmero de trminos, n, por lo comn representa el orden de la aproximacin. Por ejemplo, en la siguiente seccin, los mtodos RK de segundo orden usan la funcin incremento con dos trminos (n 2).

68

MTODO DE RUNGE KUTTA DE SEGUNDO ORDEN La segunda versin de segundo orden de la ecuacin (Ec.3.3) es (Ec.3.5) donde (Ec.3.5a) (Ec.3.5b) Como se describe a continuacin, los valores de se evalan al igualar la ecuacin (Ec.3.5) con la expansin de la serie de Taylor hasta el trmino de segundo.

3.3.1.- Ejemplo propuesto Comparacin de varios esquemas RK de segundo orden Planteamiento del problema. Utilice el mtodo de Runge Kutta para integrar numricamente la siguiente ecuacin:

Con la condicin inicial de que y = 1 en x = 0. Los valores aproximados se calcularon con el mtodo RK de segundo orden, con un tamao de paso de 0.5.

RUNGE KUTTA DE SEGUNDO ORDEN

0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 . 4.0

1 .0000 3.21875 0 3.00000 2.21875 2.00000 2.71875 4.00000 4.71875 3.00000

1.00000 3.277344 3.101563 2.347656 2.140625 2.855469 4.117188 4.800781 3.031250

0 1.8 3.4.. 5.8 7.0 5.0 2.9 1.7 1.0

69

En el primer intervalo

tambin es igual a 8.5 y

La pendiente promedio se calcula mediante

que se utiliza para predecir

Resolver la siguiente funcin con la condicin inicial en . Los valores aproximados se calcularon utilizando el mtodo de runge kutta con un tamao de paso igual a 1.

2.0000000 6.1946314 14.8439219 33.6771718 75.3389626

2.0000000 6.7010819 16.3197819 37.1992489 83.3377674

0.00 8.18 9.94 10.46 10.62

2.0000000 6.3608655 15.3022367 34.7432761 77.7350962

0.00 2.68 3.09 3.17 3.18

1
2 3 4

70

3.3.2.-Diagrama de flujo

Diagrama de Flujo Runge Kutta

71

3.3.3.- Pseudocdigo a) Programa pr nc pa o man ja or Asigna valores para n= nmero de ecuaciones yi= valores iniciales de n variables dependientes xi= valor inicial de la variable independiente xf= valor final de la variable independiente dx= clculo del tamao de paso xout= intervalo de salida x = xi m= 0 xpm = x DO I = 1, n ypi,m = yi END DO DO xend = x + xout IF (xend h= dx CALL Integrador (x, y, n, h, xend) m=m+1 xpm = x DO i = 1, n ypi,m = yi END DO IF (x LOOP DISPLAY RESULTS END xf) EXIT xf) THEN xend = xf

72

b) Rutina para tomar un paso de salida SUB integrator (x, y, n, h, xend) DO IF (xend x < h) THEN h = xend x CALL RK4 (x, y, n, h) IF (x END DO END SUB c) Mtodo RK de cuarto orden para un sistema de EDO SUB RK4(x, y, n, h) CALL Derivs (x, y, k1) DO i = 1, n ymi = yi + k1i * h / 2 END DO CALL Derivs (x + h / 2, ym, k2) DO i = 1, n ymi = yi + k2i * h / 2 END DO CALL Derivs (x + h / 2, ym, k3) DO i = 1, n yei = yi + k3i * h END DO CALL Derivs (x + h, ye, k4) DO i = 1, n slopei = (k1i + 2* (k2i+k3i)+k4i)/6 yi = yi + slopei * h END DO x=x+h END SUB d) Rutina para determinar derivadas SUB Derivs (x, y, dy) dy1 = dy2 = . END SUB xend) EXIT

73

3.3.4.- Programas en C RUNGE KUTTA #include <iostream.h> #include <iomanip.h> #include <conio.h> #include <math.h> #include <stdlib.h> #include <dos.h> MAIN return 4*exp(0.8*x)-(0.5*y); case RK2: Lee(x0,xf,y0,h); Heun(x0,xf,y0,h); getch(); break;

case SALIR: gotoxy(34,20);

default:

} cout<<"METODO DE HEUN (RK Orden 2)"<<endl; gotoxy(10,4); cout<<"Xo = "<< setw(10) << setprecision(5) <<x0; gotoxy(10,5); cout<<"Xf = "<< setw(10) << setprecision(5) <<xf; gotoxy(10,6); cout<<"Yo = "<< setw(10) << setprecision(5) <<y0; gotoxy(10,7); cout<<"h = "<< setw(10) << setprecision(5) <<h; gotoxy(10,9); cout<<"x y"; gotoxy(9,10); cout<<"----------------------"; cout<<endl; cout<<setw(10) << setprecision(5) << setiosflags(ios::fixed) << x; cout<<setw(20) << setprecision(5) << setiosflags(ios::fixed) << y <<endl; while(x<xf){ k1=h*f(x,y); k2=h*f(x+h,y+k1); y+=(k1/2.0+k2/2.0); x+=h; cout<<setw(10) << setprecision(5) << setiosflags(ios::fixed) << x <<setw(20) << setprecision(5) << setiosflags(ios::fixed) << y <<endl; } } { void rk4(float x0,float xf,float y0,float h)

} }while(op!=SALIR); return 0;

cout<<"Fin de "<<__FILE__; gotoxy(34,21); cout<<"Espere un momento..."; sleep(1); exit(0); break; gotoxy(34,15); cout<<"Opcion no permitida"; getch(); break;

74

3.3.5.- Demostracin del programa

75

4.- INTEGRACIN 4.1.- Concepto y clasificacin En este captulo se abordar el tema clsico de integracin definida. Para ello se utilizarn procesos finitos, en los que a diferencia de los mtodos analticos, donde el concepto de lmite es central y por tanto los procesos infinitos se manejan conjuntos de puntos discretos y haremos pasar por ellos o entre ellos un polinomio, para despus integrar o derivar dicho polinomio. Con esta tcnica podremos integrar y derivar funciones dadas tabularmente o bien funciones analticas muy complejas e, incluso, integrar aq as c a nt gra no st , como s n caso de s n cos s n tc

Adems, dicha tcnica se puede aproximar a la obtencin de integrales dobles y triples. Siendo la derivada la medida de cambio puntual o instantneo y la integral la suma o acumulacin de tales cambios, resulta fundamental en cualquier actividad de ingeniera o ciencias, conocer ambas tcnicas, y no menos importante, darle sentido fsico a los resultados. 4.2.- Simpson 1/3 Una forma de obtener una estimacin ms exacta de una integral consiste en usar polinomios de grado superior para unir los puntos. Por ejemplo, si hay otro punto a la mitad entre y los tres puntos se pueden unir con una parbola (figura 4.1a). Si hay dos puntos igualmente espaciados entre f(a) y f b , los cuatro puntos se pueden unir mediante un polinomio de tercer grado (figura 4.1b). Las frmulas que resultan de tomar las integrales bajo esos polinomios se conocen como reglas de Simpson. La regla de Simpson 1/3 resulta cuando un polinomio de interpolacin de segundo grado se sustituye en la siguiente ecuacin:

Figura 4.1a

a) Descripcin grfica de la regla de Simpson 1/3, que consiste en tomar el rea bajo una parbola que une tres puntos. 76

Figura 4.1b

b) Descripcin grfica de la regla de Simpson 3/8 que consiste en tomar el rea bajo una ecuacin cubica que une cuatro puntos. 4.2.1.- Ejemplo propuesto Si se designan a y b como x0 y x2 respectivamente y f2(x) se representa por un polinomio de Lagrange de segundo grado, la integral se transforma en

Despus de la integracin y de las manipulaciones algebraicas, se obtiene la siguiente frmula: f f f

(Ec.4.1)

77

donde, en este caso, . Esta ecuacin se conoce como regla de Simpson 1/3, y es la segunda frmula de integracin cerrada de Newton-Cotes. La especificacin "1/3" se origina del hecho de que est dividida entre 3 en la ecuacin (Ec.4.1). Una alternativa para obtenerla se integra el polinomio de NewtonGregory para llegar a la misma frmula.

La regla de Simpson 1/3 tambin se puede expresar usando el formato de la siguiente ecuacin:

(Ec.4.2)

Ancho

Altura promedio

donde a b y el punto a la mitad entre a y b , que est dado por (b+a)/2. Observe que, de acuerdo con la ecuacin (Ec.4.2), el punto medio est ponderado por dos tercios; y los dos puntos extremos, por un sexto. Se puede demostrar que la aplicacin a un solo segmento de la regla de Simpson 1/3 tiene un error de truncamiento. f

o como
b a

(Ec.4.3)

donde est en algn lugar en el intervalo de y As, la regla de Simpson 1/3 es ms exacta que la regla del trapecio. No obstante, una comparacin con la ecuacin (21.6) indica que es ms exacta de lo esperado. En lugar de ser proporcional a la tercera derivada, el error es proporcional a la cuarta derivada. Esto es porque, como se muestra en el cuadro 21.3, el trmino del coeficiente de tercer grado se hace cero durante la integracin de la interpolacin polinomial. En consecuencia, la regla de Simpson 1/3 alcanza una precisin de tercer orden aun cuando se base en slo tres puntos.

78

Aplicacin simple de la regla de Simpson 1/3 Planteamiento del problema. Con la ecuacin (Ec.4.2) integre

desde Solucin.

hasta

. Recuerde que la integral exacta es 1.640533

Por lo tanto, la ecuacin (Ec.4.2.2) se utiliza para calcular

Que representa un error exacto de

que es aproximadamente 5 veces ms precisa que una sola aplicacin de la regla del trapecio El error estimado es [(Ec.4.2.2)]

. donde -2400 es el promedio de la cuarta derivada en el intervalo, , debido a que el promedio de la cuarta derivada no es una estimacin exacta de . Sin embargo, como este caso tiene que ver con un polinomio de quinto grado, el resultado concuerda.

79

4.2.2.- Diagrama de flujo

INICIO

n_s, n_p, h, b, a, x_j, j, k, i

Diagrama de Flujo Simpson 1/3

80

4.2.3. - Pseudocdigo a) FUNCTION Simp13 (h, f0, fl, f2) simp13 = 2* h * (f0+4*f1+f2) /6 END Simp13 b) FUNCTION Simp38 (h, f0, fl, f2) simp38 = 3*h* (f0+3*(f1+f2)+f3) /8 END Simp38 c) FUNCION Simp13m (h, n, f) sum = f(0) DO i = 1, n- 2, 2 sum = sum + 4 * fi + 2 * fi+1 END DO sum = sum + 4 * fn-1 + 2 * fn simp13m = h * sum / 3 END Simp13m d) FUNCTION SimpInt (a, b, n, f) h = (b a) / n IF n = 1 THEN sum = trap (h, fn-1,fn) ELSE m=n odd = n / 2 INT(n / 2) IF odd > 0 AND > 1 THEN sum = sum + simp38(h, fn-3, fn-2, fn-1, fn) m=n3 END IF IF m > 1 THEN sum = sum + simp13m(h,m,f) END IF END IF SimpInt =sum END SimpInt 81

4.2.4.- Programas en C #include <stdio.h> /*para printf(),scanf()*/ #include <conio.h> /*para getch(),clrscr()*/ #include <stdlib.h>/*para exit()*/ #include <dos.h> #include <math.h> #define NUMEL 20 #define INTERVALOS 0 float f(float); void _error(int n); MAIN } h=(b-a)/(2*n); S0=S1=0; for(i=1;i<=(2*n-1);++i){ x=a+((double)i)*h; if(!(i%2)) S0+=f(x); else S1+=f(x); } *Area=(h*(f(a)+4*S1+2*S0+f(b))/3.0); printf("\n El area es -> %5.6f",*Area); getch(); } void LeeDatos(int opc) { if(opc==SIMPSON1_3){ clrscr(); printf("\n Metodo de Integracion por 1/3 de Simpson"); printf("\n ========================================"); putchar('\n'); printf("\n Numero de intervalos (PAR) -> "); } scanf("%d",&n); if(n<1){ _error(INTERVALOS); exit(1); } else printf("\n Valor de a =>"); scanf("%f",&a); printf("\n Valor de b =>"); scanf("%f",&b); }

82

4.2.5.- Demostracin del programa

83

COSTOS Para la elaboracin de este manual de programas aplicados a mtodos numricos se recopil informacin de diferentes fuentes: libros e internet pero como herramienta principal, el programa borland c++ versin 5.0 y el costo de operacin de este software fue gratuito ya que la facultad cuenta con esta herramienta y est instalado en el centro de cmputo en nuestra facultad de ingeniera mecnica elctrica.

84

CAPITULO III

APORTACIONES Y CONTRIBUCIONES AL DESARROLLO Una de las razones por la que se elabor este manual, es para que el estudiante tenga como apoyo en la experiencia de mtodos numricos, programas para aplicar los mtodos, brindndoles as una herramienta que podrn utilizar y les permitir ahorrar tiempo y esfuerzo. Con este trabajo prctico educativo se pretende que al estudiante le sea de mucha utilidad y disponga de una herramienta ms, principalmente a los estudiantes de ingeniera que cursen la experiencia educativa de mtodos numricos con el fin de que logre una mayor comprensin de los temas mencionados, utilizando como estrategia de aprendizaje el uso de programas que ayuden a agilizar el procedimiento de los mtodos expuestos en este tema.

86

BIBLIOGRAFA MTODOS NUMRICOS APLICACIN STEVEN C. CHAPRA RAYMOND P. CANALE MTODOS NUMRICOS LUTHE OLVERA SCHUTZ MTODOS NUMRICOS APLICADOS A LA INGENIERA ANTONIO NIEVES PARA INGENIEROS CON PROGRAMAS DE

87

ANEXOS
Anexo A DIAGRAMAS DE FLUJO TERMINAL: Indica el inicio y el fin de un Diagrama de Flujo. DEFINICIN DE VARIABLES: Define todas y cada una de las variables que sern utilizadas en el programa representado en el diagrama de flujo.

PROCESO: Cualquier tipo de operacin que pueda originar cambio de valor, formato o posicin de la informacin almacenada en memoria, operaciones aritmticas, de transferencia, etc.

DECISIN: Indica operaciones lgicas o de comparacin de datos, normalmente dos, y en funcin del resultado de la misma determina cual de los distintos caminos alternativos del programa se debe seguir; normalmente tiene dos salidas respuestas: s o no, pero puede tener ms segn los casos.

ENTRADA: Indica la asignacin de un valor de una variable tomando este valor desde un dispositivo de entrada.

SALIDA: Indica que el resultado ser presentado ya sea por pantalla o por impresora.

88

Anexo B

CICLOS

Ciclos: Son procesos repetitivos los cuales se ejecutan una o ms instrucciones varias veces. Valor Inicial: Se encuentra asignado a una variable la cual es la que controla el ciclo y debe ser de tipo entero, adems tiene el valor de inicio del ciclo. Valor Final: Con este valor indicamos la ltima vez que el ciclo debe ejecutarse. Incremento: Representa la frecuencia en que debe aumentarse la variable. Entrada: Marca el principio o reinicio de las instrucciones que se encuentran dentro del ciclo. Regreso: Indica donde termina el ciclo, en qu momento el proceso se repite. Salida: Indica la finalizacin de la ejecucin de un ciclo.

89

Anexo C PRINCIPIOS DE C En este anexo se ofrece una breve historia del desarrollo del lenguaje C y se consideran tambin sus caractersticas. ORGENES DEL C El proceso de desarrollo del lenguaje C se origina con la creacin de un lenguaje llamado BCPL, que fue desarrollado por Martin Richards. El BCPL tuvo influencia en un lenguaje llamado B, el cual se us en 1970 y fue inventado por Ken Thompson y que permiti el desarrollo de C en 1971, el cual lo invent e implement Dennis Ritchie. Para 1973 el sistema operativo UNIX estaba casi totalmente escrito en C. Durante muchos aos el estndar para C fue la versin 5 del sistema operativo UNIX, documentada en ``The C Programming Language'' escrito por Brian W. Kernighan and Dennis M. Ritchie in 1978 comnmente referido como K&R. Posteriormente se hicieron varias implementaciones las cuales mostraban las siguientes tendencias: Nuevas caractersticas Diferencias de mquinas Diferencias de productos Errores en los compiladores Malas implementaciones Esto origin que en el verano de 1983 se estableciera un comit para resolver estas discrepancias, el cual empez a trabajar en un estndar ANSI C, la cual fue completada en 1988. CARACTERSTICAS DE C Algunas de las caractersticas ms importantes que definen el lenguaje y que han permitido que sea tan popular, como lenguaje de programacin son: Tamao pequeo. Uso extensivo de llamadas a funciones. Comandos breves (poco tecleo). Lenguaje estructurado. Programacin de bajo nivel (nivel bit) Implementacin de apuntadores - uso extensivo de apuntadores para la memoria, arreglos, estructuras y funciones Las diversas razones por la cual se ha convertido en un lenguaje de uso profesional son: El uso de constructores de alto nivel. El poder manejar actividades de bajo-nivel. El generar programas eficientes. La posibilidad de poder ser compilado en una variedad de computadoras, con 90

pocos cambios (portabilidad). Un punto en contra es que tiene una deteccin pobre de errores, lo cual en ocasiones es problemtico para los principiantes. Estructura de un programa en C Un programa de C tiene bsicamente la siguiente forma: Comandos del preprocesador. Definiciones de tipos. Prototipos de funciones - declara el tipo de funcin y las variables pasadas a la misma. Variables Funciones Para un programa se debe tener una funcin main(). Una funcin tiene la forma: tipo nombre_de_la_funcion (parmetros) { variables locales sentencias de C } Si la definicin del tipo es omitida, C asume que la funcin regresa un tipo entero. Nota: Lo anterior puede ser una fuente de problemas en un programa. A continuacin se muestra un primer programa: /* Programa ejemplo */ main() { printf( "Me gusta C\n" ); exit (0); } NOTAS: C requiere un punto y coma al final de cada sentencia. printf es una funcin estndar de C, la cual es llamada en la funcin main(). \n significa salto de lnea. Salida formateada. exit() es tambin una funcin estndar que hace que el programa termine. En el sentido estricto no es necesario ya que es la ltima lnea de main() y de cualquier forma terminar el programa. En caso de que se hubiera llamado a la funcin printf de la siguiente forma: printf(".\n.1\n..2\n...3\n"); La salida tendra la siguiente forma: .1 ..2 ...3

91

VARIABLES C tiene los siguientes tipos de datos simples: Tabla: Tipos de C Tipo Char unsigned char short int Tamao (bytes) Lmite inferior 1 1 2 -Lmite superior --

unsigned short int 2 (long) int Float double 4 4 8

Los tipos de datos bsicos tiene varios modificadores que les preceden. Se usa un modificador para alterar el significado de un tipo base para que encaje con las diversas necesidades o situaciones. Los modificadores son: signed, unsigned, long y short. En los sistemas UNIX todos los tipos int son long int, a menos que se especifique explcitamente short int. Nota: no hay un tipo booleano en C -- se deber usar char, int o an mejor unsigned char. signed, unsigned, long y short pueden ser usados con los tipos char e int. Aunque es permitido el uso de signed en enteros, es redundante porque la declaracin de entero por defecto asume un nmero con signo. Para declarar una variable en C, se debe seguir el siguiente formato: tipo lista_variables; tipo es un tipo vlido de C y lista_variables puede consistir en uno o ms identificadores separados por una coma. Un identificador debe comenzar con una letra o un guin bajo. Ejemplo: int i, j, k; float x,y,z; char ch;

92

DEFINICIN DE VARIABLES GLOBALES Una variable global se declara fuera de todas las funciones, incluyendo a la funcin main(). Una variable global puede ser utilizada en cualquier parte del programa. Por ejemplo: short numero, suma; int numerogr, sumagr; char letra; main() { ... } Es tambin posible pre inicializar variables globales usando el operador de asignacin =, por ejemplo: float suma= 0.0; int sumagr= 0; char letra= 'A'; main() { ... } Que es lo mismo que: float suma; int sumagr; char letra; main() { suma = 0.0; sumagr= 0; letra = 'A'; ... } Dentro de C tambin se permite la asignacin mltiple usando el operador =, por ejemplo: a = b = c = d = 3; ...que es lo mismo, pero ms eficiente que: a = 3; b = 3; c = 3; 93

d = 3;

La asignacin mltiple se puede llevar a cabo, si todos los tipos de las variables son iguales. Se pueden redefinir los tipos de C usando typedef. Como un ejemplo de un simple uso se considera como se crean dos nuevos tipos real y letra. Estos nuevos tipos pueden ser usados de igual forma como los tipos predefinidos de C. typedef float real; typedef char letra; /* Declaracin de variables usando el nuevo tipo */ real suma=0.0; letra sig_letra;

LECTURA Y ESCRITURA DE VARIABLES El lenguaje C usa salida formateada. La funcin printf tiene un carcter especial para formatear (%) -- un carcter enseguida define un cierto tipo de formato para una variable. %c caracteres %s cadena de caracteres %d enteros %f flotantes Por ejemplo: printf("%c %d %f",ch,i,x); La sentencia de formato se encierra entre " ", y enseguida las variables. Asegurarse que el orden de formateo y los tipos de datos de las variables coincidan. scanf() es la funcin para entrar valores a variables. Su formato es similar a printf. Por ejemplo: scanf("%c %d %f %s",&ch, &i, &x, cad); Observar que se antepone & a los nombres de las variables, excepto a la cadena de caracteres. CONSTANTES ANSI C permite declarar constantes. Cuando se declara una constante es un poco parecido a declarar una variable, excepto que el valor no puede ser cambiado. La palabra clave const se usa para declarar una constante, como se muestra a continuacin: const a = 1; int a = 2; Notas: Se puede usar constantes o despus del tipo. 94

Es usual inicializar una constante con un valor, ya que no puede ser cambiada de alguna otra forma.

La directiva del preprocesador #define es un mtodo ms flexible para definir constantes en un programa. Frecuentemente se ve la declaracin const en los parmetros de la funcin. Lo anterior simplemente indica que la funcin no cambiara el valor del parmetro. Por ejemplo, la siguiente funcin usa este concepto: char *strcpy(char *dest, const char *orig); El segundo argumento orig es una cadena de C que no ser alterada, cuando se use la funcin de la biblioteca para copiar cadenas.

OPERADORES ARITMTICOS Lo mismo que en otros lenguajes de programacin, en C se tienen los operadores aritmticos ms usuales (+ suma, - resta, * multiplicacin, / divisin y % mdulo). El operador de asignacin es =, por ejemplo: i=4; ch='y'; Incremento ++ y decremento -- unario. Los cuales son ms eficientes que las respectivas asignaciones. Por ejemplo: x++ es ms rpido que x=x+1. Los operadores ++ y -- pueden ser prefijos o postfijos. Cuando son prefijos, el valor es calculado antes de que la expresin sea evaluada, y cuando es postfijo el valor es calculado despus que la expresin es evaluada. En el siguiente ejemplo, ++z es prefijo y -- es postfijo: int x,y,z; main() { x=( ( ++z ) - ( y-- ) ) % 100; } Que es equivalente a: int x,y,z; main() { z++; x = ( z-y ) % 100; y--; } El operador % (mdulo o residuo) solamente trabaja con enteros, aunque existe una funcin para flotantes. El operador divisin / es para divisin entera y flotantes. Por lo tanto hay que tener cuidado. El resultado de x = 3 / 2; es uno, an si x es declarado como float. La regla es: si ambos argumentos en una divisin son enteros, entonces el resultado es entero. Si se desea obtener la divisin con la fraccin, entonces escribirlo como: x = 3.0 / 2; o x = 3 / 2.0 y an mejor x = 3.0 / 2.0. Por otra parte, existe una forma ms corta para expresar clculos en C. Por ejemplo, si se tienen expresiones como: i = i + 3; o x = x * (y + 2); , pueden ser 95

reescritas como:

Lo cual es equivalente, pero menos eficiente que: Por lo que podemos reescribir las expresiones anteriores como: i += 3; y x *= y + 2; respectivamente.

OPERADORES DE COMPARACIN El operador para probar la igualdad es ==, por lo que se deber tener cuidado de no escribir accidentalmente slo =, ya que: if ( i = j ) ... Es una sentencia legal de C (sintcticamente hablando aunque el compilador avisa cuando se emplea), la cual copia el valor de ``j'' en ``i'', lo cual ser interpretado como VERDADERO, si j es diferente de cero. Diferente es !=, otros operadores son: < menor que, > mayor que, <= menor que o igual a y >= (mayor que o igual a).

OPERADORES LGICOS Los operadores lgicos son usualmente usados con sentencias condicionales o relacionales, los operadores bsicos lgicos son: && Y lgico, || O lgico y! negacin.

ORDEN DE PRECEDENCIA Es necesario ser cuidadosos con el significado de expresiones tales como a + b * c, dependiendo de lo que se desee hacer (a + b) * c o a + (b * c) Todos los operadores tienen una prioridad, los operadores de mayor prioridad son evaluados antes que los que tienen menor prioridad. Los operadores que tienen la misma prioridad son evaluados de izquierda a derecha, por lo que: a-b-c es evaluado como (a - b) - c Prioridad Operador(es) Ms alta ( ) [ ] -> ! ~ ++ -- - (tipo) * & sizeof */% +96

<< >> < <= > >= == != & ^ | && || ? = += -= *= /= Ms baja , De acuerdo a lo anterior, la siguiente expresin: a < 10 && 2 * b < c Es interpretada como: (a < 10) && ( (2 * b) < c ) y a= b= 10 / 5 + 2; como a= (b= ( 10 / 5 ) + 2 );

ESTRUCTURAS CONDICIONALES En este captulo se revisan los distintos mtodos con los que C controla el flujo lgico de un programa. Como se revis en el captulo anterior, los operadores relaciones binarios que se usan son: ==, !=, <, <=, > y >= adems los operadores lgicos binarios: ||, && y el operador lgico unario de negacin !, que slo toma un argumento. Los operadores anteriores son usados con las siguientes estructuras que se muestran.

97

LA SENTENCIA IF Las tres formas como se puede emplear la sentencia if son:

if (condicin) sentencia; ...o if (condicin) sentencia1; else sentencia2; ...o if (condicion1) sentencia1; else if (condicion2) sentencia2; ... else sentencian; El flujo lgico de esta estructura es de arriba hacia abajo. La primera sentencia se ejecutar y se saldr de la estructura if si la primera condicin es verdadera. Si la primera condicin fue falsa, y existe otra condicin, se evala, y si la condicin es verdadera, entonces se ejecuta la sentencia asociada. Si existen ms condiciones dentro de la estructura if, se van evaluando stas, siempre y cuando las condiciones que le precedan sean falsas. La sentencia que est asociada a la palabra reservada else, se ejecuta si todas las condiciones de la estructura if fueron falsas. Por ejemplo: main() { int x, y, w; ........ if (x>0) { z=w; ....... } else { z=y; ....... } }

98

EL OPERADOR ? El operador ternario condicional ? es ms eficiente que la sentencia if. El operador ? tiene el siguiente formato: expresin1 ? expresin 2 : expresion3; Que es equivalente a la siguiente expresin: if (expresin1) then expresin2 else expresin3; Por ejemplo, para asignar el mximo de a y b a la variable z, usando ?, tendramos: z = (a>b) ? a : b; que es lo mismo que: if (a > b) z = a; else z = b; El uso del operador ? para reemplazar las sentencias if ... else no se restringe slo a asignaciones, como en el ejemplo anterior. Se pueden ejecutar una o ms llamadas de funcin usando el operador ? ponindolas en las expresiones que forman los operandos, como en el ejemplo siguiente: f1(int n) { printf("%d ",n); } f2() { printf("introducido\n"); } main() { int t; printf(": "); scanf("%d",&t); /* imprime mensaje apropiado */ t ? f1(t) + f2() : printf("Se dio un cero\n"); }

99

LA SENTENCIA SWITCH Aunque con la estructura if ... else if se pueden realizar comprobaciones mltiples, en ocasiones no es muy elegante, ya que el cdigo puede ser difcil de seguir y puede confundir incluso al autor transcurrido un tiempo. Por lo anterior, C tiene incorporada una sentencia de bifurcacin mltiple llamada switch. Con esta sentencia, la computadora comprueba una variable sucesivamente frente a una lista de constantes enteras o de carcter. Despus de encontrar una coincidencia, la computadora ejecuta la sentencia o bloque de sentencias que se asocian con la constante. La forma general de la sentencia switch es: switch (variable) { case constante1: secuencia de sentencias break; case constante2: secuencia de sentencias break; case constante3: secuencia de sentencias break; ... default: secuencia de sentencias } Donde la computadora ejecuta la sentencia default si no coincide ninguna constante con la variable, esta ltima es opcional. Cuando se encuentra una coincidencia, la computadora ejecuta las sentencias asociadas con el case hasta encontrar la sentencia break con lo que sale de la estructura switch. Las limitaciones que tiene la sentencia switch ... case respecto a la estructura if son: Slo se tiene posibilidad de revisar una sola variable. Con switch slo se puede comprobar por igualdad, mientras que con if puede ser con cualquier operador relacional. No se puede probar ms de una constante por case. La forma como se puede simular el ltimo punto, es no teniendo sentencias asociados a un case, es decir, teniendo una sentencia nula donde slo se pone el caso, con lo que se permite que el flujo del programa caiga al omitir las sentencias, como se muestra a continuacin: switch (letra) { case 'a': case 'e': case 'i': case 'o': case 'u': numvocales++; break; 100

case ' ': numesp++; break; default: numotras++; break; }

ITERACIN En este captulo se revisan los mecanismos de C para repetir un conjunto de instrucciones hasta que se cumple cierta condicin.

LA SENTENCIA FOR La sentencia for tiene el siguiente formato: for ( expresin1; expresin2; expresin3) sentencia; o { bloque de sentencias } En donde expresin1 se usa para realizar la inicializacin de variables, usando una o varias sentencias, si se usan varias sentencias deber usarse el operador, para separarlas. Por lo general, establece el valor de la variable de control del ciclo. expresin2 se usa para la condicin de terminacin del ciclo y expresin3 es el modificador a la variable de control del ciclo cada vez que la computadora lo repite, pero tambin puede ser ms que un incremento. Por ejemplo: int X; main() { for( X=3; X>0; X--) { printf("X=%d\n",X); } }

genera la siguiente salida a pantalla ... X=3 X=2 X=1

101

Todos las siguientes sentencias for son vlidas en C. Las aplicaciones prcticas de tales sentencias no son importantes aqu, ya que tan slo se intenta ilustrar algunas caractersticas que pueden ser de utilidad: for ( x=0; ( (x>3) && (x<9) ); x++ ) for ( x=0, y=4; ( (x>3) && (x<9) ); x++, y+=2) for ( x=0, y=4, z=4000; z; z/=10) En el segundo ejemplo se muestra la forma como mltiples expresiones pueden aparecer, siempre y cuando estn separadas por una coma , En el tercer ejemplo, el ciclo continuar iterando hasta que z se convierta en .

LA SENTENCIA WHILE La sentencia while es otro ciclo o bucle disponible en C. Su formato es: while ( expresin) sentencia; donde sentencia puede ser una sentencia vaca, una sentencia nica o un bloque de sentencias que se repetirn. Cuando el flujo del programa llega a esta instruccin, primero se revisa si la condicin es verdad para ejecutar la(s) sentencia(s), y despus el ciclo while se repetir mientras la condicin sea verdadera. Cuando llega a ser falsa, el control del programa pasa a la lnea que sigue al ciclo. En el siguiente ejemplo se muestra una rutina de entrada desde el teclado, la cual se cicla mientras no se pulse A: main() { char carac; carac = '\0'; while( carac != 'A') carac = getchar(); } Antes de entrar al ciclo se inicializa la variable carac a nulo. Despus pasa a la sentencia while donde se comprueba si carac no es igual a 'A', como sea verdad entonces se ejecuta la sentencia del bucle (carac = getchar();). La funcin getchar() lee el siguiente carcter del flujo estndar (teclado) y lo devuelve, que en nuestro ejemplo es el caracter que haya sido tecleado. Una vez que se ha pulsado una tecla, se asigna a carac y se comprueba la condicin nuevamente. Despus de pulsar A, la condicin llega a ser falsa porque carac es igual a A, con lo que el ciclo termina. De lo anterior, se tiene que tanto el ciclo for, como el ciclo while comprueban la condicin en lo alto del ciclo, por lo que el cdigo dentro del ciclo no se ejecuta siempre.

102

A continuacin mostramos otro ejemplo: main() { int x=3; while( x>0 ) { printf("x = %d\n", x); x--; } } que genera la siguiente salida en pantalla: x=3 x=2 x=1 Como se observa, dentro del ciclo tenemos ms de una sentencia, por lo que se requiere usar la llave abierta y la llave cerrada { ... } para que el grupo de sentencias sean tratadas como una unidad. Como el ciclo while pueda aceptar tambin expresiones, y no solamente condiciones lo siguiente es vlido: while ( x-- ); while ( x = x + 1 ); while ( x += 5 ); Si se usan este tipo de expresiones, solamente cuando el resultado de x--, x=x+1 o x+=5 sea cero, la condicin fallar y se podr salir del ciclo. De acuerdo a lo anterior, podemos realizar una operacin completa dentro de la expresin. Por ejemplo: main() { char carac; carac = '\0'; while ( (carac = getchar()) != 'A' ) putchar(carac); } En este ejemplo se usan las funciones de la biblioteca estndar getchar() -- lee un carcter del teclado y putchar() escribe un carcter dado en pantalla. El ciclo while proceder a leer del teclado y lo mostrar hasta que el carcter A sea ledo. LA SENTENCIA DO-WHILE Al contrario de los ciclos for y while que comprueban la condicin en lo alto del bucle, el bucle do ... while la examina en la parte baja del mismo. Esta caracterstica provoca que un ciclo do ... while siempre se ejecute al menos una 103

vez. La forma general del ciclo es: do { sentencia; } while (condicin); Aunque no son necesarias las llaves cuando slo est presente una sentencia, se usan normalmente por legibilidad y para evitar confusin (respecto al lector, y no del compilador) con la sentencia while. En el siguiente programa se usa un ciclo do ... while para leer nmeros desde el teclado hasta que uno de ellos es menor que o igual a 100: main() { int num; do { scanf("%d", &num); } while ( num>100 ); } Otro uso comn de la estructura do... while es una rutina de seleccin en un men, ya que siempre se requiere que se ejecute al menos una vez. main() { int opc; printf("1. Derivadas\n"); printf("2. Limites\n"); printf("3. Integrales\n"); do { printf(" Teclear una opcion: "); scanf("%d", &opc); switch(opc) { case 1: printf("\tOpcion 1 seleccionada\n\n"); break; case 2: printf("\tOpcion 2 seleccionada\n\n"); break; case 3: printf("\tOpcion 3 seleccionada\n\n"); break; default: printf("\tOpcion no disponible\n\n"); break; } 104

} while( opc != 1 && opc != 2 && opc != 3); } Se muestra un ejemplo donde se reescribe usando do... while uno de los ejemplos ya mostrados. main() { int x=3; do { printf("x = %d\n", x--); } while( x>0 ) ; }

USO DE BREAK Y CONTINUE Como se comento uno de los usos de la sentencia break es terminar un case en la sentencia switch. Otro uso es forzar la terminacin inmediate de un ciclo, saltando la prueba condicional del ciclo. Cuando se encuentra la sentencia break en un bucle, la computadora termina inmediatamente el ciclo y el control del programa pasa a la siguiente sentencia del ciclo. Por ejemplo: main() { int t; for(t=0; t<100; t++) { printf("%d ", t); if (t==10) break; } } Este programa muestra en pantalla los nmeros del 0 al 10, cuando alcanza el valor 10 se cumple la condicin de la sentencia if, se ejecuta la sentencia break y sale del ciclo. La sentencia continue funciona de manera similar a la sentencia break. Sin embargo, en vez de forzar la salida, continue fuerza la siguiente iteracin, por lo que salta el cdigo que falta para llegar a probar la condicin. Por ejemplo, el siguiente programa visualizar slo los nmeros pares: main() { int x; for( x=0; x<100; x++) { if (x%2) continue; printf("%d ",x); 105

} } Finalmente se considera el siguiente ejemplo donde se leen valores enteros y se procesan de acuerdo a las siguientes condiciones. Si el valor que sea ledo es negativo, se desea imprimir un mensaje de error y se abandona el ciclo. Si el valor es mayor que 100, se ignora y se contina leyendo, y si el valor es cero, se desea terminar el ciclo. main() { int valor; while( scanf("%d", &valor) == 1 && valor != 0) { if ( valor<0 ) { printf("Valor no valido\n"); break; /* Salir del ciclo */ } if ( valor>100) { printf("Valor no valido\n"); continue; /* Pasar al principio del ciclo nuevamente */ } printf("Se garantiza que el valor leido esta entre 1 y 100"); } }

ARREGLOS UNIDIMENSIONALES Y MULTIDIMENSIONALES Los arreglos son una coleccin de variables del mismo tipo que se referencian utilizando un nombre comn. Un arreglo consta de posiciones de memoria contigua. La direccin ms baja corresponde al primer elemento y la ms alta al ltimo. Un arreglo puede tener una o varias dimensiones. Para acceder a un elemento en particular de un arreglo se usa un ndice. El formato para declarar un arreglo unidimensional es: tipo nombre_arr [ tamao ] Por ejemplo, para declarar un arreglo de enteros llamado listanum con diez elementos se hace de la siguiente forma: int listanum[10]; En C, todos los arreglos usan cero como ndice para el primer elemento. Por tanto, el ejemplo anterior declara un arreglo de enteros con diez elementos desde listanum[0] hasta listanum[9]. La forma como pueden ser accesados los elementos de un arreglo, es de la siguiente forma: 106

listanum[2] = 15; /* Asigna 15 al 3er elemento del arreglo listanum*/ num = listanum[2]; /* Asigna el contenido del 3er elemento a la variable num */ El lenguaje C no realiza comprobacin de contornos en los arreglos. En el caso de que sobrepase el final durante una operacin de asignacin, entonces se asignarn valores a otra variable o a un trozo del cdigo, esto es, si se dimensiona un arreglo de tamao N, se puede referenciar el arreglo por encima de N sin provocar ningn mensaje de error en tiempo de compilacin o ejecucin, incluso aunque probablemente se provoque el fallo del programa. Como programador se es responsable de asegurar que todos los arreglos sean lo suficientemente grandes para guardar lo que pondr en ellos el programa. C permite arreglos con ms de una dimensin, el formato general es: tipo nombre_arr [ tam1 ][ tam2 ] ... [ tamN]; Por ejemplo un arreglo de enteros bidimensionales se escribir como: int tabladenums[50][50]; Observar que para declarar cada dimensin lleva sus propios parntesis cuadrados. Para acceder los elementos se procede de forma similar al ejemplo del arreglo unidimensional, esto es, tabladenums[2][3] = 15; /* Asigna 15 al elemento de la 3 fila y la 4 columna*/ num = tabladenums[25][16]; A continuacin se muestra un ejemplo que asigna al primer elemento de un arreglo bidimensional cero, al siguiente 1, y as sucesivamente. main() { int t,i,num[3][4]; for(t=0; t<3; ++t) for(i=0; i<4; ++i) num[t][i]=(t*4)+i*1; for(t=0; t<3; ++t) { for(i=0; i<4; ++i) printf("num[%d][%d]=%d ", t,i,num[t][i]); printf("\n"); } } En C se permite la inicializacin de arreglos, debiendo seguir el siguiente formato: tipo nombre_arr[ tam1 ][ tam2 ] ... [ tamN] = {lista-valores}; Por ejemplo: int i[10] = {1,2,3,4,5,6,7,8,9,10}; int num[3][4]={0,1,2,3,4,5,6,7,8,9,10,11};

107

CADENAS A diferencia de otros lenguajes de programacin que emplean un tipo denominado cadena string para manipular un conjunto de smbolos, en C, se debe simular mediante un arreglo de caracteres, en donde la terminacin de la cadena se debe indicar con nulo. Un nulo se especifica como '\0'. Por lo anterior, cuando se declare un arreglo de caracteres se debe considerar un carcter adicional a la cadena ms larga que se vaya a guardar. Por ejemplo, si se quiere declarar un arreglo cadena que guarde una cadena de diez caracteres, se har como: char cadena[11]; Se pueden hacer tambin inicializaciones de arreglos de caracteres en donde automticamente C asigna el carcter nulo al final de la cadena, de la siguiente forma: char nombre_arr[ tam ]="cadena"; Por ejemplo, el siguiente fragmento inicializa cadena con ``hola'': char cadena[5]="hola"; El cdigo anterior es equivalente a: char cadena[5]={'h','o','l','a','\0'}; Para asignar la entrada estndar a una cadena se puede usar la funcin scanf con la opcin %s (observar que no se requiere usar el operador &), de igual forma para mostrarlo en la salida estndar. Por ejemplo: main() { char nombre[15], apellidos[30]; printf("Introduce tu nombre: "); scanf("%s",nombre); printf("Introduce tus apellidos: "); scanf("%s",apellidos); printf("Usted es %s %s\n",nombre,apellidos); } El lenguaje C no maneja cadenas de caracteres, como se hace con enteros o flotantes, por lo que lo siguiente no es vlido: main() { char nombre[40], apellidos[40], completo[80]; nombre="Jos Mara"; /* Ilegal */ apellidos="Morelos y Pavn"; /* Ilegal */ completo="Gral."+nombre+apellidos; /* Ilegal */ } Funciones Una funcin es un conjunto de declaraciones, definiciones, expresiones y sentencias que realizan una tarea especfica. 108

El formato general de una funcin en C es: especificador_de_tipo nombre_de_funcin( lista_de_parmetros ) { variables locales cdigo de la funcin } El especificador_de_tipo indica el tipo del valor que la funcin devolver mediante el uso de return. El valor puede ser de cualquier tipo vlido. Si no se especfica un valor, entonces la computadora asume por defecto que la funcin devolver un resultado entero. No se tienen siempre que incluir parmetros en una funcin. la lista de parmetros puede estar vaca. Las funciones terminan y regresan automticamente al procedimiento que las llam cuando se encuentra la ltima llave}, o bien, se puede forzar el regreso antes usando la sentencia return. Adems del uso sealado la funcin return se usa para devolver un valor. Se examina a continuacin un ejemplo que encuentra el promedio de dos enteros: float encontprom(int num1, int num2) { float promedio; promedio = (num1 + num2) / 2.0; return(promedio); } main() { int a=7, b=10; float resultado; resultado = encontprom(a, b); printf("Promedio=%f\n",resultado); }

FUNCIONES VOID Las funciones void dan una forma de emular, lo que en otros lenguajes se conocen como procedimientos (por ejemplo, en PASCAL). Se usan cuando no requiere regresar un valor. Se muestra un ejemplo que imprime los cuadrados de ciertos nmeros. void cuadrados() { int contador; for( contador=1; contador<10; contador++) printf("%d\n",contador*contador); } main() { 109

cuadrados(); } En la funcin cuadrados no est definido ningn parmetro, y por otra parte tampoco se emplea la sentencia return para regresar de la funcin.

FUNCIONES Y ARREGLOS Cuando se usan un arreglo como un argumento a la funcin, se pasa slo la direccin del arreglo y no la copia del arreglo entero. Para fines prcticos podemos considerar el nombre del arreglo sin ningn ndice como la direccin del arreglo. Considerar el siguiente ejemplo en donde se pasa un arreglo a la funcin imp_rev, observar que no es necesario especificar la dimensin del arreglo cuando es un parmetro de la funcin. void imp_rev(char s[]) { int t; for( t=strlen(s)-1; t>=0; t--) printf("%c",s[t]); } main() { char nombre[]="Facultad"; imp_rev(nombre); } Observar que en la funcin imp_rev se usa la funcin strlen para calcular la longitud de la cadena sin incluir el terminador nulo. Por otra parte, la funcin imp_rev no usa la sentencia return ni para terminar de usar la funcin, ni para regresar algn valor. Se muestra otro ejemplo, float enconprom(int tam, float lista[]) { int i; float suma = 0.0; for ( i=0; i<tam; i++) suma += lista[i]; return(suma/tam); } main() { float numeros[]={2.3, 8.0, 15.0, 20.2, 44.01, -3.0, -2.9}; printf("El promedio de la lista es %f\n", enconprom(7,numeros) ); } 110

Para el caso de que se tenga que pasar un arreglo con ms de una dimensin, no se indica la primera dimensin pero, el resto de las dimensiones deben sealarse. Se muestra a continuacin un ejemplo: void imprtabla(int tamx,int tamy, float tabla[][5]) { int x,y; for ( x=0; x<tamx; x++ ) { for ( y=0; y<tamy; y++ ) printf("t[%d][%d]=%f",x,y,tabla[x][y]); printf("\n"); } } PROTOTIPOS DE FUNCIONES Antes de usar una funcin C debe tener conocimiento acerca del tipo de dato que regresar y el tipo de los parmetros que la funcin espera. El estndar ANSI de C introdujo una nueva (mejor) forma de hacer lo anterior respecto a las versiones previas de C. La importancia de usar prototipos de funciones es la siguiente: Se hace el cdigo ms estructurado y por lo tanto, ms fcil de leer. Se permite al compilador de C revisar la sintaxis de las funciones llamadas. Lo anterior es hecho, dependiendo del alcance de la funcin. Bsicamente si una funcin ha sido definida antes de que sea usada (o llamada), entonces se puede usar la funcin sin problemas. Si no es as, entonces la funcin se debe declarar. La declaracin simplemente maneja el tipo de dato que la funcin regresa y el tipo de parmetros usados por la funcin. Es una prctica usual y conveniente escribir el prototipo de todas las funciones al principio del programa, sin embargo esto no es estrictamente necesario. Para declarar un prototipo de una funcin se indicar el tipo de dato que regresar la funcin, el nombre de la funcin y entre parntesis la lista del tipo de los parmetros de acuerdo al orden que aparecen en la definicin de la funcin. Por ejemplo: int longcad(char []); Lo anterior declara una funcin llamada longcad que regresa un valor entero y acepta una cadena como parmetro.

111

Вам также может понравиться