您好,登錄后才能下訂單哦!
這篇文章主要介紹“C語言外部鏈接的靜態變量怎么使用”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“C語言外部鏈接的靜態變量怎么使用”文章能幫助大家解決問題。
外部鏈接的靜態變量具有文件作用域、外部鏈接和靜態存儲期。該類別有時稱為外部存儲類別(external storage class),屬于該類別的變量稱為外部變量(external variable)。把變量的定義性聲明(defining declaration)放在所有函數的外面便創建了外部變量。
當然,為了指出該函數使用了外部變量,可以在函數中用關鍵字extern
再次聲明。如果一個源代碼文件使用的外部變量定義在另一個源代碼文件中,則必須用extern
在該文件中聲明該變量。如下所示:
int Errupt; /* externally defined variable */ double Up[100]; /* externally defined array */ extern char Coal; /* mandatory declaration if */ /* Coal defined in another file */ void next(void); int main(void) { extern int Errupt; /* optional declaration */ extern double Up[]; /* optional declaration */ ... } void next(void) { ... }
注意,在main()
中聲明Up
數組時(這是可選的聲明)不用指明數組大小,因為第1次聲明已經提供了數組大小信息。main()
中的兩條extern
聲明完全可以省略,因為外部變量具有文件作用域,所以Errupt
和Up
從聲明處到文件結尾都可見。它們出現在那里,僅為了說明main()
函數要使用這兩個變量。如果省略掉函數中的extern
關鍵字,相當于創建了一個自動變量。去掉下面聲明中的extern
:
extern int Errupt;
便成為:
int Errupt;
這使得編譯器在main()
中創建了一個名為Errupt
的自動變量。它是一個獨立的局部變量,與原來的外部變量Errupt
不同。該局部變量僅main()
中可見,但是外部變量Errupt
對于該文件的其他函數(如next())也可見。簡而言之,在執行塊中的語句時,塊作用域中的變量將“隱藏”文件作用域中的同名變量。如果不得已要使用與外部變量同名的局部變量,可以在局部變量的聲明中使用auto
存儲類別說明符明確表達這種意圖。外部變量具有靜態存儲期。因此,無論程序執行到main()
、next()
還是其他函數,數組Up
及其值都一直存在。下面3個示例演示了外部和自動變量的一些使用情況。示例1中有一個外部變量Hocus
。該變量對main()
和magic()
均可見。
/* Example 1 */ int Hocus; int magic(); int main(void) { extern int Hocus; // Hocus declared external ... } int magic() { extern int Hocus; // same Hocus as above ... }
示例2中有一個外部變量Hocus
,對兩個函數均可見。這次,在默認情況下對magic()
可見。
/* Example 2 */ int Hocus; int magic(); int main(void) { extern int Hocus; // Hocus declared external ... } int magic() { // Hocus not declared but is known ... }
在示例3中,創建了4個獨立的變量。main()
中的Hocus
變量默認是自動變量,屬于main()
私有。magic()
中的Hocus
變量被顯式聲明為自動,只有magic()
可用。外部變量Hocus
對main()
和magic()
均不可見,但是對該文件中未創建局部Hocus
變量的其他函數可見。最后,Pocus
是外部變量,magic()可見
,但是main()
不可見,因為Pocus
被聲明在main()
后面。
/* Example 3 */ int Hocus; int magic(); int main(void) { int Hocus; // Hocus declared, is auto by default ... } int Pocus; int magic() { auto int Hocus; // local Hocus declared automatic ... }
這3個示例演示了外部變量的作用域是:從聲明處到文件結尾。除此之外,還說明了外部變量的生命期。外部變量Hocus
和Pocus
在程序運行中一直存在,因為它們不受限于任何函數,不會在某個函數返回后就消失。
外部變量和自動變量類似,也可以被顯式初始化。與自動變量不同的是,如果未初始化外部變量,它們會被自動初始化為0。這一原則也適用于外部定義的數組元素。與自動變量的情況不同,只能使用常量表達式初始化文件作用域變量:
int x = 10; // ok, 10 is constant int y = 3 + 20; // ok, a constant expression size_t z = sizeof(int); // ok, a constant expression int x2 = 2 * x; // not ok, x is a variable
(只要不是變長數組,sizeof
表達式可被視為常量表達式。)
下面來看一個使用外部變量的示例。假設有兩個函數main()
和critic()
,它們都要訪問變量units
。可以把units
聲明在這兩個函數的上面,如程序清單12.4所示(注意:該例的目的是演示外部變量的工作原理,并非它的典型用法)。
/* global.c -- uses an external variable */ #include <stdio.h> int units = 0; /* an external variable */ void critic(void); int main(void) { extern int units; /* an optional redeclaration */ printf("How many pounds to a firkin of butter?n"); scanf("%d", &units); while ( units != 56) critic(); printf("You must have looked it up!n"); return 0; } void critic(void) { /* optional redeclaration omitted */ printf("No luck, my friend. Try again.n"); scanf("%d", &units); }
下面是該程序的輸出示例:
How many pounds to a firkin of butter? 14 No luck, my friend. Try again. 56 You must have looked it up! (We did.)
注意,critic()
是如何讀取units
的第2個值的。當while
循環結束時,main()
也知道units
的新值。所以main()
函數和critic()
都可以通過標識符units
訪問相同的變量。用C
的術語來描述是,units
具有文件作用域、外部鏈接和靜態存儲期。
把units
定義在所有函數定義外面(即外部),units
便是一個外部變量,對units
定義下面的所有函數均可見。因此,critics()
可以直接使用units
變量。
類似地,main()
也可直接訪問units
。但是,main()
中確實有如下聲明:
extern int units;
本例中,以上聲明主要是為了指出該函數要使用這個外部變量。存儲類別說明符extern
告訴編譯器,該函數中任何使用units
的地方都引用同一個定義在函數外部的變量。再次強調,main()
和critic()
使用的都是外部定義的units
。
C99
和C11
標準都要求編譯器識別局部標識符的前63個字符和外部標識符的前31個字符。這修訂了以前的標準,即編譯器識別局部標識符前31個字符和外部標識符前6個字符。你所用的編譯器可能還執行以前的規則。外部變量名比局部變量名的規則嚴格,是因為外部變量名還要遵循局部環境規則,所受的限制更多。
下面進一步介紹定義變量和聲明變量的區別。考慮下面的例子:
int tern = 1; /* tern defined */ main() { external int tern; /* use a tern defined elsewhere */
這里,tern
被聲明了兩次。第1次聲明為變量預留了存儲空間,該聲明構成了變量的定義。第2次聲明只告訴編譯器使用之前已創建的tern
變量,所以這不是定義。第1次聲明被稱為定義式聲明(defining declaration),第2次聲明被稱為引用式聲明(referencing declaration)。關鍵字extern
表明該聲明不是定義,因為它指示編譯器去別處查詢其定義。
假設這樣寫:
extern int tern; int main(void) {
編譯器會假設tern
實際的定義在該程序的別處,也許在別的文件中。該聲明并不會引起分配存儲空間。因此,不要用關鍵字extern
創建外部定義,只用它來引用現有的外部定義。
外部變量只能初始化一次,且必須在定義該變量時進行。假設有下面的代碼:
// file one.c char permis = 'N'; ... // file two.c extern char permis = 'Y'; /* error */
file_two
中的聲明是錯誤的,因為file_one.c
中的定義式聲明已經創建并初始化了permis
。
關于“C語言外部鏈接的靜態變量怎么使用”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。