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

PRCTICA APUNTADORES

Objetivos El alumno conocer y aplicar el concepto de apuntador para la realizacin de programas de manejo eficiente de memoria. Al final de esta prctica el alumno podr: 1. Acceder a localidades de memoria a travs de apuntadores para el uso eficiente del almacenamiento primario. Antecedentes 1. Manejar sentencias de control de flujo en lenguaje C 2. Utilizar arreglos de varias dimensiones para almacenamiento de datos 3. Conocer la estructura de la memoria principal de una computadora Introduccin Apuntador Comnmente se manejan variables que tienen el siguiente aspecto:
int i; char c; float f;

Cada una de estas variables tiene asignada una localidad de memoria, de tamao suficiente para almacenar un valor del tipo especificado; es decir, a travs del nombre de la variable y no de la direccin se almacenan datos o valores en la memoria. Otro tipo de variables, que se utilizan en el lenguaje C, son las de tipo apuntador (o puntero). Su caracterstica principal es que, a diferencia de las variables de uso comn, stas no almacenan datos como tal, sino que almacenan direcciones de memoria. En la declaracin de variables de tipo apuntador, se debe indicar el tipo de valor que se almacenar en la direccin contenida por dicha variable apuntador. Para especificar que se trata de un apuntador, al declararlo, se debe anteponer un asterisco al nombre de la variable. Ejemplos:
int *ip; char *cp; float *fp; /* ip contendr direcciones de memoria en donde se almacenen valores del tipo entero */ /* cp contendr direcciones de memoria en donde se almacenen valores del tipo carcter */ /* fp contendr direcciones de memoria en donde se almacenen valores del tipo flotante */

Elaborada por: Ing. Laura Sandoval Montao Viridiana del Carmen De Luna Bonilla Virgilio Green Prez

Programacin Avanzada y Mtodos Numricos

PRCTICA APUNTADORES

Ejemplo 1 Programa A
#include<stdio.h> main(){ int a=0; a = 5; a = a * 2; printf(El valor de a es %d,a); }

Programa B
#include<stdio.h> main(){ int a=0,*ip=&a; *ip=5; *ip = *ip * 2; printf(El valor de a es %d,*ip); }

Estos dos cdigos hacen exactamente lo mismo, la diferencia es que en el Programa A, slo se emplea la variable a, y en el Programa B, se utiliza adems un apuntador a travs del cual se modifica el valor de la variable a. Del Programa B, se puede observar que con la sentencia int a=0, *ip=&a; al tiempo que se declara el apuntador a enteros ip, se le da el valor inicial &a. El operador & indica la direccin de; as, el valor inicial de ip ser la direccin de a. En el manejo de apuntadores, adems del operador &, existe el operador *, con el cual se accede a la informacin que est almacenada en la direccin contenida en la variable apuntador. Por esta razn, la siguiente lnea de cdigo
*ip=5;

asigna el valor de 5 a la localidad de memoria que apunta ip; equivalente a escribir a = 5, ya que ip tiene la direccin de a. Ahora, si se desea mostrar la direccin en la cual est contenido el valor de la variable a, se puede agregar la siguiente sentencia: printf(La direccin de a es %X,ip); Con esto se despliega en pantalla la direccin de la variable a en hexadecimal (formato %X); como se puede observar no utilizamos el operador *, debido a que deseamos conocer la direccin de memoria. Nombre de un arreglo como apuntador Cuando se hace referencia a un elemento del arreglo, generalmente se usa el nombre de la variable y su posicin dentro de ste: vector[2] = 4; /* al tercer elemento de vector se le asigna un valor de 4 */ Pero lo que hace C, en realidad, es utilizar el nombre del arreglo como un apuntador y al indicarle la posicin del elemento, hace referencia a la direccin que obtiene de sumar la
Elaborada por: Ing. Laura Sandoval Montao Viridiana del Carmen De Luna Bonilla Virgilio Green Prez Programacin Avanzada y Mtodos Numricos

PRCTICA APUNTADORES

