C語言作用域和鏈接屬性


一.作用域

當變量被定義在程序不同位置時,它的作用范圍是不一樣的,這個作用范圍就是我們所說的作用域。

C語言編譯器可以確認4種不同類型的作用域:

——代碼塊作用域

——文件作用域

——原型作用域

——函數作用域

1.代碼塊作用域

在代碼塊中定義的變量,具有代碼塊作用域。作用范圍是從變量定義的位置開始,到標志該代碼塊結束的右大括號{}處

盡管函數的形式參數不在大括號內定義,但同樣具有代碼塊作用域,隸屬於包含函數體的代碼塊

#include <stdio.h>

int main(void)
{
    int i = 100; // i1
    {
        int i = 110; // i2
        {
            int i = 120; // i3
            printf("i = %d\n", i);
        }
        // i = 110
        {
            printf("i = %d\n", i);
            int i = 130; // i4
            printf("i = %d\n", i);
        }
        printf("i = %d\n", i);
    }
    printf("i = %d\n", i);

    return 0;
}

 

 

2.文件作用域

任何在代碼塊之外聲明的標識符都具有文件作用域,作用范圍是從它們的聲明位置開始,到文件的結尾處都是可以訪問的。

另外,函數名也具有文件作用域,因為函數名本身也是在代碼塊之外。

#include <stdio.h>

void func(void);

int main(void)
{
    extern int count;

    func();
    count++;
    printf("In main, count = %d\n", count);    

    return 0;
}

int count;

void func(void)
{
    count++;
    printf("In func, count = %d\n", count);
}

 

3.原型作用域

原型作用域只適用於那些在函數原型中聲明的參數名。函數在聲明的時候可以不寫參數的名字(但參數類型是必須是寫上的),其實函數原型的參數名還可以隨便寫一個名字,不必與形式參數相匹配。

void func(int a,int b,int c);
void func(int d,int e, int f)
{
....
}

4.函數作用域

函數作用域只適用於goto語句的標簽,作用將goto語句的標簽限制在同一個函數內部,以及防止出現重名標簽

二.定義和聲明

當一個變量被定義的時候,編譯器為變量申請內存空間並填充一些值。
當一個變量被聲明的時候,編譯器就知道該變量被定義在其他地方。
聲明是通知編譯器該變量名及相關的類型已存在,不需要再為此申請內存空間。
局部變量既是定義又是聲明。
定義只能來一次,否則就叫做重復定義某個同名變量;而聲明可以有很多次。

三.鏈接屬性

1.external(外部的)
多個文件中聲明的同名標識符表示同一個實體
internal(內部的)
單個文件中聲明的同名標識符表示同一個實體
none(無)
聲明的同名標識符被當作獨立不同的實體

2.只有具備文件作用域的標識符才能擁有external或internal的鏈接屬性,其他作用域的標識符都是none屬性。
默認情況下,具備文件作用域的標識符擁有external屬性。也就是說該標識符允許跨文件訪問。對於external屬性的標識符,無論在不同文件中聲明多少次,表示的都是同一個實體。
 
3.使用static關鍵字可以使得原先擁有external屬性的標識符變為internal屬性。這里有兩點需要注意:
使用static關鍵字修改鏈接屬性,只對具有文件作用域的標識符生效(對於擁有其他作用域的標識符是另一種功能)
鏈接屬性只能修改一次,也就是說一旦將標識符的鏈接屬性變為internal,就無法變回external了
 

 

 編譯器工作原理:https://fishc.com.cn/forum.php?mod=viewthread&tid=78063&extra=page%3D1%26filter%3Dtypeid%26typeid%3D571

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM