Sie sind auf Seite 1von 31

Almacenamiento

de punteros

Estructura de Datos
Lus Fdo. Miranda S.
19/04/2010
Almacenamiento de punteros
Contenido

Conceptos
Declaracin de punteros
Asignacin de valores a punteros
Punteros y parmetros



Declaraciones de punteros.
El operador "direccin de" (&).
El operador de desreferenciacin (*).
Arreglos de punteros.
Son variables que siguen todas las convenciones sobre nombres
que utilizan las variables regulares de todos los dems tipos.
Se deben declarar las variables de tipo puntero antes de poder
utilizarlas.
Existe un tipo de puntero para cada tipo de dato en C.
Puede declarar puntero globales o locales, segn donde se los
declare.
Los punteros contienen direcciones de datos en memoria.
Existen dos tipos de operadores de punteros en C:

& El operador "direccin de".

* El operador de desreferenciacin.

Cuando vea el & utilizado con variables de tipo puntero,
considrelo equivelente a las palabras "direccin de". El
operador & siempre retorna la direccin de memoria
de lo que venga despus del mismo. El operador *,
cuando se lo emplea con punteros, puede declarar un
puntero o desreferenciar (entregar) el valor que se
encuentra alojado en la direccin que referencia el
puntero.
Declaracin de punteros
Declarar punteros es tan sencillo como declarar variables
convencionales.

Si necesitara declarar una variable que almacenara su edad, podra
hacerlo con la declaracin siguiente:

int edad=30; // Declaro una variable que almacenara mi edad

Al declarar edad de esa manera se llevan a cabo varias cosas. C
ahora sabe que usted necesitar una variable denominada edad,
as que reserva espacio en memoria para esa variable. C tambin
sabe que en esa variable, almacenar solo valores enteros, no de
punto flotante o de punto flotante doble. Esa declaracin tambin
requiere de C que ste, una vez que haya reservado espacio en
memoria para la variable edad, almacene en sta el valor 30.

En qu lugar de la memoria C almacena edad? Como
programador, a usted no debera importarle dnde decida C
almacenar edad. Usted no necesita conocer la direccin de esa
variable porque nunca se va a referir a edad por su direccin. Si
quisiera calcular o imprimir con edad, directamente la llamara por
su nombre, edad.

CONSEJO
Asgneles a sus variables puntero nombres que tengan significado
en el contexto. El nombre punteroArchivo es ms entendible para
un puntero de archivo que x13, aunque cualquiera de los dos es un
nombre vlido.

Declare una variable puntero. Esta variable puntero no
almacenar su edad, sino que apuntar a edad, la
variable de tipo numrico que contiene su edad. (Para
qu necesita de toda esa complicacin ser explicado a
continuacin.) pEdad podra ser un buen nombre para
una variable puntero. La Figura a continuacin ilustra lo
que el programador quiere hacer. La figura muestra que
C almacen edad en la direccin de memoria 350.606;
sin embargo, es su compilador el que determina la
direccin que asignar a edad, as que esta puede ser
cualquiera.

El nombre pEdad por s mismo no tiene nada que ver con los
punteros, excepto que es el nombre que se asign al puntero de
edad. pEdad podra para el caso haber sido llamado miguelito,
X43344, viaje_espacial o cualquier otra cosa que se le pudiera
ocurrir al programador, lo mismo sucede con los nombres de las
variables (en tanto dichos nombres se ajusten a las convenciones
formales sobre nombres de variables).

pEdad es un buen nombre para una variable que apunta hacia
Edad, como lo seran tambin punteroEdad o punteroAEdad.

Para declarar la variable de tipo puntero pEdad. deber hacer lo
siguiente:

int * pEdad; // Declara un puntero a variable de tipo entero

Algunos prefieren declarar una variable sin dejar un espacio en
blanco luego del *, como sigue:

int *pAge; // Declara un puntero a variable de tipo entero

