分享
 
 
 

IL系列文章之三:Array in IL

王朝other·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

IL系列文章之三:

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语句相差无几了。

关于一维数组的用法基本上差不多了,下一次我可能要写一些关于多维数组和锯齿数组的内容。

待续……

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有