c筆記06 編譯與作用域

2022-02-20 13:02:43 字數 2983 閱讀 9103

程式在計算機中的執行

符號表編譯器編譯流程參考資料

編譯四階段: (注意各個階段輸入輸出的檔案字尾變化)

(**)

四個階段總結:

elf(executable and linkable format,可執行和可鏈結格式)是一種物件檔案的格式,用於定義不同型別的物件檔案(object files)中都放了什麼東西、以及都以什麼樣的格式去放這些東西。

elf檔案分類:

因此,我們編譯鏈結c源程式的step3和step4得到的檔案(.o與.exe)都屬於elf檔案.

1.檔案結構: (**)

2.各主要部分簡介:

1.檔案結構: (**)

4.辨析:

1.計算機的記憶體分配:

計算機中的記憶體是分割槽來管理的,程式和程式之間的記憶體是獨立的,不能互相訪問,比如qq和瀏覽器分別所佔的記憶體區域是不能相互訪問的。而每個程式的記憶體也是分割槽管理的,乙個應用程式所佔的記憶體可以分為很多個區域,我們需要了解的主要有四個區域,通常叫記憶體四區.

(**)

(**)

說明:1.靜態區包括 .text(**段).rodata(常量段), .data(初始化非零的變數), .bss(未初始化/初始化為零的變數) 四個部分.

2.由上圖可以看出,.text, .rodata, .data 三部分的內容分別是拷貝的可執行檔案的對應部分內容

3.靜態區內儲存的值是c語言中用extern,static兩個儲存型別關鍵字修飾的變數以及一般的常量.c語言中共有四個儲存型別修飾關鍵字,分別是auto,register,static和extern:

在電腦科學中,符號表是一種用於語言翻譯器(例如編譯器和直譯器)中的資料結構。在符號表中,程式源**中的每個識別符號都和它的宣告或使用資訊繫結在一起,比如其資料型別、作用域以及記憶體位址。

符號表在編譯程式工作的過程中需要不斷收集、記錄和使用源程式中一些語法符號的型別和特徵等相關資訊。這些資訊一般以**形式儲存於系統中。如常數表、變數名錶、陣列名表、過程名錶、標號表等等,統稱為符號表。對於符號表組織、構造和管理方法的好壞會直接影響編譯系統的執行效率。

符號表的操作和進行操作的時機:

說明:1.當定義性出現時,查詢符號表是否有已經定義的與之衝突的同名符號,若無,新增符號表專案(填入名稱和資訊)

2.當使用性出現時,查詢符號表是否有相關專案,若有,訪問相關資訊,將使用性符號替換為記憶體位址,將相關語句翻譯為二進位制機器碼

3.當c語言某乙個塊中的語句或者函式呼叫執行完畢時,會退出塊作用域/函式作用域到上一級作用域,棧記憶體執行出棧操作,同時符號表相關的專案執行刪除操作.

4.當c語言中的變數被執行型別轉換之類的操作時,對應的專案進行修改操作.

1.說明:

(1)我們這裡所說的符號表指的是整個編譯過程中的符號管理及其組織形式,不是elf檔案中的用於重定位的"符號表節區",這一點必須首先指出來.

(2)變數作用域,本質上是由符號表這種資料結構的實現決定的.變數作用域是符號表組織與管理的外在表現.因此,用符號表的概念來理解作用域的種種特徵,從根源上把握,更能有所得.

(3)這裡,我們只是借助符號表的概念和相應的操作來幫助我們更好地理解和記憶c變數作用域的特徵,是假想的符號表系統,絕不是c符號表這種資料結構的具體實現.

我們假想的各種符號表:(後續鏈結屬性部分會增加"庫表")

定義性語句出現時:

使用性語句出現時:

**:

#include long int a = 1; //定義性語句,檔案域預設為extern型別,新增符號專案到檔案表

static float b = 2.0f; //定義性語句,新增符號專案到到檔案表

static char d = 'd'; //定義性語句,新增符號專案到到檔案表

int main()

fun(); //函式呼叫,建立函式fun的區域性表1-2

printf("這裡的d的值為 : %c",d); //使用性語句,在**系統中查詢符號d,在區域性表1中不存在,在檔案表中存在,並訪問值'd'

return 0;

}void fun()

}

執行結果:

符號表組織形式:

(1)關於命名空間,我們可以做出這樣的假象模型來幫助理解:

(2)因為任何符號定義都必然屬於四頁之一,查詢某一符號時,僅在其對應所屬的頁中查詢(整個符號表系統都僅在該頁中查詢該符號).

特別注意:

(1)鏈結過程是什麼?

總結:(2)鏈結過程對於符號表系統的影響,我們可以等價為如下模型:

說明:假設整個程式的執行需要依賴三個模組main.c(檔案1),mod1.c(檔案2)和mod2.c(檔案3)

鏈結過程就是將三個檔案各自的檔案作用域內定義/初始化的extern變數或函式拿出來,新組成乙個庫表(extern linkage表)(所有檔案共享乙個extern linkage表)

注意 : 庫表與檔案表的辨析

(1)定義external linkage,internal linkage變數相關問題測試

對於internal linkage

其他問題的測試

(2)引入鏈結屬性後的查詢規則可以歸納為如下的圖形:

說明:

1.當遇到extern符號宣告(引入符號)時,直接跳到檔案表中查詢該符號.

舉例說明:

分析:

第12行–宣告符號a

第13行–申明符號b

第14行–符號a使用性出現,進行符號表的查詢操作

第15行–符號b使用性出現,進行符號表查詢操作

C06 C語言 變數作用域

cpp view plain copy print include 全域性變數 作 用 域 當前檔案中從定義的這一行,到檔案結尾可用 生命週期 程式啟動到程式退出 intw 全域性變數有預設初始值,int型別預設初始值為0 void changew void change w inti void m...

c 作用域與可見域

c 作用域可分為5類 函式原型作用域 塊作用域 類作用域 檔案作用域和全域性 程式 作用域 跨檔案 1.函式原型作用域 最小的作用域 函式原型 int func int x 這是乙個函式宣告,函式形參x 的作用域就時所謂的函式原型作用域。2.塊作用域 一對大括號 內的一段程式,塊中宣告的識別符號作用...

9 26 預編譯與函式作用域問題

var bar 1 function foo bar foo 2 console.log bar 1預編譯 1,建立ao go 物件 2,找形參和變數宣告,把形參和變數宣告的名字作為ao的屬性名,值統一為undefined 3,形參實參相統一 4,函式宣告整體提公升,函式名作為ao屬性名 函式名有重...