C語言中變量和函數的做用域和連接屬性

C語言中變量和函數的做用域和連接屬性

做用域

  1. 代碼塊做用域: 代碼塊指的是使用「{}」包圍起來的部分。
    1. 在代碼塊中定義的變量,代碼塊以外是不能訪問的。
    2. 代碼塊嵌套以後的變量做用域,子代碼塊中定義的同名變量會覆蓋父代碼塊中的同名變量。
    3. #include <stdio.h>
       int main(){
           {
               int i=0;
               printf("%d\n",i);//0
               {                   
                   int i=1;
                   printf("%d\n",i);//1
               }
           }
       }
  2. 函數原型做用域: 函數原型做用域僅包括函數原型形式參數所在的括號。該做用於主要強調聲明函數時不能使用相同名稱的形式參數。
  3. 函數做用域: 函數做用域指的就是函數體的部分。K&R C的函數體不包含函數參數,因此在函數體內定義和函數參數同名變量會替代函數參數。ANSI C修改了該問題,函數參數在函數體的最外層做用域以內。
    1. 函數做用域內定義的變量,在函數以外不能進行訪問。
  4. 文件做用域: 源文件所在的範圍。
    1. 全部代碼塊以外定義的標識符就有文件做用域。(全局變量)
    2. 函數名不屬於任何任何代碼塊,所以也具備文件做用域。

連接屬性

  • 當組成一個程序的全部源文件被編譯以後,全部目標文件以及那些從一個或多個函數庫中引用的函數連接在一塊兒,組成可執行文件。問題是當相同的標識符出如今不一樣的源文件時該怎麼辦?標識符的連接屬性用來處理不一樣源文件中出現的標識符。標識符的連接屬性和它的做用域有關但並不相同。
  1. none(無): 老是被當作單獨個體,也就是說該標識符在不一樣源文件中的屢次聲明之間毫無關係,分屬不一樣的實體。
    1. 代碼塊以內定義的變量默認具備none鏈接屬性。經過extern修飾符能夠修改成外部連接屬性,這樣就能夠訪問其餘源文件中定義的外部變量了。static修飾符不能修改鏈接屬性和做用域,只修改存儲類型。
      C #include <stdio.h> int main(){ { static int i=0; printf("%d\n",i);//0 } printf("%d\n",i);//error: ‘i’ undeclared (first use in this function) }
  2. internal(內部): 在同一個源文件中的全部聲明指向同一實體,不一樣源文件指向不一樣實體。全局變量和函數能夠經過static修飾符從外部連接屬性改成內部連接屬性。
  3. external(外部):在全部源文件中指向同一實體。全局變量和函數默認具備全局做用域,能夠經過extern將從未顯式聲明連接屬性的標識符修改成外部連接屬性。
    1. static關鍵字能夠將全局變量和函數修改成內部鏈接屬性。
    2. 全局變量默認爲外部連接屬性:
      C main.c #include <stdio.h> int i; int main(){return 0;}; test.c #include <stdio.h> int i=0; gcc -c main.c test.c //success gcc -o main main.o test.o //multiple definination of "i" main.c修改: #include <stdio.h> extern int i;//經過使用extern將該全局變量聲明爲外部連接屬性,使用外部定義的變量。 int main(){return 0;} gcc -o main main.o test.o //success
    3. 函數經過extern關鍵字修飾爲全局鏈接屬性,指的是該函數可能在其餘源文件中進行定義。
      C main.c #include <stdio.h> extern int printHello();//僅指明該函數是在外部函數中聲明定義。 int main(){ printHello(); return 0; } test.c #include <stdio.h> int printHello(){ printf("hello\n"); return 0; }
相關文章
相關標籤/搜索