ASP中数组用法—静态数组与动态数组

数组是具有相同名字的一组变量,数组中包含多个元素,由不同的下标值区分数组的各个元素。在VBScript中,数组有两种类型:静态数组和动态数组。

1、静态数组

静态数组在编译时开辟内存区,数组大小在运行时不可改变。

定义一个一维数组mmArray(3)

Dim mmArray(3)
mmArray(0)=1
mmArray(1)=3
mmArray(2)=5
mmArray(3)=7

其中mmArray是数组名,数组的下界为0,上界为3,数组元素从mmArray(0)到mmArray(3),共有4个元素。

也可以这样定义:

Dim MyArray
MyArray=Array(1,3,5,7)

n=10
Dim MyArray(n) '这样定义数组错误
定义静态数组,必须确定数组的上界,数组的上界不能为变量。因为静态数组是在编译时就开辟内存区的。

2、动态数组

动态数组是运行时大小可变的数组。当程序没运行时,动态数组不占内存,在程序运行时才开辟内存。

动态数组的定义一般分两步:

首先,用Dim语句声明一个括号内不包含下标的数组。
然后,在使用数组之前用ReDim语句根据实际需要重新定义下标值。

也可以用Redim语句直接定义数组。例如

ReDim a(2)
a(0)=1
a(1)=2
a(2)=3

ReDim语句的格式为:ReDim [Preserve] 变量(下标)

例如定义动态数组arrOrg
Dim arrOrg()
ReDim arrOrg(3)'在使用arrOrg之前,必须用ReDim语句分配实际的元素个数

可以用ReDim不断改变元素数目
Dim ArrOrg()
ReDim arrOrg(3)
ReDim arrOrg(5)
ReDim arrOrg(2)

每次执行ReDim语句时,存储在数组中的当前值都会全部丢失。如果希望改变数组大小而又不丢失数组中的数据,要使用关键字Preserve。

<%
ReDim a(2)
a(0)=1
a(1)=2
a(2)=3
ReDim Preserve a(1)
a(1)=9
For n=0 To UBound(a)
  Response.Write a(n) & "<br>"
Next
%>

ReDim Preserve arrOrg(Ubound(arrOrg)+1)
以上代码将数组扩大一个元素,现有元素值不变。Ubound()函数返回数组的上界。

注意:在用ReDim语句重新定义数组时,只能改变数组元素的个数,而不能改变数组的维数。

3、为什么要使用动态数组?

当程序没运行时,动态数组不占内存,在程序运行时才开辟内存。
动态数组是运行时大小可变的数组。
使用动态数组的优点是可以根据用户需要,有效利用存储空间。

如果你将某数据存入数组中,在不确定有多少个的情况下,使用动态数组将是非常好的办法。
比如,有1亿个数据。其中仅需100个符合要求的数据放到数组中。选用动态数组的方法将是明智的。

下例将1000内被54整除的数放到某数组中。

Dim MyArray()'声明一个括号内不包含下标的数组。
Dim i,j
j=0
For i=0 To 1000
  IF i Mod 54=0 Then
    ReDim Preserve MyArray(j)
    MyArray(j)=i
    j=j+1
  End IF
Next
'输出
Response.Write "1000内被54整除的数共有:" & Ubound(MyArray)+1 & "个,分别是:<p>"
For i=0 to Ubound(MyArray)
  Response.Write MyArray(i) & "<br>"
Next

这个例子说明,你不确定数组元素个数,但如果你直接定义Dim MyArray(1000),是极其愚蠢的。
一是这样定义将浪费存储空间。本例中实际需要的数组元素为19个
二是这样的代码执行效率低,造成资源浪费。比如对这元素重新排序。直接定义Dim MyArray(1000),将要遍历1000次。

 可扩展数组,程序代码如下

Dim MyArray()
For i=0 To 10
  ReDim Preserve MyArray(i)
  MyArray(i)=i
Next

 将一个字符串分割并返回分割结果的数组,程序代码如下

Dim tmpStr,MyArray
tmpStr="1,3,5,7,9"
MyArray=Split(tmpStr,",")
For N=0 to Ubound(MyArray)
  Response.Write MyArray(N) & "<br>"
Next


在Application和Session中使用数组(Session使用方法与Application相同)

以Application为例,将数组放到全局缓存中。程序代码如下

Application.Lock
Application("appArray")=MyArray
Application.Unlock

更改全局缓存数组时,必须先将全局缓存数组赋给变量,更改该变量某一元素值,然后再将该变量放到全局缓存中。而不能直接修改全局缓存某一元素而改变该元素的值。请分析以下例子:

<%
Dim MyArray,tmpArr
MyArray=array(1,2,3)
Application.Lock
Application("appArray")=MyArray
Application.Unlock
Response.Write Application("appArray")(1) & "<br>"
'以下方法是错误的
Application.Lock
Application("appArray")(1)=9
Application.Unlock
Response.Write Application("appArray")(1) & "<br>"
'以下方法是正确的
tmpArr=Application("appArray")
tmpArr(1)=9
Application.Lock
Application("appArray")=tmpArr
Application.Unlock
Response.Write Application("appArray")(1) & "<br>"
%>
结果是:
2
2
9

