funciones vactores y matrices

18
UN U DOC LIC FUNCIONE NIVERSIDAD TECNICA DE AMBATO UNIVERSIDAD TECNICA DE AMBATO. FECH CARRERA: CENCIA EN INFORMATICA Y COMPUTACION. MATERIA: PROGRAMACION II PROFESOR: CDA. WILMA GAVILANES. TEMA: ES CON VECTORES Y MATRI REALIZADO POR: EDISSON GOMEZ FECHA: 13/01/2012 1 ICES.

description

conceptos y ejercicios con funciones ejercicios y vectores.

Transcript of funciones vactores y matrices

Page 1: funciones vactores y matrices

UNIVERSIDAD TECNICA DE AMBATO

UNIVERSIDAD TECNICA

DOCENCIA EN INFORMATICA

LICDA.

FUNCIONES CON VECTORES Y MATRICES.

UNIVERSIDAD TECNICA DE AMBATO

UNIVERSIDAD TECNICA

DE AMBATO.

FECH

CARRERA:

DOCENCIA EN INFORMATICA

Y COMPUTACION.

MATERIA:

PROGRAMACION II

PROFESOR:

LICDA. WILMA GAVILANES.

TEMA:

FUNCIONES CON VECTORES Y MATRICES.

REALIZADO POR:

EDISSON GOMEZ

FECHA:

13/01/2012

1

FUNCIONES CON VECTORES Y MATRICES.

Page 2: funciones vactores y matrices

UNIVERSIDAD TECNICA DE AMBATO

2

Funciones

Como vimos anteriormente C tiene como bloque básico la función. main() es una función, printf() otra, y

hay muchas más funciones predefinidas, pero nosotros mismos también podemos definir nuestras propias

funciones. De hecho, es fundamental hacerlo.

Podemos definir una función cualquiera de la misma manera en que definimos la función main(). Basta

con poner su tipo, su nombre, sus argumentos entre paréntesis y luego, entre llaves, su código:

/* Inclusión de archivos */

#include <stdio.h>

void holamundo(void) /*Función donde se ejecuta la lógica del programa*/

{

printf("Hola Mundo\n"); /*imprime la cadena*/

return; /*sale de la función*/

}

int main(void) /*Función principal del programa*/

{

holamundo(); /*llamada a la función que lleva el peso*/

return 0; /*sale del programa: correcto*/

}

Este código es en todo equivalente al "Hola Mundo" original, sólo que nos muestra cómo escribir y cómo

utilizar una función. Y además nos muestra un principio de buena programación: meter las sentencias que

"hacen el trabajo" en otras funciones específicas para sacarlas de main(), dejando en ésta tan sólo un

guión general de lo que hace el programa, no las órdenes específicas. De esta manera se facilita la

comprensión del programa, y por tanto el futuro trabajo de modificarlo.

De la misma manera que tenemos que declarar una variable antes de utilizarla, no es indiferente el orden

en que se sitúen las diferentes funciones en el fichero: las funciones deben declararse antes de ser

llamadas.

Page 3: funciones vactores y matrices

UNIVERSIDAD TECNICA DE AMBATO

3

Igualmente vemos que, para una función void, la sentencia de control return no puede llamarse como

pseudofunción, porque en dicho caso la función void (en nuestro caso holamundo()) devolvería un valor,

cosa que su definición no permite.

Las funciones también permiten recibir tipos de datos, así pues las funciones nos sirven para hacer de un

gran problema pequeñas partes de un problema o sea dividir un gran problema en diferentes problemas

más pequeños. Así que las funciones también pueden retornar un tipo de dato que hemos definido dentro

de la misma.

La definición de una función para sumar dos números sería de la siguiente manera:

#include <stdio.h>

int sumar(int numero1, int numero2); /* prototipo de la función */

int main(void)

{

int suma; /* definimos una variable*/

suma = sumar(5, 3);

/* la variable obtiene el valor retornado de sumar

* puede verse que entre los paréntesis se mandan los valores

* de los números que se desean sumar en este caso 5 y 3

* pueden haberse declarados estos dos números en otras variables

* int dato = 4, valor = 3;

* suma = sumar(dato, valor);

*/

/* imprimimos la suma de los dos números */

printf("La suma es: %d ", suma);

return 0;

}

int sumar(int numero1, int numero2)

Page 4: funciones vactores y matrices

UNIVERSIDAD TECNICA DE AMBATO

4

