Flex3.0 RIA开发详解
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

第4章 数据类型

程序中使用的各种变量都应预先定义,即先定义,后使用。对变量的定义可以包括三个方面:数据类型,存储类型,作用域。ActionScript 3.0语言的数据类型包括基本数据类型和复杂数据类型。本章中先介绍基本数据类型中的整型、浮点型和字符型。其余类型在以后各章中陆续介绍。

数据类型表示了变量的性质、表示形式、占据存储空间等。在ActionScript 3.0语言中,数据类型可分为:基本数据类型和复杂数据类型两大类。

· 基本数据类型:其值不可以再分解为其他类型。基本数据类型是最基础的数据类型。

· 复杂数据类型:复杂数据类型根据已定义的一个或多个数据类型定义。也就是说,一个构造类型的值可以分解成若干个“成员”或“元素”。每个“成员”都是一个基本数据类型或者是一个复杂数据类型。在ActionScript 3.0语言中,常用的复杂数据类型,如Array、Object等都被定义在核心类中。

4.1 常量与变量

对于基本数据类型量,按其取值是否可改变又分为常量和变量两种。在程序执行过程中,其值不发生改变的量称为常量,其值可变的量称为变量。常量和变量可与数据类型结合起来,如整型常量、整型变量、实型常量、实型变量、字符串常量、字符串变量。在程序中常量是可以不经说明而直接引用的,而变量则必须先定义后使用。

4.1.1 直接常量和符号常量

常量按其表现形式又可分为直接常量和符号常量。

1.直接常量

直接常量是指不经声明、直接使用的常量。直接常量包括:

(1)整型常量:12、0、-3;

(2)实型常量:4.6、-1.23;

(3)字符串常量:“adf”、“b”。

2.符号常量

符号常量是用标识符代表一个常量。标识符是用来标识变量名、符号常量名、函数名、数组名、类型名、文件名的有效字符序列。符号常量在使用之前必须先定义,其语法为:

        const var标识符:数据类型=直接常量;

const关键字指明此为符号常量。一经定义,程序中所有出现该标识符的地方均以该常量值代之。习惯上符号常量的标识符用大写字母,变量标识符用小写字母。

以下代码中定义了一个符号常量。

        public const var PRICE:int=30;
        …
        total=num* PRICE;

符号常量与变量不同,它的值在其作用域内不能改变,也不能再被赋值。使用符号常量的好处是:含义清楚,能做到“一改全改”。

4.1.2 变量

程序中值可以改变的量称为变量。一个变量应该有一个名字,在内存中占据一定的存储单元。变量定义必须放在变量使用之前。变量名和变量值是两个不同的概念。变量名是指变量的名称,用以区别不同的变量。变量值是指变量中包含的值。变量定义的语法为:

        var变量1:数据类型,变量2:数据类型,…;

以下代码中定义了变量。

        var a:int,c:Number,d:String;

4.1.3 变量赋初值

变量赋初值是指变量定义时就赋值给变量,也称为变量初始化。变量赋初值的语法为:

         var变量1:数据类型=值1, 变量1:类型说明符=值1,…;

以下代码中新定义了变量,并为变量赋初值。

         var a:int=3;
        var b:int,c:int=5;
        var x:Number=3.2,y:Number=3,z:Number=0.75;
        var ch1:String="K",ch2:String="P";

4.1.4 局部变量和全局变量

局部变量也称为内部变量,是在函数内作定义说明的变量。其作用域仅限于函数内,离开该函数后再使用这种变量就是非法的。以下代码说明了局部变量的作用域。

        function f1(a:int):int  /*函数f1*/
        {
          var b:int,c:int;                 // a,b,c有效
          …
        }
        function f2(x:int):int  /*函数f2*/
        {
          var y:int,z:int;                 // x,y,z有效
          …
        }
        function main():void
        {
          var m:int,n:int;                 // m,n有效
          …
        }

在函数f1内定义了三个变量:a为形参,b、c为一般变量。在函数f1的范围内a、b、c有效,或者说a、b、c变量的作用域限于函数f1内。同理x、y、z的作用域限于函数f2内。m、n的作用域限于main函数内。关于局部变量的作用域还要说明以下几点:

