Está en la página 1de 9

PD

H F-XC A N GE

PD

H F-XC A N GE

O W !

bu

to

lic

lic

to

bu

N
.c

O W !
w
.d o

.d o

c u-tr a c k

c u-tr a c k

.c

Lenguaje C PUNTEROS

2007

Un Puntero es una variable que contiene como valor una direccin de memoria de otra variable.

Declaracin de un Puntero.Un puntero apunta a una variable, es por esta razn que al declarar una variable tipo puntero se debe indicar el tipo de variable a la cual el puede apuntar. Si se desea declarar una variable tipo puntero a variables tipo entero se indica: int *p ; De manera general sera lo siguiente: Tipo *nombre_puntero; Ejemplo: float *sueldoptr; Sueldoptr es un puntero a variable tipo float. Todo apuntador o puntero, debe ser declarado con el prefijo * al nombre. Algunos autores recomiendan agregar como sufijo al nombre las letras ptr para recordar que se trata de una variable puntero y debe ser manejada de manera apropiada.

OPERADORES DE PUNTEROS.Existen dos operadores de apuntador o punteros: & y * . El operador & es un operador monario que devuelve la direccin de memoria de su operando. Es decir, para asignar a la variable puntero sueldo la direccin de

memoria de la variable cuenta, utilizamos el operador & de la siguiente manera: Sueldoptr = &cuenta ; Grficamente lo podramos representar as:
Cuenta Sueldoptr AA00

Direccin de Memoria

AA00

Guia Preparada por: .............................................................................................NEREYDA CARRERO MIRANDA

47

w
w

w
w

PD

H F-XC A N GE

PD

H F-XC A N GE

O W !

bu

to

lic

lic

to

bu

N
.c

O W !
w
.d o

.d o

c u-tr a c k

c u-tr a c k

.c

Lenguaje C

2007

De otra forma sera:

Cuenta

Sueldoptr

El operador * es un operador monario que apunta al valor de la variable cuya direccin est contenida en el puntero. Ejemplo: si deseamos almacenar el valor 120000 en la variable cuenta, podemos hacerlo de varias formas: Utilizando el operador de apuntador: sueldoptr = &cuenta; *sueldoptr = 120000; O a travs de las formas convencionales: asignando el valor directamente por medio de una operacin de asignacin; o a travs de una operacin de lectura.

Grficamente sera:
Cuenta 120000 Sueldoptr

Otra forma de verlo; asumiendo que cuenta contiene el valor 120000 sueldoptr = &cuenta; k = *sueldoptr;

Estas instrucciones hacen que el valor de cuenta se guarde en k, por lo tanto el valor de k es 120000.

Guia Preparada por: .............................................................................................NEREYDA CARRERO MIRANDA

48

w
w

w
w

PD

H F-XC A N GE

PD

H F-XC A N GE

O W !

bu

to

lic

lic

to

bu

N
.c

O W !
w
.d o

.d o

c u-tr a c k

c u-tr a c k

.c

Lenguaje C
ARITMETICA DE PUNTEROS.-

2007

Un conjunto limitado de operaciones aritmticas se pueden ejecutar con punteros. Un puntero puede ser incrementado ( + + ) o decrementado (-- ), se puede aadir un entero a un puntero, o restar un entero de un puntero, o un puntero puede ser sustrado o restado de otro. Suponga que se declara el arreglo p[ 5 ] y su primer elemento est en memoria en la posicin 3000. Suponga que se declara el puntero a entero pptr que se inicializa para apuntar a p[0 ]m es decir, el valor de pptr es 3000. En una mquina con enteros de 4 bytes sera lo siguiente: Posicin
3000 3004 3008 3012 3016

pptr

p[ 0 ]

p[ 1 ]

p[ 2 ]

p[ 3 ]

p[ 4 ]

