Specifikátory třídy úložiště pro deklarace na externí úrovni
Externí proměnné jsou proměnné v rozsahu souboru. Jsou definovány mimo jakoukoliv funkci a jsou potenciálně dostupné pro mnoho funkcí. Funkce lze definovat pouze na externí úrovni, a proto nemohou být vnořeny. Ve výchozím nastavení jsou všechny odkazy na externí proměnné a funkce stejného názvu odkazy na stejný objekt, což znamená, že mají externí propojení. (Toto chování můžete přepsat pomocí klíčového static
slova.)
Deklarace proměnných na externí úrovni jsou definice proměnných (definování deklarací) nebo odkazy na proměnné definované jinde (odkazující na deklarace).
Externí deklarace proměnné, která také inicializuje proměnnou (implicitně nebo explicitně), je definující deklarací proměnné. Definici na externí úrovni lze provést několika způsoby:
Proměnná, kterou deklarujete pomocí specifikátoru
static
třídy úložiště. Proměnnou můžete explicitně inicializovatstatic
konstantním výrazem, jak je popsáno v inicializaci. Při vynechání inicializátoru je ve výchozím nastavení proměnná inicializována na hodnotu 0. Například tyto dva příkazy jsou oba považovány za definice proměnnék
.static int k = 16; static int k;
Proměnná, která je explicitně inicializována na externí úrovni. Například
int j = 3;
je definicí proměnnéj
.
V deklarací proměnných na externí úrovni (tj. mimo všechny funkce) můžete použít static
specifikátor třídy úložiště nebo extern
zcela vynechat specifikátor třídy úložiště. Nemůžete používat terminály auto
na register
storage-class-specifier
vnější úrovni.
Jakmile je proměnná definována na externí úrovni, je viditelná ve zbytku jednotky překladu. Proměnná není viditelná před deklarací ve stejném zdrojovém souboru. Také se nezobrazuje v jiných zdrojových souborech programu, pokud není umožněno její zobrazení pomocí odkazující deklarace, jak je popsáno níže.
Pravidla týkající se zahrnutí static
:
Proměnné deklarované mimo všechny bloky bez klíčového
static
slova vždy zachovají své hodnoty v rámci programu. Pokud chcete omezit přístup k určité jednotce překladustatic
, musíte použít klíčové slovo. To jim dává interní propojení. Aby mohly být globálními v rámci celého programu, je třeba vynechat třídu explicitního úložiště a použít klíčové slovoextern
(viz pravidla v dalším seznamu). To jim dává externí propojení. Interní a externí propojení jsou popsány také ve službě Linkage.V rámci programu lze definovat proměnné na externí úrovni pouze jednou. V jiné jednotce překladu můžete definovat jinou proměnnou se stejným názvem a specifikátorem
static
třídy úložiště. Vzhledem k tomu, že každástatic
definice je viditelná pouze v rámci vlastní jednotky překladu, nedojde ke konfliktu. Poskytuje užitečný způsob, jak skrýt názvy identifikátorů, které musí být sdíleny mezi funkcemi jedné jednotky překladu, ale není viditelné pro jiné jednotky překladu.static
Specifikátor třídy úložiště se může použít i pro funkce. Pokud deklarujete funkcistatic
, její název je neviditelný mimo soubor, ve kterém je deklarován.
Pravidla pro používání specifikátoru třídy úložiště extern
jsou:
Specifikátor třídy úložiště
extern
deklaruje odkaz na proměnnou definovanou jinde. Deklaraci můžete použítextern
k zobrazení definice v jiném zdrojovém souboru nebo k tomu, aby byla proměnná viditelná před definicí ve stejném zdrojovém souboru. Jakmile deklarujete odkaz na proměnnou na externí úrovni, bude proměnná viditelná ve zbývající části jednotky překladu, ve které se deklarovaný odkaz vyskytuje.Aby byl odkaz
extern
platný, proměnná, na kterou odkazuje, musí být na externí úrovni definována nanejvýš jednou. Tato definice (bez třídy úložištěextern
) může být v libovolných jednotkách překladu, které tvoří program.
Příklad
Následující příklad znázorňuje externí deklarace:
/******************************************************************
SOURCE FILE ONE
*******************************************************************/
#include <stdio.h>
extern int i; // Reference to i, defined below
extern void other ( void ); // Reference to other(), defined in second source file
void next( void ); // Function prototype
int main()
{
i++;
printf_s( "%d\n", i ); // i equals 4
next();
}
int i = 3; // Definition of i
void next( void )
{
i++;
printf_s( "%d\n", i ); // i equals 5
other();
}
/******************************************************************
SOURCE FILE TWO
*******************************************************************/
#include <stdio.h>
extern int i; // Reference to i in
// first source file
void other( void )
{
i++;
printf_s( "%d\n", i ); // i equals 6
}
V tomto příkladu obsahují dva zdrojové soubory celkem tři externí deklarace i
. Pouze jedna deklarace je "definující deklarace". Tato deklarace,
int i = 3;
definuje globální proměnnou i
a inicializuje ji s počáteční hodnotou 3. Deklarace odkazující na i
první zdrojový soubor, která používá první zdrojový soubor, extern
zviditelní globální proměnnou před definicí deklarace v souboru. Odkazující deklarace i
také způsobí ve druhém zdrojovém souboru zviditelnění proměnné v daném zdrojovém souboru. Není-li poskytnuta definující instance proměnné v jednotce překladu, předpokládá kompilátor přítomnost
extern int x;
odkazující deklarace a to, že se definující odkaz
int x = 0;
zobrazí v jiné jednotce překladu programu.
Všechny tři funkce, main
, next
a other
, provádějí stejný úkol: zvyšují proměnnou i
a vypíší ji. Jsou vypsány hodnoty 4, 5 a 6.
i
Pokud proměnná nebyla inicializována, byla by nastavena na hodnotu 0 automaticky. V tomto případě by byly vypsány hodnoty 1, 2 a 3. Informace o inicializaci proměnných najdete v části Inicializace .