{

int retsuma; /* creamos la variable a retornar*/

retsuma = numero1 + numero2; /* asignamos a esa variable la suma de número 1 y 2*/

return retsuma; /* retornamos la suma de los números */

}

Paso de Parámetros

Las funciones pueden recibir datos como lo hemos observado, pero existen dos formas importantes de

enviar los datos hacia una función por valor y por referencia, con las cuales observarse que son muy

diferentes y que una puede ser muy diferente de la otra, haciendo modificaciones en nuestro programa.

Por Valor

El paso por valor envía una copia de los parámetros a la función por lo tanto los cambios que se hagan en

ella no son tomados en cuenta dentro de la función main().

Ejemplo:

#include <stdio.h>

void sumar_valor(int numero); /* prototipo de la función */

int main(void)

{

int numero = 57; /* definimos numero con valor de 57*/

sumar_valor(numero); /* enviamos numero a la función */

printf("Valor de numero dentro de main() es: %d\n", numero);

/* podemos notar que el valor de numero se modifica

* sólo dentro de la función sumar_valor pero en la principal

* número sigue valiendo 57

*/

Page 5: funciones vactores y matrices

UNIVERSIDAD TECNICA DE AMBATO

5

return 0;

}

void sumar_valor(int numero)

{

numero++; /* le sumamos 1 al numero */

/* el valor de número recibido se aumenta en 1

* y se modifica dentro de la función sumar_valor()

*/

printf("Valor de numero dentro sumar_valor() es: %d\n", numero);

return;

}

Por Referencia

El paso por referencia se hace utilizando apuntadores. Se envía la dirección de memoria de la variable,

por lo tanto los cambios que haga la función si afectan el valor de la variable.

Ejemplo:

#include <stdio.h>

void sumar_referencia(int *numero); /* prototipo de la función */

int main(void)

{

int numero = 57; /* definimos numero con valor de 57*/

sumar_referencia(&numero); /* enviamos numero a la función */

printf("\nValor de numero dentro de main() es: %d ", numero);

Page 6: funciones vactores y matrices

UNIVERSIDAD TECNICA DE AMBATO

6

/* podemos notar que el valor de numero se modifica

* y que ahora dentro de main() también se ha modificado

* aunque la función no haya retornado ningún valor.

*/

return 0;

}

void sumar_referencia(int *numero)

{

*numero += 1; /* le sumamos 1 al numero */

/* el valor de numero recibido se aumenta en 1

* y se modifica dentro de la función

*/

printf("\nValor de numero dentro sumar_referencia() es: %d", *numero);

return;

}

Variables Locales y Globales

Además de pasar valores a una función, también se pueden declarar tipos de datos dentro de las

funciones, estos tipos de datos declarados dentro de una función solo son accesibles dentro de esta misma

función y se les conocen como variables locales, así pues podemos definir los mismos nombres de

variables en diferentes funciones, ya que estas variables solo son accesibles dentro de esas funciones.

Ejemplo:

#include <stdio.h>

void funcion1()

{

int dato = 53; /* definimos dato en 53*/

char num1 = 'a'; /* num1 vale a */

Page 7: funciones vactores y matrices

UNIVERSIDAD TECNICA DE AMBATO

7

/* imprimimos */

printf("Funcion1, dato=%d, num1=%c\n", dato, num1);

return;

}

void funcion2()

{

int dato = 25; /* definimos dato en 25*/

char num2 = 'z'; /* num2 vale z*/

/* imprimimos */

printf("Funcion2, dato=%d, num2=%c\n", dato, num2);

return;

}

int main(void)

{

funcion1(); /* llamamos a funcion1() */

funcion2(); /* llamamos a funcion2() */

return 0;

}

En este caso la variable dato, esta definida dentro de cada una de las funciones y son totalmente distinta

una de otra y no se puede utilizar fuera de esta, así pues num2 no puede ser utilizada por la funcion1() y

num1 tampoco puede ser utilizada por funcion2().

Existen pues variables que se definen fuera de la función principal main() y fuera de cualquier otra

función creada por nosotros, estas variables se les conoce con el nombre de Variables Globales ya que se

pueden utilizar dentro de main() y dentro de cualquier función creada por nosotros. Ejemplo:

#include <stdio.h>

Page 8: funciones vactores y matrices

UNIVERSIDAD TECNICA DE AMBATO

8

int variable_global = 99; /* inicializamos la variable global */

void funcion();

int main(void)

{

/* imprimimos el valor*/

printf("main(), acceso a variable_global %d\n", variable_global);

/* llamamos a la función */

funcion();

return 0;

}

