[Risolto] [C] Variabili globali gestite da più file

Linguaggi di programmazione: php, perl, python, C, bash e tutti gli altri.
Scrivi risposta
Carlit0sway+
Prode Principiante
Messaggi: 92
Iscrizione: martedì 16 dicembre 2008, 17:26

[Risolto] [C] Variabili globali gestite da più file

Messaggio da Carlit0sway+ »

Salve a tutti.
Come da oggetto, vi chiedo un aiuto sulla dichiarazione/definizione di variabili globali in C, che devono essere viste e /o modificate da più files.

Ho creato un albero binario di ricerca in un file BistTree.c (con il relativo header con i prototipi in un file BistTree.h)
I nodi dell'albero hanno come campi un array, e una variabile int, che chiamo id.

io ho bisogno di una variabile int globale, che chiamo ID, che all'inizio voglio sia 0. Ed ogni volta che inserisco un nodo in un albero, assegno ID a id, poi incremento ID. Cosicchè la variabile globale sia sempre aggiornata all'inserimento di ogni nodo.
solo che non so come si gestiscono le variabili globali esterne. Ho leggiucchiato su internet ma sto divagando e più perdendo tempo che altro.



In  Bist_Tree.h ho questa situazione:

Codice: Seleziona tutto

#ifndef BIST_ITEM_H
#define BIST_ITEM_H

typedef int *Bist_Key;		/* La chiave negli alberi è una configurazione assumibile dai contenitori */
struct configurazione{		/* Una struct configurazione è un tipo che definisce una configurazione dei contenitori, e il suo id associato */
	Bist_Key livello;
	int id;
};
typedef struct configurazione *Bist_Item; /* Gli Item nell'albero sono puntatori a configurazioni */
Mentre in Bist_Tree.c, oltre  le varie implementazioni delle funzioni dichiarate nell'header, c'è:

Codice: Seleziona tutto

extern int ID;

Bist_Item newBist_Item( Bist_Key k ){
	Bist_Item it = my_malloc( sizeof(struct configurazione) );
	it->livello = k;
	it->id = ID;
        ID++;
	return it;
}
Ho dichiarato nel main la variabile globale

Codice: Seleziona tutto

int ID = 0;
int main(void){...}
Io poi vorrei usare ID anche in altri 2 file .c (il main appunto e un'altra struttura, che banalmente è un'array, dove ID mi serve ad accedere ai vari elementi. es.: Tabella[ID] ... )

E' corretta questa procedura? grazie in anticipo.
Ultima modifica di Carlit0sway+ il mercoledì 30 dicembre 2009, 1:57, modificato 1 volta in totale.
Avatar utente
crisixk
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1402
Iscrizione: domenica 17 maggio 2009, 1:15
Località: Pontedera - Pisa
Contatti:

Re: [C] Variabili globali gestite da più file

Messaggio da crisixk »

Esempio di utilizzo di una variabile globale utilizzabile da piu' file sorgente:

main.c

Codice: Seleziona tutto

#include <stdio.h>
#include "h1.h"
#include "h2.h"

int main(int argc, char *argv[])
{

    inizialize_id();

  f1();
  f2();
  id ++;
  printf("\n main id :%u \n",id);

  return 0;
}
h1.h

Codice: Seleziona tutto

#ifndef H1_H
#define H1_H

int id;

void inizialize_id();

void
f1 (void);

#endif /* H1_H */
h2.h

Codice: Seleziona tutto

#ifndef H2_H
#define H2_H

void
f2 (void);


#endif /* H2_H */
code.c

Codice: Seleziona tutto

#include <stdio.h>
#include "h1.h"
#include "h2.h"

void inizialize_id() { id = 0; }

void
f1 (void)
{
    id ++;
    printf("\n f1 id :%u \n",id);

}

void
f2 (void)
{
    id ++;
    printf("\n f2 id :%u \n",id);

}

Nota:
se nell'header h1.h provi ad inizializzare la variabile id:

Codice: Seleziona tutto

int id = 0;
ottieni errore ^^

