18/10/05 17:46
Nophiq
Vorrei commentare un programma a proposito:
Tutto questo non si potrebbe riassumere in
#include <stdio.h> #include <stdlib.h> main () { float *v; int n; printf("Inserisci la dimensione: "); scanf("%d", &n); v = (float*) malloc(n*sizeof(float)); ... uso dell'array ... free(v); }
Tutto questo non si potrebbe riassumere in
#include <stdio.h> #include <stdlib.h> main () { int n; printf("Inserisci la dimensione: "); scanf("%d", &n); [b]float v[n];[/b] ... uso dell'array ... }
Ultima modifica effettuata da Nophiq 18/10/05 17:46
aaa
19/10/05 12:31
pierotofy
Non puoi compilarlo il tuo esempio perch? in C la dichiarazione delle variabili va fatta all'inizio del programma. Non ? come in C++.
Il mio blog: piero.dev
19/10/05 15:19
Zizzius
Esatto: come dice Piero, non ? possibile, in C, istanziare variabili se non all'inizio di un blocco. Quindi, quando un programmatore ha la necessit? di istanziare variabili di dimensioni che dipendono da condizioni dettate dalla stesso blocco, ? necessario allocare dinamicamente la memoria. Un valido esempio di questo meccanismo ? il tuo stesso programma, Nophiq: posto che si deve istanziare un vettore di lunghezza dipendente da una scelta dell'utente, si possono seguire due strade:
1) il programmatore poco avveduto (cio?, che non ha ancora studiato l'allocazione dinamica ) - o come insegnano a scuola - istanzier? un vettore di lunghezza fissata arbitrariamente:
2) il programmatore che vuole fare le cose per bene... proceder? invece come segue:
Esiste anche un altro utilizzo dell'allocazione dinamica della memoria. Come tutti sappiamo, una funzione pu? ricevere pi? di un parametro, ma pu? restituire un solo valore: ma nel caso vi sia la necessit? di restituire un vettore, come si pu? aggirare questa regola? Con l'allocazione dinamica!
All'interno della funzione viene allocato dinamicamente un vettore (questo meccanismo ? valido ovviamente anche per le stringhe) e viene restituito il puntatore a tale vettore; vediamo un esempio:
Questo utilizzo dell?allocazione dinamica ? possibile in quanto il tempo di vita delle variabili istanziate dinamicamente cessa solo con la chiamata alla funzione free() e la loro visibilit? dura finch? sono puntate .
Un fattore assolutamente importante da tener presente ? il seguente: dopo un?allocazione dinamica, bisogna ricordarsi di verificare che l?allocazione abbia avuto successo, ovvero che sia stata trovata sufficiente memoria nell?heap per eseguire l?operazione di allocazione dinamica:
Spero di aver risolto i tuoi dubbi ( ma se speri di superarmi nelle Olimpiadi di Informatica, ti sbagli... ...scherzo! ).
1) il programmatore poco avveduto (cio?, che non ha ancora studiato l'allocazione dinamica ) - o come insegnano a scuola - istanzier? un vettore di lunghezza fissata arbitrariamente:
main() { float v[100]; }Una cosa del genere ? stata insegnata alla mia classe giusto luned? scorso... ma questo pu? causare uno spreco della memoria eccedente da un lato, e un overflow se, viceversa, si superano il limite della dimensione del vettore (o comunque, la mancanza di spazio per eventuali ulteriori dati da memorizzare);
2) il programmatore che vuole fare le cose per bene... proceder? invece come segue:
main() { int n; float *v; printf("Inserisci il numero di elementi: "); /* o simile */ scanf("%d", &n); v =(float *) calloc(n, sizeof(float)); /* trattandosi di vettori si pu? usare la funzione calloc, molto simile a malloc */ }
Esiste anche un altro utilizzo dell'allocazione dinamica della memoria. Come tutti sappiamo, una funzione pu? ricevere pi? di un parametro, ma pu? restituire un solo valore: ma nel caso vi sia la necessit? di restituire un vettore, come si pu? aggirare questa regola? Con l'allocazione dinamica!
All'interno della funzione viene allocato dinamicamente un vettore (questo meccanismo ? valido ovviamente anche per le stringhe) e viene restituito il puntatore a tale vettore; vediamo un esempio:
#include <stdlib.h> #include <string.h> /* funzione che esegue la copia di una stringa; restituisce un puntatore alla nuova stringa */ char *strdup(const char *s1) { int i=0; char *s2 =(char *) calloc(strlen(s1), sizeof(char)); for (i = 0; i < strlen(s1); i++) s2[i] = s1[i]; s2[i] = 'Esatto: come dice Piero, non ? possibile, in C, istanziare variabili se non all'inizio di un blocco. Quindi, quando un programmatore ha la necessit? di istanziare variabili di dimensioni che dipendono da condizioni dettate dalla stesso blocco, ? necessario allocare dinamicamente la memoria. Un valido esempio di questo meccanismo ? il tuo stesso programma, Nophiq: posto che si deve istanziare un vettore di lunghezza dipendente da una scelta dell'utente, si possono seguire due strade:
1) il programmatore poco avveduto (cio?, che non ha ancora studiato l'allocazione dinamica ) - o come insegnano a scuola - istanzier? un vettore di lunghezza fissata arbitrariamente:main() { float v[100]; }Una cosa del genere ? stata insegnata alla mia classe giusto luned? scorso... ma questo pu? causare uno spreco della memoria eccedente da un lato, e un overflow se, viceversa, si superano il limite della dimensione del vettore (o comunque, la mancanza di spazio per eventuali ulteriori dati da memorizzare);
2) il programmatore che vuole fare le cose per bene... proceder? invece come segue:main() { int n; float *v; printf("Inserisci il numero di elementi: "); /* o simile */ scanf("%d", &n); v =(float *) calloc(n, sizeof(float)); /* trattandosi di vettori si pu? usare la funzione calloc, molto simile a malloc */ }
Esiste anche un altro utilizzo dell'allocazione dinamica della memoria. Come tutti sappiamo, una funzione pu? ricevere pi? di un parametro, ma pu? restituire un solo valore: ma nel caso vi sia la necessit? di restituire un vettore, come si pu? aggirare questa regola? Con l'allocazione dinamica!
All'interno della funzione viene allocato dinamicamente un vettore (questo meccanismo ? valido ovviamente anche per le stringhe) e viene restituito il puntatore a tale vettore; vediamo un esempio:
#include <stdlib.h> #include <string.h> /* funzione che esegue la copia di una stringa; restituisce un puntatore alla nuova stringa */ char *strdup(const char *s1) { int i=0; char *s2 =(char *) calloc(strlen(s1), sizeof(char)); for (i = 0; i < strlen(s1); i++) s2[i] = s1[i]; s2[i] = '{parsed_message}'; return s2; }
Questo utilizzo dell?allocazione dinamica ? possibile in quanto il tempo di vita delle variabili istanziate dinamicamente cessa solo con la chiamata alla funzione free() e la loro visibilit? dura finch? sono puntate .
Un fattore assolutamente importante da tener presente ? il seguente: dopo un?allocazione dinamica, bisogna ricordarsi di verificare che l?allocazione abbia avuto successo, ovvero che sia stata trovata sufficiente memoria nell?heap per eseguire l?operazione di allocazione dinamica:
#include <stdio.h> #include <stdlib.h> /* ... il vettore [i]v[/i] ? stato allocato dinamicamente ... */ if (v == NULL) { printf(?Memoria non disponibile per completare le operazioni.\n?); exit(EXIT_FAILURE); }
Spero di aver risolto i tuoi dubbi ( ma se speri di superarmi nelle Olimpiadi di Informatica, ti sbagli... ...scherzo! ).
'; return s2; }
Questo utilizzo dell?allocazione dinamica ? possibile in quanto il tempo di vita delle variabili istanziate dinamicamente cessa solo con la chiamata alla funzione free() e la loro visibilit? dura finch? sono puntate .
Un fattore assolutamente importante da tener presente ? il seguente: dopo un?allocazione dinamica, bisogna ricordarsi di verificare che l?allocazione abbia avuto successo, ovvero che sia stata trovata sufficiente memoria nell?heap per eseguire l?operazione di allocazione dinamica:
#include <stdio.h> #include <stdlib.h> /* ... il vettore [i]v[/i] ? stato allocato dinamicamente ... */ if (v == NULL) { printf(?Memoria non disponibile per completare le operazioni.\n?); exit(EXIT_FAILURE); }
Spero di aver risolto i tuoi dubbi ( ma se speri di superarmi nelle Olimpiadi di Informatica, ti sbagli... ...scherzo! ).
Ultima modifica effettuata da Zizzius 19/10/05 15:21
aaa
19/10/05 16:08
Rand
Nophiq...
...x lo stesso effetto (ma in c++), puoi usare l'operatore "new"... x allocare dinamicamente la memoria!
Questo programma qua sotto (in c++) equivale a quello che hai fatto tu in c (x l'array di 5 elementi):
...lo so che forse non ti serve sapere il c++ ...ma secondo me ? meglio che se stai imparando il c, lo confronti con la sua versione migliorata... il c++!!
ciaooo
...x lo stesso effetto (ma in c++), puoi usare l'operatore "new"... x allocare dinamicamente la memoria!
Questo programma qua sotto (in c++) equivale a quello che hai fatto tu in c (x l'array di 5 elementi):
#include <iostream> using namespace std; int main() { int dim; //dimensione dell'array int *array; //puntatore int alla prima cella dell'array (che verr? creato in seguito) //chiedo all'utente di che dimensione vuole l'array cout<<"Inserisci la dimensione dell'array: "; cin>>dim; //alloco dinamicamente l'array con l'operatore new array=new int[dim] //da qua in poi... lo puoi usare come se fosse un semplice array[dim] ...esempio... for(int i=0; i<dim; i++) { cout<<"Inserisci l'ele num "<<i+1<<" dell'array: "; cin>>array[i]; } // e poi fai tutto il resto... return 0; }
...lo so che forse non ti serve sapere il c++ ...ma secondo me ? meglio che se stai imparando il c, lo confronti con la sua versione migliorata... il c++!!
ciaooo
aaa
19/10/05 16:20
Rand
Postato originariamente da pierotofy:
Non puoi compilarlo il tuo esempio perch? in C la dichiarazione delle variabili va fatta all'inizio del programma. Non ? come in C++.
Non puoi compilarlo il tuo esempio perch? in C la dichiarazione delle variabili va fatta all'inizio del programma. Non ? come in C++.
...non sono d'accordo con Piero! ...e nemmeno con zizzius!
...io il c lo faccio da una vita... e non mi ha mai dato problemi sul fatto di aver dichiarato variabili anche in mezzo a un blocco di istruzioni! ...non condivido quello che avete detto...
...questo programma lo dimostra (compilato con successo su dev-c++ 4.9.9.0 x win32 con gcc 3.44)...
#include <stdio.h> int main() { int i=2; printf("I vale: %d\n", i); int k=3; printf("K vale: %d\n", k); char c='f'; printf("C vale: %c\n", c); return 0; }
...forse il problema sta che ora i compilatori di c... accettano anche istruzioni proprie del c++
Ultima modifica effettuata da Rand 19/10/05 16:22
aaa
19/10/05 20:49
pierotofy
Infatti
Se i compilatori fanno i comodi loro senza rispettare lo standard ANSI e lasciano la possibilit? di dichiarare le variabili anche dopo un blocco di istruzioni non ? colpa di nessuno
Se i compilatori fanno i comodi loro senza rispettare lo standard ANSI e lasciano la possibilit? di dichiarare le variabili anche dopo un blocco di istruzioni non ? colpa di nessuno
Ultima modifica effettuata da pierotofy 19/10/05 20:50
Il mio blog: piero.dev
19/10/05 20:59
Nophiq
Postato originariamente da Zizzius:
non ? possibile, in C, istanziare variabili se non all'inizio di un blocco.
non ? possibile, in C, istanziare variabili se non all'inizio di un blocco.
Era quello che stavo cercando, il mio parere riguardo all'inizializzazione del vettore non all'inizio proviene dal Java...
Grazie
aaa