C – 函數與變數

來源:互聯網
上載者:User

7.4   內部變數與外部變數

C語言中所有的變數都有自己的範圍。變數說明的位置不同,其範圍也不同,據此將C語言中的變數分為內部變數和外部變數。

7.4.1  內部變數

7.4.2  外部變數

7.4.1  內部變數

在一個函數內部說明的變數是內部變數,它只在該函數範圍內有效。

也就是說,只有在包含變數說明的函數內部,才能使用被說明的變數,在此函數之外就不能使用這些變數了。所以內部變數也稱“局部變數”。

例如:

int f1(int a)     /*函數f1*/

    {  int b,c;

        ……

    }                  /*a,b,c範圍:僅限於函數f1()中*/

int f2(int x)     /*函數f2*/

   {  int y,z;     

 ……

   }           /*x,y,z範圍:僅限於函數f2()中*/

main()

    { int m,n;

       ……

    }                  /*m,n範圍:僅限於函數main()中*/

關於局部變數的範圍還要說明以下幾點:

1.主函數main()中定義的內部變數,也只能在主函數中使用,其它函數不能使用。同時,主函數中也不能使用其它函數中定義的內部變數。因為主函數也是一個函數,與其它函數是平行關係。這一點是與其它語言不同的,應予以注意。

2.形參變數也是內部變數,屬於被調用函數;實參變數,則是調用函數的內部變數。

3.允許在不同的函數中使用相同的變數名,它們代表不同的對象,分配不同的單元,互不干擾,也不會發生混淆。

4.在複合陳述式中也可定義變數,其範圍只在複合陳述式範圍內。

7.4.2  外部變數

在函數外部定義的變數稱為外部變數。以此類推,在函數外部定義的數組就稱為外部數組。

外部變數不屬於任何一個函數,其範圍是:從外部變數的定義位置開始,到本檔案結束為止。

外部變數可被範圍內的所有函數直接引用,所以外部變數又稱全域變數。

    [案例7.9]  輸入長方體的長(l)、寬(w)、高(h),求長方體體積及正、側、頂三個面的面積。

/*案例代碼檔案名稱:AL7_9.C*/

/*功能:利用全域變數計算長方體的體積及三個面的面積*/

int s1,s2,s3;

int vs(int a,int b,int c)

     {  int v;

          v=a*b*c;  s1=a*b;  s2=b*c;  s3=a*c;

         return  v;

          }

    main()

          {int v,l,w,h;

            clrscr();

            printf("/ninput length,width and height: ");

            scanf("%d%d%d",&l,&w,&h);

            v=vs(l,w,h);

           printf("v=%d    s1=%d    s2=%d    s3=%d/n",v,s1,s2,s3);

           getch();

          }                                                        

對於全域變數還有以下幾點說明:

(1)外部變數可加強函數模組之間的資料聯絡,但又使這些函數依賴這些外部變數,因而使得這些函數的獨立性降低。

從模組化程式設計的觀點來看這是不利的,因此不是非用不可時,不要使用外部變數。

(2)在同一源檔案中,允許外部變數和內部變數同名。在內部變數的範圍內,外部變數將被屏蔽而不起作用。

(3)外部變數的範圍是從定義點到本檔案結束。如果定義點之前的函數需要引用這些外部變數時,需要在函數內對被引用的外部變數進行說明。外部變數說明的一般形式為:

extern  資料類型  外部變數[,外部變數2……];

注意:外部變數的定義和外部變數的說明是兩回事。外部變數的定義,必須在所有的函數之外,且只能定義一次。而外部變數的說明,出現在要使用該外部變數的函數內,而且可以出現多次。

[案例7.10]  外部變數的定義與說明。

/*案例代碼檔案名稱:AL7_10.C*/

int vs(int xl,int xw)

    { extern int xh;                  /*外部變數xh的說明*/

       int v;

       v=xl*xw*xh;                 /*直接使用外部變數xh的值*/

       return v;

    }

main()

    {  extern int xw,xh;           /*外部變數的說明*/

        int xl=5;                        /*內部變數的定義*/

        printf("xl=%d,xw=%d,xh=%d/nv=%d",xl,xw,xh,vs(xl,xw));

    }

int xl=3,xw=4,xh=5;            /*外部變數xl、xw、xh的定義*/

                                             

