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

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • 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.kjueaiud.com

    評論列表(網友評論僅供網友表達個人看法,并不表明本站同意其觀點或證實其描述)
    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>