系列文章之四: Array in IL ( 續 ) 上次談了 Array 中的一維數組,這次要談的是多維數組和鋸齒形數組。 多維數組其實就是數組的數組(好像不如 Arra" 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 ( 續 ) 上次談了 Array 中的一維數組,這次要談的是多維數組和鋸齒形數組。 多維數組其實就是數組的數組(好像不如 Arra

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

    Array in IL ()

    上次談了Array中的一維數組,這次要談的是多維數組和鋸齒形數組。

    多維數組其實就是數組的數組(好像不如Array of Array那么好聽)。上次說過我們用IL可以做一些在C#中不可能做到的事情,比如定義一個數組,它的下界不是從0開始的而是任意一個值。閑話休說,先來看個二維數組的例子。

    .assembly matrix{}

    //it is a matrix with 2 dimensions

    //dim1 from 3 to 5 and dim2 from 4 to 5

    //the matrix like this could not be defined in C#

    .class private auto ansi beforefieldinit matrix

           extends [mscorlib]System.Object

    {

      .method public hidebysig static void  Main() cil managed

      {

        .entrypoint

        .maxstack  4

        .locals init (int32[,] matrix)

             ldc.i4.3// load the lower bound for dimension 1

        ldc.i4.5// load the upper bound for dim 1

             ldc.i4.4// load the lower bound for dim 2

        ldc.i4.5// load the upper bound for dim 2

        newobj     instance void int32[,]::.ctor(int32,int32,int32,int32)

                       // ctor means constructor

        stloc matrix

        ldloc matrix

        ldc.i4.3// index of 1st dimension

        ldc.i4.4// index of 2nd dimension

        ldc.i4.s   34// the value

        call       instance void int32[,]::Set(int32,int32,int32)//matrix[3,4] = 34

             //a section of error code "matrix[1,1] = 11"

             //------------------------------------------------------------------

             //ldloc matrix

             //ldc.i4.1

             //ldc.i4.1

             //ldc.i4.s 11

             //call           instance void int32[,]::Set(int32,int32,int32)

             //------------------------------------------------------------------

             //it will course an exception "System.IndexOutOfRangeException"

        ldloc matrix

        ldc.i4.3

        ldc.i4.4

        call       instance int32& int32[,]::Address(int32,int32)

                       //generate a 32 bit integer instance of matrix element matrix[3,4]

                       //in order to conver it to string for output

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

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

        ret

      }

    }

    在這個例子中既有二維數組的普通使用方法,又有下界不為0的定義方法。其實我也沒有太多好說的了,我要說的大多都寫在注釋里了。多維數組的定義比一維數組要復雜一些,需要調用專門的構造函數“void int32[,]::.ctor(int32,int32,int32,int32)”來進行構造。還有一點要注意的了,這里使用的是“newobj”,而不是上次所用的“newarr”。就我們一般的二維數組而言下界都是從0開始的,所以實際上我最常用的是這樣的一個構造函數“void int32[0…,0…]::.ctor(int32,int32)”,在這個構造函數中,我們只需要提供兩個維的上就夠了,下界默認從0開始。例子中間有一段注釋掉的代碼,我利用這段代碼來檢驗IL中定義的非0下界數組是不是真的不從0開始。大家可以試一下這段代碼,它一旦運行起來的話系統就會拋出一個"System.IndexOutOfRangeException",看來IL沒用騙我們,的確是從我們定義的下界開始的。

    總的看來雖然二維數組的定義要比一維數組復雜一些,但還是比較規整的。接下來我們要看的就是不太規整的東東了——鋸齒數組(Jagged Array)。寫文章離不了例子,我還是只有從例子開始。

    //jagged.cs

    class jagged

    {

             public static void Main()

             {

                       int[][] jagged;

                       jagged = new int[3][];

                       jagged[0] = new int[1];

                       jagged[1] = new int[2];

                       jagged[2] = jagged[1];

                       jagged[1][1] = 11;

                       System.Console.WriteLine(jagged[2][1].ToString());

             }

    }

    通過它的輸出可以看出這個鋸齒數組的第3維(jagged[2])和第2維(jagged[1])其實是同一個一維數組,對第2維的處理就是對第3維的處理。

    有些朋友可能已經看出來了,我的第一個例子——matrix,其實也是鋸齒形的,但我們并不稱其為鋸齒數組。為什么呢?反編譯上面的代碼,看看真正的鋸齒數組是怎么實現的。(和以前一樣,為了大家看這方便,我對反編譯出來的代碼作了一些修改。)

    .assembly jagged{}

    .class private auto ansi beforefieldinit jagged

           extends [mscorlib]System.Object

    {

               .method public hidebysig static void  Main() cil managed

               {

                                .entrypoint

                                .maxstack  4

                                .locals init (int32[][] jagged)

                                ldc.i4.3

                                newarr     int32[]// the jagged array has 3 dimensions

                                         //create a array of int pointer

                                stloc jagged// jagged = new int[3][];

                                ldloc jagged

                                ldc.i4.0//dimension

                                ldc.i4.1//length of dimension

                                newarr     [mscorlib]System.Int32//jagged[0] = new int[1];

                                stelem.ref// set the int[] by reference

                                ldloc jagged

                                ldc.i4.1

                                ldc.i4.2

                                newarr     [mscorlib]System.Int32

                                stelem.ref// it is like the first dimension

                                ldloc jagged

                                ldc.i4.2

                                //{load pionter of 2nd dimension by reference

                                ldloc jagged

                                ldc.i4.1

                                ldelem.ref

                                //}

                                stelem.ref// set the pointer of 3rd dimension

                                ldloc jagged

                                ldc.i4.1

                                ldelem.ref// load jagged[1][]

                                ldc.i4.1// jagged[1][1]

                                ldc.i4.s   11

                                stelem.i4// jagged[1][1] = 11

                                ldloc jagged

                                ldc.i4.2

                                ldelem.ref

                                ldc.i4.1

                                ldelema    [mscorlib]System.Int32

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

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

                                ret

               }

    }

    在鋸齒形數組中,我們首先定義的是一個三行一列的Pointer數組,每個Pointer指向一個Array的實例(當然有可以沒有)。它的處理方式和一維數組很相似(本質上就是一維數組的集合),都是用的IL基本指令ldelemstelem,不過這里是按引用的方式傳遞的。鋸齒數組的結構如同下圖所示,

    鋸齒形數組有一列指針數組,在對數組的操作時起到作用(我想主要是對數組元數的尋址)。C#語言在實現鋸齒形數組的時候隱藏了這一列Pointer的細節,用戶在使用的時候感覺不到它的存在。當然這是在為用戶著想,使用戶不會在使用鋸齒形數組的時候將心思局限于某些技術細節之中。到這里為止,大家對數組也是很明了了吧,我也就到此為止了。

    原文轉自: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>