系列文章之三: Array in IL 正如題目所言,這一節我們研究 IL 中的 array (數組)。我們將看到如何定義一個數組,如何查詢數組元數,使用 for 語句" name="description" />

IL系列文章之三:ArrayinIL

發表于:2007-05-25來源:作者:點擊數: 標簽:ArrayinIL之三文章宋體系列
IL MI LY: 宋體; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">系列文章之三: Array in IL 正如題目所言,這一節我們研究 IL 中的 array (數組)。我們將看到如何定義一個數組,如何查詢數組元數,使用 for 語句

ILMILY: 宋體; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">系列文章之三:

Array in IL

         正如題目所言,這一節我們研究IL中的array(數組)。我們將看到如何定義一個數組,如何查詢數組元數,使用for語句和foreach語句的異同。

         先來看看我用C#寫的一段程序:

 

using System;

class array1

{

         public static void Main ()

         {

                   int [] number;

                   number = new int [6];

                   for(int i = 0;  i < 6; i++)

                   {

                            number[i] = i * i;

                   }

                   foreach(int num in number)

                   {

                            Console.WriteLine(num.ToString());

                   }

         }

}

         這段程序相信大家都看得懂吧(如果看不懂的話最好就別往下看了)。在這段程序中我們看到了C#如何定義一個數組,這和我們以前在C/C++使用的方法不太相同。C#使用了如下兩句,來定義一個數組:

                   int [] number;

                   number = new int [6];

而在C/C++中使用一句

                   int number[6];

就夠了。產生這種差異的緣由何在呢?別慌,馬上就能看到。還有一點,C#中有foreach語句,這個語句與傳統的for語句比較起來又如何呢?看下面,是上面的程序用ildasm反編譯產生的(為了大家能看得更明白,我對反編譯產生的il程序做了一些修改)。

 

.assembly array1{}

 

.class private auto ansi beforefieldinit array1

       extends [mscorlib]System.Object

{

  .method public static void  Main() cil managed

  {

    .entrypoint

    .maxstack  4

    .locals init (int32[] V_0,//int[] number

             int32 V_1,//i

             int32 V_2,

             int32[] V_3,//a pointer of array

             int32 V_4)

                   ldc.i4.6//load int32 const 6(length of the array) onto the stack

                   newarr     [mscorlib]System.Int32//number = new int[6],

//length of the array must be loaded onto the stack before

                   stloc.0//number

                   ldc.i4.0//load first local(V_0) onto the stack

                   stloc.1//int i = 0

                   br.s       loopfor      //goto “loopfor”, “loopfor” is only a lable

         //startfor is a lable too

    startfor:  ldloc.0//number

                   ldloc.1//load V_1 onto the stack

                   ldloc.1

                   ldloc.1

                   mul//multiply

                   stelem.i4//i = i * i

                   ldloc.1

                   ldc.i4.1

                   add

                   stloc.1//i = i + 1

    loopfor:  ldloc.1

                   ldc.i4.6

                   blt.s      startfor//if i(V_1) less than 6, goto “startfor”

 

                   ldloc.0

                   stloc.3//look it!!

                   ldc.i4.0

                   stloc.s    V_4

                   br.s       loopforeach

 

    startforeach:  ldloc.3

                   ldloc.s    V_4

                   ldelem.i4

                   stloc.2

                   ldloca.s   V_2//load address of local_2(V_3)

                   call       instance string [mscorlib]System.Int32::ToString()

                            //cast int to a new string instance and stord it into local_2

                   call       void [mscorlib]System.Console::WriteLine(string)//print it

                   ldloc.s    V_4

                   ldc.i4.1

                   add

                   stloc.s    V_4

    loopforeach:  ldloc.s    V_4//index of V_3[]

                   ldloc.3

                   ldlen

                   conv.i4//conver len to int32

                   blt.s      startforeach

 

                   ret//return, must exist, or else the program will stop here

  } // end of method array1::Main

}

         分析這段程序我們可以看出來定義一個數組的三個步驟,不知你看出了沒有?

1.   定義一個數組指針,int32[] V_0

2.   將數組長度移到堆棧頂,ldc.i4.6

3.   為其分配空間,newarr [mscorlib]System.Int32

這下明白了C#中的數組為什么要通過兩個步驟來定義了吧。其原因就在于在C#中我們是把數組放到托管堆上,而在C++中使用(int number[6])數組不是放在堆上的。IL能做C#不能做到的事情,如數組的下界可以不從0開始等(下次有機會寫個例子J)。

為數組元素賦值,需要四個步驟,

1.     將數組指針移到棧頂,ldloc.0

2.     將數組元素的Index移到棧頂,ldloc.1

3.     將要賦的值移到棧頂(這里是同過mul運算實現),

4.     將值從棧頂移出,賦給元素,stelem.i4

選擇數組元素的方法和上面差不多,只是用不著第3步了,第4步的st換成ld。

對于for語句和foreach語句其實沒有本質的差異。使用foreach語句時,IL會預先產生一個數組指針int32[] V_3,在遍歷數組時再把已知數組的指針賦給這個指針,以后的指令就和for語句相差無幾了。

        關于一維數組的用法基本上差不多了,下一次我可能要寫一些關于多維數組和鋸齒數組的內容。

        待續……

原文轉自:http://www.anti-gravitydesign.com

評論列表(網友評論僅供網友表達個人看法,并不表明本站同意其觀點或證實其描述)
国产97人人超碰caoprom_尤物国产在线一区手机播放_精品国产一区二区三_色天使久久综合给合久久97