c
語言中的
for語句使用最為靈活,不僅可以用於迴圈次數已經確定的情況,而且可以用於迴圈次數不確定而只給出迴圈結束條件的情況。因此,這個語句的使用頻率是最高的,當然它的處理情況比上面兩種迴圈要複雜一些。它的形式如下:
for(
表示式1;
表示式2;
表示式3) 語句
1 它的執行過程是先求解表示式
1的值,然後再計算表示式
2的值。如果其值為真,就執行語句
1,然後再執行表示式
3。如果其值為假,就直接跳出迴圈不再執行語句
1和表示式
3。如果在
c++裡還會有作用域的範圍不同樣的。
下面就是
lcc處理
for迴圈的**:
#023 case for:
#024 forstmt(genlabel(4), swp, lev + 1);
#025 break; 第
24行是呼叫函式
forstmt
來處理for
語句。
而函式forstmt
的**如下:
#001 static void forstmt(int lab, swtch swp, int lev)
#002 ', 0 };
#031 test(')', stop);
#032 }
#033 第
26行是判斷第三個表示式是否存在,如果存在就呼叫函式
texpr
來處理第三個表示式。如果不存在,就需要處理右括號了。
#034 if (e2)
#035
#040 第
34行是判斷第二個表示式是否存在,如果存在就查詢迴圈是否需要執行一次,如果不需要執行就跳到第三個標號。
#041 definelab(lab);
#042 statement(lab, swp, lev);
#043
#044 definelab(lab + 1);
#045 definept(&pt3); 第
41行是定義第乙個標號。 第
42行是處理迴圈體的語句1。
第44行是定義第二個標號。
#046 if (e3)
#047 walk(e3, 0, 0);
#048
#049 if (e2)
#050
#056 else
#057
#061
#062 if (findlabel(lab + 2)->ref)
#063 definelab(lab + 2);
#064
#065 } 第
46行和第
47行是計算第三個表示式。 第第
49行到第
55行是處理第二個表示式,如果第二個表示式值為真就需要跳轉到第乙個標號執行語句。 第
52行是生成第
4個標號,由於不能判斷是否需要執行一次時,就需要計算表示式的值,才能決定。 第
57行到第
60行是沒有第二個表示式,所以無條件跳到第乙個標號那裡繼續執行語句1。
通過執行上面的**就會生成下面形式的彙編**:
表示式1
標號1:語句1 標號
2:表示式3
標號4:如果表示式
2值不等於
0 就跳到標號1
標號3:
上面的優化**,如果當常量判斷表示式
2要執行一次時,就直接從標號
1開始執行了,不用跳到標號
4作一次判斷。如果不是常量判斷出來的,就需要多乙個跳轉,先跳到標號
4那裡執行,作表示式
2的計算再作出選擇。
LCC編譯器的源程式分析 12 13
語法分析是比較複雜的處理,下面再來分析乙個例子,它的 如下 typedef unsigned short wchar t typedef wchar t wint t 第一句語句在lcc裡的處理,前面已經解釋清楚,主要生成wchar t儲存符號表裡,並且記錄這個id的型別屬性。那麼第二句是怎麼樣通過...
LCC編譯器的源程式分析 18 19
lcc編譯器的源程式分析 19 全域性函式的定義 函式定義funcdefn處理裡,已經準備好呼叫引數和引數返回,接著就是呼叫全域性函式宣告來處理。如下面的 132 宣告函式。133 cfunc dclglobal sclass,id,ty,pt 134 上面的 是處理函式全域性定義。現在就去就分析d...
LCC編譯器的源程式分析 20 復合語句
在 c語言裡,有一種語句叫做復合語句。它是由 把一些語句括起來的,如下面的例子 在lcc 裡處理這樣的復合語句的函式是 compound 它在上面函式定義函式 funcdefn 是這樣呼叫的 150labels table null,labels 151stmtlabs table null,lab...