Vectores

El nombre de una tabla en lenguaje C es un puntero constante en el tipo de dato de los elementos que almacena la mesa y que apunta a la posición de memoria donde se encuentra la primera casilla de la tabla.

int t[100]; 

t es un puntero en el inicio de una zona de memoria que ocupa el espacio de 100 elementos de tipo int. Si p es un puntero que apunta a un tipo T que ocupa n bytes y p apunta a una variable v del tipo T, resulta que p+1 apunta a una supuesta variable de tipo T, que estaría ubicada en memoria después de v; p+2 apunta a una supuesta variable de tipo T que estaría situada en memoria a continuación de la anterior, y así sucesivamente.

Esto permite realizar mediante punteros operaciones que se realizan mediante la indexación de la tabla:

int y; ...
for (i=0; i<100; i++) printf("Posición %d: %d\n", i, t[i]);

Es equivalente a

int y; ...
for (i=0; i<100; i++) printf("Posición %d: %d\n", y, *(t+i));

La expresión *(t+i) se evalúa como el contenido que hay donde apunta el puntero que contiene t (que es el inicio de la tabla) + el desplazamiento en y posiciones, lo que acaba siendo igual a t[i].

Si tenemos int * p son equivalentes las expresiones: p = t; y p = & t[0], ya que t es la dirección donde se encuentra la primera casilla, y la expresión &t[0] nos proporciona precisamente esa dirección.

Para obtener la dirección de un elemento de una tabla, simplemente se escribe el operador dirección '&' frente al elemento de la tabla referenciado. Por ejemplo:

int t[10];
int *pt;
pt = &t[4]; /* pt contiene la dirección del elemento t[4] */
*pt = 13; /* ponemos un 13 dentro de t[4] , a través de pt */

Podemos utilizar los punteros para recorrer toda una tabla de elementos, posicionando el puntero en principio de la tabla (sobre t[0]), e incrementando el contenido de la variable puntero para "saltar" al siguiente elemento de la tabla (los elementos de una tabla se almacenan en posiciones consecutivas de memoria). No se debe tener en cuenta cuántas posiciones de memoria ocupa cada elemento, puesto que el incremento de un puntero se indica con número de elementos, y el compilador multiplica este número por las posiciones de memoria que ocupan los elementos, en función del tipo (en el PC, un puntero a int se multiplica por 2, un puntero a float por 4 y un puntero a char por 1).

Ejemplo: Inicializar todos los elementos de un vector de 10 elementos a través de un puntero (del mismo tipo que los elementos de la mesa):

#include <stdio.h>
void main(void) {
   int t[10];
   int *pt, y;
   pt = &t[0]; /* posicionar pt sobre el primer elemento del vector */
   for (i=0; i<10; i++) /* repetir 10 veces ... */
   {
      *pt = 13; /* coloca un 13 sobre el elemento que está apuntando */
      pt++; /* pt apuntará al siguiente entero (sumar 2 a pt) */
   }
   for(i=0; i<10; i++) printf("%d\n",t[i]); /* escribe el vector */
}

Otra forma de acceder a una mesa a través de punteros es utilizar el puntero como base y indicar un desplazamiento hasta el elemento que se desea referenciar. Otra vez el desplazamiento se expresará en número de elementos, y el compilador se encarga de convertirlo en desplazamiento en posiciones de memoria (en función del tipo de los elementos y del Hardware que se utiliza). Para expresar la dirección base de una tabla podemos hacerlo dando la dirección de su primer elemento o simplemente con el nombre de la tabla sin ningún índice.

Ejemplo: Éste es el mismo algoritmo que el ejemplo anterior, pero utilizando el modo de acceso base más desplazamiento (modo de direccionamiento):

#include <stdio.h>
void main(void) {
  int t[10];
  int *pt, y;
  pt = t; /* pt toma por valor la dirección base del vector */
  for(i=0; y<10; i++) {
     /* acceso puntero base más desplazamiento */
     *(pt + i) = 13; /* (hay que poner el puntero y el desplazamiento entre
     paréntesis, antes de poner el asterisco) */
  }
  for(i=0; i<10; i++) printf("%d\n",t[i]);
}

Un aspecto curioso del lenguaje C es que permite intercambiar los métodos de referencia de elementos de los punteros y de las tablas. Es decir, podemos poner el desplazamiento respecto a uno puntero entre corchetes, y podemos poner el índice de un vector sumado a la dirección del vector y todo junto precedido de un asterisco. Sin embargo, hay que tener presente que el puntero es variable (pt++; está permitido) y el nombre de la tabla no (t++ no está permitido).

Ejemplos:

pt[i] = 13; <=> *(pt + i) = 13 
printf("%d\n", *(t + i)); <=> printf("%d\n", t[i]);

 

Pin It