Newsgroup: it.comp.lang.c
Titolo: puntatori void

Leggo sul K&R che i puntatori void non possono essere referenziati. 
Cosa significa? Mi scuso per aver lurkato 
pochiiiiiiiiiiiiiiiiiiiissimo, quasi niente. 
--
bubbo

pochiiiiiiiiiiiiiiiiiiiissimo, quasi niente. 
Dato un puntatore:
int * pi;
Deferenziare e' questa operazione:
*pi;
Ovvero andare a leggere il valore puntato.
Questo lo puoi fare con tutti i puntatori, tranne che con quelli a
void, per il semplice fatto che il tipo void "non e' definito" come
gli altri tipi, ma serve solo per indicare che non ci sono valori.
Deverenziare un puntatore a void sarebbe come ottenere un oggetto di
tipo void, che non avrebbe senso.
-- 
Mox
"Trust the programmer."
"Don't prevent the programmer from doing what needs to be done."
"Keep the language small and simple."
"Provide only one way to do an operation."

 tipo void, che non avrebbe senso.
Del resto dereferenziare un puntatore p significa andare a leggere un valore
prendendo x byte a partire da quello puntato da p. Se il puntatore punta ad
uno short int, allora preleva due byte a partire da quello puntato da p, se
punta invece ad un long, allora preleva 4 byte a partire da quello puntato
da p. DOMANDA: e se punta a void, quanti byte preleva, ma soprattutto come
deve interpretare il valore? La risposta che il compilatore ci darebbe sarà:
"e se non me lo dici tu!". Allora dovremmo dire *((short *)p) per esempio.

 Cosa significa? 
