Nophiq (Founder Member)
Expert
Messaggi: 537
Iscritto: 15/11/2004
|
Volevo chiedere alcune cose sulla funzione malloc:
da quello che ho capito scrivendo:
- int *p;
- p = (int*) malloc (5*sizeof(int));
faccio in modo di occupare della memoria; ma non equivale ad inizializzare un array di int di 5 valori? ovvero queste due righe di codice non si possono riassumere in:
- int array[5];
|
|
Nophiq (Founder Member)
Expert
Messaggi: 537
Iscritto: 15/11/2004
|
Vorrei commentare un programma a proposito:
Codice sorgente - presumibilmente C++ |
#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
Codice sorgente - presumibilmente C/C++ |
#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 il 18/10/2005 alle 19:46 |
|
pierotofy (Admin)
Guru^2
Messaggi: 6230
Iscritto: 04/12/2003
|
Non puoi compilarlo il tuo esempio perch? in C la dichiarazione delle variabili va fatta all'inizio del programma. Non ? come in C++.
|
|
Zizzius (Honoris User)
Guru
Messaggi: 675
Iscritto: 28/02/2005
|
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:
Codice sorgente - presumibilmente C/C++ |
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:
Codice sorgente - presumibilmente C/C++ |
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:
Codice sorgente - presumibilmente C++ |
#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] = '\0'; 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:
Codice sorgente - presumibilmente C/C++ |
#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 il 19/10/2005 alle 17:21 |
|
Rand (Ex-Member)
Pro
Messaggi: 163
Iscritto: 17/05/2005
|
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):
Codice sorgente - presumibilmente C# |
#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 //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
|
|
Rand (Ex-Member)
Pro
Messaggi: 163
Iscritto: 17/05/2005
|
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 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)...
Codice sorgente - presumibilmente C++ |
#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 il 19/10/2005 alle 18:22 |
|
pierotofy (Admin)
Guru^2
Messaggi: 6230
Iscritto: 04/12/2003
|
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
Ultima modifica effettuata da pierotofy il 19/10/2005 alle 22:50
|
|
Nophiq (Founder Member)
Expert
Messaggi: 537
Iscritto: 15/11/2004
|
Postato originariamente da Zizzius:
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 |
|
Rand (Ex-Member)
Pro
Messaggi: 163
Iscritto: 17/05/2005
|
|
|