1.主调函数中定义的变量也只能在主调函数中使用,不能在其他函数中使用。主调函数中也不能使用其他函数中定义的变量。因为主调函数也是一个函数,与其他函数是平行关系。

2.形参变量是属于被调函数的局部变量,实参变量是属于主调函数的局部变量。

3.允许在不同的函数中使用相同的变量名。但它们代表不同的对象,分配不同的单元,互不干扰,也不会发生混淆。

全局变量也称为外部变量,是在函数外部定义的变量。全局变量不属于哪一个函数,而属于一个源程序文件。用户可将源文件看成是一个对象类,那么函数可以看成是类的成员方法,定义于函数体外的变量可以看成是类的成员变量。有关对象和类的详细介绍,请参看后面章节。

以下代码在model.mxml文件中定义了一个全局变量a。

        //model.mxml
        private var a:int;
        public function t():void
        {
          a=10;
        }

本例中变量a是model文件中的成员,其作用域为model文件,这也包含了函数t。所以在函数t中可对变量a操作。

若用户想要在全局范围内,也就是整个工程范围内使用某个变量。推荐的做法是将该变量定义为一个类的成员变量。这样不同程序块都存取该成员变量的值就能起到全局调用的效果。

以下代码在model.as文件中定义一个可全局调用的类。

        //model.as
        package  com.a.model
        {
          public class model
          {
            public static var LineHeight : int = 20;
          }
        }

static表示变量以静态存储方式存储,这样使用model.LineHeight就能调用。否则要先对类model实例化,类的实例化语句可以为var m:model=new model()。

以下代码实现调用model类中的LineHeight变量。

        import  com.a.model  //引用类
        …
        model.LineHeight=1000;
        …

要使用类必须先引用类,方法是“import类所在的包”。

4.1.5 变量的存储方式

变量的存储方式按是否预先分配内存空间,可分为动态存储方式和静态存储方式。静态存储方式是指在程序运行期间分配固定的存储空间方式。动态存储方式是指在程序运行期间根据需要进行动态的分配存储空间方式。

用户存储空间可以分为三个部分:

1.程序区

2.静态存储区

3.动态存储区

全局变量全部存放在静态存储区,并在程序开始执行时给全局变量分配存储区,程序执行完毕就释放。在程序执行过程中,全局变量占据固定的存储单元,不动态地进行分配和释放存储空间。

动态存储区存放以下数据:

1.函数形式参数

2.自动变量(未加static声明的局部变量)

3.函数调用时的现场保护和返回地址

对于以上这些数据,在函数开始调用时分配动态存储空间,函数结束时释放这些空间。

有时用户希望函数中的局部变量的值在函数调用结束后仍保留原值,这时就需要指定局部变量为静态局部变量,使用关键字static进行声明。

以下代码说明定义了一个静态局部变量a。

        function f():void
        {
          static var a:int=9;
          trace(a.toString());
        }
        function main():void
        {
          trace(a.toString());
        }

本例中变量a为静态变量,在编译时就分配了固定的内存空间,程序运行期间都不释放。函数f调用完后会释放动态变量的内存空间,但不包括变量a,所以在函数main中变量a仍然能访问。

4.2 整型数据

整型数据用来存储整型量,如2、60等。整型数据可以是整型常量,也可以是整型变量。

4.2.1 整型常量

整型常量是指存储整型的常量。在ActionScript 3.0语言中,整型常量有十进制、八进制和十六进制三种。

1.十进制整型常量

十进制整型常量没有前缀,其数码为0~9。以下各数是合法的十进制整型常量。

        237
        -568
        65535
        1627

以下各数不是合法的十进制整型常量。

        023(不能有前导0)
        23D(含有非十进制数码)

编译器根据前缀来区分各种进制数。因此,在书写整型常量时,注意不要把前缀弄错。

2.八进制整型常量

八进制整型常量以0开头,即以0作为八进制数的前缀,数码取值为0~7。以下各数是合法的八进制数。

        015(十进制为13)
        0101(十进制为65)
        0177777(十进制为65535)

以下各数不是合法的八进制数。

        256(无前缀0)
        03A2(包含了非八进制数码)
        -0127(出现了负号)

3.十六进制整型常量

十六进制整型常量的前缀为0X或0x,其数码取值为0~9、A~F或a~f。以下各数是合法的十六进制整型常量。

        0X2A(十进制为42)
        0XA0(十进制为160)
        0XFFFF(十进制为65535)

