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

NDICE

Objetivo...2
Introduccin3
Conceptos de los apuntadores.4
Apuntadores4
Declaracin de apuntadores4
Los operadores de los apuntadores.5
Un operador de direccin &5
Un operador de indireccin o de desreferencia...5
Inicializacin de apuntadores..6
Apuntadores y funciones.7
Apuntadores y arreglos...7
Arreglos de apuntadores..8
Apuntadores y arreglos multidimensionales...9
Diferentes formas de declarar a[i][j] 11
Argumentos en la lnea de comandos12
Fallas comunes con apuntadores...12
Apuntadores de mayor complejidad..13
Conclusin.15
Bibliografa...16

OBJETIVO

INTRODUCCIN
Un puntero o apuntador es una variable que contiene la direccin de una posicin de
memoria. Esa posicin de memoria es la direccin de comienzo de una variable; la variable
puede ser dinmica.
El uso de estos en C supone, por su proximidad a las direcciones del lenguaje mquina, una
fuente de potencia y flexibilidad.
Son de amplia utilizacin en programacin y muchos lenguajes permiten la manipulacin
directa o indirecta de los mismos.
La principal razn de ser de los punteros es la de manejar datos alojados en la zona de
memoria dinmica o heap, bien sean datos elementales, estructuras (struct en C) u objetos
pertenecientes a una clase, gracias a esta propiedad, los punteros permiten modelar un
grafo, en donde los elementos de ste son los datos residentes en memoria y las relaciones
entre los elementos son los propios apuntadores.

CONCEPTOS DE LOS APUNTADORES


APUNTADORES
Los apuntadores son variables que almacenan direcciones de memoria. En general una
variable contiene un valor especfico dependiendo de cmo fue declarada.
Un apuntador contiene la direccin de una variable que contiene un valor especfico. Una
variable se refiere directamente a un valor y un apuntador se refiere indirectamente a un
valor.
Apuntadores usados en C debido a que a veces son la nica manera de expresar un clculo.
Se puede llegar a obtener un cdigo ms compacto y eficiente. Cuando se emplean sin
cuidado pueden crear programas imposibles de entender. Cuentan con una declaracin
propia.
Los apuntadores disponen de dos operadores:
El operador unario o mondico & devuelve la direccin de memoria de una
variable.
El operador de indireccin o desreferencia * devuelve el ``contenido de un objeto
apuntado por un apuntador''.

DECLARACIN DE APUNTADORES
Cuando se declara una variable, el compilador reserva un espacio de memoria para ella y
asocia el nombre de sta a la direccin de memoria desde donde comienzan los datos de esa
variable. Las direcciones de memoria se suelen describir como nmeros en hexadecimal.
Un apuntador es una variable cuyo valor es la direccin de memoria de otra variable. Se
dice que un apuntador apunta a la variable cuyo valor se almacena a partir de la direccin
de memoria que contiene el apuntador. Por ejemplo, si un apuntador p almacena la
direccin de una variable x, se dice que p apunta a x.
Los apuntadores como cualquier otra variable deben de ser declarados antes de que puedan
ser utilizados. El tipo de un apuntador lo proporciona implcitamente el tipo de la variable a
la que apunta. Los apuntadores pueden ser declarados para apuntar a objetos de cualquier
clase.
La sintaxis general de declaracin es:
<tipo> * <variable>
Ejemplos de declaraciones:
La variable contPtr es del tipo apuntador a entero, (int *) y se lee ``contPtr es un apuntador
a int'' o ``contPtr apunta a una variable entera''.
4

NOTA: Un apuntador a cualquier tipo de variables es una direccin en memoria, la cual es


una direccin entera, pero un apuntador NO es un entero.
La razn por la cual se asocia un apuntador a un tipo de dato, es porque se debe conocer en
cuantos bytes est guardado el dato. De tal forma, que cuando se incrementa un apuntador,
se incrementa el apuntador por un ``bloque'' de memoria, en donde el bloque est en
funcin del tamao del dato. Por lo tanto para un apuntador a un char, se agrega un byt a la
direccin y para un apuntador a entero o a flotante se agregan 4 bytes. De esta forma si a un
apuntador a flotante se le suman 2, el apuntador entonces se mueve dos posiciones float que
equivalen a 8 bytes.