以下为实例分析:

05年给网吧写的一个“万象2003数据库操作”的程序,其中涉及到下面一个功能:
开卡上机操作:双击列表中的一台机器,在弹出的窗口中,输入押金(金额),点击确定。网吧中这样的开卡上机是很频繁的,那么我需要查看最近10条开卡记录。这段代码我是用缓存数组来解决的,代码如下:

下面这段代码是开卡后将数据写入缓存,为了描述方便,这里只记录卡号,将机器编号,金额,标准费率,开卡时间等省略掉

为了便于演示,卡号sCardID由系统生成

将以下代码保存为app.asp文件并执行,用户每次刷新页面(刷新间隔时间至少间隔一秒以上为宜)即可看到效果。

<%
'sCardID为当前卡号,这里就用现行时间代替
Dim i,k,sCardID
sCardID=Now
Dim CardLogArr(9)
IF IsArray(Application("CardLogArr")) Then
  For i=1 to 9
    CardLogArr(i)=Array(Application("CardLogArr")(i-1)(0)+1,Application("CardLogArr")(i-1)(1))
  next
  CardLogArr(0)=Array(1,sCardID)
Else
  CardLogArr(0)=Array(1,sCardID)
  For k=1 to 9
    CardLogArr(k)=Array(2,"-")
  Next
End IF
Application.Lock
Application("CardLogArr")=CardLogArr
Application.UnLock
%>
<!-- ######以下为显示部分###### -->
<table width=370 border=0>
  <tr bgcolor="#FAFAFA">
    <td width="15%" height="20" align=center>序号</td>
    <td width="20%">卡号</td>
  </tr>
  <%
  IF IsArray(Application("CardLogArr")) Then
    For i = 0 To 9
      Response.Write  "<tr>" & _
      "<td height=20 align=center>" & Application("CardLogArr")(i)(0) & "</td>" & _
      "<td>" & Application("CardLogArr")(i)(1) & "</td>" & _
      "</tr>"
    Next
  End IF
  %>
</table>

有用的数组函数

Ubound(arrayName)函数,这个函数是返回数组的下标,也就是数组最后一个元素的标记。
Lbound(arrayName)函数,这个函数是返回数组的上标,也就是数组第一个元素的标记。
Split(string,splitby)函数,返回基于0的一维数组,其中包含指定数目的子字符串。string是一个字符串,sqlitby是分隔符

进一步分析实例

如果说缓存是一种技术的话,那么数组就是一种算法。利用好数组,某些看似复杂的问题便迎刃而解。

例1:
<%
Dim CardLogArr(9),i
IF IsArray(Application("CardLogArr")) Then
  For i = 1 To 9
    CardLogArr(i) = Array(Application("CardLogArr")(i-1)(0) 1,Application("CardLogArr")(i-1)(1),Application("CardLogArr")(i-1)(2),Application("CardLogArr")(i-1)(3),Application("CardLogArr")(i-1)(4))
  Next
  CardLogArr(0) = Array(1,sCardID,Pwd,strMoney,UserName)
Else
  CardLogArr(0) = Array(1,sCardID,Pwd,strMoney,UserName)
  For i = 1 To 9
    CardLogArr(i) = Array(2,"-","-","-","-")
  Next
End IF
Application.Lock
Application("CardLogArr") = CardLogArr
Application.UnLock
%>


分析:
先定义变量,此时程序的目的只需要10个数据,故定义数组元素10个的固定数组。
然后判断Application("CardLogArr")是否为数组,第一次执行,Application("CardLogArr")为假,执行IF语句中的Else语句。
这时,将一数组赋给CardLogArr数组的第一个元素。即CardLogArr(0)。注意,此时CardLogArr(0)为数组CardLogArr的一个元素。而这个元素也是一个数组。
下面循环九次类似,目的是填充数据。OK,第一次执行后,此时的Application("CardLogArr")就是一个数组了。只要Application("CardLogArr")不丢失,以后执行IF语句中的Then语句。
那么Then语句中循环9次又是为什么呢?请看程序的功能就能清楚。
当10个数据填充满时,第11个数据该放哪?最终目的是,第11个数据应放在第一个。那么原第一个数据,就放到第二个,依此类推。当然原第10个数据就得丢掉。
现在,明白Then语句的功能了吗?

Ubound函数
功能:返回指定数组维数的最大可用下标。
语法:UBound(ArrayName[, dimension])
参数
ArrayName 必选项。数组变量名,遵循标准变量命名约定。
Dimension 可选项。指定返回哪一维上界的整数。1 表示第一维,2 表示第二维,以此类推。如果省略 dimension 参数,则默认值为 1。