以下各数不是合法的十六进制整型常量。

        5A(无前缀0X)
        0X3H(含有非十六进制数码)

4.2.2 整型变量

整型变量是指存储整型的变量。ActionScript 3.0中整型变量的数据类型可为int和uint,int和uint在内存中都以32位存储。int是有符号整型类型,uint是无符号整型类型。若用户想要存储一个负整数就不能使用uint类型,而应该使用int类型。

1.整型变量的分类

按照整型是否有符号,整型变量分为以下两类。

(1)有符号整型变量:类型说明符为int,在内存中占4个字节(32位)。

(2)无符号整型变量:类型说明符为uint,所占字节与有符号整型相同。

无符号类型量所占的内存空间字节数与有符号类型量相同,但由于省去了符号位,故不能表示负数。有符号整型变量的最大值为231,无符号整型变量的最大值为232。ActionScript 3.0中整型数据类型所配的内存字节数及数的表示范围如表4-1所示。

表4-1 整型数据类型的内存字节数及表示范围

2.整型变量的定义

整型变量定义的语法为:

        var标识符1:数据类型,标识符2:数据类型,...;

数据类型可以是int,也可以是uint。以下代码定义了整型变量。

        var a:int,b:int,c:int;                      //a,b,c为整型变量
        var p:uint,q:uint;                          //p,q为无符号整型变量

在整型变量定义时,应注意以下几点:

(1)一条语句中可定义多个变量,各变量名之间用逗号间隔。

(2)最后一个变量名之后以分号结束。

(3)变量定义必须放在变量使用之前。

以下代码中定义了整型变量,并使用变量进行了运算。

        var a:int,b:int,c:int,d;
        var uint:u;
        a=12;b=-24;u=10;
        c=a+u;d=b+u;

3.整型数据的溢出

由于实型数据在内存中以8字节(64位)存储,而整型数据在内存中以4字节(32位)存储,所以实型数据能表示的有效范围比整型大。若将实型数据赋值给整型数据,就有可能造成整型数据的溢出,所以用户应尽量避免实型数据赋值给整型数据的情况发生。

4.3 实型数据

实型数据用以存储实型量。ActionScript 3.0中实型数据类型只有一种:Number型。实型数据可以是实型常量,也可以是实型变量。

4.3.1 实型常量的表示方法

实型常量是指存储实型的常量。在ActionScript 3.0语言中,实型可用十进制形式或指数形式表示。

1.十进制形式

十进制形式由数码0~9和小数点组成。

以下各数为合法的十进制实型。

0.0、25.0、5.789、0.13、5.0、300.、-267.8230

2.指数形式

指数形式由十进制数,阶码标志“e”或“E”以及阶码(只能为整数,可以带符号)组成。

其一般形式为:

        a E n

其中,a为十进制数,n为十进制整数。相当于a×10n。

以下各数是合法的指数形式实型。

        2.1E5(等于2.1×105)
        3.7E-2(等于3.7×10-2)
        0.5E7(等于0.5×107)
        -2.8E-2(等于-2.8×10-2)