LOS OPERADORES DE LOS APUNTADORES


UN OPERADOR DE DIRECCIN &
Representa la direccin de memoria de la variable que le sigue; operador unario que regresa
la direccin de su operando, ejemplo:
main()
{
int y;
int *yPtr;
y = 5;
yPtr = &y;
}

UN OPERADOR DE INDIRECCIN O DE DESREFERENCIA


El operador * aplicado al nombre de un apuntador indica el valor de la variable apuntada;
Regresa el valor del objeto hacia el cual su operando apunta, es decir un apuntador,
ejemplo:
main()
{
int x,y;
int *py;
y = 5;
*py = y;
x = *py + 5;
printf(''%d %d nn'',*py,x);
}
Veamos con un ejemplo en C la diferencia entre todos estos conceptos.
Es decir: int x = 25, *pint;
pint = &x;
5

La variable pint contiene la direccin de memoria de la variable x. La expresin: *pint


representa el valor de la variable (x) apuntada, es decir 25. La variable pint tambin tiene su
propia direccin: &pint

INICIALIZACIN DE APUNTADORES
< Almacenamiento > < Tipo > * < Nombre > = < Expresin >
Si <Almacenamiento> es extern o static, <Expresin> deber ser una expresin constante
del tipo <Tipo> expresado.
Si <Almacenamiento> es auto, entonces <Expresin> puede ser cualquier expresin del
<Tipo> especificado.
Ejemplos:
La constante entera 0, NULL (cero) proporciona un apuntador nulo a cualquier tipo
de datos:
int *p;
p = NULL; //actualizacin
El nombre de un arreglo de almacenamiento static o extern se transforma segn la
expresin:
a) float mat[12];
float *punt = mat;
b) float mat[12];
float *punt = &mat[0];
Un cast apuntador a apuntador:
int *punt = (int *) 123.456;
Inicializa el apuntador con el entero. Esto es, en la direccin a la que apunta la variable
punt se almacena el valor 123.
Un apuntador a carcter puede inicializarse en la forma:
char *cadena = Esto es una cadena;
Se pueden sumar o restar valores enteros a las direcciones de memoria en la forma:
(aritmtica de APUNTADORES)
static int x;
int *punt = &x+2, *p = &x-1;
Equivalencia: Dos tipos definidos como APUNTADORES a objeto P y apuntador a
objeto son equivalentes slo si P y Q son del mismo tipo. Aplicado a matrices:
nombre_apuntador = nombre_matriz;
6