Observe que pptr puede ser inicializado para apuntar a p[ 0 ] con cualquiera de los enunciados: pptr = p; pptr = &p[ 0 ]; En aritmtica convencional, la adicin 3000 + 2 da como resultado 3002. Por lo general, este no es el caso en la aritmtica de punteros. Cuando se aade o se resta un entero de un puntero, no se incrementa o decrementa solo por el valor de dicho entero, sino por el entero multiplicado por el tamao del objeto al cual el apuntador se refiere. El nmero de bytes depende del tipo de datos del objeto. Por ejemplo, el enunciado pptr + = 2; producira 3008, es decir, (3000 + 2*4), suponiendo un entero almacenado en 4 bytes de memoria. Ahora, pptr sealara a p[ 2 ]

Guia Preparada por: .............................................................................................NEREYDA CARRERO MIRANDA

49

w
w

w
w

PD

H F-XC A N GE

PD

H F-XC A N GE

O W !

bu

to

lic

lic

to

bu

N
.c

O W !
w
.d o

.d o

c u-tr a c k

c u-tr a c k

.c

Lenguaje C

2007

Si se trata de una mquina que almacena un entero en 2 bytes de memoria, entonces del clculo anterior resultara una posicin de memoria de 3004, es decir, (3000 + 2*2). Si el arreglo es de un tipo diferente de datos, el clculo anterior incrementara el puntero por dos veces el nmero de bytes que toma para almacenar un objeto de dicho tipo de datos. Al ejecutar aritmtica de punteros en un arreglo de caracteres, los resultados sern consistentes con la aritmtica normal, porque cada carcter tiene la longitud de un byte. Si pptr ha sido incrementado a 3016, lo que seala a p[ 4 ], el enunciado: pptr - = 4; Definira a pptr de vuelta a 3000, es decir, al comienzo del arreglo, en una mquina que almacena un entero en 4 bytes. Cualquiera del los enunciados: + + pptr; pptr + +-; incrementan al puntero para que apunte a la siguiente posicin. Y - - pptr; pptr- -; decrementan el apuntador, para que apunte al elemento anterior del arreglo. Las variables punteros pueden ser restadas una de otra. Por ejemplo, si pptr contiene la posicin 3000 y p2ptr contiene la posicin 3008, el enunciado: x = p2ptr pptr; Asignara a x el nmero de los elementos del arreglo de pptr hasta p2ptr, en este caso 2. La aritmtica de apuntadores no tiene significado, a menos que se ejecute en un arreglo. No podemos suponer que dos variables del mismo tipo estn almacenadas en forma contigua en memoria, a menos que sean elementos adyacentes en un arreglo. Tampoco tiene sentido restar dos punteros que no se refieran al mismo arreglo. 50

Guia Preparada por: .............................................................................................NEREYDA CARRERO MIRANDA

w
w

w
w

PD

H F-XC A N GE

PD

H F-XC A N GE

O W !

bu

to

lic

lic

to

bu

N
.c

O W !
w
.d o

.d o

c u-tr a c k

c u-tr a c k

.c

Lenguaje C

2007

Un puntero puede ser asignado a otro puntero, si ambos son del mismo tipo. La excepcin de esta regla es el puntero a void* , que es un puntero genrico, que puede representar cualquier tipo de puntero. Todos los tipos de punteros, pueden ser asignados a un puntero void y un puntero void puede ser asignado a un puntero de cualquier tipo. Un puntero void no puede ser utilizado como referencia. Por ejemplo, el

compilador sabe que un puntero a int se refiere a 4 bytes, en memoria en una mquina con enteros de 4 bytes, pero un puntero a void solo contiene una posicin de memoria para un tipo de datos desconocido, es decir, el nmero preciso de bytes a los que se refiere el puntero no es conocido para el compilador. Y el compilador debe saber el tipo de datos para determinar el nmero de bytes a referenciar. En el caso de un puntero void, el nmero de bytes no puede ser determinado partiendo del tipo. Los punteros pueden ser comparados mediante operadores de igualdad y relacionales, pero dichas comparaciones solo tendrn sentido cuando sealen a miembros de un mismo arreglo. Las comparaciones de punteros, comparan las Una comparacin podra mostrar, por

