Introducción a los punteros
Enviado por Esteban Montero • 16 de Octubre de 2015 • Apuntes • 2.564 Palabras (11 Páginas) • 96 Visitas
Introducción a los punteros
Los puntos que detallaremos son:
- Definición del concepto de puntero.
- Declaración de punteros.
- Operadores de punteros: & y *.
- Aritmética de punteros.
- Asignación dinámica de memoria.
- Punteros y arrays.
- Inicializaciones de punteros.
- Punteros a funciones.
- Tipo void y punteros.
- Declaraciones curiosas.
El concepto de puntero es importantísimo en la programación en C. Un puntero contiene una dirección de memoria. Cuando una variable contiene la dirección de otra variable se dice que la primera variable apunta a la segunda.
Variables punteros
La forma general para declarar una variable puntero es:
tipo *nombre;
donde tipo es cualquier tipo válido de C (también llamado tipo base) y nombre es el nombre de la variable puntero.
Operadores de punteros
Existen dos operadores especiales de punteros: & y *. Estos dos operados son monarios y no tienen nada que ver con los operadores binarios de multiplicación (*) y de and a nivel de bits (&).
Operador &
& es un operador monario que devuelve la dirección de memoria de su operando.
Ejemplo:
#include
main (void)
{
int x = 10;
printf (" x = %d\n &x = %p\n",
x, &x);
}
Salida del ejemplo anterior:
x = 10
&x = 8FBC:0FFE
Operador *
El operador * es el complemento de &. Es un operador monario que devuelve el valor de la variable localizada en la dirección que sigue.
Ejemplo 1:
#include
main (void)
{
int x = 10;
printf (" x = %d\n", x);
printf (" *&x = %d", *&x);
}
Salida de ejemplo 1:
x = 10
*&x = 10
Aritmética de punteros
Existen 4 operadores que realizan operaciones aritméticas que pueden utilizarse con punteros:
+, -, ++, --
Ejemplo
#include
#define imprimir_p printf ("\np = %p", p);
main (void)
{
int *p;
imprimir_p;
printf ("\tsizeof(*p) = %d", sizeof(*p));
p++; imprimir_p;
p -= 5; imprimir_p;
}
/* SALIDA DEL EJEMPLO:
p = 76F69E34 sizeof(*p) = 4
p = 76F69E38
p = 76F69E24
*/
Ojo : ¿Cuánto es (76F69E38 – 14) en hexadecimal?
En el ejemplo anterior se aprecia que si hacemos p++; no aumenta el valor de p en 1 sino que aumenta en 4, que es el tamaño en bytes de un int, es decir, el tamaño del objeto al que apunta.
Por lo tanto, la sentencia p++ hay que interpretarla de la siguiente forma: «p apunta al siguiente elemento del tipo base». Lo mismo se puede decir de los demás operadores aritméticos aplicados a los punteros.
Supóngase que queremos hacer un programa que lea n valores enteros introducidos por teclado por el usuario, los almacene en un vector y los imprima en orden inverso.
Una solución es:
#include
main (void)
{
#define NMAX 100 /* número máximo de elementos */
int v[NMAX]; /* vector */
int n = 0; /* número de elementos introducidos */
int varaux; /* variable auxiliar */
register int i; /* índice */
do
{
printf ("\nIntroduce número de valores a leer (1-%d): ", NMAX);
scanf ("%d", &n);
} while (n < 1 || n > NMAX);
for (i = 0; i < n; i++)
{
printf ("Introduce valor %d: ", i);
scanf ("%d", &varaux);
v[i] = varaux;
}
printf ("\n\nValores en orden inverso:\n");
for (i = n - 1; i >= 0; i--)
printf ("%d ", v[i]);
}
Si el usuario introduce como valor de n, el valor 10, estaremos desperdiciando, si un int ocupa 2 bytes, 90*2 bytes de memoria. Además, el usuario no puede introducir más de NMAX valores. Estas restricciones vienen impuestas porque el tamaño de un array en la declaración ha de ser una expresión constante. La asignación de memoria en este caso se dice que es estática porque se determina en el momento de la compilación. Cuando la asignación de memoria se determina en tiempo de ejecución se dice que es asignación dinámica.
Veamos cómo se haría el programa anterior con asignación dinámica y luego pasamos a explicarlo:
#include
#include
main (void)
{
int *v; /* vector */
int n = 0; /* número de elementos introducidos */
int varaux; /* variable auxiliar */
register int i; /* índice */
printf ("\nIntroduce número de valores a leer: ");
scanf ("%d", &n);
v = (int *) malloc (n * sizeof (int));
if (v == NULL)
printf ("Memoria insuficiente.");
...