APUNTADORES Y FUNCIONES
Cuando C pasa argumentos a funciones, los pasa por valor, es decir, si el parmetro es
modificado dentro de la funcin, una vez que termina la funcin el valor pasado de la
variable permanece inalterado.
Hay muchos casos que se quiere alterar el argumento pasado a la funcin y recibir el nuevo
valor una vez que la funcin ha terminado. Para hacer lo anterior se debe usar una llamada
por referencia, en C se puede simular pasando un puntero al argumento. Con esto se
provoca que la computadora pase la direccin del argumento a la funcin.
Para entender mejor lo anterior consideremos la funcin swap() que intercambia el valor de
dos argumentos enteros:
void swap(int *px, int *py);
main()
{
int x, y;
x = 10;
y = 20;
printf("x=%d\ty=%d\n",x,y);
swap(&x, &y);
printf("x=%d\ty=%d\n",x,y);
}
void swap(int *px, int *py)
{
int temp;
temp = *px; /* guarda el valor de la direccin x */
*px = *py; /* pone y en x */
*py = temp; /* pone x en y */

APUNTADORES Y ARREGLOS
Existe una estrecha relacin entre apuntadores y arreglos, tanto que pueden ser usados en
forma casi indistinta. En C, un nombre de un arreglo es un ndice a la direccin de
comienzo del arreglo. En esencia, el nombre de un arreglo es un puntero al arreglo.
Una variable de tipo arreglo puede considerarse como un apuntadora tipo del arreglo.
Los apuntadores pueden ser utilizados en cualquier operacin que involucre subndices de
arreglos.

Ejemplo:
main()
{
int tabla[10],i,x,*pt,*ptr;
pt = &tabla[0];
x = *pt;
for (i=0; i!10; i++)
*(pt+i) = random();
ptr = tabla;
for (i=0; i!10; i++)
printf(''%d nn'',*(ptr+i),tabla[i]);
}
Cuando se suma 1 a un apuntador el incremento se adecua al tamao en memoria del objeto
apuntado.
Un apuntador es una variable, por lo que operaciones como pa = a y pa++ son permitidas.
Un nombre de un arreglo es una constante, no una variable, de ah que a = pa o a++ o p = a.

ARREGLOS DE APUNTADORES
Los arreglos pueden contener apuntadores. El uso ms comn es el de formar arreglos de
cadenas de caracteres. Cada entrada en el arreglo es un apuntador al primer carcter de la
cadena. Sea la declaracin:
char * mensaje[4] = {''Hola'',''Adios'',''Bye'',''Salut''}
Cada cadena est almacenada en memoria como una cadena de caracteres terminada en
NULL n0. En el arreglo no estn colocadas las cadenas, tan solo estn almacenados los
apuntadores. Aunque el arreglo es de tamao fijo, permite el acceso a cadenas de caracteres
de cualquier longitud. En C se pueden tener arreglos de apuntadores ya que los apuntadores
son variables.
A continuacin se muestra un ejemplo de su uso: ordenar las lneas de un texto de diferente
longitud.
Los arreglos de apuntadores son una representacin de datos que manejan de una forma
eficiente y conveniente lneas de texto de longitud variable.
Cmo se puede hacer lo anterior?
Guardar todas las lneas en un arreglo de tipo char grande. Observando que \n marca
el fin de cada lnea. Ver figura 1.1.
Guardar los apuntadores en un arreglo diferente donde cada apuntador apunta al
primer carcter de cada lnea.
Comparar dos lneas usando la funcin de la biblioteca estndar strcmp().

Si dos lneas estn desacomodadas -- intercambiar (swap) los apuntadores (no el


texto).

Figura 1.1: Arreglos de apuntadores (Ejemplo de ordenamiento de cadenas).


Con lo anterior se elimina:
El manejo complicado del almacenamiento.
Alta sobrecarga por el movimiento de lneas.

APUNTADORES Y ARREGLOS MULTIDIMENSIONALES


Puede provocar confusin el uso de arreglos de dos dimensiones y un arreglo de
apuntadores. Considerar:
int a[10][10];
int *b[10];
El uso de a y b puede ser parecido, desde el momento en que a[5][5] y b[5][5] son
referencias validas a un int.
El arreglo a es un arreglo verdadero, existen 100 celdas de memoria asignadas y se efecta
el clculo de subndices rectangulares convencional para localizar un elemento dado.
Sin embargo, a b la declaracin solo le asigna 10 apuntadores, cada uno de los cuales
deber de apuntar a un arreglo de enteros.
Las desventajas de b son:
Ocupa ms espacio, suponiendo que cada uno apunta a un arreglo de 10 elementos,
el tamao ser de 10 apuntadores ms 100 elementos.
Se debe de crear el espacio de los arreglos antes de asignarlos.
La declaracin b tiene dos ventajas:
El acceso se hace ms rpido, una indireccin es ms rpida que el hacer una
multiplicacin seguida de una suma.
El tamao de los arreglos apuntados por cada una de las diez localidades pueden
ser diferentes.
9

Un arreglo multidimensional puede ser visto en varias formas en C, por ejemplo:


Un arreglo de dos dimensiones es un arreglo de una dimensin, donde cada uno de los
elementos es en s mismo un arreglo. Por lo tanto, la notacin:
a[n][m]
Nos indica que los elementos del arreglo estn guardando rengln por rengln.
Cuando se pasa una arreglo bidimensional a una funcin se debe especificar el nmero de
columnas -- el nmero de renglones es irrelevante.
La razn de lo anterior, es nuevamente los apuntadores. C requiere conocer cuantas son las
columnas para que pueda brincar de rengln en rengln en la memoria.
Considerando que una funcin deba recibir int a[5][35], se puede declarar el argumento de
la funcin como:
f( int a[][35] ) { ..... }
o an
f( int (*a)[35] ) { ..... }
En el ltimo ejemplo se requieren los parntesis (*a) ya que [ ] tiene una precedencia ms
alta que *. Por lo tanto:
int (*a)[35]; declara un apuntador a un arreglo de 35 enteros, y por ejemplo si
hacemos la siguiente referencia a+2, nos estaremos refiriendo a la direccin del
primer elemento que se encuentran en el tercer rengln de la matriz supuesta,
mientras que
int *a[35]; declara un arreglo de 35 apuntadores a enteros.
Ahora veamos la diferencia (sutil) entre apuntadores y arreglos. El manejo de cadenas es
una aplicacin comn de esto. Considera:
char *nomb[10];
char anomb[10][20];
En donde es vlido hacer nomb[3][4] y anomb[3][4] en C. Sin embargo: anomb es un
arreglo verdadero de 200 elementos de dos dimensiones tipo char.
El acceso de los elementos anomb en memoria se hace bajo la siguiente
frmula 20*renglon + columna + direccin_base. En cambio nomb tiene 10 apuntadores a
elementos.

NOTA: si cada apuntador en nomb indica un arreglo de 20 elementos entonces y


solamente entonces 200 chars estarn disponibles (10 elementos).
Con el primer tipo de declaracin se tiene la ventaja de que cada apuntador puede apuntar a
arreglos de diferente longitud. Considerar:

10

char *nomb[] = { "No mes", "Ene", "Feb", "Mar", .... };


char anomb[][15] = { "No mes", "Ene", "Feb", "Mar", ... };
Lo cual grficamente se muestra en la figura 1.2. Se puede indicar que se hace un manejo
ms eficiente del espacio haciendo uso de un arreglo de apuntadores y usando un arreglo
bidimensional.

Figura 1.2: Arreglo de 2 dimensiones VS arreglo de apuntadores.

DIFERENTES FORMAS DE DECLARAR a[i][j]


Cuando se ve la referencia a un arreglo de dos dimensiones, a[i][j] , no se puede deducir
inmediatamente como fue declarado a:}
Como un arreglo de 10 arreglos de tamao 20:
int a[10][20];
Como un arreglo de tamao 20 de vectores de longitud variable:
int *a[10];
Como un apuntador de apuntadores a enteros:
int **a;
Como un apuntador a un arreglo de enteros de tama~no 20:
int (* a)[20];
Para poder direccionar un elemento de un apuntador de apuntadores se sigue la regla:
tab[i][j] * ( *(tab + i) + j)

