Académique Documents
Professionnel Documents
Culture Documents
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 !
.d o
c u-tr a c k
.d o
c u-tr a c k
.c
como declarar e inicializar punteros. Tambin veremos los operadores de punteros y la relacin entre punteros y arreglos.
Introduccin a la Clase
Antes de tratar el tema de Punteros es conveniente repasar un concepto bsico, ya visto y ampliamente manejado a lo largo de este curso. F Bien. Recuerdan a qu llamamos variable?
En trminos de computacin, una variable es una localidad de memoria, donde se guarda un valor
para su uso en un programa, dicho valor puede cambiar durante la ejecucin de un programa. F Cules son las partes que tiene una variable?
1500000
Valor de la Variable
Sueldo
Nombre de la Variable
F Muy bien, ahora estamos listos para empezar el estudio de los Punteros.
Cuerpo la Clase
F Por qu estudiar el tema de Punteros?
Porque son usados frecuentemente en Lenguaje C y tienen gran cantidad de aplicaciones. Por
ejemplo, pueden ser usados para trasladar informacin entre una funcin y sus puntos de llamada. Los punteros proporcionan una forma de devolver datos desde una funcin a travs de sus argumentos.
Los punteros, adems, estn muy relacionados con los arreglos y proporcionan una va
alternativa de acceso a los elementos individuales del arreglo.
Por otro lado, los punteros permiten crear y manipular estructuras de datos que pueden crecer o
encogerse como son las pilas, las listas enlazadas, las colas y los rboles.
w
w
w
w
PD
H F-XC A N GE
PD
H F-XC A N GE
O W !
bu
Punteros
m
C lic
to
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
F Ahora, Qu es un Puntero? Un Puntero es una variable que contiene como valor una direccin de memoria de otra variable. Por ejemplo: Si tenemos una variable llamada pago cuya direccin de memoria es AA77 y tenemos un puntero llamado pagoptr cuyo valor es AA77, entonces podemos decir que el puntero pagoptr apunta a la variable pago. Grficamente lo podramos ilustrar como sigue: pagoptr pago
pagoptr se refiere en forma indirecta a la variable
70000
AA77
pago 70000
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.
Todo 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. La instruccin para declarar la variable pago y la variable puntero pagoptr sera : float pago, *pagoptr ;
F Cmo hacemos para asignar al puntero pagoptr la direccin de memoria de la variable pago?
Para asignar al puntero pagoptr la direccin de memoria de la variable pago se utiliza el operador
de punteros &
El operador & llamado operador de direccines un operador unario que devuelve la direccin
de memoria de su operando. Es decir, para asignar a la variable puntero pagoptr la direccin de memoria de la variable pago, utilizamos el operador & de la siguiente manera: pagoptr = &pago ;
pago
70000 AA77 Direccin de Memoria
w
w
w
w
PD
H F-XC A N GE
PD
H F-XC A N GE
O W !
bu
Punteros
m
C lic
to
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
Desde el momento en un puntero apunta a una variable los datos de esa variable pueden ser
accedidos a travs del puntero.
Cmo acceder a los datos de la variable pago a travs del puntero pagoptr?
Lo haremos a travs de operador de puntero * llamado operador de indireccin
El operador * es un operador unario que hace referencia al valor de la variable cuya direccin
est contenida en el puntero. Por tanto, *pagoptr y pago representan el mismo valor almacenado en la memoria.
La instruccin:
k = *pagoptr; har que en la variable k se guarde el valor de la variable pago, es decir, k vale 70000
p = &tot; do { clrscr(); con++; printf("\nINGRESE UN VALOR PARA NUM: "); scanf("%d",&num); *p = *p + num; } while (con < 3);
w
w
w
w
PD
H F-XC A N GE
PD
H F-XC A N GE
O W !
bu
Punteros
m
C lic
to
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
F El enunciado:
p = &tot;
F El enunciado:
*p = *p + num;
Acumula el valor de la variable num en la variable a la cual hace referencia el puntero p. Es decir, acumula el valor de num en la variable tot Si se ejecuta este programa para los valores: 13 18 14 se imprimir:
El promedio de los datos es: 15
F Un puntero puede utilizarse a la derecha de una instruccin de asignacin, para asignar un puntero a otro puntero, como se muestra en el siguiente programa:
printf("\n Valores apuntados por p1 y p2: %d y %d",*p1,*p2); printf("\n Direcciones guardadas en p1 y p2: %p y %p",p1,p2); getch(); }
En este programa se declaran dos punteros: p1 y p2. Posteriormente a p1 se le asigna la direccin de la variable x, y luego a p2 se le asigna p1. Por tanto, p1 y p2 quedan apuntando a la variable x. Para imprimir la direccin de la variable x, guardada tanto en el puntero p1 como en p2, se utiliza el especificador de formato %p
w
w
w
w
PD
H F-XC A N GE
PD
H F-XC A N GE
O W !
bu
Punteros
m
C lic
to
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
Se puede apreciar que se asigna la direccin del la variable sueldo de tipo float a un puntero a enteros: sueldoptr. Esto provoca un error, no permite que el programa produzca el resultado deseado. Cul es el problema? Asumamos que en el computador donde se ejecuta el programa, un entero se almacena en 4 bytes y un flotante se almacena en 8 bytes. Como sueldoptr es un puntero a enteros solo se transfieren 4 bytes y no los 8 bytes correspondientes al valor de sueldo
Veamos, ahora, algo sobre la Aritmtica de Punteros Slo dos operaciones aritmticas se pueden utilizar con los punteros: suma y resta. 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 restado de otro. Si declararmos un arreglo unidimensional llamado a de 4 elementos, cuyo primer elemento se almacena en la direccin de memoria 3000, en un computador con enteros de 4 bytes. Y se declara un puntero llamado b
int a [ 4 ] , *b ; Podemos inicializar al puntero b para que apunte al arreglo a con cualquiera de las siguientes instrucciones: b=&a[0]; b= a;
w
w
w
w
PD
H F-XC A N GE
PD
H F-XC A N GE
O W !
bu
Punteros
m
C lic
to
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
Porque el nombre de un vector contiene la direccin de memoria del primer elemento. Grficamente, sera lo siguiente: b a[0] a[1] a[2] a[3]
3000
3004
3008
3012
F El puntero b apunta a la posicin 3000. 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 puntero se refiere. Por ejemplo, en este caso, el enunciado b + = 2; Producira 3008, es decir, (3000 + 2*4), pues un entero es almacenado en 4 bytes de memoria. Ahora, b sealara a a[ 2 ] b a[0]
5
a[1]
8
a[2]
4
a[3]
3
En resumen, b++, ++b incrementan al puntero para que apunte a la siguiente direccin. Por supuesto,
la aritmtica de punteros 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. F Vista la posible aritmtica de punteros, podemos establecer una relacin entre punteros y arreglos. Podramos hacernos la siguiente pregunta:
a[0]
5
a[1]
8
a[2]
4
a[3]
3
F Almacenados los valores mostrados en el arreglo se asignar el mismo valor en la variable z con cada uno de los siguientes enunciados? z = *b + 2; z = *( b + 2 );
No. En el primer enunciado toma el valor guardado en la posicin b [ 0 ] y le suma 2. Por tanto,
en z queda guardado el valor 7.
w
w
w
w
PD
H F-XC A N GE
PD
H F-XC A N GE
O W !
bu
Punteros
m
C lic
to
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
F En conclusin: y = *b *b b [0 ] y = *( b + 1 ) *( b + 1 ) b[1] F En general: y = *( b + i ) *( b + i ) b[i] es equivalente a es equivalente a es equivalente a a[i] a[i] a[i] es equivalente a es equivalente a es equivalente a es equivalente a es equivalente a es equivalente a y =a[0] a[0] a[0] a[1] a[1] a[1]
Esta equivalencia entre los arreglos permite que los elementos del arreglo puedan ser accesados a travs del arreglo directamente o a travs de un puntero que apunte al primer elemento del arreglo.
Cierre de la Clase
F Podras mencionar algunas ventajas de los punteros?
Proporcionan una manera indirecta para accesar el valor de una variable. Por estar muy relacionados con los arreglos y proporcionan una va alternativa de acceso a los
elementos individuales del arreglo. F Dado el siguiente programa,
Programa No. 3 punteros # include <stdio.h> # include <conio.h> void main() { float v1, v2, *pvptr; clrscr(); printf("\nINGRESE UN VALOR PARA v1: "); scanf("%f",&v1); printf("\n INGRESE UN VALOR PARA v2: "); scanf("%f",&v2); pvptr = &v1; v2 = v2 + (*pvptr); v1 = (*pvptr)*2 - v1; printf("\n\n El valor de v1 es: %.2f",v1); printf("\n El valor de v2 es: %.2f",v2); getch(); }
w
w
w
w
PD
H F-XC A N GE
PD
H F-XC A N GE
O W !
bu
Punteros
m
C lic
to
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
Indica la cul ser la salida despus de su ejecucin, tomando como valores de entrada 90 y 30.5 F Con frecuencia algunos estudiantes incurren en errores al iniciarse en el uso de los punteros. Algunos errores frecuentes son:
Declarar varios punteros con un solo *. Por ejemplo, si se quieren declarar dos punteros p1 y p2
como punteros a enteros, lo incorrecto sera: int *p1, p2. Lo correcto sera: int *p1, *p2
Si se tiene un puntero k. Un error comn es confundir: *k + 1, con *( k + 1) Asignar a un puntero la direccin de una variable diferente al tipo de puntero. Por ejemplo: asignar
a un puntero a enteros la direccin de una variable flotante.
Utilizar un puntero al que no se le ha asignado una direccin inicial, lo que puede producir
resultados inesperados. F Que tal si mencionan algunas aplicaciones de los conocimientos adquiridos acerca de punteros
Los conocimientos adquiridos acerca de los punteros sern aplicados para el paso de parmetros
por referencia cuando estudiemos el tema de funciones.
w
w
w
w