Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Punteros PDF
Punteros PDF
Índice
1. Qué es un puntero y por que son
importantes.
2. Punteros a tipos básicos.
3. Punteros sin tipo.
4. Memoria dinámica.
5. Punteros a estructuras.
6. Punteros a matrices.
7. Punteros a punteros a punteros….
8. Punteros a funciones.
1
Qué es un puntero y por
qué son importantes
Introducción
2
Introducción
¿Alguien se atreve a definir lo que es
un puntero?.
Un puntero es una variable capaz de almacenar
direcciones de memoria y mediante los operadores
adecuados acceder a la información que contiene la
dirección de memoria a la que “apunta” en cada momento.
Introducción
¿Por
qué son importantes los
punteros?.
– Tablas y cadenas.
– Parámetros por referencia.
– Biblioteca de funciones (scanf).
– Coger la memoria que necesitamos.
3
Introducción
¿Cuáles son los peligros / errores
típicos con punteros?.
– Olvidarnos de reservar memoria.
– Olvidarnos de devolver memoria.
– Apuntar a dónde no es.
– No utilizar el operador adecuado (*, &).
Punteros a tipos
básicos
4
Punteros a tipos básicos
Así se declaran punteros:
int *a; // puntero a entero
char *c; // puntero a caracter
int *a;
….
a
*a ¿Cuál es la diferencia
(un dibujo)?
&a
5
Punteros a tipos básicos
¿Cómo podemos declarar un puntero
que apunte al número 3?.
int *a;
*a = 3;
Mal !!!!!
¿Y por qué?.
a = &b;
Un dibujo.
6
Punteros a tipos básicos
Ejemplos de uso de operadores de punteros.
Se declaran dos variable enteras “i” y “j” y un puntero a entero “p”
int i, j, *p;
Suponemos que “i” y “j” se ubican en las direcciones 13B6 e 5FC4,
respectivamente.
Contenido
operación Variable de la memoria
i=15; i 13B6 15
?
p=&i; (p “apunta” a i)
j 5FC4 15
?
j=*p; (se accede a lo
apuntado por p) p ? 13B6
?
Punteros y constantes
Punteros y constantes:
const int*
int* a;
Puntero a una constante. Puede
cambiar el puntero pero no puede
cambiar el valor apuntado.
int*
int* const a = [Dirección de memoria];
Puntero constante. Puede cambiar el
valor pero no la dirección de
memoria.
7
Punteros
En C también tenemos NULL.
Ojo, se escribe todo en mayúsculas y
NO es una palabra reservada.
¿Para qué utilizamos NULL?.
int *a = NULL;
….
if (a == NULL) {
printf(“a no apunta a ningún sitio ”);
}
#include
#include<stdio.h>
<stdio.h>
x p1 8A48 void
void intercambio
void intercambio
intercambio (int *,
*,int
(int(int *);
*p1,
int *);int
int*p2)
85 void
void
main
intercambio
(void)
(int *p1, *p2)
{
void{ main (void)
8A48 {{ int
inttmp;
int
intx=5,
x=5,
tmp
tmp;
y=8;
=y=8;
*p1; El contenido de 8 lo
y p2 8A4A tmp = *p1;Son punteros almacenan
58 intercambio
intercambio
*p1
(&x,
==*p2; &y); apuntado por p1
(&x,&y);
8A4A printf*p1
printf (“\n
(“\n
*p2;
x=
x= %d”,
%d”,
direcciones
x);
x);
*p2
*p2 ==tmp;
tmp;
printf (“\n y= %d”,
printf (“\n y= %d”, y); y);
Memoria
tmp 5? }} }}
main Se pasan las direcciones
Memoria 5
intercambio
8
Punteros sin tipo
9
Punteros sin tipo
Antesde usar el valor apuntado
necesitamos forzar el tipo.
void *p;
int a = 5, b;
p = &a;
b = (* (int *)p );
¿Os imagináis como están hechas
printf y scanf?.
Memoria dinámica
10
Memoria dinámica
Los punteros y la memoria dinámica
están muy relacionados… pero no
siempre van juntos.
Podemos trabajar con punteros sin
memoria dinámica.
¿Un ejemplo?.
Memoria dinámica
¿Qué es la memoria dinámica?.
Memoria que reservamos durante la
ejecución de nuestro programa.
Ejemplo típico: romper la limitación
de las tablas (listas, pilas, colas,
etc.)
11
Memoria dinámica
Reservar memoria:
#include <stdlib.h>
stdlib.h>
void *malloc(
malloc( size_t size );
Memoria dinámica
¿Cómo podemos crear un puntero
al número 5 con memoria
dinámica?.
1. int *p;
2. p = (int *)malloc(sizeof(int));
3. (*p)=5;
12
Memoria dinámica
Importante !!!!!!
Si reservamos memoria hemos de
liberarla.
Si no la liberamos, es un trozo de
memoria que NADIE puede usar.
Si perdemos el puntero al trozo de
memoria, ya no podremos liberarla.
Memoria dinámica
Liberar memoria.
#include <stdlib.h>
void free( void *ptr );
Un ejemplo:
1. int *p;
2. p = (int
(int *)malloc(sizeof(int
*)malloc(sizeof(int));
));
3. (*p)=5;
4. free(p);
free(p);
13
Punteros a estructuras
Punteros a estructuras
Acceso a los campos de una estructura:
struct
structTR TR
{{
T1
T1c1; c1;
T2
T2c2; c2;
...... Son necesarios los paréntesis
Tn
Tncn; cn; porque el operador “.” es de
}};; mayor precedencia que el “*”
struct
structTR TRr,r,*pr;
*pr;
Acceso
Accesoaatravés
travésde
devariable
variableestructura
estructura
r.ci
r.ci
Acceso
Accesoaatravés
travésde
depuntero
punteroaaestructura
estructura
(*pr).ci
(*pr).ci
14
Punteros a estructuras
Acceso a los campos de una estructura:
typedef
typedefstruct
struct
En C (y en C++) {{
existe un operador Cadena
Cadenanombre,
nombre,apellido1,
apellido1,apellido2;
apellido2;
para simplificar el int
intedad;
edad;
long
longdni;
dni;
acceso a los char
charsexo;
sexo;
campos de una }}Tpersona;
Tpersona;
estructura Tpersona
Tpersonaempleado,
empleado,*p;
*p;
referenciada por un
puntero: ‘->’ Acceso
Accesoaatravés
travésde
devariable
variableestructura
estructura
strcpy
strcpy(empleado.nombre,
(empleado.nombre,"Alicia");
"Alicia");
printf
printf("%d",
("%d",empleado.edad);
empleado.edad);
Acceso
Acceso a travésde
a través depuntero
punteroaaestructura
estructura
p->sexo = ‘m’;
p->sexo = ‘m’;
(*p).sexo
(*p).sexo==‘m’;
‘m’;
Punteros a estructuras
¿Cómo creamos nuevas estructuras de
manera dinámica?.
typedef
typedefstruct
struct
{{
Cadena pp==(Tpersona
(Tpersona*)*)malloc(sizeof(Tpersona));
malloc(sizeof(Tpersona));
Cadenanombre,
nombre,apellido1,
apellido1,apellido2;
apellido2;
int edad;
int edad;
long
longdni;
dni; /*/*ppapunta
char apuntaaauna
unaestructura
estructurade
detipo
tipo
charsexo;
sexo; Tpersona
Tpersona cuya memoria ha sidoreservada
cuya memoria ha sido reservada
}}Tpersona;
Tpersona; durante
durantelalaejecución
ejecución*/*/
Tpersona
Tpersona*p;
*p;
15
Punteros a matrices
Punteros a matrices
Una matriz es un puntero constante
a la primera de un conjunto de
posiciones de memoria consecutivas
que guardan datos del mismo tipo
16
Punteros a matrices
¿Cómo recorremos una matriz con un
puntero?
int
int t[]
t[] =
= {1,
{1, 2,
2, 3,
3, 5}; pp =
5}; = &t[0];
&t[0];
int *p;
int *p;
int
int i;i; for
for (i
(i =
= 0;
0; ii <
< 5;
5; i++)
i++) {{
printf("%d
printf("%d ", (*(p+i)) );
", (*(p+i)) );
}}
Memoria dinámica
¿Cómo podemos crear
dinámicamente una tabla de
enteros de 5 posiciones?.
1. int *p;
2. p = (int
(int *)malloc(sizeof(int
*)malloc(sizeof(int)) *5 );
3. (*p)=5;
¿Qué
significa
esto?
17
Siempre que se llama a malloc hay
que llamar a…
4. free(p);
Punteros a punteros a
punteros a punteros….
18
Punteros a punteros….
Puedo tener punteros que apunten a
punteros.
Y punteros que apunten a punteros
que apunten a punteros.
Y punteros que apunten a punteros
que apunten a punteros que apunten
a punteros.
Y …..
Punteros a punteros….
¿Cómo declaramos un puntero que
apunte a un puntero a entero?.
int **a;
¿Cómo guardamos en a el entero 5
(usando todas las variables auxiliares
necesarias)?
int b = 5, *c;
c = &b;
a = &c;
19
Punteros a punteros….
¿Cómo mostramos el valor de a?.
printf(“%d “, **a);
Un dibujo.
Punteros a punteros….
Un ejemplo: intercambiar dos punteros de
manera que, cuando termine la función, a apunta
a donde apuntaba b y b a donde apuntaba a.
void
voidintercambia(int
intercambia(int*a,
*a,int
int*b); void
*b); voidintercambia(int
intercambia(int*a,
*a,int
int*b)
*b){{
int *tmp;
int *tmp;
int
intmain()
main(){{
int
int*a,
*a,*b; tmp
*b; tmp==a;a;
int
intx=1,
x=1,y=2;
y=2; aa==b;
b;
aa==&x;
&x; bb==tmp;
tmp;
bb==&y;
&y; }}
intercambia(a,
intercambia(a,b);
b);
printf("%d
printf("%d//%d
%d\n",
\n",*a,
*a,*b);
*b);
}} ¿Por qué no funciona?
¿Cómo lo arreglamos?
20
Punteros a funciones
Punteros a funciones
¿Qué es un puntero a una función?.
¿Para qué sirve?.
Un ejemplo:
void calcular(int r, void (*avisa)(int)); void m1(int r) {
void m1(int); printf("1: %d\n", r);
void m2(int); }
21