美文网首页
Q语言——基础操作

Q语言——基础操作

作者: Hero_cxs | 来源:发表于2019-04-04 23:26 被阅读0次

    前言

    Q语言在执行顺序是从右到左,这与其他编程语言非常的不同,这一点可能会非常的不习惯,再加上本身的是一种vector language,当参数是标量和参数是向量时,常常会有不一样的效果,特别是操作符有各种前缀,中缀,后缀用法,因此要对Q语言的执行顺序非常了解。

    一、运算符、函数、动词

    Kdb +有名词,动词和副词。所有数据对象和函数都是nouns。Verbs通过减少表达式中的方括号和括号的数量来增强可读性。Adverbs修改二元(2个参数)函数和动词以产生新的相关动词。 副词derived functions称为derived functions或derived verbs。

    1. 函数表示方法

    Q语言中有着丰富的内置函数,具体可以参考官网介绍:https://code.kx.com/q4m3/A_Built-in_Functions/

    当然我们也可以定义自己的函数,我们编写的函数和内置函数之间有两个主要的区别:

    1)自定义的函数必须具有字母数字名称,而q内置函数可以是纯符号;

    2)自定义的函数只能用于前缀表示法,而q内置函数可以用前缀或中缀。

    自定义函数具体形式如下:

    F:{[参数1;……;参数n] 表达式1;……;表达式n}
    

    后续会专用一个专栏介绍关于Q语言的自定义函数,此处可以先了解下,本次先着重介绍Q预言的内置函数。

    2. 动词和函数表示方法

    Q语言中的函数常见的是用前缀或中缀的表示形式,而在大多数编程语言中都习惯采用中缀的形式,如:

    q)+[2;3] /前缀形式,计算2+3
    5
    q)2+3 /中缀形式,计算2+3
    5
    q)=[2;3] /前缀形式,判断2和3是否相等
    0b
    q)2=3 /中缀形式,判断2和3是否相等
    0b
    

    3. 原子函数的扩展

    参数为原子的我们称为原子函数,原子函数的一个基本特征是它们的动作自动扩展到列表中的项目。

    q)neg 1 2 3
    -1 -2 -3
    q)1 2 3+10 20 30
    11 22 33
    q)1 2 3+10 20 30 40 /由于长度不相等,因此结果返回长度错误
    'length
    q)neg (1 2 3; 4 5)
    -1 -2 -3
    -4 -5
    q)(1 2 3; 4 5)+(100 200 300; 400 500)
    101 202 303
    404 505
    q)100+1 2 3
    101 102 103
    q)1 2 3+100
    01 102 103
    q)100+(1 2 3; 4 5)
    101 102 103
    104 105
    q)(1 2 3; 4 5)+100
    101 102 103
    104 105
    

    二、操作符的优先级

    在Q语言中,操作符是没有优先级的,这非常重要,与其他编程语言不用,如*或者/的优先级要高于+后者-,而在Q语言中,不存在操作符的优先级,按照顺序从右到左执行,这样做的目的也是为了提高计算或处理速度。

    q)2*3+4 /一般编程语言中,结果应该是10,但是在Q中,由于从右到左的执行,而结果就是14
    14 
    q)2*(3+4)
    14
    q)2*3-4 /一般编程语言中,结果应该是2,但是在Q中,由于从右到左的执行,而结果就是-2
    -2
    q)2*(3-4)
    -2
    q)(2+3)*3+4 /一般编程语言中,结果应该是19,但是在Q中,由于从右到左的执行,而结果就是35
    35
    

    三、匹配操作符

    “~”为匹配操作符,匹配的两个对象必须是一样的类型和一样的值。

    q)42~40+2 /由于40+2=42,结果类型为-7h,因此两个相同,结果为真
    1b
    q)42~42h /由于42h的类型数-5h,42的结果类型为-7h,两个不相同,结果为假
    0b
    q)42f~42.0
    1b
    q)42~`42
    0b
    q)4 2~4 2 /多个值的匹配,每个相同结果才为真,判断整体
    1b
    q)4 2=4 2 /多个值用=进行匹配,进行单个判断
    11b
    q)4 2 1=4 2 3 /多个值用=进行匹配,进行单个判断
    110b
    q)(4 2)~(4;2*1)
    1b
    q)(())~enlist ()
    0b
    q)(1; 2 3 4)~(1; (2; 3; 4))
    1b
    q)(1; 2 3 4)=(1; (2; 3; 4))
    1b
    111b
    q)(1 2;3 4)~(1;2 3 4)
    0b
    q)(1 2;3 4)=(1;2 3 4) /用=进行匹配结果返回长度不相等的错误
    'length
    

    四、等式和其相关操作

    前面介绍过匹配,匹配需要两个对象的类型和值是一样结果才是真,关系运算符则不同,关系运算不需要匹配它们的操作数类型,只要他们互相兼容。

    1. =和<>

    q)42=42i /=号操作符的结果就为真,但是~操作符的结果为假
    1b
    q)42=42h 
    1b
    q)42=42.0 /=号操作符的结果就为真,但是~操作符的结果为假
    1b
    q)42=0x42
    0b
    q)42="*" /=号操作符的结果就为真,但是~操作符的结果为假
    1b
    q)2000.01.01=2000.01.01D00:00:00.000000000 /时间类型的判断
    1b
    q)2015.01.01<2015.02m
    1b
    q)12:00:00=12:00:00.000
    1b
    q)25<>33 /<>表示不等于
    1b
    q)25<>25h
    0b
    q)25<>25.0
    0b
    q)25<>26.0
    1b
    

    2. not

    运算符not它返回一个布尔结果,并课用于所有数字类型,时间和字符类型,当原数据类型的值为0或者0b时,返回结果为1b;不为零或者1b时返回结果为0b。

    q)not 0b
    1b
    q)not 1b
    0b
    q)not 42 
    0b
    q)not 0
    1b
    q)not 0xff
    0b
    q)not 98.6
    0b
    q)not "*" /这里会先将*转换为ASCII的值,然后再判断,由于*好的ASCII值不为0 ,则结果返回0b
    0b
    q)not " "
    0b
    q)not "\000"
    1b
    q)not 2000.01.01 /由于Q的时间是以2000.01.01为原点,因此该值相当于0 ,则结果返回1b
    1b
    q)not 2014.01.01
    0b
    q)not 2000.01.01T00:00:00.000000000
    1b
    q)not 2000.01m
    1b
    q)not 12:00:00.000000000
    0b
    

    3. 关系运算符:>;<=;>;>=

    同样关系运算符也可以用于不同类型的关系判断,其结果返回也是布尔值,对于多个值同时判断,则返回每个对应的判断结果。

    q)4<42
    1b
    q)4<42h
    1b
    q)4h>0x2a
    0b
    q)-1.414<99i
    1b
    q)2000.01.01<2000.01.01D00:00:00.000000001
    1b
    q)2015.01.01<2015.02m
    1b
    q)"A"<"Z"
    1b
    q)"A"<"O"
    1b
    q)`abc<`aba
    0b
    q)5<=5
    1b
    q)"A"<="O"
    1b
    q)"A">="O"
    0b
    q)5<=5
    1b
    q)5>=5
    1b
    q)10 20 30<=30 20 10
    110b
    q)2=1 2 3 /一个原子可以同时匹配多个原子
    010b
    q)20 10=10 20 30 /由于两边长度不相等,无法进行匹配
    'length
    q)"zaphod"="Arthur"
    000100b
    q)"zaphod">"Arthur"
    100000b
    

    4. 基本数学运算符:+;-;*;%

    与其他编程语言,Q语言也含有基础数学运算符,只是除号由/改为了%,由于/用于注释时使用。

    q)2+3 /加运算
    5 
    q)2-3 /减运算
    -1
    q)2*3 /乘运算
    6
    q)4%2 /除运算,除运算的结果是float类型
    2f
    q)a:4
    q)b:2
    q)a+b
    6
    q)a-b
    2
    q)a*b
    8
    q)a%b
    2f
    q)1b+1b /布尔类型也可以进行加减乘除运算
    2i
    q)1b-1b
    0i
    q)42*1b
    42
    q)1b%1b
    1f
    q)42%1b
    42f
    q)1b%42
    0.02380952
    q)58*0x2a /不同类型的数据进行数学运算
    2436
    q)5i*0x2a
    210i
    q)6+7.0
    13f
    q)1.0+1b
    2f
    q)a:4
    q)-a /数学基础运算符是二元运算,必须传入两个参数,因此-a不会等于-4,需要用0-a或者neg a进行处理
    '-
     [0] -a
     ^
    q)0-42
    -42
    q)0-a
    -4
    q)neg a
    -4
    q)1.0 + 10 20 30
    11 21 31f
    q)10 20 30%1 2 3
    10 10 10f
    q)100 200 300+1b
    101 201 301
    q)1+(100 200; 300 400) /整数与列表进行计算
    101 201
    301 401
    

    五、最大值与最小值操作符

    最大值操作符“|”返回最大的结果值,最小值操作符“&”返回最小的结果值,同时也可以用于逻辑与和或的操作。

    q)42|43 /返回42与43中的最大值
    43
    q)98.6&101.9  /返回98.6与101.9中的最小值
    98.6
    q)0b|1b /返回0b与1b中的最大值(对于二进制也可以理解为或操作)
    1b
    q)0b&1b /返回0b与1b中的最小值(对于二进制也可以理解为与操作)
    0b
    q)42|0x2b /返回42与0x2b中的最大值(结果将16进制转换成10进制了)
    43
    q)0x2a|0x2b 
    0x2b
    q)"a"|"z" /返回“a”与”z”中的最大值(通过ASCII码进行比较)
    "z"
    q)"a"&"z"
    "a"
    q)`a|`z /不能对symbol类型进行操作
    'type
     [0] `a|`z
     ^
    q)2|0 1 2 3 4 /原子与列表进行最大值操作
    2 2 2 3 4
    q)"zaphod"|"arthur"
    "zrthur"
    q)1b or 0b /逻辑或操作,也可以理解为返回最大值
    1b
    q)1b and 0b /逻辑与操作,也可以理解为返回最小值
    0b
    q)42 or 43 /返回最大值
    43
    q)42 and 0b /返回最小值,会将0b看成0
    0
    q)42 or 0b /返回最大值,会讲0b看成0
    42
    

    六、修饰符:号

    在这里:作为一个重载操作符,先介绍其赋值的使用,前面我们看到过比如a:42,意思是将42的值赋值给变量a,与C语言中a=42类似。

    q)a:42 /将42的值赋值给变量a
    q)a
    42
    q)a+:1 /给变量a的值加1并赋值给变量a,等价于C语言中的a=a+1
    q)a
    43
    q)a-:1 /给变量a的值减1并赋值给变量a,等价于C语言中的a=a-1
    q)a
    42
    q)a&:21 /比较a的值与21的大小,将小的值赋值给a
    q)a
    21
    q)a|:42 /比较a的值与21的大小,将大的值赋值给a
    q)a
    42
    q)x /由于变量x值未定义,因此直接使用变量x会出错
    'x
     [0] x
    q)x+:42  /这里定义一个变量x,并将其加42,在之前为定义x的变量的情况下将默认x的初始值为0
    q)x
    42
    q)L:100 200 300 400 /定义一个列表L
    q)L
    100 200 300 400
    q)L[1]+:99 /给列表L中的第二个元素+99并赋值给列表中第二个元素
    q)L
    100 299 300 400 
    q)L[1 3]-:1 /给列表L中的第二和第四个个元素-1并赋值给列表中第二和第四个元素
    q)L
    100 298 300 399
    q)L1:(1 2 3; 4 5) /定义一个列表L1
    q)L1
    1 2 3
    4 5
    q)L1[;1]+:100 /给列表L1的每一行中的第二个元素+100并赋值给列表L1中的每一行中的第二个元素
    q)L1
    1 102 3
    4 105
    q)L
    100 298 300 399
    q)L,:99 / ,号为附加的含义,将99附件到列表L中
    q)L
    100 298 300 399 99
    

    七、指数与对数等基本操作

    sqrt、exp、log、xexp、xlog为常见的开方、自然常数e、自然对数、幂指数、对数

    q)sqrt 2  /根号2
    1.414214
    q)sqrt 42.4   /根号42.4
    6.511528
    q)sqrt 1b  /对布尔值开根号,变为float类型
    1f
    q)sqrt 0b
    0f
    q)sqrt -2 /负数开根号,不会报错,返回值为0n(float类型的空值)
    0n
    q)sqrt -5
    0n
    q)exp 1 /以e为底的指数
    2.718282
    q)exp 0
    1f
    q)exp 4.2
    66.68633
    q)exp -12 
    6.144212e-006
    q)exp -12i
    6.144212e-006
    q)1e5 /表示1x10的5次方
    100000f
    q)1e1   /表示1x10的1次方
    10f
    q)log 1  /表示以自然常数e为底的对数 
    0f
    q)log 42
    3.73767
    q)log 0.001
    -6.907755
    q)log -1
    0n
    q)2 xexp 5 /表示2的5次方
    32f
    q)-2 xexp 5
    -32f
    q)2 xlog 32 /表示以2为底5的对数
    5f
    q)2 xlog -1
    0n
    

    八、更多数学操作符

    div和mod分别表示取整和取余,signnum表示数学上的符号函数(符号函数为大于0的值返回结果都为1,小于0的值返回结果都为-1),reciprocal表示求倒数,floor表示向下取整,ceiling表示向上取整,abs表示绝对值。

    q)7 div 3 /7除以3,最大只能商2,因此结果返回2
    2
    q)7 div 2  /7除以2,最大只能商3,因此结果返回3
    3
    q)6 div 3  
    2
    q)-7 div 3 /对于负数,-7除以3,最大只能商-2,单结果需要向下进1,因此返回结果为-3
    -3
    q)-7 div 2.5
    -3
    q)7 div -2
    -4
    q)7 div -3
    -3
    q)6 div -3
    -2
    q)7 mod 2 /7除以2余1,返回结果为1
    1
    q)7 mod 3 /7除以3余1,返回结果为1
    1
    q)6 mod 3
    0
    q)-7 mod 2 /-7除以2与7除以-2取余返回结果不同。
    1
    q)7 mod -2
    -1
    q)3 4 5 mod 2
    1 0 1
    q)3 4 5 div 2
    1 2 2
    q)3 4 5 mod 2 3 4
    1 1 1
    q)3 4 5 div 2 3 4
    1 1 1
    q)signum 9999 /符号函数给的参数大于0结果都为1,小于0结果都是-1,参数为0时结果为0
    1i
    q)signum -9999
    -1i
    q)signum -1
    -1i
    q)signum 1
    1i
    q)signum 0
    0i
    q)reciprocal 100 /100的倒数
    0.01
    q)reciprocal 10
    0.1
    q)reciprocal 1
    1f
    q)reciprocal -1
    -1f
    q)reciprocal -10
    -0.1
    q)reciprocal 0 /数学书0的倒数不存在,Q中则返回无穷大
    0w
    q)floor 4.6 /对于大于0的数只取整数部分
    4
    q)floor 4.1
    4
    q)floor 4
    4
    q)floor -4.3 /对于小于0的数取整数部分-1
    -5
    q)ceiling 4.2 /对于大于0的数只取整数部分+1
    5
    q)ceiling 4.9
    5
    q)ceiling -4.2 /对于小于0的数只取整数部分
    -4
    q)ceiling -4.9
    -4
    q)abs -4 /取绝对值
    4
    q)abs 1.2
    1.2
    q)abs -1.2
    1.2
    

    九、时间数据操作

    前面我们介绍过Q语言中时间的操作非常的强大,日期都是以2000.01.01为时间的起始点,时间都是以00:00:00:0000为起点。由于有了相对的原点,我们就可以将日期和时间转换成整数。

    q)`int$1999.12.31 /将1999年12月31日转换成int类型,1999年12月31日与2000年1月1日少一天,因此返回结果为-1
    -1i
    q)`int$2003.01m /将2003年1月转换成int类型,2003年1月与2000年1月相比多了36个月,因此返回结果为36
    36i
    q)`int$12:00:00.123 /转换为毫秒
    43200123i
    q)`int$00:00:00.123 /转换为毫秒
    123i
    q)2000.01.02=2000.01.02D00:00:00.000000000 
    1b
    q)`timestamp$2001.01.02 /转换为日期+时间的形式
    2001.01.02D00:00:00.000000000
    q)2000.01.01<2000.01.01D12:00:00.000000000 /判断大小
    1b
    q)2000.01.01=0
    1b
    q)12:00:00=12*60*60
    1b
    q)1999.12.31<0
    1b
    q)2014.12.31+1 /加一天就变为了2015年1月1日
    2015.01.01
    q)12:00:00+1 /加一分钟
    12:00:01
    q)12:00:00+01:00:00  /加一个小时
    13:00:00
    

    十、别名::

    在Q语言中,可以使用::建立别名,别名的好处就是当原数据改变时,别名也变为,但赋值就不会改变

    q)a:42 /42赋值给a
    q)b::a /建立a的别名b
    q)c:a /将a的值赋值给c
    q)a
    42
    q)b
    42
    q)c
    42
    q)a:43 /修改a的值
    q)a
    43
    q)b /b的值也同时修改
    43
    q)c /c的值还是42,因此可以看出别名的作用
    42
    

    相关文章

      网友评论

          本文标题:Q语言——基础操作

          本文链接:https://www.haomeiwen.com/subject/ncbciqtx.html