PDA

View Full Version : [C] difficoltà coi puntatori


RaouL_BennetH
16-01-2005, 15:02
Salve ragazzi, vi confesso che mi sento davvero tanto scemo ma, non riesco a capire l'utilità dei puntatori in C.

Cioè, mi chiedevo, che utilità hanno, nel senso che avere una variabile che punta all'indirizzo di un'altra variabile, non riesco a darle un senso.

Dato che, per imparare il linguaggio C i puntatori sono una condizione sine qua non, prima di darmi all'ippica, qualcuno di voi dotato di un pò di pazienza, cercherebbe di far capire ad un testone come me a cosa servono?

Thx.

RaouL.

VegetaSSJ5
16-01-2005, 16:34
io penso che chiunque all'inizio abbia pensato almeno una volta all'inutilità dei puntatori se visti con la definizione che ne hai dato tu. per il momento prendi un puntatore come un modo per realizzare le stringhe in c, oppure per allocare dinamicamente memoria (cioè ridimensionare un array, dare una dimensione a runtime ecc..). quando comincerai ad impratichieri ti sorprenderai della grandissima varietà di utilizzi che potrai farne.:)

Argosoft
16-01-2005, 16:44
già: a che potrebbe servire sapere l'indirizzo di una variabile? :)
Prova a pensare per esempio al passaggio dei parametri nelle funzioni:

void aaa (int x, int *y){
x = 5;
*y = 5;
}

il parametro "x" viene passato per VALORE, mentre il parametro "y" per RIFERIMENTO. Che vuol dire ciò?
Per valore - Che quando la funzione sarà chiamata, le verrà passata UNA COPIA del parametro x; nella funzione puoi assegnare qualsiasi valore ad x, ma modificherai solo la copia, quindi quando la funzione terminerà ti ritroverai esattamente come prima :) , cioè, la variabile che hai passato come x è rimasta invariata.
Per riferimento - alla funzione verrà passato L'INDIRIZZO della variabile, quindi un PUNTATORE ad essa. :) Agendo sul puntatore, ora, non stai modificando una copia della variabile passata, ma la variabile originale ! (Nell'esempio che ho fatto io , *y = 5 significa: poni a 5 il contenuto della variabile di indirizzo y).
Per questo quando serve che una funzione possa modificare un parametro si usano i puntatori.

Un altro utilizzo sta nella creazione di strutture dinamiche (array, liste, alberi... ). Prendiamo il caso più semplice: la creazione di un array dinamico. Come saprai, se noi dichiariamo un array , per esempio, in questo modo

int vet[10];

nella sezione di memoria del nostro programma dedicata ai dati verrà fatto spazio per 10 variabili int contigue, e "vet" verrà fatto puntare alla prima. Ora, quest'array è STATICO, perché una volta dichiarato da 10, niente e nessuno potrà ridimensionarlo :) . Se non si sanno a priori le dimensioni dell'array da gestire, si userà la creazione DINAMICA. Come si fa?
Qui ci viene in aiuto una funzione di nome malloc() . La malloc , dato come parametro un numero di byte, alloca per noi uno spazio di memoria di quella dimensione nella parte di memoria centrale inutilizzata dal sistema operativo e dagli altri programmi (che si chiama HEAP). Dopo averlo fatto restituisce un puntatore a quell'area di memoria appena creata, che noi possiamo usare a piacimento. Nel caso di un array dinamico, di 20 elementi per esempio, la procedura da seguire sarà:


void main(void){
int *vet; //vogliamo dichiarare un vettore di interi
int ne = 20; //Lo mettiamo come esempio, nella realtà la dimensione non si definisce qui, sennò che array dinamico sarebbe? :)
int dimVet = sizeof(int) * ne; //questo sarà lo spazio da allocare. sizeof restituisce la dimensione in byte di un tipo di dato, che noi moltiplicheremo per il numero degli elementi che ci servono

vet = malloc(dimVet); //tracchete! la malloc ci riserverà un tot di spazio per il nostro array e ne assegnerà l'indirizzo a vet. a questo punto vet potrà essere usato come un normale array:
vet[0] = 5;

//Dopo aver utilizzato l'array .. dovremo liberarcene :). Visto che viene creato non nell'area di memoria del programma ma in un posto dimenticato da Dio, al momento dell'uscita dal programma / dalla procedura , l'array rimane lì a occupare spazio, invece di essere liberato automaticamente. per farlo esiste la funzione

free(vet); //che ditrugge l'area di memoria collegata a vet e la fa tornare "disponibile" al sistema operativo. Cmq, ora che ci penso, mi pare che Windows al momento dell'uscita dal programma faccia automaticamente una "liberazione totale" di tutta la memoria occupata, ma... è sempre buona norma farlo "a mano" durante il programma non appena una struttura dinamica non dovesse più servire.
}


Spero di essere stato chiaro, se nel C capisci i puntatori capisci tutto :D

ciao!

