jump to navigation

Non è un maleficio……..è un void* 24 novembre 2007

Posted by fripp in C, Informatica, Java, Programmazione.
Tags: , , ,
trackback

Quando mi sono avvicinato per la prima volta al linguaggio C (solo 4 anni fa) rimasi sinceramente perplesso e un poco impaurito: non avevo le conoscienze e nemmeno la spavalderia neccessaria per padroneggiare un linguaggio così di basso livello; per tale motivo mi feci accoglier tra le larghe e capienti braccia di Java.Piano piano però ho iniziato ad avvicinarmi al C con la riverenza che merita e ora posso dire che sono “madrelingua C”!.

Uno degli strumenti più potenti (e pericolosi!) del C sono i void*. La possibilità di poter referenziare il “non-tipo”, il “vuoto”, sinceramente mi metteva i brividi: era come poter accedere alle profondità più oscure dell’universo (o della RAM, che è lo stesso), come smascherare la (non) esistenza di entità spirituali più o meno onnipotenti!

Ok, basta, è un delirio, scusate.

Sappiamo che in C esiste una regola ferrea (anche in C nulla è ferreo): se dichiaro un puntatore ad un tipo, quel puntatore potrà refrerenziare solo zone di memoria che contengono quel tipo. I void* sono l’eccezione a quanto detto ora: un void* può contenere l’indirizzo di qualsiasi area di memoria contentente qualsiasi tipo di dato, tranne il tipo void stesso, che non può esser in se e per se non può e non potrà mai esser istanziato.Di fatto il void* in C rappresenta un “tipo generico”.

Ecco un esempio che potrà chiarire un poco di perplessità:

#include <stdio.h>
#include <stdlib.h>

int main(){
	int val=90;

	void* ptr=&val;

	printf("%d\n",*((int*)ptr));

	return 0;
}

Se provate a compilare e ad eseguire questo piccolo pezzo di codice, vedrete che stamperà a schermo esattamente il contenuto di val, 90, senza alcuna perdita di informazione! Come potete vedere, visto che il tipo void non si può dereferenziare, è necessario fare un cast a int* per acceder al valore puntato.Nell’usare i void* come tipi generici i cast di tipo sono una costante, che deve esser usata con molta attenzione: posso fare il cast a qualsiasi tipo mi venga in mente (il compilatore è tollerante), col rischio di accedere a zone di memoria che non mi competono. I void* vengono anche usati per implemenatare funzioni “generiche”, come le funzioni template del C++; un esempio è la funzione qsort implementata in stdlib.h:

#include <stdlib.h>

void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void*, const void*));

La funzione implementa l’algoritmo di ordinamento Quicksort e permette di ordinare qualsiasi vettore di qualsiasi tipo, visto che accetta come argomento un void*. Osservando il suo prototipo, notiamo che la situazione è alquanto complicata! Visto che la funzione non sa che tipo di vettore dovrà ordinare, occorre specificare non solo il numero di elementi del vettore (il parametro nmemb), ma anche la dimensione in byte di ogni elemento (il parametro size) e un puntatore a funzione che specifica la relazione d’ordine tra questi elementi.Ecco un esempio di come usare questa funzione:

#include
#include

#define DIM(v,type) (sizeof(v)/sizeof(type))

//prototipo della funzione di comparazione
int compare_function_int(const void*, const void*);
int main(){
int v[]={5,4,3,2,1};
int i;

//facciamo il cast a void* per passare il vettore alla funzione
qsort((void*)v,DIM(v,int),sizeof(int),compare_function_int);

//il vettore adesso è ordinato
for(i=0;i

Annunci

Commenti»

1. Ordeal - 24 novembre 2007

Nel primo codice sostituisci a void* ptr=&k;
void* p=&val;

2. fripp - 24 novembre 2007

@Ordeal: grazie per la segnalazione


Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...

%d blogger hanno fatto clic su Mi Piace per questo: