2010-07-08 9 views
6

Używam C (nie C++) i nie jestem pewien, jak unikać zmiennych globalnych.C - struktura programu (unikanie zmiennych globalnych, obejmuje, itp.)

Mam całkiem przyzwoity chwyt na temat C, jego składni i jak napisać podstawową aplikację, ale nie jestem pewien co do właściwego sposobu struktury programu.

W jaki sposób naprawdę duże aplikacje unikają stosowania zmiennych globalnych? Jestem pewien, że zawsze będą potrzebne przynajmniej niektóre, ale w przypadku dużych gier i innych aplikacji napisanych w C, jaki jest najlepszy sposób na zrobienie tego?

Czy jest jakieś dobre oprogramowanie o otwartym kodzie źródłowym napisane w C, na które mogłem spojrzeć? Nie wyobrażam sobie, żebym był z głowy, większość z nich wydaje się być w C++.

Dzięki.

Edit

Oto przykład, gdzie chciałbym użyć zmiennej globalnej w prostej aplikacji API hakowym, który jest po prostu DLL wewnątrz innego procesu.

Ta aplikacja, w szczególności, przechwytuje funkcje API używane w innej aplikacji. Robi to za pomocą WriteProcessMemory, aby nadpisać połączenie do oryginału, i zamiast tego wywoła to wywołanie do mojej biblioteki DLL.

Jednakże, gdy un zahaczenie funkcji API, muszę zapisać oryginalny kod pamięci/komputera.

Potrzebuję więc tablicy tablic prostych dla tego kodu maszynowego, po jednym dla każdej funkcji API, która jest podłączona, i jest wiele.

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

Przepraszam, jeśli to jest mylące.

+1

Czy możesz podać konkretny przykład? Jak myślisz, do czego może być potrzebna zmienna globalna? W 99% przypadków nie musi mieć globalnego charakteru. –

Odpowiedz

7

"Jak naprawdę duże aplikacje unikają stosowania zmiennych globalnych?"

  1. Użycie zmiennych statycznych. Jeśli funkcja musi pamiętać coś między połączeniami, użyj tej w porównaniu ze zmiennymi globalnymi.Przykład:

    int running_total (int num) { 
        static int sum = 0; 
        sum    += num; 
        return sum; 
    } 
    
  2. dane przekazywanie za pośrednictwem parametrów, tak, że wartość jest to określone miejsce, może main() i przekazywane tam, gdzie jest to potrzebne.

  3. Jeśli wszystko inne zawiedzie, skorzystaj z opcji globalnej, ale spróbuj złagodzić potencjalne problemy.

    1. Konwencje nazewnictwa wymagają minimum, aby zminimalizować potencjalne konflikty. EG: Gbl_MyApp_DeveloperName. Więc wszystkie zmienne globalne zaczynałyby się od części Gbl_MyApp_ - gdzie "MojaAplikacja" miała charakter opisowy dla Twojej aplikacji.
    2. Staraj się grupować funkcje według celu, aby wszystko, co potrzebuje danego globusa, znajdowało się w tym samym pliku (w granicach rozsądku). Następnie można zdefiniować globale i ograniczyć do tego pliku (uwaga na słowo kluczowe extern).
+2

Wygląda na to, że zmienne statyczne znajdujące się w różnych plikach mogą być o wiele trudniejsze do śledzenia niż zmienna globalna, z prefiksem, w jednym pliku globals.h. –

+0

Jedną z używanych przeze mnie metod jest struktura, która zostanie zadeklarowana w funkcji main(). Następnie wskaźnik do tej struktury jest przekazywany do funkcji Init() modułów i dowolnej innej funkcji modułu. Ta struktura zawiera wszystkie zmienne używane w module. Jest to jedno podejście i są w nim zalety i wady. Jednym z nich jest to, że pozwala na łatwe używanie modułu na wiele sposobów. Na przykład moduł pętli sterowania może być użyty do sterowania wieloma pętlami sterowania w ten sposób. – Seidleroni

1

Najlepiej rekomendowanym oprogramowaniem open-source do nauki C w moim college'u był Linux, więc możesz pobrać przykłady z ich źródła.

2

Istnieje kilka poprawnych zastosowań zmiennych globalnych. Szkoły zaczęły nauczać, że są złe, aby powstrzymać programistów od lenistwa i używania ich. Jeśli masz pewność, że dane są rzeczywiście potrzebne na całym świecie, użyj ich. Biorąc pod uwagę, że jesteś zaniepokojony wykonaniem dobrej pracy, nie sądzę, że popełnisz za duży błąd, stosując własną ocenę.

0

Zmienne globalne są prawie nieuniknione. Są one jednak często nadużywane. Nie są one substytutem przekazywania właściwych parametrów i projektowania właściwych struktur danych.

Za każdym razem, gdy chcesz zmiennej globalnej, pomyśl: co, jeśli potrzebuję jeszcze jeden taki?

+1

Czy masz konkretny przykład "nieuniknionej" zmiennej globalnej? – Secure

2

To proste - po prostu ich nie używaj. utwórz, co by miało zmienne globalne w funkcji main(), a następnie przekaż je stamtąd jako parametry do funkcji, które ich potrzebują.

+1

Chciałem być "kawalerem" - jeśli jest to trudne, dane prawie na pewno nie powinny być globalne. –

0

myślę same, globalne są złe, zmniejsza czytelność i zwiększa możliwość błędu i inne problemy.

Wyjaśnię mój przykład. Mam main() robiąc naprawdę mało rzeczy. Większość akcji pochodzi z timerów i przerwań zewnętrznych. Są to funkcje bez parametrów, ze względu na platformę, z której korzystam, 32-bitowy mikrokontroler. Nie mogę przekazać parametrów, a ponadto te przerwania i timery są asynchroniczne. Najprostszym sposobem jest globalne, wyobraź sobie, przerywa wypełnianie bufora, ten bufor jest przetwarzany wewnątrz licznika czasu, a informacje są analizowane, używane, przechowywane, wysyłane w innych programach czasowych. OK, mogę podnieść flagę przerwania i przetworzyć główną funkcję, ale podczas wykonywania krytycznego oprogramowania w ten sposób nie jest to dobry pomysł.

Jest to jedyny rodzaj zmiennej globalnej, która nie sprawia, że ​​czuję się źle ;-)

Powiązane problemy