c語言的程式環境主要分為翻譯環境和執行環境。其中翻譯環境是將源**轉換為可執行的機器指令。
2.翻譯環境又分為編譯和鏈結兩個部分。
1.1編譯又分為三個小部分
*預編譯(預處理):a.包含標頭檔案b.注釋刪除。c.#define定義的常量的替換。d.#define定義的巨集的替換。在gcc(linuxs環境下的c語言編譯器)使用命令gcc test.c -e —-與編譯後停止- 可以檢視預編譯後的內容(test.i)
> *編譯(源**——彙編**):a.語法分析。b.詞法分析。c.語義分析。d.符號彙總。
gcc test.i -s 編譯後停止 生成(test.s)
*彙編(彙編指令——機器指令):a.形成符號表。3.linuxs系統中的常用命令gcc test.s -c 彙編後停止 生成(test.o)目標檔案 elf格式,用命令readelf-s可以顯示符號列表
1.2鏈結
*a.符號表合併。b.符號表重定位。c.合併段表。
a.ls:列出當錢資料夾下的檔案
b.cd+檔名:可以進入目標資料夾
c.pwd:顯示工作路徑
預定符號
file// 進行編譯的原始檔
line//檔案編譯的行號
date// 檔案編譯的日期
time// 檔案編譯的時間
stdc// 如果編譯遵循asci c,其值為一,否則未定義。
這些定義符號都是內建的。
printf("file:s% line:d%\n",__file__,__line__);
2.#define定義的識別符號
//語法
#define name stuff
//如果定義的stuff過長都是,可以換行寫,除最後一行外,每一行的最後加上\(續行符)
//define定義識別符號時,結尾不建議加上;,避免會出現問題
//如下面的場景
#define
max1000;
#define
max1000
if(condition)
max=
max;
else
max=
0;//這裡會出現語法錯誤
3.define定義巨集
//巨集的申明方式
#define name(parament-list) stuff
//其中parament-list是由乙個都好隔開的符號表,可能在stuff中出現
//注意:引數列表的左括號必須與name緊鄰,否則引數列表會被解釋為stuff的一部分
//用於數值表示式的求職時的巨集定義都應該加上括號,避免在預算時的運算優先順序導致的不可預料的作用。
//例如
#define square(x) x*x
int a = 5;
printf("%d\n",square(a+1));
//不仔細看以為會列印36,但實際列印的是11.
實際上,在預編譯是這段**被替換為
printf("%d\n",a+1*a+1);
實際計算時由於優先順序會先計算1*a
因此該巨集的證正確定義方式為:
#define square(x) (x)*(x)
int a = 5;
printf("%d\n"square(a+1));
這是就會輸出36了
看完上面這例子之後,我們再來看乙個巨集,這個定義是否有什莫問題嗎?
#define double(x) (x)+(x)
int a = 5;
printf("d%\n"
10*double(a));
這個程式輸出的是100|55.
4.#和##
4.1——#
printf("d%","the value of"
#value"is""formate""\n",value);
int i = 10;
printf("%d",i+3);
這個程式會輸出:the value of i+3
is13
//使用#可以把乙個巨集引數程式設計對應的字串。
4.2——##
##可以把位於它兩邊的符號合成乙個符號。它允許巨集定義從分離的文字片段建立識別符號。
#define add_to_sum(num,value)\
sum##num += vilue;
add_to_sum(5,10);//作用給sum5增加10.
5,巨集和函式
//代有***的巨集引數
#define max(x,y) ((x>(y)) ? (x) : (y)
int a = 5;
int b = 8;
z = max(a++,y++);
printf("%d
%d%d",a ,b,z);
這個程式輸出結果為6,9,10.
該程式預編譯後的結果為:
z = ((a++) > (b++)) ? (a++) :(b++)
程式環境與預處理
程式環境 我們知道計算機是沒有辦法認識除了二進位制之外的語言,所以我們現在編寫出來的 想要讓計算機認識並實現,就必須把它轉換成二進位制語言.我們把這個過程叫做程式的翻譯過程.程式的翻譯過程又分為四個階段 預處理 在這個階段,它只做了四個工作 巨集替換,去注釋,標頭檔案展開和條件編譯.編譯 將c語言編...
程式環境和預處理
程式環境 1.翻譯環境 編譯 鏈結 先將組成乙個程式的每個原始檔通過編譯轉換成目標檔案,再將每個目標檔案通過編譯器 在一起鏈結成乙個 可執行檔案 翻譯過程 1.預處理 c c 標頭檔案展開,巨集替換,去注釋,條件編譯 2.編譯 c 彙編 3.彙編 彙編 二進位制 4.鏈結 常見的鏈結方式 2.執行環...
程式環境和預處理
一 程式的編譯環境和執行環境 1 每乙個程式的原始檔都會通過編譯過程轉換為相應的目標 2 每乙個目標 由鏈結器 在一起,形成乙個單一的可執行程式。3 鏈結器同時也會引入標準庫函式中被程式任意引用的庫函式,而且還可以搜尋程式設計師的個人程式庫,將需要的函式也鏈結到程式之中。編譯分為幾個階段組成 程式執...