la dichiarazione di variabili globali in un header apposito mi sembra la soluzione piu' semplice ^^
Avvolte cio' che si crea per facilitarci la vita, ci libera dal ragionare ed insieme ci imprigiona in una sorta di limbo nel quale la coscienza è solo un limite, uno spreco di risorse e tempo. Cosa fa' la mia mano ?
... s'impara un passo alla volta ...
Carlit0sway+
Prode Principiante
Messaggi: 92
Iscrizione: martedì 16 dicembre 2008, 17:26

Re: [C] Variabili globali gestite da più file

Messaggio da Carlit0sway+ »

Ti ringrazio crisixk! Sempre disponibile  :) !!!

Dunque mi stai suggerendo di dichiarare la variabile globale nell'header BistTree.h, e di fare una funzione che la inizializza a 0 nel BisTree.c, e che la incrementi? Perchè io ho bisogno di non incrementarla nel main.

Oppure dichiararla nel main?
Avatar utente
crisixk
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1402
Iscrizione: domenica 17 maggio 2009, 1:15
Località: Pontedera - Pisa
Contatti:

Re: [C] Variabili globali gestite da più file

Messaggio da crisixk »

esempio (bruttoooo) con 'extern'

main.c

Codice: Seleziona tutto

#include <stdio.h>
#include "h1.h"
#include "h2.h"

int main(int argc, char *argv[])
{

    extern int id;
    inizialize_id();

  f1();
  f2();
  id ++;
  printf("\n main id :%u \n",id);

  return 0;
}
h1.h

Codice: Seleziona tutto

#ifndef H1_H
#define H1_H

void inizialize_id();

void
f1 (void);

#endif /* H1_H */
h2.h

Codice: Seleziona tutto

#ifndef H2_H
#define H2_H

void
f2 (void);


#endif /* H2_H */
code.c

Codice: Seleziona tutto

#include <stdio.h>
#include "h1.h"
#include "h2.h"

int id;

void inizialize_id() { id = 0; }

void
f1 (void)
{
    id ++;
    printf("\n f1 id :%u \n",id);

}

void
f2 (void)
{
    id ++;
    printf("\n f2 id :%u \n",id);

}
in ogni file in cui vuoi utilizzare id devi dichiararla in questo modo

Codice: Seleziona tutto

extern int id;
altrimenti il linker non capisce di cosa si sta' parlando ^^

Nota:
in quest'esempio puoi nel file code.c dichiarare ed inizializzare contemporaneamente la variabile id

Codice: Seleziona tutto

int id = 0;
ma l'utilizzo di extern in progetti con molti file è abbastanza noioso nell'aggiornamento del codice ^^
Avvolte cio' che si crea per facilitarci la vita, ci libera dal ragionare ed insieme ci imprigiona in una sorta di limbo nel quale la coscienza è solo un limite, uno spreco di risorse e tempo. Cosa fa' la mia mano ?
... s'impara un passo alla volta ...
Avatar utente
crisixk
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1402
Iscrizione: domenica 17 maggio 2009, 1:15
Località: Pontedera - Pisa
Contatti:

Re: [C] Variabili globali gestite da più file

Messaggio da crisixk »

Corry2 ha scritto: Ti ringrazio crisixk! Sempre disponibile  :) !!!

Dunque mi stai suggerendo di dichiarare la variabile globale nell'header BistTree.h, e di fare una funzione che la inizializza a 0 nel BisTree.c, e che la incrementi? Perchè io ho bisogno di non incrementarla nel main.

Oppure dichiararla nel main?
nel primo esempio id viene incrementata nelle funzioni dichiarate e definite fuori dalla main come nella stessa main ..

una volta dichiarata la variabile id in un header, devi semplicemente includere l'header nel file dove vuoi utilizzare la variabile id

Codice: Seleziona tutto

#include "header_id.h"
utilizzando gli header per la dichiarazione di variabili globali, MACRO, funzioni, tipi strutture, ecc. rendi il codice del progetto piu' fluido e meno contorto ..

