Publicado el 11 de Enero del 2019
1.055 visualizaciones desde el 11 de Enero del 2019
1,4 MB
49 paginas
Creado hace 6a (31/12/2017)
Estructuras de Datos
y Algoritmos
Tema 1. Punteros
Contenido
• CONCEPTO
• DECLARACIÓN
• OPERADORES
• OPERACIONES
• PUNTEROS Y FUNCIONES
• PUNTEROS Y VECTORES
• ASIGNACIÓN DINÁMICA DE MEMORIA
•
• PUNTEROS A ESTRUCTURAS Y ESTRUCTURAS AUTO-REFERENCIADAS
• PUNTEROS A FUNCIONES
• ORDEN DE APLICACIÓN DE MODIFICADORES
ERRORES HABITUALES AL UTILIZAR PUNTEROS
Tema 1. Punteros - Curso 2017/18
2
CONCEPTO
• Almacenan direcciones de memoria, en vez de valores.
• Cada posición de almacenamiento en la memoria de un ordenador, tiene
una dirección de memoria.
• Cada posición de memoria almacena 1 byte.
•
En lo aprendido hasta ahora, mediante la utilización de variables, se hace
referencia a un dirección de memoria para conseguir su valor.
• Ahora, vamos a estudiar que mediante variables de tipo puntero, es
posible manejar direcciones de memoria y valores. Este tipo de variables,
tienen las siguientes ventajas:
– Su utilización hace posible definir vectores y matrices que empleen únicamente la
cantidad de memoria requerida, ajustando su tamaño dinámicamente.
– Hacen posible implementar estructuras de datos más complejas, como por ejemplo,
árboles y listas.
– Su utilización permite que las funciones puedan devolver más de un valor.
Tema 1. Punteros - Curso 2017/18
DECLARACIÓN
•
tipo *nombre_puntero;
– nombre_puntero: nombre de la variable de tipo puntero.
– tipo: tipo de datos al que “apuntará” el puntero.
• Una variable de tipo puntero, una vez declarada, contiene un valor inicial
cualquiera, es decir, apuntará a una dirección aleatoria que puede no
existir.
Ejemplos:
char *pCar; /* Variable pCar que es de tipo puntero a carácter */
float *pNum; /* Variable pNum que es de tipo puntero a float */
Dirección Valor Variable
Dirección Valor Variable
?
?
CDA5
pCar
CDA5
‘B’
CD86
pNum
CD86
6.67
Tema 1. Punteros - Curso 2017/18
OPERADORES
• Operador &:
– Operador unario de dirección.
– Opera sobre cualquier tipo de variable.
– Obtiene la dirección de memoria de su operando, es decir, la dirección de
memoria de la variable sobre la que se aplica.
– El compilador dará un aviso si se intenta realizar una asignación en la que no
corresponden los tipos.
Tema 1. Punteros - Curso 2017/18
OPERADORES
Dirección
Valor
Variable
?
34FF
pNum
34FF
10
Num
Ejemplo:
int Num;
int *pNum;
double *pNumD;
•
•
•
•
• …
• Num = 10;
•
•
•
pNum = &Num; /* se asigna la
dirección de numero a una variable
puntero*/
pNumD = &Num; /* Aviso, no se
corresponden los tipos */ …
Resultado: la variable numero esta en la
posición (dirección ) 34FF, después de
la asignación a la variable puntero
pNum tendrá el valor 34FF.
Tema 1. Punteros - Curso 2017/18
OPERADORES
• Operador * :
– Operador unario de indirección
– Complemento del operador &.
– Permite operar sobre las variables a las que apunta la variable de tipo
puntero.
– Proporciona el valor de la dirección de memoria a la que apunta el
puntero sobre el que se aplica, es decir, permite acceder al valor por
medio del puntero.
Tema 1. Punteros - Curso 2017/18
OPERADORES
•
Ejemplo:
...
int Num1, Num2;
int *p;
Num1 = 5;
p = &Num1;
Num2 = *p;
*p = 10;
…
Resultado: pondrá en Num2 el valor de Num1,
por tanto Num2 = 5;
ATENCIÓN: Después de la asignación p =
&Num1; tenemos dos maneras de
manipular los valores enteros
almacenados en la variable Num1:
directamente mediante Num1 o
indirectamente mediante el puntero p.
Dirección
Valor
?
34FF
Variable
p
34FF
X
5 10
Num1
5
Num2
Tema 1. Punteros - Curso 2017/18
OPERADORES
•
Asignación de punteros:
– Es posible asignar una dirección de una variable a un puntero (ejemplo 1)
– Es posible asignar el contenido de un puntero a otro puntero (ejemplo 2)
#include <stdio.h>
int main(void)
{
int a;
int *pNum1;
int *pNum2;
a = 10;
pNum1 = &a; /* ejemplo1 */
pNum2 = pNum1; /* ejemplo2 */
printf(" El valor %d esta en la posicion %x ", *pNum2, pNum2);
return 0;
}
Pregunta: Cuál es el resultado?.
Tema 1. Punteros - Curso 2017/18
OPERACIONES
Incrementar o decrementar variables de tipo puntero.
•
• Debe entenderse como modificaciones en la dirección a la que apunta el puntero
•
•
•
(se produce un cambio en la dirección de memoria contenida en el puntero).
El incremento o decremento de un puntero depende exclusivamente del tipo de
dato base dado en su declaración.
En la declaración de un puntero es necesario indicar a qué tipo de dato apunta
para que al utilizar los incrementos o decrementos se conozca cuánto hay que
sumar o restar.
La operación de sumar 1 a un puntero hace que su dirección se incremente la
cantidad necesaria para pasar a apuntar al siguiente dato del mismo tipo (cantidad
que coincide con el número de bytes que ocupa dicho tipo de dato).
Por lo tanto, sólo en el caso de variables que ocupan 1 byte en memoria (variables
de tipo “char”) la operación de incremento aumenta en 1 la dirección de memoria;
en los demás casos aumenta más.
Tema 1. Punteros - Curso 2017/18
OPERACIONES
– Resta de punteros:
• Tiene sentido si apuntan a direcciones diferentes de un mismo VECTOR.
• El resultado de la resta es la diferencia de posiciones del VECTOR que
existe entre ambos
– Es posible comparar punteros mediante cualquier operador de comparación y
relacional, pero:
• Es necesario que ambos punteros sean del mismo tipo.
• Resultan de gran utilidad cuando se trabaja con vectores utilizando
punteros.
– OPERACIONES PROHIBIDAS CON PUNTEROS
• Suma de punteros
• Multiplicación de punteros
• División de punteros
Tema 1. Punteros - Curso 2017/18
OPERACIONES
Ejemplo 1: Incremento de un puntero
•
#include <stdio.h>
int main( void)
{
int Num=7;
int *pNum;
pNum = &Num;
printf("\nLa direccion del dato =%x",&Num);
printf("\nEl valor que apunta el puntero = %d", *pNum);
printf("\nEl contenido de pNum =%x",pNum);
pNum++;
printf("\nel contenido de pNum =%x",pNum);
printf("\nEl valor que apunta el puntero = %d",*pNum);
return 0;
}
Pregunta: ¿Cuál es el resultado?
Tema 1. Punteros - Curso 2017/18
OPERACIONES
Ejemplo 2: Incremento de un puntero
…
int *pNumI;
Si el contenido de pNumI (la dirección de una variable) = 1000, podemos escribir:
pNumI
pNumI +1
pNumI +2
pNumI +3
…
…
1000
1004
1008
100C
char *pChar;
Si el contenido de pChar(la dirección de una variable) = 1000, podemos escribir:
pChar
pChar
pChar
1000
1001
1002
Tema 1. Punteros - Curso 2017/18
OPERACIONES
No confundir incremento o decremento del puntero con el incremento o
decremento del valor a donde apunta el puntero
Ejemplo 3: Incremento de un puntero
Dirección Valor Variable
•
int *pNumI;
int Num;
...
Num = 78;
pNumI = &Num;
*pNumI += 8;
pNumI += 8;
...
1
1
2
3
?
34E0
pNumI
34E0
78
Num
Después de *pNumI += 8
2
Dirección Valor Variable
3
Después de pNumI += 8
Dirección Valor Variable
?
3500
pNumI
?
34E0
pNumI
34E0
86
Num
34E0
86
Num
3500
???
Tema 1. Punteros - Curso 2017/18
OPERACIONES
Ejemplo 4: sustracción de punteros
#include <stdio.h>
int main(void)
{
Resultado:
dirección del primer elemento = 8276
dirección del ultimo elemento = 8286
p2 - p1 = 4
(8286-8276) / 4 = 4
int vector[5] = {2,4,6,8,10};
int *p1, *p2;
p1= &vector[0];
p2 = &vector[4];
printf("\ndirección del primer elemento =%x ",p1);
printf("\ndirección del ultimo elemento =%x ",p2);
printf("\n p2-p1 = %d",p2-p1);
printf("\n *p2-*p1 = %d",*p2-*p1);
return 0;
*p2 - *p1 = 8
}
Tema 1. Punteros - Curso 2017/18
OPERACIONES
Ejemplo 5: comparación de punteros
#include <stdio.h>
int main(void)
{ int vector[5] = {2,4,6,8,10};
int *p1, *p2;
p1= &vector[0];
p2= &vector[4];
if (p1 > p2) {
}
else {
if (p1 == p2) {
}
}
return 0;
}
printf(“\np1 apunta a una dirección más alta que p2”);
printf(“\np1 y p2 apuntan al mismo elemento del vector”);
printf(“\n Y es el elemento %d”, *p1);
Tema 1. Punteros - Curso 2017/18
OPERACIONES
En cada dirección de memoria se guarda 1 byte.
Si el tipo del puntero ocupa más de 1 byte al incrementar el puntero
se adelantan tantas posiciones de memoria como nº de bytes ocupe
el tipo de puntero.
Ejemplo:
char *pC;
double *pD;
...
/*Sumamos 1 a un
puntero a char*/
pC++;
/*Sumamos 1 a un
puntero a double*/
pD++;
Tema 1. Punteros - Curso 2017/18
OPERACIONES - SÍNTESIS
• Asignar la dirección de una variable ordinaria a un puntero
– p = &variable;
• Asignar el valor de un puntero a otro
•
•
•
•
•
– punt1 = punt2;
Se puede asignar un valor inicial nulo (cero) a un puntero
– puntero = NULL;
Se puede sumar o restar un valor entero a un puntero
– punt+2, o --punt.
Tiene sentido restar un puntero a otro si ambos apuntan a los elementos de
un mismo vector.
Se puede comparar los punteros cuando apunten al mismo tipo de dato.
PROHIBIDO:
– Sumar punteros
– Dividir punteros
– Multiplicar punteros
Tema 1. Punteros - Curso 2017/18
PUNTEROS Y FUNCIONES
•
•
Los punteros permiten realizar un paso por referencia de parámetros a
funciones:
– Es posible cambiar el valor de una variable en el interior de una función y
conservar su valor una vez terminada la ejecución de la función.
Idea:
– En lugar de pasar la variable como parámetro real a la función (paso por
valor) se pasa un puntero a la dirección en la que se encuentra la variable
(parámetro por referencia).
– En el paso de pasopor valor, lo único que ocurre es que se hace una copia
del valor del parámetro real sobre el parámetro formal, de manera que
cualquier cambio en el parámetro formal NO afecta al parámetro real.
– En el paso paso por referencia, lo que en realidad se pasa es la dirección
de la variable, de manera que los cambios, por tanto, se pueden hacer
manipulando el puntero de manera que afecten directamente al
contenido de la variable apuntada.
Tema 1. Punteros - Curso 2017/18
PUNTEROS Y FUNCIONES
Ejemplo 6: Ejemplo paso por referencia:
#include <stdio.h>
void cambiar (int *x, int *y);
int
Comentarios de: Tema 1. Punteros - Estructuras de Datos y Algoritmos (0)
No hay comentarios