11

ARGUMENTOS EN LA LNEA DE COMANDOS


Existe una forma de transmitir al programa los argumentos de la lnea de comando, o
parmetros, cuando comienza la ejecucin Cuando se invoca el main() se le puede pasar
dos argumentos, (los nombres son por convencin):
argc es el nmero de argumentos en la lnea de comandos.
argv[] es un apuntador a un arreglo de cadena de caracteres que contienen los
argumentos, uno por cadena.
Ejemplo de uso:

main( int argc, char *argv[])


{
int i;
for (i=0; i!argc; i++)
printf(''Argumento %d :'' %s'',);
}

Ya que el primer elemento del arreglo, (*argv[]) apunta a la cadena que contiene el nombre
del comando, argc es al menos igual a 1.
Esta estructura de datos es creada por el sistema operativo, (Unix u otro), por lo que la
nica preocupacin del programador es usarla, no generarla.

FALLAS COMUNES CON APUNTADORES


A continuacin se muestran dos errores comunes que se hacen con los apuntadores:
No asignar un apuntador a una direccin de memoria antes de usarlo:
int *x
*x = 100;
Lo adecuado ser, tener primeramente una localidad fsica de memoria, digamos int y;
nt *x, y;
x = &y;
*x = 100;
Indireccin no vlida:
Supongamos que se tiene una funcin llamada malloc() la cual trata de asignar memoria
dinmicamente (en tiempo de ejecucin), la cual regresa un apuntador al bloque de
memoria requerida si se pudo o un apuntador a nulo en otro caso.
char *malloc() -- una funcin de la biblioteca estndar que se ver ms adelante.
Supongamos que se tiene un apuntador char *p.