7.5   內建函式和外部函數

        當一個來源程式由多個源檔案組成時,C語言根據函數能否被其它源檔案中的函數調用,將函數分為內建函式和外部函數。

7.5.1  內建函式(又稱靜態函數)

7.5.2  外部函數

7.5.3  多個來源程式檔案的編譯和串連

7.5.1  內建函式(又稱靜態函數)

如果在一個源檔案中定義的函數,只能被本檔案中的函數調用,而不能被同一程式其它檔案中的函數調用,這種函數稱為內建函式。

定義一個內建函式,只需在函數類型前再加一個“static”關鍵字即可,如下所示:

static  函數類型  函數名(函數參數表)

                {……}

關鍵字“static”,譯成中文就是“靜態”,所以內建函式又稱靜態函數。但此處“static”的含義不是指儲存方式,而是指對函數的範圍僅局限於本檔案。

使用內建函式的好處是:不同的人編寫不同的函數時,不用擔心自己定義的函數,是否會與其它檔案中的函數同名,因為同名也沒有關係。

7.5.2  外部函數

外部函數的定義:在定義函數時,如果沒有加關鍵字“static”,或冠以關鍵字“extern”,表示此函數是外部函數:

[extern]  函數類型  函數名(函數參數表)

                       {……}

調用外部函數時,需要對其進行說明:

[extern]  函數類型  函數名(參數類型表)[,函數名2(參數類型表2)……];

[案例7.11]  外部函數應用。

(1)檔案mainf.c

main()

{  extern void input(…),process(…),output(…);         

    input(…);  process(…);  output(…);

}

(2)檔案subf1.c

……

extern void input(……)                           /*定義外部函數*/

   {……}

(3)檔案subf2.c

……

extern void process(……)                      /*定義外部函數*/

   {……}

(4)檔案subf3.c

……

extern void output(……)                        /*定義外部函數*/

   {……}

7.5.3  多個來源程式檔案的編譯和串連

(1)一般過程

編輯各源檔案 → 建立Project(項目)檔案 → 設定項目名稱 → 編譯、串連,運行,查看結果。

(2)建立Project(項目)檔案

用編輯源檔案相同的方法,建立一個副檔名為.PRJ的專案檔:該檔案中僅包括將被編譯、串連的各源檔案名稱,一行一個,其副檔名.C可以預設;檔案名稱的順序,僅影響編譯的順序,與運行無關。

注意:如果有某個(些)源檔案不在目前的目錄下,則應在檔案名稱前冠以路徑。

(3)設定項目名稱

開啟菜單,選取Project/Project name,輸入專案檔名即可。

(4)編譯、串連,運行,查看結果

與單個源檔案相同。編譯產生的目標檔案,以及串連產生的可執行檔,它們的主檔案名,均與專案檔的主檔案名相同。

注意:當前專案檔調試完畢後,應選取Project/Clear project,將其項目名稱從“Project name”中清除(清除後為空白)。否則,編譯、串連和啟動並執行,始終是該專案檔!

(5)關於錯誤跟蹤

預設時,僅跟蹤當前一個來源程式檔案。如果希望自動跟蹤項目中的所有源檔案,則應將Options/Environment/Message Tracking開關置為“All files ”:連續按斷行符號鍵,直至“All files”出現為止。此時,滾動訊息視窗中的錯誤資訊時,系統會自動載入相應的源檔案到編輯視窗中。

也可關閉跟蹤(將“Message Tracking”置為“Off”)。此時,只要定位於感興趣的錯誤資訊上,然後斷行符號,系統也會自動將相應源檔案載入到編輯視窗中。

7.6   變數的動態儲存裝置與靜態儲存簡介

在C語言中,對變數的儲存類型說明有以下四種:自動變數(auto)、寄存器變數(register)、外部變數(extern)、靜態變數(static)。自動變數和寄存器變數屬於動態儲存裝置方式,外部變數和靜態內部變數屬於靜態儲存方式。

7.6.1  內部變數的儲存方式

7.6.2  外部變數的儲存方式

7.6.1  內部變數的儲存方式

1.靜態儲存──靜態內部變數

(1)定義格式: static  資料類型  內部變數表;

(2)儲存特點