Non possono essere _dereferenziati_. Un  puntatore e` una variabile come
le altre,  solo che contiene  un indirizzo di memoria. Quando  valuti il
nome  del puntatore  valuti quindi  un indirizzo  di memoria. In  alcune
circostanze e` pero` utile vedere non  il contenuto del puntatore in se,
ma  il  contenuto dell'area  di  memoria  puntata. Questa operazione  di
chiama, appunto, dereferenziazione.
int i = 123;        /* Variabile intera */
int *p;             /* Puntatore ad un intero, non inizializzato */
p = &i;             /* Faccio puntare il puntatore all'area di memoria
                       allocata per la variabile 'i' (con l'operatore &)
                    */
printf("%p\n", p);  /* Stampa il valore di 'p', ovvero l'indirizzo di 'i'*/
printf("%d\n", *p); /* Dereferenzio 'p', quindi stampo il valore di 'i' */
I  puntatori  sono  tipizzati,  ovvero  contengono  un'informazione  sul
contenuto dell'area  di memoria  puntata. Esiste un tipo  particolare di
puntatore,  il  puntatore a  void  (void  *),  che non  fornisce  alcuna
informazione  sulla memoria  puntata  (diciamo generico). E`  facilmente
intuibile che non e` possibile  dereferenziare tale puntatore, visto che
non e` disponibile alcuna informazione sul tipo di dato puntato.
I puntatori  sono uno degli  argomenti piu` ostici  del C, e  questa non
vuole certo essere una trattazione esaustiva. Ti consiglio di continuare
la lettura del K&R per approfondire il concetto.
ciao
Kronos
-- 
Home: 
http://kronoz.cjb.net
Mi piace avere amici rispettabili;
Mi piace essere il peggiore della compagnia.

 Allora dovremmo dire *((short *)p) per esempio. 
Quindi si usano le conversioni cast. Giusto?
Ma esiste forse un modo per sapere di che dimensioni è una variabile 
puntata da un puntatore void? Qualcosa tipo l'operatore sizeof, ma 
riferito ai puntatori. Io credo che non sia possibile farlo a runtime, 
ma forse in c++... 
--
bubbo

 ma forse in c++...
NO! Sono problemi tuoi! Il compilatore da più responsabilità a te!
Il problema ( e qui si incomincia a filosofeggiare) è che il C è un
linguaggio ad alto livello, ma secondo me (ma secondo anche altri) è per
certi versi anche di basso livello.
Mi spiego meglio:
Attenzione ai cast per i puntatori! In questo caso è cura del programmatore
ricordare il puntatore a quale tipo di dato sta puntando. Se io facessi:
int x=1024;
void * p;
p=&x;
è lecito fare: printf("Il valore di x è %d",*((int *)p) );
ma se facessimo: printf("Il valore di x è %d",*((char*)p) );
cosa verrebbe stampato?
Prova a rispondere senza provarlo con la macchina...
Suggerimento: come si rappresenta in binario 1024?
Prova poi a compilarlo per x = 1000 e per x = 10.
Alla prossima!
johnpp

ricordare il puntatore a quale tipo di dato sta puntando. Se io facessi:
Leggi la mia firma :)  Se proprio deve aprirsi un discorso filosofico
e' su questo punto che si apre.
Ti riporto un'analogia tratta dal Koenig: il C e' come un coltello
affilato, funziona molto bene e fa' solo quello che vuio, il prezzo e'
questo: se sbagli ti tagli.


 ma forse in c++... 
Non si puo`  fare neppure in C++. La RTTI funziona  solo quando in gioco
ci  sono puntatori  (o reference)  ad  una classe  base. Se utilizzi  un
puntatore a void ne` static_cast<> ne` dynamic_cast<> (e neppure typeid)
funzionano piu`.
f/up settato
ciao
Kronos
-- 
Home: 
http://kronoz.cjb.net
La vispa candela bruciava l'erbetta
creando un'essenza alquanto sospetta;
sembrava l'odore di una sacrestia
ma presto mi accorsi che era maria.

 "Provide only one way to do an operation."
Me la traduci in napoletano o in italiano? Grazie!
johnpp

Me la traduci in napoletano o in italiano? Grazie!
Sono di Asti e piemontese, il napoleta non mi viene molto bene :P
Accontentati dell'italiano :)
Dai fiducia al programmatore
Non impedirgli di fare quello che deve fare
Mantieni il linguaggio semplice e leggero (li dice letteralmente
"piccolo")
Fornisci solo un modo per fare un'operazione (in aperta
contrapposizione al Perl NdT)
-- 


Fornisci solo un modo per fare un'operazione 
come mai?
credevo che più modi ci sono meglio è...

credevo che piů modi ci sono meglio č...
Programmatore Perl? :)
Sono punti di vista, il Perl ti fornisce N modi diversi, il che
significa che c'e' una buona probabilita' che in ogni occasione ci sia
un modo ottimo per farla... ma quanto e' complesso il Perl?
Quando hanno scritto il C volevano un linguaggio semplice e diretto,
la scelta in tal senso sarebbe stata inconcigliabile se avessero
voluto fare un linguaggio TIMTOWTDAT.
Nessuna delle 2 scelte e' sbagliata, sono solo diverse.


Suggerimento: come si rappresenta in binario 1024?
suggerimento al suggeritore: 
parliamo prima di endianess della macchina, del fatto che nessuno ha
mai sostenuto che sizeof(int) debba esser 4? delle diverse
rappresentazioni di un numero negativo su una macchina?

Nessuna delle 2 scelte e' sbagliata, sono solo diverse.
ma fino a ora mi risulta che in C (in tutti i programmi che ho
incontrato)ci sono 100ia di modi per ottenere da un PC il medesimo
risultato in termini di input-output ma con istruzioni del linguaggio
diverse

 rappresentazioni di un numero negativo su una macchina?
Ho utilizzato un int positivo apposta.
Grazie,
johnpp
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

diverse
Non si parla di librerie (standard o meno), che possono fornire
centinaia e centinaia di funzioni, ma del core del linguaggio.
Proviamo a spiegare, anche se non sara' facile.
La filosofia del Perl e' in sintesi questa: "per ogni azione ti
forniamo N modi diversi di procedere, sta a te programmatore essere
abbastanza sveglio da scegliere quello che meglio si adatta al
momento".
Un esempio? Beh, solo per fare l'IF hai 3 modi diversi... basta aprire
un manuale di Perl per rimanere spiazzati dall'enormita' di modi
diversi di procedere che vengono presentati... e non si parla ancora
di moduli aggiuntivi.
Qui sta la differenza: in C le istruzioni sono quelle, ognuna ha un
suo scopo[1] diverso da quello di tutte le altre.
Il C e' concettualmente semplice e facile da usare, il Perl
assolutamente no... il lato opposto della medaglia e' che in Perl per
moltissime cose esiste un modo di procedere pulito ed elegante
inglobato nel core del linguaggio[2], mentre in C si deve praticamente
sempre ricorrere a librerie esterne.
Detto lo spiegone, vediamo se posso rendere una buona idea su questi 2
linguaggi e le loro differenze / affinita'.
- il Perl come il C ha una sezione che raccoglie i codici "migliori": 
  Black Perl, e il nome dice tutto... sono degli ottimi concorrenti 
  dell'International Obfuscated C Code Contest.
- Entrambi si rispecchiano pienamente in questa frase: "Un linguaggio 
  che non influenza il tuo modo di pensare circa la programmazione non
  vale la pena di essere imparato."
- su internet girava un simpatico documento, che parlava dei vari
linguaggi di programmazione e (ovviamente in tono scherzoso) di come
fosse possibile in ciascuno di essi eseguire una semplice operazione
("TASK :- To Shoot Yourself In The Foot"), ma rende molto bene le
differenze tra i linguaggi:
  a) in C ti spari su un piede
  b) in Perl anche, solo che puoi scegliere tra dozzine di armi e 
     munizionamenti diversi
Spero di essermi spiegato chiaramente :)
Per concludere un consiglio: quando qualcuno dice "Voglio un
linguaggio di programmazione in cui ho bisogno di dire solamente ciň
che vorrei fare", dategli un lecca-lecca.
[1] Se escludiamo da questo elenco la keyword for, che e' se vogliamo
l'unica non fondamentale, anche se indubbiamente comoda
[2] Per es la gestione delle espressioni regolari, portata al massimo
dello sviluppo e dell'integrazione con il resto del linguaggio.
