Zmienna zewnętrzna - External variable

W języku programowania C An zmienna zewnętrzna jest definiowana w poza każdym bloku. Z drugiej strony, zmienna lokalna (automatyczna) to zmienna zdefiniowana wewnątrz bloku funkcyjnego.

Jako alternatywę dla zmiennych automatycznych można zdefiniować zmienne, które są zewnętrzne w stosunku do wszystkich funkcji, to znaczy zmienne, do których można uzyskać dostęp według nazwy przez dowolną funkcję. (Ten mechanizm przypomina raczej zmienne Fortran COMMON lub Pascal zadeklarowane w najbardziej zewnętrznym bloku). Ponieważ zmienne zewnętrzne są dostępne globalnie, można ich używać zamiast list argumentów do przesyłania danych między funkcjami. Co więcej, ponieważ zmienne zewnętrzne istnieją na stałe, zamiast pojawiać się i znikać podczas wywoływania i wychodzenia z funkcji, zachowują swoje wartości nawet po zwróceniu funkcji, które je ustawiają.

Definicja, deklaracja i externsłowo kluczowe

Aby zrozumieć, w jaki sposób zmienne zewnętrzne odnoszą się do externsłowa kluczowego, konieczne jest poznanie różnicy między definiowaniem a deklaracją zmiennej. Gdy zmienna jest zdefiniowana , kompilator przydziela pamięć dla tej zmiennej i prawdopodobnie inicjuje jej zawartość do pewnej wartości. Gdy zmienna jest zadeklarowana , kompilator wymaga, aby zmienna była zdefiniowana w innym miejscu. Deklaracja informuje kompilator, że zmienna o tej nazwie i typie istnieje, ale kompilator nie musi alokować dla niej pamięci, ponieważ jest ona przydzielona gdzie indziej. Słowo externkluczowe oznacza „deklaruj bez definiowania”. Innymi słowy, jest to sposób na jawne zadeklarowanie zmiennej lub wymuszenie deklaracji bez definicji. Możliwe jest również jawne zdefiniowanie zmiennej, czyli wymuszenie definicji. Odbywa się to poprzez przypisanie wartości inicjującej do zmiennej. Jeśli nie ma externsłowa kluczowego ani wartości inicjującej, instrukcja może być deklaracją lub definicją. Do kompilatora należy przeanalizowanie modułów programu i podjęcie decyzji.

Zmienna musi być zdefiniowana dokładnie raz w jednym z modułów programu. Jeśli nie ma definicji lub więcej niż jedna, pojawia się błąd, prawdopodobnie na etapie łączenia. Zmienną można deklarować wielokrotnie, o ile deklaracje są zgodne ze sobą iz definicją (co bardzo ułatwiają pliki nagłówkowe ). Może być deklarowana w wielu modułach, w tym w module, w którym została zdefiniowana, a nawet wielokrotnie w tym samym module. Ale zwykle nie ma sensu deklarować go więcej niż raz w module.

Zmienna zewnętrzna może być również zadeklarowana wewnątrz funkcji. W takim przypadku externnależy użyć słowa kluczowego, w przeciwnym razie kompilator uzna je za definicję zmiennej lokalnej ( automatycznej ), która ma inny zasięg, czas życia i wartość początkową. Ta deklaracja będzie widoczna tylko wewnątrz funkcji, a nie w całym module funkcji.

externKluczowe stosowane do prototypu funkcji robi nic (the externkluczowe stosowane do definicji funkcji jest, oczywiście, nie sensical). Prototyp funkcji jest zawsze deklaracją, a nigdy definicją. Ponadto w standardowym C funkcja jest zawsze zewnętrzna, ale niektóre rozszerzenia kompilatora pozwalają na zdefiniowanie funkcji wewnątrz funkcji.

Zmienna zewnętrzna musi być zdefiniowana dokładnie raz, poza jakąkolwiek funkcją; to odkłada na to miejsce do przechowywania. Zmienna musi być również zadeklarowana w każdej funkcji, która chce uzyskać do niej dostęp; to określa typ zmiennej. Deklaracja może być wyraźnym externoświadczeniem lub może być niejawna z kontekstu. ... Należy zauważyć, że przy odwoływaniu się w tej sekcji do zmiennych zewnętrznych używamy ostrożnie definicji i deklaracji słów. Definicja odnosi się do miejsca, w którym zmienna jest utworzona lub przypisana do przechowywania; deklaracja odnosi się do miejsc, w których określono charakter zmiennej, ale nie jest przydzielona pamięć.

Zakres, czas życia i staticsłowo kluczowe

Dostęp do zmiennej zewnętrznej można uzyskać za pomocą wszystkich funkcji we wszystkich modułach programu. Jest to zmienna globalna . Aby funkcja mogła korzystać ze zmiennej, deklaracja lub definicja zmiennej zewnętrznej musi znajdować się przed definicją funkcji w kodzie źródłowym. Lub musi być deklaracja zmiennej ze słowem kluczowym externwewnątrz funkcji.

Słowo statickluczowe ( statici externwzajemnie się wykluczają), zastosowane do definicji zmiennej zewnętrznej, nieco to zmienia: dostęp do zmiennej mogą uzyskać tylko funkcje w tym samym module, w którym została zdefiniowana. Istnieje jednak możliwość, że funkcja w tym samym module przekaże odwołanie (wskaźnik) zmiennej do innej funkcji w innym module. W takim przypadku, mimo że funkcja znajduje się w innym module, może odczytywać i modyfikować zawartość zmiennej — po prostu nie może odwoływać się do niej po nazwie.

Możliwe jest również użycie staticsłowa kluczowego na definicji zmiennej lokalnej. Bez staticsłowa kluczowego zmienna jest automatycznie przydzielana, gdy funkcja jest wywoływana i zwalniana, gdy funkcja kończy działanie (stąd nazwa „zmienna automatyczna”). Jego wartość nie jest zachowywana pomiędzy wywołaniami funkcji. Za pomocą staticsłowa kluczowego zmienna jest alokowana, gdy program się uruchamia, i zwalniana, gdy program się kończy. Jego wartość nie jest tracona między wywołaniami funkcji. Zmienna jest nadal lokalna, ponieważ można uzyskać do niej dostęp tylko przez nazwę wewnątrz funkcji, która ją zdefiniowała. Ale odwołanie (wskaźnik) do niej można przekazać do innej funkcji, umożliwiając jej odczytywanie i modyfikowanie zawartości zmiennej (znowu bez odwoływania się do niej po nazwie).

Zmienne zewnętrzne są przydzielane i inicjalizowane podczas uruchamiania programu, a pamięć jest zwalniana dopiero po zakończeniu programu. Ich żywotność jest taka sama jak programu.

Jeśli inicjalizacja nie jest wykonywana jawnie, zewnętrzne (statyczne lub nie) i lokalne zmienne statyczne są inicjowane na zero. Lokalne zmienne automatyczne są niezainicjalizowane, tzn. zawierają wartości „śmieci”.

Słowo statickluczowe zastosowane do definicji funkcji zmienia powiązanie funkcji tak, że jest ona widoczna tylko z jednostki tłumaczeniowej, w której znajduje się jej definicja. Zapobiega to wywołaniu funkcji przez nazwę spoza jej modułu (pozostaje możliwe przekazanie wskaźnika funkcji poza moduł i użycie go do wywołania funkcji). Zadeklarowanie funkcji za pomocą staticsłowa kluczowego jest również dobrym sposobem na zachowanie krótkiej nazwy przy jednoczesnym uniknięciu kolizji nazw.

Przykład (język programowania C)

Plik 1:

  // Explicit definition, this actually allocates
  // as well as describing
  int Global_Variable;

  // Function prototype (declaration), assumes 
  // defined elsewhere, normally from include file.       
  void SomeFunction(void);        

  int main(void) {
    Global_Variable = 1;
    SomeFunction();
    return 0;
  }

Plik 2:

  // Implicit declaration, this only describes and
  // assumes allocated elsewhere, normally from include
  extern int Global_Variable;  

  // Function header (definition)
  void SomeFunction(void) {       
    ++Global_Variable;
  }

W tym przykładzie zmienna Global_Variable jest zdefiniowana w Pliku 1. Aby użyć tej samej zmiennej w Pliku 2, należy ją zadeklarować . Niezależnie od liczby plików, zmienna globalna jest definiowana tylko raz; jednak musi być zadeklarowany w dowolnym pliku poza tym, który zawiera definicję.

Jeśli program znajduje się w kilku plikach źródłowych, a zmienna jest zdefiniowana w plik1 i używana w plik2 i plik3, to potrzebne są deklaracje extern w plik2 i plik3, aby połączyć wystąpienia zmiennej. Typową praktyką jest zbieranie zewnętrznych deklaracji zmiennych i funkcji w oddzielnym pliku, historycznie nazywanym nagłówkiem, który jest dołączany przez #include na początku każdego pliku źródłowego. Sufiks .h jest konwencjonalny dla nazw nagłówków.

Normalna metodologia polega na alokacji i faktycznych definicjach w plikach .c, ale zwykłe deklaracje i prototypy nie przydzielają i po prostu opisują typy i parametry, aby kompilator mógł działać poprawnie, a informacje te należą do pliku nagłówkowego .h, który inni mogą bezpiecznie włączyć bez konfliktu.

Zobacz też

Bibliografia

Linki zewnętrzne

  • Dokumentacja języka Microsoft C: Specyfikatory klasy pamięci dla deklaracji na poziomie zewnętrznym
  • „Norma C (C99 z poprawkami technicznymi TC1, TC2 i TC3) włącznie)” (PDF) . (3,61  MiB ) . W szczególności patrz sekcje 6.2.2 (Powiązanie identyfikatorów), 6.2.4 (Czas przechowywania obiektów), 6.7.1 (Specyfikatory klasy przechowywania) i 6.9 (Definicje zewnętrzne).