leggi qui(se non l'hai fatto  :D )
http://a2.pluto.it/a2717.htm
581.3    Semplificazione dovuta all'uso comune dei file di intestazione

Nella tradizione del linguaggio C si fa uso di file di intestazione, ovvero porzioni di codice, in cui, tra le altre cose, si vanno a mettere i prototipi delle funzioni e le dichiarazioni delle variabili globali, a cui tutto il programma deve poter accedere.
Avvolte cio' che si crea per facilitarci la vita, ci libera dal ragionare ed insieme ci imprigiona in una sorta di limbo nel quale la coscienza è solo un limite, uno spreco di risorse e tempo. Cosa fa' la mia mano ?
... s'impara un passo alla volta ...
Carlit0sway+
Prode Principiante
Messaggi: 92
Iscrizione: martedì 16 dicembre 2008, 17:26

Re: [C] Variabili globali gestite da più file

Messaggio da Carlit0sway+ »

Bleah...mi sa che ho fatto confusione!
Ora avevo modificato la mia configurazione, similmente al primo esempio che mi hai postato.

Allora quando serve dichiarare extern? E quando posso evitare?

BistItem* sono i due file(interfaccia e implementazione) dove definisco i tipi di cui sono composti gli oggetti dei nodi dell'albero

Ora In BistItem.h ho :

Codice: Seleziona tutto

int ID;
void inizialize_ID();
Bist_Item newBist_Item( Bist_Key k ); 	
In BistItem.c ora ho:

Codice: Seleziona tutto

#include "bist_itemkey.h"  /* Se io includo BistTree.h, la variabile globale ID viene vista dal compilatore qui?
// extern int ID;                              // O serve questa riga di codice? la devo dichiarare esterna?

void inizialize_ID(){ ID = 0; }

Bist_Item newBist_Item( Bist_Key k ){
	Bist_Item it = my_malloc( sizeof(struct configurazione) );
	it->livello = k;
	it->id = ID;  // Posso farlo?
	ID++;  // Posso farlo?
	return it;
}
Infine, se includo BistItem.h in altri files .c (il main e un'altra struttura), posso usare ID a mio piacimento?
O la devo prima dichiarar SEMPRE con extern int ID; ?

Grazie
Ultima modifica di Carlit0sway+ il martedì 29 dicembre 2009, 18:34, modificato 1 volta in totale.
Carlit0sway+
Prode Principiante
Messaggi: 92
Iscrizione: martedì 16 dicembre 2008, 17:26

Re: [C] Variabili globali gestite da più file

Messaggio da Carlit0sway+ »

Ahhh ok perfetto!

Il problema era solo che io ti ho risposto, mentre tu stavi ancora rispondendo con il secondo caso XD

Quindi ho fatto bene a seguire il tuo primo esempio?
Butto via gli extern, dichiaro la variabile globale nell'header, e utilizzo funzioni apposite per inizializzare e incrementare la variabile globale, che implemento nel .c

(yes)?? Spero di aver capito

(b2b)
Ultima modifica di Carlit0sway+ il martedì 29 dicembre 2009, 18:28, modificato 1 volta in totale.
Avatar utente
crisixk
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1402
Iscrizione: domenica 17 maggio 2009, 1:15
Località: Pontedera - Pisa
Contatti:

Re: [C] Variabili globali gestite da più file

Messaggio da crisixk »

#include cosa fa?
semplicemente inserisce nel file dove viene utilizzato tutto quello che c'è nel file linkato
ora se tu utilizzi #include"header_id.h" nel file dove vuoi utilizzare la variabile id, ti ritrovi in quel file tutto il codice che sta nel file header_id.h, quindi anche la dichiarazione di id ... a quel punto non puoi dopo scrivere extern perche avresti una doppia dichiarazione della stessa variabile:

header_id.h:

Codice: Seleziona tutto

int id;
file_sorgente.c dopo la fase di preprocessore:

Codice: Seleziona tutto

int id; // riga aggiunta dal preprocessore quando risolve il comando #include
extern int id; // NO, id e' stata gia' dichiarata
o utilizzi #include "header_id.h" o dichiari esterna la variabile id nei file nei quali appunto non è stata dichiarata per la prima volta.

è chiara la cosa, altrimenti ti faccio un esempio in codice  :-\
Avvolte cio' che si crea per facilitarci la vita, ci libera dal ragionare ed insieme ci imprigiona in una sorta di limbo nel quale la coscienza è solo un limite, uno spreco di risorse e tempo. Cosa fa' la mia mano ?
... s'impara un passo alla volta ...
Carlit0sway+
Prode Principiante
Messaggi: 92
Iscrizione: martedì 16 dicembre 2008, 17:26

Re: [C] Variabili globali gestite da più file

Messaggio da Carlit0sway+ »

Nono è chiarissima. non so come ringraziarti...me l'hai spiegata a dovere, meglio di tutorials che ho trovato in giro!
Grazie mille  (good)
Avatar utente
crisixk
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1402
Iscrizione: domenica 17 maggio 2009, 1:15
Località: Pontedera - Pisa
Contatti:

Re: [C] Variabili globali gestite da più file

Messaggio da crisixk »

bene allora  :)

la parte che riguarda il campo d'azione delle variabili è un po' intricata ..

se accetti un consiglio, quando ti trovi alle prese con nuovi argomenti un po' contorti, metti da parte i codici su cui lavori e scrivi 10 righe 10 con l'essenziale per cercare di vedere come funziona cosa .. gli esempi che ti ho fatto sono apparentemente banali, eppure spiegano bene il meccanismo ... quando si ha troppo codice per le mani non si distingue piu' l'essenziale  ::)