direcciones almacenadas en los mismos.

ejemplo, que un puntero seale a un elemento de numeracin mas alta en el arreglo que el otro.

RELACION ENTRE PUNTEROS Y ARREGLOS.En C existe una fuerte relacin entre punteros y arreglos. La declaracin: int ed[ 5 ]; define un arreglo ed de tamao 5, es decir, un arreglo con 5 posiciones referenciadas ed[ 0 ], ed[1], .....,ed[ 5 ], donde ed[ i ] hace referencia al i-esimo elemento del arreglo. Si paptr es un puntero a un entero, declarado: int *paptr; entonces la asignacin: paptr = &ed[ 0 ];

Guia Preparada por: .............................................................................................NEREYDA CARRERO MIRANDA

51

w
w

w
w

PD

H F-XC A N GE

PD

H F-XC A N GE

O W !

bu

to

lic

lic

to

bu

N
.c

O W !
w
.d o

.d o

c u-tr a c k

c u-tr a c k

.c

Lenguaje C

2007

hace que apunte al elemento cero de ed, es decir, paptr contiene la direccin de ed[ 0 ].

paptr

ed[ 0 ] ed[ 1 ] ed[ 2 ] ed[ 3 ] ed[ 4 ]

La asignacin: y = *paptr; Copiar el contenido de ed[ 0 ] en y. Si paptr apunta a un elemento particular de un arreglo, entonces paptr + 1 apunta al siguiente elemento, paptr + i apunta i elementos despus de paptr, y paptr i , apunta i elementos antes. Por tanto, *(paptr + 1) se refiere al contenido de ed[ 1 ]. En general, si paptr apunta a ed[ 0 ], entonces ed[ i ] es equivalente a *(paptr + i ) y paptr + i = &ed[ i ] El nombre de un arreglo puede ser considerado como un puntero constante a la direccin del primer elemento

ed ed[ 0 ]

Por tanto, el enunciado paptr = &ed[ 0 ] es equivalente al enunciado paptr = ed Aunque existe una diferencia entre un nombre de arreglo y un puntero. Un puntero es una variable, por eso se puede asignar paptr = paptr + 1 y es vlido. Pero un nombre de arreglo no es una variable, por eso, la asignacin ed = ed + 1 no es vlida.

Guia Preparada por: .............................................................................................NEREYDA CARRERO MIRANDA

52

w
w

w
w

PD

H F-XC A N GE

PD

H F-XC A N GE

O W !

bu

to

lic

lic

to

bu

N
.c

O W !
w
.d o

.d o

c u-tr a c k

c u-tr a c k

.c

Lenguaje C

2007

Los punteros pueden tener subndice como los arreglos. Ejemplo: paptr[ 1 ] se refiere al elemento del arreglo ed[ 1 ]. En general, todas las expresiones de arreglos con subndice pueden ser escritas con punteros.

El siguiente programa hace referencia a los elementos de un arreglo utilizando diferentes anotaciones: notacin de arreglos con subndice, notacin de puntero / desplazamiento con el nombre del arreglo como puntero, notacin de puntero con subndice, y puntero / desplazamiento con puntero para imprimir los elementos de un arreglo entero b.

/* UTILIZACION DE NOTACION CON SUBINDICE Y PUNTEROS EN ARREGLOS */ # include<stdio.h> void main( ) { int i, b[ 4 ] = { 10, 20, 30, 40 }; int *bptr = b; printf("Impresion del arreglo b con: \n"); printf("Notacion de arreglos con subindices\n"); for ( i = 0; i<=3; i++) printf("b[ %d ] = %d \n", i, b[i] ); printf(" Impresion con puntero/desplazamiento \n"); for ( i = 0; i<= 3; i++) printf("*( b + %d ) = %d \n", i, *( b + i )); printf(" Impresion con puntero con subindice \n"); for ( i = 0; i<=3; i++) printf("bptr[ %d ] = %d \n", i, bptr[ i ]); printf(" Impresion con puntero/desplazamiento con puntero \n"); for ( i = 0; i<= 3; i++) printf("*( bptr + %d ) = %d \n", i, *( bptr + i )); getch(); }
Guia Preparada por: .............................................................................................NEREYDA CARRERO MIRANDA

