D. PUNTEROS



D.1 Concepto
D.2 Declaración
D.3 Operadores
D.4 Aritmética de punteros
D.5 Errores comunes con punteros
D.6 Relación entre punteros y vectores
D.7 Relación entre punteros y matrices
D.8 Bibliografía
D.9 Ejercicios sobre punteros





  • D.1 - Concepto:

Un puntero o apuntador es una variable que contiene una dirección de memoria. En esa posición de memoria se encuentra almacenada una variable de un tipo determinado (entera, real o carácter). Su tamaño es de 4 bytes.
Se dice que la primera variable (el puntero) apunta a la segunda.
Un puntero también puede apuntar a otro puntero, es decir, almacenar la dirección de memoria de otro puntero.



  • D.2 - Declaración:
Para que un puntero pueda apuntar a una variable debe ser declarado de la siguiente manera:
tipo*identificador
donde tipo es el tipo de variable a la que apunta (si es variable entera, int; si es real, float o double; y si es un carácter, char), * indica que es un puntero, e identificador es el nombre del puntero.
Los punteros sólo pueden apuntar a variables del mismo tipo que ellos.
(A partir de ahora llamaremos p, q... a identificadores de punteros en general, que deberemos inicializar para poder usarlos).
Si queremos que un puntero q apunte a otro p se declara así:
tipo* *q



  • D.3 - Operadores:
Los operadores que se usan con los punteros son &, *, y el operador asignación =.

-En C, al contrario que en otros lenguajes de programación, se puede obtener directamente la dirección de memoria de cualquier variable sobre la que opera el puntero. Esto es posible hacerlo con el operador referencia & de la siguiente forma:
p=&x
donde x es la variable a la que apunta el puntero.

-Para acceder a la variable a la que apunta el puntero se utiliza el operador desreferencia * de esta forma:
x=*p
donde x es la variable que obtiene un nuevo valor (el valor de la variable a la que apunta el puntero).
Si un puntero q apunta a otro p, se utiliza dos veces el operador *.

-El operador asignación entre punteros, =, permite que la dirección de memoria de un puntero se asigne al otro puntero .Se usa así:
p=q

Si quieres más información sobre operadores, haz clic en este link:
Operadores



  • D.4 - Aritmética de punteros:
-Suma/resta de punteros:
Sólo puede hacerse suma y resta de un puntero con un entero. Esta operación avanza o retrasa el puntero tantas veces como indica el entero con el que se opera. Se procede así:
p=p+n
donde n es un entero. (Por ejemplo, si n=1, el puntero p avanza 4 bytes).

-Comparación de punteros:
Se pueden comparar punteros, es decir, comparar las relativas posiciones de memoria:
Si tenemos que p>q, significa que p apunta a una dirección de memoria mayor que q.
Si tenemos que p<q, significa que p apunta a una dirección de memoria menor que q.



  • D.5 - Errores comunes con punteros:
-Asignar punteros de distinto tipo (un float con un char, un int con un double...).
Por ejemplo:
int a=1 ;
int *p ;
double b=2.0 ;
double *q ;
p=&a ;
q=&x ;
q=p; ERROR

-Usar punteros no inicializados.
Por ejemplo:
char *p;
*p='a';
(FALTARÍA PONER: char c;
p=&c; )

-Asignar valores al puntero en vez de a la variable:
Por ejemplo:
int x;
int *p;
p=&x;
p=7; MAL (DEBERÍA SER *p=7)

-Hacer asignaciones a la dirección de memoria NULL (dirección de memoria cero).
Por ejemplo:
int *p=NULL;
*p=6; // ERROR (NO SE PUEDE ASIGNAR NADA A LA DIRECCIÓN DE MEMORIA NULL)



  • D.6 - Relación entre punteros y vectores:
Un vector es un conjunto de variables del mismo tipo que se referencian con un mismo nombre y con un índice.
En C, los punteros y los vectores están fuertemente relacionados, hasta el punto de que el nombre de un vector es un puntero al primer elemento del vector. Para ir avanzando sobre el vector, cuyos elementos están situados en memoria consecutivamente, basta ir moviendo el puntero con simples incrementos sobre el vector. Así pues, siendo v el nombre de un vector en general, tenemos que:
v[i] es equivalente a *(v+i)
(Ej: v[4]=v[3]+7 es equivalente a *(v+4)=*(v+3)+7)
&v[i] es equivalente a (v+i)
(Ej: &v[2] es equivalente a (v+2))
Por tanto, todas las operaciones que utilizan vectores e índices pueden realizarse mediante punteros.
Sin embargo, hay que tener cuidado a la hora de no rebasar los límites del trozo de memoria donde se almacena el vector.



  • D.7 - Relación entre punteros y matrices:
Una matriz es un conjunto de variables del mismo tipo que se referencian con un mismo nombre y con dos índices.
Al igual que con vectores, en C, al declarar una matriz, se crea un puntero con el mismo nombre que la matriz. También se puede avanzar en la matriz y realizar operaciones de idéntica forma que con los vectores.
Siendo m una matriz en general, m[DIM1][DIM2], tenemos que:
m[i] es equivalente a &m[i][0]
(Ej: m[7]=&m[7][0])
m[i][j] es equivalente a *(m[i]+j) y es equivalente a *(m[0]+i*DIM2+j)
(Ej: m[2][3]=20 es equivalente a *(m[2]+3) y es equivalente a *(m[0]+2*DIM2+3)
(m+i) es equivalente a &m[i]
(Ej: (m+4) es equivalente a &m[4])
m[i][j] es equivalente a *(*m+i*DIM2+j)
(Ej: m[5][6] es equivalente a *(*m+5*DIM2+6))

Para más información acerca de vectores y matrices, visita el siguiente link:
Vectores y matrices



  • D.8 - Bibliografía:

http://www.mailxmail.com/curso-introduccion-lenguaje-c/punteros
www.uhu.es/04004/material/Transparencias6.pdf
Apuntes de clase