direccin de inicio del arreglo ms la posicin del elemento en cuestin. De la lnea de cdigo anterior, sera equivalente a: *(vector +2) = 4; Ejemplo 2 Programa que presenta el manejo de arreglos empleando el nombre del arreglo como apuntador. -Explicacin de variables arr: Arreglo unidimensional de tipo entero ip: Apuntador de tipo entero i: Variable de tipo entero, utilizada como variable de control de ciclos y como ndice del arreglo. -Cdigo
#include<stdio.h> void main(){ /*Se declara un arreglo de 5 elementos con valores iniciales*/ int arr[5]={5,7,11,13,17}; /*Se declara un apuntador a enteros*/ int *ip; /*Se declara una variable entera que sirva como contador*/ int i; /*Se asigna a ip, la direccin del primer elemento de arr*/ ip=arr; /*Esta lnea es equivalente a utilizar ip = &arr[0]*/ printf("El valor de ip es %X\n",ip); /*Ciclo de impresin de los elementos de arr*/ for(i=0;i<5;i++){ printf("El valor de arr[%d] es: %d\n",i,arr[i]); } /*Ciclo de impresin de los elementos del arreglo utilizando el apuntador ip*/ for(i=0;i<5;i++){ printf("El valor de arr[%d] usando ip es: %d, dir: %X\n",i,*(ip+i),(ip+i)); } /*Ciclo de impresin de los elementos del arreglo utilizando su nombre(arr) como apuntador*/ for(i=0;i<5;i++){ printf("El valor de arr[%d] usando solo arr es: %d, dir: %X\n",i,*(arr+i),(arr+i)); } }

Elaborada por: Ing. Laura Sandoval Montao Viridiana del Carmen De Luna Bonilla Virgilio Green Prez

Programacin Avanzada y Mtodos Numricos

PRCTICA APUNTADORES

Revisando el cdigo, primeramente se hace la declaracin de un arreglo de tipo int de 5 elementos, asignndole valores iniciales; as como de una variable de tipo apuntador a enteros.
int arr[5]={5,7,11,13,17}; int *ip;

Posteriormente se almacena el valor de la direccin inicial del arreglo, que corresponde al elemento cero de ste, en la variable de tipo apuntador.
ip=arr;

En el primer ciclo de impresin de los valores del arreglo, se contina usando arr[i]; pero en el segundo ciclo se utiliza el apuntador ip para hacer referencia a los mismos elementos de arr, y esto se hace mediante el lgebra de apuntadores, donde slo existen 2 operaciones: suma y resta; de esta forma un apuntador slo puede operar con otro apuntador o con cualquier variable o constante entera. En el ltimo ciclo de impresin, se observa que la utilizacin del nombre del arreglo sigue las mismas reglas como si se estuviera utilizando apuntadores, porque se comporta de la misma forma. Ejemplo 3 Programa que realiza la suma de dos polinomios de cualquier grado. -Explicacin de variables polinom: Nuevo tipo de estructura, definida por el usuario. grado: Variable de tipo entero que almacena el grado del polinomio a manipular. coef: Variable de tipo apuntador que ayudar en el almacenamiento de los coeficientes del polinomio. polA: Variable de tipo polinom que almacenar la informacin del polinomio A polB: Variable de tipo polinom que almacenar la informacin del polinomio B polRes: Variable de tipo polinom que almacenar la informacin del polinomio resultante de la suma de A y B. i: Variable de tipo entero, utilizada como variable de control de ciclos gradoMAX: Variable de tipo entero, utilizada para identificar el grado mximo entre A y B polMAX: Variable de tipo entero, utilizada para indicar el polinomio de grado mximo.

Elaborada por: Ing. Laura Sandoval Montao Viridiana del Carmen De Luna Bonilla Virgilio Green Prez

Programacin Avanzada y Mtodos Numricos

PRCTICA APUNTADORES

-Cdigo
#include<stdio.h> #include<stdlib.h> // Definicin de un nuevo tipo de dato: polinom typedef struct{ int grado; int *coef; }polinom; // Funcin de lectura de polinomios polinom LeePolinom(){ polinom pol; int i = 0; pol.grado=0; pol.coef=NULL; printf("Indica el grado del polinomio: "); scanf("%d",&pol.grado); /* Asignacin de memoria para el vector de coeficientes, segn el grado del polinomio */ pol.coef = (int *)malloc((pol.grado + 1) * sizeof(int)); if(pol.coef != NULL){ //Lectura de coeficientes, de mayor a menor grado for(i=pol.grado; i>=0;i--){ printf("Dame el valor del coeficiente %d: ",i); scanf("%d",&pol.coef[i]); } } return pol; } // Funcin que suma A y B polinom SumaPolinom(polinom polA, polinom polB){ int gradoMAX, polMAX; int i=0; polinom polRes = {0,NULL}; /* Condicin que indica el grado que tendr polRes */ if(polA.grado>=polB.grado){ gradoMAX = polA.grado; polMAX = 1; } else{ gradoMAX = polB.grado; polMAX = 2; } polRes.grado = gradoMAX;
Elaborada por: Ing. Laura Sandoval Montao Viridiana del Carmen De Luna Bonilla Virgilio Green Prez Programacin Avanzada y Mtodos Numricos

PRCTICA APUNTADORES

