2010-07-08 15 views
6

Sto usando C (non C++) e non so come evitare l'uso di variabili globali.C - struttura del programma (evitare variabili globali, include, ecc.)

Ho una presa abbastanza decente su C, la sua sintassi e come scrivere un'applicazione di base, ma non sono sicuro del modo corretto di strutturare il programma.

In che modo le applicazioni di grandi dimensioni evitano l'utilizzo di variabili globali? Sono abbastanza sicuro che ci sarà sempre bisogno di esserne almeno alcuni, ma per i grandi giochi e altre applicazioni scritte in C, qual è il modo migliore per farlo?

Esiste un buon software open source scritto rigorosamente in C che potrei esaminare? Non riesco a pensare a nessuno in cima alla mia testa, la maggior parte di loro sembra essere in C++.

Grazie.

Modifica

Ecco un esempio di dove avrei utilizzare una variabile globale in una semplice applicazione API di aggancio, che è solo un DLL all'interno di un altro processo.

Questa applicazione, in particolare, aggancia le funzioni API utilizzate in un'altra applicazione. Lo fa usando WriteProcessMemory per sovrascrivere la chiamata sull'originale, e fargli invece una chiamata alla mia DLL.

Tuttavia, quando un agganciando la funzione API, devo scrivere nuovamente il codice di memoria/macchina originale.

Quindi, ho bisogno di mantenere un semplice array di byte per quel codice macchina, uno per ogni funzione API che è agganciata, e ce ne sono molti.

// Global variable to store original assembly code (6 bytes) 
BYTE g_MessageBoxA[6]; 

// Hook the API function 
HookAPIFunction ("user32.dll", "MessageBoxA", MyNewFunction, g_MessageBoxA); 

// Later on, unhook the function 
UnHookAPIFunction ("user32.dll", "MessageBoxA", g_MessageBoxA); 

Scusa se questo è confuso.

+1

Può fare un esempio specifico? Per cosa pensi che potresti aver bisogno di una variabile globale? Il 99% delle volte non ha bisogno di essere globale. –

risposta

7

"In che modo applicazioni davvero grandi evitano l'uso di variabili globali?"

  1. Utilizzare variabili statiche. Se una funzione deve ricordare qualcosa tra le chiamate, utilizzare questa contro le variabili globali.Esempio:

    int running_total (int num) { 
        static int sum = 0; 
        sum    += num; 
        return sum; 
    } 
    
  2. dati passare per parametri, in modo che il valore è definito un unico luogo, forse main() e passato a dove è necessario.

  3. Se tutto il resto fallisce, andare avanti e utilizzare un globale, ma cercare di mitigare i potenziali problemi.

    1. Come minimo, utilizzare le convenzioni di denominazione per ridurre al minimo i potenziali conflitti. EG: Gbl_MyApp_DeveloperName. Quindi tutte le variabili globali inizieranno con la parte Gbl_MyApp_ - dove "MyApp" era qualcosa di descrittivo della tua app.
    2. Provare a raggruppare le funzioni in base allo scopo, in modo che tutto ciò che ha bisogno di un dato globale si trovi nello stesso file (entro limiti ragionevoli). Quindi le globali possono essere definite e limitate a quel file (attenzione alla parola chiave extern).
+2

Sembra che le variabili statiche situate in file diversi possano essere molto più difficili da tenere traccia di una variabile globale, con prefisso, in un singolo file globals.h. –

+0

Un metodo che utilizzo è che ogni modulo abbia una struttura che viene dichiarata nella funzione main(). Quindi un puntatore a questa struttura viene passato alla funzione Init() dei moduli e a qualsiasi altra funzione del modulo. Questa struttura contiene tutte le variabili utilizzate nel modulo. Questo è un approccio e ci sono pro e contro. Un professionista è che consente a un modulo di essere facilmente utilizzato in più modi. Ad esempio, un modulo del loop di controllo potrebbe essere utilizzato per controllare più loop di controllo in questo modo. – Seidleroni

1

Il software open source più consigliato per imparare C nel mio college era Linux, quindi è possibile ottenere esempi dalla loro fonte.

2

Esistono alcuni usi validi per le variabili globali. Le scuole hanno iniziato a insegnare che erano malvagie per impedire ai programmatori di essere pigri e di usarli. Se sei sicuro che i dati siano realmente necessari a livello globale, usali. Dato che sei preoccupato di fare un buon lavoro, non penso che ti sbagli troppo lontano usando il tuo stesso giudizio.

0

Le variabili globali sono quasi inevitabili. Tuttavia, sono spesso abusati. Non sono un sostituto per il passaggio di parametri adeguati e la progettazione delle giuste strutture di dati.

Ogni volta che vuoi una variabile globale, pensa: cosa succede se ne ho bisogno di una in più in questo modo?

+1

Avete un esempio concreto di una variabile globale "inevitabile"? – Secure

2

È semplice, semplicemente non usarli. crea quello che avrebbe ben le variabili globali nella tua funzione main(), e poi passali da lì come parametri alle funzioni che ne hanno bisogno.

+1

Intendevo essere "cavalier" - se è difficile da fare, i dati quasi certamente non dovrebbero essere globali. –

0

Penso che lo stesso, globali sono cattivi, riduce la leggibilità e aumenta la possibilità di errore e altri problemi.

Spiegherò il mio esempio. Ho un main() facendo davvero poche cose. La maggior parte dell'azione proviene da timer e interrupt esterni. Queste sono funzioni senza parametri, a causa della piattaforma che sto usando, microcontrollore a 32 bit. Non riesco a passare i parametri e inoltre, questi interrupt e timer sono asincroni. Il modo più semplice è un globale, immaginare, interrompe il riempimento di un buffer, questo buffer viene analizzato all'interno di un timer e le informazioni analizzate vengono utilizzate, memorizzate, inviate in altri timer. Ok, posso richiamare un flag di interrupt ed elaborare nella funzione principale, ma quando l'esecuzione di un software critico in questo modo non è una buona idea.

questo è l'unico tipo di variabile globale che non mi fa sentire male ;-)