ciao, buon anno  ;)
Avvolte cio' che si crea per facilitarci la vita, ci libera dal ragionare ed insieme ci imprigiona in una sorta di limbo nel quale la coscienza è solo un limite, uno spreco di risorse e tempo. Cosa fa' la mia mano ?
... s'impara un passo alla volta ...
tomallevi
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1746
Iscrizione: venerdì 24 ottobre 2008, 22:41

Re: [C] Variabili globali gestite da più file

Messaggio da tomallevi »

se posso consigliare, le variabili locali sono da evitare. un metodo alternativo al bruttissimo extern sarebbe quello di dichiarare la variabile che ti serve nel .c (non nel .h). nell'header crei un prototipo di func che prendendo come parametro un intero, lo somma alla variabile "globale" che + globale non è. in questo modo è una variabile che viene definita nel .c, all'interno del programma non te la trovi in giro che può dar fastidio (per esempio potresti aver bisogno dello stesso nome per un'altra variabile), non fa si che per qualche errore si modifichi o cambi valore, puoi accedere facilmente al valore e puoi modificarlo...

il tutto on 3 righe XD  :o
Carlit0sway+
Prode Principiante
Messaggi: 92
Iscrizione: martedì 16 dicembre 2008, 17:26

Re: [C] Variabili globali gestite da più file

Messaggio da Carlit0sway+ »

tomallevi ha scritto: se posso consigliare, le variabili locali sono da evitare. un metodo alternativo al bruttissimo extern sarebbe quello di dichiarare la variabile che ti serve nel .c (non nel .h). nell'header crei un prototipo di func che prendendo come parametro un intero, lo somma alla variabile "globale" che + globale non è. in questo modo è una variabile che viene definita nel .c, all'interno del programma non te la trovi in giro che può dar fastidio (per esempio potresti aver bisogno dello stesso nome per un'altra variabile), non fa si che per qualche errore si modifichi o cambi valore, puoi accedere facilmente al valore e puoi modificarlo...

il tutto on 3 righe XD   :o
Sì grazie, ma ho già evitato di usare xtern anche con il metodo sovra indicato da crisixk.
Non mi è ben chiara, a questo punto, il vantaggio di dichiarare la variabile  nel .c  e non nel .h. ... Premetto che ho ugualmente realizzato le funzioni che mi suggerivi.
Scrivendo le varie soluzioni mi sono reso conto che il metodo di extern è scomodo! :)
Scrivi risposta

Ritorna a “Programmazione”

Chi c’è in linea

Visualizzano questa sezione: 0 utenti iscritti e 3 ospiti