Go Down

Topic: Puntatori ... deep inside (Read 1 time) previous topic - next topic

MauroTec

@niki77

Se i valori dell'array cambiano e si riflettono alla struttura e viceversa stai occupando lo spazio di un puntatore di 16 bit. Mentre se non cambiano come penso complessivamente stai usando ptr 2 byte + a1,a2,a3=6 byte totale 8 byte. Mentre se i campi della struttura fossero puntatori a interi sensa segno occupi sempre 8 byte ma i valori si riflettono. Un puntatore viene salvato in un suo indirizzo di memoria e punta ad un'altro quindi complessivamente 8 byte per la struttura e 14 byte per l'array.

Ciao.
AvrDudeQui front end per avrdude https://gitorious.org/avrdudequi/pages/Home

niki77

Ok, si, sto usando un puntatore a 16 bit, occupa 2 byte , va benissimo così.

Ora visto che siamo in tema adiacente vorrei affrontare un altro mio dubbio amletico .(perdonatevi eventuali domande stupide ma negli ultimi 10 anni ho usato quasi esclusivamente linguaggi interpretati e non ho avuto modo di forgiare competenze un pò più advanced dei linguaggi compilati)


Code: [Select]

int A = 128; // Creo una variabile di tipo int (2 byte)

int * prtA = &a; // questo è un puntatore ad A , ovvero una 'variabile' di tipo puntatore che contiene l'indirizzo di memoria della variabile A
//occupa in memoria 2 byte(non perchè contiene un intero ma perchè un puntatore occupa 2 byte,perlomeno su questa architettura)


Veniamo al dunque, per semplicità farò l'esempio col tipo INT (2 byte).

Code: [Select]

void changeMyVal(int myval)
{
myval ++;
}
// che richiamo in questa maniera
int myInt = 128;
changeMyVal(myInt);
//giustamente qui il valore di myInt è rimasto 128, perchè nella chiamata è stata creata una variabile myVal che contiene lo stesso valore numerico //(128)della variabile passata dalla chiamata stessa.


Se invece :

Code: [Select]

void changeMyVal(int * myval)
{
*myval ++;
}

// che richiamo in questa maniera

int myInt = 128;
changeMyVal(&myInt);
//il valore in di myInt quì è stato correttamente portato a 129 perchè dentro la funzione è stato incrementato.Tuttavia, se non ho capito male, anche in questo caso la chiamata ha creato una variabile di tipo puntatore ad intero(quindi allocando 2 ulteriori byte) contenente la locazione di memoria del mio myInt .


Ora , tralasciando tutto il discorso di scope e visibilità variabili, allocazioni e deallocazioni, la domanda è questa:
E' possibile fare in modo che chiamando una procedura e/o funzione si possa passare per riferimento DIRETTAMENTE una variabile definita in un altro contesto ?

praticamente

Code: [Select]

int myInt = 128;
int * prtA = &myInt ; // qui ho già creato un puntatore a myInt

// vorrei chiamare la procedura
changeMyVal(prtA);
// passando come parametro QUEL ESATTO PUNTATORE per riferimento , e non creandone un altra copia.

oppure anche

int myInt = 128;

// vorrei chiamare la procedura
changeMyVal(myInt);
// passando come parametro QUELLA VARIABILE ESATTA per riferimento , e non creandone un altra copia.



Sperando di essere stato comprensibile, sto sbarellando o si può fare?
Grazie

Vi è una spiegazione scientifica a tutto.
La fede è solo quell'anello che si porta al dito dopo il matrimonio.

MauroTec

Si è possibile e lo stai già facendo nel primo e ultimo esempio. I puntatori passati come argomento di funzione sono più efficienti perchè automaticamente non viene creata una copia locale, cosa che accade solo passando la variabile per valore.

Usare & per referenziare è di uso comune e non occorre creare un puntatore prima della chiamata, in questo modo si risparmi tempo per allocare il puntatore.

I puntatori sono molto convenienti quando fanno riferimento ad una struttura oggetto di grandi dimensioni, più grande è più conviene. Usare un puntatore a byte che comunque è grande 16 bit non è conveniente, ma se è richiesto per la funzionalità pasienza.

Ciao.
AvrDudeQui front end per avrdude https://gitorious.org/avrdudequi/pages/Home

niki77

Intanto grazie per il supporto!



I puntatori sono molto convenienti quando fanno riferimento ad una struttura oggetto di grandi dimensioni, più grande è più conviene. Usare un puntatore a byte che comunque è grande 16 bit non è conveniente, ma se è richiesto per la funzionalità pasienza.



Mi permetto di aggiungere che, a volte, non è solo questione di convenienza, ma anche perchè non si può fare diversamente.
Ad esempio se da una funzione ho necessità di ritornare una serie di risultati superiori a 1.
In questo caso la funzione si comporta da 'FILLER' di oggetti/variabili.

oppure come nel mio caso, quando hai una serie di valori alla rinfusa dentro un array e vuoi modificarli più praticamente tramite una struttura.  :smiley-mr-green:

Vi è una spiegazione scientifica a tutto.
La fede è solo quell'anello che si porta al dito dopo il matrimonio.

MauroTec

Per impacchettare dati in un array ed estrarli singolarmente si possono usare le define o enum al fine di creare delle costanti numeriche da usare come indice di array, oppure ancora si possono creare funzioni/macro che ritornano il dato e prendono il puntatore ad array è la costante, se non si vuole usare l'operatore [] per estrarre il dato. Oppure come hai fatto tu, con le strutture ma occupando un po di spazio in più, comunque fintanto che le dichiarazioni sono dentro i blocchi {} cessano di esistere all'esterno liberando memoria.

Sta diventando una discussione a due.

Ciao.
AvrDudeQui front end per avrdude https://gitorious.org/avrdudequi/pages/Home

Go Up