void funcion()

{

/* imprimimos el valor*/

printf("funcion(), acceso a variable_global %d\n", variable_global);

return;

}

Funciones Recursivas

La recursividad (recursión) es la propiedad por la cual una función se llama a sí misma directa o

indirectamente. La recursión indirecta implica utilizar más de una función.

Se puede considerar la recursividad como una alternativa a la iteración. La recursión permite especificar

soluciones naturales, sencillas, que serían, en caso contrario, difíciles de resolver. Toda función recursiva

debe contemplar un caso base o condición de salida, para terminar, o la recursividad no podrá terminar

nunca.

Una función recursiva podría definirse así:

Page 9: funciones vactores y matrices

UNIVERSIDAD TECNICA DE AMBATO

9

funcion_recursiva( /* parámetros recibidos por la función */ )

{

/* Código */

funcion_recursiva( ); /* llamada a la función misma */

/* Código */

}

Uno de los ejemplos más representativos en la recursividad es el factorial

de un numero ( n) la definición de recursividad del factorial es:

En esta definición, n = 0, es nuestro caso base, que le da fin a la recursividad.

También existen otros tipos de funciones recursivas como lo es el producto de dos números. El producto

de a, b, donde a y b son números enteros positivos seria:

Solución recursiva:

Así pues es:

Podemos ver que la multiplicación de dos números a, b se puede transformar en otro problema más

pequeño multiplicar a por (b-1), el caso base se produce cuando b = 0 y el producto es 0. Ejemplo:

#include <stdio.h>

int producto(int a, int b)

{

if (b == 0) /* caso base */

return 0; /* como b = 0, se retorna 0*/

else

return a + producto (a, b - 1); /* llamada a esta misma función */

}

int main(void)

{

/* en este caso se llama a la función y se imprime directamente*/

printf("%i ", producto( 7, 3));

Page 10: funciones vactores y matrices

UNIVERSIDAD TECNICA DE AMBATO

10

return 0;

}

Vectores

Los vectores son una forma de almacenar datos que permiten contener una serie de valores del mismo

tipo, cada uno de los valores contenidos tiene una posición asociada que se usará para accederlos. Está

posición o índice será siempre un número entero positivo.

En C la cantidad de elementos que podrá contener un vector es fijo, y en principio se define cuando se

declara el vector. Los vectores se pueden declarar de la siguiente forma:

tipo_elemento nombre[largo];

Esto declara la variable nombre como un vector de tipo_elementos que podrá contener largo cantidad de

elementos, y cada uno de estos elemento podrá contener un valor de tipo tipo_elemento.

Por ejemplo:

double valores[128];

En este ejemplo declaramos un vector de 128 elementos del tipo double, los índices de los elementos irían

entre 0 (para el primer elemento y 127 para el último).

De la misma forma que con las otras declaraciones de variables que hemos visto se le puede asignar un

valor iniciar a los elementos.

O también se pueden declarar:

tipo_elemento nombre[largo]={valor_0, valor_1, valor_2};

En caso estamos asignadole valores a los primeros 3 elementos del vector nombre. Notar que largo debe

ser mayor o igual a la cantidad de valores que le estamos asignando al vector, en el caso de ser la misma

cantidad no aporta información, por lo que el lenguaje nos permite escribir:

tipo_elemento nombre[]={valor_0, valor_1, valor_2};

Page 11: funciones vactores y matrices

UNIVERSIDAD TECNICA DE AMBATO

11

Que declarará nombre como el vector de largo 3.

Para acceder a un elemento accederemos a través de su posición. Es decir:

tipo_elemento elemento;

...

elemento = nombre[2];

Asumiendo que tenemos el vector anterior definido estaríamos guardando valor_2 en elemento.

Veamos un ejemplos:

/*

* Ejemplo : El producto escalar de dos vectores

*/

#include <stdio.h>

double producto_escalar(double v1[], double v2[], int d);

int main()

{

const int largo = 3;

double vector_1[] = {5,1,0};

double vector_2[] = {-1,5,3};

double resultado = producto_escalar(vector_1, vector_2, largo);

// imprime el resultado

printf("(%f, %f, %f) . (%f, %f, %f) = %f\n",

vector_1[0], vector_1[1], vector_1[2],

vector_2[0], vector_2[1], vector_2[2],

resultado);

return 0;

}

Page 12: funciones vactores y matrices

UNIVERSIDAD TECNICA DE AMBATO

12

/* producto escalar entre dos vectores */

