[C] Dichiarare un array globale con dimensione da definire
Salve, sono alle prese con un programmino in C nel quale ho bisogno di dichiarare un array globale la cui dimensione la chiedo tramite scanf in un'altra funzione.
Come si fa?
Se faccio ad esempio:
Mi esce questo errore: variable-size type declared outside of any function
Come si fa?
Se faccio ad esempio:
int dim = 0;
int array[dim];
int main () {
funzione1();
...
}
void funzione1(void) {
printf("quanti elementi ha l'array?\n");
scanf("%d", &dim);
...
}
Mi esce questo errore: variable-size type declared outside of any function
Risposte
Forse ti conviene utilizzare i puntatori
int dim = 0;
int *array;
int main () {
funzione1();
...
}
void funzione1(void) {
printf("quanti elementi ha l'array?\n");
scanf("%d", &dim);
array = (int *)malloc(dim * sizeof(int));
}
e poi utilizzi l'array normalmente.
Una volta utilizzato l'array, devi rilasciare la memoria allocata con la funzione free:
free(array);
Ciao
int dim = 0;
int *array;
int main () {
funzione1();
...
}
void funzione1(void) {
printf("quanti elementi ha l'array?\n");
scanf("%d", &dim);
array = (int *)malloc(dim * sizeof(int));
}
e poi utilizzi l'array normalmente.
Una volta utilizzato l'array, devi rilasciare la memoria allocata con la funzione free:
free(array);
Ciao
In C (prima dello standard del 99 ignorato da tutti) la dimensione deve essere una espressione costante a tempo di compilazione. Anche le variabili costanti non sono permesse. Nell'ultimo standard è stata permessa la definizione di array con una dimensione data da una variabili in circostanze particolari (solo array locali). L'unica soluzione al tuo problema è quello già consigliato da frodo4. Ma l'uso di variabili globali è comunque sconsigliato in qualsiasi guida di stile.
Effettivamente ha funzionato. Ma la funzione free la uso al termine della funzione o alla fine del main?
Lo chiedo anche perchè lo stesso aray lo uso in altre funzioni dello stesso programma (ecco perchè l'avevo chiamata funzione1).
Cmq ho un nuovo problema. Come stampo a video il contenuto dell'array creato con malloc?
Lo chiedo anche perchè lo stesso aray lo uso in altre funzioni dello stesso programma (ecco perchè l'avevo chiamata funzione1).
Cmq ho un nuovo problema. Come stampo a video il contenuto dell'array creato con malloc?
Lo stampi esattamente come qualsiasi altro array. Puntatori e array sono in effetti spesso intercambiabili.
Rinnovo comunque l'invito a ripensare alla struttura della tua applicazione. Un array globale, soprattutto quando questo viene allocato dinamicamente è una pessima idea. È normalmente meglio passare l'array come parametro alla funzione.
La funzione free deve essere chiamata quando l'array non è più utile, quindi è meglio chiamarla alla fine del main se hai dei dubbi.
Rinnovo comunque l'invito a ripensare alla struttura della tua applicazione. Un array globale, soprattutto quando questo viene allocato dinamicamente è una pessima idea. È normalmente meglio passare l'array come parametro alla funzione.
La funzione free deve essere chiamata quando l'array non è più utile, quindi è meglio chiamarla alla fine del main se hai dei dubbi.
"apatriarca":
Lo stampi esattamente come qualsiasi altro array. Puntatori e array sono in effetti spesso intercambiabili.
Ho capito perchè non lo stampa!
In pratica nella funzione1 (per popolare l'elenco di persone) chiedo tramite dim quante persone inserire. Poi nella funzione2 (per stampare a video l'elenco) dim non ha più il valore chiesto all'utente con la funzione1 e dunque il ciclo for utilizzato per la stampa (i
Rinnovo comunque l'invito a ripensare alla struttura della tua applicazione. Un array globale, soprattutto quando questo viene allocato dinamicamente è una pessima idea. È normalmente meglio passare l'array come parametro alla funzione.
La funzione free deve essere chiamata quando l'array non è più utile, quindi è meglio chiamarla alla fine del main se hai dei dubbi.
Per adesso proseguo su questa strada per scopi puramente didattici, poi farò una nuova versione del programmino passando l'array alle funzioni. A tale scopo, dovrei passare anche la dimensione dell'array stesso, giusto? Se si, come faccio a passarlo se la dimensione è definita dall'utente?
Per adesso proseguo su questa strada per scopi puramente didattici, poi farò una nuova versione del programmino passando l'array alle funzioni. A tale scopo, dovrei passare anche la dimensione dell'array stesso, giusto? Se si, come faccio a passarlo se la dimensione è definita dall'utente?
È abbastanza evidente che non hai alcuna esperienza con l'allocazione dinamica della memoria e fare tutto questo con una variabile globale complica solo le cose. Quando un array viene passato come argomento ad una funzione si passa sempre anche la sua dimensione sia quando è stato allocato dinamicamente, sia quando staticamente. Se invece vuoi fare tutto con variabili globali allora anche la dimensione lo deve essere.
Se posto il programmino a cui sto lavorando per esercitarmi nello studio, ci date un'occhiata?
Se non è troppo lungo, posta pure il tuo codice.
"apatriarca":
Se non è troppo lungo, posta pure il tuo codice.
http://pastebin.com/m5b706aec
Se è lungo, ignoralo pure. Vorrei solo capire come fare per far funzionare tutto a dovere...
C'e' un pezzo del codice che a me non piace molto.
Si tratta della sezione "inserisci".
In questa sezione chiedi quanti esami vuoi inserire, per poi loopizzare fino alla fine.
Se ad esempio devi inserire 40 esami, ed al 30 devi andare via perchè inizia la partita, sei costretto obbligatoriamente a caricare tutti gli altri.
IMHO: a me piace di piu inserire un record alla volta, ed eventualmente ritornare sul menu principale delle scelte
Si tratta della sezione "inserisci".
In questa sezione chiedi quanti esami vuoi inserire, per poi loopizzare fino alla fine.
Se ad esempio devi inserire 40 esami, ed al 30 devi andare via perchè inizia la partita, sei costretto obbligatoriamente a caricare tutti gli altri.
IMHO: a me piace di piu inserire un record alla volta, ed eventualmente ritornare sul menu principale delle scelte
"Umby":
C'e' un pezzo del codice che a me non piace molto.
Si tratta della sezione "inserisci".
In questa sezione chiedi quanti esami vuoi inserire, per poi loopizzare fino alla fine.
Se ad esempio devi inserire 40 esami, ed al 30 devi andare via perchè inizia la partita, sei costretto obbligatoriamente a caricare tutti gli altri.
IMHO: a me piace di piu inserire un record alla volta, ed eventualmente ritornare sul menu principale delle scelte
Ti ringrazio per il consiglio, ma il problema è un altro!
Prova a caricare gli esami da file e poi a stamparli a video...
"Umby":
C'e' un pezzo del codice che a me non piace molto.
Si tratta della sezione "inserisci".
In questa sezione chiedi quanti esami vuoi inserire, per poi loopizzare fino alla fine.
Se ad esempio devi inserire 40 esami, ed al 30 devi andare via perchè inizia la partita, sei costretto obbligatoriamente a caricare tutti gli altri.
IMHO: a me piace di piu inserire un record alla volta, ed eventualmente ritornare sul menu principale delle scelte
Ti ringrazio per il consiglio, ma il problema è un altro!
Prova a caricare gli esami da file e poi a stamparli a video...
"smartmouse":
Ti ringrazio per il consiglio, ma il problema è un altro!
Prova a caricare gli esami da file e poi a stamparli a video...
Lo so che stavi ceracndo di risolvere un altro problema, un problema legato a come usare le variabili in C.
Il mio commento era molto piu generico...
Il codice non è scritto male, ma ci sono alcune cose che cambierei:
1. Chiamerei la struttura struct esame semplicemente esame e non libretto. Credo che usare due nomi crei solo confusione e un libretto non è un esame.
2. Scriverei le funzioni in modo da ricevere o restituire l'array di esami. Potresti anche unire la dimensione e l'array in un'unica struttura che puoi chiamare libretto. Le funzioni inserisci e carica restituirebbero quindi un nuovo libretto, la funzione menu ne modificherebbe uno e le funzioni salva, stampa e calcola elaborerebbero un libretto passato per parametro.
3. Aggiungerei delle funzioni per semplificare la gestione del libretto.
4. Per verificare se il libretto è vuoto utilizzerei dim, oppure confronterei il puntatore del libretto con NULL.
1. Chiamerei la struttura struct esame semplicemente esame e non libretto. Credo che usare due nomi crei solo confusione e un libretto non è un esame.
2. Scriverei le funzioni in modo da ricevere o restituire l'array di esami. Potresti anche unire la dimensione e l'array in un'unica struttura che puoi chiamare libretto. Le funzioni inserisci e carica restituirebbero quindi un nuovo libretto, la funzione menu ne modificherebbe uno e le funzioni salva, stampa e calcola elaborerebbero un libretto passato per parametro.
3. Aggiungerei delle funzioni per semplificare la gestione del libretto.
4. Per verificare se il libretto è vuoto utilizzerei dim, oppure confronterei il puntatore del libretto con NULL.
"apatriarca":
1. Chiamerei la struttura struct esame semplicemente esame e non libretto. Credo che usare due nomi crei solo confusione e un libretto non è un esame.
Fatto!
2. Scriverei le funzioni in modo da ricevere o restituire l'array di esami. Potresti anche unire la dimensione e l'array in un'unica struttura che puoi chiamare libretto. Le funzioni inserisci e carica restituirebbero quindi un nuovo libretto, la funzione menu ne modificherebbe uno e le funzioni salva, stampa e calcola elaborerebbero un libretto passato per parametro.
C'ho provato a farlo qualche giorno fa, ma non sono riuscito a far restituire l'array di esami! Il compilatore mi dava degli errori e ci avevo rinunciato. Precisamente... come si fa per far restituire l'array?
3. Aggiungerei delle funzioni per semplificare la gestione del libretto.
Tipo?
4. Per verificare se il libretto è vuoto utilizzerei dim, oppure confronterei il puntatore del libretto con NULL.
Purtroppo non sono ancora ferrato in fatto di puntatori (e liste).