日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

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。

分享到:
標簽:變量 靜態 語言
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定