//Asignacin de memoria para polRes polRes.coef=(int *)malloc((gradoMAX + 1) * sizeof(int)); //Si A fue de mayor grado if(polMAX == 1){ /*Ciclo de copiado de los primeros coeficientes de A en Res */ for(i=gradoMAX;i>polB.grado;i--){ polRes.coef[i]=polA.coef[i]; } //Suma de coeficientes restantes for(i=polB.grado;i>=0;i--){ polRes.coef[i]=polA.coef[i]+polB.coef[i]; } } //Si B fue de mayor grado else{ /* Ciclo de copiado de los primeros coeficientes de B en Res */ for(i=gradoMAX;i>polA.grado;i--){ polRes.coef[i]=polB.coef[i]; } //Suma de coeficientes restantes for(i=polA.grado;i>=0;i--){ polRes.coef[i]=polB.coef[i]+polA.coef[i]; } } return polRes; } // Funcin Principal void main(){ polinom polA, polB, polRes; int i=0; polA = LeePolinom(); if(polA.coef !=NULL){ polB = LeePolinom(); if(polB.coef != NULL){ polRes = SumaPolinom(polA,polB); if(polRes.coef != NULL){ for(i=polRes.grado;i>=0;i--){ printf("+(%d)x^%d ",polRes.coef[i],i); } } } }
Elaborada por: Ing. Laura Sandoval Montao Viridiana del Carmen De Luna Bonilla Virgilio Green Prez Programacin Avanzada y Mtodos Numricos

PRCTICA APUNTADORES

//Se libera la memoria asignada a los polinomios free(polA.coef); free(polB.coef); free(polRes.coef); }

Descripcin del ejemplo 3 En este programa, primeramente se define un nuevo tipo de dato, utilizando typedef; el nuevo tipo de dato nombrado polinom corresponde a una estructura que contiene dos elementos: grado y coef. En el primer elemento se almacenar el grado de un polinomio y en el segundo, los coeficientes de dicho polinomio, los cuales debern ser enteros; como coef est definido como un apuntador a enteros, se utilizar para generar un vector de enteros (los coeficientes).
typedef struct{ int grado; int *coef; }polinom; /* nombre del nuevo tipo de datos */

Como el programa requiere leer dos polinomios de cualquier grado, se define una funcin que haga la lectura de un polinomio, la cual se invocar dos veces.
// Funcin de lectura de polinomios polinom LeePolinom(){ polinom pol; int i = 0; pol.grado=0; pol.coef=NULL; printf("Indica el grado del polinomio: "); scanf("%d",&pol.grado); /* Asignacin de memoria para el vector de coeficientes, segn el grado del polinomio */ pol.coef = (int *)malloc((pol.grado + 1) * sizeof(int)); if(pol.coef != NULL){ //Lectura de coeficientes, de mayor a menor grado for(i=pol.grado; i>=0;i--){ printf("Dame el valor del coeficiente %d: ",i); scanf("%d",&pol.coef[i]); } } return pol; }

Elaborada por: Ing. Laura Sandoval Montao Viridiana del Carmen De Luna Bonilla Virgilio Green Prez

Programacin Avanzada y Mtodos Numricos

PRCTICA APUNTADORES

Como puede observarse, esta funcin define una variable pol de tipo polinom y le asigna valores iniciales a sus elementos: a pol.grado el valor de cero y a pol.coef la direccin nula (NULL) por ser del tipo apuntador. Despus de conocer el grado del polinomio asignamos la memoria que requiere el apuntador coef para almacenar a todos los coeficientes, esto se hace empleando la funcin malloc():
pol.coef = (int *)malloc((pol.grado + 1) * sizeof(int));

El apuntador coef ahora se puede utilizar como un arreglo, por ejemplo en la lectura de los coeficientes.
scanf("%d",&pol.coef[i]);

Adems de la lectura de polinomios, se necesita otra funcin con la cual se har la suma de ambos polinomios.
// Funcin que suma A y B polinom SumaPolinom(polinom polA, polinom polB){ int gradoMAX, polMAX; int i=0; polinom polRes = {0,NULL}; /* Condicin que indica el grado que tendr polRes */ if(polA.grado>=polB.grado){ gradoMAX = polA.grado; polMAX = 1; } else{ gradoMAX = polB.grado; polMAX = 2; } polRes.grado = gradoMAX; //Asignacin de memoria para polRes polRes.coef=(int *)malloc((gradoMAX + 1) * sizeof(int)); //Si A fue de mayor grado if(polMAX == 1){ /*Ciclo de copiado de los primeros coeficientes de A en Res */ for(i=gradoMAX;i>polB.grado;i--){ polRes.coef[i]=polA.coef[i]; } //Suma de coeficientes restantes for(i=polB.grado;i>=0;i--){ polRes.coef[i]=polA.coef[i]+polB.coef[i]; } } //Si B fue de mayor grado else{ /* Ciclo de copiado de los primeros coeficientes de B en Res */ for(i=gradoMAX;i>polA.grado;i--){
Elaborada por: Ing. Laura Sandoval Montao Viridiana del Carmen De Luna Bonilla Virgilio Green Prez Programacin Avanzada y Mtodos Numricos