double producto_escalar(double v1[], double v2[], int d)

{

double resultado = 0;

int i;

for (i=0; i < d; i++) {

resultado += v1[i] * v2[i];

}

return resultado;

}

En el ejemplo anterior usamos los vectores de C para representar vectores matemáticos y calcular el

producto vectorial entre ellos. Una peculiaridad que se puede notar es que al recibir un arreglo en una

función no se especifica el largo, volveremos a esto en un capítulo posterior.

En resumen, suponiendo que v[n] es un vector de cualquier tipo de dato con n cantidad de posiciones, al

vector v se le aplican las siguientes reglas:

1. La primera posición siempre será v[0]

2. La última posición es v[n-1]

3. En versiones previas a C99 n es una constante definida antes de la declaración de v[n]

Matrices

Observación

No confundir el paso de una matriz en su conjunto (multidimensional o no) como argumento de una

función, con el paso de un elemento de una matriz. Ejemplo:

int dias[2][12] = {

{31,28,31,30,31,30,31,31,30,31,30,31},

{31,29,31,30,31,30,31,31,30,31,30,31} };

....

x = fun1(dias, f, c, d, e); // paso de matriz

z = fun2(dias[f][c], d, e); // paso de elemento

Page 13: funciones vactores y matrices

UNIVERSIDAD TECNICA DE AMBATO

13

Sinopsis

Cuando hay que pasar una matriz bidimensional como argumento a una función, la declaración de

parámetros formales de esta debe incluir el número de columnas, ya que la función receptora debe conoce

la estructura interna de la matriz, para poder para acceder a sus elementos, y esto solo es posible

informándole de su tipo y dimensiones. En el caso que nos ocupa las dimensiones son dos, por lo que la

definición de la función llamada sería algo así:

func (int dias[2][12]) {...} //

Observe que en la expresión anterior está incluida toda la información necesaria: número de filas, número

de columnas y tamaño de cada elemento (un int ). Desde luego la función receptora necesita conocer

también la dirección de inicio del almacenamiento, pero ya hemos señalado que "el identificador de una

matriz puede ser utilizado como un puntero a su primer elemento", con lo que si mentalmente sustituimos

dias por un puntero al número 31 (primer elemento) de la primera matriz, la información pasada es

completa.

Ya se ha señalado que C++ no contiene operadores para manejar matrices como una sola unidad. Al

contrario de lo que ocurre en otros lenguajes (por ejemplo Java), en C++ es responsabilidad del

programador no salirse del ámbito de la matriz al acceder a sus elementos, lo que una vez aceptado, nos

conduce a que en realidad es innecesario conocer la primera dimensión. En efecto, en nuestro caso, el

primer elemento (primera sub-matriz), es accedido directamente mediante el puntero dias; su tamaño ya

lo conocemos (12 int ), y con esta información es suficiente para acceder a cualquier otro elemento n.

Solo es necesario desplazar el puntero los las posiciones de memoria correspondientes.

La conclusión anterior estaba ya implícitamente establecida en, donde hemos visto que, en una matriz

bidimensional m[F][C], la posición Pf,c respecto del comienzo del elemento m[f][c] viene determinado

por:

Pf,c = ( C * f ) + c

expresión que es independiente del valor F (número de filas). Como consecuencia, la definición podría

ser del tipo:

func (int dias[][12]) {...} //

El primer paréntesis vacío es necesario para colocar el segundo, que es el que interesa. La expresión es

conceptualmente equivalente a:

Page 14: funciones vactores y matrices

UNIVERSIDAD TECNICA DE AMBATO

14

func (int (*dias)[12]) {...} //

que indica explícitamente el hecho de que el parámetro es un puntero-a-matriz de 12 int .

Comprobamos la veracidad de lo expuesto a un sencillo ejemplo:

#include <stdio.h>

void escribe(int a[][12], int x, int y); // prototipo

void escribo(int (*a)[12], int x, int y); // prototipo

void main () { // =============

int dias[2][12] = {

{ 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12},

{13,14,15,16,17,18,19,20,21,22,23,24}

};

escribe(dias, 1, 3);

escribe(dias, 0, 7);

escribo(dias, 1, 3);

escribo(dias, 0, 7);

}

void escribe(int a[][12], int f, int c) { // definición

printf("Valor [%2i,%2i] = %3i\n", f, c, a[f][c]);

}

void escribo(int (*a)[12], int f, int c) { // definición

printf("Valor [%2i,%2i] = %3i\n", f, c, a[f][c]);

}