1)靜態內部變數屬於靜態儲存。在程式執行過程中,即使所在函數調用結束也不釋放。換句話說,在程式執行期間,靜態內部變數始終存在,但其它函數是不能引用它們的。

2)定義但不初始化,則自動賦以"0"(整型和實型)或'/0'(字元型);且每次調用它們所在的函數時,不再重新賦初值,只是保留上次調用結束時的值!

(3)何時使用靜態內部變數

1)需要保留函數上一次調用結束時的值。

2)變數只被引用而不改變其值。

2.動態儲存裝置──自動局部變數(又稱自動變數)

(1)定義格式:[auto]  資料類型  變數表;        

(2)儲存特點

1)自動變數屬於動態儲存裝置方式。在函數中定義的自動變數,只在該函數內有效;函數被調用時分配儲存空間,調用結束就釋放。

在複合陳述式中定義的自動變數,只在該複合陳述式中有效;退出複合陳述式後,也不能再使用,否則將引起錯誤。

2)定義而不初始化,則其值是不確定的。如果初始化,則賦初值操作是在調用時進行的,且每次調用都要重新賦一次初值。

3)由於自動變數的範圍和生存期,都局限於定義它的個體內(函數或複合陳述式),因此不同的個體中允許使用同名的變數而不會混淆。即使在函數內定義的自動變數,也可與該函數內部的複合陳述式中定義的自動變數同名。

建議:系統不會混淆,並不意味著人也不會混淆,所以盡量少用同名自動變數!

[案例7.13]自動變數與靜態局部變數的儲存特性。

/*案例代碼檔案名稱:AL7_13.C*/

void  auto_static(void)

   {  int var_auto=0;               /*自動變數:每次調用都重新初始化*/

       static int var_static=0;              /*靜態局部變數:只初始化1次*/

       printf(“var_auto=%d, var_static=%d/n”, var_auto, var_static);

       ++var_auto;

       ++var_static;

     }

main()

     {  int i;

       for(i=0; i<5; i++) auto_static();

     }   

3.寄存器儲存──寄存器變數

一般情況下,變數的值都是儲存在記憶體中的。為提高執行效率,C語言允許將局部變數的值存放到寄存器中,這種變數就稱為寄存器變數。定義格式如下:

          register   資料類型   變數表;

(1)只有局部變數才能定義成寄存器變數,即全域變數不行。

(2)對寄存器變數的實際處理,隨系統而異。例如,微機上的MSC和TC 將寄存器變數實際當作自動變數處理。

(3)允許使用的寄存器數目是有限的,不能定義任意多個寄存器變數。

7.6.2  外部變數的儲存方式

外部變數屬於靜態儲存方式:

(1)靜態外部變數──只允許被本源檔案中的函數引用

其定義格式為:  static  資料類型  外部變數表;

(2)非靜態外部變數──允許被其它源檔案中的函數引用

定義時預設static關鍵字的外部變數,即為非靜態外部變數。其它源檔案中的函數,引用非靜態外部變數時,需要在引用函數所在的源檔案中進行說明:

extern  資料類型  外部變數表;

注意:在函數內的extern變數說明,表示引用本源檔案中的外部變數!而函數外(通常在檔案開頭)的extern變數說明,表示引用其它檔案中的外部變數。

靜態局部變數和靜態外部變數同屬靜態儲存方式,但兩者區別較大:

(1)定義的位置不同。靜態局部變數在函數內定義,靜態外部變數在函數外定義。

(2)範圍不同。靜態局部變數屬於內部變數,其範圍僅限於定義它的函數內;雖然生存期為整個來源程式,但其它函數是不能使用它的。

靜態外部變數在函數外定義,其範圍為定義它的源檔案內;生存期為整個來源程式,但其它源檔案中的函數也是不能使用它的。

    (3)初始化處理不同。靜態局部變數,僅在第1次調用它所在的函數時被初始化,當再次調用定義它的函數時,不再初始化,而是保留上1次調用結束時的值。而靜態外部變數是在函數外定義的,不存在靜態內部變數的“重複”初始化問題,其當前值由最近1次給它賦值的操作決定。

務必牢記:把局部變數改變為靜態內部變數後,改變了它的儲存方式,即改變了它的生存期。把外部變數改變為靜態外部變數後,改變了它的範圍,限制了它的使用範圍。因此,關鍵字“static”在不同的地方所起的作用是不同的。
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.