Anda di halaman 1dari 17

UNIDAD V. PUNTEROS.

5.1 INTRODUCCION

Un puntero es una variable (que apunta a otra variable) que guarda la direccin en memoria de otra variable, hasta el momento las variables que se han manejado guardan datos de tipo entero, carcter o flotante, pero ninguna de estas variables, guarda el valor de una direccin en memoria. La utilizacin de punteros en la elaboracin de programas hace que estos sean ms eficientes, adems que se puede utilizar lo que se conoce comomemoria dinmica.

Direccin en memoria:

Cuando se declara una variable en esta se pueden manejar 3 aspectos :

Nombre de la variable. Contenido o valor de esta. Direccin en memoria.

Por ejemplo:

int x=10;

10

0XFF3

En este caso la variable se llama X, su valor es 10 y su direccin en memoria es 0XFF3.

El valor de la variable se muestra as:

printf(%d,x);

La direccin de la variable se muestra as:

printf(%p,&x);

Concepto de puntero:

La definicin de puntero ya se menciono anteriormente, este es una variable que guarda la direccin en memoria de otra. Cuando una variable se declara el compilador de C establece un rea de memoria para almacenar el contenido de la variable, esto de acuerdo al tipo de dato que se manejar por ejemplo si es de tipo entero se reservan 2 bytes, si es de tipo flota se reservan 4 bytes y as sucesivamente. Esto se hace en una direccin especifica de memoria a la cual se puede accesar con ya sabemos (por medio de el nombre de la variable), pero adems podemos tener acceso a esta variable por medio de un puntero el cual tiene acceso a su direccin de memoria y adems de proporcionarnos su direccin de memoria tambin puede modificar o mostrar el valor que esta contiene por medio de indireccin (manipulacin de el valor de una variable por medio de un puntero).

Los punteros se rigen por las siguientes reglas bsicas:

Un puntero es una variable como cualquier otra. Una variable puntero contiene una direccin que apunta a otra posicin en memoria. En esa posicin se almacenan los datos a los que apunta el puntero. Un puntero apunta a una variable en memoria.

5.2 DECLARACION E INICIALIZACION DE VARIABLES PUNTEROS.

Declaracin de punteros:

El puntero se declara igual que cualquier otra variable, solo que sabemos que este guardar la direccin en memoria de una variable cualesquiera que tambin fue declarada, por lo que para declarar un puntero antes debemos de saber a que tipo de variable va a apuntar. Si la variable es de tipo int el puntero ser declarado de tipo int, si la variable es de tipo float el puntero se declarado de tipo float, etc.

Por lo que la declaracin ser:

Tipo de dato del puntero *Nombre de la variable tipo puntero;

Ejemplos:

int *p; //Puntero a un entero float *f; //Puntero a un flotante

El operador * en una declaracin indica que la variable declarada almacenar una direccin de un tipo de dato especificado, por lo que siempre que en una declaracin aparezca un * esta ser un puntero.

Inicializacin de punteros:

Al igual que otras variables, C no inicializa los punteros cuando se declaran y es preciso inicializarlos antes de su uso. La inicializacin de un puntero proporciona a ese puntero la direccin del dato correspondiente. Despus de la inicializacin, se puede utilizar el puntero para referenciar los datos direccionados. Para asignar una direccin de memoria a un puntero se utiliza el operador de referencia &. As por ejemplo:

&valor significa la direccin de valor . Por lo tanto, el mtodo de inicializacin tambin denominado esttico

Asignar memoria definiendo una variable y a continuacin hacer que el puntero apunte al valor de la variable:

int x; //Declaracin de la variable x int *p; //Declaracin del puntero p=&x; //puntero p apuntando a x

Indireccin:

Manejar por medio de un puntero la direccin en memoria de una variable, por ejemplo; si se quiere asignar un valor a x por medio del puntero *p: se escribira: *p=valor; De tal manera que siempre que queramos accesar al valor de nuestra variable por medio del puntero que apunta a ella, antepondremos un * al puntero.

5.3 Operadores de apuntadores

Operador & * *