RaouL_BennetH
16-01-2005, 16:52
Grazie mille ad entrambi :)

Devo sbatterci un bel pò la capoccia comunque perchè non mi sono ancora chiari :muro:

Argosoft
16-01-2005, 17:10
Originariamente inviato da RaouL_BennetH
Devo sbatterci un bel pò la capoccia comunque perchè non mi sono ancora chiari :muro:

:eek: nnnooooooooooooo!!!! :cry: ho fallito nel tentare di dare la spiegazione più chiara possibile ai puntatori!!! :cry: non potrò mai essere un professore di informaticaaa!!!! :cry:

ora mi ammazzo. addio.


PAF




:Prrr:
però dai, l'hai letto in 2 minuti.. prova a concentrarti un po' e vedrai che sarà chiaro ^_^

ciao!

VegetaSSJ5
16-01-2005, 17:31
Originariamente inviato da Argosoft
:eek: nnnooooooooooooo!!!! :cry: ho fallito nel tentare di dare la spiegazione più chiara possibile ai puntatori!!! :cry: non potrò mai essere un professore di informaticaaa!!!! :cry:
ti assicuro che i professori di informatica (almeno alcuni) hanno molto da invidiare su come si spiega a della gente che non sa nulla su quell'argomento... almeno da me ci sono delle capre immani...:eek: :cry:

RaouL_BennetH
16-01-2005, 18:23
Originariamente inviato da Argosoft
:eek: nnnooooooooooooo!!!! :cry: ho fallito nel tentare di dare la spiegazione più chiara possibile ai puntatori!!! :cry: non potrò mai essere un professore di informaticaaa!!!! :cry:

ora mi ammazzo. addio.


PAF




:Prrr:
però dai, l'hai letto in 2 minuti.. prova a concentrarti un po' e vedrai che sarà chiaro ^_^

ciao!

ma la colpa mica è tua !!

Anche se un professore è bravo, un alunno può sempre essere deficiente :)

(nel senso che deficie nell'apprendimento :O ) :D

VegetaSSJ5
16-01-2005, 18:28
Originariamente inviato da RaouL_BennetH
deficie
questo termine mi è nuovo...:what:

Ziosilvio
16-01-2005, 19:04
Originariamente inviato da RaouL_BennetH
non riesco a capire l'utilità dei puntatori in C.
Anzitutto: se, come in C, passi i parametri alle funzioni solo per valore, e se una funzione ha la necessità di eseguire una reimpostazione di uno dei suoi parametri; allora l'unico modo per farlo è passare un puntatore alla variabile.

Inoltre, se puoi ottenere l'indirizzo di una variabile ed elaborarlo, allora molte altre operazioni (tra tutte, ottenere un indirizzo un certo numero di locazioni dopo una variabile data) diventano molto più semplici.

Non va dimenticato il fatto che, con ottima probabilità, una variabile di un tipo strutturato occupa più spazio di una variabile puntatore allo stesso tipo.

Altro non mi viene in mente, per ora...

Cfranco
17-01-2005, 09:28
Utilizzi tipici dei puntatori :
- passaggio per riferimento .
Esempi di questo tipo ne trovi parecchi in questo thread , non insisterò oltre sulla sua importanza basti sapere che qualsiasi linguaggio di programmazione prevede questo tipo di uso dei puntatori , talvolta sarà mascherato in modo da non mostrare esplicitamente il passaggio del puntatore ( come ad es. in VB o in Java ) , ma sotto sotto funziona sempre in questo modo .
- utilizzo dinamico della memoria .
Anche questa funzionalità é già stata accennata , tramite l' utilizzo dei puntatori é possibile allocare la memoria secondo le necessità senza imporre dimensioni predefinite .
- utilizzo di dati astratti .
Questa é un uso dei puntatori molto interessante , anche se raro , si riferisce alla creazione di tipi di dato che riferiscono ad altri dati .
Le forme più comuni con cui si presentano sono le liste concatenate e gli alberi , ma esistono anche casi più complessi .
Per esempio se volessimo fare una struttura di dati per una persona cominceremo a creare i campi relativi al nome , alla data di nascita , altezza etc. , poi quando arriviamo a dover inserire i dati relativi ai genitori , al coniuge o ai figli cosa facciamo ? Se inserissimo un' altra struttura sarebbe uno spreco di spazio , oltretutto sarebbe anche poco pratico , se cercassimo il fratello del nonno della moglie di una persona come possiamo fare ?
La soluzione più semplice é che i dati relativi alla parentela siano dei puntatori a strutture analoghe , ogni persona ha la sua e in ogni struttura sono definiti i puntatori che ti dicono dove trovare i dati relativi .

L' utilizzo dei puntatori é tuttavia fonte inesauribile di errori terrificanti per cui spesso nei linguaggi "evoluti" si cerca di limitare la possibilità di utilizzo di questi strumenti , e spesso si ricorre a sistemi estremi per nascondere in ogni maniera la loro esistenza .