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

 
Punters a qualsevol tipus de dades

Recordem que un punter és una variable que conté l'adreça d’altra variable. És possible assignar el contingut d'un punter a un altre punter si els dos són del mateix tipus, si no és així,  hem de fer ús d'un operador de conversió. És possible, no obstant, utilitzar uns punters a qualsevol tipus de dades. Aquests punters són els anomenats punters void. Veurem en aquesta pràctica l'ús d'aquests tipus de punters.

 

Desenvolupament de la pràctica

Els punters del tipus void  es declaren com:

void *

Tots els tipus de punters poden ser assignats a un punter del tipus void. En canvi un punter del tipus void no pot ser directament assignat a un punter d'un altre tipus sense una conversió explícita.

Per exemple, el compilador sap que un punter a un int fa referència a 4 octets de memòria en una màquina de 32 bytes. Els punters a void simplement fan referència a una posició de memòria i el compilador no sap la grandària de l'objecte a què fa referència. El compilador necessita conèixer el tipus de dades per saber el nombre d'octets a desreferenciar.

En aquesta pràctica veurem una senzilla aplicació dels punters tipus void. Consisteix en una funció que pot admetre un argument de tipus indeterminat. Aquest tipus de funció ens recorda les funcions d'entrada i sortida printf() i scanf() que tenen aquesta característica.

Creeu un nou arxiu del tipus C anomenat m5p03.cc i escriviu el següent codi:

// m5p03.cc - Ús dels punters tipus void -
#include <iostream>

#include <stdlib.h>

using namespace std;

void funcio_exemple( void *prtvoid, char tipus);

int main(){

   // declarem les variables i al
   //mateix moment assignem valors.

   int a=10,*prta=&a;
   float b=5.5, *prtb=&b;
   char c='a', *prtc=&c;
   system("clear");

   // cridem a la funció i li passem com a segon argument el
   //tipus de dada a la que apunta el punter

   // una referència a int
   funcio_exemple(prta, 'i');

   // una referència a float
   funcio_exemple(prtb, 'f');

   // una referència a char
   funcio_exemple(prtc, 'c');

 
  return 0;
}

void funcio_exemple( void *prtvoid, char tipus){

   switch(tipus){
      case 'i':
              cout<<"Valor rebut per la funció ... "
              << *((int *) prtvoid)<<endl;
              break;

      case 'f':
              cout<<"Valor rebut per la funció ... "
              << *((float *) prtvoid)<<endl;
              break;

      case 'c':
              cout<<"Valor rebut per la funció ... "
              << *((char *) prtvoid)<<endl;
              break;

      default:
             cout<<"Tipus no vàlid .."<<endl;

   }

}

 

Captura de l'execució del programa.

 

Explicació del programa

Fixeu-vos que la funció funcio_exemple té dos arguments. El segon argument és necessàriament un caràcter, però el primer argument pot ser qualsevol punter. En la declaració de la funció, el primer argument és un punter del tipus void *

Quan es té un punter del tipus void *, és necessari fer una conversió explícita per tenir un punter d'un tipus específic per tal de fer-lo servir. Això es fa amb els operadors: (int *) (float *) i (char *) que converteixen el punter void * en punters del tipus int, float i char respectivament.