Domanda

Sto usando C (non C++) e non sono sicuro di come evitare l'uso di variabili globali.

Ho una conoscenza abbastanza discreta del C, della sua sintassi e di come scrivere un'applicazione di base, ma non sono sicuro del modo corretto di strutturare il programma.

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

Esiste qualche buon software open source scritto rigorosamente in C a cui potrei dare un'occhiata?Non riesco a pensare a nessuno in cima alla mia testa, la maggior parte sembra essere in C++.

Grazie.

Modificare

Ecco un esempio di dove utilizzerei una variabile globale in una semplice applicazione di hooking API, che è semplicemente una DLL all'interno di un altro processo.

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

Tuttavia, quando unagganciando la funzione API, devo riscrivere il codice memoria/macchina originale.

Quindi, devo mantenere un semplice array di byte per quel codice macchina, uno per ciascuna funzione API agganciata, e ce ne sono molte.

// 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 );

Scusate se crea confusione.

È stato utile?

Soluzione

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

  1. Utilizza variabili statiche.Se una funzione deve ricordare qualcosa tra una chiamata e l'altra, usa questo invece delle variabili globali.Esempio:

    int running_total (int num) {
        static int sum  = 0;
        sum             += num;
        return sum;
    }
    
  2. Passare i dati tramite parametri, in modo che il valore sia definito in un posto, forse main() e passato dove serve.

  3. Se tutto il resto fallisce, vai avanti e utilizza un globale ma prova a mitigare i potenziali problemi.

    1. Come minimo, utilizzare le convenzioni di denominazione per ridurre al minimo i potenziali conflitti.PER ESEMPIO: Gbl_MyApp_DeveloperName.Quindi tutte le variabili globali inizierebbero con Gbl_MyApp_ part - dove "MyApp" era qualcosa di descrittivo della tua app.
    2. Prova a raggruppare le funzioni per scopo, in modo che tutto ciò che necessita di un dato globale sia nello stesso file (entro limiti ragionevoli).Quindi i globali possono essere definiti e limitati a quel file (attenzione a extern parola chiave).

Altri suggerimenti

Ci sono alcuni usi validi per le variabili globali.Le scuole hanno iniziato a insegnare che fossero cattivi per mantenere i programmatori di essere pigri e per usarli.Se sei sicuro che i dati siano davvero globalmente necessari, usali.Dato che sei preoccupato di fare un buon lavoro, non penso che andrai troppo sbagliato usando il tuo giudizio.

È facile - semplicemente non usarli.Creare ciò che avrebbe Ben le variabili globali nella funzione principale () e poi passarle da lì come parametri alle funzioni che ne hanno bisogno.

Il software open source più consigliato per imparare C nel mio college era stato Linux in modo da poter ottenere esempi dalla loro fonte.

Penso che lo stesso, i globali siano cattivi, riducono la leggibilità e aumenta la possibilità di errori e altri problemi.

Spiegherò il mio esempio.Ho un principale () facendo davvero poche cose.La maggior parte dell'azione proviene da timer e interrupt esterni.Queste sono funzioni senza parametro, a causa della piattaforma che sto usando, 32 bit micro controller.Non riesco a passare i parametri e in aggiunta, questi interrupt e timer sono asincroni.Il modo più semplice è un globale, immagina, interrompe il riempimento di un buffer, questo buffer è analizzato all'interno di un timer e le informazioni analizzate vengono utilizzate, memorizzate, inviate in altri timer. OK, posso tirare su una bandiera di interrupt e processare nella funzione principale, ma quando si esegue il software critico in questo modo non è una buona idea.

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

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

Ogni volta che vuoi una variabile globale, pensa: cosa succede se ne avessi bisogno di un altro tipo?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top