中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C語言中的作用域、鏈接、存儲期的概念

發布時間:2021-07-12 11:47:43 來源:億速云 閱讀:157 作者:chen 欄目:編程語言

這篇文章主要講解了“C語言中的作用域、鏈接、存儲期的概念”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“C語言中的作用域、鏈接、存儲期的概念”吧!

1. 作用域

C 程序中出現的每個標識符都僅在一些可能不連續的部分可見(即可使用),這些部分被稱為其作用域。作用域描述程序中可訪問標識符的區域。

C 擁有四種作用域:

  1. 塊作用域

  2. 函數作用域

  3. 函數原型作用域

  4. 文件作用域

1.1. 塊作用域

任何在復合語句,包含函數體或出現于 if 、 switch 、 for 、 while 或 do-while 語句中的任何表達式、聲明或語句 (C99 起),或在函數定義內的參數列表中聲明的標識符的作用域,在聲明點開始,在聲明于其中的塊或語句的結尾結束。

1.2. 函數作用域

聲明于函數內部的標號(且只有標號),在該函數中的所有位置(所有嵌套塊中,其自身聲明前后)都在作用域內。注意:任何語句前的冒號字符前的標識符,若不用于其他用途,則隱式聲明一個標號。

void f()
{
   {   
       goto label; // label 在作用域中,盡管之后才聲明
label:;
   }
   goto label; // 標號忽略塊作用域
}
 
void g()
{
    goto label; // 錯誤: g() 中 label 不在作用域中
}
1.3. 函數原型作用域

非函數定義的函數聲明的參數列表中引入的名稱的作用域,在函數聲明器的結尾結束。

int f(int n,
      int a[n]); // n 在作用域中并指代第一參數
1.4. 文件作用域

在任何塊或參數列表外聲明的任何標識符的作用域,在聲明點開始,翻譯單元尾結束。

int i; // i 的作用域開始
static int g(int a) { return a; } // g 的作用域開始(注意 "a" 擁有塊作用域)
int main(void)
{
    i = g(2); // i 和 g 在作用域中
}
1.5. 嵌套作用域

若相同標識符所命名的二個不同實體在同一時刻都在作用域中,且它們屬于同一命名空間,則作用域被嵌套(不允許其他形式的作用域重疊),而內層作用域中的聲明隱藏外層作用域中的聲明:

// 此處的命名空間為通常標識符。
 
int a;   // 名稱 a 的文件作用域始于此
 
void f(void)
{
    int a = 1; // 名稱 a 的塊作用域始于此;隱藏文件作用域的 a
    {
      int a = 2;         // 內層 a 的作用域始于此,隱藏外層 a 
      printf("%d\n", a); // 內層 a 在作用域中,打印 2
    }                    // 內層 a 的塊作用域終于此
    printf("%d\n", a);   // 外層 a 在作用域中,打印 1
}                        // 外層 a 的作用域終于此
 
void g(int a);   // 名稱 a 擁有函數原型作用域;隱藏文件作用域的 a

注意,若聲明中有多個或嵌套聲明器,則作用域在最近的外圍函數聲明器的結尾結束:

void f ( // 函數名 'f' 在文件作用域
 long double f,            // 標識符 'f' 現在在作用域中,隱藏文件作用域的 'f'
 char (**a)[10 * sizeof f] // 'f' 指代第一參數,它在作用域中
);
 
enum{ n = 3 };
int (*(*g)(int n))[n]; // 函數參數 'n' 的作用域在其函數聲明器的結尾結束
                       // 數組聲明器中,全局 n 在作用域
// (這聲明指向返回 3 個 int 的數組的指針的函數的指針)
1.6. 聲明點

結構體、聯合體及枚舉標簽的作用域,在聲明該標簽的類型指定符中的標簽出現后立即開始。

struct Node {
   struct Node* next; // Node 在作用域中并指代此 struct
};

枚舉常量的作用域,在枚舉項列表中其定義枚舉項的出現后立即開始。

enum { x = 12 };
{
    enum { x = x + 1, // 新 x 在逗號前不在作用域中,初始化 x 為 13
           y = x + 1  // 新枚舉項 x 現在在作用域中,初始化 y 為 14
         };
}

任何其他標識符的作用域,正好在其聲明器結束后和初始化器前開始,若存在初始化器:

int x = 2; // 第一個 'x' 的作用域開始
{
    int x[x]; // 新聲明的 x 的作用域在聲明器 ( x[x] )后開始。
              // 在聲明器內,外層 'x' 仍在作用域中。
              // 這聲明 2 個 int 的 VLA 數組。
}
 