53

w
w

w
w

PD

H F-XC A N GE

PD

H F-XC A N GE

O W !

bu

to

lic

lic

to

bu

N
.c

O W !
w
.d o

.d o

c u-tr a c k

c u-tr a c k

.c

Lenguaje C

2007

Ya se mencion que una cadena de caracteres es un arreglo de caracteres. En la representacin interna, el arreglo termina con el carcter nulo \ 0. La declaracin char *mensajeptr; Define la variable mensajeptr como un apuntador a caracteres. El enunciado: mensajeptr = TODO HA TERMINADO ; Asigna a mensaje ptr la direccin de inicio del arreglo de caracteres. Es decir, mensaje ptr es un apuntador inicializado para apuntar a una cadena constante.

ARREGLOS DE PUNTEROS.Puesto que los punteros son variables, pueden estructurarse en arreglos. La declaracin int *a[ 10 ]; define un arreglo de 10 punteros a enteros. Los arreglos de punteros se usan para almacenar cadenas de caracteres. En esta caso cada elemento del arreglo es un puntero que indica donde empieza cada cadena. Cada entrada en el arreglo es una cadena, pero en C una cadena es un puntero a su primer carcter. Por lo que en un arreglo de cadenas de caracteres, cada entrada es de hecho un puntero al primer carcter de una cadena. En la siguiente declaracin: char *nombre[4] = { LUIS , MARA , ALICIA , ROBERTO }; nombre[ 4 ] indica un arreglo de 4 elementos. char * indica que cada elemento del arreglo nombre es del tipo apuntador a char. Los cuatro valores a colocarse en el arreglo: LUIS , MARIA , ROBERTO , ALEJANDRA , estn almacenados en memoria, cada uno como una cadena terminada por NULL, de una longitud de un carcter mas largo que el nmero de caracteres entre comillas. Las cuatro cadenas son de 5, 6, 8, 10 caracteres de longitud, respectivamente. Aunque pareciera como si estas cadenas

Guia Preparada por: .............................................................................................NEREYDA CARRERO MIRANDA

54

w
w

w
w

PD

H F-XC A N GE

PD

H F-XC A N GE

O W !

bu

to

lic

lic

to

bu

N
.c

O W !
w
.d o

.d o

c u-tr a c k

c u-tr a c k

.c

Lenguaje C

2007

estn colocadas en el arreglo nombre, en el arreglo solo estn almacenados los apuntadores, como sigue:

nombre[ 0 ]

L U I S \ 0

nombre[ 1 ]

M A R

I A \ 0

nombre[ 2 ]

A L I C I A \ 0

nombre[ 3 ]

R O B E R T 0 \ 0

Cada puntero seala al primer carcter de su cadena correspondiente. Por lo tanto, aunque el arreglo nombre es de tamao fijo, permite el acceso a cadenas de cualquier longitud. Los nombres podran haber sido colocados en un arreglo bidimensional, en el cual cada fila representara un nombre, y cada columna representara un carcter del nombre. Una estructura de datos como esta tiene un nmero fijo de columnas por fila, y dicho nmero debe ser igual que el nombre mas largo. Por tanto, se desperdicia espacio de memoria, cuando se tiene que almacenar un gran nmero de nombres, donde la mayora de ellos son cadenas mas cortas que el nombre mas largo.

Guia Preparada por: .............................................................................................NEREYDA CARRERO MIRANDA

55

w
w

w
w

También podría gustarte