Salida:

Valor [ 1, 3] = 16

Valor [ 0, 7] = 8

Valor [ 1, 3] = 16

Valor [ 0, 7] = 8

Ejercicio con matriz y vectores.

Page 15: funciones vactores y matrices

UNIVERSIDAD TECNICA DE AMBATO

15

#include<conio.h> #include<stdio.h> int vector[20],col,aux,fila,vector1[20],vector2[20],i,j,k,l,a,op,c; void borde() { textcolor(18); for(i=2;i<=78;i++) { gotoxy(i,2);cprintf("*"); gotoxy(i,24);cprintf("*"); } for(i=2;i<=24;i++) { gotoxy(2,i);cprintf("*"); gotoxy(78,i);cprintf("*"); } } void ingreso(int l) { col=5;fila=10; gotoxy(15,6);cprintf("Ingrese el Primer Vector==> "); textcolor(53); gotoxy(3,10);cprintf("1 Vector"); for(i=1;i<=l;i++) { do{ gotoxy(47,6);printf(" "); gotoxy(47,6);scanf("%d",&a); }while(a<3||a>53); vector[i]=a; gotoxy(col,fila+=2);cprintf("%d. %d",i,vector[i]); if(fila>20) { col=col+8; fila=10; } } col=15;fila=10; textcolor(15); gotoxy(15,8);cprintf("Ingrese el Segundo Vector==> "); textcolor(53); gotoxy(13,10);cprintf("2 Vector"); for(i=1;i<=l;i++) { do{

Page 16: funciones vactores y matrices

UNIVERSIDAD TECNICA DE AMBATO

16

gotoxy(47,8);printf(" "); gotoxy(47,8);scanf("%d",&a); }while(a<3||a>53); vector1[i]=a; gotoxy(col,fila+=2);cprintf("%d. %d",i,vector1[i]); if(fila>20) { col=col+8; fila=10; } } } void intercalar() { j=0;col=26;fila=10;k=1;a=1; textcolor(53); gotoxy(24,10);cprintf("Vector Intercalado"); for(i=1;i<=l*2;i++) { if(j==0) { vector2[i]=vector[a]; gotoxy(col,fila+=2);cprintf("%d. %d",i,vector2[i]); j++; a++; } else if(j==1) { vector2[i]=vector1[k]; gotoxy(col,fila+=2);cprintf("%d. %d",i,vector2[i]); j--; k++; } if(fila>20) { col=col+8; fila=10; } } } void orden() { col=36;fila=10; for(i=1;i<=l*2;i++)

Page 17: funciones vactores y matrices

UNIVERSIDAD TECNICA DE AMBATO

17

{ for(j=1;j<=l*2;j++) { if(vector2[i]<=vector2[j]) { aux=vector2[i]; vector2[i]=vector2[j]; vector2[j]=aux; } } } col=50;fila=10; textcolor(53); gotoxy(45,10);cprintf(" Ascendente"); for(i=1;i<=l*2;i++) { gotoxy(col,fila+=2);cprintf("%d",vector2[i]); if(fila>20) { col=col+8; fila=10; } } col=62;fila=10; textcolor(53); gotoxy(58,10);cprintf(" Descendente"); for(i=l*2;i>0;i--) { gotoxy(col,fila+=2);cprintf("%d",vector2[i]); if(fila>20) { col=col+8; fila=10; } } } void main() { do{ clrscr(); borde(); gotoxy(25,4);printf("Ingrese el L¡mite==> ");scanf("%d",&l); ingreso(l); intercalar(); orden();

Page 18: funciones vactores y matrices

UNIVERSIDAD TECNICA DE AMBATO

18

gotoxy(25,22);printf("Desea volver==> ");scanf("%d",&op); }while(op==1); getch(); }

Conclusión

El uso de funciones nos permite ir realizando paso a paso los procesos que se van a ejecutar el programa

principal VOID MAIN ( ) es mucho mas fácil y mejor estructurada, el uso de los vectores es una forma

de almacenar datos en con posiciones que luego los datos podemos utilizarlos de distintas maneras ya

que en un vector los datos se almacenar con posiciones desde cero sin importar el valor del dato entrante

de esa manera luego es muy fácil y practico buscar un dato y almacenar en un nuevo vector, y las

matrices nos permiten almacenar datos de forma cuadrática secuencialmente uno tras de otro hasta que su

fila y columna se llene, el uso de funciones, vectores, matrices nos van a permitir que nuestra

programación sea mas básica y estructurada.