Unqualunque ha scritto:
zio_mangrovia ha scritto:
probabilmente il mio errore è perché guardo solo il contenuto che è un indirizzo di memoria mentre in questo caso è diverso il tipo ...
Ecco bravo, un puntatore ad un intero ed un puntatore ad un puntatore non possono essere la stessa cosa, e guai se il linguaggio accettasse una simile confusione.
non è proprio così.
bisogna partire dall'A, non dall'ABC.
una volta, tanto tempo fa, non esistevano i linguaggi di programmazione ad alto livello, esisteva solo l'assembler (poi chiamato assembly), nel quale non esistono tipi, esistono essenzialmente numeri interi (tralascio la questione ftp).
questi numeri interi, tipicamente a 8, 16, 32 e oggi 64 bit, possono rappresentare qualsiasi cosa, da un contatore, al numero del voto preso all'esame, fino ad una locazione di memoria (cuttone sul cervellotico sistema segmentato tipico di intel, facciamo finta di avere un singolo segmentone e quindi una memoria flat, anche se flat in realtà non è).
bene, nel mondo della CPU non c'è distinzione tra dato, indirizzo e addirittura tra dato e programma (cuttone sui meccanismi introdotti per ridurre il rischio di modifica dei programmi e quindi del codice da parte di injection virale etc. la faccio facile).
benissimo, sta quindi al PROGRAMMA stabilire se il numero 27 è il mio voto in fisica, oppure l'indirizzo della 27-esima cella di memoria.
---
In C, nel vecchio C, questo è stato mantenuto, cioè i puntatori sono puntatori a qualcosa, senza sapere bene cosa.
un puntatore a un intero è identico a un puntatore a un float, oppure a una stringa.
è materialmente un numero intero (tipicamente a 32bit).
Questo però mantiene sul programmatore il "peso" di dover scrivere bene il programma, e in particolare evitare il "mischione" tra tipi diversi.
Se dichiari un puntatore a un intero, teoricamente, quello deve essere e quello deve rimanere, cioè deve puntare a un "qualcosa" che è un intero.
Se dichiari un puntatore a una stringa, allo stesso modo, dall'altra parte dovrebbe starci una stringa.
Non c'è però la minima garanzia, in C, che ciò avvenga.
Quindi, per mitigare questo problema, hanno introdotto (progressivamente) controlli sui tipi dei puntatori, al fine di intercettare, addirittura in fase di compilazione, operazioni "mischiate" in cui un puntatore al tipo X viene usato per il tipo Y.
Ci sono meccanismi per "evadere" (casting implicito ed esplicito) a questo limite così rigido.
---
In altri linguaggi la questione è ancora più "irrigidita", cioè il compilatore fa verifiche stringenti e assai "intrusive" sui puntatori.
Al fine, si auspica, di individuare i bug prima che il programma venga compilato
---
Riassumendo: tutti i puntatori sono uguali, in realtà.
La CPU se ne frega dei tipi, basta che in un registro di indirizzamento ci sia un intero (cuttone sulle varie piattaforme, su quelle in cui ci sono registri diversi tipo D0, A0, quelle in cui ci sono EAX, quelle in cui i registri sono tutti uguali tra di loro etc.etc)
Spero che lo spiegone, mentre sto guardando la mia gatta stecchita dal caldo, sia utile