12

Considerar:
*p = (char *) malloc(100): /* pide 100 bytes de la memoria */
*p = 'y';
Existe un error en el cdigo anterior. Cul es?
El * en la primera lnea ya que malloc regresa un apuntador y *p no apunta a ninguna
direccin. El cdigo correcto deber ser:
p = (char *) malloc(100);
Ahora si malloc no puede regresar un bloque de memoria, entonces p es nulo, y por lo tanto
no se podr hacer:
*p = 'y';
Un buen programa en C debe revisar lo anterior, por lo que el cdigo anterior puede ser
reescrito como:
p = (char *) malloc(100): /* pide 100 bytes de la memoria */
if ( p == NULL )
{
printf("Error: fuera de memoria\n");
exit(1);
}
*p = 'y';

APUNTADORES DE MAYOR COMPLEJIDAD


int *p;
int *p[10];
int (*p)[10];
int *p(void);
int p(char *a);
int *p(char *a);
int (*p)(char *a);
int (*p(char *a))[10];
int p(char (*a)[]);
int p(char *a[]);
int *p(char a[]);

p es un apuntador a un entero.
p es un arreglo de 10 apuntadores a enteros.
p es un apuntador a un arreglo de 10 enteros.
p es una funcin que devuelve un apuntador a entero.
p es una funcin que acepta un argumento que es un
apuntador a carcter, devuelve un entero.
p es una funcin que acepta un argumento que es un
apuntador a carcter, devuelve un apuntador a entero.
p es un apuntador a funcin que acepta un argumento que es
un apuntador a carcter, devuelve un apuntador a entero.
p es una funcin que acepta un argumento que es un
apuntador a carcter, devuelve un apuntador a un arreglo de
10 enteros.
p es un apuntador a funcin que acepta un argumento que es
un apuntador a un arreglo de caracteres, devuelve un
apuntador a entero.
p es un apuntador a funcin que acepta un argumento que es
un arreglo de apuntadores a caracteres, devuelve un apuntador
a entero.
p es una funcin que acepta un argumento que es un arreglo
13

int *p(char (*a)[]);


int *p(char *a[]);
int (*p)(char (*a)[]);
int *(*p)(char (*a)[]);
int *(*p)(char *a[]);
int(*p[10])(void);
int (*p[10])(char * a);
int *(*p[10])(char a);
char *(*p[10])(char *
a);

de caracteres, devuelve un apuntador a entero.


p es una funcin que acepta un argumento que es un
apuntador a un arreglo de caracteres, devuelve un apuntador a
entero.
p es una funcin que acepta un argumento que es un
apuntador a un arreglo de apuntadores a caracteres, devuelve
un apuntador a entero.
p es una funcin que acepta un argumento que es un
apuntador a un arreglo de caracteres, devuelve un apuntador a
entero.
p es un apuntador a una funcin que acepta un argumento que
es un apuntador a un arreglo de apuntadores a caracteres,
devuelve un apuntador a entero.
p es un apuntador a una funcin que acepta un argumento que
es un arreglo de apuntadores a caracteres, devuelve un
apuntador a entero.
p es un arreglo de 10 apuntadores a funcin, cada funcin
devuelve un entero.
p es un arreglo de 10 apuntadores a funcin; cada funcin
acepta un argumento que es un apuntador a carcter y
devuelve un entero.
p es un arreglo de 10 apuntadores a funcin; cada funcin
acepta un argumento que es un carcter, y devuelve un
apuntador a entero.
p es un arreglo de 10 apuntadores a funcin; cada funcin
acepta un argumento que es un carcter, y devuelve un
apuntador a carcter.

14

CONCLUSIN

15

BIBLIOGRAFA
http://html.rincondelvago.com/apuntadores-en-lenguajes-de-programacion.html

16

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