当前位置:编程学习 > wap >>

第四章 WML Script语法基础

答案:wml script是属于无限应用协议wap应用层的一部分,使用它可以向wml卡片组和卡片中添加客户端的处理逻辑,目前最新的版本是1.1版。wml script1.1是在欧洲计算机制造商协议会制定的ecmascript脚本语言的基础上,经过修改和优化而指定的。它能够更好的支持诸如移动电话类的乍带宽通信设备,在wml编程中使用wml script可以有效的增强客户端应用的灵活性,而且,我们也可以把wml script作为一个工具使用,开发出功能强大的wap网络应用和无限网页。本章我们将详细讲解wml script1.1编程的基础预法制时,如基本规则、变量预数据类型、操作赋予表达式等。为了叙述上的简便,以后我们将“wml script1.1”简称“wmlscript ”。
  4.1 wml 程序中调用wml script函数
  经过前两章的学习,熟悉c语言的读者可能会认识到,wml 的函数功能、逻辑运算功能等都是十分有限的。而wmlscript提供了丰富的函数功能,我们在wap应用开发可以使用wmlscript来增强wml编程。因此,wmlscript成为扩展wml编程能力的主要开发工具。
  4.2 wmlscript的主要优点及其字节码解释器
  wmlscript具有一套定义好的字节码和一个解释器参考结构。无线网络传输中wmlscript的数据均以二进制格式进行传输,所以,用户可以使用乍带宽通信信道,从而能够保持客户端手机只需要最小限度的内存。ecmascript修改后得到的wmlscript能够更快、更小、更容易的编译程序为字节码形式。所有这些特点,是wmlscript具备了wml所不能具备的很多优点和功能。
  4.2.1 使用wmlscript的主要优点
  wmlscript的设计宗旨是为wmlscript系统提供一般的脚本处理能力,使用wmlscript我们可以进一步补充基于xml的wml语言的编程功能,开发针对乍带宽的网络应用及内容,如文本、图像、选择列表等,我们可以使用简单的格式编写出更灵活和更具可读性的用户界面。wmlscript具备的wml所不能具备的优点和功能,主要包括如下几个方面:(1)检查用户输入的合法性:
  (2)扩展用户浏览器的功能,比如允许程序员开发手机的电话呼叫、发送短信息、存储电话号码、管理电话簿或sim卡等;
  (3)生成用户端的确认、提示、警告信息或操作对话框,并使之快速显示在浏览器上;
  (4)在用户浏览器的更改后,能够对浏览器端的软件和参数进行扩展与配置;
  (5)最大程度克服客户端的乍带宽通信连接限制,并提供丰富的程序功能;
  (6)补充wml并使之实现针对微型移动终端设备的多种服务,如支持高级用户界面、增加客户端智能型、提供用户浏览器外围功能的访问能力,以及在服务器与客户端浏览传输数据是减少带宽占用等。
  4.2.2 wmlscript的字节码解释器
  在wmlscript的字节码解释器解释之前,wmlscript语言编写的文本格式的程序将被首先编译为二进制格式的代码。编译时,编译器通常先将wmlscript程序分成若干个编辑单位,每个单位的程序都包含一定数量的语句行和wmlscript函数,然后,wmlscript的编译器将按照这些编译单位,逐一将wmlscript程序作为输入内容,而把对应的字节码作为输出内容。当用户通过wap手机调用wmlscript程序时,编译器的编码功能即被激活、执行。
  4.3 wmlscript基本规则
  wmlscript在许多基本规则方面沿用了wml的做法。不过,由于wmlscript是以c语言为蓝本而指定的,所以它的语法特征和c语言非常相像。如果大家对c语言比较熟悉,那么学习和掌握这部分内容应当是比较容易的。
  4.3.1 wmlscript与url
  与wml一样,wmlscript也沿用了www和html访问资源的url、http等规范,并扩大了url使用的范围。在wmlscript中,不仅超链接、文件路径即文件名可以作为url处理,外部函数、访问控制信息等也可以作为url处理。
  为此,wmlscript采用了wml的变通方法,即改进html命名资源为值的方式,采用程序段锚点(fragment anchor)的形式来处理资源定位。程序段锚点根据文档url规则进行定义,并按照程序段标识符前加井字号(#)的方式书写。使用程序段锚点,wmlscript程序可以在wmlscript编译单位内可任意指定的函数,并可在调用该函数的同时传递所需的参数。
  4.3.2 词法结构
  wmlscript编程中的词法结构并不复杂,我们下面就从大小写敏感、空格、换行、注释即保留字等方面讲解相关的具体规则。
  (1)内容类型。wmlscript的内容类型主要针对文件形式和二进制形式两种情况,类型结构可以在服务器端进行指定,具体形式为:
  文本形式:text/vnd.wap.wmlscript;
  二进制形式:application/vnd.wap.wmlscriptc。
  具体指定方法我们在第4章已经介绍过,这里不再重述。
  (2)大小写敏感。wmlscript1.1是一种大小写敏感的脚本语言。它所设计的各种关键字、变量和函数名都必须合理的使用大小写。
  (3)空格和换行。一般情况下,wmlscript程序值形式将忽略所有的空格、制表符合换行符等。但如果把这些特殊字符通过代码进行表述,或者作为字符串进行处理时,wmlscript将不再忽略它们。了如,字符串"oct 28,2001"中含有空格,该空格在执行时就不会被忽略,它与不含空格的字符串"oct28,2001"是不同的。
  (4)注释。与wml编程一样,在wmlscript脚本程序中也可以加入注释内容。注释内容不被程序执行,且注释不能嵌套。wmlscript的注释方法有两种:
  其一,行注释。即使用双斜行号(//)引导以一行内容,这一行内容全部作为注释内容。如:
  //这是以行注释,由双斜杠号开始到结束都是注释。
  其二,块选择。即以符号“/*”开始,而以符号“/*”结束的期间所有内容都是注释内容。如:
  /*这就是块注释,加在中间的内容就是注释内容*/
  (5)数据类型与直接编码。wmlscript允许将4种类型的数据直接编码并可嵌套并可嵌如在程序之中。直接编码的4中数据类型为:整数、浮点数、字符串和布尔值。另外,“无效性”值也可直接编码”1. 整数。当以十进制、十六进制或八进制方式使用整数时,可对这类整数进行直接编码。
  编程序时,十进制的数字均不以0开头,只包含0~9的数值串;十六进制的数据以ox或者ox开头,只包含0~9、a~f或者a~f的字符串;八进制的数均以0开头,只包含0~7的数字串。
  2.浮点数。浮点数通常定义为含有小数点的数字,可以包含小数和指数部分。浮点数的形式较多,可以使十进制的整数或浮点数,可以是分

[page_break] 数,也可以是指数;但一个浮点数必须至少有一个数。
  指数是以e或e开头,后面跟着一个整数。指数是以10为底幂。例如:e0时10的零次幂,例如:e0时10的另次幂,e-2时10的负2次幂集等于0.01。指数可以带符号,正好(+)或者减号(-),它们分别代表是正指数和负指数。
  3.字符串。字符串是指定义在成对的双引号("")或单引号(‘’)之间的内容。
  由于wmlscript只允许使用成对的双引号或但引号来定义字符串,所以程序中使用一个单引号或一个双引号时就会出现编译错误。
  考虑到有些特殊字符不能在字符串中直接显现出来,所以wmlscript提供了转译序列来表示这些特殊字符。
  4.布尔型。它只是ture和false两个数值,用于表示wmlscript中的“真值”或“假值”。布尔型数据可参与异、或等运算,具体规则我们后面介绍。
  5.无效型。也称为“空类型”,它是wmlscript支持的一个表示无效值的量,以invalid表示。该两与c语言中的null类似。
  4.保留字。wmlscript中定义有一个保留字集合,含有一些表示特殊意义的单词这些次不能另外定义,也不能最为其他标识符。wmlscript中的保留字如下:
  acces http agent if break isvalid continue meta header
  div name div= path domain return else typeof while
  equiv url extern use for user function var
  另外,wmlscript还为将来的版本预留了一些保留字,主要有:
  case finally catch import class private const public debugger
  sizeof default struct do super enum switch export throw
  extends try
  wmlscript还有一些没有使用的保留字:
  delete null in this lib void new with
  7.标识符。wmlscript的标识符可以指定或命名3种元素:变量、函数和标注。标识符不能以数字开头,但能一段下划线(-)开头,而且,标识符不能是wmlscript的保留字。例如,timeofday、speed 、quality、home_address、_myname、__、varo等都是合法的标识符;而以数字或非短下划线的特殊符号开头的字串,以及保留字等都属于不合法的标志赋,如while、for、if、my~name、$sys、123、3piecs、take.this等。
  由于wmlscript是严格区分大小写的,所以字母相同但大小写不同的标识符不是同一个标识,例如,work和work就是不同的标识符。
  8.名称空间。wmlscript提供了比较自由的名称空间,同一标识符可以同时用作不同的目的。例如,作为某一函数名称的标识符,还可以同时用作变量名、函数参数、程序标注等,使用时他们的属性或值等并不相互影响。在下面的简单的例程中,mytest这一标识符即用作了函数名,又用作了变量名、函数参数名、函数参数名、常量名。显然,wmlscript的这一特定为我们编写程序提供了很大的方便。
  4.3.3 wmlscript程序的基本书写规则
  wmlscript程序的基本书本写规则:
  1.程序由若干语句或函数组成,函数有由若干语句组成;
  2.每个完整的语句后面必须加上分号(;),语句关键词语操作数之间必须有空间;分号(;)是wmlscript程序的组成部分;
  3.函数体之间必须使用成对的花括号({ })括起来,而且函数结束时在右花括号(})的后面还要加上分号(;);函数说明部分,如函数名、函数类型、函数参数等要放在花括号({})的前面;
    4.有些语句可能也需要实用花括号({ })办含内容,这类语句通常也可以放在函数中,所以花括号({ })是可以嵌套的。
  当然,不同的语句、参数、变量等元素在声明和书写时可能还有一些更细的要求,具体我们后面介绍这些元素是再专门给出,
  4.4 变量与数据类型
  变量即数据类型是所有编程语言的概念和组成部分,wmlscript对此也不例外。它对其变量使用方法和数据类型定义方法给出了详细的规定。变量通常与某数据之相对应,我们可以给变量赋值,并可在程序执行中改变变量的值。下面我们讲解wmlscript有关变量与数据类型的详细规定。
  4.4.1变量及其声明
  变量是在wmlscript脚本程序中具有值的符号名,或说标识符。使用变量可以存储和改变程序中需要的数据。与c语言不同的是,wmlscript仅支持函数内定义的变量或用于传送数的参变量。
  变量使用前必须进行声明,也就是定义变量,即指定变量的名字。声明变量的关键字是var,它的后面根上作为变量名的合法的标识符,并于最后加上分号(;),即完成一个量的声明。声明变量是可以使用var一次声明多个变量名,相邻变量之间使用都号(,)间隔。
  一般情况下,我们在给变量命名的时候,都希望能够使用有意义的变量名。例如,当需要使用一个变量表示一本书的价格时,虽然将变量命名为j或book都没有什么错误,但若能命名为bookprice则会是的wmlscript脚本程序具有更好的可读性,可以方便编程人员进行脚本的编写和调试工作。而且,由于wmlscript在给变量命名是不能使用保留字,所以考虑到避免由于一时的疏忽时变量名欲保留字发生冲突,我们建议使用多个单词组合在以其作为一个变量的名称,这是一个比较好的解决办法。例如,如果要定义一个变量来存储的、一本书的价格,那我们可以不妨使用bookprice或者book_price作为变量的名称,这样,一方面可以时变量显得更加清晰,另一方面也可以避免变量与保留字的冲突问题。
  以上只是我们对于变量命名的建议,并不是强制性的要求,用户完全可以不按照我们的要求来做,只要遵守wmlscript对于标识符命名的要求就可以了,但养成良好的编程风格不论是对编程人员还是对脚本编写人员来说,都是十分有意义的。

  4.4.2 变量的作用域与生命期
  一个变量的作用域是指在程序中能够引用这个变量的一段代码。由于wmlscript仅支持函数内定义的变量,所以wmlscript变量的作用与通常就是定义它们的那个函数。在该函数之外,变量不再发挥直接作用。
  变量的生命起始值从变量声明开始到失效为止。变量的生命期也被称为变量的持久期、存活期。一个变量在定义它的整个函数内都是有效的,函数内的任何语句块都不会削减变量的生命期或限制变量的作用域。
  如果一个变量未经生命就直接使用,或声明过后再次声明,都会破坏变量的生命期。前一种情况会导致变量没有开始声明期,即没有“生命”;而后一种情况则导致变量

上一页  [1] [2] [3] [4]  下一页

[page_break] 声明期没有结束以前就重新赋予声明期,即让它多次“降生”。这都会导致变量无效使用。下面函数中的变量使用就说明了这一问题:
  function foo(){
  x=1;//错误:变量使用前没有声明,改变量还没有“声明”。
  var x,y,z;
  y=x+3;
  var zd =invalid
  if(x){
  var(y);//错误:这一变量已经声明,这里是重复声明。
  };
  };
  4.4.3 变量的使用
  wmlscript的变量只能在定义它的函数内使用。使用时需要声明变量,声明变量是可以同时对变量赋值,甚至对变量进行运算。例如,下面的简单函数就说明了变量的这种灵活的使用方法:
  function ourage(){
  var myage=38;
  var yourage=26;
  var ourage=myage+yourage;
  return ourage;
  };
  使用变量时可通过调用变量名字的形式来实现。上面例子中的“var ourage=myage+yourage;”一句,通过调用变量名,变量ourage对变量myage和变量yourage实行了求和操作。
  4.4.4 变量类型与数据类型
  wmlscript是一种“弱类型”的语言,及其变量没有确定的类型。wmlscript变量的类型有改变量所赋数据的类型决定,并根据数据类型的改变而改变。wmlscript只支持内部定义的数据,因此我们编写程序是无需指定wmlscript变量的类型,wmlscript减根据变量而赋数据的类型自动进行匹配。由于wmlscript的数据类型共有整数、浮点数、字符串、布尔型和“无效型”五种类型,所以wmlscript变量的类型所能匹配的也就是这五种类型。
  4.4.5 变量值域
  由于变量类型尤其所赋数据的类型决定,所以变量值与域其所赋数据的可取范围等价的。下面的我们就给出整数、浮点数、字符串和布尔型的区值范围,以参照确定应类型变量的值域。1.整数的范围。wmlscript支持的整数是32位的,也就是说整数的区值范围是从2147483648到+2147483647。我们可以在程序运行期是用lang函数来取得这些值,如:
  lang.maxint(); //获取最大的整数
  lang.maxint(); //获取最小的整数
  2.浮点数的范围。它是指wmlscript浮点数的精度所能表示的最小和最大数值wmlscript支持32为的单精度浮点数,其最大至时3.40282347e+38,最小的非零的数是1.17549435e-38或更小(按照正常的精度)。
  我们可以使用浮点float函数库在程序运行其取得这些数值:
  float.maxfloa(); //获得wmlscript所支持的最大浮点值
  float.maxfloa(); //获得wmlscript所支持的最小浮点值
  对于运行期出现的一些特殊的浮点数,wmlscript将按照下述规则处理:
  其一,如果操作结果是一个不能被单精度浮点数所能表示的数值,那么该结果将被认为是invalid,即无效值;
  其二,如果操作结果发生下溢出,那么结果将作为0.0处理:
  其三,负的零和正的零是完全相等的。
  3.字符串的范围。任何由于字母、数字或特殊字符组成的符号串都是wmlscript中定义的有关字符串的操作或string库中的函数控制字符串。
  4.布尔型数据的范围。布尔型数据只有ture和flase两个取值,这也是布尔型变量的两种数值。我们可以使用布尔型数据取初始化或指定某一变量的数值,或将布尔值变量写入一个需要布尔值作为参数的语句。布尔值可以是数值运算的结果,也可以是逻辑运算的结果。
  下面就是定义布尔型变量并赋初值的例句:
  var truth=truth;
  var lie=!truth;
  4.5 操作符与表达式
  在wmlscript中,表达式可以把变量、常量与操作符结合起来,经过运算能够产生一定的运算结果。表达式运算后产生的结果可以是整数型、浮点数型、字符串型或布尔型的数据。其实,对于表达式我们并不陌生,例如,1+2就是一个简单的表达式。
  wmlscript的表达式主要有两种类型。一种是赋值表达式,即把数据赋给变量的一种表达式,例如,mybook=3,在这个表达式中,将3 赋给变量mybook,同时,这个表达式本身也有一个运算结果,那就是3。另外一种是运算表达式,它是指产生一个运算结果而不进行赋值操作的表达式,例如1+2就是一个运算表达式,在这个表达式运算产生的结果是3,但这个表达式并没有把运算结果赋给变量。
  在表达式运算的过程中,表达式中操作一个或这两个数据产生运算的符号做操作符,被操作符操作的数据称作操作数,在wmlscript中我们会使用到各种操作符,下面就对操作符及有关的表达式进行详细讲解。
  4.5.1 赋值操作符
  赋值操作符用于赋值操作,即给变量指定所需的数值,它能把有操作数的运算结果给做操作数,最简单的赋值操作符就是“=”,例如x=2,就是将2赋值给变量x。在如以下几行语句都是赋值操作:
  var="abc";
  var b=a;
  b="def";
  赋值操作符不需要指定使用对象,也不会改变赋值操作符右边变量的数值。wmlscript的赋值操作符主要包括以下几种:
  1.=。用于赋值操作,将有操作数赋给左操作。
  2 +=。将有操作数与左操作数进行相见运算,然后把运算结果赋值给左操作数。例如,假设x=3,那么x+=2运算后的结果为x=5。
  +=是比较特别的操作符,因为它可以将两个字符串相连,所以+=操作符也可以对字符串进行操作,然后将连接后的字符串赋给左操作数。例如,假设x="happy",那么x+="new year"运算后结果是x="happy new year"。
  3.-=。将左操作数简取有操作数,然后把运算结果赋值给左操作数。例如,假设x=3那么x-=运算后的结果为x=1。
  4*=。将左操作属于有操作符进行相乘运算,然后把运算结果赋值给左操作数。例如,假设x=6,那么x*=2运算后的结果为x=6。
  5/=。将右操作属于右操作符进行相乘运算,然后把运算结果赋值给左操作数。例如,假设x=6,那么x*=2运算后的结果为x=6。
  6div=。拥有操作数处理左操作数,然后把运算结果中的整数部分赋值给左操作数,例如x=7,那么xdiv=2运算后的结果为x=3。
  7%=。功能是求余数并赋值,用右操作数除以做操作数,最后把运算得到的余数值给操作数。例如,假设x=7,那么x%=3运算后的结果为x=1。
  8<<=。功能是带符号左位移并赋值,即将左操作和右操作数进行左位移操作,在将结果赋给左操作数。
  9>>=。可将左操作和右操作进行右操作进行补零右位移操作,在将结果赋给左操作数。
  4.5.2 数学运算操作符
  数学运算操作符可以对数值类型的操作数进行运算,然后返回一个数值类型的运

上一页  [1] [2] [3] [4]  下一页

[page_break] 算结果。
  1+。这是加运算操作等,它对应着数学运算中的加法运算,例如表达式1+2的运算结果为3。
  加操作符还可以对字符串类型的操作数进行运算,然后将两个字符串相连起来作为运算
  2- 。即检操作符,对应着速学运算中的减法运算,例如表达式2-1的运算结果为1。
  同时,“-”还是一个取负操作符,当它作为取负操作符的是一个操作数,取负操作符的功能使返回操作数的相反数。
  3*。这是乘操作符,它对应着数学运算中的乘法运算,例如表达式2*3的运算结果为6。
  4/。即除操作符,对应着数学运算中的除法运算,但wmlscript中的除法运算有些特别,在wmlscript中,除法运算后的结果是一个浮点数,而不想c语言或者java语言那样在整数进行除法运算式井运算结果强行转化整数。在wmlscript中,1/2=0.5,而在jave中,1/2=0。
  5div。这是整除操作符,对应着数学运算中的整数运算,运算后的结果一个整数,这一点与c语言或者java语言中的情况是一样的,可以在整数进行除法运算式将运算结果强行转换整数。
  6%。即取模操作符,它对应着数学运算中的取莫运算,也就是将两个操作相除,返回相除后的余数。
  取模操作符主要用于判断一个数字是否能被另一个数字整除。
  ((the year%3==0))&&(the year%100!=0))||(the year%400==0)
  其中&&代表的是逻辑运算中的与运算,||代表的是逻辑运算中的或运算,关于逻辑运算,我们后面会详细介绍。
  7++。这是递增操作符,它只有一个操作数,操作可以在操作符的左边,也可以在操作符的右边,它所完成的运算操作是将操作数加1。假设操作数名称为j,值为2,那么++j加1,然后返回j的值3;而j++则实现返回j的值2,然后将j加1。
  在循环中,我们常常会用到递增操作符的作用正好相反。递减操作完成的运算操作是经操作数减1。例如,假设操作数名称为j,值为2,那么--j先将j减1,然后返回的值1;而j--是先返回j的值2,然后将j减1。
  4.5.3 位操作符
  为操作符在运算实现将操作转化32位的二进制数,然后对每个操作数分别按位进行运算,运算后在将二进制的结果按照标准wmlscript数值类型返回运算结束。
  1&。这是为与操作符,它可以对两个操作数按位进行于操作,其运算规则是:
  0&0=0,0&1=0,1&0=0,1&1=1
  2|。这是位或操作符,它可以对两个操作数按位进行或操作,运算规则是:
  0|0=0 ,0|1=1,1|0=1,1|1=1
  3^。这是唯一或操作符,它可以对两个操作按位进行异或操作,其运算规则是:0^0=0,0^1=1,1^0=1,1^1=0
  4~。这是位非操作符,它只有一个操作数,可对操作数按位进行非操作,运算规则是:~0=1,~=0
  5<<。这是左移操作,它可以对左操作数进行向左一位的操作,由操作数给定了要移动的位数,在移动过程中,左操作数的最低为补充0。
  6>>。这是右移操作符,它可以对左操作数进行向右移位的操作,由操作数给定要移动的位数,在移位的过程中,丢弃向右移的位。
  7>>>。这是填0右移操作符,它与右移操作符相似。当对证正数进行操作时,它们的效果完全相同;不同之处在于,当进行负整数右移操作时,因为负责转化为二进制后,最高为1,所以在进行右移操作后,最高位仍然补充1,而在进行填0右移操作时,最高为补充的是0,因此,这是负数将转化为正数。
  4.5.4 逻辑操作符
  逻辑操作符可以将布尔类型的表达式组合起来,完成逻辑运算操作,然后返回逻辑运算的结果——真或假,这样就可以完成比较复杂的逻辑判断工作。逻辑操作共有3种;
  1&&。即逻辑与操作符它只有在两个操作数都为ture的时候,返回结果为ture,在其他情况下,返回结果为false或者invalid。
  2||。这是或操作符,它在两个操作数至少有一个为ture的时候,返回结果为ture,在其他情况下,返回结果为false或者invalid。
  3!。即非操作符,它只有一个操作数。当操作数为ture时,返回结果为flase;返回结果为ture.
  4.5.5 比较操作符
  比较操作符可以把操作数进行比较,然后返回一个逻辑值,表明这个比较操作的结果是否为真。比较操作的操作数可以是数值类型或者字符串类型的数据。比较操作符也常被称为关系运算符。
  wmlscript支持的比较操作符共有6种,下面被介绍一下。
  1. ==。即等于操作符,它可以比较两个操作数是否相等。如果两个操作数相等,则返回ture,否则返回false
  2. !=。即不等操作符。它可以比较两个操作数是否相等。如果两个操作数相等,则返回false,否则返回ture。
  3. >。即大于操作等。其运算规则时,如果左操作数大于右操作数,则返回ture。

上一页  [1] [2] [3] [4] 

上一个:Wbmp格式研究
下一个:如何在PWS(Microsoft Personal Web Server)上建立WAP网站

更多图片编程知识:
更多wap疑问解答:
为什么程序都退出了还可以收到推送?如果大多设备都可以推送那运营商怎么办?
qt 4.7 sqlserver2000 存储过程调用
Android FrameBuffer读屏幕30秒后mmap失败
联通粗定位用java程序如何来请求和接受数据
为什么QT运行Android平台的程序时,mouseMoveEvent事件响应的间隔时间很长??????????
android与PC蓝牙通讯
指定大小的label 内容可变,如果内容超出label的宽度,将未能显示的部分显示在另一个label上
android如何通过wifi连接无线打印机
运行程序,release目录下产生一个乱码文件夹
分享个某机构最新安卓资料,自己验证了
求助:QT5.0 没有QPrinter吗
直接调用 openmax IL 做 h264 解码, 有人会吗?
android在锁屏界面之上添加一个View
Bada模拟器如何访问pc机上的web
18396828106@163.com
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,