PRCTICA APUNTADORES

polRes.coef[i]=polB.coef[i]; } //Suma de coeficientes restantes for(i=polA.grado;i>=0;i--){ polRes.coef[i]=polB.coef[i]+polA.coef[i]; } } return polRes; }

Esta funcin recibe como parmetros los dos polinomios a sumar: polA y polB; despus define el polinomio resultante (el que contendr el resultado de la suma), asignndole valores iniciales.
polinom polRes = {0,NULL};

Se asigna el grado al polinomio resultante polRes determinado por el grado mayor gradoMax de entre los polinomios polA y polB. Una vez conocido el grado de polRes, se asigna la memoria que requiere su elemento apuntador coef para almacenar a todos los coeficientes, esto se hace empleando la funcin malloc():
polRes.coef=(int *)malloc((gradoMAX + 1) * sizeof(int));

Ahora, para hacer la suma se vacan los coeficientes de mayor grado, no incluidos en el polinomio de menor grado para despus realizar la suma de coeficientes uno a uno:
//Suma de coeficientes para el caso de que A sea de mayor grado for(i=polB.grado;i>=0;i--){ polRes.coef[i]=polA.coef[i]+polB.coef[i]; La funcin SumaPolinom, como es del tipo polinom, regresa el polinomio resultante: return polRes;

Y por ltimo, la funcin principal main, define a los polinomios, invoca dos veces a la funcin LeePolinom para leer cada uno de los polinomios a sumar, posteriormente invoca a la funcin SumaPolinom para que realice la suma de los polinomios y finalmente imprime el polinomio resultante. Cabe hacer notar que en la funcin principal tambin se libera la memoria asignada a los polinomios, esto es conveniente hacer cuando se usa la funcin malloc(), para evitar que el sistema genere errores de manejo de memoria.

Elaborada por: Ing. Laura Sandoval Montao Viridiana del Carmen De Luna Bonilla Virgilio Green Prez

Programacin Avanzada y Mtodos Numricos

PRCTICA APUNTADORES

EJERCICIOS PROPUESTOS 1. Dadas las siguientes declaraciones:


int dato; int *apuntador; apuntador = &dato; *apuntador = 5;

a) Qu valor tiene apuntador? b) Cul es el valor de dato? c) Cul es el valor de *apuntador? 2. Del siguiente programa:
#include<stdio.h> main(){ char *apuntador; char variable; variable = 1; apuntador = &variable; printf("Valor almacenado en variable = %d\n",variable); printf("Valor almacenado en apuntador = %d\n",apuntador); *apuntador = 2; printf("Nuevo valor almacenado en variable = %d\n",variable); printf("Valor almacenado en apuntador = %d\n",apuntador); }

a) Cul es la salida que produce? b) Hacer el anlisis del programa, es decir explicarlo de manera puntual. 3. Se tiene un programa con las siguientes declaraciones: int num; int *p; Suponiendo que la direccin de num es 7753 y la de p 8364, determinar los siguientes valores: a) num b) p c) &num d) &p e) *p Despus de ejecutar, de forma acumulativa, las siguientes sentencias:
A. B. C. D. E. F.

num = 5; p=12 num = p num = &p p = &p p = &num *p = 10

Elaborada por: Ing. Laura Sandoval Montao Viridiana del Carmen De Luna Bonilla Virgilio Green Prez

Programacin Avanzada y Mtodos Numricos

PRCTICA APUNTADORES

Por ejemplo: Resolviendo A A. num=5, p=12, &num=7735, &p=8364,*p=dato almacenado en 12 4. Utilizando el nombre de un arreglo unidimensional como apuntador, implemente una funcin que lea los coeficientes de un polinomio de orden 4, y que con base en ellos, obtenga el valor de dicho polinomio, para una X, dada por el usuario. 5. Utilizando la aritmtica de apuntadores, implemente una funcin que transponga una matriz cuadrada utilizando nicamente un apuntador. 6. Utilizando 2 apuntadores, intercambiar los valores de 2 arreglos de una dimensin con el mismo nmero de elementos. 7. Elabore un programa que defina una variable de tipo int, y un apuntador de tipo double. Haga que el apuntador obtenga la direccin de la variable tipo int. Qu pasa? Imprima en pantalla el valor de la variable usando el apuntador, y usando en el printf() el modificador %g. Qu pasa? 8. Modifique el programa anterior, ahora usando una variable double y un apuntador int. Conteste las mismas preguntas.

Elaborada por: Ing. Laura Sandoval Montao Viridiana del Carmen De Luna Bonilla Virgilio Green Prez

Programacin Avanzada y Mtodos Numricos

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