以下各数不是合法的实型。

        345(无小数点)
        E7(阶码标志E之前无数字)
        -5(无阶码标志)
        53.-E3((负号位置不对)
        2.7E (无阶码)

4.3.2 实型变量

实型变量是指存储实型的变量。

1.实型数据在内存中的存放形式

实型数据在内存中占8个字节(64位),且以指数形式存储。例如,实型“3.14159”在内存中的存放形式如图4-1所示。

图4-1 实型“3.14159”在内存中的存放形式

小数部分占的位数越多,数的有效数字就越多,精度越高。指数部分占的位数越多,则能表示的数值范围越大。

2.实型变量的定义

实型变量定义的语法如下所示:

        var标识符1:Number,标识符2:Number,...;

以下代码中定义了实型变量。

        var x:Number,y:Number;                          //(x,y为实型变量)

3.实型数据的舍入误差

由于实型变量是由有限的存储单元组成的,因此能提供的有效数字位总是有限的,这样有时会带来错误。例如,1.0/3×3的结果并不等于1。这种错误有时无法避免,好在实型数据类型为64位,有效数字位很长,从而有效地减小舍入误差带来的影响。对于一般的计算不会带来问题,但对于高精度的科学计算时会有一定的影响。

4.4 字符串数据

字符串数据存储字符串量,包括字符串常量和字符串变量。ActionScript 3.0中字符串数据类型为String型。

4.4.1 字符串常量

字符串常量是指存储字符串的常量,由一对双引号或单引号封闭的字符串序列。以下各字符串序列都是合法的字符串常量。

        "CHINA"
        "ActionScript program"
        "$12.5"
        '222'

4.4.2 转义字符

转义字符是一种特殊的字符常量,主要用来表示那些用一般字符不便于表示的控制代码。转义字符以反斜线"\"开头,后跟一个或几个字符。转义字符具有特定的含义,不同于字符原有的意义,故称“转义”字符。例如,“\n”就是一个转义字符,表示回车换行。常用的转义字符如表4-2所示。

表4-2 常用的转义字符及其含义

一般来说,任何一个字符都可用转义字符来表示。表中的\ddd和\xhh正是为此而提出的。ddd和xhh分别为八进制和十六进制的ASCII代码。例如,\101表示字母A,\102表示字母B,\134表示反斜线,\XOA表示换行等。

如下示例中使用了转义字符。

        var a:int,b:int,c:int;
        a=5; b=6; c=7;
        trace(a.toString()+b.toString()+c.toString()+"\t\de\rf\n");

4.4.3 字符串变量

字符串变量是指存储字符串的变量。字符串变量定义的语法如下所示:

        var标识符1:String,标识符2: String,...;

以下代码声明一个字符串变量s。

        var s:String;

4.5 各类型数据之间的转换

变量的数据类型是可以转换的。转换的方法有两种,一种是自动转换,一种是强制转换。

4.5.1 自动类型转换

自动转换发生在不同数据类型的量混合运算时,由编译器自动完成。自动转换遵循以下规则:

(1)若参与运算量的类型不同,则先转换成同一类型,然后进行运算。

(2)转换按数据长度增加的方向进行,以保证精度不降低。如int型和Number型运算时,先把int量转成Number型后再进行运算。

(3)在赋值运算中,赋值号两边量的数据类型不同时,赋值号右边量的类型将转换为左边量的类型。如果右边量的数据类型长度左边长时,将丢失一部分数据。这样会降低精度,丢失的部分按四舍五入向前舍入。

如下示例中各类型数据自动转化。

        var PI:Number=3.14159;
        var s:int,t:int=5;
        s=r*r*PI;
        trace("s="+s.toString());

· 本例程序中,PI为实型,s,r为整型。在执行s=r*r*PI语句时,r和PI都转换成Number型计算,结果也为Number型。但由于s为整型,故赋值结果仍为整型,舍去了小数部分。

4.5.2 强制类型转换

强制类型转换把表达式的运算结果强制转换成某种数据类型。其一般形式为:

        数据类型(表达式) 或 (数据类型)(表达式) 或 (表达式) as数据类型

以下代码强制转换Number型和int型。

        Number(a)  或a as Number或 (Number)(a)        //把a转换为实型
        int(x+y) 或 (x+y) as int或 (int)(x+y)         //把x+y的结果转换为整型

在使用强制转换时应注意以下问题:

(1)括号所处的位置要正确。例如,把(int)(x+y)写成(int)x+y,就变成了把x转换成int型之后再与y相加。

(2)无论是强制转换或是自动转换,都只是为了本次运算的需要而对变量的数据长度进行的临时性转换,而不改变数据说明时对该变量定义的类型。

以下代码说明强制转换只是临时性的转换。

        var f:Number=5.75;
        trace("(int)f="+((int)f).toString()+",f="+f.toString());

· 本例表明变量f虽然强制转为int型,但只在运算中起作用,是临时的。而变量f本身的类型并不改变。因此,(int)f的值为5,而f的值仍为5.75。

4.6 小结

ActionScript 3.0中的数据类型分为基本数据类型和复杂数据类型。本章详细介绍了整型、实型、字符串型。根据数据是否是变量或常量,基本数据又可分为整型常量、整型变量、实型常量、实型变量、字符串常量、字符串变量。

各数据类型间可进行转换。转换的方式有自动转换和强制转换两种。自动转换由编译器自动完成,强制转换由用户确定转换的方向。