View Full Version : [C] Puntatori e pila
Supponendo di avere un programma che fa solo
int main()
{
int var = 0;
int *p;
p = &a;
...non importante
}
nella pila come viene gestito il tutto?
cioè:
1 - int var = 0; var viene messo nella pila, ma viene inserito anche il suo valore nello stack oppure va in un altro segmento?
2- int var = 0; per allocare un intero in memoria usiamo 4 byte, pero c'e anche il nome della variabile (var) che sono 3 caratteri piu il terminatore, quindi sulla pila avremmo 4 byte del nome della variabile piu 4 byte del contenuto della variabile?
3- int *p; quando dichiaro un puntatore, nello stack che valore gli viene assegnato di default? viene creato un indirizzo dinamico dall'heap che viene assegnato al puntatore?
4- p = &a; a questo punto nella pila cosa succede? a p assegniamo l'indirizzo della variabile a, ma come fa a prenderla, chi deteneva l'indirizzo della variabile?
sicuramente ho fatto 1000! errori ma sto cercando di imparare come lavora la pila :doh:
p.s. questo prototipo di funzione void *f(); è uguale a void f(); o sono due cose diverse?
Daniels118
20-01-2014, 13:25
Ciao,
1 - nello stack viene inserito solo il valore di var, in questo caso 4 byte tutti a zero;
2 - i nomi delle variabili figurano solo nel sorgente, una volta compilato il programma non vengono più presi in considerazione, pertanto non occupano spazio in memoria;
3 - quando dichiari un puntatore senza inizializzarlo, viene solo decrementato lo stack pointer, senza scrivere alcun valore (vale anche per variabili non inizializzate), pertanto assume il valore che si trovava in quell'area dello stack (praticamente spazzatura);
4 - gli indirizzi delle variabili li decide il compilatore (a meno di eventuali offset per la rilocazione del programma in memoria) e restano invariati per tutta la fase di compilazione.
Se dichiari una funzione void vuol dire che quella funzione non restituisce alcun valore. se la dichiari come void* vuol dire che restituisce un puntatore a void, ovvero un puntatore ad un tipo di dato non determinato; tipicamente si utilizza quando la stessa funzione può restituire un puntatore a dati di diverso tipo; sta al chiamante determinare che tipo di dato viene restituito in base alle specifiche della funzione.
grazie mille daniele.
volevo chiederti due cose che non ho ancora ben chiare:
1) so che la funzione void f(){..} restituisce un void, tu dici che void *f() restituisce un puntatore a void..quindi è uguale a scrivere *void f()?
2)se i nomi delle variabili non vengono considerati piu una volta compilato il programma, se il programma implica una modifica di una variabile, ad esempio un incremento (x++) come fa a sapere il valore che aveva prima quella variabile se non ne conosco il nome?
Daniels118
20-01-2014, 14:25
1) Personalmente non ricordo di aver mai visto l'asterisco scritto prima del tipo di dato, credo che *void generi un errore di sintassi.
2) (come ho scritto prima) una volta che il compilatore ha assegnato un indirizzo ad una variabile, tale indirizzo rimane invariato durante tutta la fase di compilazione e (aggiungo) resta legato alla variabile a cui è assegnato; pertanto, ogni volta che il compilatore incontra la variabile x - qualunque operazione tu voglia fare con essa - utilizzerà l'indirizzo assegnato al momento della dichiarazione.
1) Personalmente non ricordo di aver mai visto l'asterisco scritto prima del tipo di dato, credo che *void generi un errore di sintassi.
2) (come ho scritto prima) una volta che il compilatore ha assegnato un indirizzo ad una variabile, tale indirizzo rimane invariato durante tutta la fase di compilazione e (aggiungo) resta legato alla variabile a cui è assegnato; pertanto, ogni volta che il compilatore incontra la variabile x - qualunque operazione tu voglia fare con essa - utilizzerà l'indirizzo assegnato al momento della dichiarazione.
grazie mille daniele, alla fine è tutto piu semplice di quello che sembra.
la dichiarazione del prototipo void *f(); mi aveva spiazzato perche avevo letto che le funzioni erano dei puntatori e vedere * prima della funzione pensavo fosse un puntatore a puntatore, invece come mi hai spiegato è cioè che viene restituito, un puntatore a void.
grazie mille ancora:)
vendettaaaaa
20-01-2014, 18:04
grazie mille daniele, alla fine è tutto piu semplice di quello che sembra.
la dichiarazione del prototipo void *f(); mi aveva spiazzato perche avevo letto che le funzioni erano dei puntatori e vedere * prima della funzione pensavo fosse un puntatore a puntatore, invece come mi hai spiegato è cioè che viene restituito, un puntatore a void.
grazie mille ancora:)
Infatti l'asterisco dovrebbe stare attaccato al tipo, anzichè alla variabile (o alla funzione), perchè va a modificare il tipo. Invece i C-isti lo attaccano alle variabili...bah!
Cmq non si dice "restituisce un void", perchè void non è un tipo. Indica la mancanza di un valore di ritorno.
void* invece significa un puntatore a qualsiasi tipo. Una funzione che accetta un parametro void* può prendere in ingresso un puntatore qualsiasi. Poi lo casta a quel che le serve e lo usa, ed è un passaggio obbligato visto che non puoi dereferenziare una variabile void:
void* a = f();
*a = 3; // errore
*((int*)a) = 3; // ok (sintatticamente, per lo meno)
Oceans11
20-01-2014, 19:30
Infatti l'asterisco dovrebbe stare attaccato al tipo, anzichè alla variabile (o alla funzione), perchè va a modificare il tipo. Invece i C-isti lo attaccano alle variabili...bah!
Personalmente l'asterisco lo attacco (come i C-isti) alla variabile perchè dichiarazioni del tipo:
int *x, y; scritta così mi rende chiaro subito che x è puntatore e y no. Al contrario:
int* x, y; così sembrano entrambi variabili di tipo int* (ossia puntatori a int)
vendettaaaaa
20-01-2014, 22:10
Personalmente l'asterisco lo attacco (come i C-isti) alla variabile perchè dichiarazioni del tipo:
int *x, y; scritta così mi rende chiaro subito che x è puntatore e y no. Al contrario:
int* x, y; così sembrano entrambi variabili di tipo int* (ossia puntatori a int)
Perchè ti capita spesso? Io metto una variabile per riga cmq, più chiaro per me.
Oceans11
20-01-2014, 23:01
Perchè ti capita spesso? Io metto una variabile per riga cmq, più chiaro per me.
No in realtà non lo faccio capitare, metto anche io una variabile per riga.
Volevo dire che ho fatto mio quello stile di format quando ho approcciato al c e quello mi è rimasto.
Devo dire che però non così infrequentemente incontro codice (di altre persone) che usa l'altro tipo.
Daniels118
21-01-2014, 07:44
Sintatticamente è corretto in entrambi i modi, io personalmente ricordo di aver variato il mio stile, gli ultimi programmi che ho scritto in c avevano l'asterisco attaccato alla variabile. In ogni caso ho sempre adottato il metodo di scrivere una variabile per riga, lo trovo molto più chiaro.
bancodeipugni
21-01-2014, 19:56
Sintatticamente è corretto in entrambi i modi, io personalmente ricordo di aver variato il mio stile, gli ultimi programmi che ho scritto in c avevano l'asterisco attaccato alla variabile. In ogni caso ho sempre adottato il metodo di scrivere una variabile per riga, lo trovo molto più chiaro.
ma anche più lungo
tu scrivi:
int a;
int b;
int *c;
char *T;
float m;
....
....
Daniels118
21-01-2014, 20:07
La gente fa sempre a gara per quello e tu ti preoccupi di risparmiare :D
A parte gli scherzi, nomi di variabili a, b, c possono andare bene a scuola, in un progetto serio si utilizzano quasi sempre nomi mnemonici di discreta lunghezza (chi non lo fa dovrebbe cominciare), basta metterne 3 sulla stessa riga per andare oltre il margine. Avendo scritto di recente programmi su terminale 3270 ho trovato molto sconveniente superare i 72 caratteri per riga, la navigazione diventa un inferno, poi, de gustibus...
bancodeipugni
22-01-2014, 10:13
si puo' andare a capo con la virgola per evitare di ripetere int ;)
su programmi complessi converrebbe proprio creare l'.h solo per le variabili, uno solo per le costanti ecc
bancodeipugni
22-01-2014, 19:48
le metti dentro la funzione, ovviamente
Daniels118
23-01-2014, 08:08
Credo che intendesse dire "mettere l'include nella funzione". A me personalmente non piace quest'approccio ma, come ho detto prima, è questione di gusti.
bancodeipugni
23-01-2014, 10:49
dipende quanto vasto è il programma :sofico:
potrebbe far comodo anche la realizzazione di librerie condivise ecc per unificare il codice
vendettaaaaa
23-01-2014, 18:15
dipende quanto vasto è il programma :sofico:
potrebbe far comodo anche la realizzazione di librerie condivise ecc per unificare il codice
Che trovata geniale!!! :eek:
bancodeipugni
23-01-2014, 20:27
prova in c:\windows\system32
è pieno :eek: :oink: :ciapet:
bancodeipugni
24-01-2014, 11:25
l'estetica nei prg conta fino a mezzogiorno conta che funzionino
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.