说明
UBound 函数与 LBound 函数一起使用,用于确定数组的大小。使用 LBound 函数可以确定数组某一维的下界。所有维的下界均为 0。
举例:
Dim a(10)
Ubound(a) = 10

Dim A(100,3,4)
UBound(A,1) 100
UBound(A,2) 3
UBound(A,3) 4

Dim a(10)
a(0) = Array(0,1,2,3,4,5,6,7,8,9)

LBound 函数
功能:返回指定数组维的最小可用下标。
语法:LBound(ArrayName[, Dimension])

参数
ArrayName 数组变量名,遵循标准变量命名约定。
Dimension 指明要返回哪一维下界的整数。使用 1 表示第一维,2 表示第二维,以此类推。如果省略 dimension 参数,默认值为 1。

说明
LBound 函数与 UBound 函数共同使用以确定数组的大小。使用 UBound 函数可以找到数组某一维的上界。任一维的下界都是 0。


ReDim 语句
在过程级中声明动态数组变量并分配或重新分配存储空间。

ReDim [Preserve] varname(subscripts) [, varname(subscripts)] . . .

参数
Preserve 当更改现有数组最后一维的大小时保留数据。
varname 变量名,遵循标准变量命名约定。
subscripts 数组变量的维数,最多可以声明 60 维数组。subscripts 参数语法格式如下:
upper [,upper] . . .
数组的下界总是零。

说明
ReDim 语句通常用于指定或修改动态数组的大小,这些数组已用带有空括号的 Private、Public 或 Dim 语句(没有维数下标)正式声明过。可以重复使用 ReDim 语句更改数组维数和元素数目。
如果使用了 Preserve 关键字,就只能调整数组最后维的大小,并且不能改变数组的维数。
比如定义一个一维数组Dim a()
ReDim Preserve a(19)是可以的
Redim Preserve a(20)也是可以的
但Redim Preserve a(10)(4)这样是不行的。不能改变数组的维数。

例如,如果数组只有一维,就可以修改该数组的大小,因为该维是最后的也是仅有的一维。但是,如果数组有两个或更多维,就只能改变末维的大小并保留数组内容。

这个例子说明如何不擦掉该数组中存在的数据,而增加动态数组的终止维数。

ReDim X(10, 10, 10)
...
ReDim Preserve X(10, 10, 15) ... ok
ReDim Preserve X(10, 15, 15) ... error
小心 如果减小数组的大小,则将丢失被排除的元素中的数据。
变量初始化时,数值变量初始化为 0,字符串变量初始化为零长度字符串 ("")。在使用引用对象的变量前,必须使用 Set 语句将某个现有对象赋予该变量。在进行对象赋值以前,已声明的对象变量有特定值 Nothing。

开发“万象2003 WEB版”原因

04年,网吧还没有强制要求使用pubwin软件,一般网吧业主都是使用“万象2003”,我家也不例外。但后来,文化局要求网吧刷卡上网,并在检查时要检查刷卡记录。要知道一般网吧,如果按国家政策行事的话,估计连卖白菜的都不如了。这中间的一些情况在这就不说了,开过网吧的,或者懂得社会一些规则的,大家都懂。比如,文化局规定早上8点到晚上12点之间营业,这时间之外是不允许营业的,实际过程中,难免严格遵守这样的规定,这是一。其实,有的人由于各种原因没带身份证的,也就无法刷卡,但你网吧做生意不能赶他们走呀,如果所有网吧都一样也无话可说,但正是由于一些潜规则,有的网吧照收不误,所以,没带身份证的这批客户上网的问题要解决,这是其二。更重要的是,父母年龄偏大,软件操作对他们来说实在是麻烦,而且易忘。为了解决这个问题,才使我用WEB开发了这款应用程序。功能如下:

1、双击某台机器,填写金额,确定后,自动生成卡号,用户记住该卡号,即可在客户机登陆上网。上机非常方便。

2、用户下机时,双击电脑对应的机器号,即可结帐,并提示需要支付多少钱。下机非常方便。

3、可模拟生成刷卡信息,再也不用担心用卡号刷卡上网了。因为我是直接操作“万象2003”的数据库,绕过刷卡程序。

4、程序精确生成早上8点到晚上12点这之间的信息,并可精确定控制金额范围。(要知道,如果你网吧生意好,人家可会有想法的~~)

5、支持换机操作

6、支持中途加钱操作、商品销售管理。

7、可显示最近10人上机的机器号、卡号、金额等信息。因为有的用户上机前卡号丢失或忘记之类,网吧老板可以随时查看并告诉他们帐号。

8、设定多少分钟前提醒用户余额不足,语音提示并红色醒目显示。

基本上“万象2003”的实际功能,WEB版的都能操作,而且尽最大方便父母操作。

“万象2003数据库操作”源码下载:稍后上传

你可能感兴趣的:(数据库,session,application,存储,VBScript,asp)