[C] Alternativa all'utilizzo di variabili globali?

Messaggioda bad.alex » 05/08/2017, 16:36

Ciao a tutti.
Ho bisogno di un consiglio: ho un programma in cui sono presenti almeno una cinquantina di variabili globali. Il mio professore, a suo tempo, ricordo che sconsigliò due cose: di riempire il main con qualsiasi cosa che non fosse una funzione; di utilizzare in maniera spropositata le variabili globali.
Premetto che non sono un amante dei puntatori, in quanto non riesco ad utilizzarli ( e a capire come funzionino). C'è qualche altra alternativa per poter ridurre il numero di variabili utilizzate nel programma? Premetto che tutte sono utilizzate da più funzioni all'interno del programma e che penso, dunque, che non possano essere modificate come locali...
Spero possiate aiutarmi.
Vi ringrazio
bad.alex
Senior Member
Senior Member
 
Messaggio: 1076 di 1283
Iscritto il: 10/01/2007, 19:01

Re: [C] Alternativa all'utilizzo di variabili globali?

Messaggioda Summerwind78 » 07/08/2017, 07:00

Ciao

diciamo che in C (non orientato ad oggetti quindi), è un po' più difficile non utilizzare variabili globali dato che non puoi costruirti classi o oggetti simili

Inoltre, secondo me, diventa un po' complicato darti qualche suggerimento senza sapere per quale scopo tu abbia creato quelle variabili e come le usi.

Diciamo che per prima cosa potresti inserire queste variabili in un file .c che includi nelle varie parti del programma in modo tale da non averle tutte nel main.

Una possibilità potrebbe essere quella di avere le tue variabili inglobate all'interno di una struttura ed utilizzare quella come elemento condiviso tra le varie funzioni.

Spero di esserti stato utile in qualche modo.

Se hai domande non farti problemi a chiedere

Saluti
Summerwind78
Advanced Member
Advanced Member
 
Messaggio: 1394 di 2976
Iscritto il: 29/01/2011, 14:06
Località: Italia

Re: [C] Alternativa all'utilizzo di variabili globali?

Messaggioda insideworld » 07/08/2017, 11:30

Soprattutto se devi dare un esame tipo algoritmi e programmazione, allora DEVI imparare ad usare i puntatori, non credo ci sia altro modo.
Comunque imparare ad usarli bene è molto semplice:
Ti devi solo mettere 3-4 giorni col pensiero di risolverti tutti i dubbi su passaggio di parametri.
Ora non mi ricordo esattamente come funzionano perchè li ho fatti più di 2 anni fa, quindi prefrisco dirti il metodo che ho usato
-Raccogli tutti gli appunti che hai sui puntatori
-prepara carta e penna
-(al pc, su code blocks o quello che usi tu) inizi con una variabile semplice(tipo int) allocata dinamicamente, inizi a vedere come passarla da una variabile all'altra facendo alcuni programmi e facendoli girare.
Provi a copiare l'indirizzo in una nuova variabile e a copiare solo il valore.
-Una volta che ti sei chiarito tutti i dubbi, devi scriverti perchè quel codice è giusto, tutti i ragionamenti e gli schemi, come se lo dovessi spiegare ad una persona che non sa niente di puntatori.(fidati, se per caso ti capita di non utilizzarli per un pò ti dimenticherai tutto...specie se non li usi per qualche settimana, in cui magari studi per altre materie)
-A questo punto prova a passarlo per parametro ad una funzione, ricordati che alla funzione stai passando una variabile che viene copiata SEMPRE "By Value", quindi, per ottenere un passaggio "By Reference" tu devi passare un indirizzo di memoria.
se hai una variabile classica (esempio int a;)
allora si passa con
Codice:
funz(&a)

mentre (se non ricordo male)nel caso di un int* b, in b c'è l'indirizzo della cella in cui è contenuto il valore.
quindi scrivendo
Codice:
funz(b)
stai facendo un passaggio "by reference", ovvero stai facendo la stessa cosa che hai fatto in a mettendo la
Codice:
&
, ovvero stai passando l'indirizzo in memoria.
Poi quando hai finito con questi, provi con i vettori e le matrici, sia dinamiche sia statiche, e infine con le struct e con liste- alberi.(ti ho scritto queste cose perchè da me erano tutte incluse nello stesso esame, non so come sia da te.)
Con le struct e gli alberi è un pò più difficile perchè hai anche l'operatore -> , ma ragionando passo a passo, in un paio d'ore ti risolvi tutti questi dubbi e non avrai più dubbi (salvo il fatto di non usarli per un pò prima di averli ben memorizzati, per quello ti consiglio di scriverti tutti i ragionamenti e gli schemini)
Avatar utente
insideworld
Junior Member
Junior Member
 
Messaggio: 140 di 306
Iscritto il: 13/01/2017, 15:24

Re: [C] Alternativa all'utilizzo di variabili globali?

Messaggioda vict85 » 08/08/2017, 07:42

Summerwind78 ha scritto:Ciao

diciamo che in C (non orientato ad oggetti quindi), è un po' più difficile non utilizzare variabili globali dato che non puoi costruirti classi o oggetti simili

Inoltre, secondo me, diventa un po' complicato darti qualche suggerimento senza sapere per quale scopo tu abbia creato quelle variabili e come le usi.

Diciamo che per prima cosa potresti inserire queste variabili in un file .c che includi nelle varie parti del programma in modo tale da non averle tutte nel main.

Una possibilità potrebbe essere quella di avere le tue variabili inglobate all'interno di una struttura ed utilizzare quella come elemento condiviso tra le varie funzioni.

Spero di esserti stato utile in qualche modo.

Se hai domande non farti problemi a chiedere

Saluti


Non c'è alcun legame tra programmazione ad oggetti e campo di applicazione della variabile se non che la creazione di oggetti globali può aggiungere problemi. Nota che ogni programma in C++ è sostanzialmente tradotto in C durante la compilazione.

Detto questo è difficile fare un refactoring di un programma con molte variabili globali. Fai prima a riscrivere completamente il programma. Le costanti le potresti anche lasciare globali, a menbmo che tu non voglia rendere il programma più semplice da estendere generalizzare. Comunque aggiungere una variabile globale non è mai una soluzione alla tua ignoranza sul saper usare i puntatori.
vict85
Moderatore
Moderatore
 
Messaggio: 9103 di 19253
Iscritto il: 16/01/2008, 00:13
Località: Berlin

Re: [C] Alternativa all'utilizzo di variabili globali?

Messaggioda bad.alex » 08/08/2017, 15:54

Grazie a tutti. Terrò a mente tutti i vostri consigli. Si, hai ragione Summerworld. Il fatto che non ci siano classi d oggetti rende il tutto più difficile da semplificare. Al momento sto seguendo il tuo, insideworld, perché è bene saper utilizzare i puntatori, lo riconosco. Entro in confusione quando si tratta di richiamare il valore di una variabile tramite puntatore. Ma sto creando dei programmi abbastanza semplici così da vedere un po' come farli funzionare. Stesso discorso per le strutture dati. Sono gli argomenti a me più ostici. Mai quanto l'allocazione dinamica, però ;)
Grazie a tutti.

"Comunque aggiungere una variabile globale non è mai una soluzione alla tua ignoranza sul saper usare i puntatori"

Lo so, vic85. Ad ogni modo sono un tipo abbastanza volenteroso e testardo e, per questo motivo, mi sto mettendo d'impegno per imparare ad utilizzare correttamente i puntatori :) Grazie per la dritta.

Alex
bad.alex
Senior Member
Senior Member
 
Messaggio: 1077 di 1283
Iscritto il: 10/01/2007, 19:01

Re: [C] Alternativa all'utilizzo di variabili globali?

Messaggioda bad.alex » 09/08/2017, 01:18

Sto provando ad allocare dinamicamente la memoria per un array bidimensionale. Tuttavia ricevo un messaggio di errore non appena inizializzo gli elementi della matrice a 0. Sapreste dirmi in cosa sto sbagliando? (questa parte di codice è all'interno di una funzione che viene richiamata nel main() ). L'errore che mi compare è il seguente: "Thread 1: EXC_BAD_ACCESS[code=1, address=0x0".


Codice:
 
    int ** matrix, *vicino, i, j;
       
    matrix=malloc(15 * 15 * sizeof(int));
    vicino=(int *)malloc(15 * sizeof(int));
   
    printf("\n");
    printf("Matrix\n");
   
    for ( i = 0; i < 15; i ++ ){
        for ( j = 0; j < 15; j ++ ){
            matrix[i][j] = 0; // In questo punto viene segnalato l'errore
            matrix[j][i] = 0;
        }
    }


Vi ringrazio
bad.alex
Senior Member
Senior Member
 
Messaggio: 1078 di 1283
Iscritto il: 10/01/2007, 19:01

Re: [C] Alternativa all'utilizzo di variabili globali?

Messaggioda insideworld » 09/08/2017, 09:13

guarda, il primo link che ho trovato http://www.dis.uniroma1.it/~terpa/MatDid/RMIngClinFondInf/023250.pdf
a pagina 4, matrix, ovvero il vettore di int** deve essere inizializzato così;
Codice:
matrix=malloc(15 * sizeof(int*));

ovvero come vettore di puntatori ad int.
ad ogni elemento di questo vettore(che scandirai con un for da 0 a 15, con 15 escluso) devi fare una malloc di vettori, che saranno memorizzate nelle celle di Matrix(quindi devi fare la malloc di matrix più le 15 malloc delle righe)
prova a guardare il disegno nel pdf che ti ho linkato.
Il vettore matrix nel pdf si chiama "a" ed è giallo, e punta alle varie righe della matrice che sono i vettori gialli.
Non ti serve il vettore di appoggio "vicino".

L'errore è dato dal tentato accesso a memoria protetta (puntatore a NULL o zero(0x0), perchè non hai inizializzato tutte le celle di matrix, hai allocato solo una riga invece di 15, tra l'altro sono 15 x 15 = 225 righe... ti stai confondendo con la matrice implementata come vettore unico, e non con doppio puntatore, sono due cose diverse)

il codice dovrebbe essere:
Codice:
matrix=malloc(15 * sizeof(int*));
for(i=0;i<15;i++){
     matrix[i]=malloc(15*sizeof(int));
}

a questo punto puoi accedere a tutti gli elementi della matrice usando la classica sintassi: matrix[i][j];

ricordati che quando devi fare la free (se la vuoi fare) devi fare prima la free con il ciclo for per eliminare le righe, e poi fai la free di matrix.
:smt023
Avatar utente
insideworld
Junior Member
Junior Member
 
Messaggio: 141 di 306
Iscritto il: 13/01/2017, 15:24


Torna a Informatica

Chi c’è in linea

Visitano il forum: Nessuno e 1 ospite