CONSEJO
En la definicin de una variable cada vez que aparezca el operador
de desreferenciacin ( *variable, esa variable que se declara es
siempre un puntero.
Asignacin de valores a punteros
pEdad es un puntero a una variable entera. Esto es muy importante.
pEdad puede apuntar solo a variables de tipo entero, nunca a
variables de tipo punto flotante, doble punto flotante o siquiera a
variables alfanumricas.

C no inicializa los punteros cuando se los declara. Si hubiese
declarado pEdad como se acaba de describir, y quisiera que pEdad
sealara hacia edad, tendra que asignarle en forma explcita a
pEdad la direccin de edad. La sentencia siguiente hace justamente
eso:
pAge = &edad; // Asigna a pEdad la direccin de edad


Qu valor est alojado ahora en pEdad?

En lugar de asignar la direccin de edad a pEdad
con un operador de asignacin, puede declarar e inicializar un puntero al
mismo tiempo. Estas lneas declaran e inicializan tanto edad como pEdad.

int edad=30; /* Declara una variable entera ordinaria, asignndole el
valor 30 */
int *pEdad=&edad; /* Declara un puntero a variable entera,
inicializndolo con la direccin de edad */

Observacin
Estas dos lneas producen las variables que se describen en la
Figura anterior.
Si usted quisiese imprimir el valor de edad, podra hacerlo con la siguiente
printf ();

printf("%d", edad); // Imprime el valor de edad

Tambin podra imprimir el valor de edad como sigue:

printf("%d", *pEdad); // Desreferencia pEdad

El operador de desreferenciacin le indica al puntero que lo que
debe imprimir no es su propio contenido sino el contenido de
la variable a la cual apunta. Sin el *, la ltima printf () hubiera
impreso una direccin (la direccin donde se encontrase edad). Con
el *, la printf () imprime el valor numrico alojado en esa direccin.

Usted puede asignarle a edad un valor diferente con la sentencia siguiente:

edad=41; /* Asigna a edad un nuevo valor */

Tambin le puede asignar el mismo valor as:

*pEdad=41;

Esta declaracin asigna el valor 41 a la variable a la que apunta pEdad.

CONSEJO
El * aparece antes de una variable puntero en solo dos lugares: a)
cuando se la declara, y b) cuando se desreferencia dicha variable
(para obtener el valor contenido en la variable a la cual apunta).
Punteros y parmetros
Cuando se transfera una variable ordinaria a scanf (), haba que
preceder el nombre de la variable con el operador &. Por ejemplo, la
siguiente scanf () obtiene tres valores enteros que ingresa el
usuario:

scanf (" %d %d %d", &nuraero1, &numero2, &nurnero3);

Esta scanf () no transfiere las tres variables a su cdigo interno, sino
que le transfiere las direcciones de esas tres variables. Como scanf
( ) sabe las ubicaciones exactas de estos parmetros en la memoria
(porque se le pasaron sus direcciones como argumentos), su cdigo
interno localiza estas direcciones y les asigna los valores
ingresados desde el teclado.
La siguiente funcin transfiere la variable intentos por direccin a la
funcin receptora denominada imprimirlo().

Imprimirlo(&intentos); /* Transfiere la variable entera intentos a
imprimirlo() por direccin (intentos
seria normalmente transferida por
copia) */

La funcin siguiente, imprimirlo (), recibe la direccin de intentos, ya
que la variable intentos le es transferida por direccin:

imprimirlo(int *intentos) /* Recibe la variable intentos por
direccin para proceder a
desreferenciar su valor */
{
*intentos++; /* Esto modifica intentos tanto en la funcin invocante
como en la funcin llamada */
return 0;
}

Ahora que usted comprende los operadores & y *, est en
condiciones de comprender totalmente la transferencia de
argumentos no-arreglo por direccin a las funciones receptoras.
(Los arreglos son transferidos por direccin como opcin
predeterminada, y por lo tanto no requieren que se los preceda por
& ni por *.)


1. El siguiente fragmento de programa declara tres variables ordinarias de
tres tipos diferentes de datos, y tres punteros que apuntan a cada una de
esas variables.

char inicial =Q; /* Declara tres variables ordinarias */

int numero=40; /* cada una de ellas de un tipo
diferente */
float ventas= 2321.59;

char *plnicial=&inicial; /* Declara tres punteros. */

int * punteroANumero=№ /* Los nombres de estos y el
espaciado */

float * DireccionDeVentas = &ventas; /* despus del * no resultan
criticos. */
2. Usted puede inicializar punteros, igual que en el caso de las variables ordinarias, con
sentencias de asignacin. No hace falta inicializarlos er. el momento en que se los declara. Las
siguientes lneas de programa son equivalentes al cdigo del ejemplo anterior.

Observe que no se coloca el operador * delante de los nombres de las variables puntero cuando
se les asignan valores (direcciones de otras variables). Solo se los precede con * cuando se las
desreferencia.
char inicial;
int numero;
float ventas; /* Declara tres variables
ordinarias */
/* de tres tipos diferentes */
char *plnicial; /* Declara tres punteros pero todavia
int * punteroANumero; /* no los inicializa */
float * DireccionDeVentas;

inicial='Q';
numero=40;
ventas=2321.59; /* Inicializa las variables ordinarias
/* con valores */

