Enrere Mòdul 5
Fonaments de Programació. Llenguatge C/C++---
Pràctica    Resum teòric Exercicis
Pràctica d'ampliació

 
Ús dels punters en els vectors multidimensionals

En aquesta pràctica es tractarà d'entendre bé com s'emmagatzemen les dades en un vector multidimensional. També aprendrem la relació entre els punters i els vectors multidimensionals.

 

Desenvolupament de la pràctica

Parlem indistintament de vector o de taula per fer referència a la mateixa estructura de dades. Així com en els vectors unidimensionals, en els vectors multidimensionals el nom del vector també assenyala la direcció de la memòria del primer element. Si tenim la declaració:

int taula[3][5];

el nom taula representa l'adreça del primer element del vector, és a dir, &taula[0][0].

Un vector bidimensional es pot considerar com un vector de vectors, i és possible, per tant, pensar que taula[0] representa al subvector:

taula[0][0], taula[0][1], taula[0][2], taula[0][3], taula[0][4]

i que taula[1] representa al subvector;

taula[1][0], taula[1][1], taula[1][2], taula[1][3], taula[1][4]

Resumint, taula apunta a taula[0], que és un vector d'enters, i taula[0] apunta a taula[0][0], que és un enter. Per tant, taula és un punter que apunta a un punter.

Quina diferència existeix entre un punter a un vector i un punter a un enter? Tot i que els dos emmagatzemen posicions de memòria, la diferència està en la grandària de l'objecte al qual apunten. A l'exemple anterior,  el punter taula[0] apunta a un enter per tant apunta a un objecte de 4 octets mentre que taula apunta a un vector de 5 enters i, per tant, a un objecte de 20 octets.

És per aquesta raó que si tenim:

taula + 1 s’obtindrà una adreça 20 octets més gran.

taula[0] + 1 s’obtindrà una adreça 4 octets més gran.

com podrem comprovar en el següent programa.

// m6p05.c - Ús de punters en matrius bidimensionals -
#include <stdio.h>

#include <stdlib.h>


int main(){

   int taula [3][5];
   int *p;

   /*el nom taula representa l'adreça del primer element
   del vector es a dir &taula[0][0].*/
   system("clear");
   printf("\n valor de taula = %u",taula);

   printf("\n valor de taula[0] = %u",taula[0]);
   printf("\n adreça de taula[0][0] = %u",&taula[0][0]);
   printf("\n adreça de taula[0][1] = %u",&taula[0][1]);
   printf("\n adreça de taula[0][2] = %u",&taula[0][2]);
   printf("\n adreça de taula[0][3] = %u",&taula[0][3]);
   printf("\n adreça de taula[0][4] = %u\n",&taula[0][4]);


   printf("\n valor de taula[1] = %u",taula[1]);
   printf("\n valor de taula[2] = %u",taula[2]);
   printf("\n valor de taula[3] = %u",taula[3]);

   printf("\n taula+1 = %u ",taula+1);
   printf("\n taula[0] + 1 = %u",taula[0]+1);

   taula[2][3]=5;
   p=taula[0];

   printf("\n taula[2][3] = %d",taula[2][3]);
   printf("\n *(*(taula+2)+3) = %d",*(*(taula+2)+3));
   printf("\n *(p+2*5+3) = %d\n", *(p+2*5+3));
   return 0;

}

 

Captura de l'execució del programa.

 

Explicació del programa

Per tal d'explicar aquest programa, fixem-nos en la sortida, que pot ser com aquesta (les adreces concretes poden variar d'una execució a una altra):

Segons les dades de la sortida del programa, les adreces de les 15 posicions de memòria de la matriu taula[][] són:

6684092 6684096 6684100 6684104 6684108
6684112 6684116 6684120 6684124 6684128
6684132 6684136 6684140 6684144 6684144

 

Tant taula com taula[0] són punters que apunten a la primera posició de memòria, és a dir, 6684092

El punter taula[1] apunta al primer element de la segona fila (del segon subvector) i taula[2] apunta al primer element de la tercera fila.

Encara que sembli que taula és el mateix que taula[0], ambdós punters apunten a objectes diferents, això és posa de manifest en l'aritmètica de punters:

taula+1 = 6684112  (una posició de memòria 20 octets més alta) 
taula[0] + 1 = 6684096 (una posició de memòria 4 octets més alta)

Per últim, el programa mostra tres formes de referir-nos a un element concret de la matriu, en aquest cas, l'element [2][3], 

  • taula[2][3]; 
  • *(*(taula+2)+3));
  • *(p+2*5+3));    (on p és un punter enter a la primera posició del vector p=taula[0])

En general, per referir-nos a l'element [i][j] s'escriuria:

  • taula[i][j]
  • *(*(taula+i)+j));
  • *(p+i*5+j)); 

Si en el cas d'un vector unidimensional, taula[2] era equivalent a *(taula+2) i proporciona el tercer element del vector, en un vector bidimensional, *(taula+2) és el nom d’un vector.

¿Com representaríem taula[2][3] (tercera fila, quarta columna)?

Per arribar a la tercera fila del vector hem d'escriure *(taula+2), per arribar a la columna 4 afegint 3, és a dir *(taula+2)+3 i l’ element hauria de ser *(*(taula+2)+3).