unsigned char y = 32; // 外層 'y' 的作用域開始
{
    unsigned char y = y;
            // 內層 'y' 的作用域在初始化器( = y )前開始
            // 這不會以值 32 初始化內層 'y' ,
            // 這以其自身的不確定值初始化內層 'y'
}
 
unsigned long factorial(unsigned long n)
// 聲明器結束, 'factorial' 從此點開始在作用域中
{
   return n < 2 ? 1 : n * factorial(n - 1); // 遞歸調用
}

2. 鏈接

鏈接指的是在其他作用域指代一個標識符(具名對象或函數)的能力。若在數個作用域中聲明有同一標識符的對象或函數,但不能從所有這些作用域指代它們,則會創建數個對象的實例。

C 變量具有3種鏈接屬性:

  • 外部鏈接

  • 內部鏈接

  • 無鏈接

2.1. 無鏈接

只能從其所在的作用域指代該標識符。

  • 所有函數參數

  • 所有非 extern 的塊作用域對象(包含聲明為 static 者)

2.2. 內部鏈接

能從當前翻譯單元的所有作用域指代該標識符。在一個翻譯單元內,帶內部鏈接的標識符的每個實例均表示相同的標識符或函數。 內部鏈接的標識符對于翻譯單元是唯一的。

  • 所有 static 文件作用域標識符(函數和對象)

2.3. 外部鏈接

能從整個程序的任何其他翻譯單元指代該標識符。具有外部鏈接的標識符的名稱指定相同的函數或數據對象,這與具有外部連接的相同名稱的任何其他聲明一樣。 這兩個聲明可以在同一個翻譯單元中,也可以在不同的翻譯單元中。 如果該對象或函數還具有全局生存期,則該對象或函數由整個程序共享。

  • 所有非 static 函數

  • 所有 extern 對象(除非之前聲明為 static )

  • 所有文件作用域的非 static 對象擁有此鏈接。

若同一標識符在同一翻譯單元中一同帶內部和外部鏈接出現,則行為未定義。這在使用試探性定義時有可能。

3. 存儲期

每個對象都有稱為存儲期的屬性,它限制對象的生存期。 C 中有四種存儲期:

  • 自動存儲期。

  • 靜態存儲期。

  • 線程存儲期。

  • 分配存儲期。

3.1. 自動存儲期

如果對象具有自動存儲期,那么它存在于,程序進入定義這些變量的塊到退出這個塊。進入聲明對象于其中的塊時分配其存儲,而在以任何方式( goto 、 return 、抵達結尾)退出該塊時解分配存儲。

一個例外是 VLA ;在執行聲明時而非塊入口分配其存儲,并在聲明離開作用域而非退出塊時解分配存儲。 (C99 起)若遞歸地進入塊,則對每個遞歸層進行新的分配。

以下變量具有自動存儲期:

  • 非 static 塊作用域對象

  • 所有函數參數

  • 用于塊作用域的復合字面量

3.2. 靜態存儲期

如果對象具有靜態存儲期,那么它在程序執行期間一直存在。存儲期是整個程序的執行過程,只在 main 函數之前初始化一次存儲于對象的值。

以下變量具有靜態存儲期:

  • 所有聲明為 static 對象

  • 所有帶內部或外部鏈接且不聲明為 _Thread_local (C11 起)的對象都擁有此存儲期。

3.3. 線程存儲期

存儲期是創建對象的線程的整個執行過程,在啟動線程時初始化存儲于對象的值。每個線程擁有其自身的相異對象。若執行訪問此對象的表達式的線程,不是執行其初始化的線程,則行為是實現定義的。

以下變量具有靜態存儲期:

  • 所有聲明為 _Thread_local 的對象(C11 起)

3.4. 分配存儲期

按照請求,用動態內存分配函數分配和解分配存儲。

感謝各位的閱讀,以上就是“C語言中的作用域、鏈接、存儲期的概念”的內容了,經過本文的學習后,相信大家對C語言中的作用域、鏈接、存儲期的概念這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

黎平县| 五寨县| 买车| 临夏县| 昌都县| 靖西县| 息烽县| 安阳市| 综艺| 平原县| 正安县| 收藏| 肥东县| 甘孜县| 无锡市| 长沙市| 边坝县| 宜良县| 和硕县| 社会| 山西省| 迁安市| 涡阳县| 武夷山市| 五华县| 栖霞市| 松原市| 翁牛特旗| 垦利县| 通化市| 铜鼓县| 辽宁省| 瑞丽市| 新兴县| 博客| 灌阳县| 罗城| 建瓯市| 宕昌县| 汤阴县| 九龙县|