plnicial=&inicial; /* Inicializa los punteros con "/
punteroANumero=№ /* las direcciones de sus */
direccionDeVentas=&ventas; /* correspondientes variables *

Observacin:

En este ejemplo, a las variables punteros se les podra
haber asignado las direcciones de las variables
ordinarias antes de que a estas ltimas se le hubiesen
asignado a su vez valores. La operacin del programa
no mostrara ninguna diferencia. A los punteros les son
asignadas las direcciones de las variables ordinarias sin
que importen para nada los valores que estas puedan
contener.


Mantenga consistencia en el tipo de cada puntero y su
correspondiente variable. No le asigne al puntero de una variable de
punto flotante la direccin de una variable de tipo entero. Por
ejemplo, no se puede efectuar la siguiente asignacin:

plnicial = &ventas; /* Asignacin de puntero invalida */
3. El programa siguiente es un ejemplo que usted debiera estudiar en forma
atenta. Ensea ms sobre los punteros y sus operadores, que lo que lo
podran hacer varias pginas de texto.

/* Filename: C20POINT.C
Demuestra el empleo de las declaraciones de punteros
y de su operadores */
#include <stdio.h>
main()
{
int numero=123; // Variable entera ordinaria
int *pNumero; // Declara un puntero de tipo entero
printf("El contenido de la variable numero es %d\n", numero);
// Imprime el valor de nmero
printf("La direccin de la variable numero es %ld \n", &numero) ;
// Imprime la ubicacin de numero

pNumero = &numero; // Asigna la direccin de numero a pNumero,
// haciendo que pNmero apunte hacia
// numero. No va ningn * delante de pNumero

printf ("*pNumero es %d \n", *pNumero) ; // Imprime el valor de
numero

printf ("pNumero es %ld \n", pNmero); // Imprime la direccin de
numero


La salida de este programa es la siguiente:

El contenido de la variable numero es 123

La direccin de la variable numero es 65522

*pNumero es 123

pNumero es 65522

Si usted hiciera ejecutar este programa, tal vez obtendra resultados
diferentes para el valor de pNumero, porque su compilador probablemente
colocara la variable numero en otra ubicacin de memoria, segn sea la
configuracin de su computadora. Sin embargo, la direccin efectiva no es lo
importante del ejemplo. Como el puntero pNumero siempre contendr la
direccin de la variable numero, y como usted puede en todos los casos
desreferenciar pNumero para obtener el valor alojado en numero, la direccin
efectiva no resulta crtica. Lo que s es crtico es que el programa pueda
encontrarla.
4. El programa siguiente incluye una funcin que
permuta los valores de dos nmeros enteros cualquiera
que le sean ingresados. Recuerde que una funcin
puede regresar un solo valor cada vez que es llamada.
Por lo tanto, hasta ahora, usted no poda escribir una
funcin que cambiase dos valores diferentes y retornase
ambos valores al mismo tiempo a la funcin que la haba
invocado.
Para permutar dos variables (intercambiando
sus valores para propsitos de ordenamiento,
como se vio en el Captulo 19, "Trabajo con
arreglos"), necesita contar con la posibilidad de
transferir ambas variables por direccin. En este
caso, cuando la funcin permute los valores de
las variables, los valores presentes en la funcin
invocante tambin resultarn permutados.
Observe el empleo que hace la funcin de
los operadores de desreferenciacin antes
de cada ocurrencia de numero1 y
numero2. Usted no debe preocuparse
respecto de las direcciones efectivas
donde estn almacenadas las variables
numero1 y numero2, sino que solo debe
asegurarse de desreferenciar las
direcciones que se le hayan transferido a
la funcin receptora.
Asegrese de transferir los argumentos
que sern recibidos por direccin
precedindolos del operador &, como se
hace aqu en main ().
/* Nombre de archivo: C20PERMT.C
Programa que incluye una funcin para permutar valores a la que se le transfieren
dos valores enteros */
tfinclude <stdio.h>
void permutarlos(int *numero1, int *numero2);
void main(void);
void main(void)
{
int i=10, j=20;
printf("\n\nAntes permutar sus valores, i vale %d y j vale
%d\n\n", i, j); permutarlos(&i, &j); printf("\n\nDespues de la permutacin, i vale %d y
j vale
%d\n\n", i, j); return 0;
}
void permutarlos(int *numero1, int *numero2)
int temp;temp = *numero1; ///* Variable auxiliar que almacena el valor de la
permutacin intermedia. *'/ Los asteriscos garantizan que sean las numl =
*numero2; // direcciones de las variables de la funcin invocante (y no los
valores de las mismas) las que se transfieran a esta.funcin
*num2 = temp; return 0;

Das könnte Ihnen auch gefallen