Propsito Obtiene la direccin de una variable Define una variable como puntero Obtiene el contenido de una variable puntero

5.4 Llamar a funciones por referencia.(Paso de parmetros por referencia)

Cuando una funcin debe modificar el valor del parmetro pasado y devolver este valor modificado a la funcin que lo llama, se tiene que pasar el parmetro por referencia. En este mtodo el compilador pasa la direccin de memoria del valor del parmetro a la funcin. Cuando se modifica el valor del parmetro (la variable local), este valor queda almacenado en la misma direccin de memoria, por lo que al retornar a la funcin llamadora la direccin de la memoria donde se almacen el parmetro contendr el valor modificado. Para pasar una variable por referencia, el smbolo & debe preceder al nombre de la variable y el parmetro variable correspondiente de la funcin debe declararse como puntero.

float x; int y; Entrada (&x,&y); ... void entrada(float * x, int* y);

C permite utilizar punteros para implementar parmetros por referencia, ya que por defecto en C el paso de parmetros es por valor.

/* mtodo de paso por referencia, mediante punteros */

void intercambio (int *a, int *b) { int aux=*a; *a=*b; *b=aux; }

En la llamada siguiente, la funcin intercambio() utiliza las expresiones *a y *b para acceder a los enteros referenciados por las direcciones de las variables i y j:

int i=3, j=50; printf(i = %d y j = %d \n, i,,j); intercambio (&i,&j); printf(i = %d y j = %d \n, i,,j);

La llamada a la funcin intercambio() debe pasar las direcciones de las variables intercambiadas. El operador & delante de una variable significa <<dame la direccin de la variable>>.

double x; &x; /* direccin en memoria de x */

Una variable, o parmetro puntero se declara posicionando el asterisco (*) antes del nombre de la variable. Las variables p, r y q son punteros a distintos tipos.

char *p; int *r; double *q;

5.5 Expresiones de apuntadores y aritmtica de apuntadores. Al contario que un nombre de arreglo, que es un puntero constante y no se puede modificar, un puntero es una variable que se puede modificar. Como consecuencia, se puede realizar ciertas operaciones aritmticas sobre punteros.

A puntero se le puede sumar o restar un entero n; esto hace que apunte n posiciones adelante, o atrs de la actual. Una variable puntero puede modificarse para que contenga una direccin de memoria n posiciones adelante o atrs. Por ejemplo:

int v[10]; int *p; p =v; (v+4); /* apunta al 5 elemento */ p=p+6; /8 contiene la direccin del elemento 7 */

A una variable puntero se le puede aplicar el operador ++, o el operador --. Esto hace que contenga la direccin del siguiente, o anterior elemento. Por ejemplo:

float m[20]; float *r; r=m; r++ /* contiene la direccin del elemento siguiente */

Recuerde que un puntero es una direccin, por consiguiente, slo aquellas operaciones de <<sentido comn>> son legales. No tiene sentido, por ejemplo, sumar o restar una constante de coma flotante.

Operaciones no vlidas como punteros

No se pueden sumar dos punteros. No se pueden multiplicar dos punteros. No se pueden dividir dos punteros.

Si p apunta a la letra A en el alfabeto, si se escribe

p=p+1; entonces p apunta a la letra B

Se puede utilizar esta tcnica para explorar cada elemento de alfabeto sin utilizar una variable de ndice. Un ejemplo puede ser: p =&alfabeto[0]; for (i=0; i<strlen(alfabeto); i++) { printf (%c,*p);

p=p+1; }

las sentencias dentro del ciclo se pueden sustituir por printf(%c,*p++);

5.6 Relacin entre arreglos y apuntadores.

Los arreglos y punteros estn fuertemente relacionados en el lenguaje C. Se pueden direccionar arreglos como si fueran punteros y punteros como si fueran arreglos. La posibilidad de alamacenar y acceder a punteros y arreglos, implica que se pueden almacenar cadenas de datos en elementos de arrays. Sin punteros eso no es posible, ya que no existe el tipo de dato cadena (string) en c. No existen variables de cadena, nicamente constantes de cadena.

Un nombre de un arreglo es simplemente un apuntador. Supongamos que se tiene la siguiente declaracin de un array:

int lista[5] = {10,20,30,40,50}

lista

[0]

Memoria 10

Lista

[1] [2] [3] [4]

20 30 40 50

*(lista+1) *(lista+2) *(lista+3) *(lista+4)

Este seria un arreglo en memoria

Si se manda visualizar lista[0] se ver 10. Pero que sucede si se visualiza *lista? Como el nombre de un arreglo es un puntero, tambin se ver 10. Esto significa que:

Lista +0 apunta a lista[0] Lista +1 apunta a lista[1] Lista +2 apunta a lista[2] Lista +3 apunta a lista[3] Lista +4 apunta a lista[4]

Por lo que, para imprimir, almacenar o calcular un elemento de un arreglo, se puede utilizar notacin de subndices o de punteros. Dado que un nombre de un arreglo contiene la direccin del primer elemento del arreglo, se debe indireccionar el puntero para obtener el valor del elemento. El nombre de un arreglo es un puntero, contiene la direccin en memoria de comienzo de la secuencia de elementos que forma el arreglo. Es un puntero

constante ya que no se puede modificar, slo se puede acceder para indexar a los elementos del arreglo. En el ejemplo se pone de manifiesto operaciones correctas y errneas con nombres de arreglo.

float v[10]; float *p; float x =100.5; int j;

/* Se indexa a partir de v */ for (j=0;j<10;j++) (v+j)= j10.0; p = v+4 /* se le asigna la direccin del 4to. Elemento */ v = &x; /* error: intento de modificar un puntero constante */

Punteros de cadenas

Los punteros se pueden utilizar en lugar de ndice de arreglos. Considrese la siguiente declaracin de un arreglo de caracteres que contiene las veintisis letras del alfabeto internacional (no se considera la ). char alfabeto[27] = ABCDEFGHIJKLMNOPQRSTUVWXYZ;

Declaremos ahora p un puntero a char

char *p;

Se establece que p apunta al primer carcter del alfabeto escribiendo:

p= &alfabeto[0];

p=alfabeto;

de modo que si escribe la sentencia

printf(%c\n, *p);

se visualiza la letra A, ya que p apunta al primer elemento de la cadena. Se puede tambin :

p= &alfabeto[15];

de modo que p apuntar al carcter 16 (la letra Q). Sin embargo, no se puede hacer

p = &alfabeto;

ya que alfabeto es un arreglo cuyos elemntos son de tipo char, y se producira un error al compilar (tipo de asignacin es incompatible).

Es posible, entonces, considerar dos tipos de definiciones de cadena:

char cadena1[ ]=Hola viejo mundo; /* Arreglo contiene una cadena */ char cptr = C a su alacance ; / puntero a cadena, el sistema reserva memoria para la cadena */

Punteros contra arreglos:

El siguiente programa implementa una funcin para contar el nmero de caracteres de una cadena. En el primero programa, la cadena se describe utilizando un arreglo, y en el segundo, se describe utilizando un puntero.

/*implementacin de un arreglo */ #include <stdio.h>

int longitud ( char cad[ ]);

main()

{ char cad [ ] = Universidad Autonoma de Baja California ; printf(La longitud de %s es %d caracteres \n, cad, longitud(cad)); }

int longitud (char cad[ ]) { int pos=0; while (cad[pos]) { pos++; } return pos; }

El Segundo programa utiliza un puntero para la funcin que cuenta los caracteres de la cadena. Adems, utiliza la aritmtica de punteros para indexar los caracteres. El bucle termina cuando llega al ltimo carcter, que es el delimitador de una cadana: \0.

/* Implementacin con un puntero */

#include <stdio.h>

int longitud ( char cad[ ]);

main() { char cad [ ] = Universidad Autnoma de Baja California ; printf(La longitud de %s es %d caracteres \n, cad, longitud(cad)); }

int longitud (char cad[ ]) { int cuenta=0; while (*cad++) { cuenta++; } return cuenta; }

Anda mungkin juga menyukai